Browse Source

GL: unindent the workaround list so it shows better in the docs.

pull/331/head
Vladimír Vondruš 7 years ago
parent
commit
689fbe7f35
  1. 432
      src/Magnum/GL/Implementation/driverSpecific.cpp

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

@ -34,228 +34,216 @@ namespace Magnum { namespace GL {
namespace { namespace {
/* Search the code for the following strings to see where they are implemented. */ /* Search the code for the following strings to see where they are implemented. */
std::vector<std::string> KnownWorkarounds{ std::vector<std::string> KnownWorkarounds{
/* [workarounds] */ /* [workarounds] */
#if !defined(MAGNUM_TARGET_GLES) && !defined(CORRADE_TARGET_APPLE) #if !defined(MAGNUM_TARGET_GLES) && !defined(CORRADE_TARGET_APPLE)
/* Creating core context with specific version on AMD and NV /* Creating core context with specific version on AMD and NV proprietary
proprietary drivers on Linux/Windows and Intel drivers on Windows drivers on Linux/Windows and Intel drivers on Windows causes the context to
causes the context to be forced to given version instead of be forced to given version instead of selecting latest available version */
selecting latest available version */ "no-forward-compatible-core-context",
"no-forward-compatible-core-context", #endif
#endif
#if !defined(MAGNUM_TARGET_GLES) && defined(CORRADE_TARGET_WINDOWS)
#if !defined(MAGNUM_TARGET_GLES) && defined(CORRADE_TARGET_WINDOWS) /* On Windows Intel drivers ARB_shading_language_420pack is exposed in GLSL
/* On Windows Intel drivers ARB_shading_language_420pack is exposed in even though the extension (e.g. binding keyword) is not supported */
GLSL even though the extension (e.g. binding keyword) is not "intel-windows-glsl-exposes-unsupported-shading-language-420pack",
supported */ #endif
"intel-windows-glsl-exposes-unsupported-shading-language-420pack",
#endif #ifndef MAGNUM_TARGET_GLES
/* Forward-compatible GL contexts on Mesa still report line width range as
#ifndef MAGNUM_TARGET_GLES [1, 7], but setting wide line width fails. According to the specs the max
/* Forward-compatible GL contexts on Mesa still report line width range value on forward compatible contexts should be 1.0, so patching it. */
as [1, 7], but setting wide line width fails. According to the specs "mesa-forward-compatible-line-width-range",
the max value on forward compatible contexts should be 1.0, so #endif
patching it. */
"mesa-forward-compatible-line-width-range", #if !defined(MAGNUM_TARGET_GLES2) && defined(CORRADE_TARGET_WINDOWS)
#endif /* On Windows NVidia drivers the glTransformFeedbackVaryings() does not make a
copy of its char* arguments so it fails at link time when the original char
#if !defined(MAGNUM_TARGET_GLES2) && defined(CORRADE_TARGET_WINDOWS) arrays are not in scope anymore. Enabling *synchronous* debug output
/* On Windows NVidia drivers the glTransformFeedbackVaryings() does not circumvents this bug. Can be triggered by running TransformFeedbackGLTest
make a copy of its char* arguments so it fails at link time when the with GL_KHR_debug extension disabled. */
original char arrays are not in scope anymore. Enabling "nv-windows-dangling-transform-feedback-varying-names",
*synchronous* debug output circumvents this bug. Can be triggered by #endif
running TransformFeedbackGLTest with GL_KHR_debug extension
disabled. */ #ifndef MAGNUM_TARGET_GLES
"nv-windows-dangling-transform-feedback-varying-names", /* Layout qualifier causes compiler error with GLSL 1.20 on Mesa, GLSL 1.30 on
#endif NVidia and 1.40 on macOS. Everything is fine when using a newer GLSL
version. */
#ifndef MAGNUM_TARGET_GLES "no-layout-qualifiers-on-old-glsl",
/* Layout qualifier causes compiler error with GLSL 1.20 on Mesa, GLSL
1.30 on NVidia and 1.40 on macOS. Everything is fine when using /* NVidia drivers (358.16) report compressed block size from internal format
newer GLSL version. */ query in bits instead of bytes */
"no-layout-qualifiers-on-old-glsl", "nv-compressed-block-size-in-bits",
/* NVidia drivers (358.16) report compressed block size from internal /* NVidia drivers (358.16) report different compressed image size for cubemaps
format query in bits instead of bytes */ based on whether the texture is immutable or not and not based on whether
"nv-compressed-block-size-in-bits", I'm querying all faces (ARB_DSA) or a single face (non-DSA, EXT_DSA) */
"nv-cubemap-inconsistent-compressed-image-size",
/* NVidia drivers (358.16) report different compressed image size for
cubemaps based on whether the texture is immutable or not and not /* NVidia drivers (358.16) return only the first slice of compressed cube map
based on whether I'm querying all faces (ARB_DSA) or a single face image when querying all six slices using the ARB_DSA API */
(non-DSA, EXT_DSA) */ "nv-cubemap-broken-full-compressed-image-query",
"nv-cubemap-inconsistent-compressed-image-size",
/* NVidia drivers return 0 when asked for GL_CONTEXT_PROFILE_MASK, so it needs
/* NVidia drivers (358.16) return only the first slice of compressed to be worked around by asking for GL_ARB_compatibility */
cube map image when querying all six slice using ARB_DSA API */ "nv-zero-context-profile-mask",
"nv-cubemap-broken-full-compressed-image-query",
/* (Headless) EGL contexts for desktop GL on NVidia 384 and 390 drivers don't
/* NVidia drivers return 0 when asked for GL_CONTEXT_PROFILE_MASK, have correct statically linked GL 1.0 and 1.1 functions (such as
so it needs to be worked around by asking for GL_ARB_compatibility */ glGetString()) and one has to retrieve them explicitly using
"nv-zero-context-profile-mask", eglGetProcAddress(). Doesn't seem to happen on pre-384 and 396, but it's not
possible to get driver version through EGL, so enabling this unconditionally
/* (Headless) EGL contexts for desktop GL on NVidia 384 and 390 drivers on all EGL NV contexts. */
don't have correct statically linked GL 1.0 and 1.1 functions (such "nv-egl-incorrect-gl11-function-pointers",
as glGetString()) and one has to retrieve them explicitly using #endif
eglGetProcAddress(). Doesn't seem to happen on pre-384 and 396, but
it's not possible to get driver version through EGL, so enabling #ifndef MAGNUM_TARGET_GLES
this unconditionally on all EGL NV contexts. */ /* SVGA3D (VMware host GL driver) glDrawArrays() draws nothing when the vertex
"nv-egl-incorrect-gl11-function-pointers", buffer memory is initialized using glNamedBufferData() from ARB_DSA. Using
#endif the non-DSA glBufferData() works. */
"svga3d-broken-dsa-bufferdata",
#ifndef MAGNUM_TARGET_GLES
/* SVGA3D (VMware host GL driver) glDrawArrays() draws nothing when the /* SVGA3D does out-of-bound writes in some cases of glGetTexSubImage(), leading
vertex buffer memory is initialized using glNamedBufferData() from to memory corruption on client machines. That's nasty, so the whole
ARB_DSA. Using the non-DSA glBufferData() works. */ ARB_get_texture_sub_image is disabled. */
"svga3d-broken-dsa-bufferdata", "svga3d-gettexsubimage-oob-write",
#endif
/* SVGA3D does out-of-bound writes in some cases of glGetTexSubImage(),
leading to memory corruption on client machines. That's nasty, so the /* SVGA3D has broken handling of glTex[ture][Sub]Image*D() for 1D arrays, 2D
whole ARB_get_texture_sub_image is disabled. */ arrays, 3D textures and cube map textures where it uploads just the first
"svga3d-gettexsubimage-oob-write", slice in the last dimension. This is only with copies from host memory, not
#endif with buffer images. Seems to be fixed in Mesa 13, but I have no such system
to verify that on.
/* SVGA3D has broken handling of glTex[ture][Sub]Image*D() for 1D https://github.com/mesa3d/mesa/commit/2aa9ff0cda1f6ad97c83d5583fab7a84efabe19e */
arrays, 2D arrays, 3D textures and cube map textures where it "svga3d-texture-upload-slice-by-slice",
uploads just the first slice in the last dimension. This is only
with copies from host memory, not with buffer images. Seems to be #if defined(CORRADE_TARGET_EMSCRIPTEN) && defined(__EMSCRIPTEN_PTHREADS__)
fixed in Mesa 13, but I have no such system to verify that on. /* Shader sources containing UTF-8 characters are converted to empty strings
https://github.com/mesa3d/mesa/commit/2aa9ff0cda1f6ad97c83d5583fab7a84efabe19e */ when running on Emscripten with -s USE_PTHREADS=1. Working around that by
"svga3d-texture-upload-slice-by-slice", replacing all chars > 127 with spaces. Relevant code:
https://github.com/kripken/emscripten/blob/7f89560101843198787530731f40a65288f6f15f/src/fetch-worker.js#L54-L58 */
#if defined(CORRADE_TARGET_EMSCRIPTEN) && defined(__EMSCRIPTEN_PTHREADS__) "emscripten-pthreads-broken-unicode-shader-sources",
/* Shader sources containing UTF-8 characters are converted to empty #endif
strings when running on Emscripten with -s USE_PTHREADS=1. Working
around that by replacing all chars > 127 with spaces. Relevant code: #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
https://github.com/kripken/emscripten/blob/7f89560101843198787530731f40a65288f6f15f/src/fetch-worker.js#L54-L58 */ /* Empty EGL_CONTEXT_FLAGS_KHR cause SwiftShader 3.3.0.1 to fail context
"emscripten-pthreads-broken-unicode-shader-sources", creation with EGL_BAD_ATTRIBUTE. Not sending the flags then. Relevant code:
#endif https://github.com/google/swiftshader/blob/5fb5e817a20d3e60f29f7338493f922b5ac9d7c4/src/OpenGL/libEGL/libEGL.cpp#L794-L810 */
"swiftshader-no-empty-egl-context-flags",
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
/* Empty EGL_CONTEXT_FLAGS_KHR cause SwiftShader 3.3.0.1 to fail /* SwiftShader 3.3.0.1 crashes deep inside eglMakeCurrent() when using
context creation with EGL_BAD_ATTRIBUTE. Not sending the flags then. EGL_NO_SURFACE. Supplying a 32x32 PBuffer to work around that. */
Relevant code: https://github.com/google/swiftshader/blob/5fb5e817a20d3e60f29f7338493f922b5ac9d7c4/src/OpenGL/libEGL/libEGL.cpp#L794-L810 */ "swiftshader-egl-context-needs-pbuffer",
"swiftshader-no-empty-egl-context-flags", #endif
/* SwiftShader 3.3.0.1 crashes deep inside eglMakeCurrent() when using #if defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
EGL_NO_SURFACE. Supplying a 32x32 PBuffer to work around that. */ /* SwiftShader 4.1.0 on ES2 contexts reports GL_ANGLE_instanced_arrays and
"swiftshader-egl-context-needs-pbuffer", GL_EXT_instanced_arrays but has no glDrawArraysInstancedANGLE /
#endif glDrawArraysInstancedEXT nor glDrawElementsInstancedANGLE /
glDrawElementsInstancedEXT entrypoints, only the unsuffixed versions for
#if defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) ES3. OTOH, glVertexAttribDivisor is there for both ANGLE and EXT. Relevant
/* SwiftShader 4.1.0 on ES2 contexts reports GL_ANGLE_instanced_arrays code: https://github.com/google/swiftshader/blob/ad5c2952ca88730c07e04f6f1566194b66860c26/src/OpenGL/libGLESv2/libGLESv2.cpp#L6352-L6357
and GL_EXT_instanced_arrays but has no glDrawArraysInstancedANGLE / Disabling the two extensions on ES2 contexts to avoid nullptr crashes. */
glDrawArraysInstancedEXT nor glDrawElementsInstancedANGLE / "swiftshader-no-es2-draw-instanced-entrypoints",
glDrawElementsInstancedEXT entrypoints, only the unsuffixed versions
for ES3. OTOH, glVertexAttribDivisor is there for both ANGLE and /* SwiftShader 4.1.0 on ES2 contexts reports GL_OES_texture_3D but from all its
EXT. Relevant code: entrypoints only glTexImage3DOES is present, all others are present only in
https://github.com/google/swiftshader/blob/ad5c2952ca88730c07e04f6f1566194b66860c26/src/OpenGL/libGLESv2/libGLESv2.cpp#L6352-L6357 the ES3 unsuffixed versions. Relevant code:
Disabling the two extensions on ES2 contexts to avoid nullptr https://github.com/google/swiftshader/blob/ad5c2952ca88730c07e04f6f1566194b66860c26/src/OpenGL/libGLESv2/libGLESv2.cpp#L6504
crashes. */ Disabling the extension on ES2 contexts to avoid nullptr crashes. */
"swiftshader-no-es2-draw-instanced-entrypoints", "swiftshader-no-es2-oes-texture-3d-entrypoints",
#endif
/* SwiftShader 4.1.0 on ES2 contexts reports GL_OES_texture_3D but from
all its entrypoints only glTexImage3DOES is present, all others are #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
present only in the ES3 unsuffixed versions. Relevant code: /* SwiftShader 4.1.0 has special handling for binding buffers to the transform
https://github.com/google/swiftshader/blob/ad5c2952ca88730c07e04f6f1566194b66860c26/src/OpenGL/libGLESv2/libGLESv2.cpp#L6504 feedback target, requiring an XFB object to be active when a buffer is bound
Disabling the extension on ES2 contexts to avoid nullptr crashes. */ to GL_TRANSFORM_FEEDBACK_BUFFER and ignoring the glBindBuffer() call
"swiftshader-no-es2-oes-texture-3d-entrypoints", otherwise. No other driver does that. As a workaround, setting
#endif Buffer::TargetHint::TransformFeedback will make it use
Buffer::TargetHint::Array instead, as that works okay. */
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) "swiftshader-broken-xfb-buffer-binding-target",
/* SwiftShader 4.1.0 has special handling for binding buffers to the
transform feedback target, requiring an XFB object to be active when /* SwiftShader 4.1.0 does implement gl_VertexID for ES3 contexts, but in
a buffer is bound to GL_TRANSFORM_FEEDBACK_BUFFER and ignoring the practice it doesn't work, returning a constant value. In order to make this
glBindBuffer() call otherwise. No other driver does that. As a easier to check, there's a dummy MAGNUM_shader_vertex_id extension that's
workaround, setting Buffer::TargetHint::TransformFeedback will make defined on all GL 3.0+ and GLES 3.0+ / WebGL 2+ contexts *except* for
it use Buffer::TargetHint::Array instead, as that works okay. */ SwiftShader. */
"swiftshader-broken-xfb-buffer-binding-target", "swiftshader-broken-shader-vertex-id",
#endif
/* SwiftShader 4.1.0 does implement gl_VertexID for ES3 contexts, but
in practice it doesn't work, returning a constant value. In order to #ifndef MAGNUM_TARGET_GLES
make this easier to check, there's a dummy MAGNUM_shader_vertex_id /* Even with the DSA variant, where GL_IMPLEMENTATION_COLOR_READ_* is passed to
extension that's defined on all GL 3.0+ and GLES 3.0+ / WebGL 2+ glGetNamedFramebufferParameter(), Mesa complains that the framebuffer is not
contexts *except* for SwiftShader. */ bound for reading. Relevant code:
"swiftshader-broken-shader-vertex-id", https://github.com/mesa3d/mesa/blob/212c0c630a849e4737e2808a993d708cbb2f18f7/src/mesa/main/framebuffer.c#L841-L843
#endif Workaround is to explicitly bind the framebuffer for reading. */
"mesa-implementation-color-read-format-dsa-explicit-binding",
#ifndef MAGNUM_TARGET_GLES #endif
/* Even with the DSA variant, where GL_IMPLEMENTATION_COLOR_READ_* is
passed to glGetNamedFramebufferParameter(), Mesa complains that the #if !defined(MAGNUM_TARGET_GLES2) && defined(CORRADE_TARGET_WINDOWS)
framebuffer is not bound for reading. Relevant code: /* Intel drivers on Windows return GL_UNSIGNED_BYTE for *both*
https://github.com/mesa3d/mesa/blob/212c0c630a849e4737e2808a993d708cbb2f18f7/src/mesa/main/framebuffer.c#L841-L843 GL_IMPLEMENTATION_COLOR_READ_FORMAT and _TYPE when using either
Workaround is to explicitly bind the framebuffer for reading. */ glGetNamedFramebufferParameter() or glGetFramebufferParameter(),
"mesa-implementation-color-read-format-dsa-explicit-binding", independently on what's the actual framebuffer format. Using glGetInteger()
#endif makes it return GL_RGBA and GL_UNSIGNED_BYTE for RGBA8 framebuffers, and
cause an "Error has been generated. GL error GL_INVALID_OPERATION in
#if !defined(MAGNUM_TARGET_GLES2) && defined(CORRADE_TARGET_WINDOWS) GetIntegerv: (ID: 2576729458) Generic error" when it is not. Since glGetInteger() is actually able to return a correct value in *one
/* Intel drivers on Windows return GL_UNSIGNED_BYTE for *both* circumstance*, it's preferrable to the other random shit the driver is
GL_IMPLEMENTATION_COLOR_READ_FORMAT and _TYPE when using either doing. */
glGetNamedFramebufferParameter() or glGetFramebufferParameter(), "intel-windows-implementation-color-read-format-completely-broken",
independently on what's the actual framebuffer format. Using #endif
glGetInteger() makes it return GL_RGBA and GL_UNSIGNED_BYTE for
RGBA8 framebuffers, and cause a "Error has been generated. GL error #if !defined(MAGNUM_TARGET_GLES) && defined(CORRADE_TARGET_WINDOWS)
GL_INVALID_OPERATION in GetIntegerv: (ID: 2576729458) Generic error" /* Intel drivers on Windows have some synchronization / memory alignment bug in
when it is not. Since glGetInteger() is actually able to return a the DSA glNamedBufferData() when the same buffer is set as an index buffer
correct value in *one circumstance*, it's preferrable to the other to a mesh right after or repeatedly. Calling glBindBuffer() right before or
random shit the driver is doing. */ after the data upload fixes the issue. Note that this workaround is done
"intel-windows-implementation-color-read-format-completely-broken", only for buffers with TargetHint::ElementArray, as the issue was not
#endif observed elsewhere. Reproducible with the 2019.01 ImGui example,
unfortunately I was not able to create a standalone minimal repro case. */
#if !defined(MAGNUM_TARGET_GLES) && defined(CORRADE_TARGET_WINDOWS) "intel-windows-buggy-dsa-bufferdata-for-index-buffers",
/* Intel drivers on Windows have some synchronization / memory
alignment bug in the DSA glNamedBufferData() when the same buffer is /* ARB_direct_state_access implementation on Intel Windows drivers has broken
set as an index buffer to a mesh right after or repeatedly. Calling *everything* related to cube map textures (but not cube map arrays) -- data
glBindBuffer() right before or after the data upload fixes the upload, data queries, framebuffer attachment, framebuffer copies, all
issue. Note that this workaround is done only for buffers with complaining about "Wrong <func> 6 provided for <target> 34067" and similar (GL_TEXTURE_CUBE_MAP is 34067). Using the non-DSA code path as a
TargetHint::ElementArray, as the issue was not observed elsewhere. workaround. */
Reproducible with the 2019.01 ImGui example, unfortunately I was not "intel-windows-broken-dsa-for-cubemaps",
able to create a standalone minimal repro case. */
"intel-windows-buggy-dsa-bufferdata-for-index-buffers", /* DSA glBindTextureUnit() on Intel Windows drivers simply doesn't work when
passing 0 to it. Non-zero IDs work correctly except for cube maps. Using the
/* ARB_direct_state_access implementation on Intel Windows drivers has non-DSA code path for unbinding and cube maps as a workaround. */
broken *everything* related to cube map textures (but not cube map "intel-windows-half-baked-dsa-texture-bind",
arrays) -- data upload, data queries, framebuffer attachment,
framebuffer copies, all complaining about "Wrong <func> 6 provided /* DSA glNamedFramebufferTexture() on Intel Windows drivers doesn't work for
for <target> 34067" (GL_TEXTURE_CUBE_MAP is 34067). Using the layered cube map array attachments. Non-layered or non-array cube map
non-DSA code path as a workaround. */ attachment works. Using the non-DSA code path as a workaround. */
"intel-windows-broken-dsa-for-cubemaps", "intel-windows-broken-dsa-layered-cubemap-array-framebuffer-attachment",
/* DSA glBindTextureUnit() on Intel Windows drivers simply doesn't work /* DSA glClearNamedFramebuffer*() on Intel Windows drivers doesn't do anything.
when passing 0 to it. Non-zero IDs work correctly except for cube Using the non-DSA code path as a workaournd. */
maps. Using the non-DSA code path for unbinding and cube maps as a "intel-windows-broken-dsa-framebuffer-clear",
workaround. */
"intel-windows-half-baked-dsa-texture-bind", /* Using DSA glCreateQueries() on Intel Windows drivers breaks
glBeginQueryIndexed(). Using the non-DSA glGenQueries() instead makes it
/* DSA glNamedFramebufferTexture() on Intel Windows drivers doesn't work properly. See TransformFeedbackGLTest for a test. */
work for layered cube map array attachments. Non-layered or "intel-windows-broken-dsa-indexed-queries",
non-array cube map attachment works. Using the non-DSA code path as
a workaround. */ /* DSA-ified "vertex layout" glVertexArrayAttribIFormat() is broken when
"intel-windows-broken-dsa-layered-cubemap-array-framebuffer-attachment", passing shorts instead of full 32bit ints. Using the old-style
glVertexAttribIPointer() works correctly. No idea if the non-DSA
/* DSA glClearNamedFramebuffer*() on Intel Windows drivers doesn't do glVertexAttribIFormat() works or not. A test that triggers this issue is in
anything. Using the non-DSA code path as a workaournd. */ MeshGLTest::addVertexBufferIntWithShort(). */
"intel-windows-broken-dsa-framebuffer-clear", "intel-windows-broken-dsa-integer-vertex-attributes",
#endif
/* Using DSA glCreateQueries() on Intel Windows drivers breaks
glBeginQueryIndexed(). Using the non-DSA glGenQueries() instead #ifndef MAGNUM_TARGET_GLES
makes it work properly. See TransformFeedbackGLTest for a test. */ /* NVidia seems to be returning values for the default framebuffer when
"intel-windows-broken-dsa-indexed-queries", GL_IMPLEMENTATION_COLOR_READ_FORMAT and _TYPE is queried using
glGetNamedFramebufferParameter(). Using either glGetInteger() or
/* DSA-ified "vertex layout" glVertexArrayAttribIFormat() is broken glGetFramebufferParameter() works correctly. */
when passing shorts instead of full 32bit ints. Using the old-style "nv-implementation-color-read-format-dsa-broken",
glVertexAttribIPointer() works correctly. No idea if the non-DSA #endif
glVertexAttribIFormat() works or not. A test that triggers this /* [workarounds] */
issue is in MeshGLTest::addVertexBufferIntWithShort(). */
"intel-windows-broken-dsa-integer-vertex-attributes",
#endif
#ifndef MAGNUM_TARGET_GLES
/* NVidia seems to be returning values for the default framebuffer when
GL_IMPLEMENTATION_COLOR_READ_FORMAT and _TYPE is queried using
glGetNamedFramebufferParameter(). Using either glGetInteger() or
glGetFramebufferParameter() works correctly. */
"nv-implementation-color-read-format-dsa-broken",
#endif
/* [workarounds] */
}; };
} }

Loading…
Cancel
Save