From 7e6959402de45a668ec4efa3cdac042bcfa2b349 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 19 Oct 2015 15:50:45 -0700 Subject: [PATCH] nir/spirv: Handle builtins in OpAccessChain Previously, we were trying to handle them later when loading. However, at that point, you've already lost information and it's harder to handle certain corner-cases. In particular, if you have a shader that does gl_PerVertex.gl_Position.x = foo we have trouble because we see the .x and we don't know that we're in gl_Position. If we, instead, handle it in OpAccessChain, we have all the information we need and we can silently re-direct it to the appropreate variable. This also lets us delete some code which is a nice side-effect. --- src/glsl/nir/spirv_to_nir.c | 61 ++++++++----------------------------- 1 file changed, 12 insertions(+), 49 deletions(-) diff --git a/src/glsl/nir/spirv_to_nir.c b/src/glsl/nir/spirv_to_nir.c index a62ec6661b0..2ba8216c0b4 100644 --- a/src/glsl/nir/spirv_to_nir.c +++ b/src/glsl/nir/spirv_to_nir.c @@ -854,44 +854,6 @@ get_builtin_variable(struct vtn_builder *b, return var; } -static void -vtn_builtin_load(struct vtn_builder *b, - struct vtn_ssa_value *val, - SpvBuiltIn builtin) -{ - assert(glsl_type_is_vector_or_scalar(val->type)); - - nir_variable *var = get_builtin_variable(b, val->type, builtin); - - nir_intrinsic_instr *load = - nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var); - nir_ssa_dest_init(&load->instr, &load->dest, - glsl_get_vector_elements(val->type), NULL); - - load->variables[0] = nir_deref_var_create(load, var); - load->num_components = glsl_get_vector_elements(val->type); - nir_builder_instr_insert(&b->nb, &load->instr); - val->def = &load->dest.ssa; -} - -static void -vtn_builtin_store(struct vtn_builder *b, - struct vtn_ssa_value *val, - SpvBuiltIn builtin) -{ - assert(glsl_type_is_vector_or_scalar(val->type)); - - nir_variable *var = get_builtin_variable(b, val->type, builtin); - - nir_intrinsic_instr *store = - nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var); - - store->variables[0] = nir_deref_var_create(store, var); - store->num_components = glsl_get_vector_elements(val->type); - store->src[0] = nir_src_for_ssa(val->def); - nir_builder_instr_insert(&b->nb, &store->instr); -} - static struct vtn_ssa_value * _vtn_variable_load(struct vtn_builder *b, nir_deref_var *src_deref, struct vtn_type *src_type, @@ -900,11 +862,6 @@ _vtn_variable_load(struct vtn_builder *b, struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value); val->type = src_deref_tail->type; - if (src_type->is_builtin) { - vtn_builtin_load(b, val, src_type->builtin); - return val; - } - /* The deref tail may contain a deref to select a component of a vector (in * other words, it might not be an actual tail) so we have to save it away * here since we overwrite it later. @@ -976,11 +933,6 @@ _vtn_variable_store(struct vtn_builder *b, struct vtn_type *dest_type, nir_deref_var *dest_deref, nir_deref *dest_deref_tail, struct vtn_ssa_value *src) { - if (dest_type->is_builtin) { - vtn_builtin_store(b, src, dest_type->builtin); - return; - } - nir_deref *old_child = dest_deref_tail->child; if (glsl_type_is_vector_or_scalar(src->type)) { @@ -1410,7 +1362,18 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, default: unreachable("Invalid type for deref"); } - tail = tail->child; + + if (deref_type->is_builtin) { + /* If we encounter a builtin, we throw away the ress of the + * access chain, jump to the builtin, and keep building. + */ + nir_variable *builtin = get_builtin_variable(b, deref_type->type, + deref_type->builtin); + val->deref = nir_deref_var_create(b, builtin); + tail = &val->deref->deref; + } else { + tail = tail->child; + } } /* For uniform blocks, we don't resolve the access chain until we -- 2.30.2