From 191f8a4b9fcdf71c4edaa523e10b744b354fb5e4 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Mon, 31 Aug 2020 21:58:12 +0200 Subject: [PATCH] spirv: Deal with glslang not setting NonUniform on constructors. Especially a problem for OpImage/OpSampledImage. Note that the problem doesn't seem to be propagation through glslang, but only in emitting the SPIR-V. So it is fine if we are somewhat lossy in handling this, as long as direct Op(Sampled)Image -> texture op chains work. Fixes: af81486a8cd "spirv: Simplify our handling of NonUniform" Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 Reviewed-by: Jason Ekstrand Part-of: --- src/compiler/spirv/spirv_to_nir.c | 30 ++++++++++++++++++++++++------ src/compiler/spirv/vtn_private.h | 6 ++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index d39f2a0d4f1..12699ce5d6d 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -324,11 +324,12 @@ vtn_get_image(struct vtn_builder *b, uint32_t value_id) static void vtn_push_image(struct vtn_builder *b, uint32_t value_id, - nir_deref_instr *deref) + nir_deref_instr *deref, bool propagate_non_uniform) { struct vtn_type *type = vtn_get_value_type(b, value_id); vtn_assert(type->base_type == vtn_base_type_image); - vtn_push_nir_ssa(b, value_id, &deref->dest.ssa); + struct vtn_value *value = vtn_push_nir_ssa(b, value_id, &deref->dest.ssa); + value->propagated_non_uniform = propagate_non_uniform; } static nir_deref_instr * @@ -349,11 +350,13 @@ vtn_sampled_image_to_nir_ssa(struct vtn_builder *b, static void vtn_push_sampled_image(struct vtn_builder *b, uint32_t value_id, - struct vtn_sampled_image si) + struct vtn_sampled_image si, bool propagate_non_uniform) { struct vtn_type *type = vtn_get_value_type(b, value_id); vtn_assert(type->base_type == vtn_base_type_sampled_image); - vtn_push_nir_ssa(b, value_id, vtn_sampled_image_to_nir_ssa(b, si)); + struct vtn_value *value = vtn_push_nir_ssa(b, value_id, + vtn_sampled_image_to_nir_ssa(b, si)); + value->propagated_non_uniform = propagate_non_uniform; } static struct vtn_sampled_image @@ -2490,11 +2493,23 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, .image = vtn_get_image(b, w[3]), .sampler = vtn_get_sampler(b, w[4]), }; - vtn_push_sampled_image(b, w[2], si); + + enum gl_access_qualifier access = 0; + vtn_foreach_decoration(b, vtn_untyped_value(b, w[3]), + non_uniform_decoration_cb, &access); + vtn_foreach_decoration(b, vtn_untyped_value(b, w[4]), + non_uniform_decoration_cb, &access); + + vtn_push_sampled_image(b, w[2], si, access & ACCESS_NON_UNIFORM); return; } else if (opcode == SpvOpImage) { struct vtn_sampled_image si = vtn_get_sampled_image(b, w[3]); - vtn_push_image(b, w[2], si.image); + + enum gl_access_qualifier access = 0; + vtn_foreach_decoration(b, vtn_untyped_value(b, w[3]), + non_uniform_decoration_cb, &access); + + vtn_push_image(b, w[2], si.image, access & ACCESS_NON_UNIFORM); return; } @@ -2816,6 +2831,9 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, enum gl_access_qualifier access = 0; vtn_foreach_decoration(b, sampled_val, non_uniform_decoration_cb, &access); + if (sampled_val->propagated_non_uniform) + access |= ACCESS_NON_UNIFORM; + if (image && (access & ACCESS_NON_UNIFORM)) instr->texture_non_uniform = true; diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index 300fb017257..b47fed64649 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -584,6 +584,12 @@ struct vtn_image_pointer { struct vtn_value { enum vtn_value_type value_type; + + /* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 + * Only set for OpImage / OpSampledImage. Note that this is in addition + * the existence of a NonUniform decoration on this value.*/ + uint32_t propagated_non_uniform : 1; + const char *name; struct vtn_decoration *decoration; struct vtn_type *type; -- 2.30.2