From 0fb61dfdebac802e4b4c7b5dbebf3d7ba1e60dc2 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Thu, 16 May 2019 13:06:27 +0100 Subject: [PATCH] spirv: propagate access qualifiers through ssa & pointer Not only variables can be flagged as NonUniformEXT but also expressions. We're currently ignoring it in an expression such as : imageLoad(data[nonuniformEXT(rIndex)], 0) The associated SPIRV : OpDecorate %69 NonUniformEXT ... %69 = OpLoad %61 %68 This changes propagates access qualifiers through ssa & pointers so that when it hits a OpLoad/OpStore style instructions, qualifiers are not forgotten. Fixes failure the following tests : dEQP-VK.descriptor_indexing.* Signed-off-by: Lionel Landwerlin Fixes: 8ed583fe523703 ("spirv: Handle the NonUniformEXT decoration") Reviewed-by: Caio Marcelo de Oliveira Filho --- src/compiler/spirv/spirv_to_nir.c | 2 ++ src/compiler/spirv/vtn_private.h | 34 ++++++++++++++++++++++++++++++ src/compiler/spirv/vtn_variables.c | 30 ++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index c2528cef35a..7a2e30707ce 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -2575,6 +2575,8 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode, intrin->src[2] = nir_src_for_ssa(image.sample); } + nir_intrinsic_set_access(intrin, image.image->access); + switch (opcode) { case SpvOpAtomicLoad: case SpvOpImageQuerySize: diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index 5998196a838..4c1e4f6bb04 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -269,6 +269,9 @@ struct vtn_ssa_value { struct vtn_ssa_value *transposed; const struct glsl_type *type; + + /* Access qualifiers */ + enum gl_access_qualifier access; }; enum vtn_base_type { @@ -418,6 +421,9 @@ struct vtn_access_chain { */ bool ptr_as_array; + /* Access qualifiers */ + enum gl_access_qualifier access; + /** Struct elements and array offsets. * * This is an array of 1 so that it can conveniently be created on the @@ -724,6 +730,34 @@ vtn_constant_int(struct vtn_builder *b, uint32_t value_id) } } +static inline enum gl_access_qualifier vtn_value_access(struct vtn_value *value) +{ + switch (value->value_type) { + case vtn_value_type_invalid: + case vtn_value_type_undef: + case vtn_value_type_string: + case vtn_value_type_decoration_group: + case vtn_value_type_constant: + case vtn_value_type_function: + case vtn_value_type_block: + case vtn_value_type_extension: + return 0; + case vtn_value_type_type: + return value->type->access; + case vtn_value_type_pointer: + return value->pointer->access; + case vtn_value_type_ssa: + return value->ssa->access; + case vtn_value_type_image_pointer: + return value->image->image->access; + case vtn_value_type_sampled_image: + return value->sampled_image->image->access | + value->sampled_image->sampler->access; + } + + unreachable("invalid type"); +} + struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id); struct vtn_value *vtn_push_value_pointer(struct vtn_builder *b, diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 0b03c224af7..c73cbd37cec 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -45,6 +45,22 @@ vtn_push_value_pointer(struct vtn_builder *b, uint32_t value_id, return val; } +static void +ssa_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member, + const struct vtn_decoration *dec, void *void_ssa) +{ + struct vtn_ssa_value *ssa = void_ssa; + + switch (dec->decoration) { + case SpvDecorationNonUniformEXT: + ssa->access |= ACCESS_NON_UNIFORM; + break; + + default: + break; + } +} + struct vtn_value * vtn_push_ssa(struct vtn_builder *b, uint32_t value_id, struct vtn_type *type, struct vtn_ssa_value *ssa) @@ -55,6 +71,7 @@ vtn_push_ssa(struct vtn_builder *b, uint32_t value_id, } else { val = vtn_push_value(b, value_id, vtn_value_type_ssa); val->ssa = ssa; + vtn_foreach_decoration(b, val, ssa_decoration_cb, val->ssa); } return val; } @@ -225,7 +242,7 @@ vtn_nir_deref_pointer_dereference(struct vtn_builder *b, struct vtn_access_chain *deref_chain) { struct vtn_type *type = base->type; - enum gl_access_qualifier access = base->access; + enum gl_access_qualifier access = base->access | deref_chain->access; unsigned idx = 0; nir_deref_instr *tail; @@ -2450,6 +2467,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, case SpvOpInBoundsAccessChain: case SpvOpInBoundsPtrAccessChain: { struct vtn_access_chain *chain = vtn_access_chain_create(b, count - 4); + enum gl_access_qualifier access = 0; chain->ptr_as_array = (opcode == SpvOpPtrAccessChain || opcode == SpvOpInBoundsPtrAccessChain); unsigned idx = 0; @@ -2461,8 +2479,8 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, } else { chain->link[idx].mode = vtn_access_mode_id; chain->link[idx].id = w[i]; - } + access |= vtn_value_access(link_val); idx++; } @@ -2492,6 +2510,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, struct vtn_pointer *ptr = vtn_pointer_dereference(b, base_val->pointer, chain); ptr->ptr_type = ptr_type; + ptr->access = access; vtn_push_value_pointer(b, w[2], ptr); } break; @@ -2629,10 +2648,11 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, "scalar type"); /* The pointer will be converted to an SSA value automatically */ - nir_ssa_def *ptr_ssa = vtn_ssa_value(b, w[3])->def; + struct vtn_ssa_value *ptr_ssa = vtn_ssa_value(b, w[3]); u_val->ssa = vtn_create_ssa_value(b, u_val->type->type); - u_val->ssa->def = nir_sloppy_bitcast(&b->nb, ptr_ssa, u_val->type->type); + u_val->ssa->def = nir_sloppy_bitcast(&b->nb, ptr_ssa->def, u_val->type->type); + u_val->ssa->access |= ptr_ssa->access; break; } @@ -2652,6 +2672,8 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, nir_ssa_def *ptr_ssa = nir_sloppy_bitcast(&b->nb, u_val->ssa->def, ptr_val->type->type); ptr_val->pointer = vtn_pointer_from_ssa(b, ptr_ssa, ptr_val->type); + vtn_foreach_decoration(b, ptr_val, ptr_decoration_cb, ptr_val->pointer); + ptr_val->pointer->access |= u_val->ssa->access; break; } -- 2.30.2