Mesa (master): mesa: Add support for ARB_depth_clamp.

Eric Anholt anholt at kemper.freedesktop.org
Tue Sep 8 21:34:00 UTC 2009


Module: Mesa
Branch: master
Commit: b4922b533155cc139ebafb111502bb55d2ad2ccf
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b4922b533155cc139ebafb111502bb55d2ad2ccf

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Aug 26 09:51:15 2009 -0700

mesa: Add support for ARB_depth_clamp.

This currently doesn't include fixing up the cliptests in the assembly
paths to support ARB_depth_clamp, so enabling depth_clamp forces the C path.

---

 src/mesa/drivers/dri/swrast/swrast.c |    1 +
 src/mesa/drivers/x11/xm_api.c        |    1 +
 src/mesa/glapi/ARB_depth_clamp.xml   |   12 +++++++++
 src/mesa/glapi/Makefile              |    1 +
 src/mesa/glapi/gl_API.xml            |    2 +
 src/mesa/main/attrib.c               |    7 +++++
 src/mesa/main/enable.c               |   20 +++++++++++++++
 src/mesa/main/extensions.c           |    2 +
 src/mesa/main/get_gen.py             |    4 +++
 src/mesa/main/mtypes.h               |    2 +
 src/mesa/math/m_clip_tmp.h           |   44 ++++++++++++++++++++++-----------
 src/mesa/math/m_debug_clip.c         |    9 ++++--
 src/mesa/math/m_xform.h              |    6 +++-
 src/mesa/sparc/clip.S                |    3 +-
 src/mesa/sparc/sparc.c               |    6 +++-
 src/mesa/swrast/s_depth.c            |   27 ++++++++++++++++++++
 src/mesa/swrast/s_depth.h            |    2 +
 src/mesa/swrast/s_span.c             |    3 ++
 src/mesa/tnl/t_rasterpos.c           |   25 +++++++++++-------
 src/mesa/tnl/t_vb_program.c          |    6 +++-
 src/mesa/tnl/t_vb_vertex.c           |    6 +++-
 src/mesa/x86/x86_xform.c             |    9 ++++--
 22 files changed, 158 insertions(+), 40 deletions(-)

diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index a858af3..9a130d6 100644
--- a/src/mesa/drivers/dri/swrast/swrast.c
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -95,6 +95,7 @@ const struct dri_extension card_extensions[] =
     { "GL_EXT_histogram",		GL_EXT_histogram_functions },
     { "GL_SGI_color_table",		GL_SGI_color_table_functions },
 
+    { "GL_ARB_depth_clamp",		NULL },
     { "GL_ARB_shader_objects",		GL_ARB_shader_objects_functions },
     { "GL_ARB_vertex_array_object",	GL_ARB_vertex_array_object_functions },
     { "GL_ARB_vertex_program",		GL_ARB_vertex_program_functions },
diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index 2c7be9f..78545d0 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -1347,6 +1347,7 @@ const struct dri_extension card_extensions[] =
    { "GL_EXT_histogram",		GL_EXT_histogram_functions },
    { "GL_SGI_color_table",		GL_SGI_color_table_functions },
 
+   { "GL_ARB_depth_clamp",		NULL },
    { "GL_ARB_shader_objects",		GL_ARB_shader_objects_functions },
    { "GL_ARB_sync",			GL_ARB_sync_functions },
    { "GL_ARB_vertex_program",		GL_ARB_vertex_program_functions },
diff --git a/src/mesa/glapi/ARB_depth_clamp.xml b/src/mesa/glapi/ARB_depth_clamp.xml
new file mode 100644
index 0000000..157c9a8
--- /dev/null
+++ b/src/mesa/glapi/ARB_depth_clamp.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_ARB_depth_clamp" number="61">
+    <enum name="DEPTH_CLAMP" count="1"  value="0x864F">
+        <size name="Get" mode="get"/>
+    </enum>
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/glapi/Makefile b/src/mesa/glapi/Makefile
index 65edab7..22f65b7 100644
--- a/src/mesa/glapi/Makefile
+++ b/src/mesa/glapi/Makefile
@@ -48,6 +48,7 @@ SERVER_OUTPUTS = \
 API_XML = gl_API.xml \
 	EXT_framebuffer_object.xml \
 	ARB_copy_buffer.xml \
+	ARB_depth_clamp.xml \
 	ARB_framebuffer_object.xml \
 	ARB_map_buffer_range.xml \
 	ARB_seamless_cube_map.xml \
diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml
index 1dfd92b..920ce80 100644
--- a/src/mesa/glapi/gl_API.xml
+++ b/src/mesa/glapi/gl_API.xml
@@ -7950,6 +7950,8 @@
 
 <xi:include href="ARB_copy_buffer.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
+<xi:include href="ARB_depth_clamp.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
 <xi:include href="ARB_map_buffer_range.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
 <xi:include href="ARB_vertex_array_object.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index ab99ca1..0fb8fa3 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -74,6 +74,7 @@ struct gl_enable_attrib
    GLboolean Convolution2D;
    GLboolean Separable2D;
    GLboolean CullFace;
+   GLboolean DepthClamp;
    GLboolean DepthTest;
    GLboolean Dither;
    GLboolean Fog;
@@ -265,6 +266,7 @@ _mesa_PushAttrib(GLbitfield mask)
       attr->Convolution2D = ctx->Pixel.Convolution2DEnabled;
       attr->Separable2D = ctx->Pixel.Separable2DEnabled;
       attr->CullFace = ctx->Polygon.CullFlag;
+      attr->DepthClamp = ctx->Transform.DepthClamp;
       attr->DepthTest = ctx->Depth.Test;
       attr->Dither = ctx->Color.DitherFlag;
       attr->Fog = ctx->Fog.Enabled;
@@ -514,6 +516,8 @@ pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
                    enable->ColorTable[COLORTABLE_POSTCOLORMATRIX],
                    GL_POST_COLOR_MATRIX_COLOR_TABLE);
    TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
+   TEST_AND_UPDATE(ctx->Transform.DepthClamp, enable->DepthClamp,
+		   GL_DEPTH_CLAMP);
    TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
    TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
    TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D,
@@ -1221,6 +1225,9 @@ _mesa_PopAttrib(void)
                if (xform->RescaleNormals != ctx->Transform.RescaleNormals)
                   _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT,
                                    ctx->Transform.RescaleNormals);
+               if (xform->DepthClamp != ctx->Transform.DepthClamp)
+                  _mesa_set_enable(ctx, GL_DEPTH_CLAMP,
+                                   ctx->Transform.DepthClamp);
             }
             break;
          case GL_TEXTURE_BIT:
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index 4bc5477..d066153 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -37,6 +37,7 @@
 #include "mtypes.h"
 #include "enums.h"
 #include "math/m_matrix.h"
+#include "math/m_xform.h"
 #include "api_arrayelt.h"
 
 
@@ -947,6 +948,20 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
          ctx->Depth.BoundsTest = state;
          break;
 
+      case GL_DEPTH_CLAMP:
+         if (ctx->Transform.DepthClamp == state)
+            return;
+	 /* Neither the x86 nor sparc asm cliptest functions have been updated
+	  * for ARB_depth_clamp, so force the C paths.
+	  */
+	 if (state)
+	    init_c_cliptest();
+
+	 CHECK_EXTENSION(ARB_depth_clamp, cap);
+         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+	 ctx->Transform.DepthClamp = state;
+	 break;
+
 #if FEATURE_ATI_fragment_shader
       case GL_FRAGMENT_SHADER_ATI:
         CHECK_EXTENSION(ATI_fragment_shader, cap);
@@ -1395,6 +1410,11 @@ _mesa_IsEnabled( GLenum cap )
          CHECK_EXTENSION(EXT_depth_bounds_test);
          return ctx->Depth.BoundsTest;
 
+      /* GL_ARB_depth_clamp */
+      case GL_DEPTH_CLAMP:
+         CHECK_EXTENSION(ARB_depth_clamp);
+         return ctx->Transform.DepthClamp;
+
 #if FEATURE_ATI_fragment_shader
       case GL_FRAGMENT_SHADER_ATI:
 	 CHECK_EXTENSION(ATI_fragment_shader);
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index e3070b1..ea67f82 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -47,6 +47,7 @@ static const struct {
 } default_extensions[] = {
    { OFF, "GL_ARB_copy_buffer",                F(ARB_copy_buffer) },
    { OFF, "GL_ARB_depth_texture",              F(ARB_depth_texture) },
+   { OFF, "GL_ARB_depth_clamp",                F(ARB_depth_clamp) },
    { ON,  "GL_ARB_draw_buffers",               F(ARB_draw_buffers) },
    { OFF, "GL_ARB_fragment_program",           F(ARB_fragment_program) },
    { OFF, "GL_ARB_fragment_program_shadow",    F(ARB_fragment_program_shadow) },
@@ -192,6 +193,7 @@ void
 _mesa_enable_sw_extensions(GLcontext *ctx)
 {
    ctx->Extensions.ARB_copy_buffer = GL_TRUE;
+   ctx->Extensions.ARB_depth_clamp = GL_TRUE;
    ctx->Extensions.ARB_depth_texture = GL_TRUE;
    /*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
 #if FEATURE_ARB_fragment_program
diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py
index 2878c1b..364d8c5 100644
--- a/src/mesa/main/get_gen.py
+++ b/src/mesa/main/get_gen.py
@@ -905,6 +905,10 @@ StateVars = [
 	  ["ctx->Depth.BoundsMin", "ctx->Depth.BoundsMax"],
 	  "", ["EXT_depth_bounds_test"] ),
 
+	# GL_ARB_depth_clamp
+	( "GL_DEPTH_CLAMP", GLboolean, ["ctx->Transform.DepthClamp"], "",
+	  ["ARB_depth_clamp"] ),
+
 	# GL_ARB_draw_buffers
 	( "GL_MAX_DRAW_BUFFERS_ARB", GLint,
 	  ["ctx->Const.MaxDrawBuffers"], "", None ),
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 6b64bf8..20cd3aa 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1482,6 +1482,7 @@ struct gl_transform_attrib
    GLboolean Normalize;				/**< Normalize all normals? */
    GLboolean RescaleNormals;			/**< GL_EXT_rescale_normal */
    GLboolean RasterPositionUnclipped;           /**< GL_IBM_rasterpos_clip */
+   GLboolean DepthClamp;			/**< GL_ARB_depth_clamp */
 
    GLboolean CullVertexFlag;	/**< True if GL_CULL_VERTEX_EXT is enabled */
    GLfloat CullEyePos[4];
@@ -2475,6 +2476,7 @@ struct gl_extensions
    GLboolean dummy;  /* don't remove this! */
    GLboolean ARB_copy_buffer;
    GLboolean ARB_depth_texture;
+   GLboolean ARB_depth_clamp;
    GLboolean ARB_draw_buffers;
    GLboolean ARB_fragment_program;
    GLboolean ARB_fragment_program_shadow;
diff --git a/src/mesa/math/m_clip_tmp.h b/src/mesa/math/m_clip_tmp.h
index f3a589b..2e30964 100644
--- a/src/mesa/math/m_clip_tmp.h
+++ b/src/mesa/math/m_clip_tmp.h
@@ -44,7 +44,8 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec,
                                                      GLvector4f *proj_vec,
                                                      GLubyte clipMask[],
                                                      GLubyte *orMask,
-                                                     GLubyte *andMask )
+                                                     GLubyte *andMask,
+						     GLboolean viewport_z_clip )
 {
    const GLuint stride = clip_vec->stride;
    const GLfloat *from = (GLfloat *)clip_vec->start;
@@ -66,16 +67,20 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec,
       mask |= (((cw < -cx) << CLIP_LEFT_SHIFT));
       mask |= (((cw < cy) << CLIP_TOP_SHIFT));
       mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT));
-      mask |= (((cw < cz) << CLIP_FAR_SHIFT));
-      mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
+      if (viewport_z_clip) {
+	 mask |= (((cw < cz) << CLIP_FAR_SHIFT));
+	 mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
+      }
 #else /* !defined(macintosh)) */
       GLubyte mask = 0;
       if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT;
       if ( cx + cw < 0) mask |= CLIP_LEFT_BIT;
       if (-cy + cw < 0) mask |= CLIP_TOP_BIT;
       if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT;
-      if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
-      if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
+      if (viewport_z_clip) {
+	 if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
+	 if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
+      }
 #endif /* defined(macintosh) */
 
       clipMask[i] = mask;
@@ -119,7 +124,8 @@ static GLvector4f * _XFORMAPI TAG(cliptest_np_points4)( GLvector4f *clip_vec,
 							GLvector4f *proj_vec,
 							GLubyte clipMask[],
 							GLubyte *orMask,
-							GLubyte *andMask )
+							GLubyte *andMask,
+							GLboolean viewport_z_clip )
 {
    const GLuint stride = clip_vec->stride;
    const GLuint count = clip_vec->count;
@@ -141,16 +147,20 @@ static GLvector4f * _XFORMAPI TAG(cliptest_np_points4)( GLvector4f *clip_vec,
       mask |= (((cw < -cx) << CLIP_LEFT_SHIFT));
       mask |= (((cw < cy) << CLIP_TOP_SHIFT));
       mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT));
-      mask |= (((cw < cz) << CLIP_FAR_SHIFT));
-      mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
+      if (viewport_z_clip) {
+	 mask |= (((cw < cz) << CLIP_FAR_SHIFT));
+	 mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
+      }
 #else /* !defined(macintosh)) */
       GLubyte mask = 0;
       if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT;
       if ( cx + cw < 0) mask |= CLIP_LEFT_BIT;
       if (-cy + cw < 0) mask |= CLIP_TOP_BIT;
       if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT;
-      if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
-      if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
+      if (viewport_z_clip) {
+	 if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
+	 if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
+      }
 #endif /* defined(macintosh) */
 
       clipMask[i] = mask;
@@ -171,7 +181,8 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec,
                                                      GLvector4f *proj_vec,
                                                      GLubyte clipMask[],
                                                      GLubyte *orMask,
-                                                     GLubyte *andMask )
+                                                     GLubyte *andMask,
+						     GLboolean viewport_z_clip )
 {
    const GLuint stride = clip_vec->stride;
    const GLuint count = clip_vec->count;
@@ -187,8 +198,10 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec,
       else if (cx < -1.0)  mask |= CLIP_LEFT_BIT;
       if (cy >  1.0)       mask |= CLIP_TOP_BIT;
       else if (cy < -1.0)  mask |= CLIP_BOTTOM_BIT;
-      if (cz >  1.0)       mask |= CLIP_FAR_BIT;
-      else if (cz < -1.0)  mask |= CLIP_NEAR_BIT;
+      if (viewport_z_clip) {
+	 if (cz >  1.0)       mask |= CLIP_FAR_BIT;
+	 else if (cz < -1.0)  mask |= CLIP_NEAR_BIT;
+      }
       clipMask[i] = mask;
       tmpOrMask |= mask;
       tmpAndMask &= mask;
@@ -204,7 +217,8 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec,
                                                      GLvector4f *proj_vec,
                                                      GLubyte clipMask[],
                                                      GLubyte *orMask,
-                                                     GLubyte *andMask )
+                                                     GLubyte *andMask,
+						     GLboolean viewport_z_clip )
 {
    const GLuint stride = clip_vec->stride;
    const GLuint count = clip_vec->count;
@@ -231,7 +245,7 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec,
 }
 
 
-static void TAG(init_c_cliptest)( void )
+void TAG(init_c_cliptest)( void )
 {
    _mesa_clip_tab[4] = TAG(cliptest_points4);
    _mesa_clip_tab[3] = TAG(cliptest_points3);
diff --git a/src/mesa/math/m_debug_clip.c b/src/mesa/math/m_debug_clip.c
index 460fed4..f2b757a 100644
--- a/src/mesa/math/m_debug_clip.c
+++ b/src/mesa/math/m_debug_clip.c
@@ -67,7 +67,8 @@ static GLvector4f *ref_cliptest_points4( GLvector4f *clip_vec,
 					 GLvector4f *proj_vec,
 					 GLubyte clipMask[],
 					 GLubyte *orMask,
-					 GLubyte *andMask )
+					 GLubyte *andMask,
+					 GLboolean viewport_z_clip )
 {
    const GLuint stride = clip_vec->stride;
    const GLuint count = clip_vec->count;
@@ -87,8 +88,10 @@ static GLvector4f *ref_cliptest_points4( GLvector4f *clip_vec,
       if (  cx + cw < 0 ) mask |= CLIP_LEFT_BIT;
       if ( -cy + cw < 0 ) mask |= CLIP_TOP_BIT;
       if (  cy + cw < 0 ) mask |= CLIP_BOTTOM_BIT;
-      if ( -cz + cw < 0 ) mask |= CLIP_FAR_BIT;
-      if (  cz + cw < 0 ) mask |= CLIP_NEAR_BIT;
+      if (viewport_z_clip) {
+	 if ( -cz + cw < 0 ) mask |= CLIP_FAR_BIT;
+	 if (  cz + cw < 0 ) mask |= CLIP_NEAR_BIT;
+      }
       clipMask[i] = mask;
       if ( mask ) {
 	 c++;
diff --git a/src/mesa/math/m_xform.h b/src/mesa/math/m_xform.h
index 7ef76e0..33421ad 100644
--- a/src/mesa/math/m_xform.h
+++ b/src/mesa/math/m_xform.h
@@ -43,7 +43,8 @@
 
 extern void
 _math_init_transformation(void);
-
+extern void
+init_c_cliptest(void);
 
 /* KW: Clip functions now do projective divide as well.  The projected
  * coordinates are very useful to us because they let us cull
@@ -102,7 +103,8 @@ typedef GLvector4f * (_XFORMAPIP clip_func)( GLvector4f *vClip,
 					     GLvector4f *vProj,
 					     GLubyte clipMask[],
 					     GLubyte *orMask,
-					     GLubyte *andMask );
+					     GLubyte *andMask,
+					     GLboolean viewport_z_clip );
 
 typedef void (*dotprod_func)( GLfloat *out,
 			      GLuint out_stride,
diff --git a/src/mesa/sparc/clip.S b/src/mesa/sparc/clip.S
index 208843c..dc23917 100644
--- a/src/mesa/sparc/clip.S
+++ b/src/mesa/sparc/clip.S
@@ -58,7 +58,8 @@ clip_table:
 	.byte	31, 29, 31, 30, 27, 25, 27, 26
 
 /* GLvector4f *clip_vec, GLvector4f *proj_vec, 
-   GLubyte clipMask[], GLubyte *orMask, GLubyte *andMask */
+   GLubyte clipMask[], GLubyte *orMask, GLubyte *andMask,
+   GLboolean viewport_z_enable */
 
 	.align		64
 __pc_tramp:
diff --git a/src/mesa/sparc/sparc.c b/src/mesa/sparc/sparc.c
index d2286a2..cea0c7c 100644
--- a/src/mesa/sparc/sparc.c
+++ b/src/mesa/sparc/sparc.c
@@ -78,13 +78,15 @@ extern GLvector4f  *_mesa_sparc_cliptest_points4(GLvector4f *clip_vec,
 						 GLvector4f *proj_vec,
 						 GLubyte clipMask[],
 						 GLubyte *orMask,
-						 GLubyte *andMask);
+						 GLubyte *andMask,
+						 GLboolean viewport_z_clip);
 
 extern GLvector4f  *_mesa_sparc_cliptest_points4_np(GLvector4f *clip_vec,
 						    GLvector4f *proj_vec,
 						    GLubyte clipMask[],
 						    GLubyte *orMask,
-						    GLubyte *andMask);
+						    GLubyte *andMask,
+						    GLboolean viewport_z_clip);
 
 #define NORM_ARGS	const GLmatrix *mat,				\
 			GLfloat scale,					\
diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c
index 26e23f0..1a428fb 100644
--- a/src/mesa/swrast/s_depth.c
+++ b/src/mesa/swrast/s_depth.c
@@ -497,6 +497,33 @@ depth_test_span32( GLcontext *ctx, GLuint n,
    return passed;
 }
 
+/* Apply ARB_depth_clamp to span of fragments. */
+void
+_swrast_depth_clamp_span( GLcontext *ctx, SWspan *span )
+{
+   struct gl_framebuffer *fb = ctx->DrawBuffer;
+   struct gl_renderbuffer *rb = fb->_DepthBuffer;
+   const GLuint count = span->end;
+   GLuint *zValues = span->array->z;
+   GLuint near, far;
+   int i;
+
+   if (rb->DataType == GL_UNSIGNED_SHORT) {
+      near = FLOAT_TO_UINT(ctx->Viewport.Near);
+      far = FLOAT_TO_UINT(ctx->Viewport.Far);
+   } else {
+      assert(rb->DataType == GL_UNSIGNED_INT);
+      CLAMPED_FLOAT_TO_USHORT(near, ctx->Viewport.Near);
+      CLAMPED_FLOAT_TO_USHORT(far, ctx->Viewport.Far);
+   }
+   for (i = 0; i < count; i++) {
+      if (zValues[i] < near)
+	 zValues[i] = near;
+      if (zValues[i] > far)
+	 zValues[i] = far;
+   }
+}
+
 
 
 /*
diff --git a/src/mesa/swrast/s_depth.h b/src/mesa/swrast/s_depth.h
index 3688625..7eae366 100644
--- a/src/mesa/swrast/s_depth.h
+++ b/src/mesa/swrast/s_depth.h
@@ -33,6 +33,8 @@
 extern GLuint
 _swrast_depth_test_span( GLcontext *ctx, SWspan *span);
 
+extern void
+_swrast_depth_clamp_span( GLcontext *ctx, SWspan *span );
 
 extern GLboolean
 _swrast_depth_bounds_test( GLcontext *ctx, SWspan *span );
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index 0e2793b..a45eac4 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -880,6 +880,9 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
       stipple_polygon_span(ctx, span);
    }
 
+   if (ctx->Transform.DepthClamp)
+      _swrast_depth_clamp_span(ctx, span);
+
    /* Stencil and Z testing */
    if (ctx->Stencil._Enabled || ctx->Depth.Test) {
       if (!(span->arrayMask & SPAN_Z))
diff --git a/src/mesa/tnl/t_rasterpos.c b/src/mesa/tnl/t_rasterpos.c
index f1fdddf..99b6787 100644
--- a/src/mesa/tnl/t_rasterpos.c
+++ b/src/mesa/tnl/t_rasterpos.c
@@ -46,11 +46,10 @@
  * \return zero if outside view volume, or one if inside.
  */
 static GLuint
-viewclip_point( const GLfloat v[] )
+viewclip_point_xy( const GLfloat v[] )
 {
    if (   v[0] > v[3] || v[0] < -v[3]
-       || v[1] > v[3] || v[1] < -v[3]
-       || v[2] > v[3] || v[2] < -v[3] ) {
+       || v[1] > v[3] || v[1] < -v[3] ) {
       return 0;
    }
    else {
@@ -408,18 +407,18 @@ _tnl_RasterPos(GLcontext *ctx, const GLfloat vObj[4])
       /* apply projection matrix:  clip = Proj * eye */
       TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye );
 
-      /* clip to view volume */
-      if (ctx->Transform.RasterPositionUnclipped) {
-         /* GL_IBM_rasterpos_clip: only clip against Z */
+      /* clip to view volume. */
+      if (!ctx->Transform.DepthClamp) {
          if (viewclip_point_z(clip) == 0) {
             ctx->Current.RasterPosValid = GL_FALSE;
             return;
          }
       }
-      else if (viewclip_point(clip) == 0) {
-         /* Normal OpenGL behaviour */
-         ctx->Current.RasterPosValid = GL_FALSE;
-         return;
+      if (!ctx->Transform.RasterPositionUnclipped) {
+         if (viewclip_point_xy(clip) == 0) {
+            ctx->Current.RasterPosValid = GL_FALSE;
+            return;
+         }
       }
 
       /* clip to user clipping planes */
@@ -443,6 +442,12 @@ _tnl_RasterPos(GLcontext *ctx, const GLfloat vObj[4])
                                   / ctx->DrawBuffer->_DepthMaxF;
       ctx->Current.RasterPos[3] = clip[3];
 
+      if (ctx->Transform.DepthClamp) {
+	 ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3],
+					   ctx->Viewport.Near,
+					   ctx->Viewport.Far);
+      }
+
       /* compute raster distance */
       if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
          ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index dc954bc..5d89f8b 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -137,7 +137,8 @@ do_ndc_cliptest(GLcontext *ctx, struct vp_stage_data *store)
                                             &store->ndcCoords,
                                             store->clipmask,
                                             &store->ormask,
-                                            &store->andmask );
+                                            &store->andmask,
+					    !ctx->Transform.DepthClamp );
    }
    else {
       VB->NdcPtr = NULL;
@@ -145,7 +146,8 @@ do_ndc_cliptest(GLcontext *ctx, struct vp_stage_data *store)
                                             NULL,
                                             store->clipmask,
                                             &store->ormask,
-                                            &store->andmask );
+                                            &store->andmask,
+					    !ctx->Transform.DepthClamp );
    }
 
    if (store->andmask) {
diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c
index 30aa7c4..6a74641 100644
--- a/src/mesa/tnl/t_vb_vertex.c
+++ b/src/mesa/tnl/t_vb_vertex.c
@@ -173,7 +173,8 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
 					    &store->proj,
 					    store->clipmask,
 					    &store->ormask,
-					    &store->andmask );
+					    &store->andmask,
+					    !ctx->Transform.DepthClamp );
    }
    else {
       VB->NdcPtr = NULL;
@@ -181,7 +182,8 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
 					    NULL,
 					    store->clipmask,
 					    &store->ormask,
-					    &store->andmask );
+					    &store->andmask,
+					    !ctx->Transform.DepthClamp );
    }
 
    if (store->andmask)
diff --git a/src/mesa/x86/x86_xform.c b/src/mesa/x86/x86_xform.c
index 16b2b26..52f6b25 100644
--- a/src/mesa/x86/x86_xform.c
+++ b/src/mesa/x86/x86_xform.c
@@ -60,21 +60,24 @@ _mesa_x86_cliptest_points4( GLvector4f *clip_vec,
 			    GLvector4f *proj_vec,
 			    GLubyte clipMask[],
 			    GLubyte *orMask,
-			    GLubyte *andMask );
+			    GLubyte *andMask,
+			    GLboolean viewport_z_clip );
 
 extern GLvector4f * _ASMAPI
 _mesa_x86_cliptest_points4_np( GLvector4f *clip_vec,
 			       GLvector4f *proj_vec,
 			       GLubyte clipMask[],
 			       GLubyte *orMask,
-			       GLubyte *andMask );
+			       GLubyte *andMask,
+			       GLboolean viewport_z_clip );
 
 extern void _ASMAPI
 _mesa_v16_x86_cliptest_points4( GLfloat *first_vert,
 				GLfloat *last_vert,
 				GLubyte *or_mask,
 				GLubyte *and_mask,
-				GLubyte *clip_mask );
+				GLubyte *clip_mask,
+				GLboolean viewport_z_clip );
 
 extern void _ASMAPI
 _mesa_v16_x86_general_xform( GLfloat *dest,




More information about the mesa-commit mailing list