From: Arcady Goldmints-Orlov Date: Tue, 10 Dec 2019 20:53:15 +0000 (-0500) Subject: compiler/spirv: Add support for non-constant initializers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e459c7f0a14b65617e16b92f42abad2fe5878872;p=mesa.git compiler/spirv: Add support for non-constant initializers This adds support for OpVariable having an initializer that points to another variable, rather than a constant. In this case, the variable is initialized to a pointer to the other variable. Fixes Vulkan CTS tests: dEQP-VK.spirv_assembly.instruction.compute.variable_init.private.* Reviewed-by: Caio Marcelo de Oliveira Filho Part-of: --- diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 95e941c481a..1bb48642b3f 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -2155,7 +2155,7 @@ assign_missing_member_locations(struct vtn_variable *var) static void vtn_create_variable(struct vtn_builder *b, struct vtn_value *val, struct vtn_type *ptr_type, SpvStorageClass storage_class, - nir_constant *initializer) + nir_constant *const_initializer, nir_variable *var_initializer) { vtn_assert(ptr_type->base_type == vtn_base_type_pointer); struct vtn_type *type = ptr_type->deref; @@ -2378,10 +2378,14 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val, unreachable("Should have been caught before"); } - if (initializer) { + /* We can only have one type of initializer */ + assert(!(const_initializer && var_initializer)); + if (const_initializer) { var->var->constant_initializer = - nir_constant_clone(initializer, var->var); + nir_constant_clone(const_initializer, var->var); } + if (var_initializer) + var->var->pointer_initializer = var_initializer; vtn_foreach_decoration(b, val, var_decoration_cb, var); vtn_foreach_decoration(b, val, ptr_decoration_cb, val->pointer); @@ -2503,11 +2507,25 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_pointer); SpvStorageClass storage_class = w[3]; - nir_constant *initializer = NULL; - if (count > 4) - initializer = vtn_value(b, w[4], vtn_value_type_constant)->constant; + nir_constant *const_initializer = NULL; + nir_variable *var_initializer = NULL; + if (count > 4) { + struct vtn_value *init = vtn_untyped_value(b, w[4]); + switch (init->value_type) { + case vtn_value_type_constant: + const_initializer = init->constant; + break; + case vtn_value_type_pointer: + var_initializer = init->pointer->var->var; + break; + default: + vtn_fail("SPIR-V variable initializer %u must be constant or pointer", + w[4]); + } + } + + vtn_create_variable(b, val, ptr_type, storage_class, const_initializer, var_initializer); - vtn_create_variable(b, val, ptr_type, storage_class, initializer); break; }