summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2009-08-26 09:51:15 -0700
committerEric Anholt <[email protected]>2009-09-08 14:30:15 -0700
commitb4922b533155cc139ebafb111502bb55d2ad2ccf (patch)
treea784133f9de7e5fccda5305ab926bebc5ffbaf19
parent3e4539a471da48066a83eda8e14301dbc4dbf6db (diff)
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.
-rw-r--r--src/mesa/drivers/dri/swrast/swrast.c1
-rw-r--r--src/mesa/drivers/x11/xm_api.c1
-rw-r--r--src/mesa/glapi/ARB_depth_clamp.xml12
-rw-r--r--src/mesa/glapi/Makefile1
-rw-r--r--src/mesa/glapi/gl_API.xml2
-rw-r--r--src/mesa/main/attrib.c7
-rw-r--r--src/mesa/main/enable.c20
-rw-r--r--src/mesa/main/extensions.c2
-rw-r--r--src/mesa/main/get_gen.py4
-rw-r--r--src/mesa/main/mtypes.h2
-rw-r--r--src/mesa/math/m_clip_tmp.h44
-rw-r--r--src/mesa/math/m_debug_clip.c9
-rw-r--r--src/mesa/math/m_xform.h6
-rw-r--r--src/mesa/sparc/clip.S3
-rw-r--r--src/mesa/sparc/sparc.c6
-rw-r--r--src/mesa/swrast/s_depth.c27
-rw-r--r--src/mesa/swrast/s_depth.h2
-rw-r--r--src/mesa/swrast/s_span.c3
-rw-r--r--src/mesa/tnl/t_rasterpos.c25
-rw-r--r--src/mesa/tnl/t_vb_program.c6
-rw-r--r--src/mesa/tnl/t_vb_vertex.c6
-rw-r--r--src/mesa/x86/x86_xform.c9
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 a858af30c11..9a130d61cf4 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 2c7be9f182d..78545d0e170 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 00000000000..157c9a86b12
--- /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 65edab7cec9..22f65b74c29 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 1dfd92be080..920ce80c459 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 ab99ca1c642..0fb8fa3bba2 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 4bc54771e97..d066153fc2c 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 e3070b1547d..ea67f820af5 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 2878c1b5526..364d8c55c45 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 6b64bf8139f..20cd3aa5c0d 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 f3a589be051..2e30964057c 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 460fed4a754..f2b757a91b8 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 7ef76e0b926..33421ad1c0a 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 208843c6069..dc239171ff9 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 d2286a2c837..cea0c7cecf1 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 26e23f02d59..1a428fb1a28 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 36886256830..7eae3667428 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 0e2793b4740..a45eac438e4 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 f1fdddf0f5a..99b67874556 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 dc954bcba14..5d89f8bc313 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 30aa7c40868..6a746417c87 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 16b2b26bcc8..52f6b25d817 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,