}
struct vtn_value *
-vtn_push_value_pointer(struct vtn_builder *b, uint32_t value_id,
- struct vtn_pointer *ptr)
+vtn_push_pointer(struct vtn_builder *b, uint32_t value_id,
+ struct vtn_pointer *ptr)
{
struct vtn_value *val = vtn_push_value(b, value_id, vtn_value_type_pointer);
val->pointer = vtn_decorate_pointer(b, val, ptr);
return val;
}
-static void
-ssa_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
- const struct vtn_decoration *dec, void *void_ctx)
-{
- switch (dec->decoration) {
- case SpvDecorationNonUniformEXT:
- if (val->value_type == vtn_value_type_ssa) {
- val->ssa->access |= ACCESS_NON_UNIFORM;
- } else if (val->value_type == vtn_value_type_pointer) {
- val->pointer->access |= ACCESS_NON_UNIFORM;
- } else if (val->value_type == vtn_value_type_sampled_image) {
- val->sampled_image->image->access |= ACCESS_NON_UNIFORM;
- } else if (val->value_type == vtn_value_type_image_pointer) {
- val->image->image->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)
-{
- struct vtn_value *val;
- if (type->base_type == vtn_base_type_pointer) {
- val = vtn_push_value_pointer(b, value_id, vtn_pointer_from_ssa(b, ssa->def, type));
- } else {
- val = vtn_push_value(b, value_id, vtn_value_type_ssa);
- val->ssa = ssa;
- vtn_foreach_decoration(b, val, ssa_decoration_cb, NULL);
- }
- return val;
-}
-
void
vtn_copy_value(struct vtn_builder *b, uint32_t src_value_id,
uint32_t dst_value_id)
src_copy.type = dst->type;
*dst = src_copy;
- vtn_foreach_decoration(b, dst, ssa_decoration_cb, NULL);
+ if (dst->value_type == vtn_value_type_pointer)
+ dst->pointer = vtn_decorate_pointer(b, dst, dst->pointer);
}
static struct vtn_access_chain *
struct vtn_type *type, enum gl_access_qualifier access,
struct vtn_ssa_value **inout)
{
- if (load && *inout == NULL)
- *inout = vtn_create_ssa_value(b, type->type);
-
enum glsl_base_type base_type = glsl_get_base_type(type->type);
switch (base_type) {
case GLSL_TYPE_UINT:
nir_ssa_def *offset, *index = NULL;
offset = vtn_pointer_to_offset(b, src, &index);
- struct vtn_ssa_value *value = NULL;
+ struct vtn_ssa_value *value = vtn_create_ssa_value(b, src->type->type);
_vtn_block_load_store(b, op, true, index, offset,
access_offset, access_size,
src->type, src->access, &value);
* deref.
*/
if (load) {
- *inout = vtn_create_ssa_value(b, ptr->type->type);
(*inout)->def = nir_load_deref_with_access(&b->nb, deref,
ptr->type->access | access);
} else {
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_STRUCT: {
unsigned elems = glsl_get_length(ptr->type->type);
- if (load) {
- vtn_assert(*inout == NULL);
- *inout = rzalloc(b, struct vtn_ssa_value);
- (*inout)->type = ptr->type->type;
- (*inout)->elems = rzalloc_array(b, struct vtn_ssa_value *, elems);
- }
-
struct vtn_access_chain chain = {
.length = 1,
.link = {
if (vtn_pointer_uses_ssa_offset(b, src)) {
return vtn_block_load(b, src);
} else {
- struct vtn_ssa_value *val = NULL;
+ struct vtn_ssa_value *val = vtn_create_ssa_value(b, src->type->type);
_vtn_variable_load_store(b, true, src, src->access, &val);
return val;
}
vtn_fail("invalid stage for SpvBuiltInViewportIndex");
break;
case SpvBuiltInTessLevelOuter:
- if (b->options && b->options->tess_levels_are_sysvals &&
- *mode == nir_var_shader_in) {
- *location = SYSTEM_VALUE_TESS_LEVEL_OUTER;
- set_mode_system_value(b, mode);
- } else {
- *location = VARYING_SLOT_TESS_LEVEL_OUTER;
- }
+ *location = VARYING_SLOT_TESS_LEVEL_OUTER;
break;
case SpvBuiltInTessLevelInner:
- if (b->options && b->options->tess_levels_are_sysvals &&
- *mode == nir_var_shader_in) {
- *location = SYSTEM_VALUE_TESS_LEVEL_INNER;
- set_mode_system_value(b, mode);
- } else {
- *location = VARYING_SLOT_TESS_LEVEL_INNER;
- }
+ *location = VARYING_SLOT_TESS_LEVEL_INNER;
break;
case SpvBuiltInTessCoord:
*location = SYSTEM_VALUE_TESS_COORD;
case SpvDecorationRestrict:
var_data->access |= ACCESS_RESTRICT;
break;
+ case SpvDecorationAliased:
+ var_data->access &= ~ACCESS_RESTRICT;
+ break;
case SpvDecorationVolatile:
var_data->access |= ACCESS_VOLATILE;
break;
switch (builtin) {
case SpvBuiltInTessLevelOuter:
case SpvBuiltInTessLevelInner:
- /* Since the compact flag is only valid on arrays, don't set it if
- * we are lowering TessLevelInner/Outer to vec4/vec2. */
- if (!b->options || !b->options->lower_tess_levels_to_vec)
- var_data->compact = true;
- break;
case SpvBuiltInClipDistance:
case SpvBuiltInCullDistance:
var_data->compact = true;
case SpvDecorationRowMajor:
case SpvDecorationColMajor:
case SpvDecorationMatrixStride:
- case SpvDecorationAliased:
case SpvDecorationUniform:
case SpvDecorationUniformId:
case SpvDecorationLinkageAttributes:
}
}
-static void
-var_decoration_tess_level_vec_cb(
- struct vtn_builder *b, struct vtn_value *val, int member,
- const struct vtn_decoration *dec, void *void_var)
-{
- struct vtn_variable *vtn_var = void_var;
- if (dec->decoration == SpvDecorationBuiltIn) {
- SpvBuiltIn builtin = dec->operands[0];
- if (builtin == SpvBuiltInTessLevelOuter) {
- vtn_var->var->type = glsl_vector_type(GLSL_TYPE_FLOAT, 4);
- } else if (builtin == SpvBuiltInTessLevelInner) {
- vtn_var->var->type = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
- }
- }
-}
-
enum vtn_variable_mode
vtn_storage_class_to_mode(struct vtn_builder *b,
SpvStorageClass class,
if (var_initializer)
var->var->pointer_initializer = var_initializer;
+ if (var->mode == vtn_variable_mode_uniform ||
+ var->mode == vtn_variable_mode_ssbo) {
+ /* SSBOs and images are assumed to not alias in the Simple, GLSL and Vulkan memory models */
+ var->var->data.access |= b->mem_model != SpvMemoryModelOpenCL ? ACCESS_RESTRICT : 0;
+ }
+
vtn_foreach_decoration(b, val, var_decoration_cb, var);
vtn_foreach_decoration(b, val, ptr_decoration_cb, val->pointer);
- if (b->options && b->options->lower_tess_levels_to_vec)
- vtn_foreach_decoration(b, val, var_decoration_tess_level_vec_cb, var);
-
/* Propagate access flags from the OpVariable decorations. */
val->pointer->access |= var->access;
switch (opcode) {
case SpvOpUndef: {
struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_undef);
- val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
+ val->type = vtn_get_type(b, w[1]);
break;
}
case SpvOpVariable: {
- struct vtn_type *ptr_type = vtn_value(b, w[1], vtn_value_type_type)->type;
+ struct vtn_type *ptr_type = vtn_get_type(b, w[1]);
struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_pointer);
chain->link[idx].mode = vtn_access_mode_id;
chain->link[idx].id = w[i];
}
- access |= vtn_value_access(link_val);
idx++;
}
- struct vtn_type *ptr_type = vtn_value(b, w[1], vtn_value_type_type)->type;
+ struct vtn_type *ptr_type = vtn_get_type(b, w[1]);
struct vtn_value *base_val = vtn_untyped_value(b, w[3]);
if (base_val->value_type == vtn_value_type_sampled_image) {
/* This is rather insane. SPIR-V allows you to use OpSampledImage
vtn_pointer_dereference(b, base_val->pointer, chain);
ptr->ptr_type = ptr_type;
ptr->access |= access;
- vtn_push_value_pointer(b, w[2], ptr);
+ vtn_push_pointer(b, w[2], ptr);
}
break;
}
}
case SpvOpLoad: {
- struct vtn_type *res_type =
- vtn_value(b, w[1], vtn_value_type_type)->type;
+ struct vtn_type *res_type = vtn_get_type(b, w[1]);
struct vtn_value *src_val = vtn_value(b, w[3], vtn_value_type_pointer);
struct vtn_pointer *src = src_val->pointer;
if (res_type->base_type == vtn_base_type_image ||
res_type->base_type == vtn_base_type_sampler) {
- vtn_push_value_pointer(b, w[2], src);
+ vtn_push_pointer(b, w[2], src);
return;
} else if (res_type->base_type == vtn_base_type_sampled_image) {
struct vtn_value *val =
}
}
- vtn_push_ssa(b, w[2], res_type, vtn_variable_load(b, src));
+ vtn_push_ssa_value(b, w[2], vtn_variable_load(b, src));
break;
}
nir_imm_int(&b->nb, 0u)),
nir_imm_int(&b->nb, stride));
- struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
- val->ssa = vtn_create_ssa_value(b, glsl_uint_type());
- val->ssa->def = array_length;
+ vtn_push_nir_ssa(b, w[2], array_length);
break;
}
case SpvOpConvertPtrToU: {
- struct vtn_value *u_val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+ struct vtn_type *u_type = vtn_get_type(b, w[1]);
+ struct vtn_type *ptr_type = vtn_get_value_type(b, w[3]);
+
+ vtn_fail_if(ptr_type->base_type != vtn_base_type_pointer ||
+ ptr_type->type == NULL,
+ "OpConvertPtrToU can only be used on physical pointers");
- vtn_fail_if(u_val->type->base_type != vtn_base_type_vector &&
- u_val->type->base_type != vtn_base_type_scalar,
+ vtn_fail_if(u_type->base_type != vtn_base_type_vector &&
+ u_type->base_type != vtn_base_type_scalar,
"OpConvertPtrToU can only be used to cast to a vector or "
"scalar type");
/* The pointer will be converted to an SSA value automatically */
- 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->def, u_val->type->type);
- u_val->ssa->access |= ptr_ssa->access;
+ nir_ssa_def *ptr = vtn_get_nir_ssa(b, w[3]);
+ nir_ssa_def *u = nir_sloppy_bitcast(&b->nb, ptr, u_type->type);
+ vtn_push_nir_ssa(b, w[2], u);
break;
}
case SpvOpConvertUToPtr: {
- struct vtn_value *ptr_val =
- vtn_push_value(b, w[2], vtn_value_type_pointer);
- struct vtn_value *u_val = vtn_untyped_value(b, w[3]);
+ struct vtn_type *ptr_type = vtn_get_type(b, w[1]);
+ struct vtn_type *u_type = vtn_get_value_type(b, w[3]);
- vtn_fail_if(ptr_val->type->type == NULL,
+ vtn_fail_if(ptr_type->base_type != vtn_base_type_pointer ||
+ ptr_type->type == NULL,
"OpConvertUToPtr can only be used on physical pointers");
- vtn_fail_if(u_val->type->base_type != vtn_base_type_vector &&
- u_val->type->base_type != vtn_base_type_scalar,
+ vtn_fail_if(u_type->base_type != vtn_base_type_vector &&
+ u_type->base_type != vtn_base_type_scalar,
"OpConvertUToPtr can only be used to cast from a vector or "
"scalar type");
- struct vtn_ssa_value *u_ssa = vtn_ssa_value(b, w[3]);
- nir_ssa_def *ptr_ssa = nir_sloppy_bitcast(&b->nb, u_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;
+ nir_ssa_def *u = vtn_get_nir_ssa(b, w[3]);
+ nir_ssa_def *ptr = nir_sloppy_bitcast(&b->nb, u, ptr_type->type);
+ vtn_push_pointer(b, w[2], vtn_pointer_from_ssa(b, ptr, ptr_type));
break;
}