Browse Source

Implement completion status fallback & fixes

pull/576/head
Vladislav Oleshko 4 years ago
parent
commit
05d49d666e
  1. 16
      src/Magnum/GL/AbstractShaderProgram.cpp
  2. 2
      src/Magnum/GL/AbstractShaderProgram.h
  3. 7
      src/Magnum/GL/Implementation/ShaderProgramState.cpp
  4. 1
      src/Magnum/GL/Implementation/ShaderProgramState.h
  5. 12
      src/Magnum/GL/Implementation/ShaderState.cpp
  6. 1
      src/Magnum/GL/Implementation/ShaderState.h
  7. 16
      src/Magnum/GL/Shader.cpp
  8. 2
      src/Magnum/GL/Shader.h
  9. 21
      src/Magnum/Shaders/FlatGL.cpp
  10. 10
      src/Magnum/Shaders/FlatGL.h

16
src/Magnum/GL/AbstractShaderProgram.cpp

@ -605,19 +605,17 @@ bool AbstractShaderProgram::checkLink() {
be said, handle that as well. */ be said, handle that as well. */
Context::current().state().shaderProgram.cleanLogImplementation(message); Context::current().state().shaderProgram.cleanLogImplementation(message);
/** @todo update log messages */
/* Show error log */ /* Show error log */
if(!success) { if(!success) {
Error out{Debug::Flag::NoNewlineAtTheEnd}; Error out{Debug::Flag::NoNewlineAtTheEnd};
out << "GL::AbstractShaderProgram::link(): linking"; out << "GL::AbstractShaderProgram::link(): linking failed with the following message:"
out << "failed with the following message:" << Debug::newline << message; << Debug::newline << message;
/* Or just warnings, if any */ /* Or just warnings, if any */
} else if(!message.empty()) { } else if(!message.empty()) {
Warning out{Debug::Flag::NoNewlineAtTheEnd}; Warning out{Debug::Flag::NoNewlineAtTheEnd};
out << "GL::AbstractShaderProgram::link(): linking"; out << "GL::AbstractShaderProgram::link(): linking succeeded with the following message:"
out << "succeeded with the following message:" << Debug::newline << message; << Debug::newline << message;
} }
return success; return success;
@ -632,7 +630,7 @@ bool AbstractShaderProgram::link(std::initializer_list<Containers::Reference<Abs
bool AbstractShaderProgram::isLinkFinished() { bool AbstractShaderProgram::isLinkFinished() {
GLint success; GLint success;
glGetProgramiv(_id, GL_COMPLETION_STATUS_KHR, &success); Context::current().state().shaderProgram.completionStatusImplementation(_id, GL_COMPLETION_STATUS_KHR, &success);
return success == GL_TRUE; return success == GL_TRUE;
} }
@ -650,6 +648,10 @@ void AbstractShaderProgram::cleanLogImplementationAngle(std::string& message) {
} }
#endif #endif
void AbstractShaderProgram::completionStatusImplementationFallback(GLuint, GLenum, GLint* value) {
*value = GL_TRUE;
}
Int AbstractShaderProgram::uniformLocationInternal(const Containers::ArrayView<const char> name) { Int AbstractShaderProgram::uniformLocationInternal(const Containers::ArrayView<const char> name) {
const GLint location = glGetUniformLocation(_id, name); const GLint location = glGetUniformLocation(_id, name);
if(location == -1) if(location == -1)

2
src/Magnum/GL/AbstractShaderProgram.h

@ -1692,6 +1692,8 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
static MAGNUM_GL_LOCAL void cleanLogImplementationAngle(std::string& message); static MAGNUM_GL_LOCAL void cleanLogImplementationAngle(std::string& message);
#endif #endif
static MAGNUM_GL_LOCAL void completionStatusImplementationFallback(GLuint, GLenum, GLint*);
MAGNUM_GL_LOCAL static void use(GLuint id); MAGNUM_GL_LOCAL static void use(GLuint id);
void use(); void use();

7
src/Magnum/GL/Implementation/ShaderProgramState.cpp

@ -78,6 +78,13 @@ ShaderProgramState::ShaderProgramState(Context& context, Containers::StaticArray
cleanLogImplementation = &AbstractShaderProgram::cleanLogImplementationNoOp; cleanLogImplementation = &AbstractShaderProgram::cleanLogImplementationNoOp;
} }
if(context.isExtensionSupported<Extensions::KHR::parallel_shader_compile>()) {
extensions[Extensions::KHR::parallel_shader_compile::Index] = Extensions::KHR::parallel_shader_compile::string();
completionStatusImplementation = glGetProgramiv;
} else {
completionStatusImplementation = &AbstractShaderProgram::completionStatusImplementationFallback;
}
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES

1
src/Magnum/GL/Implementation/ShaderProgramState.h

@ -47,6 +47,7 @@ struct ShaderProgramState {
void(AbstractShaderProgram::*transformFeedbackVaryingsImplementation)(Containers::ArrayView<const std::string>, AbstractShaderProgram::TransformFeedbackBufferMode); void(AbstractShaderProgram::*transformFeedbackVaryingsImplementation)(Containers::ArrayView<const std::string>, AbstractShaderProgram::TransformFeedbackBufferMode);
#endif #endif
void(*cleanLogImplementation)(std::string&); void(*cleanLogImplementation)(std::string&);
void(*completionStatusImplementation)(GLuint, GLenum, GLint* value);
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
void(APIENTRY *uniform1fvImplementation)(GLuint, GLint, GLsizei, const GLfloat*); void(APIENTRY *uniform1fvImplementation)(GLuint, GLint, GLsizei, const GLfloat*);

12
src/Magnum/GL/Implementation/ShaderState.cpp

@ -31,12 +31,13 @@
#include "Magnum/GL/Context.h" #include "Magnum/GL/Context.h"
#include "Magnum/GL/Shader.h" #include "Magnum/GL/Shader.h"
#include "Magnum/GL/Extensions.h"
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
using namespace Containers::Literals; using namespace Containers::Literals;
ShaderState::ShaderState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*>): ShaderState::ShaderState(Context& context, Containers::StaticArrayView<Implementation::ExtensionCount, const char*> extensions):
maxVertexOutputComponents{}, maxFragmentInputComponents{}, maxVertexOutputComponents{}, maxFragmentInputComponents{},
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
maxTessellationControlInputComponents{}, maxTessellationControlOutputComponents{}, maxTessellationControlTotalOutputComponents{}, maxTessellationEvaluationInputComponents{}, maxTessellationEvaluationOutputComponents{}, maxGeometryInputComponents{}, maxGeometryOutputComponents{}, maxGeometryTotalOutputComponents{}, maxAtomicCounterBuffers{}, maxCombinedAtomicCounterBuffers{}, maxAtomicCounters{}, maxCombinedAtomicCounters{}, maxImageUniforms{}, maxCombinedImageUniforms{}, maxShaderStorageBlocks{}, maxCombinedShaderStorageBlocks{}, maxTessellationControlInputComponents{}, maxTessellationControlOutputComponents{}, maxTessellationControlTotalOutputComponents{}, maxTessellationEvaluationInputComponents{}, maxTessellationEvaluationOutputComponents{}, maxGeometryInputComponents{}, maxGeometryOutputComponents{}, maxGeometryTotalOutputComponents{}, maxAtomicCounterBuffers{}, maxCombinedAtomicCounterBuffers{}, maxAtomicCounters{}, maxCombinedAtomicCounters{}, maxImageUniforms{}, maxCombinedImageUniforms{}, maxShaderStorageBlocks{}, maxCombinedShaderStorageBlocks{},
@ -68,9 +69,12 @@ ShaderState::ShaderState(Context& context, Containers::StaticArrayView<Implement
cleanLogImplementation = &Shader::cleanLogImplementationNoOp; cleanLogImplementation = &Shader::cleanLogImplementationNoOp;
} }
/* Needed only if neither of these ifdefs above hits, but I won't bother if(context.isExtensionSupported<GL::Extensions::KHR::parallel_shader_compile>()) {
crafting the preprocessor logic for this. */ extensions[Extensions::KHR::parallel_shader_compile::Index] = Extensions::KHR::parallel_shader_compile::string();
static_cast<void>(context); completionStatusImplementation = glGetShaderiv;
} else {
completionStatusImplementation = &Shader::completionStatusImplementationFallback;
}
} }
}}} }}}

1
src/Magnum/GL/Implementation/ShaderState.h

@ -53,6 +53,7 @@ struct ShaderState {
void(Shader::*addSourceImplementation)(std::string); void(Shader::*addSourceImplementation)(std::string);
void(*cleanLogImplementation)(std::string&); void(*cleanLogImplementation)(std::string&);
void(*completionStatusImplementation)(GLuint, GLenum, GLint* value);
GLint maxVertexOutputComponents, GLint maxVertexOutputComponents,
maxFragmentInputComponents; maxFragmentInputComponents;

16
src/Magnum/GL/Shader.cpp

@ -782,19 +782,17 @@ bool Shader::checkCompile() { /* After compilation phase, check status of all sh
be said, handle that as well. */ be said, handle that as well. */
Context::current().state().shader.cleanLogImplementation(message); Context::current().state().shader.cleanLogImplementation(message);
/** @todo update log messages */
/* Show error log */ /* Show error log */
if(!success) { if(!success) {
Error out{Debug::Flag::NoNewlineAtTheEnd}; Error out{Debug::Flag::NoNewlineAtTheEnd};
out << "GL::Shader::compile(): compilation of" << shaderName(_type) << "shader"; out << "GL::Shader::compile(): compilation of" << shaderName(_type) << "shader"
out << "failed with the following message:" << Debug::newline << message; << "failed with the following message:" << Debug::newline << message;
/* Or just warnings, if any */ /* Or just warnings, if any */
} else if(!message.empty()) { } else if(!message.empty()) {
Warning out{Debug::Flag::NoNewlineAtTheEnd}; Warning out{Debug::Flag::NoNewlineAtTheEnd};
out << "GL::Shader::compile(): compilation of" << shaderName(_type) << "shader"; out << "GL::Shader::compile(): compilation of" << shaderName(_type) << "shader"
out << "succeeded with the following message:" << Debug::newline << message; << "succeeded with the following message:" << Debug::newline << message;
} }
return success; return success;
@ -810,7 +808,7 @@ bool Shader::compile(std::initializer_list<Containers::Reference<Shader>> shader
bool Shader::isCompileFinished() { bool Shader::isCompileFinished() {
GLint success; GLint success;
glGetShaderiv(_id, GL_COMPLETION_STATUS_KHR, &success); Context::current().state().shader.completionStatusImplementation(_id, GL_COMPLETION_STATUS_KHR, &success);
return success == GL_TRUE; return success == GL_TRUE;
} }
@ -822,6 +820,10 @@ void Shader::cleanLogImplementationIntelWindows(std::string& message) {
} }
#endif #endif
void Shader::completionStatusImplementationFallback(GLuint, GLenum, GLint* value) {
*value = GL_TRUE;
}
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
Debug& operator<<(Debug& debug, const Shader::Type value) { Debug& operator<<(Debug& debug, const Shader::Type value) {
debug << "GL::Shader::Type" << Debug::nospace; debug << "GL::Shader::Type" << Debug::nospace;

2
src/Magnum/GL/Shader.h

@ -676,6 +676,8 @@ class MAGNUM_GL_EXPORT Shader: public AbstractObject {
static MAGNUM_GL_LOCAL void cleanLogImplementationIntelWindows(std::string& message); static MAGNUM_GL_LOCAL void cleanLogImplementationIntelWindows(std::string& message);
#endif #endif
static MAGNUM_GL_LOCAL void completionStatusImplementationFallback(GLuint, GLenum, GLint*);
Type _type; Type _type;
GLuint _id; GLuint _id;

21
src/Magnum/Shaders/FlatGL.cpp

@ -208,33 +208,33 @@ template<UnsignedInt dimensions> typename FlatGL<dimensions>::CompileState FlatG
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_attrib_location>(version)) if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_attrib_location>(version))
#endif #endif
{ {
cs.bindAttributeLocation(Position::Location, "position"); out.bindAttributeLocation(Position::Location, "position");
if(flags & Flag::Textured if(flags & Flag::Textured
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
|| flags >= Flag::ObjectIdTexture || flags >= Flag::ObjectIdTexture
#endif #endif
) )
cs.bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates"); out.bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
if(flags & Flag::VertexColor) if(flags & Flag::VertexColor)
cs.bindAttributeLocation(Color3::Location, "vertexColor"); /* Color4 is the same */ out.bindAttributeLocation(Color3::Location, "vertexColor"); /* Color4 is the same */
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
if(flags & Flag::ObjectId) { if(flags & Flag::ObjectId) {
cs.bindFragmentDataLocation(ColorOutput, "color"); out.bindFragmentDataLocation(ColorOutput, "color");
cs.bindFragmentDataLocation(ObjectIdOutput, "objectId"); out.bindFragmentDataLocation(ObjectIdOutput, "objectId");
} }
if(flags >= Flag::InstancedObjectId) if(flags >= Flag::InstancedObjectId)
cs.bindAttributeLocation(ObjectId::Location, "instanceObjectId"); out.bindAttributeLocation(ObjectId::Location, "instanceObjectId");
#endif #endif
if(flags & Flag::InstancedTransformation) if(flags & Flag::InstancedTransformation)
cs.bindAttributeLocation(TransformationMatrix::Location, "instancedTransformationMatrix"); out.bindAttributeLocation(TransformationMatrix::Location, "instancedTransformationMatrix");
if(flags >= Flag::InstancedTextureOffset) if(flags >= Flag::InstancedTextureOffset)
cs.bindAttributeLocation(TextureOffset::Location, "instancedTextureOffset"); out.bindAttributeLocation(TextureOffset::Location, "instancedTextureOffset");
} }
#endif #endif
out.submitLink(); out.submitLink();
return CompileState{std::move(out), std::move()}; return CompileState{std::move(out), std::move(vert), std::move(frag), version};
} }
template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(CompileState&& cs) template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(CompileState&& cs)
@ -305,6 +305,9 @@ template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(CompileState&& cs)
/* Object ID is zero by default */ /* Object ID is zero by default */
} }
#endif #endif
static_cast<void>(version);
static_cast<void>(context);
} }
template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(Flags flags template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(Flags flags

10
src/Magnum/Shaders/FlatGL.h

@ -603,7 +603,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT FlatGL: public GL::
*/ */
explicit FlatGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {} explicit FlatGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {}
struct CompileState; class CompileState;
explicit FlatGL(CompileState&& cs); explicit FlatGL(CompileState&& cs);
@ -1053,14 +1053,16 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT FlatGL: public GL::
}; };
template<UnsignedInt dimensions> class FlatGL<dimensions>::CompileState : public FlatGL<dimensions> { template<UnsignedInt dimensions> class FlatGL<dimensions>::CompileState : public FlatGL<dimensions> {
public:
using FlatGL::isLinkFinished;
private: private:
friend class FlatGL; friend class FlatGL;
using FlatGL::isLinkFinished;
CompileState(NoCreateT) : FlatGL(NoCreate), _vert{NoCreate}, _frag{NoCreate} {} CompileState(NoCreateT) : FlatGL(NoCreate), _vert{NoCreate}, _frag{NoCreate} {}
CompileState(FlatGL<dimensions>&& shader, GL:Shader&& vert, GL::Shader&& frag, GL::Version version) : CompileState(FlatGL<dimensions>&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version) :
FlatGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {} FlatGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
GL::Shader _vert, _frag; GL::Shader _vert, _frag;
GL::Version _version; GL::Version _version;

Loading…
Cancel
Save