Browse Source

GL: advertise the "intel-windows-chatty-shader-compiler" workaround.

This was done silently until now and I think such platform-specific code
should be always exposed as a disableable workaround. Moreover, I need a
similar thing for ANGLE, so this comes handy.
pull/495/head
Vladimír Vondruš 5 years ago
parent
commit
d0574b83ed
  1. 4
      doc/changelog.dox
  2. 21
      src/Magnum/GL/AbstractShaderProgram.cpp
  3. 5
      src/Magnum/GL/AbstractShaderProgram.h
  4. 9
      src/Magnum/GL/Implementation/ShaderProgramState.cpp
  5. 1
      src/Magnum/GL/Implementation/ShaderProgramState.h
  6. 20
      src/Magnum/GL/Implementation/ShaderState.cpp
  7. 1
      src/Magnum/GL/Implementation/ShaderState.h
  8. 36
      src/Magnum/GL/Implementation/driverSpecific.cpp
  9. 21
      src/Magnum/GL/Shader.cpp
  10. 5
      src/Magnum/GL/Shader.h

4
doc/changelog.dox

@ -175,6 +175,10 @@ See also:
- Added @ref GL::Framebuffer::Status::IncompleteDimensions for ES2. This enum - 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 isn't available on ES3 or desktop GL, but NVidia drivers are known to emit
it, which is why it got added. 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 @subsubsection changelog-latest-changes-math Math library

21
src/Magnum/GL/AbstractShaderProgram.cpp

@ -46,11 +46,6 @@
namespace Magnum { namespace GL { namespace Magnum { namespace GL {
namespace Implementation {
/* Defined in Implementation/driverSpecific.cpp */
bool isProgramLinkLogEmpty(const std::string& result);
}
Int AbstractShaderProgram::maxVertexAttributes() { Int AbstractShaderProgram::maxVertexAttributes() {
GLint& value = Context::current().state().shaderProgram->maxVertexAttributes; GLint& value = Context::current().state().shaderProgram->maxVertexAttributes;
@ -508,12 +503,16 @@ bool AbstractShaderProgram::link(std::initializer_list<Containers::Reference<Abs
glGetProgramiv(shader._id, GL_INFO_LOG_LENGTH, &logLength); glGetProgramiv(shader._id, GL_INFO_LOG_LENGTH, &logLength);
/* Error or warning message. The string is returned null-terminated, /* 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, '\n'); std::string message(logLength, '\n');
if(message.size() > 1) if(message.size() > 1)
glGetProgramInfoLog(shader._id, message.size(), nullptr, &message[0]); glGetProgramInfoLog(shader._id, message.size(), nullptr, &message[0]);
message.resize(Math::max(logLength, 1)-1); 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 */ /* Show error log */
if(!success) { if(!success) {
Error out{Debug::Flag::NoNewlineAtTheEnd}; Error out{Debug::Flag::NoNewlineAtTheEnd};
@ -522,7 +521,7 @@ bool AbstractShaderProgram::link(std::initializer_list<Containers::Reference<Abs
out << "failed with the following message:" << Debug::newline << message; out << "failed with the following message:" << Debug::newline << message;
/* Or just warnings, if any */ /* Or just warnings, if any */
} else if(!message.empty() && !Implementation::isProgramLinkLogEmpty(message)) { } else if(!message.empty()) {
Warning out{Debug::Flag::NoNewlineAtTheEnd}; Warning out{Debug::Flag::NoNewlineAtTheEnd};
out << "GL::AbstractShaderProgram::link(): linking"; out << "GL::AbstractShaderProgram::link(): linking";
if(shaders.size() != 1) out << "of shader" << i; if(shaders.size() != 1) out << "of shader" << i;
@ -537,6 +536,14 @@ bool AbstractShaderProgram::link(std::initializer_list<Containers::Reference<Abs
return allSuccess; return allSuccess;
} }
void AbstractShaderProgram::cleanLogImplementationNoOp(std::string&) {}
#if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES)
void AbstractShaderProgram::cleanLogImplementationIntelWindows(std::string& message) {
if(message == "No errors.\n") message = {};
}
#endif
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)

5
src/Magnum/GL/AbstractShaderProgram.h

@ -1347,6 +1347,11 @@ class MAGNUM_GL_EXPORT AbstractShaderProgram: public AbstractObject {
#endif #endif
#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(); void use();
/* /*

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

@ -60,6 +60,15 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string
} }
#endif #endif
#if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES)
if((context.detectedDriver() & Context::DetectedDriver::IntelWindows) && !context.isDriverWorkaroundDisabled("intel-windows-chatty-shader-compiler")) {
cleanLogImplementation = &AbstractShaderProgram::cleanLogImplementationIntelWindows;
} else
#endif
{
cleanLogImplementation = &AbstractShaderProgram::cleanLogImplementationNoOp;
}
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::separate_shader_objects>()) if(context.isExtensionSupported<Extensions::ARB::separate_shader_objects>())

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

@ -46,6 +46,7 @@ struct ShaderProgramState {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
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(AbstractShaderProgram::*uniform1fvImplementation)(GLint, GLsizei, const GLfloat*); void(AbstractShaderProgram::*uniform1fvImplementation)(GLint, GLsizei, const GLfloat*);
void(AbstractShaderProgram::*uniform2fvImplementation)(GLint, GLsizei, const Math::Vector<2, GLfloat>*); void(AbstractShaderProgram::*uniform2fvImplementation)(GLint, GLsizei, const Math::Vector<2, GLfloat>*);

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

@ -25,11 +25,10 @@
#include "ShaderState.h" #include "ShaderState.h"
#include "Magnum/GL/Shader.h" /* Needed only for Emscripten+pthread- / Windows+Intel-specific workarounds,
but I won't bother crafting the preprocessor logic for this. */
#if defined(CORRADE_TARGET_EMSCRIPTEN) && defined(__EMSCRIPTEN_PTHREADS__)
#include "Magnum/GL/Context.h" #include "Magnum/GL/Context.h"
#endif #include "Magnum/GL/Shader.h"
namespace Magnum { namespace GL { namespace Implementation { namespace Magnum { namespace GL { namespace Implementation {
@ -56,9 +55,18 @@ ShaderState::ShaderState(Context& context, std::vector<std::string>&):
addSourceImplementation = &Shader::addSourceImplementationDefault; addSourceImplementation = &Shader::addSourceImplementationDefault;
} }
#if !defined(CORRADE_TARGET_EMSCRIPTEN) || !defined(__EMSCRIPTEN_PTHREADS__) #if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES)
static_cast<void>(context); if((context.detectedDriver() & Context::DetectedDriver::IntelWindows) && !context.isDriverWorkaroundDisabled("intel-windows-chatty-shader-compiler")) {
cleanLogImplementation = &Shader::cleanLogImplementationIntelWindows;
} else
#endif #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<void>(context);
} }
}}} }}}

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

@ -52,6 +52,7 @@ struct ShaderState {
}; };
void(Shader::*addSourceImplementation)(std::string); void(Shader::*addSourceImplementation)(std::string);
void(*cleanLogImplementation)(std::string&);
GLint maxVertexOutputComponents, GLint maxVertexOutputComponents,
maxFragmentInputComponents; maxFragmentInputComponents;

36
src/Magnum/GL/Implementation/driverSpecific.cpp

@ -336,6 +336,10 @@ const char* KnownWorkarounds[]{
MeshGLTest::addVertexBufferIntWithShort(). */ MeshGLTest::addVertexBufferIntWithShort(). */
"intel-windows-broken-dsa-integer-vertex-attributes", "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, /* When using more than just a vertex and fragment shader (geometry shader,
e.g.), ARB_explicit_uniform_location on Intel silently uses wrong e.g.), ARB_explicit_uniform_location on Intel silently uses wrong
locations, blowing up with either a non-descript 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<void>(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<void>(result);
#endif
return false;
}
}
auto Context::detectedDriver() -> DetectedDrivers { auto Context::detectedDriver() -> DetectedDrivers {
if(_detectedDrivers) return *_detectedDrivers; if(_detectedDrivers) return *_detectedDrivers;

21
src/Magnum/GL/Shader.cpp

@ -48,11 +48,6 @@ typedef char GLchar;
namespace Magnum { namespace GL { namespace Magnum { namespace GL {
namespace Implementation {
/* defined in Implementation/driverSpecific.cpp */
bool isShaderCompilationLogEmpty(const std::string& result);
}
namespace { namespace {
std::string shaderName(const Shader::Type type) { std::string shaderName(const Shader::Type type) {
@ -786,12 +781,16 @@ bool Shader::compile(std::initializer_list<Containers::Reference<Shader>> shader
glGetShaderiv(shader._id, GL_INFO_LOG_LENGTH, &logLength); glGetShaderiv(shader._id, GL_INFO_LOG_LENGTH, &logLength);
/* Error or warning message. The string is returned null-terminated, /* 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'); std::string message(logLength, '\0');
if(message.size() > 1) if(message.size() > 1)
glGetShaderInfoLog(shader._id, message.size(), nullptr, &message[0]); glGetShaderInfoLog(shader._id, message.size(), nullptr, &message[0]);
message.resize(Math::max(logLength, 1)-1); 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 */ /* Show error log */
if(!success) { if(!success) {
Error out{Debug::Flag::NoNewlineAtTheEnd}; Error out{Debug::Flag::NoNewlineAtTheEnd};
@ -800,7 +799,7 @@ bool Shader::compile(std::initializer_list<Containers::Reference<Shader>> shader
out << "failed with the following message:" << Debug::newline << message; out << "failed with the following message:" << Debug::newline << message;
/* Or just warnings, if any */ /* Or just warnings, if any */
} else if(!message.empty() && !Implementation::isShaderCompilationLogEmpty(message)) { } else if(!message.empty()) {
Warning out{Debug::Flag::NoNewlineAtTheEnd}; Warning out{Debug::Flag::NoNewlineAtTheEnd};
out << "GL::Shader::compile(): compilation of" << shaderName(shader._type) << "shader"; out << "GL::Shader::compile(): compilation of" << shaderName(shader._type) << "shader";
if(shaders.size() != 1) out << i; if(shaders.size() != 1) out << i;
@ -815,6 +814,14 @@ bool Shader::compile(std::initializer_list<Containers::Reference<Shader>> shader
return allSuccess; 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 #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;

5
src/Magnum/GL/Shader.h

@ -652,6 +652,11 @@ class MAGNUM_GL_EXPORT Shader: public AbstractObject {
void MAGNUM_GL_LOCAL addSourceImplementationEmscriptenPthread(std::string source); void MAGNUM_GL_LOCAL addSourceImplementationEmscriptenPthread(std::string source);
#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
Type _type; Type _type;
GLuint _id; GLuint _id;

Loading…
Cancel
Save