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 <nunes.erico@gmail.com>
Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25084>
(cherry picked from commit cb1c88d41f)
This commit is contained in:
Erico Nunes 2023-09-03 23:45:01 +02:00 committed by Dylan Baker
parent 6cfb05190d
commit 0a6043c632
3 changed files with 12 additions and 4 deletions

View file

@ -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

View file

@ -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)

View file

@ -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);