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>
This commit is contained in:
Jose Fonseca
2023-01-25 13:54:41 +00:00
committed by Marge Bot
parent b6a344f4ba
commit 77092ca8f4
5 changed files with 35 additions and 3 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;