break;
}
+ case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_STRUCT: {
vtn_assert(deref_chain->link[idx].mode == vtn_access_mode_literal);
unsigned member = deref_chain->link[idx].id;
static void
_vtn_local_load_store(struct vtn_builder *b, bool load, nir_deref_instr *deref,
- struct vtn_ssa_value *inout)
+ struct vtn_ssa_value *inout,
+ enum gl_access_qualifier access)
{
if (glsl_type_is_vector_or_scalar(deref->type)) {
if (load) {
- inout->def = nir_load_deref(&b->nb, deref);
+ inout->def = nir_load_deref_with_access(&b->nb, deref, access);
} else {
- nir_store_deref(&b->nb, deref, inout->def, ~0);
+ nir_store_deref_with_access(&b->nb, deref, inout->def, ~0, access);
}
} else if (glsl_type_is_array(deref->type) ||
glsl_type_is_matrix(deref->type)) {
for (unsigned i = 0; i < elems; i++) {
nir_deref_instr *child =
nir_build_deref_array_imm(&b->nb, deref, i);
- _vtn_local_load_store(b, load, child, inout->elems[i]);
+ _vtn_local_load_store(b, load, child, inout->elems[i], access);
}
} else {
vtn_assert(glsl_type_is_struct_or_ifc(deref->type));
unsigned elems = glsl_get_length(deref->type);
for (unsigned i = 0; i < elems; i++) {
nir_deref_instr *child = nir_build_deref_struct(&b->nb, deref, i);
- _vtn_local_load_store(b, load, child, inout->elems[i]);
+ _vtn_local_load_store(b, load, child, inout->elems[i], access);
}
}
}
}
struct vtn_ssa_value *
-vtn_local_load(struct vtn_builder *b, nir_deref_instr *src)
+vtn_local_load(struct vtn_builder *b, nir_deref_instr *src,
+ enum gl_access_qualifier access)
{
nir_deref_instr *src_tail = get_deref_tail(src);
struct vtn_ssa_value *val = vtn_create_ssa_value(b, src_tail->type);
- _vtn_local_load_store(b, true, src_tail, val);
+ _vtn_local_load_store(b, true, src_tail, val, access);
if (src_tail != src) {
val->type = src->type;
void
vtn_local_store(struct vtn_builder *b, struct vtn_ssa_value *src,
- nir_deref_instr *dest)
+ nir_deref_instr *dest, enum gl_access_qualifier access)
{
nir_deref_instr *dest_tail = get_deref_tail(dest);
if (dest_tail != dest) {
struct vtn_ssa_value *val = vtn_create_ssa_value(b, dest_tail->type);
- _vtn_local_load_store(b, true, dest_tail, val);
+ _vtn_local_load_store(b, true, dest_tail, val, access);
if (nir_src_is_const(dest->arr.index))
val->def = vtn_vector_insert(b, val->def, src->def,
else
val->def = vtn_vector_insert_dynamic(b, val->def, src->def,
dest->arr.index.ssa);
- _vtn_local_load_store(b, false, dest_tail, val);
+ _vtn_local_load_store(b, false, dest_tail, val, access);
} else {
- _vtn_local_load_store(b, false, dest_tail, src);
+ _vtn_local_load_store(b, false, dest_tail, src, access);
}
}
nir_intrinsic_set_range(instr, access_size);
}
- if (op == nir_intrinsic_load_ssbo ||
+ if (op == nir_intrinsic_load_ubo ||
+ op == nir_intrinsic_load_ssbo ||
op == nir_intrinsic_store_ssbo) {
nir_intrinsic_set_access(instr, access);
}
return;
}
+ case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_STRUCT: {
unsigned elems = glsl_get_length(type->type);
for (unsigned i = 0; i < elems; i++) {
static void
_vtn_variable_load_store(struct vtn_builder *b, bool load,
struct vtn_pointer *ptr,
+ enum gl_access_qualifier access,
struct vtn_ssa_value **inout)
{
enum glsl_base_type base_type = glsl_get_base_type(ptr->type->type);
*/
if (load) {
*inout = vtn_create_ssa_value(b, ptr->type->type);
- (*inout)->def = nir_load_deref(&b->nb, deref);
+ (*inout)->def = nir_load_deref_with_access(&b->nb, deref,
+ ptr->type->access | access);
} else {
- nir_store_deref(&b->nb, deref, (*inout)->def, ~0);
+ nir_store_deref_with_access(&b->nb, deref, (*inout)->def, ~0,
+ ptr->type->access | access);
}
} else {
if (load) {
- *inout = vtn_local_load(b, deref);
+ *inout = vtn_local_load(b, deref, ptr->type->access | access);
} else {
- vtn_local_store(b, *inout, deref);
+ vtn_local_store(b, *inout, deref, ptr->type->access | access);
}
}
return;
}
/* Fall through */
+ case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_STRUCT: {
unsigned elems = glsl_get_length(ptr->type->type);
for (unsigned i = 0; i < elems; i++) {
chain.link[0].id = i;
struct vtn_pointer *elem = vtn_pointer_dereference(b, ptr, &chain);
- _vtn_variable_load_store(b, load, elem, &(*inout)->elems[i]);
+ _vtn_variable_load_store(b, load, elem, ptr->type->access | access,
+ &(*inout)->elems[i]);
}
return;
}
return vtn_block_load(b, src);
} else {
struct vtn_ssa_value *val = NULL;
- _vtn_variable_load_store(b, true, src, &val);
+ _vtn_variable_load_store(b, true, src, src->access, &val);
return val;
}
}
dest->mode == vtn_variable_mode_workgroup);
vtn_block_store(b, src, dest);
} else {
- _vtn_variable_load_store(b, false, dest, &src);
+ _vtn_variable_load_store(b, false, dest, dest->access, &src);
}
}
vtn_variable_store(b, vtn_variable_load(b, src), dest);
return;
+ case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_STRUCT: {
struct vtn_access_chain chain = {
set_mode_system_value(b, mode);
break;
default:
- vtn_fail("unsupported builtin: %u", builtin);
+ vtn_fail("Unsupported builtin: %s (%u)",
+ spirv_builtin_to_string(builtin), builtin);
}
}
break;
default:
- vtn_fail("Unhandled decoration");
+ vtn_fail_with_decoration("Unhandled decoration", dec->decoration);
}
}
}
}
+static void
+ptr_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
+ const struct vtn_decoration *dec, void *void_ptr)
+{
+ struct vtn_pointer *ptr = void_ptr;
+
+ switch (dec->decoration) {
+ case SpvDecorationNonUniformEXT:
+ ptr->access |= ACCESS_NON_UNIFORM;
+ break;
+
+ default:
+ break;
+ }
+}
+
static enum vtn_variable_mode
vtn_storage_class_to_mode(struct vtn_builder *b,
SpvStorageClass class,
break;
case SpvStorageClassGeneric:
default:
- vtn_fail("Unhandled variable storage class");
+ vtn_fail("Unhandled variable storage class: %s (%u)",
+ spirv_storageclass_to_string(class), class);
}
if (nir_mode_out)
/* Private variables don't have any explicit layout but some layouts
* may have leaked through due to type deduplication in the SPIR-V.
*/
- var->var->type = glsl_get_bare_type(var->type->type);
+ var->var->type = var->type->type;
}
var->var->data.mode = nir_mode;
var->var->data.location = -1;
* layouts may have leaked through due to type deduplication in the
* SPIR-V.
*/
- var->var->type = glsl_get_bare_type(var->type->type);
+ var->var->type = var->type->type;
var->var->data.mode = nir_var_mem_shared;
}
break;
* the SPIR-V. We do, however, keep the layouts in the variable's
* interface_type because we need offsets for XFB arrays of blocks.
*/
- var->var->type = glsl_get_bare_type(var->type->type);
+ var->var->type = var->type->type;
var->var->data.mode = nir_mode;
var->var->data.patch = var->patch;
}
vtn_foreach_decoration(b, val, var_decoration_cb, var);
+ vtn_foreach_decoration(b, val, ptr_decoration_cb, val->pointer);
if ((var->mode == vtn_variable_mode_input ||
var->mode == vtn_variable_mode_output) &&
struct vtn_value *link_val = vtn_untyped_value(b, w[i]);
if (link_val->value_type == vtn_value_type_constant) {
chain->link[idx].mode = vtn_access_mode_literal;
- switch (glsl_get_bit_size(link_val->type->type)) {
+ const unsigned bit_size = glsl_get_bit_size(link_val->type->type);
+ switch (bit_size) {
case 8:
- chain->link[idx].id = link_val->constant->values[0].i8[0];
+ chain->link[idx].id = link_val->constant->values[0][0].i8;
break;
case 16:
- chain->link[idx].id = link_val->constant->values[0].i16[0];
+ chain->link[idx].id = link_val->constant->values[0][0].i16;
break;
case 32:
- chain->link[idx].id = link_val->constant->values[0].i32[0];
+ chain->link[idx].id = link_val->constant->values[0][0].i32;
break;
case 64:
- chain->link[idx].id = link_val->constant->values[0].i64[0];
+ chain->link[idx].id = link_val->constant->values[0][0].i64;
break;
default:
- vtn_fail("Invalid bit size");
+ vtn_fail("Invalid bit size: %u", bit_size);
}
} else {
chain->link[idx].mode = vtn_access_mode_id;
val->sampled_image->image =
vtn_pointer_dereference(b, base_val->sampled_image->image, chain);
val->sampled_image->sampler = base_val->sampled_image->sampler;
+ vtn_foreach_decoration(b, val, ptr_decoration_cb,
+ val->sampled_image->image);
+ vtn_foreach_decoration(b, val, ptr_decoration_cb,
+ val->sampled_image->sampler);
} else {
vtn_assert(base_val->value_type == vtn_value_type_pointer);
struct vtn_value *val =
vtn_push_value(b, w[2], vtn_value_type_pointer);
val->pointer = vtn_pointer_dereference(b, base_val->pointer, chain);
val->pointer->ptr_type = ptr_type;
+ vtn_foreach_decoration(b, val, ptr_decoration_cb, val->pointer);
}
break;
}
case SpvOpCopyMemorySized:
default:
- vtn_fail("Unhandled opcode");
+ vtn_fail_with_opcode("Unhandled opcode", opcode);
}
}