mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 05:08:08 +02:00
lima: avoid situations when scissor minx > maxx or miny > maxy
Clip scissor to viewport and then to framebuffer to avoid that since hardware can't handle this case. Reviewed-by: Qiang Yu <yuq825@gmail.com> Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com> Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4427> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4427>
This commit is contained in:
parent
eed5a00989
commit
c04964c690
2 changed files with 48 additions and 34 deletions
|
|
@ -191,6 +191,7 @@ struct lima_context {
|
|||
struct lima_context_framebuffer framebuffer;
|
||||
struct lima_context_viewport_state viewport;
|
||||
struct pipe_scissor_state scissor;
|
||||
struct pipe_scissor_state clipped_scissor;
|
||||
struct lima_vs_shader_state *vs;
|
||||
struct lima_fs_shader_state *fs;
|
||||
struct lima_vertex_element_state *vertex_elements;
|
||||
|
|
|
|||
|
|
@ -49,16 +49,47 @@
|
|||
|
||||
#include <drm-uapi/lima_drm.h>
|
||||
|
||||
static void
|
||||
lima_clip_scissor_to_viewport(struct lima_context *ctx)
|
||||
{
|
||||
struct lima_context_framebuffer *fb = &ctx->framebuffer;
|
||||
struct pipe_scissor_state *cscissor = &ctx->clipped_scissor;
|
||||
int viewport_left, viewport_right, viewport_bottom, viewport_top;
|
||||
|
||||
if (ctx->rasterizer && ctx->rasterizer->base.scissor) {
|
||||
struct pipe_scissor_state *scissor = &ctx->scissor;
|
||||
cscissor->minx = scissor->minx;
|
||||
cscissor->maxx = scissor->maxx;
|
||||
cscissor->miny = scissor->miny;
|
||||
cscissor->maxy = scissor->maxy;
|
||||
} else {
|
||||
cscissor->minx = 0;
|
||||
cscissor->maxx = fb->base.width;
|
||||
cscissor->miny = 0;
|
||||
cscissor->maxy = fb->base.height;
|
||||
}
|
||||
|
||||
viewport_left = MAX2(ctx->viewport.left, 0);
|
||||
cscissor->minx = MAX2(cscissor->minx, viewport_left);
|
||||
viewport_right = MIN2(ctx->viewport.right, fb->base.width);
|
||||
cscissor->maxx = MIN2(cscissor->maxx, viewport_right);
|
||||
if (cscissor->minx > cscissor->maxx)
|
||||
cscissor->minx = cscissor->maxx;
|
||||
|
||||
viewport_bottom = MAX2(ctx->viewport.bottom, 0);
|
||||
cscissor->miny = MAX2(cscissor->miny, viewport_bottom);
|
||||
viewport_top = MIN2(ctx->viewport.top, fb->base.height);
|
||||
cscissor->maxy = MIN2(cscissor->maxy, viewport_top);
|
||||
if (cscissor->miny > cscissor->maxy)
|
||||
cscissor->miny = cscissor->maxy;
|
||||
}
|
||||
|
||||
static bool
|
||||
lima_is_scissor_zero(struct lima_context *ctx)
|
||||
{
|
||||
if (!ctx->rasterizer || !ctx->rasterizer->base.scissor)
|
||||
return false;
|
||||
struct pipe_scissor_state *cscissor = &ctx->clipped_scissor;
|
||||
|
||||
struct pipe_scissor_state *scissor = &ctx->scissor;
|
||||
return
|
||||
scissor->minx == scissor->maxx
|
||||
&& scissor->miny == scissor->maxy;
|
||||
return cscissor->minx == cscissor->maxx || cscissor->miny == cscissor->maxy;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -268,14 +299,8 @@ lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
|
|||
static void
|
||||
lima_pack_plbu_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
|
||||
{
|
||||
struct lima_context_framebuffer *fb = &ctx->framebuffer;
|
||||
struct lima_vs_shader_state *vs = ctx->vs;
|
||||
unsigned minx, maxx, miny, maxy;
|
||||
|
||||
/* If it's zero scissor, we skip adding all other commands */
|
||||
if (lima_is_scissor_zero(ctx))
|
||||
return;
|
||||
|
||||
struct pipe_scissor_state *cscissor = &ctx->clipped_scissor;
|
||||
struct lima_job *job = lima_job_get(ctx);
|
||||
PLBU_CMD_BEGIN(&job->plbu_cmd_array, 32);
|
||||
|
||||
|
|
@ -317,26 +342,12 @@ lima_pack_plbu_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
|
|||
* - we should set it only for the first draw that enabled the scissor and for
|
||||
* latter draw only if scissor is dirty
|
||||
*/
|
||||
if (ctx->rasterizer->base.scissor) {
|
||||
struct pipe_scissor_state *scissor = &ctx->scissor;
|
||||
minx = scissor->minx;
|
||||
maxx = scissor->maxx;
|
||||
miny = scissor->miny;
|
||||
maxy = scissor->maxy;
|
||||
} else {
|
||||
minx = 0;
|
||||
maxx = fb->base.width;
|
||||
miny = 0;
|
||||
maxy = fb->base.height;
|
||||
}
|
||||
|
||||
minx = MAX2(minx, ctx->viewport.left);
|
||||
maxx = MIN2(maxx, ctx->viewport.right);
|
||||
miny = MAX2(miny, ctx->viewport.bottom);
|
||||
maxy = MIN2(maxy, ctx->viewport.top);
|
||||
assert(cscissor->minx < cscissor->maxx && cscissor->miny < cscissor->maxy);
|
||||
PLBU_CMD_SCISSORS(cscissor->minx, cscissor->maxx, cscissor->miny, cscissor->maxy);
|
||||
|
||||
PLBU_CMD_SCISSORS(minx, maxx, miny, maxy);
|
||||
lima_damage_rect_union(&job->damage_rect, minx, maxx, miny, maxy);
|
||||
lima_damage_rect_union(&job->damage_rect, cscissor->minx, cscissor->maxx,
|
||||
cscissor->miny, cscissor->maxy);
|
||||
|
||||
PLBU_CMD_UNKNOWN1();
|
||||
|
||||
|
|
@ -1001,9 +1012,7 @@ lima_draw_vbo_update(struct pipe_context *pctx,
|
|||
|
||||
lima_update_varying(ctx, info);
|
||||
|
||||
/* If it's zero scissor, don't build vs cmd list */
|
||||
if (!lima_is_scissor_zero(ctx))
|
||||
lima_pack_vs_cmd(ctx, info);
|
||||
lima_pack_vs_cmd(ctx, info);
|
||||
|
||||
if (ctx->dirty & LIMA_CONTEXT_DIRTY_CONST_BUFF &&
|
||||
ctx->const_buffer[PIPE_SHADER_FRAGMENT].dirty) {
|
||||
|
|
@ -1111,6 +1120,10 @@ lima_draw_vbo(struct pipe_context *pctx,
|
|||
return;
|
||||
}
|
||||
|
||||
lima_clip_scissor_to_viewport(ctx);
|
||||
if (lima_is_scissor_zero(ctx))
|
||||
return;
|
||||
|
||||
if (!lima_update_vs_state(ctx) || !lima_update_fs_state(ctx))
|
||||
return;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue