Module: Mesa
Branch: main
Commit: 77092ca8f4f0a1a755c4f49f90d89e9a3606fc6e
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=77092ca8f4f0a1a755c4f49f90d89e9a3606fc6e

Author: Jose Fonseca <[email protected]>
Date:   Wed Jan 25 13:54:41 2023 +0000

llvmpipe: Honor zero sample_mask when multisample is disabled.

The JIT generated FS shader has logic to obey sample mask when:
multisample is enabled, or multisample is disabled but FS writes sample
mask and pipe_rasterizer_state::no_ms_sample_mask_out.

However it did not handle the case where multisample was disabled, FS
did not write sample_mask, and sample mask was zero.  Instead it relied
upon the setup to discard the primitives, but that went away with commit
da5840f3.

We could restore the discard on zero mask behavior, but we would again
blurring the semantics of rasterization discard.  Instead this change
adds logic to primitive setup to cull the primitives when sample mask is
zero.

Fixes: da5840f3 ("llvmpipe: Faithfully honour 
pipe_rasterizer_state::rasterizer_discard flag")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20934>

---

 src/gallium/drivers/llvmpipe/lp_setup_context.h |  8 ++++++++
 src/gallium/drivers/llvmpipe/lp_setup_line.c    |  6 ++++++
 src/gallium/drivers/llvmpipe/lp_setup_point.c   |  6 ++++++
 src/gallium/drivers/llvmpipe/lp_setup_rect.c    |  6 ++++++
 src/gallium/drivers/llvmpipe/lp_setup_tri.c     | 12 +++++++++---
 5 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h 
b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index d848a144013..178bc6008cd 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -306,5 +306,13 @@ lp_setup_bin_rectangle(struct lp_setup_context *setup,
                        struct lp_rast_rectangle *rect,
                        boolean opaque);
 
+static inline boolean
+lp_setup_zero_sample_mask(struct lp_setup_context *setup)
+{
+   uint32_t sample_mask = setup->fs.current.jit_context.sample_mask;
+   return sample_mask == 0 ||
+          (!setup->multisample && (sample_mask & 1) == 0);
+}
+
 
 #endif
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c 
b/src/gallium/drivers/llvmpipe/lp_setup_line.c
index c0eb5b29335..4b11e593305 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_line.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c
@@ -296,6 +296,12 @@ try_setup_line(struct lp_setup_context *setup,
    if (0)
       print_line(setup, v1, v2);
 
+   if (lp_setup_zero_sample_mask(setup)) {
+      if (0) debug_printf("zero sample mask\n");
+      LP_COUNT(nr_culled_tris);
+      return TRUE;
+   }
+
    const float (*pv)[4];
    if (setup->flatshade_first) {
       pv = v1;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c 
b/src/gallium/drivers/llvmpipe/lp_setup_point.c
index bab0bc158a9..ffff2869f56 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_point.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c
@@ -450,6 +450,12 @@ try_setup_point(struct lp_setup_context *setup,
       lp_context->pipeline_statistics.c_primitives++;
    }
 
+   if (lp_setup_zero_sample_mask(setup)) {
+      if (0) debug_printf("zero sample mask\n");
+      LP_COUNT(nr_culled_tris);
+      return TRUE;
+   }
+
    if (!u_rect_test_intersection(&setup->draw_regions[viewport_index], &bbox)) 
{
       if (0) debug_printf("no intersection\n");
       LP_COUNT(nr_culled_tris);
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_rect.c 
b/src/gallium/drivers/llvmpipe/lp_setup_rect.c
index e81f315fe45..f2dde242e30 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_rect.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_rect.c
@@ -460,6 +460,12 @@ lp_rect_cw(struct lp_setup_context *setup,
            const float (*v2)[4],
            boolean frontfacing)
 {
+   if (lp_setup_zero_sample_mask(setup)) {
+      if (0) debug_printf("zero sample mask\n");
+      LP_COUNT(nr_culled_rects);
+      return;
+   }
+
    if (!try_rect_cw(setup, v0, v1, v2, frontfacing)) {
       if (!lp_setup_flush_and_restart(setup))
          return;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c 
b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index 9097fbb70e4..45553da0e38 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -272,9 +272,6 @@ do_triangle_ccw(struct lp_setup_context *setup,
 {
    struct lp_scene *scene = setup->scene;
 
-   if (0)
-      lp_setup_print_triangle(setup, v0, v1, v2);
-
    const float (*pv)[4];
    if (setup->flatshade_first) {
       pv = v0;
@@ -1001,6 +998,15 @@ retry_triangle_ccw(struct lp_setup_context *setup,
                    const float (*v2)[4],
                    boolean front)
 {
+   if (0)
+      lp_setup_print_triangle(setup, v0, v1, v2);
+
+   if (lp_setup_zero_sample_mask(setup)) {
+      if (0) debug_printf("zero sample mask\n");
+      LP_COUNT(nr_culled_tris);
+      return;
+   }
+
    if (!do_triangle_ccw(setup, position, v0, v1, v2, front)) {
       if (!lp_setup_flush_and_restart(setup))
          return;

Reply via email to