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 <lionel.g.landwerlin@intel.com>
Fixes: 8ed583fe52
("spirv: Handle the NonUniformEXT decoration")
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
This commit is contained in:
@@ -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:
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user