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 commitda5840f3
. 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:
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user