summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLionel Landwerlin <[email protected]>2019-05-16 13:06:27 +0100
committerJuan A. Suarez Romero <[email protected]>2019-07-30 08:25:46 +0000
commit83d17d573080343abf77d9eb0baceb8a91464330 (patch)
treebf308e53fe0dfb91c2dd66a7f2a6e17c6c92f03d
parent0801a8b906547f17e6d0ef5fb4062033211498a6 (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.c2
-rw-r--r--src/compiler/spirv/vtn_private.h34
-rw-r--r--src/compiler/spirv/vtn_variables.c30
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;
}