From 05d49d666eeb75e49f0668b17eeded3401df639b Mon Sep 17 00:00:00 2001 From: Vladislav Oleshko Date: Wed, 27 Jul 2022 11:28:02 +0300 Subject: [PATCH] Implement completion status fallback & fixes --- src/Magnum/GL/AbstractShaderProgram.cpp | 16 +++++++------- src/Magnum/GL/AbstractShaderProgram.h | 2 ++ .../GL/Implementation/ShaderProgramState.cpp | 7 +++++++ .../GL/Implementation/ShaderProgramState.h | 1 + src/Magnum/GL/Implementation/ShaderState.cpp | 12 +++++++---- src/Magnum/GL/Implementation/ShaderState.h | 1 + src/Magnum/GL/Shader.cpp | 16 +++++++------- src/Magnum/GL/Shader.h | 2 ++ src/Magnum/Shaders/FlatGL.cpp | 21 +++++++++++-------- src/Magnum/Shaders/FlatGL.h | 10 +++++---- 10 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/Magnum/GL/AbstractShaderProgram.cpp b/src/Magnum/GL/AbstractShaderProgram.cpp index a246694d5..c551d876b 100644 --- a/src/Magnum/GL/AbstractShaderProgram.cpp +++ b/src/Magnum/GL/AbstractShaderProgram.cpp @@ -605,19 +605,17 @@ bool AbstractShaderProgram::checkLink() { be said, handle that as well. */ Context::current().state().shaderProgram.cleanLogImplementation(message); - /** @todo update log messages */ - /* Show error log */ if(!success) { Error out{Debug::Flag::NoNewlineAtTheEnd}; - out << "GL::AbstractShaderProgram::link(): linking"; - out << "failed with the following message:" << Debug::newline << message; + out << "GL::AbstractShaderProgram::link(): linking failed with the following message:" + << Debug::newline << message; /* Or just warnings, if any */ } else if(!message.empty()) { Warning out{Debug::Flag::NoNewlineAtTheEnd}; - out << "GL::AbstractShaderProgram::link(): linking"; - out << "succeeded with the following message:" << Debug::newline << message; + out << "GL::AbstractShaderProgram::link(): linking succeeded with the following message:" + << Debug::newline << message; } return success; @@ -632,7 +630,7 @@ bool AbstractShaderProgram::link(std::initializer_list name) { const GLint location = glGetUniformLocation(_id, name); if(location == -1) diff --git a/src/Magnum/GL/AbstractShaderProgram.h b/src/Magnum/GL/AbstractShaderProgram.h index 48d1b2b17..b6319cef8 100644 --- a/src/Magnum/GL/AbstractShaderProgram.h +++ b/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); #endif + static MAGNUM_GL_LOCAL void completionStatusImplementationFallback(GLuint, GLenum, GLint*); + MAGNUM_GL_LOCAL static void use(GLuint id); void use(); diff --git a/src/Magnum/GL/Implementation/ShaderProgramState.cpp b/src/Magnum/GL/Implementation/ShaderProgramState.cpp index 1e3125560..9799fc087 100644 --- a/src/Magnum/GL/Implementation/ShaderProgramState.cpp +++ b/src/Magnum/GL/Implementation/ShaderProgramState.cpp @@ -78,6 +78,13 @@ ShaderProgramState::ShaderProgramState(Context& context, Containers::StaticArray cleanLogImplementation = &AbstractShaderProgram::cleanLogImplementationNoOp; } + if(context.isExtensionSupported()) { + 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_GLES2 #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/GL/Implementation/ShaderProgramState.h b/src/Magnum/GL/Implementation/ShaderProgramState.h index 01f131b8f..e057e5aad 100644 --- a/src/Magnum/GL/Implementation/ShaderProgramState.h +++ b/src/Magnum/GL/Implementation/ShaderProgramState.h @@ -47,6 +47,7 @@ struct ShaderProgramState { void(AbstractShaderProgram::*transformFeedbackVaryingsImplementation)(Containers::ArrayView, AbstractShaderProgram::TransformFeedbackBufferMode); #endif void(*cleanLogImplementation)(std::string&); + void(*completionStatusImplementation)(GLuint, GLenum, GLint* value); #ifndef MAGNUM_TARGET_WEBGL void(APIENTRY *uniform1fvImplementation)(GLuint, GLint, GLsizei, const GLfloat*); diff --git a/src/Magnum/GL/Implementation/ShaderState.cpp b/src/Magnum/GL/Implementation/ShaderState.cpp index ffc0c2f1e..17758a801 100644 --- a/src/Magnum/GL/Implementation/ShaderState.cpp +++ b/src/Magnum/GL/Implementation/ShaderState.cpp @@ -31,12 +31,13 @@ #include "Magnum/GL/Context.h" #include "Magnum/GL/Shader.h" +#include "Magnum/GL/Extensions.h" namespace Magnum { namespace GL { namespace Implementation { using namespace Containers::Literals; -ShaderState::ShaderState(Context& context, Containers::StaticArrayView): +ShaderState::ShaderState(Context& context, Containers::StaticArrayView extensions): maxVertexOutputComponents{}, maxFragmentInputComponents{}, #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{}, @@ -68,9 +69,12 @@ ShaderState::ShaderState(Context& context, Containers::StaticArrayView(context); + if(context.isExtensionSupported()) { + extensions[Extensions::KHR::parallel_shader_compile::Index] = Extensions::KHR::parallel_shader_compile::string(); + completionStatusImplementation = glGetShaderiv; + } else { + completionStatusImplementation = &Shader::completionStatusImplementationFallback; + } } }}} diff --git a/src/Magnum/GL/Implementation/ShaderState.h b/src/Magnum/GL/Implementation/ShaderState.h index 3eef9f0b5..caddd741d 100644 --- a/src/Magnum/GL/Implementation/ShaderState.h +++ b/src/Magnum/GL/Implementation/ShaderState.h @@ -53,6 +53,7 @@ struct ShaderState { void(Shader::*addSourceImplementation)(std::string); void(*cleanLogImplementation)(std::string&); + void(*completionStatusImplementation)(GLuint, GLenum, GLint* value); GLint maxVertexOutputComponents, maxFragmentInputComponents; diff --git a/src/Magnum/GL/Shader.cpp b/src/Magnum/GL/Shader.cpp index b4bcf94ee..8b7bbb98b 100644 --- a/src/Magnum/GL/Shader.cpp +++ b/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. */ Context::current().state().shader.cleanLogImplementation(message); - /** @todo update log messages */ - /* Show error log */ if(!success) { Error out{Debug::Flag::NoNewlineAtTheEnd}; - out << "GL::Shader::compile(): compilation of" << shaderName(_type) << "shader"; - out << "failed with the following message:" << Debug::newline << message; + out << "GL::Shader::compile(): compilation of" << shaderName(_type) << "shader" + << "failed with the following message:" << Debug::newline << message; /* Or just warnings, if any */ } else if(!message.empty()) { Warning out{Debug::Flag::NoNewlineAtTheEnd}; - out << "GL::Shader::compile(): compilation of" << shaderName(_type) << "shader"; - out << "succeeded with the following message:" << Debug::newline << message; + out << "GL::Shader::compile(): compilation of" << shaderName(_type) << "shader" + << "succeeded with the following message:" << Debug::newline << message; } return success; @@ -810,7 +808,7 @@ bool Shader::compile(std::initializer_list> shader bool Shader::isCompileFinished() { GLint success; - glGetShaderiv(_id, GL_COMPLETION_STATUS_KHR, &success); + Context::current().state().shader.completionStatusImplementation(_id, GL_COMPLETION_STATUS_KHR, &success); return success == GL_TRUE; } @@ -822,6 +820,10 @@ void Shader::cleanLogImplementationIntelWindows(std::string& message) { } #endif +void Shader::completionStatusImplementationFallback(GLuint, GLenum, GLint* value) { + *value = GL_TRUE; +} + #ifndef DOXYGEN_GENERATING_OUTPUT Debug& operator<<(Debug& debug, const Shader::Type value) { debug << "GL::Shader::Type" << Debug::nospace; diff --git a/src/Magnum/GL/Shader.h b/src/Magnum/GL/Shader.h index af7065c76..ccc3105db 100644 --- a/src/Magnum/GL/Shader.h +++ b/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); #endif + static MAGNUM_GL_LOCAL void completionStatusImplementationFallback(GLuint, GLenum, GLint*); + Type _type; GLuint _id; diff --git a/src/Magnum/Shaders/FlatGL.cpp b/src/Magnum/Shaders/FlatGL.cpp index 91a052fd1..6fdfdbcd2 100644 --- a/src/Magnum/Shaders/FlatGL.cpp +++ b/src/Magnum/Shaders/FlatGL.cpp @@ -208,33 +208,33 @@ template typename FlatGL::CompileState FlatG if(!context.isExtensionSupported(version)) #endif { - cs.bindAttributeLocation(Position::Location, "position"); + out.bindAttributeLocation(Position::Location, "position"); if(flags & Flag::Textured #ifndef MAGNUM_TARGET_GLES2 || flags >= Flag::ObjectIdTexture #endif ) - cs.bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates"); + out.bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates"); 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 if(flags & Flag::ObjectId) { - cs.bindFragmentDataLocation(ColorOutput, "color"); - cs.bindFragmentDataLocation(ObjectIdOutput, "objectId"); + out.bindFragmentDataLocation(ColorOutput, "color"); + out.bindFragmentDataLocation(ObjectIdOutput, "objectId"); } if(flags >= Flag::InstancedObjectId) - cs.bindAttributeLocation(ObjectId::Location, "instanceObjectId"); + out.bindAttributeLocation(ObjectId::Location, "instanceObjectId"); #endif if(flags & Flag::InstancedTransformation) - cs.bindAttributeLocation(TransformationMatrix::Location, "instancedTransformationMatrix"); + out.bindAttributeLocation(TransformationMatrix::Location, "instancedTransformationMatrix"); if(flags >= Flag::InstancedTextureOffset) - cs.bindAttributeLocation(TextureOffset::Location, "instancedTextureOffset"); + out.bindAttributeLocation(TextureOffset::Location, "instancedTextureOffset"); } #endif out.submitLink(); - return CompileState{std::move(out), std::move()}; + return CompileState{std::move(out), std::move(vert), std::move(frag), version}; } template FlatGL::FlatGL(CompileState&& cs) @@ -305,6 +305,9 @@ template FlatGL::FlatGL(CompileState&& cs) /* Object ID is zero by default */ } #endif + + static_cast(version); + static_cast(context); } template FlatGL::FlatGL(Flags flags diff --git a/src/Magnum/Shaders/FlatGL.h b/src/Magnum/Shaders/FlatGL.h index 2278fa18c..55a14a461 100644 --- a/src/Magnum/Shaders/FlatGL.h +++ b/src/Magnum/Shaders/FlatGL.h @@ -603,7 +603,7 @@ template class MAGNUM_SHADERS_EXPORT FlatGL: public GL:: */ explicit FlatGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {} - struct CompileState; + class CompileState; explicit FlatGL(CompileState&& cs); @@ -1053,14 +1053,16 @@ template class MAGNUM_SHADERS_EXPORT FlatGL: public GL:: }; template class FlatGL::CompileState : public FlatGL { +public: + using FlatGL::isLinkFinished; + private: friend class FlatGL; - using FlatGL::isLinkFinished; CompileState(NoCreateT) : FlatGL(NoCreate), _vert{NoCreate}, _frag{NoCreate} {} - CompileState(FlatGL&& shader, GL:Shader&& vert, GL::Shader&& frag, GL::Version version) : - FlatGL{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {} + CompileState(FlatGL&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version) : + FlatGL{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {} GL::Shader _vert, _frag; GL::Version _version;