[Mesa-dev] [PATCH] Add support for NV_depth_buffer_float v2.
Mathias Fröhlich
Mathias.Froehlich at gmx.net
Mon Sep 8 09:39:00 PDT 2014
Hi,
On Monday, September 08, 2014 13:16:27 Roland Scheidegger wrote:
> > 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).
Thanks for pointing this out. I did indeed only look at 4.2 where
I did find hints that clamping got removed.
Below the v2 patch that only avoids clamping when being called
through the *NV functions.
Greetings
Mathias
Add support for the unclamped versions of glDepthRange
and relatives.
Note that OpenGL 4.2 introduced that the traditonal
glDepthRange functions may no longer clamp to [0, 1],
but OpenGL 4.3 already revoked this behavior to clamp
the arguments.
Signed-off-by: Mathias Froehlich <Mathias.Froehlich at 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..9a3ceb9 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)
+ 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..e18ff85 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, GL_TRUE);
}
void GLAPIENTRY
_mesa_ClearDepthf( GLclampf depth )
{
- _mesa_ClearDepth(depth);
+ GET_CURRENT_CONTEXT(ctx);
+ set_clear_depth(ctx, "glClearDepthf", depth, GL_TRUE);
}
+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, GL_TRUE);
+}
- 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..f8f78c8 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)
+ GLdouble nearval, GLdouble 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,
+ GLdouble nearval, GLdouble 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, GL_TRUE);
}
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, GL_TRUE);
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, GL_TRUE);
}
/**
diff --git a/src/mesa/main/viewport.h b/src/mesa/main/viewport.h
index f2311c0..140cfb4 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);
+ GLdouble nearval, GLdouble farval, GLboolean clamp);
+
+extern void
+_mesa_set_all_depth_range(struct gl_context *ctx,
+ GLdouble nearval, GLdouble farval, GLboolean clamp);
extern void
_mesa_init_viewport(struct gl_context *ctx);
--
1.9.3
More information about the mesa-dev
mailing list