From e3aa996d9dfdb9ce42e6327cb56b0a73ef050408 Mon Sep 17 00:00:00 2001 From: GKraats Date: Tue, 9 Apr 2024 00:09:04 +0200 Subject: [PATCH] i915g: fix generation of large mipmaps Generation of mipmaps was failing for large heights. If height > 1365 LEVEL 1 couldnot be generated because of the max texture size limit (2048). This is solved by using an offset at the texture-buffer at overflow situations. The height of the offset must be multiple of 8. This solves the problem mentioned at MR !27561 (closed). Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10410 Cc: mesa-stable Signed-off-by: GKraats Part-of: (cherry picked from commit a1a301488bf818d06d52e59ff45528b7ddc3cd30) --- .pick_status.json | 2 +- src/gallium/drivers/i915/i915_context.h | 1 + src/gallium/drivers/i915/i915_state_emit.c | 2 +- src/gallium/drivers/i915/i915_state_static.c | 9 +++++++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 6cef2836a84..0f2d92f23b1 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1184,7 +1184,7 @@ "description": "i915g: fix generation of large mipmaps", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index be2c65d21ca..12062ad9741 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -174,6 +174,7 @@ struct i915_state { unsigned dst_buf_vars; uint32_t draw_offset; uint32_t draw_size; + unsigned cbuf_offset; /* Reswizzle for OC writes in PIXEL_SHADER_PROGRAM, or 0 if unnecessary. */ uint32_t fixup_swizzle; diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 5b2d19c0786..17570670851 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -221,7 +221,7 @@ emit_static(struct i915_context *i915) if (i915->current.cbuf_bo && (i915->static_dirty & I915_DST_BUF_COLOR)) { OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(i915->current.cbuf_flags); - OUT_RELOC(i915->current.cbuf_bo, I915_USAGE_RENDER, 0); + OUT_RELOC(i915->current.cbuf_bo, I915_USAGE_RENDER, i915->current.cbuf_offset); } /* What happens if no zbuf?? diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c index 9d48b599f86..de4f7eb56ac 100644 --- a/src/gallium/drivers/i915/i915_state_static.c +++ b/src/gallium/drivers/i915/i915_state_static.c @@ -81,6 +81,7 @@ update_framebuffer(struct i915_context *i915) struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; unsigned x, y; + unsigned y1; int layer; uint32_t draw_offset, draw_size; @@ -91,11 +92,19 @@ update_framebuffer(struct i915_context *i915) i915->current.cbuf_bo = tex->buffer; i915->current.cbuf_flags = surf->buf_info; + i915->current.cbuf_offset = 0; layer = cbuf_surface->u.tex.first_layer; x = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksx; y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy; + // Use offset if buffer not within max texture size 2048 + if (y + i915->framebuffer.height >= (1 << (I915_MAX_TEXTURE_2D_LEVELS - 1))) { + // offset should be multiple of 8 to support TILE_X + y1 = (y / 8) * 8; + y -= y1; + i915->current.cbuf_offset = y1 * tex->stride; + } } else { i915->current.cbuf_bo = NULL; x = y = 0;