mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 02:10:11 +01:00
spirv: Let vtn_ssa_value hold references to variables
In certain cases, we have complex opaque objects that are loaded into (SPIR-V) SSA values. To represent these, we now can store a reference to a variable in vtn_ssa_value. Also implements a few operations we know will have to be supported, like Select and Copy. Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23825>
This commit is contained in:
parent
3d7e5ec758
commit
b17a2c35bc
3 changed files with 74 additions and 2 deletions
|
|
@ -395,6 +395,27 @@ vtn_push_nir_ssa(struct vtn_builder *b, uint32_t value_id, nir_def *def)
|
|||
return vtn_push_ssa_value(b, value_id, ssa);
|
||||
}
|
||||
|
||||
nir_deref_instr *
|
||||
vtn_get_deref_for_id(struct vtn_builder *b, uint32_t value_id)
|
||||
{
|
||||
return vtn_get_deref_for_ssa_value(b, vtn_ssa_value(b, value_id));
|
||||
}
|
||||
|
||||
nir_deref_instr *
|
||||
vtn_get_deref_for_ssa_value(struct vtn_builder *b, struct vtn_ssa_value *ssa)
|
||||
{
|
||||
vtn_fail_if(!ssa->is_variable, "Expected an SSA value with a nir_variable");
|
||||
return nir_build_deref_var(&b->nb, ssa->var);
|
||||
}
|
||||
|
||||
struct vtn_value *
|
||||
vtn_push_var_ssa(struct vtn_builder *b, uint32_t value_id, nir_variable *var)
|
||||
{
|
||||
struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, var->type);
|
||||
vtn_set_ssa_value_var(b, ssa, var);
|
||||
return vtn_push_ssa_value(b, value_id, ssa);
|
||||
}
|
||||
|
||||
static enum gl_access_qualifier
|
||||
spirv_to_gl_access_qualifier(struct vtn_builder *b,
|
||||
SpvAccessQualifier access_qualifier)
|
||||
|
|
@ -2680,6 +2701,15 @@ vtn_create_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
|
|||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
vtn_set_ssa_value_var(struct vtn_builder *b, struct vtn_ssa_value *ssa, nir_variable *var)
|
||||
{
|
||||
vtn_assert(glsl_type_is_cmat(var->type));
|
||||
vtn_assert(var->type == ssa->type);
|
||||
ssa->is_variable = true;
|
||||
ssa->var = var;
|
||||
}
|
||||
|
||||
static nir_tex_src
|
||||
vtn_tex_src(struct vtn_builder *b, unsigned index, nir_tex_src_type type)
|
||||
{
|
||||
|
|
@ -4163,6 +4193,8 @@ vtn_vector_construct(struct vtn_builder *b, unsigned num_components,
|
|||
static struct vtn_ssa_value *
|
||||
vtn_composite_copy(void *mem_ctx, struct vtn_ssa_value *src)
|
||||
{
|
||||
assert(!src->is_variable);
|
||||
|
||||
struct vtn_ssa_value *dest = rzalloc(mem_ctx, struct vtn_ssa_value);
|
||||
dest->type = src->type;
|
||||
|
||||
|
|
@ -5668,7 +5700,27 @@ vtn_nir_select(struct vtn_builder *b, struct vtn_ssa_value *src0,
|
|||
struct vtn_ssa_value *dest = rzalloc(b, struct vtn_ssa_value);
|
||||
dest->type = src1->type;
|
||||
|
||||
if (glsl_type_is_vector_or_scalar(src1->type)) {
|
||||
if (src1->is_variable || src2->is_variable) {
|
||||
vtn_assert(src1->is_variable && src2->is_variable);
|
||||
|
||||
nir_variable *dest_var =
|
||||
nir_local_variable_create(b->nb.impl, dest->type, "var_select");
|
||||
nir_deref_instr *dest_deref = nir_build_deref_var(&b->nb, dest_var);
|
||||
|
||||
nir_push_if(&b->nb, src0->def);
|
||||
{
|
||||
nir_deref_instr *src1_deref = vtn_get_deref_for_ssa_value(b, src1);
|
||||
vtn_local_store(b, vtn_local_load(b, src1_deref, 0), dest_deref, 0);
|
||||
}
|
||||
nir_push_else(&b->nb, NULL);
|
||||
{
|
||||
nir_deref_instr *src2_deref = vtn_get_deref_for_ssa_value(b, src2);
|
||||
vtn_local_store(b, vtn_local_load(b, src2_deref, 0), dest_deref, 0);
|
||||
}
|
||||
nir_pop_if(&b->nb, NULL);
|
||||
|
||||
vtn_set_ssa_value_var(b, dest, dest_var);
|
||||
} else if (glsl_type_is_vector_or_scalar(src1->type)) {
|
||||
dest->def = nir_bcsel(&b->nb, src0->def, src1->def, src2->def);
|
||||
} else {
|
||||
unsigned elems = glsl_get_length(src1->type);
|
||||
|
|
|
|||
|
|
@ -251,8 +251,11 @@ vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
|
|||
const uint32_t *end, vtn_instruction_handler handler);
|
||||
|
||||
struct vtn_ssa_value {
|
||||
bool is_variable;
|
||||
|
||||
union {
|
||||
nir_def *def;
|
||||
nir_variable *var;
|
||||
struct vtn_ssa_value **elems;
|
||||
};
|
||||
|
||||
|
|
@ -856,6 +859,10 @@ struct vtn_value *vtn_push_ssa_value(struct vtn_builder *b, uint32_t value_id,
|
|||
nir_def *vtn_get_nir_ssa(struct vtn_builder *b, uint32_t value_id);
|
||||
struct vtn_value *vtn_push_nir_ssa(struct vtn_builder *b, uint32_t value_id,
|
||||
nir_def *def);
|
||||
nir_deref_instr *vtn_get_deref_for_id(struct vtn_builder *b, uint32_t value_id);
|
||||
nir_deref_instr *vtn_get_deref_for_ssa_value(struct vtn_builder *b, struct vtn_ssa_value *ssa);
|
||||
struct vtn_value *vtn_push_var_ssa(struct vtn_builder *b, uint32_t value_id,
|
||||
nir_variable *var);
|
||||
|
||||
struct vtn_value *vtn_push_pointer(struct vtn_builder *b,
|
||||
uint32_t value_id,
|
||||
|
|
@ -875,6 +882,7 @@ vtn_copy_value(struct vtn_builder *b, uint32_t src_value_id,
|
|||
|
||||
struct vtn_ssa_value *vtn_create_ssa_value(struct vtn_builder *b,
|
||||
const struct glsl_type *type);
|
||||
void vtn_set_ssa_value_var(struct vtn_builder *b, struct vtn_ssa_value *ssa, nir_variable *var);
|
||||
|
||||
struct vtn_ssa_value *vtn_ssa_transpose(struct vtn_builder *b,
|
||||
struct vtn_ssa_value *src);
|
||||
|
|
|
|||
|
|
@ -139,7 +139,6 @@ vtn_copy_value(struct vtn_builder *b, uint32_t src_value_id,
|
|||
{
|
||||
struct vtn_value *src = vtn_untyped_value(b, src_value_id);
|
||||
struct vtn_value *dst = vtn_untyped_value(b, dst_value_id);
|
||||
struct vtn_value src_copy = *src;
|
||||
|
||||
vtn_fail_if(dst->value_type != vtn_value_type_invalid,
|
||||
"SPIR-V id %u has already been written by another instruction",
|
||||
|
|
@ -148,6 +147,19 @@ vtn_copy_value(struct vtn_builder *b, uint32_t src_value_id,
|
|||
vtn_fail_if(dst->type->id != src->type->id,
|
||||
"Result Type must equal Operand type");
|
||||
|
||||
if (src->value_type == vtn_value_type_ssa && src->ssa->is_variable) {
|
||||
nir_variable *dst_var =
|
||||
nir_local_variable_create(b->nb.impl, src->ssa->type, "var_copy");
|
||||
nir_deref_instr *dst_deref = nir_build_deref_var(&b->nb, dst_var);
|
||||
nir_deref_instr *src_deref = vtn_get_deref_for_ssa_value(b, src->ssa);
|
||||
|
||||
vtn_local_store(b, vtn_local_load(b, src_deref, 0), dst_deref, 0);
|
||||
|
||||
vtn_push_var_ssa(b, dst_value_id, dst_var);
|
||||
return;
|
||||
}
|
||||
|
||||
struct vtn_value src_copy = *src;
|
||||
src_copy.name = dst->name;
|
||||
src_copy.decoration = dst->decoration;
|
||||
src_copy.type = dst->type;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue