summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Iglesias Gonsálvez <siglesias@igalia.com>2020-12-14 14:05:57 +0100
committerSamuel Iglesias Gonsálvez <siglesias@igalia.com>2020-12-18 06:43:07 +0100
commit84136d78e6417c6c423111d6bab7d623f4f2f0c4 (patch)
tree513cfc3e00206d128aef0d0338bf36bb7726aa9f
parent8c5c133741f7e831637b9aee167d6e1a2300b227 (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.c46
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);