diff --git a/doc/changelog.dox b/doc/changelog.dox index 5b9765be5..bdf3ca48a 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -175,6 +175,10 @@ See also: - Added @ref GL::Framebuffer::Status::IncompleteDimensions for ES2. This enum isn't available on ES3 or desktop GL, but NVidia drivers are known to emit it, which is why it got added. +- Intel/Windows-specific code for silencing useless shader compiler output is + now advertised as a @cpp "intel-windows-chatty-shader-compiler" @ce + workaround, instead of being done silently. See @ref opengl-workarounds for + more information. @subsubsection changelog-latest-changes-math Math library diff --git a/src/Magnum/GL/AbstractShaderProgram.cpp b/src/Magnum/GL/AbstractShaderProgram.cpp index ee21e77cf..7f306e1c1 100644 --- a/src/Magnum/GL/AbstractShaderProgram.cpp +++ b/src/Magnum/GL/AbstractShaderProgram.cpp @@ -46,11 +46,6 @@ namespace Magnum { namespace GL { -namespace Implementation { - /* Defined in Implementation/driverSpecific.cpp */ - bool isProgramLinkLogEmpty(const std::string& result); -} - Int AbstractShaderProgram::maxVertexAttributes() { GLint& value = Context::current().state().shaderProgram->maxVertexAttributes; @@ -508,12 +503,16 @@ bool AbstractShaderProgram::link(std::initializer_list 1) glGetProgramInfoLog(shader._id, message.size(), nullptr, &message[0]); message.resize(Math::max(logLength, 1)-1); + /* Some drivers are chatty and can't keep shut when there's nothing to + be said, handle that as well. */ + Context::current().state().shaderProgram->cleanLogImplementation(message); + /* Show error log */ if(!success) { Error out{Debug::Flag::NoNewlineAtTheEnd}; @@ -522,7 +521,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 72791a466..6006cb8cc 100644 --- a/src/Magnum/GL/AbstractShaderProgram.h +++ b/src/Magnum/GL/AbstractShaderProgram.h @@ -1347,6 +1347,11 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject { #endif #endif + static MAGNUM_GL_LOCAL void cleanLogImplementationNoOp(std::string& message); + #if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES) + static MAGNUM_GL_LOCAL void cleanLogImplementationIntelWindows(std::string& message); + #endif + void use(); /* diff --git a/src/Magnum/GL/Implementation/ShaderProgramState.cpp b/src/Magnum/GL/Implementation/ShaderProgramState.cpp index 24fe23f34..943f99237 100644 --- a/src/Magnum/GL/Implementation/ShaderProgramState.cpp +++ b/src/Magnum/GL/Implementation/ShaderProgramState.cpp @@ -60,6 +60,15 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector()) diff --git a/src/Magnum/GL/Implementation/ShaderProgramState.h b/src/Magnum/GL/Implementation/ShaderProgramState.h index ea992308e..42e925ef6 100644 --- a/src/Magnum/GL/Implementation/ShaderProgramState.h +++ b/src/Magnum/GL/Implementation/ShaderProgramState.h @@ -46,6 +46,7 @@ struct ShaderProgramState { #ifndef MAGNUM_TARGET_GLES2 void(AbstractShaderProgram::*transformFeedbackVaryingsImplementation)(Containers::ArrayView, AbstractShaderProgram::TransformFeedbackBufferMode); #endif + void(*cleanLogImplementation)(std::string&); void(AbstractShaderProgram::*uniform1fvImplementation)(GLint, GLsizei, const GLfloat*); void(AbstractShaderProgram::*uniform2fvImplementation)(GLint, GLsizei, const Math::Vector<2, GLfloat>*); diff --git a/src/Magnum/GL/Implementation/ShaderState.cpp b/src/Magnum/GL/Implementation/ShaderState.cpp index 7518d702d..8339e5069 100644 --- a/src/Magnum/GL/Implementation/ShaderState.cpp +++ b/src/Magnum/GL/Implementation/ShaderState.cpp @@ -25,11 +25,10 @@ #include "ShaderState.h" -#include "Magnum/GL/Shader.h" - -#if defined(CORRADE_TARGET_EMSCRIPTEN) && defined(__EMSCRIPTEN_PTHREADS__) +/* Needed only for Emscripten+pthread- / Windows+Intel-specific workarounds, + but I won't bother crafting the preprocessor logic for this. */ #include "Magnum/GL/Context.h" -#endif +#include "Magnum/GL/Shader.h" namespace Magnum { namespace GL { namespace Implementation { @@ -56,9 +55,18 @@ ShaderState::ShaderState(Context& context, std::vector&): addSourceImplementation = &Shader::addSourceImplementationDefault; } - #if !defined(CORRADE_TARGET_EMSCRIPTEN) || !defined(__EMSCRIPTEN_PTHREADS__) - static_cast(context); + #if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES) + if((context.detectedDriver() & Context::DetectedDriver::IntelWindows) && !context.isDriverWorkaroundDisabled("intel-windows-chatty-shader-compiler")) { + cleanLogImplementation = &Shader::cleanLogImplementationIntelWindows; + } else #endif + { + cleanLogImplementation = &Shader::cleanLogImplementationNoOp; + } + + /* Needed only if neither of these ifdefs above hits, but I won't bother + crafting the preprocessor logic for this. */ + static_cast(context); } }}} diff --git a/src/Magnum/GL/Implementation/ShaderState.h b/src/Magnum/GL/Implementation/ShaderState.h index 1f367d58f..7dd6fc52a 100644 --- a/src/Magnum/GL/Implementation/ShaderState.h +++ b/src/Magnum/GL/Implementation/ShaderState.h @@ -52,6 +52,7 @@ struct ShaderState { }; void(Shader::*addSourceImplementation)(std::string); + void(*cleanLogImplementation)(std::string&); GLint maxVertexOutputComponents, maxFragmentInputComponents; diff --git a/src/Magnum/GL/Implementation/driverSpecific.cpp b/src/Magnum/GL/Implementation/driverSpecific.cpp index c78065eee..05a76f5eb 100644 --- a/src/Magnum/GL/Implementation/driverSpecific.cpp +++ b/src/Magnum/GL/Implementation/driverSpecific.cpp @@ -336,6 +336,10 @@ const char* KnownWorkarounds[]{ MeshGLTest::addVertexBufferIntWithShort(). */ "intel-windows-broken-dsa-integer-vertex-attributes", +/* Shader compiler on Intel Windows drivers insists on telling me "No errors." + when it should just stay silent. */ +"intel-windows-chatty-shader-compiler", + /* When using more than just a vertex and fragment shader (geometry shader, e.g.), ARB_explicit_uniform_location on Intel silently uses wrong locations, blowing up with either a non-descript @@ -382,38 +386,6 @@ const char* KnownWorkarounds[]{ } -namespace Implementation { - -/* Used in Shader.cpp (duh) */ -bool isShaderCompilationLogEmpty(const std::string&); -bool isShaderCompilationLogEmpty(const std::string& result) { - #if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES) - /* Intel Windows drivers are too chatty */ - if((Context::current().detectedDriver() & Context::DetectedDriver::IntelWindows) && result == "No errors.\n") - return true; - #else - static_cast(result); - #endif - - return false; -} - -/* Used in AbstractShaderProgram.cpp (duh) */ -bool isProgramLinkLogEmpty(const std::string&); -bool isProgramLinkLogEmpty(const std::string& result) { - #if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES) - /* Intel Windows drivers are too chatty */ - if((Context::current().detectedDriver() & Context::DetectedDriver::IntelWindows) && result == "No errors.\n") - return true; - #else - static_cast(result); - #endif - - return false; -} - -} - auto Context::detectedDriver() -> DetectedDrivers { if(_detectedDrivers) return *_detectedDrivers; diff --git a/src/Magnum/GL/Shader.cpp b/src/Magnum/GL/Shader.cpp index 2e1905ef6..046c1905d 100644 --- a/src/Magnum/GL/Shader.cpp +++ b/src/Magnum/GL/Shader.cpp @@ -48,11 +48,6 @@ typedef char GLchar; namespace Magnum { namespace GL { -namespace Implementation { - /* defined in Implementation/driverSpecific.cpp */ - bool isShaderCompilationLogEmpty(const std::string& result); -} - namespace { std::string shaderName(const Shader::Type type) { @@ -786,12 +781,16 @@ bool Shader::compile(std::initializer_list> shader glGetShaderiv(shader._id, GL_INFO_LOG_LENGTH, &logLength); /* Error or warning message. The string is returned null-terminated, - scrap the \0 at the end afterwards */ + strip the \0 at the end afterwards. */ std::string message(logLength, '\0'); if(message.size() > 1) glGetShaderInfoLog(shader._id, message.size(), nullptr, &message[0]); message.resize(Math::max(logLength, 1)-1); + /* Some drivers are chatty and can't keep shut when there's nothing to + be said, handle that as well. */ + Context::current().state().shader->cleanLogImplementation(message); + /* Show error log */ if(!success) { Error out{Debug::Flag::NoNewlineAtTheEnd}; @@ -800,7 +799,7 @@ bool Shader::compile(std::initializer_list> shader out << "failed with the following message:" << Debug::newline << message; /* Or just warnings, if any */ - } else if(!message.empty() && !Implementation::isShaderCompilationLogEmpty(message)) { + } else if(!message.empty()) { Warning out{Debug::Flag::NoNewlineAtTheEnd}; out << "GL::Shader::compile(): compilation of" << shaderName(shader._type) << "shader"; if(shaders.size() != 1) out << i; @@ -815,6 +814,14 @@ bool Shader::compile(std::initializer_list> shader return allSuccess; } +void Shader::cleanLogImplementationNoOp(std::string&) {} + +#if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES) +void Shader::cleanLogImplementationIntelWindows(std::string& message) { + if(message == "No errors.\n") message = {}; +} +#endif + #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 59f37beb1..5ecef0324 100644 --- a/src/Magnum/GL/Shader.h +++ b/src/Magnum/GL/Shader.h @@ -652,6 +652,11 @@ class MAGNUM_GL_EXPORT Shader: public AbstractObject { void MAGNUM_GL_LOCAL addSourceImplementationEmscriptenPthread(std::string source); #endif + static MAGNUM_GL_LOCAL void cleanLogImplementationNoOp(std::string& message); + #if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES) + static MAGNUM_GL_LOCAL void cleanLogImplementationIntelWindows(std::string& message); + #endif + Type _type; GLuint _id;