From 912e2be85fe15f23905ea4c8d78c437d4573667c Mon Sep 17 00:00:00 2001 From: GKraats Date: Fri, 6 Sep 2024 12:27:17 +0200 Subject: [PATCH] i915g: fix texture3d npot mipmaps At i945_texture_layout_3d() util_next_power_of_two() is called, which oversizes the npot-blocks for every level to get power of 2 for width and height. Hardware doesnot expect these oversized npot-blocks. The call is removed. Code is added to align allocation of npot-blocks correctly. Also at i915_texture_layout_3d() the util_next_power_of_two() call is removed. Besides the computation of block-allocation is changed, because it still was using classic i915-coding. Cc: mesa-stable Signed-off-by: GKraats Part-of: (cherry picked from commit a95bd2dcf0ec16b41b474eb09e50e742c5569439) --- .pick_status.json | 2 +- .../drivers/i915/i915_resource_texture.c | 51 +++++++++++++------ 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index d79f51022b8..767c7ce7b37 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -554,7 +554,7 @@ "description": "i915g: fix texture3d npot 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_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index 79e152b01a9..d5e8b8bff8b 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -389,11 +389,16 @@ i915_texture_layout_3d(struct i915_texture *tex) struct pipe_resource *pt = &tex->b; unsigned level; - unsigned width = util_next_power_of_two(pt->width0); - unsigned height = util_next_power_of_two(pt->height0); - unsigned depth = util_next_power_of_two(pt->depth0); - unsigned nblocksy = util_format_get_nblocksy(pt->format, height); + unsigned width = pt->width0; + unsigned height = pt->height0; + unsigned depth = pt->depth0; unsigned stack_nblocksy = 0; + unsigned align_y = 2; + + if (util_format_is_compressed(pt->format)) + align_y = 1; + + unsigned nblocksy = align_nblocksy(pt->format, height, align_y); /* Calculate the size of a single slice. */ @@ -403,20 +408,23 @@ i915_texture_layout_3d(struct i915_texture *tex) */ for (level = 0; level <= MAX2(8, pt->last_level); level++) { i915_texture_set_level_info(tex, level, depth); + i915_texture_set_image_offset(tex, level, 0, 0, stack_nblocksy); + stack_nblocksy += MAX2(2, nblocksy); width = u_minify(width, 1); height = u_minify(height, 1); - nblocksy = util_format_get_nblocksy(pt->format, height); + nblocksy = align_nblocksy(pt->format, height, align_y); } /* Fixup depth image_offsets: */ - for (level = 0; level <= pt->last_level; level++) { + for (level = 0; level <= MAX2(8, pt->last_level); level++) { unsigned i; - for (i = 0; i < depth; i++) - i915_texture_set_image_offset(tex, level, i, 0, i * stack_nblocksy); + nblocksy = tex->image_offset[level][0].nblocksy; + for (i = 1; i < depth; i++) + i915_texture_set_image_offset(tex, level, i, 0, nblocksy + i * stack_nblocksy); depth = u_minify(depth, 1); } @@ -425,7 +433,7 @@ i915_texture_layout_3d(struct i915_texture *tex) * remarkable how wasteful of memory the i915 texture layouts * are. They are largely fixed in the i945. */ - tex->total_nblocksy = stack_nblocksy * util_next_power_of_two(pt->depth0); + tex->total_nblocksy = stack_nblocksy * pt->depth0; } static bool @@ -511,15 +519,22 @@ static void i945_texture_layout_3d(struct i915_texture *tex) { struct pipe_resource *pt = &tex->b; - unsigned width = util_next_power_of_two(pt->width0); - unsigned height = util_next_power_of_two(pt->height0); - unsigned depth = util_next_power_of_two(pt->depth0); + int align_x = 4, align_y = 2; + unsigned width = pt->width0; + unsigned height = pt->height0; + unsigned depth = pt->depth0; + unsigned nblocksy = util_format_get_nblocksy(pt->format, height); unsigned pack_x_pitch, pack_x_nr; unsigned pack_y_pitch; unsigned level; - tex->stride = align(util_format_get_stride(pt->format, width), 4); + if (util_format_is_compressed(pt->format)) { + align_x = 1; + align_y = 1; + } + + tex->stride = align(util_format_get_stride(pt->format, width), align_x); tex->total_nblocksy = 0; pack_y_pitch = MAX2(nblocksy, 2); @@ -538,10 +553,17 @@ i945_texture_layout_3d(struct i915_texture *tex) i915_texture_set_image_offset(tex, level, q, x, y + tex->total_nblocksy); x += pack_x_pitch; + x = align(x, align_x); + } + if (x > width) { + tex->stride = util_format_get_stride(pt->format, x); + width = x; } x = 0; y += pack_y_pitch; + y = align(y, align_y); + } tex->total_nblocksy += y; @@ -558,10 +580,7 @@ i945_texture_layout_3d(struct i915_texture *tex) pack_y_pitch >>= 1; } - width = u_minify(width, 1); - height = u_minify(height, 1); depth = u_minify(depth, 1); - nblocksy = util_format_get_nblocksy(pt->format, height); } }