mesa: Add support for AMD_depth_clamp_separate
authorSagar Ghuge <sagar.ghuge@intel.com>
Fri, 27 Jul 2018 21:55:57 +0000 (14:55 -0700)
committerAnuj Phogat <anuj.phogat@gmail.com>
Tue, 28 Aug 2018 19:57:27 +0000 (12:57 -0700)
Enable _mesa_PushAttrib() and _mesa_PopAttrib() to handle
GL_DEPTH_CLAMP_NEAR_AMD and GL_DEPTH_CLAMP_FAR_AMD tokens.

Remove DepthClamp, because DepthClampNear + DepthClampFar replaces it,
as suggested by Marek Olsak.

Driver that enables AMD_depth_clamp_separate will only ever look at
DepthClampNear and DepthClampFar, as suggested by Ian Romanick.

v2: 1) Remove unnecessary parentheses (Marek Olsak)
    2) if AMD_depth_clamp_separate is unsupported, TEST_AND_UPDATE
       GL_DEPTH_CLAMP only (Marek Olsak)
    3) Clamp against near and far plane separately (Marek Olsak)
    4) Clip point separately for near and far Z clipping plane (Marek
       Olsak)

v3: Clamp raster position zw to the range [min(n,f), 0] for near plane
    and [0, max(n,f)] for far plane (Marek Olsak)

v4: Use MIN2 and MAX2 instead of CLAMP (Marek Olsak)

Signed-off-by: Sagar Ghuge <sagar.ghuge@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
12 files changed:
src/mesa/drivers/dri/i965/genX_state_upload.c
src/mesa/main/attrib.c
src/mesa/main/enable.c
src/mesa/main/get.c
src/mesa/main/get_hash_params.py
src/mesa/main/mtypes.h
src/mesa/main/rastpos.c
src/mesa/state_tracker/st_atom_rasterizer.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/swrast/s_span.c
src/mesa/tnl/t_vb_program.c
src/mesa/tnl/t_vb_vertex.c

index ca24394aa7d48a4a85dc995cdfc32a19896fb6f8..24977a7bba22263ee3a9c3530ac4f910dc8e5045 100644 (file)
@@ -1399,7 +1399,8 @@ genX(upload_clip_state)(struct brw_context *brw)
       clip.ScreenSpaceViewportYMax = 1;
 
       clip.ViewportXYClipTestEnable = true;
-      clip.ViewportZClipTestEnable = !ctx->Transform.DepthClamp;
+      clip.ViewportZClipTestEnable = !(ctx->Transform.DepthClampNear &&
+                                       ctx->Transform.DepthClampFar);
 
       /* _NEW_TRANSFORM */
       if (GEN_GEN == 5 || GEN_IS_G4X) {
@@ -1493,7 +1494,8 @@ genX(upload_clip_state)(struct brw_context *brw)
       clip.UserClipDistanceCullTestEnableBitmask =
          brw_vue_prog_data(brw->vs.base.prog_data)->cull_distance_mask;
 
-      clip.ViewportZClipTestEnable = !ctx->Transform.DepthClamp;
+      clip.ViewportZClipTestEnable = !(ctx->Transform.DepthClampNear &&
+                                       ctx->Transform.DepthClampFar);
 #endif
 
       /* _NEW_LIGHT */
@@ -2338,7 +2340,7 @@ genX(upload_cc_viewport)(struct brw_context *brw)
    for (unsigned i = 0; i < viewport_count; i++) {
       /* _NEW_VIEWPORT | _NEW_TRANSFORM */
       const struct gl_viewport_attrib *vp = &ctx->ViewportArray[i];
-      if (ctx->Transform.DepthClamp) {
+      if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) {
          ccv.MinimumDepth = MIN2(vp->Near, vp->Far);
          ccv.MaximumDepth = MAX2(vp->Near, vp->Far);
       } else {
@@ -4605,7 +4607,8 @@ genX(upload_raster)(struct brw_context *brw)
       raster.ScissorRectangleEnable = ctx->Scissor.EnableFlags;
 
       /* _NEW_TRANSFORM */
-      if (!ctx->Transform.DepthClamp) {
+      if (!(ctx->Transform.DepthClampNear &&
+            ctx->Transform.DepthClampFar)) {
 #if GEN_GEN >= 9
          raster.ViewportZFarClipTestEnable = true;
          raster.ViewportZNearClipTestEnable = true;
index cbe93ab6faa60ec5853f0d0b6165872a8d1b8321..a46fec73fdfec17157c9acd0e1c0c4c7eecf308b 100644 (file)
@@ -72,7 +72,8 @@ struct gl_enable_attrib
    GLbitfield ClipPlanes;
    GLboolean ColorMaterial;
    GLboolean CullFace;
-   GLboolean DepthClamp;
+   GLboolean DepthClampNear;
+   GLboolean DepthClampFar;
    GLboolean DepthTest;
    GLboolean Dither;
    GLboolean Fog;
@@ -336,7 +337,8 @@ _mesa_PushAttrib(GLbitfield mask)
       attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled;
       attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
       attr->CullFace = ctx->Polygon.CullFlag;
-      attr->DepthClamp = ctx->Transform.DepthClamp;
+      attr->DepthClampNear = ctx->Transform.DepthClampNear;
+      attr->DepthClampFar = ctx->Transform.DepthClampFar;
       attr->DepthTest = ctx->Depth.Test;
       attr->Dither = ctx->Color.DitherFlag;
       attr->Fog = ctx->Fog.Enabled;
@@ -627,8 +629,18 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable)
    TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial,
                    GL_COLOR_MATERIAL);
    TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
-   TEST_AND_UPDATE(ctx->Transform.DepthClamp, enable->DepthClamp,
-                   GL_DEPTH_CLAMP);
+
+   if (!ctx->Extensions.AMD_depth_clamp_separate) {
+      TEST_AND_UPDATE(ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar,
+                      enable->DepthClampNear && enable->DepthClampFar,
+                      GL_DEPTH_CLAMP);
+   } else {
+      TEST_AND_UPDATE(ctx->Transform.DepthClampNear, enable->DepthClampNear,
+                      GL_DEPTH_CLAMP_NEAR_AMD);
+      TEST_AND_UPDATE(ctx->Transform.DepthClampFar, enable->DepthClampFar,
+                      GL_DEPTH_CLAMP_FAR_AMD);
+   }
+
    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->Fog.Enabled, enable->Fog, GL_FOG);
@@ -1433,9 +1445,23 @@ _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);
+
+               if (!ctx->Extensions.AMD_depth_clamp_separate) {
+                  if (xform->DepthClampNear != ctx->Transform.DepthClampNear &&
+                      xform->DepthClampFar != ctx->Transform.DepthClampFar) {
+                     _mesa_set_enable(ctx, GL_DEPTH_CLAMP,
+                                      ctx->Transform.DepthClampNear &&
+                                      ctx->Transform.DepthClampFar);
+                  }
+               } else {
+                  if (xform->DepthClampNear != ctx->Transform.DepthClampNear)
+                     _mesa_set_enable(ctx, GL_DEPTH_CLAMP_NEAR_AMD,
+                                      ctx->Transform.DepthClampNear);
+                  if (xform->DepthClampFar != ctx->Transform.DepthClampFar)
+                     _mesa_set_enable(ctx, GL_DEPTH_CLAMP_FAR_AMD,
+                                      ctx->Transform.DepthClampFar);
+               }
+
                if (ctx->Extensions.ARB_clip_control)
                   _mesa_ClipControl(xform->ClipOrigin, xform->ClipDepthMode);
             }
index d1b2f3a962505dc8bbe1b09cd86ee5c223c9b0f8..30d275075d5714a46f71a481260f385c565433c5 100644 (file)
@@ -1007,12 +1007,14 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
          if (!_mesa_is_desktop_gl(ctx))
             goto invalid_enum_error;
          CHECK_EXTENSION(ARB_depth_clamp, cap);
-         if (ctx->Transform.DepthClamp == state)
+         if (ctx->Transform.DepthClampNear == state &&
+             ctx->Transform.DepthClampFar == state)
             return;
          FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepthClamp ? 0 :
                                                            _NEW_TRANSFORM);
          ctx->NewDriverState |= ctx->DriverFlags.NewDepthClamp;
-         ctx->Transform.DepthClamp = state;
+         ctx->Transform.DepthClampNear = state;
+         ctx->Transform.DepthClampFar = state;
          break;
 
       case GL_FRAGMENT_SHADER_ATI:
@@ -1684,7 +1686,8 @@ _mesa_IsEnabled( GLenum cap )
          if (!_mesa_is_desktop_gl(ctx))
             goto invalid_enum_error;
          CHECK_EXTENSION(ARB_depth_clamp);
-         return ctx->Transform.DepthClamp;
+         return ctx->Transform.DepthClampNear ||
+                ctx->Transform.DepthClampFar;
 
       case GL_FRAGMENT_SHADER_ATI:
          if (ctx->API != API_OPENGL_COMPAT)
index f870b217db5a281f54fc07407a96517a8b1b2f41..16625e92e25aec25f2d64bd5895b5db2c160b20b 100644 (file)
@@ -698,6 +698,10 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
       v->value_int_4[3] = GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 3);
       break;
 
+   case GL_DEPTH_CLAMP:
+      v->value_bool = ctx->Transform.DepthClampNear || ctx->Transform.DepthClampFar;
+      break;
+
    case GL_EDGE_FLAG:
       v->value_bool = ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F;
       break;
index ed5328df7cb768c6e1201e2c7da2811f503b327c..87ed4bfaeac873ab86e03e73f98c0a2762d98dd9 100644 (file)
@@ -903,7 +903,7 @@ descriptor=[
   [ "DEPTH_BOUNDS_EXT", "CONTEXT_FLOAT2(Depth.BoundsMin), extra_EXT_depth_bounds_test" ],
 
 # GL_ARB_depth_clamp
-  [ "DEPTH_CLAMP", "CONTEXT_BOOL(Transform.DepthClamp), extra_ARB_depth_clamp" ],
+  [ "DEPTH_CLAMP", "LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_ARB_depth_clamp" ],
 
 # GL_ATI_fragment_shader
   [ "FRAGMENT_SHADER_ATI", "CONTEXT_BOOL(ATIFragmentShader.Enabled), extra_ATI_fragment_shader" ],
index e752046d1b8772002f7d856d82bdab5a9d1e8f4c..5ce0b4b584719abda0aa88fb5d52bbfb07872f1c 100644 (file)
@@ -1282,7 +1282,6 @@ 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 DepthClampNear;                   /**< GL_AMD_depth_clamp_separate */
    GLboolean DepthClampFar;                    /**< GL_AMD_depth_clamp_separate */
    /** GL_ARB_clip_control */
index 1ca83c78b0a93532bda5ea17b54cee2590adeb33..0308003905b7e24859ae00ef01f1b8a8ae2e26d2 100644 (file)
@@ -61,16 +61,35 @@ viewclip_point_xy( const GLfloat v[] )
 
 
 /**
- * Clip a point against the far/near Z clipping planes.
+ * Clip a point against the near Z clipping planes.
  *
  * \param v vertex vector describing the point to clip.
  *
  * \return zero if outside view volume, or one if inside.
  */
 static GLuint
-viewclip_point_z( const GLfloat v[] )
+viewclip_point_near_z( const GLfloat v[] )
 {
-   if (v[2] > v[3] || v[2] < -v[3] ) {
+   if (v[2] < -v[3]) {
+      return 0;
+   }
+   else {
+      return 1;
+   }
+}
+
+
+/**
+ * Clip a point against the far Z clipping planes.
+ *
+ * \param v vertex vector describing the point to clip.
+ *
+ * \return zero if outside view volume, or one if inside.
+ */
+static GLuint
+viewclip_point_far_z( const GLfloat v[] )
+{
+   if (v[2] > v[3]) {
       return 0;
    }
    else {
@@ -389,8 +408,14 @@ _mesa_RasterPos(struct gl_context *ctx, const GLfloat vObj[4])
       TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye );
 
       /* clip to view volume. */
-      if (!ctx->Transform.DepthClamp) {
-         if (viewclip_point_z(clip) == 0) {
+      if (!ctx->Transform.DepthClampNear) {
+         if (viewclip_point_near_z(clip) == 0) {
+            ctx->Current.RasterPosValid = GL_FALSE;
+            return;
+         }
+      }
+      if (!ctx->Transform.DepthClampFar) {
+         if (viewclip_point_far_z(clip) == 0) {
             ctx->Current.RasterPosValid = GL_FALSE;
             return;
          }
@@ -420,10 +445,22 @@ _mesa_RasterPos(struct gl_context *ctx, const GLfloat vObj[4])
       ctx->Current.RasterPos[2] = ndc[2] * scale[2] + translate[2];
       ctx->Current.RasterPos[3] = clip[3];
 
-      if (ctx->Transform.DepthClamp) {
-        ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3],
-                                          ctx->ViewportArray[0].Near,
-                                          ctx->ViewportArray[0].Far);
+      if (ctx->Transform.DepthClampNear &&
+          ctx->Transform.DepthClampFar) {
+         ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3],
+                                           ctx->ViewportArray[0].Near,
+                                           ctx->ViewportArray[0].Far);
+      } else {
+         /* Clamp against near and far plane separately */
+         if (ctx->Transform.DepthClampNear) {
+            ctx->Current.RasterPos[3] = MAX2(ctx->Current.RasterPos[3],
+                                             ctx->ViewportArray[0].Near);
+         }
+
+         if (ctx->Transform.DepthClampFar) {
+            ctx->Current.RasterPos[3] = MIN2(ctx->Current.RasterPos[3],
+                                             ctx->ViewportArray[0].Far);
+         }
       }
 
       /* compute raster distance */
index 0383b8ac4adfc828f63bf971d25ab7a97a7cf4b2..1f66b9d05976c84715c0b7c3ed23974fe35c4c4a 100644 (file)
@@ -294,7 +294,8 @@ st_update_rasterizer(struct st_context *st)
    }
 
    /* _NEW_TRANSFORM */
-   raster->depth_clip = !ctx->Transform.DepthClamp;
+   raster->depth_clip = !(ctx->Transform.DepthClampNear &&
+                          ctx->Transform.DepthClampFar);
    raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled;
    raster->clip_halfz = (ctx->Transform.ClipDepthMode == GL_ZERO_TO_ONE);
 
index b8895684bc26dc0952b0ce5faac458b8a3576c80..67bbb358500614707d13ee950f3b1bb23fe8359c 100644 (file)
@@ -677,7 +677,8 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
                                         ctx->Color._ClampFragmentColor;
       rasterizer.half_pixel_center = 1;
       rasterizer.bottom_edge_rule = 1;
-      rasterizer.depth_clip = !ctx->Transform.DepthClamp;
+      rasterizer.depth_clip = !(ctx->Transform.DepthClampNear &&
+                                ctx->Transform.DepthClampFar);
       rasterizer.scissor = ctx->Scissor.EnableFlags;
       cso_set_rasterizer(cso, &rasterizer);
    }
index 87b72e81970440daf87a1677bc3b7f40278ab9e4..f50b549a97fe6c8849a6bdbaf9293ed79a57a381 100644 (file)
@@ -1219,7 +1219,7 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
       if (!(span->arrayMask & SPAN_Z))
          _swrast_span_interpolate_z(ctx, span);
 
-      if (ctx->Transform.DepthClamp)
+      if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar)
         _swrast_depth_clamp_span(ctx, span);
 
       if (_mesa_stencil_is_enabled(ctx)) {
index 19be5eed63a21ff82c00967ade47757d8a7f66c7..8d8aca614e3cf950a070d5ac64b6597640655bf2 100644 (file)
@@ -143,7 +143,8 @@ do_ndc_cliptest(struct gl_context *ctx, struct vp_stage_data *store)
                                             store->clipmask,
                                             &store->ormask,
                                             &store->andmask,
-                                           !ctx->Transform.DepthClamp );
+                                           !(ctx->Transform.DepthClampNear &&
+                                              ctx->Transform.DepthClampFar) );
    }
    else {
       VB->NdcPtr = NULL;
@@ -152,7 +153,8 @@ do_ndc_cliptest(struct gl_context *ctx, struct vp_stage_data *store)
                                             store->clipmask,
                                             &store->ormask,
                                             &store->andmask,
-                                           !ctx->Transform.DepthClamp );
+                                           !(ctx->Transform.DepthClampNear &&
+                                              ctx->Transform.DepthClampFar) );
    }
 
    if (store->andmask) {
index 71a32b49528ec3a1a176181c2975d3a66c5c18ee..4fb3659a3583d8757f7fd063e15208d9ed02afce 100644 (file)
@@ -123,7 +123,7 @@ tnl_clip_prepare(struct gl_context *ctx)
    /* Neither the x86 nor sparc asm cliptest functions have been updated
     * for ARB_depth_clamp, so force the C paths.
     */
-   if (ctx->Transform.DepthClamp) {
+   if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) {
       static GLboolean c_funcs_installed = GL_FALSE;
       if (!c_funcs_installed) {
          init_c_cliptest();
@@ -191,7 +191,8 @@ static GLboolean run_vertex_stage( struct gl_context *ctx,
                                            store->clipmask,
                                            &store->ormask,
                                            &store->andmask,
-                                           !ctx->Transform.DepthClamp );
+                                           !(ctx->Transform.DepthClampNear &&
+                                              ctx->Transform.DepthClampFar) );
    }
    else {
       VB->NdcPtr = NULL;
@@ -200,7 +201,8 @@ static GLboolean run_vertex_stage( struct gl_context *ctx,
                                            store->clipmask,
                                            &store->ormask,
                                            &store->andmask,
-                                           !ctx->Transform.DepthClamp );
+                                           !(ctx->Transform.DepthClampNear &&
+                                              ctx->Transform.DepthClampFar) );
    }
 
    if (store->andmask)