Browse Source

GL: implement NV_depth_buffer_float.

The GL::Renderer::setClearDepth() and setDepthRange() APIs now use the
non-clamping NV entrypoints if available. The float overloads do that
too, to avoid differences in behavior depending on whether these
functions are called with a float or a double type.
pull/601/head
Vladimír Vondruš 3 years ago
parent
commit
56a850f9ad
  1. 6
      doc/changelog.dox
  2. 4
      doc/opengl-mapping.dox
  3. 4
      doc/opengl-support.dox
  4. 45
      src/Magnum/GL/Implementation/RendererState.cpp
  5. 4
      src/Magnum/GL/Implementation/RendererState.h
  6. 12
      src/Magnum/GL/Renderer.cpp
  7. 41
      src/Magnum/GL/Renderer.h
  8. 8
      src/MagnumExternal/OpenGL/GL/extensions.txt
  9. 4
      src/MagnumExternal/OpenGL/GL/flextGL.cpp
  10. 17
      src/MagnumExternal/OpenGL/GL/flextGL.h
  11. 4
      src/MagnumExternal/OpenGL/GL/flextGLPlatform.cpp

6
doc/changelog.dox

@ -153,7 +153,11 @@ See also:
@relativeref{GL::Renderer,Feature::SampleAlphaToOne}, @relativeref{GL::Renderer,Feature::SampleAlphaToOne},
@relativeref{GL::Renderer,Feature::SampleCoverage} and @relativeref{GL::Renderer,Feature::SampleCoverage} and
@ref GL::Renderer::setSampleCoverage() GL 1.3 APIs @ref GL::Renderer::setSampleCoverage() GL 1.3 APIs
- Exposed missing @ref GL::Renderer::setDepthRange() GL 1.0 API - Using the non-clamping @gl_extension{NV,depth_buffer_float} entrypoints in
@ref GL::Renderer::setClearDepth() and a newly exposed
@ref GL::Renderer::setDepthRange() if the extension is available. See also
[mosra/magnum#543](https://github.com/mosra/magnum/issues/543) and
[mosra/magnum#558](https://github.com/mosra/magnum/issues/558).
- A new @cpp "nv-egl-crashy-query-device-attrib" @ce workaround for a crash - A new @cpp "nv-egl-crashy-query-device-attrib" @ce workaround for a crash
happening during EGL initialization in recent NVidia drivers. See happening during EGL initialization in recent NVidia drivers. See
@ref opengl-workarounds and [mosra/magnum#491](https://github.com/mosra/magnum/pull/491) @ref opengl-workarounds and [mosra/magnum#491](https://github.com/mosra/magnum/pull/491)

4
doc/opengl-mapping.dox

@ -101,7 +101,7 @@ OpenGL function | Matching API
@fn_gl{ClearBufferData}, \n `glClearNamedBufferData()` | | @fn_gl{ClearBufferData}, \n `glClearNamedBufferData()` | |
@fn_gl{ClearBufferSubData}, \n `glClearNamedBufferSubData()` | | @fn_gl{ClearBufferSubData}, \n `glClearNamedBufferSubData()` | |
@fn_gl{ClearColor} | @ref GL::Renderer::setClearColor() @fn_gl{ClearColor} | @ref GL::Renderer::setClearColor()
@fn_gl{ClearDepth} | @ref GL::Renderer::setClearDepth() @fn_gl{ClearDepth}, \n @fn_gl_extension{ClearDepthd,NV,depth_buffer_float} | @ref GL::Renderer::setClearDepth()
@fn_gl{ClearStencil} | @ref GL::Renderer::setClearStencil() @fn_gl{ClearStencil} | @ref GL::Renderer::setClearStencil()
@fn_gl{ClearTexImage} | | @fn_gl{ClearTexImage} | |
@fn_gl{ClearTexSubImage} | | @fn_gl{ClearTexSubImage} | |
@ -131,7 +131,7 @@ OpenGL function | Matching API
@fn_gl{DebugMessageInsert}, \n @fn_gl_extension{InsertEventMarker,EXT,debug_marker}, \n @fn_gl_extension{StringMarker,GREMEDY,string_marker} | @ref GL::DebugMessage::insert() @fn_gl{DebugMessageInsert}, \n @fn_gl_extension{InsertEventMarker,EXT,debug_marker}, \n @fn_gl_extension{StringMarker,GREMEDY,string_marker} | @ref GL::DebugMessage::insert()
@fn_gl{DepthFunc} | @ref GL::Renderer::setDepthFunction() @fn_gl{DepthFunc} | @ref GL::Renderer::setDepthFunction()
@fn_gl{DepthMask} | @ref GL::Renderer::setDepthMask() @fn_gl{DepthMask} | @ref GL::Renderer::setDepthMask()
@fn_gl{DepthRange} | @ref GL::Renderer::setDepthRange() @fn_gl{DepthRange}, \n @fn_gl_extension_keyword{DepthRanged,NV,depth_buffer_float} | @ref GL::Renderer::setDepthRange()
@fn_gl{DepthRangeArray} | | @fn_gl{DepthRangeArray} | |
@fn_gl{DepthRangeIndexed} | | @fn_gl{DepthRangeIndexed} | |
@fn_gl{DetachShader} | | @fn_gl{DetachShader} | |

4
doc/opengl-support.dox

@ -52,8 +52,6 @@ following:
@subsection opengl-support-30 OpenGL 3.0 @subsection opengl-support-30 OpenGL 3.0
@todo Add @gl_extension{ARB,depth_buffer_float} and implement the missing @fn_gl{DepthRange} function, but keep (and implement) @gl_extension{NV,depth_buffer_float} for non-linear depth buffer
@m_class{m-fullwidth} @m_class{m-fullwidth}
Extension | Status Extension | Status
@ -79,7 +77,7 @@ GLSL 1.30 | done
@gl_extension{EXT,texture_integer} | done (GL 3.0 subset) @gl_extension{EXT,texture_integer} | done (GL 3.0 subset)
@gl_extension{EXT,transform_feedback} | done @gl_extension{EXT,transform_feedback} | done
`MAGNUM_shader_vertex_id` \n @m_span{m-text m-dim} Pseudo-extension denoting support for the @glsl gl_VertexID @ce GLSL builtin. @m_endspan | done `MAGNUM_shader_vertex_id` \n @m_span{m-text m-dim} Pseudo-extension denoting support for the @glsl gl_VertexID @ce GLSL builtin. @m_endspan | done
@gl_extension{NV,depth_buffer_float} | | @gl_extension{NV,depth_buffer_float} | done
@gl_extension{NV,conditional_render} | done @gl_extension{NV,conditional_render} | done
@subsection opengl-support-31 OpenGL 3.1 @subsection opengl-support-31 OpenGL 3.1

45
src/Magnum/GL/Implementation/RendererState.cpp

@ -40,25 +40,46 @@ RendererState::RendererState(Context& context, ContextState& contextState, Conta
: resetNotificationStrategy() : resetNotificationStrategy()
#endif #endif
{ {
/* Float depth clear value / range implementation */ /* Depth clear value / range implementation. If the NV_depth_buffer_float
extension is present, prefer it for both the float and double overloads
to avoid accidents. Otherwise use the float variant if available, and
fall back to the double variant otherwise. */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::ES2_compatibility>()) if(context.isExtensionSupported<Extensions::NV::depth_buffer_float>()) {
extensions[Extensions::NV::depth_buffer_float::Index] =
Extensions::NV::depth_buffer_float::string();
clearDepthImplementation = glClearDepthdNV;
depthRangeImplementation = glDepthRangedNV;
clearDepthfImplementation = &Renderer::clearDepthfImplementationNV;
depthRangefImplementation = &Renderer::depthRangefImplementationNV;
} else
#endif #endif
{ {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
extensions[Extensions::ARB::ES2_compatibility::Index] = clearDepthImplementation = glClearDepth;
Extensions::ARB::ES2_compatibility::string(); depthRangeImplementation = glDepthRange;
#endif #endif
clearDepthfImplementation = glClearDepthf; #ifndef MAGNUM_TARGET_GLES
depthRangefImplementation = glDepthRangef; if(context.isExtensionSupported<Extensions::ARB::ES2_compatibility>())
} #endif
#ifndef MAGNUM_TARGET_GLES {
else { #ifndef MAGNUM_TARGET_GLES
clearDepthfImplementation = &Renderer::clearDepthfImplementationDefault; extensions[Extensions::ARB::ES2_compatibility::Index] =
depthRangefImplementation = &Renderer::depthRangefImplementationDefault; Extensions::ARB::ES2_compatibility::string();
#endif
clearDepthfImplementation = glClearDepthf;
depthRangefImplementation = glDepthRangef;
}
#ifndef MAGNUM_TARGET_GLES
else {
clearDepthfImplementation = &Renderer::clearDepthfImplementationDefault;
depthRangefImplementation = &Renderer::depthRangefImplementationDefault;
}
#endif
} }
#endif
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
/* Graphics reset status implementation */ /* Graphics reset status implementation */

4
src/Magnum/GL/Implementation/RendererState.h

@ -38,6 +38,10 @@ struct RendererState {
Range1D(*lineWidthRangeImplementation)(); Range1D(*lineWidthRangeImplementation)();
/* These are direct pointers to the GL functions, so need a __stdcall on /* These are direct pointers to the GL functions, so need a __stdcall on
Windows to compile properly on 32 bits */ Windows to compile properly on 32 bits */
#ifndef MAGNUM_TARGET_GLES
void(APIENTRY *clearDepthImplementation)(GLdouble);
void(APIENTRY *depthRangeImplementation)(GLdouble, GLdouble);
#endif
void(APIENTRY *clearDepthfImplementation)(GLfloat); void(APIENTRY *clearDepthfImplementation)(GLfloat);
void(APIENTRY *depthRangefImplementation)(GLfloat, GLfloat); void(APIENTRY *depthRangefImplementation)(GLfloat, GLfloat);
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)

12
src/Magnum/GL/Renderer.cpp

@ -96,7 +96,7 @@ void Renderer::setClearColor(const Color4& color) {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void Renderer::setClearDepth(const Double depth) { void Renderer::setClearDepth(const Double depth) {
glClearDepth(depth); Context::current().state().renderer.clearDepthImplementation(depth);
} }
#endif #endif
@ -105,6 +105,10 @@ void Renderer::setClearDepth(const Float depth) {
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void Renderer::clearDepthfImplementationNV(const GLfloat depth) {
glClearDepthdNV(GLdouble(depth));
}
void Renderer::clearDepthfImplementationDefault(const GLfloat depth) { void Renderer::clearDepthfImplementationDefault(const GLfloat depth) {
glClearDepth(GLdouble(depth)); glClearDepth(GLdouble(depth));
} }
@ -304,7 +308,7 @@ void Renderer::setDepthFunction(const DepthFunction function) {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void Renderer::setDepthRange(const Double near, const Double far) { void Renderer::setDepthRange(const Double near, const Double far) {
glDepthRange(near, far); Context::current().state().renderer.depthRangeImplementation(near, far);
} }
#endif #endif
@ -313,6 +317,10 @@ void Renderer::setDepthRange(const Float near, const Float far) {
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void Renderer::depthRangefImplementationNV(const Float near, const Float far) {
glDepthRangedNV(GLdouble(near), GLdouble(far));
}
void Renderer::depthRangefImplementationDefault(const Float near, const Float far) { void Renderer::depthRangefImplementationDefault(const Float near, const Float far) {
glDepthRange(GLdouble(near), GLdouble(far)); glDepthRange(GLdouble(near), GLdouble(far));
} }

41
src/Magnum/GL/Renderer.h

@ -690,7 +690,11 @@ class MAGNUM_GL_EXPORT Renderer {
/** /**
* @brief Set clear depth * @brief Set clear depth
* *
* Initial value is @cpp 1.0 @ce. * Initial value is @cpp 1.0 @ce. If the
* @gl_extension{NV,depth_buffer_float} desktop extension is available,
* the function uses the
* @fn_gl_extension_keyword{ClearDepthd,NV,depth_buffer_float} API
* which doesn't clamp the input to the @f$ [0, 1] @f$ range.
* @see @ref Feature::DepthTest, @ref AbstractFramebuffer::clearDepth(), * @see @ref Feature::DepthTest, @ref AbstractFramebuffer::clearDepth(),
* @ref AbstractFramebuffer::clearDepthStencil(), * @ref AbstractFramebuffer::clearDepthStencil(),
* @ref setDepthRange(), @fn_gl_keyword{ClearDepth} * @ref setDepthRange(), @fn_gl_keyword{ClearDepth}
@ -707,13 +711,17 @@ class MAGNUM_GL_EXPORT Renderer {
/** /**
* @overload * @overload
* *
* Initial value is @cpp 1.0f @ce. If OpenGL ES, OpenGL 4.1 or * Initial value is @cpp 1.0f @ce. If the
* extension @gl_extension{ARB,ES2_compatibility} is not available, * @gl_extension{NV,depth_buffer_float} desktop extension is available,
* this function behaves exactly as * the function behaves exactly as @ref setClearDepth(Double) for
* @ref setClearDepth(Double). * consistent clamping behavior between the two overloads. Otherwise,
* if OpenGL ES, OpenGL 4.1 or extension
* @gl_extension{ARB,ES2_compatibility} is available, this function
* uses the @fn_gl2_keyword{ClearDepthf,ClearDepth} API. Otherwise it
* behaves exactly as @ref setClearDepth(Double).
* @see @ref Feature::DepthTest, @ref AbstractFramebuffer::clearDepth(), * @see @ref Feature::DepthTest, @ref AbstractFramebuffer::clearDepth(),
* @ref AbstractFramebuffer::clearDepthStencil(), * @ref AbstractFramebuffer::clearDepthStencil(),
* @ref setDepthRange(), @fn_gl2_keyword{ClearDepthf,ClearDepth} * @ref setDepthRange()
* @deprecated_gl Prefer to use @ref AbstractFramebuffer::clearDepth() * @deprecated_gl Prefer to use @ref AbstractFramebuffer::clearDepth()
* / @ref AbstractFramebuffer::clearDepthStencil() instead of * / @ref AbstractFramebuffer::clearDepthStencil() instead of
* @ref setClearDepth() and @ref AbstractFramebuffer::clear() as * @ref setClearDepth() and @ref AbstractFramebuffer::clear() as
@ -1197,7 +1205,11 @@ class MAGNUM_GL_EXPORT Renderer {
* @brief Set depth range * @brief Set depth range
* @m_since_latest * @m_since_latest
* *
* Initial value is @cpp 0.0 @ce and @cpp 1.0 @ce. * Initial value is @cpp 0.0 @ce and @cpp 1.0 @ce. If the
* @gl_extension{NV,depth_buffer_float} desktop extension is available,
* the function uses the
* @fn_gl_extension_keyword{DepthRanged,NV,depth_buffer_float} API
* which doesn't clamp the input to the @f$ [0, 1] @f$ range.
* @see @fn_gl_keyword{DepthRange} * @see @fn_gl_keyword{DepthRange}
* @requires_gl See @ref setClearDepth(Float), which is available in * @requires_gl See @ref setClearDepth(Float), which is available in
* OpenGL ES and WebGL. * OpenGL ES and WebGL.
@ -1209,11 +1221,14 @@ class MAGNUM_GL_EXPORT Renderer {
* @overload * @overload
* @m_since_latest * @m_since_latest
* *
* Initial value is @cpp 0.0 @ce and @cpp 1.0 @ce. If OpenGL ES, OpenGL * Initial value is @cpp 0.0 @ce and @cpp 1.0 @ce. If the
* 4.1 or extension @gl_extension{ARB,ES2_compatibility} is not * @gl_extension{NV,depth_buffer_float} desktop extension is available,
* available, this function behaves exactly as * the function behaves exactly as @ref setDepthRange(Double, Double)
* @ref setDepthRange(Double, Double). * for consistent clamping behavior between the two overloads.
* @see @fn_gl2_keyword{DepthRangef,DepthRange} * Otherwise, if OpenGL ES, OpenGL 4.1 or extension
* @gl_extension{ARB,ES2_compatibility} is available, this function
* uses the @fn_gl2_keyword{DepthRangef,DepthRange} API. Otherwise it
* behaves exactly as @ref setDepthRange(Double, Double).
*/ */
static void setDepthRange(Float near, Float far); static void setDepthRange(Float near, Float far);
@ -2263,7 +2278,9 @@ class MAGNUM_GL_EXPORT Renderer {
/* These have to be compatible with direct pointers to the GL functions /* These have to be compatible with direct pointers to the GL functions
which need a __stdcall on Windows to compile properly on 32 bits */ which need a __stdcall on Windows to compile properly on 32 bits */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
static void APIENTRY MAGNUM_GL_LOCAL clearDepthfImplementationNV(GLfloat depth);
static void APIENTRY MAGNUM_GL_LOCAL clearDepthfImplementationDefault(GLfloat depth); static void APIENTRY MAGNUM_GL_LOCAL clearDepthfImplementationDefault(GLfloat depth);
static void APIENTRY MAGNUM_GL_LOCAL depthRangefImplementationNV(GLfloat near, GLfloat far);
static void APIENTRY MAGNUM_GL_LOCAL depthRangefImplementationDefault(GLfloat near, GLfloat far); static void APIENTRY MAGNUM_GL_LOCAL depthRangefImplementationDefault(GLfloat near, GLfloat far);
#endif #endif
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL

8
src/MagnumExternal/OpenGL/GL/extensions.txt vendored

@ -42,9 +42,17 @@ extension KHR_blend_equation_advanced optional
extension KHR_blend_equation_advanced_coherent optional extension KHR_blend_equation_advanced_coherent optional
# extension KHR_texture_compression_astc_sliced_3d optional # extension KHR_texture_compression_astc_sliced_3d optional
extension KHR_parallel_shader_compile optional extension KHR_parallel_shader_compile optional
extension NV_depth_buffer_float optional
extension NV_sample_locations optional extension NV_sample_locations optional
extension NV_fragment_shader_barycentric optional extension NV_fragment_shader_barycentric optional
extension OVR_multiview optional extension OVR_multiview optional
extension OVR_multiview2 optional extension OVR_multiview2 optional
begin functions blacklist
# Part of NV_depth_buffer_float, according to the spec file should be
# present only if EXT_depth_bounds_test is also present (which we don't
# use)
DepthBoundsdNV
end functions blacklist
# kate: hl python # kate: hl python

4
src/MagnumExternal/OpenGL/GL/flextGL.cpp vendored

@ -225,6 +225,10 @@ FlextGL flextGL{
/* GL_KHR_parallel_shader_compile */ /* GL_KHR_parallel_shader_compile */
nullptr, nullptr,
/* GL_NV_depth_buffer_float */
nullptr,
nullptr,
/* GL_NV_sample_locations */ /* GL_NV_sample_locations */
nullptr, nullptr,
nullptr, nullptr,

17
src/MagnumExternal/OpenGL/GL/flextGL.h vendored

@ -1778,6 +1778,13 @@ typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum
#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0 #define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0
#define GL_COMPLETION_STATUS_KHR 0x91B1 #define GL_COMPLETION_STATUS_KHR 0x91B1
/* GL_NV_depth_buffer_float */
#define GL_DEPTH_COMPONENT32F_NV 0x8DAB
#define GL_DEPTH32F_STENCIL8_NV 0x8DAC
#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF
/* GL_NV_sample_locations */ /* GL_NV_sample_locations */
#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D #define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D
@ -1885,6 +1892,11 @@ struct FlextGL {
void(APIENTRY *MaxShaderCompilerThreadsKHR)(GLuint); void(APIENTRY *MaxShaderCompilerThreadsKHR)(GLuint);
/* GL_NV_depth_buffer_float */
void(APIENTRY *ClearDepthdNV)(GLdouble);
void(APIENTRY *DepthRangedNV)(GLdouble, GLdouble);
/* GL_NV_sample_locations */ /* GL_NV_sample_locations */
void(APIENTRY *FramebufferSampleLocationsfvNV)(GLenum, GLuint, GLsizei, const GLfloat *); void(APIENTRY *FramebufferSampleLocationsfvNV)(GLenum, GLuint, GLsizei, const GLfloat *);
@ -2693,6 +2705,11 @@ extern FLEXTGL_EXPORT FlextGL flextGL;
#define glMaxShaderCompilerThreadsKHR flextGL.MaxShaderCompilerThreadsKHR #define glMaxShaderCompilerThreadsKHR flextGL.MaxShaderCompilerThreadsKHR
/* GL_NV_depth_buffer_float */
#define glClearDepthdNV flextGL.ClearDepthdNV
#define glDepthRangedNV flextGL.DepthRangedNV
/* GL_NV_sample_locations */ /* GL_NV_sample_locations */
#define glFramebufferSampleLocationsfvNV flextGL.FramebufferSampleLocationsfvNV #define glFramebufferSampleLocationsfvNV flextGL.FramebufferSampleLocationsfvNV

4
src/MagnumExternal/OpenGL/GL/flextGLPlatform.cpp vendored

@ -189,6 +189,10 @@ void flextGLInit(Magnum::GL::Context& context) {
/* GL_KHR_parallel_shader_compile */ /* GL_KHR_parallel_shader_compile */
flextGL.MaxShaderCompilerThreadsKHR = reinterpret_cast<void(APIENTRY*)(GLuint)>(loader.load("glMaxShaderCompilerThreadsKHR")); flextGL.MaxShaderCompilerThreadsKHR = reinterpret_cast<void(APIENTRY*)(GLuint)>(loader.load("glMaxShaderCompilerThreadsKHR"));
/* GL_NV_depth_buffer_float */
flextGL.ClearDepthdNV = reinterpret_cast<void(APIENTRY*)(GLdouble)>(loader.load("glClearDepthdNV"));
flextGL.DepthRangedNV = reinterpret_cast<void(APIENTRY*)(GLdouble, GLdouble)>(loader.load("glDepthRangedNV"));
/* GL_NV_sample_locations */ /* GL_NV_sample_locations */
flextGL.FramebufferSampleLocationsfvNV = reinterpret_cast<void(APIENTRY*)(GLenum, GLuint, GLsizei, const GLfloat *)>(loader.load("glFramebufferSampleLocationsfvNV")); flextGL.FramebufferSampleLocationsfvNV = reinterpret_cast<void(APIENTRY*)(GLenum, GLuint, GLsizei, const GLfloat *)>(loader.load("glFramebufferSampleLocationsfvNV"));
flextGL.NamedFramebufferSampleLocationsfvNV = reinterpret_cast<void(APIENTRY*)(GLuint, GLuint, GLsizei, const GLfloat *)>(loader.load("glNamedFramebufferSampleLocationsfvNV")); flextGL.NamedFramebufferSampleLocationsfvNV = reinterpret_cast<void(APIENTRY*)(GLuint, GLuint, GLsizei, const GLfloat *)>(loader.load("glNamedFramebufferSampleLocationsfvNV"));

Loading…
Cancel
Save