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
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

21
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<Containers::Reference<Abs
glGetProgramiv(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, '\n');
if(message.size() > 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<Containers::Reference<Abs
out << "failed with the following message:" << Debug::newline << message;
/* Or just warnings, if any */
} else if(!message.empty() && !Implementation::isProgramLinkLogEmpty(message)) {
} else if(!message.empty()) {
Warning out{Debug::Flag::NoNewlineAtTheEnd};
out << "GL::AbstractShaderProgram::link(): linking";
if(shaders.size() != 1) out << "of shader" << i;
@ -537,6 +536,14 @@ bool AbstractShaderProgram::link(std::initializer_list<Containers::Reference<Abs
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) {
const GLint location = glGetUniformLocation(_id, name);
if(location == -1)

5
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();
/*

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

@ -60,6 +60,15 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string
}
#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)
#ifndef MAGNUM_TARGET_GLES
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
void(AbstractShaderProgram::*transformFeedbackVaryingsImplementation)(Containers::ArrayView<const std::string>, AbstractShaderProgram::TransformFeedbackBufferMode);
#endif
void(*cleanLogImplementation)(std::string&);
void(AbstractShaderProgram::*uniform1fvImplementation)(GLint, GLsizei, const 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 "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<std::string>&):
addSourceImplementation = &Shader::addSourceImplementationDefault;
}
#if !defined(CORRADE_TARGET_EMSCRIPTEN) || !defined(__EMSCRIPTEN_PTHREADS__)
static_cast<void>(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<void>(context);
}
}}}

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

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

36
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<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 {
if(_detectedDrivers) return *_detectedDrivers;

21
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<Containers::Reference<Shader>> 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<Containers::Reference<Shader>> 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<Containers::Reference<Shader>> 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;

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);
#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;

Loading…
Cancel
Save