diff options
author | Lionel Landwerlin <[email protected]> | 2019-05-16 13:06:27 +0100 |
---|---|---|
committer | Lionel Landwerlin <[email protected]> | 2019-07-26 14:09:55 +0000 |
commit | 0fb61dfdebac802e4b4c7b5dbebf3d7ba1e60dc2 (patch) | |
tree | 5a0472a80c9b90f60c8adb8746a2f5aee5775285 | |
parent | 86b53770e1ea6e79452ccc97bab829ad58ffc5fd (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]>
-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 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; } |