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

Author: Adam Jackson <[email protected]>
Date:   Wed Feb 24 19:20:20 2021 -0500

softpipe: Implement GL_EXT_depth_bounds_test

This is a little bit contorted because the Z storage for the tile is
either float or int depending on the Z format, so we have to be careful
about types when comparing.

Reviewed-by: Eric Anholt <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9287>

---

 src/gallium/drivers/softpipe/ci/softpipe-quick.txt |   1 -
 src/gallium/drivers/softpipe/sp_quad_depth_test.c  | 111 +++++++++++++++++++--
 src/gallium/drivers/softpipe/sp_screen.c           |   1 +
 3 files changed, 103 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/softpipe/ci/softpipe-quick.txt 
b/src/gallium/drivers/softpipe/ci/softpipe-quick.txt
index 1fc063cff13..cf94d7e9226 100644
--- a/src/gallium/drivers/softpipe/ci/softpipe-quick.txt
+++ b/src/gallium/drivers/softpipe/ci/softpipe-quick.txt
@@ -1860,7 +1860,6 @@ spec/egl_nok_swap_region/basic: skip
 spec/egl_nok_texture_from_pixmap/basic: skip
 spec/ext_demote_to_helper_invocation/execution/demote: skip
 spec/ext_demote_to_helper_invocation/execution/demote_with_derivatives: skip
-spec/ext_depth_bounds_test/depth_bounds: skip
 spec/ext_direct_state_access/indexed-state-queries 12/getdoublei_vext: skip
 spec/ext_direct_state_access/indexed-state-queries 12/getfloati_vext: skip
 spec/ext_direct_state_access/indexed-state-queries 12/getpointeri_vext: skip
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c 
b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index 2fb2c5b5ec0..17caf75dde8 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -747,6 +747,76 @@ alpha_test_quads(struct quad_stage *qs,
 }
 
 
+/**
+ * EXT_depth_bounds_test has some careful language about precision:
+ *
+ *     At what precision is the depth bounds test carried out?
+ *
+ *       RESOLUTION:  For the purposes of the test, the bounds are converted
+ *       to fixed-point as though they were to be written to the depth buffer,
+ *       and the comparison uses those quantized bounds.
+ *
+ * We choose the obvious interpretation that Z32F needs no such conversion.
+ */
+static unsigned
+depth_bounds_test_quads(struct quad_stage *qs,
+                        struct quad_header *quads[],
+                        unsigned nr,
+                        struct depth_data *data)
+{
+   struct pipe_depth_stencil_alpha_state *dsa = qs->softpipe->depth_stencil;
+   unsigned i = 0, pass_nr = 0;
+   enum pipe_format format = util_format_get_depth_only(data->format);
+   double min = dsa->depth_bounds_min;
+   double max = dsa->depth_bounds_max;
+
+   for (i = 0; i < nr; i++) {
+      unsigned j = 0, passMask = 0;
+
+      get_depth_stencil_values(data, quads[i]);
+
+      if (format == PIPE_FORMAT_Z32_FLOAT) {
+         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
+            double z = uif(data->bzzzz[j]);
+
+            if (z >= min && z <= max)
+               passMask |= (1 << j);
+         }
+      } else {
+         unsigned imin, imax;
+
+         if (format == PIPE_FORMAT_Z16_UNORM) {
+            imin = ((unsigned) (min * 65535.0)) & 0xffff;
+            imax = ((unsigned) (max * 65535.0)) & 0xffff;
+         } else if (format == PIPE_FORMAT_Z32_UNORM) {
+            imin = (unsigned) (min * 4294967295.0);
+            imax = (unsigned) (max * 4294967295.0);
+         } else if (format == PIPE_FORMAT_Z24X8_UNORM ||
+                    format == PIPE_FORMAT_X8Z24_UNORM) {
+            imin = ((unsigned) (min * 16777215.0)) & 0xffffff;
+            imax = ((unsigned) (max * 16777215.0)) & 0xffffff;
+         } else {
+            unreachable("Unknown depth buffer format");
+         }
+
+         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
+            unsigned iz = data->bzzzz[j];
+
+            if (iz >= imin && iz <= imax)
+               passMask |= (1 << j);
+         }
+      }
+
+      quads[i]->inout.mask &= passMask;
+
+      if (quads[i]->inout.mask)
+         quads[pass_nr++] = quads[i];
+   }
+
+   return pass_nr;
+}
+
+
 static unsigned mask_count[16] = 
 {
    0,                           /* 0x0 */
@@ -781,18 +851,15 @@ depth_test_quads_fallback(struct quad_stage *qs,
    const struct tgsi_shader_info *fsInfo = &qs->softpipe->fs_variant->info;
    boolean interp_depth = !fsInfo->writes_z || qs->softpipe->early_depth;
    boolean shader_stencil_ref = fsInfo->writes_stencil;
+   boolean have_zs = !!qs->softpipe->framebuffer.zsbuf;
    struct depth_data data;
    unsigned vp_idx = quads[0]->input.viewport_index;
 
    data.use_shader_stencil_refs = FALSE;
 
-   if (qs->softpipe->depth_stencil->alpha_enabled) {
-      nr = alpha_test_quads(qs, quads, nr);
-   }
-
-   if (qs->softpipe->framebuffer.zsbuf &&
-         (qs->softpipe->depth_stencil->depth_enabled ||
-          qs->softpipe->depth_stencil->stencil[0].enabled)) {
+   if (have_zs && (qs->softpipe->depth_stencil->depth_enabled ||
+                   qs->softpipe->depth_stencil->stencil[0].enabled ||
+                   qs->softpipe->depth_stencil->depth_bounds_test)) {
       float near_val, far_val;
 
       data.ps = qs->softpipe->framebuffer.zsbuf;
@@ -806,7 +873,29 @@ depth_test_quads_fallback(struct quad_stage *qs,
       far_val = near_val + (qs->softpipe->viewports[vp_idx].scale[2] * 2.0);
       data.minval = MIN2(near_val, far_val);
       data.maxval = MAX2(near_val, far_val);
+   }
+
+   /* EXT_depth_bounds_test says:
+    *
+    *     Where should the depth bounds test take place in the OpenGL fragment
+    *     processing pipeline?
+    *
+    *       RESOLUTION:  After scissor test, before alpha test. In practice,
+    *       this is a logical placement of the test.  An implementation is
+    *       free to perform the test in a manner that is consistent with the
+    *       specified ordering.
+    */
+
+   if (have_zs && qs->softpipe->depth_stencil->depth_bounds_test) {
+      nr = depth_bounds_test_quads(qs, quads, nr, &data);
+   }
 
+   if (qs->softpipe->depth_stencil->alpha_enabled) {
+      nr = alpha_test_quads(qs, quads, nr);
+   }
+
+   if (have_zs && (qs->softpipe->depth_stencil->depth_enabled ||
+                   qs->softpipe->depth_stencil->stencil[0].enabled)) {
       for (i = 0; i < nr; i++) {
          get_depth_stencil_values(&data, quads[i]);
 
@@ -915,6 +1004,8 @@ choose_depth_test(struct quad_stage *qs,
 
    boolean clipped = !qs->softpipe->rasterizer->depth_clip_near;
 
+   boolean depth_bounds = qs->softpipe->depth_stencil->depth_bounds_test;
+
    if(!qs->softpipe->framebuffer.zsbuf)
       depth = depthwrite = stencil = FALSE;
 
@@ -926,7 +1017,8 @@ choose_depth_test(struct quad_stage *qs,
        !depth &&
        !occlusion &&
        !clipped &&
-       !stencil) {
+       !stencil &&
+       !depth_bounds) {
       qs->run = depth_noop;
    }
    else if (!alpha && 
@@ -935,7 +1027,8 @@ choose_depth_test(struct quad_stage *qs,
             depthwrite && 
             !occlusion &&
             !clipped &&
-            !stencil) 
+            !stencil &&
+            !depth_bounds)
    {
       if (qs->softpipe->framebuffer.zsbuf->format == PIPE_FORMAT_Z16_UNORM) {
          switch (depthfunc) {
diff --git a/src/gallium/drivers/softpipe/sp_screen.c 
b/src/gallium/drivers/softpipe/sp_screen.c
index 68185c87f47..65b01dd8a9d 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -146,6 +146,7 @@ softpipe_get_param(struct pipe_screen *screen, enum 
pipe_cap param)
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
       return 1;
    case PIPE_CAP_DEPTH_CLIP_DISABLE:
+   case PIPE_CAP_DEPTH_BOUNDS_TEST:
       return 1;
    case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
       return PIPE_MAX_SO_BUFFERS;

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to