summaryrefslogtreecommitdiffstats
path: root/src/compiler/spirv/vtn_variables.c
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2017-06-28 00:45:36 -0700
committerJason Ekstrand <[email protected]>2017-07-18 09:43:12 -0700
commitf2fe74a462ea6e019678c89632a99d8037a2f153 (patch)
tree32b5700a74780003cdf1df6db6f00d8f1e748ce5 /src/compiler/spirv/vtn_variables.c
parent182950ceaf9034e0f6f6e641784af2641d8d178f (diff)
nir/spirv: Add support for SPV_KHR_variable_pointers
Reviewed-by: Iago Toral Quiroga <[email protected]>
Diffstat (limited to 'src/compiler/spirv/vtn_variables.c')
-rw-r--r--src/compiler/spirv/vtn_variables.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c
index a9e2dbfaa04..4432e72e54a 100644
--- a/src/compiler/spirv/vtn_variables.c
+++ b/src/compiler/spirv/vtn_variables.c
@@ -223,8 +223,7 @@ vtn_pointer_dereference(struct vtn_builder *b,
struct vtn_pointer *base,
struct vtn_access_chain *deref_chain)
{
- if (base->mode == vtn_variable_mode_ubo ||
- base->mode == vtn_variable_mode_ssbo) {
+ if (vtn_pointer_uses_ssa_offset(base)) {
return vtn_ssa_offset_pointer_dereference(b, base, deref_chain);
} else {
return vtn_access_chain_pointer_dereference(b, base, deref_chain);
@@ -1478,6 +1477,53 @@ vtn_storage_class_to_mode(SpvStorageClass class,
return mode;
}
+nir_ssa_def *
+vtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr)
+{
+ /* This pointer needs to have a pointer type with actual storage */
+ assert(ptr->ptr_type);
+ assert(ptr->ptr_type->type);
+
+ if (ptr->offset && ptr->block_index) {
+ return nir_vec2(&b->nb, ptr->block_index, ptr->offset);
+ } else {
+ /* If we don't have an offset or block index, then we must be a pointer
+ * to the variable itself.
+ */
+ assert(!ptr->offset && !ptr->block_index);
+
+ /* We can't handle a pointer to an array of descriptors because we have
+ * no way of knowing later on that we need to add to update the block
+ * index when dereferencing.
+ */
+ assert(ptr->var && ptr->var->type->base_type == vtn_base_type_struct);
+
+ return nir_vec2(&b->nb, vtn_variable_resource_index(b, ptr->var, NULL),
+ nir_imm_int(&b->nb, 0));
+ }
+}
+
+struct vtn_pointer *
+vtn_pointer_from_ssa(struct vtn_builder *b, nir_ssa_def *ssa,
+ struct vtn_type *ptr_type)
+{
+ assert(ssa->num_components == 2 && ssa->bit_size == 32);
+ assert(ptr_type->base_type == vtn_base_type_pointer);
+ assert(ptr_type->deref->base_type != vtn_base_type_pointer);
+ /* This pointer type needs to have actual storage */
+ assert(ptr_type->type);
+
+ struct vtn_pointer *ptr = rzalloc(b, struct vtn_pointer);
+ ptr->mode = vtn_storage_class_to_mode(ptr_type->storage_class,
+ ptr_type, NULL);
+ ptr->type = ptr_type->deref;
+ ptr->ptr_type = ptr_type;
+ ptr->block_index = nir_channel(&b->nb, ssa, 0);
+ ptr->offset = nir_channel(&b->nb, ssa, 1);
+
+ return ptr;
+}
+
static bool
is_per_vertex_inout(const struct vtn_variable *var, gl_shader_stage stage)
{
@@ -1503,7 +1549,6 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
{
assert(ptr_type->base_type == vtn_base_type_pointer);
struct vtn_type *type = ptr_type->deref;
- assert(type->base_type != vtn_base_type_pointer);
struct vtn_type *without_array = type;
while(glsl_type_is_array(without_array->type))