etnaviv: Emulate rasterizer_discard

When rasterizer discard is enabled, we need to prevent all rasterization
without affecting vertex processing or transform feedback.

Emulate this by setting a zero-sized scissor rectangle (0,0,0,0) which
effectively clips all fragments while allowing the vertex shader to
continue running normally. This matches the behavior
implemented by the binary blob.

Passes all dEQP-GLES3.functional.rasterizer_discard.* on GC7000.

Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36373>
This commit is contained in:
Christian Gmeiner
2025-07-25 10:58:29 +02:00
committed by Marge Bot
parent 7390276d9b
commit 4ad333103f
+23 -16
View File
@@ -810,25 +810,32 @@ etna_update_clipping(struct etna_context *ctx)
const struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer);
const struct pipe_framebuffer_state *fb = &ctx->framebuffer_s;
/* clip framebuffer against viewport */
uint32_t scissor_left = ctx->viewport.SE_SCISSOR_LEFT;
uint32_t scissor_top = ctx->viewport.SE_SCISSOR_TOP;
uint32_t scissor_right = MIN2(fb->width, ctx->viewport.SE_SCISSOR_RIGHT);
uint32_t scissor_bottom = MIN2(fb->height, ctx->viewport.SE_SCISSOR_BOTTOM);
if (ctx->rasterizer->rasterizer_discard) {
ctx->clipping.minx = 0;
ctx->clipping.miny = 0;
ctx->clipping.maxx = 0;
ctx->clipping.maxy = 0;
} else {
/* clip framebuffer against viewport */
uint32_t scissor_left = ctx->viewport.SE_SCISSOR_LEFT;
uint32_t scissor_top = ctx->viewport.SE_SCISSOR_TOP;
uint32_t scissor_right = MIN2(fb->width, ctx->viewport.SE_SCISSOR_RIGHT);
uint32_t scissor_bottom = MIN2(fb->height, ctx->viewport.SE_SCISSOR_BOTTOM);
/* clip against scissor */
if (rasterizer->scissor) {
scissor_left = MAX2(ctx->scissor.minx, scissor_left);
scissor_top = MAX2(ctx->scissor.miny, scissor_top);
scissor_right = MIN2(ctx->scissor.maxx, scissor_right);
scissor_bottom = MIN2(ctx->scissor.maxy, scissor_bottom);
/* clip against scissor */
if (rasterizer->scissor) {
scissor_left = MAX2(ctx->scissor.minx, scissor_left);
scissor_top = MAX2(ctx->scissor.miny, scissor_top);
scissor_right = MIN2(ctx->scissor.maxx, scissor_right);
scissor_bottom = MIN2(ctx->scissor.maxy, scissor_bottom);
}
ctx->clipping.minx = scissor_left;
ctx->clipping.miny = scissor_top;
ctx->clipping.maxx = scissor_right;
ctx->clipping.maxy = scissor_bottom;
}
ctx->clipping.minx = scissor_left;
ctx->clipping.miny = scissor_top;
ctx->clipping.maxx = scissor_right;
ctx->clipping.maxy = scissor_bottom;
ctx->dirty |= ETNA_DIRTY_SCISSOR_CLIP;
return true;