aux/draw: add guardband clipping for lines
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Tue, 28 Jun 2022 14:49:14 +0000 (10:49 -0400)
committerMarge Bot <emma+marge@anholt.net>
Mon, 8 May 2023 16:55:50 +0000 (16:55 +0000)
to comply with ES2+ line clipping rules, guardband clipping should be
used so that the rasterizer will clip lines without using clip planes

fixes (llvmpipe):
dEQP-GLES*.functional.clipping.line.wide_line_clip_viewport_center
dEQP-GLES*.functional.clipping.line.wide_line_clip_viewport_corner

Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17284>

src/gallium/auxiliary/draw/draw_pipe_clip.c
src/gallium/drivers/llvmpipe/ci/llvmpipe-fails.txt
src/gallium/drivers/virgl/ci/virgl-gles-fails.txt
src/gallium/drivers/zink/ci/zink-lvp-fails.txt

index dec59f8..b7f7caf 100644 (file)
@@ -710,6 +710,40 @@ clip_line(struct draw_stage *stage, struct prim_header *header)
    /* else, totally clipped */
 }
 
+static void
+clip_line_guard_xy(struct draw_stage *stage, struct prim_header *header)
+{
+   unsigned clipmask = (header->v[0]->clipmask |
+                        header->v[1]->clipmask);
+
+   if ((clipmask & 0xffffffff) == 0) {
+      stage->next->line(stage->next, header);
+   }
+   else if ((clipmask & 0xfffffff0) == 0) {
+      while (clipmask) {
+         const unsigned plane_idx = ffs(clipmask)-1;
+         clipmask &= ~(1 << plane_idx);  /* turn off this plane's bit */
+         /* TODO: this should really do proper guardband clipping,
+          * currently just throw out infs/nans.
+          * Also note that vertices with negative w values MUST be tossed
+          * out (not sure if proper guardband clipping would do this
+          * automatically). These would usually be captured by depth clip
+          * too but this can be disabled.
+          */
+         if ((header->v[0]->clip_pos[3] <= 0.0f &&
+              header->v[1]->clip_pos[3] <= 0.0f) ||
+             util_is_nan(header->v[0]->clip_pos[0]) ||
+             util_is_nan(header->v[0]->clip_pos[1]) ||
+             util_is_nan(header->v[1]->clip_pos[0]) ||
+             util_is_nan(header->v[1]->clip_pos[1]))
+            return;
+      }
+      stage->next->line(stage->next, header);
+   } else if ((header->v[0]->clipmask &
+               header->v[1]->clipmask) == 0) {
+      do_clip_line(stage, header, clipmask & 0xfffffff0);
+   }
+}
 
 static void
 clip_tri(struct draw_stage *stage, struct prim_header *header)
@@ -894,7 +928,6 @@ clip_init_state(struct draw_stage *stage)
    }
 
    stage->tri = clip_tri;
-   stage->line = clip_line;
 }
 
 
@@ -912,6 +945,7 @@ clip_first_line(struct draw_stage *stage,
                 struct prim_header *header)
 {
    clip_init_state(stage);
+   stage->line = stage->draw->guard_band_points_lines_xy ? clip_line_guard_xy : clip_line;
    stage->line(stage, header);
 }
 
index e4fca54..2fd68cf 100644 (file)
@@ -7,10 +7,6 @@ dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.reset_status.
 dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.sync_status.compute,Fail
 dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.sync_status.vertex,Fail
 dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.sync_status.vertex_and_fragment,Fail
-dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_center,Fail
-dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_corner,Fail
-dEQP-GLES3.functional.clipping.line.wide_line_clip_viewport_center,Fail
-dEQP-GLES3.functional.clipping.line.wide_line_clip_viewport_corner,Fail
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_mag,Fail
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_mag_reverse_dst_x,Fail
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_mag_reverse_src_dst_x,Fail
index a8f3034..7063a0a 100644 (file)
@@ -1,9 +1,5 @@
-dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_center,Fail
-dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_corner,Fail
 dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_center,Fail
 dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_corner,Fail
-dEQP-GLES3.functional.clipping.line.wide_line_clip_viewport_center,Fail
-dEQP-GLES3.functional.clipping.line.wide_line_clip_viewport_corner,Fail
 dEQP-GLES3.functional.clipping.point.wide_point_clip,Fail
 dEQP-GLES3.functional.clipping.point.wide_point_clip_viewport_corner,Fail
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_mag,Fail
index c139ea3..ad4ba0b 100644 (file)
@@ -13,8 +13,6 @@ spec@egl_chromium_sync_control@conformance@eglGetSyncValuesCHROMIUM_msc_and_sbc_
 spec@egl_chromium_sync_control@conformance@eglGetSyncValuesCHROMIUM_ust_test,Fail
 
 
-dEQP-GLES3.functional.clipping.line.wide_line_clip_viewport_center,Fail
-dEQP-GLES3.functional.clipping.line.wide_line_clip_viewport_corner,Fail
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_mag,Fail
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_mag_reverse_dst_x,Fail
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_mag_reverse_src_dst_x,Fail
@@ -25,8 +23,6 @@ dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_min_reverse_dst_x,Fail
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_min_reverse_src_dst_x,Fail
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_min_reverse_src_dst_y,Fail
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_min_reverse_src_x,Fail
-dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_center,Fail
-dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_corner,Fail
 
 # this test tries to be error-compatible with nvidia. spoiler: mesa isn't, and no driver can pass it
 glx@glx_arb_create_context@invalid flag,Fail