Mesa (master): llvmpipe: add plumbing for ARB_depth_clamp

Jose Fonseca jrfonseca at kemper.freedesktop.org
Wed Dec 11 18:38:58 UTC 2013


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

Author: Matthew McClure <mcclurem at vmware.com>
Date:   Tue Dec 10 13:10:03 2013 -0800

llvmpipe: add plumbing for ARB_depth_clamp

With this patch llvmpipe will adhere to the ARB_depth_clamp enabled state when
clamping the fragment's zw value. To support this, the variant key now includes
the depth_clamp state. key->depth_clamp is derived from pipe_rasterizer_state's
(depth_clip == 0), thus depth clamp is only enabled when depth clip is disabled.

Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Reviewed-by: José Fonseca <jfonseca at vmware.com>

---

 src/gallium/drivers/llvmpipe/lp_setup.c    |   11 +++-
 src/gallium/drivers/llvmpipe/lp_state_fs.c |   83 +++++++++++++++++-----------
 src/gallium/drivers/llvmpipe/lp_state_fs.h |    1 +
 src/gallium/include/pipe/p_state.h         |    2 +
 4 files changed, 62 insertions(+), 35 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 31aaf96..49962af 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -656,6 +656,7 @@ lp_setup_set_viewports(struct lp_setup_context *setup,
                        unsigned num_viewports,
                        const struct pipe_viewport_state *viewports)
 {
+   struct llvmpipe_context *lp = llvmpipe_context(setup->pipe);
    unsigned i;
 
    LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
@@ -670,8 +671,14 @@ lp_setup_set_viewports(struct lp_setup_context *setup,
       float min_depth;
       float max_depth;
 
-      min_depth = viewports[i].translate[2];
-      max_depth = viewports[i].translate[2] + viewports[i].scale[2];
+      if (lp->rasterizer->clip_halfz == 0) {
+         float half_depth = viewports[i].scale[2];
+         min_depth = viewports[i].translate[2] - half_depth;
+         max_depth = min_depth + half_depth * 2.0f;
+      } else {
+         min_depth = viewports[i].translate[2];
+         max_depth = min_depth + viewports[i].scale[2];
+      }
 
       if (setup->viewports[i].min_depth != min_depth ||
           setup->viewports[i].max_depth != max_depth) {
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 93c24f6..2118c1a 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -445,47 +445,52 @@ generate_fs_loop(struct gallivm_state *gallivm,
                                          0);
 
       if (pos0 != -1 && outputs[pos0][2]) {
-         LLVMValueRef viewport, min_depth, max_depth;
-         LLVMValueRef viewport_index;
-         struct lp_build_context f32_bld;
-
-         assert(type.floating);
-         lp_build_context_init(&f32_bld, gallivm, type);
+         z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
 
          /*
-          * Assumes clamping of the viewport index will occur in setup/gs. Value
-          * is passed through the rasterization stage via lp_rast_shader_inputs.
-          *
-          * See: draw_clamp_viewport_idx and lp_clamp_viewport_idx for clamping
-          *      semantics.
+          * Clamp according to ARB_depth_clamp semantics.
           */
-         viewport_index = lp_jit_thread_data_raster_state_viewport_index(gallivm,
-                             thread_data_ptr);
+         if (key->depth_clamp) {
+            LLVMValueRef viewport, min_depth, max_depth;
+            LLVMValueRef viewport_index;
+            struct lp_build_context f32_bld;
 
-         /*
-          * Load the min and max depth from the lp_jit_context.viewports
-          * array of lp_jit_viewport structures.
-          */
-         viewport = lp_llvm_viewport(context_ptr, gallivm, viewport_index);
+            assert(type.floating);
+            lp_build_context_init(&f32_bld, gallivm, type);
 
-         /* viewports[viewport_index].min_depth */
-         min_depth = LLVMBuildExtractElement(builder, viewport,
-                        lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MIN_DEPTH),
-                        "");
-         min_depth = lp_build_broadcast_scalar(&f32_bld, min_depth);
+            /*
+             * Assumes clamping of the viewport index will occur in setup/gs. Value
+             * is passed through the rasterization stage via lp_rast_shader_inputs.
+             *
+             * See: draw_clamp_viewport_idx and lp_clamp_viewport_idx for clamping
+             *      semantics.
+             */
+            viewport_index = lp_jit_thread_data_raster_state_viewport_index(gallivm,
+                                thread_data_ptr);
 
-         /* viewports[viewport_index].max_depth */
-         max_depth = LLVMBuildExtractElement(builder, viewport,
-                        lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MAX_DEPTH),
-                        "");
-         max_depth = lp_build_broadcast_scalar(&f32_bld, max_depth);
+            /*
+             * Load the min and max depth from the lp_jit_context.viewports
+             * array of lp_jit_viewport structures.
+             */
+            viewport = lp_llvm_viewport(context_ptr, gallivm, viewport_index);
 
-         z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
+            /* viewports[viewport_index].min_depth */
+            min_depth = LLVMBuildExtractElement(builder, viewport,
+                           lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MIN_DEPTH),
+                           "");
+            min_depth = lp_build_broadcast_scalar(&f32_bld, min_depth);
 
-         /*
-          * Clamp to the min and max depth values for the given viewport.
-          */
-         z = lp_build_clamp(&f32_bld, z, min_depth, max_depth);
+            /* viewports[viewport_index].max_depth */
+            max_depth = LLVMBuildExtractElement(builder, viewport,
+                           lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MAX_DEPTH),
+                           "");
+            max_depth = lp_build_broadcast_scalar(&f32_bld, max_depth);
+
+            /*
+             * Clamp to the min and max depth values for the given viewport.
+             */
+            z = lp_build_clamp(&f32_bld, z, min_depth, max_depth);
+         }
       }
 
       lp_build_depth_stencil_load_swizzled(gallivm, type,
@@ -2860,6 +2865,18 @@ make_variant_key(struct llvmpipe_context *lp,
       }
    }
 
+   /*
+    * Propagate the depth clamp setting from the rasterizer state.
+    * depth_clip == 0 implies depth clamping is enabled.
+    *
+    * When clip_halfz is enabled, then always clamp the depth values.
+    */
+   if (lp->rasterizer->clip_halfz) {
+      key->depth_clamp = 1;
+   } else {
+      key->depth_clamp = (lp->rasterizer->depth_clip == 0) ? 1 : 0;
+   }
+
    /* alpha test only applies if render buffer 0 is non-integer (or does not exist) */
    if (!lp->framebuffer.nr_cbufs ||
        !util_format_is_pure_integer(lp->framebuffer.cbufs[0]->format)) {
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h
index aac4526..2ddd851 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.h
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h
@@ -76,6 +76,7 @@ struct lp_fragment_shader_variant_key
    unsigned flatshade:1;
    unsigned occlusion_count:1;
    unsigned resource_1d:1;
+   unsigned depth_clamp:1;
 
    enum pipe_format zsbuf_format;
    enum pipe_format cbuf_format[PIPE_MAX_COLOR_BUFS];
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 29e8cc9..1b5f88e 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -130,6 +130,8 @@ struct pipe_rasterizer_state
    /**
     * When true clip space in the z axis goes from [0..1] (D3D).  When false
     * [-1, 1] (GL).
+    *
+    * NOTE: D3D will always use depth clamping.
     */
    unsigned clip_halfz:1;
 




More information about the mesa-commit mailing list