diff options
author | Lionel Landwerlin <[email protected]> | 2019-05-16 13:06:27 +0100 |
---|---|---|
committer | Juan A. Suarez Romero <[email protected]> | 2019-07-30 08:25:46 +0000 |
commit | 83d17d573080343abf77d9eb0baceb8a91464330 (patch) | |
tree | bf308e53fe0dfb91c2dd66a7f2a6e17c6c92f03d | |
parent | 0801a8b906547f17e6d0ef5fb4062033211498a6 (diff) |
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 <[email protected]>
Fixes: 8ed583fe523703 ("spirv: Handle the NonUniformEXT decoration")
Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]>
(cherry picked from commit 0fb61dfdebac802e4b4c7b5dbebf3d7ba1e60dc2)
-rw-r--r-- | src/compiler/spirv/spirv_to_nir.c | 2 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_private.h | 34 | ||||
-rw-r--r-- | 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 230c6cd1db2..e993ec32382 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -2607,6 +2607,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 6cdcfe13843..0f1f30e3d0a 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 { @@ -416,6 +419,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 @@ -696,6 +702,34 @@ vtn_constant_uint(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 1bcf0b4f71c..2cb5c95487a 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; } @@ -218,7 +235,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; @@ -2378,6 +2395,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; @@ -2405,8 +2423,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++; } @@ -2436,6 +2454,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; @@ -2573,10 +2592,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; } @@ -2596,6 +2616,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; } |