mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-15 02:38:28 +02:00
spirv: Remove (pointed) type from vtn_pointer
This can be obtained by the pointer type (currently at ptr_type). For the cases where there wasn't an user provided type for that, now create an internal vtn_type. This can happen when creating intermediate vtn_pointer for complex loads/stores/copies. Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31069>
This commit is contained in:
parent
95d08643ed
commit
e9ba715710
5 changed files with 59 additions and 45 deletions
|
|
@ -7314,7 +7314,7 @@ vtn_print_value(struct vtn_builder *b, struct vtn_value *val, FILE *f)
|
|||
case vtn_value_type_pointer: {
|
||||
struct vtn_pointer *pointer = val->pointer;
|
||||
fprintf(f, " ptr_type=%u", vtn_id_for_type(b, pointer->ptr_type));
|
||||
fprintf(f, " (pointed-)type=%u", vtn_id_for_type(b, val->pointer->type));
|
||||
fprintf(f, " (pointed-)type=%u", vtn_id_for_type(b, val->pointer->ptr_type->pointed));
|
||||
|
||||
if (pointer->deref) {
|
||||
fprintf(f, "\n NIR: ");
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
|
|||
nir_ior(nb, signed_zero, nir_ffract(nb, abs)));
|
||||
|
||||
struct vtn_pointer *i_ptr = vtn_value(b, w[6], vtn_value_type_pointer)->pointer;
|
||||
struct vtn_ssa_value *whole = vtn_create_ssa_value(b, i_ptr->type->type);
|
||||
struct vtn_ssa_value *whole = vtn_create_ssa_value(b, i_ptr->ptr_type->pointed->type);
|
||||
whole->def = nir_ior(nb, signed_zero, nir_ffloor(nb, abs));
|
||||
vtn_variable_store(b, whole, i_ptr, 0);
|
||||
break;
|
||||
|
|
@ -614,7 +614,7 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
|
|||
dest->def = nir_frexp_sig(nb, src[0]);
|
||||
|
||||
struct vtn_pointer *i_ptr = vtn_value(b, w[6], vtn_value_type_pointer)->pointer;
|
||||
struct vtn_ssa_value *exp = vtn_create_ssa_value(b, i_ptr->type->type);
|
||||
struct vtn_ssa_value *exp = vtn_create_ssa_value(b, i_ptr->ptr_type->pointed->type);
|
||||
exp->def = nir_frexp_exp(nb, src[0]);
|
||||
vtn_variable_store(b, exp, i_ptr, 0);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -657,7 +657,7 @@ _handle_v_load_store(struct vtn_builder *b, enum OpenCLstd_Entrypoints opcode,
|
|||
unsigned alignment = vec_aligned ? glsl_get_cl_alignment(type->type) :
|
||||
glsl_get_bit_size(type->type) / 8;
|
||||
enum glsl_base_type ptr_base_type =
|
||||
glsl_get_base_type(p->pointer->type->type);
|
||||
glsl_get_base_type(p->pointer->ptr_type->pointed->type);
|
||||
if (base_type != ptr_base_type) {
|
||||
vtn_fail_if(ptr_base_type != GLSL_TYPE_FLOAT16 ||
|
||||
(base_type != GLSL_TYPE_FLOAT &&
|
||||
|
|
|
|||
|
|
@ -483,15 +483,7 @@ struct vtn_pointer {
|
|||
/** The variable mode for the referenced data */
|
||||
enum vtn_variable_mode mode;
|
||||
|
||||
/** The dereferenced type of this pointer */
|
||||
struct vtn_type *type;
|
||||
|
||||
/** The pointer type of this pointer
|
||||
*
|
||||
* This may be NULL for some temporary pointers constructed as part of a
|
||||
* large load, store, or copy. It MUST be valid for all pointers which are
|
||||
* stored as SPIR-V SSA values.
|
||||
*/
|
||||
/** The pointer type of this pointer */
|
||||
struct vtn_type *ptr_type;
|
||||
|
||||
/** The referenced variable, if known
|
||||
|
|
|
|||
|
|
@ -316,12 +316,30 @@ vtn_descriptor_load(struct vtn_builder *b, enum vtn_variable_mode mode,
|
|||
return &desc_load->def;
|
||||
}
|
||||
|
||||
static struct vtn_type *
|
||||
vtn_create_internal_pointer_type(struct vtn_builder *b,
|
||||
struct vtn_type *original,
|
||||
struct vtn_type *pointed)
|
||||
{
|
||||
assert(original->base_type == vtn_base_type_pointer);
|
||||
|
||||
/* Create a vtn_type that is not present on the SPIR-V module but
|
||||
* is useful for the compilation process. Such type will have no id.
|
||||
*/
|
||||
struct vtn_type *t = vtn_zalloc(b, struct vtn_type);
|
||||
t->base_type = vtn_base_type_pointer;
|
||||
t->pointed = pointed;
|
||||
t->storage_class = original->storage_class;
|
||||
t->type = original->type;
|
||||
return t;
|
||||
}
|
||||
|
||||
static struct vtn_pointer *
|
||||
vtn_pointer_dereference(struct vtn_builder *b,
|
||||
struct vtn_pointer *base,
|
||||
struct vtn_access_chain *deref_chain)
|
||||
{
|
||||
struct vtn_type *type = base->type;
|
||||
struct vtn_type *type = base->ptr_type->pointed;
|
||||
enum gl_access_qualifier access = base->access | deref_chain->access;
|
||||
unsigned idx = 0;
|
||||
|
||||
|
|
@ -392,7 +410,7 @@ vtn_pointer_dereference(struct vtn_builder *b,
|
|||
}
|
||||
|
||||
if (!block_index) {
|
||||
vtn_assert(base->var && base->type);
|
||||
vtn_assert(base->var && base->ptr_type->pointed);
|
||||
block_index = vtn_variable_resource_index(b, base->var, desc_arr_idx);
|
||||
} else if (desc_arr_idx) {
|
||||
block_index = vtn_resource_reindex(b, base->mode,
|
||||
|
|
@ -405,8 +423,8 @@ vtn_pointer_dereference(struct vtn_builder *b,
|
|||
* will dereference deeper.
|
||||
*/
|
||||
struct vtn_pointer *ptr = vtn_zalloc(b, struct vtn_pointer);
|
||||
ptr->ptr_type = vtn_create_internal_pointer_type(b, base->ptr_type, type);
|
||||
ptr->mode = base->mode;
|
||||
ptr->type = type;
|
||||
ptr->block_index = block_index;
|
||||
ptr->access = access;
|
||||
return ptr;
|
||||
|
|
@ -438,7 +456,7 @@ vtn_pointer_dereference(struct vtn_builder *b,
|
|||
*/
|
||||
tail = nir_build_deref_cast(&b->nb, nir_load_shader_record_ptr(&b->nb),
|
||||
nir_var_mem_constant,
|
||||
vtn_type_get_nir_type(b, base->type,
|
||||
vtn_type_get_nir_type(b, base->ptr_type->pointed,
|
||||
base->mode),
|
||||
0 /* ptr_as_array stride */);
|
||||
} else {
|
||||
|
|
@ -490,8 +508,8 @@ vtn_pointer_dereference(struct vtn_builder *b,
|
|||
}
|
||||
|
||||
struct vtn_pointer *ptr = vtn_zalloc(b, struct vtn_pointer);
|
||||
ptr->ptr_type = vtn_create_internal_pointer_type(b, base->ptr_type, type);
|
||||
ptr->mode = base->mode;
|
||||
ptr->type = type;
|
||||
ptr->var = base->var;
|
||||
ptr->deref = tail;
|
||||
ptr->access = access;
|
||||
|
|
@ -664,13 +682,13 @@ _vtn_variable_load_store(struct vtn_builder *b, bool load,
|
|||
{
|
||||
if (ptr->mode == vtn_variable_mode_uniform ||
|
||||
ptr->mode == vtn_variable_mode_image) {
|
||||
if (ptr->type->base_type == vtn_base_type_image ||
|
||||
ptr->type->base_type == vtn_base_type_sampler) {
|
||||
if (ptr->ptr_type->pointed->base_type == vtn_base_type_image ||
|
||||
ptr->ptr_type->pointed->base_type == vtn_base_type_sampler) {
|
||||
/* See also our handling of OpTypeSampler and OpTypeImage */
|
||||
vtn_assert(load);
|
||||
(*inout)->def = vtn_pointer_to_ssa(b, ptr);
|
||||
return;
|
||||
} else if (ptr->type->base_type == vtn_base_type_sampled_image) {
|
||||
} else if (ptr->ptr_type->pointed->base_type == vtn_base_type_sampled_image) {
|
||||
/* See also our handling of OpTypeSampledImage */
|
||||
vtn_assert(load);
|
||||
struct vtn_sampled_image si = {
|
||||
|
|
@ -686,7 +704,7 @@ _vtn_variable_load_store(struct vtn_builder *b, bool load,
|
|||
return;
|
||||
}
|
||||
|
||||
enum glsl_base_type base_type = glsl_get_base_type(ptr->type->type);
|
||||
enum glsl_base_type base_type = glsl_get_base_type(ptr->ptr_type->pointed->type);
|
||||
switch (base_type) {
|
||||
case GLSL_TYPE_UINT:
|
||||
case GLSL_TYPE_INT:
|
||||
|
|
@ -701,7 +719,7 @@ _vtn_variable_load_store(struct vtn_builder *b, bool load,
|
|||
case GLSL_TYPE_BOOL:
|
||||
case GLSL_TYPE_DOUBLE:
|
||||
case GLSL_TYPE_COOPERATIVE_MATRIX:
|
||||
if (glsl_type_is_vector_or_scalar(ptr->type->type)) {
|
||||
if (glsl_type_is_vector_or_scalar(ptr->ptr_type->pointed->type)) {
|
||||
/* We hit a vector or scalar; go ahead and emit the load[s] */
|
||||
nir_deref_instr *deref = vtn_pointer_to_deref(b, ptr);
|
||||
if (vtn_mode_is_cross_invocation(b, ptr->mode)) {
|
||||
|
|
@ -716,16 +734,16 @@ _vtn_variable_load_store(struct vtn_builder *b, bool load,
|
|||
*/
|
||||
if (load) {
|
||||
(*inout)->def = nir_load_deref_with_access(&b->nb, deref,
|
||||
ptr->type->access | access);
|
||||
ptr->ptr_type->pointed->access | access);
|
||||
} else {
|
||||
nir_store_deref_with_access(&b->nb, deref, (*inout)->def, ~0,
|
||||
ptr->type->access | access);
|
||||
ptr->ptr_type->pointed->access | access);
|
||||
}
|
||||
} else {
|
||||
if (load) {
|
||||
*inout = vtn_local_load(b, deref, ptr->type->access | access);
|
||||
*inout = vtn_local_load(b, deref, ptr->ptr_type->pointed->access | access);
|
||||
} else {
|
||||
vtn_local_store(b, *inout, deref, ptr->type->access | access);
|
||||
vtn_local_store(b, *inout, deref, ptr->ptr_type->pointed->access | access);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -735,7 +753,7 @@ _vtn_variable_load_store(struct vtn_builder *b, bool load,
|
|||
case GLSL_TYPE_INTERFACE:
|
||||
case GLSL_TYPE_ARRAY:
|
||||
case GLSL_TYPE_STRUCT: {
|
||||
unsigned elems = glsl_get_length(ptr->type->type);
|
||||
unsigned elems = glsl_get_length(ptr->ptr_type->pointed->type);
|
||||
struct vtn_access_chain chain = {
|
||||
.length = 1,
|
||||
.link = {
|
||||
|
|
@ -745,7 +763,7 @@ _vtn_variable_load_store(struct vtn_builder *b, bool load,
|
|||
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, ptr->type->access | access,
|
||||
_vtn_variable_load_store(b, load, elem, ptr->ptr_type->pointed->access | access,
|
||||
&(*inout)->elems[i]);
|
||||
}
|
||||
return;
|
||||
|
|
@ -760,7 +778,7 @@ struct vtn_ssa_value *
|
|||
vtn_variable_load(struct vtn_builder *b, struct vtn_pointer *src,
|
||||
enum gl_access_qualifier access)
|
||||
{
|
||||
struct vtn_ssa_value *val = vtn_create_ssa_value(b, src->type->type);
|
||||
struct vtn_ssa_value *val = vtn_create_ssa_value(b, src->ptr_type->pointed->type);
|
||||
_vtn_variable_load_store(b, true, src, src->access | access, &val);
|
||||
return val;
|
||||
}
|
||||
|
|
@ -777,9 +795,9 @@ _vtn_variable_copy(struct vtn_builder *b, struct vtn_pointer *dest,
|
|||
struct vtn_pointer *src, enum gl_access_qualifier dest_access,
|
||||
enum gl_access_qualifier src_access)
|
||||
{
|
||||
vtn_assert(glsl_get_bare_type(src->type->type) ==
|
||||
glsl_get_bare_type(dest->type->type));
|
||||
enum glsl_base_type base_type = glsl_get_base_type(src->type->type);
|
||||
vtn_assert(glsl_get_bare_type(src->ptr_type->pointed->type) ==
|
||||
glsl_get_bare_type(dest->ptr_type->pointed->type));
|
||||
enum glsl_base_type base_type = glsl_get_base_type(src->ptr_type->pointed->type);
|
||||
switch (base_type) {
|
||||
case GLSL_TYPE_UINT:
|
||||
case GLSL_TYPE_INT:
|
||||
|
|
@ -811,7 +829,7 @@ _vtn_variable_copy(struct vtn_builder *b, struct vtn_pointer *dest,
|
|||
{ .mode = vtn_access_mode_literal, },
|
||||
}
|
||||
};
|
||||
unsigned elems = glsl_get_length(src->type->type);
|
||||
unsigned elems = glsl_get_length(src->ptr_type->pointed->type);
|
||||
for (unsigned i = 0; i < elems; i++) {
|
||||
chain.link[0].id = i;
|
||||
struct vtn_pointer *src_elem =
|
||||
|
|
@ -1915,7 +1933,7 @@ nir_def *
|
|||
vtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr)
|
||||
{
|
||||
if ((vtn_pointer_is_external_block(b, ptr) &&
|
||||
vtn_type_contains_block(b, ptr->type) &&
|
||||
vtn_type_contains_block(b, ptr->ptr_type->pointed) &&
|
||||
ptr->mode != vtn_variable_mode_phys_ssbo) ||
|
||||
ptr->mode == vtn_variable_mode_accel_struct) {
|
||||
/* In this case, we're looking for a block index and not an actual
|
||||
|
|
@ -1961,7 +1979,6 @@ vtn_pointer_from_ssa(struct vtn_builder *b, nir_def *ssa,
|
|||
nir_variable_mode nir_mode;
|
||||
ptr->mode = vtn_storage_class_to_mode(b, ptr_type->storage_class,
|
||||
without_array, &nir_mode);
|
||||
ptr->type = ptr_type->pointed;
|
||||
ptr->ptr_type = ptr_type;
|
||||
|
||||
const struct glsl_type *deref_type =
|
||||
|
|
@ -1970,7 +1987,7 @@ vtn_pointer_from_ssa(struct vtn_builder *b, nir_def *ssa,
|
|||
ptr->mode != vtn_variable_mode_accel_struct) {
|
||||
ptr->deref = nir_build_deref_cast(&b->nb, ssa, nir_mode,
|
||||
deref_type, ptr_type->stride);
|
||||
} else if ((vtn_type_contains_block(b, ptr->type) &&
|
||||
} else if ((vtn_type_contains_block(b, ptr->ptr_type->pointed) &&
|
||||
ptr->mode != vtn_variable_mode_phys_ssbo) ||
|
||||
ptr->mode == vtn_variable_mode_accel_struct) {
|
||||
/* This is a pointer to somewhere in an array of blocks, not a
|
||||
|
|
@ -2148,7 +2165,6 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
|||
|
||||
val->pointer = vtn_zalloc(b, struct vtn_pointer);
|
||||
val->pointer->mode = var->mode;
|
||||
val->pointer->type = var->type;
|
||||
val->pointer->ptr_type = ptr_type;
|
||||
val->pointer->var = var;
|
||||
val->pointer->access = var->type->access;
|
||||
|
|
@ -2452,6 +2468,12 @@ vtn_assert_types_equal(struct vtn_builder *b, SpvOp opcode,
|
|||
struct vtn_type *dst_type,
|
||||
struct vtn_type *src_type)
|
||||
{
|
||||
if (!dst_type->id || !src_type->id) {
|
||||
/* Either of those are internal types, so just check for compatibility. */
|
||||
vtn_assert(vtn_types_compatible(b, dst_type, src_type));
|
||||
return;
|
||||
}
|
||||
|
||||
if (dst_type->id == src_type->id)
|
||||
return;
|
||||
|
||||
|
|
@ -2820,10 +2842,10 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
|
|||
struct vtn_value *src_val = vtn_untyped_value(b, w[2]);
|
||||
|
||||
/* OpStore requires us to actually have a storage type */
|
||||
vtn_fail_if(dest->type->type == NULL,
|
||||
vtn_fail_if(dest->ptr_type->pointed->type == NULL,
|
||||
"Invalid destination type for OpStore");
|
||||
|
||||
if (glsl_get_base_type(dest->type->type) == GLSL_TYPE_BOOL &&
|
||||
if (glsl_get_base_type(dest->ptr_type->pointed->type) == GLSL_TYPE_BOOL &&
|
||||
glsl_get_base_type(src_val->type->type) == GLSL_TYPE_UINT) {
|
||||
/* Early versions of GLSLang would use uint types for UBOs/SSBOs but
|
||||
* would then store them to a local variable as bool. Work around
|
||||
|
|
@ -2836,7 +2858,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
|
|||
"OpTypeBool. Doing an implicit conversion to work around "
|
||||
"the problem.");
|
||||
struct vtn_ssa_value *bool_ssa =
|
||||
vtn_create_ssa_value(b, dest->type->type);
|
||||
vtn_create_ssa_value(b, dest->ptr_type->pointed->type);
|
||||
bool_ssa->def = nir_i2b(&b->nb, vtn_ssa_value(b, w[2])->def);
|
||||
vtn_variable_store(b, bool_ssa, dest, 0);
|
||||
break;
|
||||
|
|
@ -2861,10 +2883,10 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
|
|||
struct vtn_pointer *ptr = vtn_pointer(b, w[3]);
|
||||
const uint32_t field = w[4];
|
||||
|
||||
vtn_fail_if(ptr->type->base_type != vtn_base_type_struct,
|
||||
vtn_fail_if(ptr->ptr_type->pointed->base_type != vtn_base_type_struct,
|
||||
"OpArrayLength must take a pointer to a structure type");
|
||||
vtn_fail_if(field != ptr->type->length - 1 ||
|
||||
ptr->type->members[field]->base_type != vtn_base_type_array,
|
||||
vtn_fail_if(field != ptr->ptr_type->pointed->length - 1 ||
|
||||
ptr->ptr_type->pointed->members[field]->base_type != vtn_base_type_array,
|
||||
"OpArrayLength must reference the last member of the "
|
||||
"structure and that must be an array");
|
||||
|
||||
|
|
@ -2879,7 +2901,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
|
|||
nir_def *array_length =
|
||||
nir_deref_buffer_array_length(&b->nb, 32,
|
||||
vtn_pointer_to_ssa(b, array),
|
||||
.access=ptr->access | ptr->type->access);
|
||||
.access=ptr->access | ptr->ptr_type->pointed->access);
|
||||
|
||||
vtn_push_nir_ssa(b, w[2], array_length);
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue