From fe884e30f8e5eb7bd1e7bfecc9b62d916c28bf0e Mon Sep 17 00:00:00 2001 From: Simon Perretta Date: Thu, 13 Mar 2025 21:41:58 +0000 Subject: [PATCH] pvr, pco: image size query support Signed-off-by: Simon Perretta Acked-by: Erik Faye-Lund Part-of: --- src/imagination/pco/pco_data.h | 2 +- src/imagination/pco/pco_nir_tex.c | 57 ++++++++++++++++++++++++-- src/imagination/pco/pco_nir_vk.c | 2 + src/imagination/vulkan/pvr_image.c | 1 + src/imagination/vulkan/pvr_tex_state.c | 2 +- src/imagination/vulkan/pvr_tex_state.h | 1 + 6 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/imagination/pco/pco_data.h b/src/imagination/pco/pco_data.h index a82b0e2e261..bd87b9c4655 100644 --- a/src/imagination/pco/pco_data.h +++ b/src/imagination/pco/pco_data.h @@ -111,9 +111,9 @@ typedef struct _pco_cs_data { /** PCO image descriptor metadata. */ enum pco_image_meta { PCO_IMAGE_META_LAYER_SIZE, + PCO_IMAGE_META_BUFFER_ELEMS, PCO_IMAGE_META_RSVD0, PCO_IMAGE_META_RSVD1, - PCO_IMAGE_META_RSVD2, PCO_IMAGE_META_COUNT, }; diff --git a/src/imagination/pco/pco_nir_tex.c b/src/imagination/pco/pco_nir_tex.c index e86d1ca4f17..bf18ab93a07 100644 --- a/src/imagination/pco/pco_nir_tex.c +++ b/src/imagination/pco/pco_nir_tex.c @@ -724,6 +724,58 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data) enum glsl_sampler_dim image_dim = nir_intrinsic_image_dim(intr); bool is_array = nir_intrinsic_image_array(intr); enum pipe_format format = nir_intrinsic_format(intr); + unsigned desc_set = nir_src_comp_as_uint(intr->src[0], 0); + unsigned binding = nir_src_comp_as_uint(intr->src[0], 1); + nir_def *elem = nir_channel(b, intr->src[0].ssa, 2); + + if (intr->intrinsic == nir_intrinsic_image_deref_size) { + if (image_dim == GLSL_SAMPLER_DIM_BUF) { + assert(intr->def.num_components == 1); + nir_def *tex_meta = nir_load_tex_meta_pco(b, + PCO_IMAGE_META_COUNT, + elem, + .desc_set = desc_set, + .binding = binding); + + return nir_channel(b, tex_meta, PCO_IMAGE_META_BUFFER_ELEMS); + } + + nir_def *tex_state = nir_load_tex_state_pco(b, + ROGUE_NUM_TEXSTATE_DWORDS, + elem, + .desc_set = desc_set, + .binding = binding); + + nir_def *tex_state_word[] = { + [0] = nir_channel(b, tex_state, 0), + [1] = nir_channel(b, tex_state, 1), + [2] = nir_channel(b, tex_state, 2), + [3] = nir_channel(b, tex_state, 3), + }; + + unsigned num_comps = intr->def.num_components; + if (is_array) + --num_comps; + + nir_def *size_comps[] = { + [0] = STATE_UNPACK_ADD(b, tex_state_word, 1, 2, 14, 1), + [1] = STATE_UNPACK_ADD(b, tex_state_word, 1, 16, 14, 1), + [2] = STATE_UNPACK_ADD(b, tex_state_word, 2, 4, 11, 1), + }; + + nir_def *base_level = STATE_UNPACK(b, tex_state_word, 3, 28, 4); + nir_def *lod = intr->src[0].ssa; + lod = nir_iadd(b, lod, base_level); + + for (unsigned c = 0; c < num_comps; ++c) + size_comps[c] = nir_umax_imm(b, nir_ushr(b, size_comps[c], lod), 1); + + if (image_dim == GLSL_SAMPLER_DIM_1D && is_array) + size_comps[1] = size_comps[2]; + + return nir_vec(b, size_comps, intr->def.num_components); + } + nir_alu_type type = intr->intrinsic == nir_intrinsic_image_deref_load ? nir_intrinsic_dest_type(intr) : nir_intrinsic_src_type(intr); @@ -731,10 +783,6 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data) bool msaa = image_dim == GLSL_SAMPLER_DIM_MS || image_dim == GLSL_SAMPLER_DIM_SUBPASS_MS; - unsigned desc_set = nir_src_comp_as_uint(intr->src[0], 0); - unsigned binding = nir_src_comp_as_uint(intr->src[0], 1); - nir_def *elem = nir_channel(b, intr->src[0].ssa, 2); - nir_def *coords = intr->src[1].ssa; nir_def *sample_index = msaa ? intr->src[2].ssa : NULL; @@ -881,6 +929,7 @@ static bool is_image(const nir_instr *instr, UNUSED const void *cb_data) switch (intr->intrinsic) { case nir_intrinsic_image_deref_load: case nir_intrinsic_image_deref_store: + case nir_intrinsic_image_deref_size: return true; default: diff --git a/src/imagination/pco/pco_nir_vk.c b/src/imagination/pco/pco_nir_vk.c index ac053ca561e..0c36364033c 100644 --- a/src/imagination/pco/pco_nir_vk.c +++ b/src/imagination/pco/pco_nir_vk.c @@ -197,6 +197,7 @@ static nir_def *lower_vk(nir_builder *b, nir_instr *instr, void *cb_data) case nir_intrinsic_image_deref_load: case nir_intrinsic_image_deref_store: + case nir_intrinsic_image_deref_size: return lower_image_derefs(b, intr, data); default: @@ -235,6 +236,7 @@ static bool is_vk(const nir_instr *instr, UNUSED const void *cb_data) case nir_intrinsic_load_vulkan_descriptor: case nir_intrinsic_image_deref_load: case nir_intrinsic_image_deref_store: + case nir_intrinsic_image_deref_size: return true; default: diff --git a/src/imagination/vulkan/pvr_image.c b/src/imagination/vulkan/pvr_image.c index 6449e3390a1..93202b99ebf 100644 --- a/src/imagination/vulkan/pvr_image.c +++ b/src/imagination/vulkan/pvr_image.c @@ -463,6 +463,7 @@ VkResult pvr_CreateBufferView(VkDevice _device, info.format = bview->vk.format; info.flags = PVR_TEXFLAGS_INDEX_LOOKUP; info.aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT; + info.buffer_elems = bview->vk.elements; if (PVR_HAS_FEATURE(&device->pdevice->dev_info, tpu_array_textures)) info.array_size = 1U; diff --git a/src/imagination/vulkan/pvr_tex_state.c b/src/imagination/vulkan/pvr_tex_state.c index 7285b3fac07..b1a360d8e71 100644 --- a/src/imagination/vulkan/pvr_tex_state.c +++ b/src/imagination/vulkan/pvr_tex_state.c @@ -246,9 +246,9 @@ VkResult pvr_pack_tex_state(struct pvr_device *device, } state->meta[PCO_IMAGE_META_LAYER_SIZE] = info->layer_size; + state->meta[PCO_IMAGE_META_BUFFER_ELEMS] = info->buffer_elems; state->meta[PCO_IMAGE_META_RSVD0] = 0; state->meta[PCO_IMAGE_META_RSVD1] = 0; - state->meta[PCO_IMAGE_META_RSVD2] = 0; return VK_SUCCESS; } diff --git a/src/imagination/vulkan/pvr_tex_state.h b/src/imagination/vulkan/pvr_tex_state.h index f0a32f00386..51f4d95a527 100644 --- a/src/imagination/vulkan/pvr_tex_state.h +++ b/src/imagination/vulkan/pvr_tex_state.h @@ -105,6 +105,7 @@ struct pvr_texture_state_info { pvr_dev_addr_t addr; uint32_t layer_size; + uint32_t buffer_elems; }; VkResult pvr_pack_tex_state(struct pvr_device *device,