compiler/nir: Add support for variable initialization from a pointer
Add a pointer_initializer field to nir_variable analogous to constant_initializer, which can be used to initialize the nir_variable to a pointer to another nir_variable. Just like the constant_initializer, the pointer_initializer gets eliminated in the nir_lower_constant_initializers pass. Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3047>
This commit is contained in:
parent
461c40e0fd
commit
7acc81056f
|
@ -578,6 +578,14 @@ typedef struct nir_variable {
|
|||
*/
|
||||
nir_constant *constant_initializer;
|
||||
|
||||
/**
|
||||
* Global variable assigned in the initializer of the variable
|
||||
* This field should only be used temporarily by creators of NIR shaders
|
||||
* and then lower_constant_initializers can be used to get rid of them.
|
||||
* Most of the rest of NIR ignores this field or asserts that it's NULL.
|
||||
*/
|
||||
struct nir_variable *pointer_initializer;
|
||||
|
||||
/**
|
||||
* For variables that are in an interface block or are an instance of an
|
||||
* interface block, this is the \c GLSL_TYPE_INTERFACE type for that block.
|
||||
|
|
|
@ -61,15 +61,23 @@ lower_const_initializer(struct nir_builder *b, struct exec_list *var_list)
|
|||
b->cursor = nir_before_cf_list(&b->impl->body);
|
||||
|
||||
nir_foreach_variable(var, var_list) {
|
||||
if (!var->constant_initializer)
|
||||
continue;
|
||||
if (var->constant_initializer) {
|
||||
build_constant_load(b, nir_build_deref_var(b, var),
|
||||
var->constant_initializer);
|
||||
|
||||
progress = true;
|
||||
progress = true;
|
||||
var->constant_initializer = NULL;
|
||||
} else if (var->pointer_initializer) {
|
||||
nir_deref_instr *src_deref = nir_build_deref_var(b, var->pointer_initializer);
|
||||
nir_deref_instr *dst_deref = nir_build_deref_var(b, var);
|
||||
|
||||
build_constant_load(b, nir_build_deref_var(b, var),
|
||||
var->constant_initializer);
|
||||
/* Note that this stores a pointer to src into dst */
|
||||
nir_store_deref(b, dst_deref, &src_deref->dest.ssa, ~0);
|
||||
|
||||
progress = true;
|
||||
var->pointer_initializer = NULL;
|
||||
}
|
||||
|
||||
var->constant_initializer = NULL;
|
||||
}
|
||||
|
||||
return progress;
|
||||
|
|
|
@ -297,7 +297,7 @@ create_shadow_temp(struct lower_io_state *state, nir_variable *var)
|
|||
/* Reparent the name to the new variable */
|
||||
ralloc_steal(nvar, nvar->name);
|
||||
|
||||
assert(nvar->constant_initializer == NULL);
|
||||
assert(nvar->constant_initializer == NULL && nvar->pointer_initializer == NULL);
|
||||
|
||||
/* Give the original a new name with @<mode>-temp appended */
|
||||
const char *mode = (temp->data.mode == nir_var_shader_in) ? "in" : "out";
|
||||
|
|
|
@ -101,7 +101,8 @@ get_reg_for_deref(nir_deref_instr *deref, struct locals_to_regs_state *state)
|
|||
{
|
||||
uint32_t hash = hash_deref(deref);
|
||||
|
||||
assert(nir_deref_instr_get_variable(deref)->constant_initializer == NULL);
|
||||
assert(nir_deref_instr_get_variable(deref)->constant_initializer == NULL &&
|
||||
nir_deref_instr_get_variable(deref)->pointer_initializer == NULL);
|
||||
|
||||
struct hash_entry *entry =
|
||||
_mesa_hash_table_search_pre_hashed(state->regs_table, hash, deref);
|
||||
|
|
|
@ -779,7 +779,8 @@ nir_lower_vars_to_ssa_impl(nir_function_impl *impl)
|
|||
memset(store_blocks, 0,
|
||||
BITSET_WORDS(state.impl->num_blocks) * sizeof(*store_blocks));
|
||||
|
||||
assert(node->path.path[0]->var->constant_initializer == NULL);
|
||||
assert(node->path.path[0]->var->constant_initializer == NULL &&
|
||||
node->path.path[0]->var->pointer_initializer == NULL);
|
||||
|
||||
if (node->stores) {
|
||||
set_foreach(node->stores, store_entry) {
|
||||
|
|
|
@ -558,6 +558,8 @@ print_var_decl(nir_variable *var, print_state *state)
|
|||
print_constant(var->constant_initializer, var->type, state);
|
||||
fprintf(fp, " }");
|
||||
}
|
||||
if (var->pointer_initializer)
|
||||
fprintf(fp, " = &%s", get_var_name(var->pointer_initializer, state));
|
||||
|
||||
fprintf(fp, "\n");
|
||||
print_annotation(state, var);
|
||||
|
|
|
@ -206,12 +206,13 @@ union packed_var {
|
|||
struct {
|
||||
unsigned has_name:1;
|
||||
unsigned has_constant_initializer:1;
|
||||
unsigned has_pointer_initializer:1;
|
||||
unsigned has_interface_type:1;
|
||||
unsigned num_state_slots:7;
|
||||
unsigned data_encoding:2;
|
||||
unsigned type_same_as_last:1;
|
||||
unsigned interface_type_same_as_last:1;
|
||||
unsigned _pad:2;
|
||||
unsigned _pad:1;
|
||||
unsigned num_members:16;
|
||||
} u;
|
||||
};
|
||||
|
@ -238,6 +239,7 @@ write_variable(write_ctx *ctx, const nir_variable *var)
|
|||
|
||||
flags.u.has_name = !ctx->strip && var->name;
|
||||
flags.u.has_constant_initializer = !!(var->constant_initializer);
|
||||
flags.u.has_pointer_initializer = !!(var->pointer_initializer);
|
||||
flags.u.has_interface_type = !!(var->interface_type);
|
||||
flags.u.type_same_as_last = var->type == ctx->last_type;
|
||||
flags.u.interface_type_same_as_last =
|
||||
|
@ -322,6 +324,8 @@ write_variable(write_ctx *ctx, const nir_variable *var)
|
|||
}
|
||||
if (var->constant_initializer)
|
||||
write_constant(ctx, var->constant_initializer);
|
||||
if (var->pointer_initializer)
|
||||
write_lookup_object(ctx, var->pointer_initializer);
|
||||
if (var->num_members > 0) {
|
||||
blob_write_bytes(ctx->blob, (uint8_t *) var->members,
|
||||
var->num_members * sizeof(*var->members));
|
||||
|
@ -392,6 +396,12 @@ read_variable(read_ctx *ctx)
|
|||
var->constant_initializer = read_constant(ctx, var);
|
||||
else
|
||||
var->constant_initializer = NULL;
|
||||
|
||||
if (flags.u.has_pointer_initializer)
|
||||
var->pointer_initializer = read_object(ctx);
|
||||
else
|
||||
var->pointer_initializer = NULL;
|
||||
|
||||
var->num_members = flags.u.num_members;
|
||||
if (var->num_members > 0) {
|
||||
var->members = ralloc_array(var, struct nir_variable_data,
|
||||
|
|
|
@ -66,7 +66,7 @@ split_variable(struct nir_variable *var, nir_shader *shader,
|
|||
assert(var->state_slots == NULL);
|
||||
|
||||
/* Constant initializers are currently not handled */
|
||||
assert(var->constant_initializer == NULL);
|
||||
assert(var->constant_initializer == NULL && var->pointer_initializer == NULL);
|
||||
|
||||
nir_variable **members =
|
||||
ralloc_array(dead_ctx, nir_variable *, var->num_members);
|
||||
|
|
Loading…
Reference in New Issue