From d2d98abf1d5f583d2bb6198b206446aa509f10d4 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 18 Jun 2025 14:29:00 -0400 Subject: [PATCH] gallium: add compressed_surface_reinterpret_blocks_layered MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this affects piglit/bin/ext_texture_array-compressed teximage pbo -auto -fbo Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6891 Reviewed-by: Marek Olšák Reviewed-by: Nanley Chery Part-of: --- docs/gallium/screen.rst | 3 ++ src/gallium/drivers/iris/iris_screen.c | 1 + .../drivers/nouveau/nv30/nv30_screen.c | 1 + src/gallium/drivers/r600/r600_pipe.c | 1 + src/gallium/drivers/radeonsi/si_get.c | 1 + src/gallium/drivers/zink/zink_screen.c | 2 + src/gallium/include/pipe/p_defines.h | 1 + src/mesa/state_tracker/st_cb_texture.c | 40 ++++++++++--------- 8 files changed, 31 insertions(+), 19 deletions(-) diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst index f14b475f745..db23e39e392 100644 --- a/docs/gallium/screen.rst +++ b/docs/gallium/screen.rst @@ -348,6 +348,9 @@ Capability about the features and limits of the driver/GPU. non-compressed surface whose texels are the same number of bits as the compressed blocks, and vice versa. The width and height of the surface is adjusted appropriately. +* ``pipe_caps.compressed_surface_reinterpret_blocks_layered``: Same as + ``pipe_caps.surface_reinterpret_blocks`` but for supporting multiple layers + of a compressed texture. * ``pipe_caps.query_buffer_object``: Driver supports context::get_query_result_resource callback. * ``pipe_caps.pci_group``: Return the PCI segment group number. diff --git a/src/gallium/drivers/iris/iris_screen.c b/src/gallium/drivers/iris/iris_screen.c index 49f25b95bda..177c398302a 100644 --- a/src/gallium/drivers/iris/iris_screen.c +++ b/src/gallium/drivers/iris/iris_screen.c @@ -369,6 +369,7 @@ iris_init_screen_caps(struct iris_screen *screen) caps->compute_shader_derivatives = true; caps->invalidate_buffer = true; caps->surface_reinterpret_blocks = true; + caps->compressed_surface_reinterpret_blocks_layered = devinfo->ver >= 9; caps->texture_shadow_lod = true; caps->shader_samples_identical = true; caps->gl_spirv = true; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index b189dd654c2..fc8292dbbd1 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -221,6 +221,7 @@ nv30_init_screen_caps(struct nv30_screen *screen) caps->string_marker = false; caps->buffer_sampler_view_rgba_only = false; caps->surface_reinterpret_blocks = false; + caps->compressed_surface_reinterpret_blocks_layered = false; caps->query_buffer_object = false; caps->framebuffer_no_attachment = false; caps->robust_buffer_access_behavior = false; diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index ea2dd2ca001..25b6f723f33 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -438,6 +438,7 @@ static void r600_init_screen_caps(struct r600_screen *rscreen) caps->copy_between_compressed_and_plain_formats = true; caps->invalidate_buffer = true; caps->surface_reinterpret_blocks = true; + caps->compressed_surface_reinterpret_blocks_layered = true; caps->query_memory_info = true; caps->query_so_overflow = family >= CHIP_CEDAR; caps->framebuffer_no_attachment = true; diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c index e13e18ec649..279bf3c2e42 100644 --- a/src/gallium/drivers/radeonsi/si_get.c +++ b/src/gallium/drivers/radeonsi/si_get.c @@ -1095,6 +1095,7 @@ void si_init_screen_caps(struct si_screen *sscreen) caps->fs_face_is_integer_sysval = true; caps->invalidate_buffer = true; caps->surface_reinterpret_blocks = true; + caps->compressed_surface_reinterpret_blocks_layered = true; caps->query_buffer_object = true; caps->query_memory_info = true; caps->shader_pack_half_float = true; diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 63d8b027238..1bef3651422 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -742,6 +742,8 @@ zink_init_screen_caps(struct zink_screen *screen) caps->surface_reinterpret_blocks = screen->info.have_vulkan11 || screen->info.have_KHR_maintenance2; + caps->compressed_surface_reinterpret_blocks_layered = caps->surface_reinterpret_blocks && + screen->info.maint6_props.blockTexelViewCompatibleMultipleLayers; caps->validate_all_dirty_states = true; caps->allow_mapped_buffers_during_execution = true; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 44a47a4d88e..e5c7a7e348d 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -893,6 +893,7 @@ struct pipe_caps { bool generate_mipmap; bool string_marker; bool surface_reinterpret_blocks; + bool compressed_surface_reinterpret_blocks_layered; bool query_buffer_object; bool query_memory_info; bool framebuffer_no_attachment; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 849c0f43daf..44d280f4b8c 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -2559,26 +2559,28 @@ st_CompressedTexSubImage(struct gl_context *ctx, GLuint dims, templ.first_layer = MIN2(layer, max_layer); templ.last_layer = MIN2(layer + d - 1, max_layer); - if (st_try_pbo_compressed_texsubimage(ctx, buf, buf_offset, &addr, - &templ)) - return; - - /* Some drivers can re-interpret surfaces but only one layer at a time. - * Fall back to doing a single try_pbo_upload_common per layer. - */ - while (layer <= max_layer) { - templ.first_layer = MIN2(layer, max_layer); - templ.last_layer = templ.first_layer; - if (!st_try_pbo_compressed_texsubimage(ctx, buf, buf_offset, &addr, - &templ)) - goto fallback; - - /* By incrementing layer here, we ensure the fallback only uploads - * layers we failed to upload. + if (templ.first_layer != templ.last_layer && + !screen->caps.compressed_surface_reinterpret_blocks_layered) { + /* Some drivers can re-interpret surfaces but only one layer at a time. + * Fall back to doing a single try_pbo_upload_common per layer. */ - buf_offset += addr.pixels_per_row * addr.image_height; - layer++; - addr.depth--; + while (layer <= max_layer) { + templ.first_layer = MIN2(layer, max_layer); + templ.last_layer = templ.first_layer; + if (!st_try_pbo_compressed_texsubimage(ctx, buf, buf_offset, &addr, + &templ)) + goto fallback; + + /* By incrementing layer here, we ensure the fallback only uploads + * layers we failed to upload. + */ + buf_offset += addr.pixels_per_row * addr.image_height; + layer++; + addr.depth--; + } + success = true; + } else { + success = st_try_pbo_compressed_texsubimage(ctx, buf, buf_offset, &addr, &templ); } if (success)