diff options
author | Samuel Iglesias Gonsálvez <siglesias@igalia.com> | 2020-12-14 14:05:57 +0100 |
---|---|---|
committer | Samuel Iglesias Gonsálvez <siglesias@igalia.com> | 2020-12-18 06:43:07 +0100 |
commit | 84136d78e6417c6c423111d6bab7d623f4f2f0c4 (patch) | |
tree | 513cfc3e00206d128aef0d0338bf36bb7726aa9f | |
parent | 8c5c133741f7e831637b9aee167d6e1a2300b227 (diff) |
turnip: fix cube map array image size calculation
imageSize() expects the last component of the return value to be the
number of layers in the texture array. In the case of cube map array,
it will return a ivec3, with the third component being the number of
layer-faces.
Fixes: dEQP-VK.image.image_size.cube_array.*
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8087>
-rw-r--r-- | src/freedreno/vulkan/tu_shader.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/freedreno/vulkan/tu_shader.c b/src/freedreno/vulkan/tu_shader.c index 92eb1a2d7c6..2cc87c56205 100644 --- a/src/freedreno/vulkan/tu_shader.c +++ b/src/freedreno/vulkan/tu_shader.c @@ -670,6 +670,50 @@ tu_lower_io(nir_shader *shader, struct tu_shader *tu_shader, return progress; } +static bool +lower_image_size_filter(const nir_instr *instr, UNUSED const void *data) +{ + if (instr->type != nir_instr_type_intrinsic) + return false; + + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + if(intrin->intrinsic != nir_intrinsic_bindless_image_size) + return false; + + return (intrin->num_components == 3 && nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_CUBE); +} + +/* imageSize() expects the last component of the return value to be the + * number of layers in the texture array. In the case of cube map array, + * it will return a ivec3, with the third component being the number of + * layer-faces. Therefore, we need to divide it by 6 (# faces of the + * cube map). + */ +static nir_ssa_def * +lower_image_size_lower(nir_builder *b, nir_instr *instr, UNUSED void *data) +{ + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + b->cursor = nir_after_instr(&intrin->instr); + nir_ssa_def *channels[NIR_MAX_VEC_COMPONENTS]; + for (unsigned i = 0; i < intrin->num_components; i++) { + channels[i] = nir_vector_extract(b, &intrin->dest.ssa, nir_imm_int(b, i)); + } + + channels[2] = nir_idiv(b, channels[2], nir_imm_int(b, 6u)); + nir_ssa_def *result = nir_vec(b, channels, intrin->num_components); + + return result; +} + +static bool +tu_lower_image_size(nir_shader *shader) +{ + return nir_shader_lower_instructions(shader, + lower_image_size_filter, + lower_image_size_lower, + NULL); +} + static void shared_type_info(const struct glsl_type *type, unsigned *size, unsigned *align) { @@ -793,6 +837,8 @@ tu_shader_create(struct tu_device *dev, NIR_PASS_V(nir, tu_lower_io, shader, layout); + NIR_PASS_V(nir, tu_lower_image_size); + nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); ir3_finalize_nir(dev->compiler, nir); |