diff options
author | Jason Ekstrand <[email protected]> | 2017-06-28 00:45:36 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2017-07-18 09:43:12 -0700 |
commit | f2fe74a462ea6e019678c89632a99d8037a2f153 (patch) | |
tree | 32b5700a74780003cdf1df6db6f00d8f1e748ce5 /src/compiler/spirv/vtn_variables.c | |
parent | 182950ceaf9034e0f6f6e641784af2641d8d178f (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.c | 51 |
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)) |