Am 06.09.2014 19:17, schrieb Mathias Froehlich: > > Hi, > > Please review: > > Add support for the unclamped versions of glDepthRange > and relatives. Also starting with OpenGL 4.2 the traditional > functions for this should no longer clamp the values to [0, 1]. This looks wrong to me (the NV_depth_buffer part may be ok, just skimmed through it). The core functions still (some would probably say unfortunately...) clamp the values to [0,1]. Only 4.2 had language indicating otherwise, however this was retroactively fixed (see GL 4.3 spec, chapter F.5, Change Log for Released Specifications, page 647).
Roland > > Signed-off-by: Mathias Froehlich <mathias.froehl...@web.de> > --- > docs/GL3.txt | 1 + > src/mapi/glapi/gen/NV_depth_buffer_float.xml | 24 ++++++++ > src/mapi/glapi/gen/gl_API.xml | 2 + > src/mesa/drivers/common/meta.c | 3 +- > src/mesa/main/attrib.c | 6 +- > src/mesa/main/depth.c | 82 > +++++++++++++++++++--------- > src/mesa/main/depth.h | 6 ++ > src/mesa/main/dlist.c | 67 +++++++++++++++++++++++ > src/mesa/main/extensions.c | 1 + > src/mesa/main/viewport.c | 77 +++++++++++++++++--------- > src/mesa/main/viewport.h | 9 ++- > 11 files changed, 223 insertions(+), 55 deletions(-) > create mode 100644 src/mapi/glapi/gen/NV_depth_buffer_float.xml > > diff --git a/docs/GL3.txt b/docs/GL3.txt > index f5d5e72..a869beb 100644 > --- a/docs/GL3.txt > +++ b/docs/GL3.txt > @@ -144,6 +144,7 @@ GL 4.2, GLSL 4.20: > GL_ARB_shading_language_420pack DONE (all drivers > that support GLSL 1.30) > GL_ARB_internalformat_query DONE (i965, nv50, > nvc0, r300, r600, radeonsi, llvmpipe, softpipe) > GL_ARB_map_buffer_alignment DONE (all drivers) > + Unclamped glDepthRange and GL_NV_depth_buffer_float DONE (all drivers) > > > GL 4.3, GLSL 4.30: > diff --git a/src/mapi/glapi/gen/NV_depth_buffer_float.xml > b/src/mapi/glapi/gen/NV_depth_buffer_float.xml > new file mode 100644 > index 0000000..17ee268 > --- /dev/null > +++ b/src/mapi/glapi/gen/NV_depth_buffer_float.xml > @@ -0,0 +1,24 @@ > +<?xml version="1.0"?> > +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"> > + > +<!-- Note: no GLX protocol info yet. --> > + > +<OpenGLAPI> > + > +<category name="GL_NV_depth_buffer_float" number="417"> > + > + <function name="DepthRangedNV" offset="assign"> > + <param name="n" type="GLdouble"/> > + <param name="f" type="GLdouble"/> > + </function> > + <function name="ClearDepthdNV" offset="assign"> > + <param name="d" type="GLdouble"/> > + </function> > + <function name="DepthBoundsdNV" offset="assign"> > + <param name="zmin" type="GLdouble"/> > + <param name="zmax" type="GLdouble"/> > + </function> > + > +</category> > + > +</OpenGLAPI> > diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml > index 73f2f75..d504faf 100644 > --- a/src/mapi/glapi/gen/gl_API.xml > +++ b/src/mapi/glapi/gen/gl_API.xml > @@ -13027,6 +13027,8 @@ > > <xi:include href="NV_vdpau_interop.xml" > xmlns:xi="http://www.w3.org/2001/XInclude"/> > > +<xi:include href="NV_depth_buffer_float.xml" > xmlns:xi="http://www.w3.org/2001/XInclude"/> > + > <xi:include href="GL4x.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> > > </OpenGLAPI> > diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c > index 7a8e627..d165f12 100644 > --- a/src/mesa/drivers/common/meta.c > +++ b/src/mesa/drivers/common/meta.c > @@ -1112,7 +1112,8 @@ _mesa_meta_end(struct gl_context *ctx) > _mesa_set_viewport(ctx, 0, save->ViewportX, save->ViewportY, > save->ViewportW, save->ViewportH); > } > - _mesa_DepthRange(save->DepthNear, save->DepthFar); > + /* Need to call ...NV since this is guaranteed not to clamp to [0,1] */ > + _mesa_DepthRangedNV(save->DepthNear, save->DepthFar); > } > > if (state & MESA_META_CLAMP_FRAGMENT_COLOR && > diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c > index 2e289b6..7368ee1 100644 > --- a/src/mesa/main/attrib.c > +++ b/src/mesa/main/attrib.c > @@ -1072,7 +1072,9 @@ _mesa_PopAttrib(void) > const struct gl_depthbuffer_attrib *depth; > depth = (const struct gl_depthbuffer_attrib *) attr->data; > _mesa_DepthFunc(depth->Func); > - _mesa_ClearDepth(depth->Clear); > + /* The ...NV variant is guaranteed not to clamp */ > + /* what was not clamped before. */ > + _mesa_ClearDepthdNV(depth->Clear); > _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test); > _mesa_DepthMask(depth->Mask); > } > @@ -1364,7 +1366,7 @@ _mesa_PopAttrib(void) > for (i = 0; i < ctx->Const.MaxViewports; i++) { > _mesa_set_viewport(ctx, i, vp[i].X, vp[i].Y, vp[i].Width, > vp[i].Height); > - _mesa_set_depth_range(ctx, i, vp[i].Near, vp[i].Far); > + _mesa_set_depth_range(ctx, i, vp[i].Near, vp[i].Far, > GL_FALSE); > } > } > break; > diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c > index 29851ec..9ef10bf 100644 > --- a/src/mesa/main/depth.c > +++ b/src/mesa/main/depth.c > @@ -32,30 +32,69 @@ > #include "mtypes.h" > > > +static void > +set_clear_depth( struct gl_context *ctx, const char* fcn, > + GLdouble depth, GLboolean clamp ) > +{ > + if (MESA_VERBOSE & VERBOSE_API) > + _mesa_debug(ctx, "%s(%f)\n", fcn, depth); > + > + if (clamp) > + depth = CLAMP( depth, 0.0, 1.0 ); > + > + ctx->Depth.Clear = depth; > +} > + > +static void > +set_depth_bounds( struct gl_context *ctx, const char* fcn, > + GLdouble zmin, GLdouble zmax, GLboolean clamp ) > +{ > + if (MESA_VERBOSE & VERBOSE_API) > + _mesa_debug(ctx, "%s(%f, %f)\n", fcn, zmin, zmax); > + > + if (zmin > zmax) { > + _mesa_error(ctx, GL_INVALID_VALUE, "%s(zmin > zmax)", fcn); > + return; > + } > + > + if (clamp) { > + zmin = CLAMP(zmin, 0.0, 1.0); > + zmax = CLAMP(zmax, 0.0, 1.0); > + } > + > + if (ctx->Depth.BoundsMin == zmin && ctx->Depth.BoundsMax == zmax) > + return; > + > + FLUSH_VERTICES(ctx, _NEW_DEPTH); > + ctx->Depth.BoundsMin = (GLfloat) zmin; > + ctx->Depth.BoundsMax = (GLfloat) zmax; > +} > + > /**********************************************************************/ > /***** API Functions *****/ > /**********************************************************************/ > > - > - > void GLAPIENTRY > _mesa_ClearDepth( GLclampd depth ) > { > GET_CURRENT_CONTEXT(ctx); > - > - if (MESA_VERBOSE & VERBOSE_API) > - _mesa_debug(ctx, "glClearDepth(%f)\n", depth); > - > - ctx->Depth.Clear = CLAMP( depth, 0.0, 1.0 ); > + set_clear_depth(ctx, "glClearDepth", depth, ctx->Version < 42); > } > > > void GLAPIENTRY > _mesa_ClearDepthf( GLclampf depth ) > { > - _mesa_ClearDepth(depth); > + GET_CURRENT_CONTEXT(ctx); > + set_clear_depth(ctx, "glClearDepthf", depth, ctx->Version < 42); > } > > +void GLAPIENTRY > +_mesa_ClearDepthdNV( GLdouble depth ) > +{ > + GET_CURRENT_CONTEXT(ctx); > + set_clear_depth(ctx, "glClearDepthdNV", depth, GL_FALSE); > +} > > void GLAPIENTRY > _mesa_DepthFunc( GLenum func ) > @@ -123,27 +162,20 @@ void GLAPIENTRY > _mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax ) > { > GET_CURRENT_CONTEXT(ctx); > + set_depth_bounds(ctx, "glDepthBoundsEXT", zmin, zmax, ctx->Version < 42); > +} > > - if (MESA_VERBOSE & VERBOSE_API) > - _mesa_debug(ctx, "glDepthBounds(%f, %f)\n", zmin, zmax); > - > - if (zmin > zmax) { > - _mesa_error(ctx, GL_INVALID_VALUE, "glDepthBoundsEXT(zmin > zmax)"); > - return; > - } > - > - zmin = CLAMP(zmin, 0.0, 1.0); > - zmax = CLAMP(zmax, 0.0, 1.0); > - > - if (ctx->Depth.BoundsMin == zmin && ctx->Depth.BoundsMax == zmax) > - return; > > - FLUSH_VERTICES(ctx, _NEW_DEPTH); > - ctx->Depth.BoundsMin = (GLfloat) zmin; > - ctx->Depth.BoundsMax = (GLfloat) zmax; > +/** > + * Specified by the NV_depth_buffer_float extension. > + */ > +void GLAPIENTRY > +_mesa_DepthBoundsdNV( GLdouble zmin, GLdouble zmax ) > +{ > + GET_CURRENT_CONTEXT(ctx); > + set_depth_bounds(ctx, "glDepthBoundsdNV", zmin, zmax, GL_FALSE); > } > > - > /**********************************************************************/ > /***** Initialization *****/ > /**********************************************************************/ > diff --git a/src/mesa/main/depth.h b/src/mesa/main/depth.h > index 5ff7a5e..f213012 100644 > --- a/src/mesa/main/depth.h > +++ b/src/mesa/main/depth.h > @@ -44,6 +44,9 @@ extern void GLAPIENTRY > _mesa_ClearDepthf( GLclampf depth ); > > extern void GLAPIENTRY > +_mesa_ClearDepthdNV( GLdouble depth ); > + > +extern void GLAPIENTRY > _mesa_DepthFunc( GLenum func ); > > extern void GLAPIENTRY > @@ -52,6 +55,9 @@ _mesa_DepthMask( GLboolean flag ); > extern void GLAPIENTRY > _mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax ); > > +extern void GLAPIENTRY > +_mesa_DepthBoundsdNV( GLdouble zmin, GLdouble zmax ); > + > extern void > _mesa_init_depth( struct gl_context * ctx ); > > diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c > index 5c7160d..2e98045 100644 > --- a/src/mesa/main/dlist.c > +++ b/src/mesa/main/dlist.c > @@ -40,6 +40,7 @@ > #include "bufferobj.h" > #include "arrayobj.h" > #include "context.h" > +#include "depth.h" > #include "dlist.h" > #include "enums.h" > #include "eval.h" > @@ -308,6 +309,10 @@ typedef enum > OPCODE_ACTIVE_STENCIL_FACE_EXT, > /* GL_EXT_depth_bounds_test */ > OPCODE_DEPTH_BOUNDS_EXT, > + /* GL_NV_depth_buffer_float */ > + OPCODE_DEPTH_RANGE_NV, > + OPCODE_CLEAR_DEPTH_NV, > + OPCODE_DEPTH_BOUNDS_NV, > /* GL_ARB_vertex/fragment_program */ > OPCODE_PROGRAM_STRING_ARB, > OPCODE_PROGRAM_ENV_PARAMETER_ARB, > @@ -4843,6 +4848,54 @@ save_DepthBoundsEXT(GLclampd zmin, GLclampd zmax) > } > > > +/* NV_depth_buffer_float */ > +static void GLAPIENTRY > +save_DepthRangedNV(GLdouble near, GLdouble far) > +{ > + GET_CURRENT_CONTEXT(ctx); > + Node *n; > + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); > + n = alloc_instruction(ctx, OPCODE_DEPTH_RANGE_NV, 2); > + if (n) { > + n[1].f = near; > + n[2].f = far; > + } > + if (ctx->ExecuteFlag) { > + CALL_DepthRangedNV(ctx->Exec, (near, far)); > + } > +} > + > +static void GLAPIENTRY > +save_ClearDepthdNV(GLdouble d) > +{ > + GET_CURRENT_CONTEXT(ctx); > + Node *n; > + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); > + n = alloc_instruction(ctx, OPCODE_CLEAR_DEPTH_NV, 1); > + if (n) { > + n[1].f = d; > + } > + if (ctx->ExecuteFlag) { > + CALL_ClearDepthdNV(ctx->Exec, (d)); > + } > +} > + > +static void GLAPIENTRY > +save_DepthBoundsdNV(GLdouble zmin, GLdouble zmax) > +{ > + GET_CURRENT_CONTEXT(ctx); > + Node *n; > + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); > + n = alloc_instruction(ctx, OPCODE_DEPTH_BOUNDS_NV, 2); > + if (n) { > + n[1].f = zmin; > + n[2].f = zmax; > + } > + if (ctx->ExecuteFlag) { > + CALL_DepthBoundsdNV(ctx->Exec, (zmin, zmax)); > + } > +} > + > > static void GLAPIENTRY > save_ProgramStringARB(GLenum target, GLenum format, GLsizei len, > @@ -8317,6 +8370,15 @@ execute_list(struct gl_context *ctx, GLuint list) > case OPCODE_DEPTH_BOUNDS_EXT: > CALL_DepthBoundsEXT(ctx->Exec, (n[1].f, n[2].f)); > break; > + case OPCODE_DEPTH_RANGE_NV: > + CALL_DepthRangedNV(ctx->Exec, (n[1].f, n[2].f)); > + break; > + case OPCODE_CLEAR_DEPTH_NV: > + CALL_ClearDepthdNV(ctx->Exec, (n[1].f)); > + break; > + case OPCODE_DEPTH_BOUNDS_NV: > + CALL_DepthBoundsdNV(ctx->Exec, (n[1].f, n[2].f)); > + break; > case OPCODE_PROGRAM_STRING_ARB: > CALL_ProgramStringARB(ctx->Exec, > (n[1].e, n[2].e, n[3].i, > @@ -9460,6 +9522,11 @@ _mesa_initialize_save_table(const struct gl_context > *ctx) > /* ???. GL_EXT_depth_bounds_test */ > SET_DepthBoundsEXT(table, save_DepthBoundsEXT); > > + /* ???. GL_NV_depth_buffer_float */ > + SET_DepthRangedNV(table, save_DepthRangedNV); > + SET_ClearDepthdNV(table, save_ClearDepthdNV); > + SET_DepthBoundsdNV(table, save_DepthBoundsdNV); > + > /* ARB 1. GL_ARB_multitexture */ > SET_ActiveTexture(table, save_ActiveTextureARB); > > diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c > index 553c01e..b5ce04f 100644 > --- a/src/mesa/main/extensions.c > +++ b/src/mesa/main/extensions.c > @@ -353,6 +353,7 @@ static const struct extension extension_table[] = { > { "GL_MESA_ycbcr_texture", o(MESA_ycbcr_texture), > GL, 2002 }, > { "GL_NV_blend_square", o(dummy_true), > GLL, 1999 }, > { "GL_NV_conditional_render", o(NV_conditional_render), > GL, 2008 }, > + { "GL_NV_depth_buffer_float", > o(ARB_depth_buffer_float), GL, 2008 }, > { "GL_NV_depth_clamp", o(ARB_depth_clamp), > GL, 2001 }, > { "GL_NV_draw_buffers", o(dummy_true), > ES2, 2011 }, > { "GL_NV_fbo_color_attachments", o(dummy_true), > ES2, 2010 }, > diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c > index 6545bf6..8fafc65 100644 > --- a/src/mesa/main/viewport.c > +++ b/src/mesa/main/viewport.c > @@ -240,14 +240,19 @@ _mesa_ViewportIndexedfv(GLuint index, const GLfloat *v) > > static void > set_depth_range_no_notify(struct gl_context *ctx, unsigned idx, > - GLclampd nearval, GLclampd farval) > + GLclampd nearval, GLclampd farval, GLboolean clamp) > { > + if (clamp) { > + nearval = CLAMP(nearval, 0.0, 1.0); > + farval = CLAMP(farval, 0.0, 1.0); > + } > + > if (ctx->ViewportArray[idx].Near == nearval && > ctx->ViewportArray[idx].Far == farval) > return; > > - ctx->ViewportArray[idx].Near = CLAMP(nearval, 0.0, 1.0); > - ctx->ViewportArray[idx].Far = CLAMP(farval, 0.0, 1.0); > + ctx->ViewportArray[idx].Near = nearval; > + ctx->ViewportArray[idx].Far = farval; > ctx->NewState |= _NEW_VIEWPORT; > > #if 1 > @@ -268,32 +273,19 @@ set_depth_range_no_notify(struct gl_context *ctx, > unsigned idx, > > void > _mesa_set_depth_range(struct gl_context *ctx, unsigned idx, > - GLclampd nearval, GLclampd farval) > + GLclampd nearval, GLclampd farval, GLboolean clamp) > { > - set_depth_range_no_notify(ctx, idx, nearval, farval); > + set_depth_range_no_notify(ctx, idx, nearval, farval, clamp); > > if (ctx->Driver.DepthRange) > ctx->Driver.DepthRange(ctx); > } > > -/** > - * Called by glDepthRange > - * > - * \param nearval specifies the Z buffer value which should correspond to > - * the near clip plane > - * \param farval specifies the Z buffer value which should correspond to > - * the far clip plane > - */ > -void GLAPIENTRY > -_mesa_DepthRange(GLclampd nearval, GLclampd farval) > +void > +_mesa_set_all_depth_range(struct gl_context *ctx, > + GLclampd nearval, GLclampd farval, GLboolean clamp) > { > unsigned i; > - GET_CURRENT_CONTEXT(ctx); > - > - FLUSH_VERTICES(ctx, 0); > - > - if (MESA_VERBOSE&VERBOSE_API) > - _mesa_debug(ctx, "glDepthRange %f %f\n", nearval, farval); > > /* The GL_ARB_viewport_array spec says: > * > @@ -307,11 +299,31 @@ _mesa_DepthRange(GLclampd nearval, GLclampd farval) > * implementation, but only signal the driver once at the end. > */ > for (i = 0; i < ctx->Const.MaxViewports; i++) > - set_depth_range_no_notify(ctx, i, nearval, farval); > + set_depth_range_no_notify(ctx, i, nearval, farval, clamp); > > - if (ctx->Driver.DepthRange) { > + if (ctx->Driver.DepthRange) > ctx->Driver.DepthRange(ctx); > - } > +} > + > +/** > + * Called by glDepthRange > + * > + * \param nearval specifies the Z buffer value which should correspond to > + * the near clip plane > + * \param farval specifies the Z buffer value which should correspond to > + * the far clip plane > + */ > +void > +_mesa_DepthRange(GLclampd nearval, GLclampd farval) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + FLUSH_VERTICES(ctx, 0); > + > + if (MESA_VERBOSE&VERBOSE_API) > + _mesa_debug(ctx, "glDepthRange %f %f\n", nearval, farval); > + > + _mesa_set_all_depth_range(ctx, nearval, farval, ctx->Version < 42); > } > > void GLAPIENTRY > @@ -320,6 +332,19 @@ _mesa_DepthRangef(GLclampf nearval, GLclampf farval) > _mesa_DepthRange(nearval, farval); > } > > +void GLAPIENTRY > +_mesa_DepthRangedNV(GLdouble nearval, GLdouble farval) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + FLUSH_VERTICES(ctx, 0); > + > + if (MESA_VERBOSE&VERBOSE_API) > + _mesa_debug(ctx, "glDepthRangeNV %f %f\n", nearval, farval); > + > + _mesa_set_all_depth_range(ctx, nearval, farval, GL_FALSE); > +} > + > /** > * Update a range DepthRange values > * > @@ -347,7 +372,7 @@ _mesa_DepthRangeArrayv(GLuint first, GLsizei count, const > GLclampd *v) > } > > for (i = 0; i < count; i++) > - set_depth_range_no_notify(ctx, i + first, p[i].Near, p[i].Far); > + set_depth_range_no_notify(ctx, i + first, p[i].Near, p[i].Far, > ctx->Version < 42); > > if (ctx->Driver.DepthRange) > ctx->Driver.DepthRange(ctx); > @@ -378,7 +403,7 @@ _mesa_DepthRangeIndexed(GLuint index, GLclampd nearval, > GLclampd farval) > return; > } > > - _mesa_set_depth_range(ctx, index, nearval, farval); > + _mesa_set_depth_range(ctx, index, nearval, farval, ctx->Version < 42); > } > > /** > diff --git a/src/mesa/main/viewport.h b/src/mesa/main/viewport.h > index f2311c0..d5cce25 100644 > --- a/src/mesa/main/viewport.h > +++ b/src/mesa/main/viewport.h > @@ -55,6 +55,9 @@ extern void GLAPIENTRY > _mesa_DepthRangef(GLclampf nearval, GLclampf farval); > > extern void GLAPIENTRY > +_mesa_DepthRangedNV(GLdouble nearval, GLdouble farval); > + > +extern void GLAPIENTRY > _mesa_DepthRangeArrayv(GLuint first, GLsizei count, const GLclampd * v); > > extern void GLAPIENTRY > @@ -62,7 +65,11 @@ _mesa_DepthRangeIndexed(GLuint index, GLclampd n, GLclampd > f); > > extern void > _mesa_set_depth_range(struct gl_context *ctx, unsigned idx, > - GLclampd nearval, GLclampd farval); > + GLclampd nearval, GLclampd farval, GLboolean clamp); > + > +extern void > +_mesa_set_all_depth_range(struct gl_context *ctx, > + GLclampd nearval, GLclampd farval, GLboolean > clamp); > > extern void > _mesa_init_viewport(struct gl_context *ctx); > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev