From 0a6043c6322e8c2f124429f40c514a03c7dba689 Mon Sep 17 00:00:00 2001 From: Erico Nunes Date: Sun, 3 Sep 2023 23:45:01 +0200 Subject: [PATCH] lima: fix plbu block stride calculation For some specific texture sizes, notably some texture sizes with width 4096, block stride calculation could end up calculating stride 256 which is an invalid value. In those specific cases, this could cause rendering artifacts or application/driver crashes. Cc: mesa-stable Signed-off-by: Erico Nunes Reviewed-by: Vasily Khoruzhick Part-of: (cherry picked from commit cb1c88d41f6dc213533f33f34e9224706f564849) --- .pick_status.json | 2 +- src/gallium/drivers/lima/lima_gpu.h | 6 +++++- src/gallium/drivers/lima/lima_job.c | 8 ++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 77d74d77ad2..ae35f933895 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -4984,7 +4984,7 @@ "description": "lima: fix plbu block stride calculation", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/gallium/drivers/lima/lima_gpu.h b/src/gallium/drivers/lima/lima_gpu.h index 7a23fc76984..4e3ea65d026 100644 --- a/src/gallium/drivers/lima/lima_gpu.h +++ b/src/gallium/drivers/lima/lima_gpu.h @@ -120,11 +120,15 @@ struct lima_render_state { plbu_cmd[i++] = v2; \ } while (0) +#define PLBU_BLOCK_W_MASK 0xff +#define PLBU_BLOCK_H_MASK 0xff + #define PLBU_CMD_BLOCK_STEP(shift_min, shift_h, shift_w) \ PLBU_CMD(((shift_min) << 28) | ((shift_h) << 16) | (shift_w), 0x1000010C) #define PLBU_CMD_TILED_DIMENSIONS(tiled_w, tiled_h) \ PLBU_CMD((((tiled_w) - 1) << 24) | (((tiled_h) - 1) << 8), 0x10000109) -#define PLBU_CMD_BLOCK_STRIDE(block_w) PLBU_CMD((block_w) & 0xff, 0x30000000) +#define PLBU_CMD_BLOCK_STRIDE(block_w) \ + PLBU_CMD((block_w) & PLBU_BLOCK_W_MASK, 0x30000000) #define PLBU_CMD_ARRAY_ADDRESS(gp_stream, block_num) \ PLBU_CMD(gp_stream, 0x28000000 | ((block_num) - 1) | 1) #define PLBU_CMD_VIEWPORT_LEFT(v) PLBU_CMD(v, 0x10000107) diff --git a/src/gallium/drivers/lima/lima_job.c b/src/gallium/drivers/lima/lima_job.c index 17a7ba30ddf..6400fdb2dd9 100644 --- a/src/gallium/drivers/lima/lima_job.c +++ b/src/gallium/drivers/lima/lima_job.c @@ -81,8 +81,9 @@ lima_get_fb_info(struct lima_job *job) fb->shift_w = 0; int limit = screen->plb_max_blk; - while ((width * height) > limit) { - if (width >= height) { + while ((width * height) > limit || + width > PLBU_BLOCK_W_MASK || height > PLBU_BLOCK_H_MASK) { + if (width >= height || width > PLBU_BLOCK_W_MASK) { width = (width + 1) >> 1; fb->shift_w++; } else { @@ -398,6 +399,9 @@ lima_pack_head_plbu_cmd(struct lima_job *job) PLBU_CMD_BEGIN(&job->plbu_cmd_head, 10); + assert((fb->block_w & PLBU_BLOCK_W_MASK) == fb->block_w); + assert((fb->block_h & PLBU_BLOCK_H_MASK) == fb->block_h); + PLBU_CMD_UNKNOWN2(); PLBU_CMD_BLOCK_STEP(fb->shift_min, fb->shift_h, fb->shift_w); PLBU_CMD_TILED_DIMENSIONS(fb->tiled_w, fb->tiled_h);