asahi: Fix scissor culling check when out of bounds for FB/viewport

Fixes a bunch of the `assert(maxx > minx && maxy > miny)` failures in
dEQP-EGL and probably others.

Signed-off-by: Asahi Lina <lina@asahilina.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21678>
This commit is contained in:
Asahi Lina 2023-03-03 17:15:54 +09:00 committed by Marge Bot
parent 1313787c12
commit 8e0c832c30

View file

@ -947,9 +947,10 @@ agx_set_viewport_states(struct pipe_context *pctx, unsigned start_slot,
}
static void
agx_upload_viewport_scissor(struct agx_pool *pool, struct agx_batch *batch,
uint8_t **out, const struct pipe_viewport_state *vp,
const struct pipe_scissor_state *ss, unsigned zbias)
agx_get_scissor_extents(const struct pipe_viewport_state *vp,
const struct pipe_scissor_state *ss,
const struct pipe_framebuffer_state *fb, unsigned *minx,
unsigned *miny, unsigned *maxx, unsigned *maxy)
{
float trans_x = vp->translate[0], trans_y = vp->translate[1];
float abs_scale_x = fabsf(vp->scale[0]), abs_scale_y = fabsf(vp->scale[1]);
@ -958,17 +959,27 @@ agx_upload_viewport_scissor(struct agx_pool *pool, struct agx_batch *batch,
* the viewport is an odd number of pixels, both the translate and the scale
* will have a fractional part of 0.5, so adding and subtracting them yields
* an integer. Therefore we don't need to round explicitly */
unsigned minx = CLAMP((int)(trans_x - abs_scale_x), 0, batch->key.width);
unsigned miny = CLAMP((int)(trans_y - abs_scale_y), 0, batch->key.height);
unsigned maxx = CLAMP((int)(trans_x + abs_scale_x), 0, batch->key.width);
unsigned maxy = CLAMP((int)(trans_y + abs_scale_y), 0, batch->key.height);
*minx = CLAMP((int)(trans_x - abs_scale_x), 0, fb->width);
*miny = CLAMP((int)(trans_y - abs_scale_y), 0, fb->height);
*maxx = CLAMP((int)(trans_x + abs_scale_x), 0, fb->width);
*maxy = CLAMP((int)(trans_y + abs_scale_y), 0, fb->height);
if (ss) {
minx = MAX2(ss->minx, minx);
miny = MAX2(ss->miny, miny);
maxx = MIN2(ss->maxx, maxx);
maxy = MIN2(ss->maxy, maxy);
*minx = MAX2(ss->minx, *minx);
*miny = MAX2(ss->miny, *miny);
*maxx = MIN2(ss->maxx, *maxx);
*maxy = MIN2(ss->maxy, *maxy);
}
}
static void
agx_upload_viewport_scissor(struct agx_pool *pool, struct agx_batch *batch,
uint8_t **out, const struct pipe_viewport_state *vp,
const struct pipe_scissor_state *ss, unsigned zbias)
{
unsigned minx, miny, maxx, maxy;
agx_get_scissor_extents(vp, ss, &batch->key, &minx, &miny, &maxx, &maxy);
assert(maxx > minx && maxy > miny);
@ -2398,10 +2409,12 @@ agx_index_buffer_direct_ptr(struct agx_batch *batch,
static bool
agx_scissor_culls_everything(struct agx_context *ctx)
{
const struct pipe_scissor_state ss = ctx->scissor;
unsigned minx, miny, maxx, maxy;
agx_get_scissor_extents(&ctx->viewport,
ctx->rast->base.scissor ? &ctx->scissor : NULL,
&ctx->framebuffer, &minx, &miny, &maxx, &maxy);
return ctx->rast->base.scissor &&
((ss.minx == ss.maxx) || (ss.miny == ss.maxy));
return (minx == maxx) || (miny == maxy);
}
static void