<div dir="ltr">Reviewed-by: Connor Abbott <<a href="mailto:cwabbott0@gmail.com">cwabbott0@gmail.com</a>></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 16, 2014 at 1:11 AM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">---<br>
 src/glsl/Makefile.sources                 |    1 -<br>
 src/glsl/nir/nir_lower_variables_scalar.c | 1249 -----------------------------<br>
 2 files changed, 1250 deletions(-)<br>
 delete mode 100644 src/glsl/nir/nir_lower_variables_scalar.c<br>
<br>
diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources<br>
index 3f5c0bd..3cee2e0 100644<br>
--- a/src/glsl/Makefile.sources<br>
+++ b/src/glsl/Makefile.sources<br>
@@ -28,7 +28,6 @@ NIR_FILES = \<br>
        $(GLSL_SRCDIR)/nir/nir_lower_samplers.cpp \<br>
        $(GLSL_SRCDIR)/nir/nir_lower_system_values.c \<br>
        $(GLSL_SRCDIR)/nir/nir_lower_variables.c \<br>
-       $(GLSL_SRCDIR)/nir/nir_lower_variables_scalar.c \<br>
        $(GLSL_SRCDIR)/nir/nir_lower_vec_to_movs.c \<br>
        $(GLSL_SRCDIR)/nir/nir_metadata.c \<br>
        $(GLSL_SRCDIR)/nir/nir_opcodes.c \<br>
diff --git a/src/glsl/nir/nir_lower_variables_scalar.c b/src/glsl/nir/nir_lower_variables_scalar.c<br>
deleted file mode 100644<br>
index 1cb79c0..0000000<br>
--- a/src/glsl/nir/nir_lower_variables_scalar.c<br>
+++ /dev/null<br>
@@ -1,1249 +0,0 @@<br>
-/*<br>
- * Copyright © 2014 Intel Corporation<br>
- *<br>
- * Permission is hereby granted, free of charge, to any person obtaining a<br>
- * copy of this software and associated documentation files (the "Software"),<br>
- * to deal in the Software without restriction, including without limitation<br>
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
- * and/or sell copies of the Software, and to permit persons to whom the<br>
- * Software is furnished to do so, subject to the following conditions:<br>
- *<br>
- * The above copyright notice and this permission notice (including the next<br>
- * paragraph) shall be included in all copies or substantial portions of the<br>
- * Software.<br>
- *<br>
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS<br>
- * IN THE SOFTWARE.<br>
- *<br>
- * Authors:<br>
- *    Connor Abbott (<a href="mailto:cwabbott0@gmail.com">cwabbott0@gmail.com</a>)<br>
- *<br>
- */<br>
-<br>
-/*<br>
- * This lowering pass converts references to variables with loads/stores to<br>
- * registers or inputs/outputs. We assume that structure splitting has already<br>
- * been run, or else structures with indirect references can't be split. We<br>
- * also assume that this pass will be consumed by a scalar backend, so we pack<br>
- * things more tightly.<br>
- */<br>
-<br>
-#include "nir.h"<br>
-<br>
-static unsigned<br>
-type_size(const struct glsl_type *type)<br>
-{<br>
-   unsigned int size, i;<br>
-<br>
-   switch (glsl_get_base_type(type)) {<br>
-   case GLSL_TYPE_UINT:<br>
-   case GLSL_TYPE_INT:<br>
-   case GLSL_TYPE_FLOAT:<br>
-   case GLSL_TYPE_BOOL:<br>
-      return glsl_get_components(type);<br>
-   case GLSL_TYPE_ARRAY:<br>
-      return type_size(glsl_get_array_element(type)) * glsl_get_length(type);<br>
-   case GLSL_TYPE_STRUCT:<br>
-      size = 0;<br>
-      for (i = 0; i < glsl_get_length(type); i++) {<br>
-         size += type_size(glsl_get_struct_field(type, i));<br>
-      }<br>
-      return size;<br>
-   case GLSL_TYPE_SAMPLER:<br>
-      return 0;<br>
-   case GLSL_TYPE_ATOMIC_UINT:<br>
-      return 0;<br>
-   case GLSL_TYPE_INTERFACE:<br>
-      return 0;<br>
-   case GLSL_TYPE_IMAGE:<br>
-      return 0;<br>
-   case GLSL_TYPE_VOID:<br>
-   case GLSL_TYPE_ERROR:<br>
-      unreachable("not reached");<br>
-   }<br>
-<br>
-   return 0;<br>
-}<br>
-<br>
-/*<br>
- * for inputs, outputs, and uniforms, assigns starting locations for variables<br>
- */<br>
-<br>
-static void<br>
-assign_var_locations(struct hash_table *ht, unsigned *size)<br>
-{<br>
-   unsigned location = 0;<br>
-<br>
-   struct hash_entry *entry;<br>
-   hash_table_foreach(ht, entry) {<br>
-      nir_variable *var = (nir_variable *) entry->data;<br>
-<br>
-      /*<br>
-       * UBO's have their own address spaces, so don't count them towards the<br>
-       * number of global uniforms<br>
-       */<br>
-      if (var->data.mode == nir_var_uniform && var->interface_type != NULL)<br>
-         continue;<br>
-<br>
-      var->data.driver_location = location;<br>
-      location += type_size(var->type);<br>
-   }<br>
-<br>
-   *size = location;<br>
-}<br>
-<br>
-static void<br>
-assign_var_locations_shader(nir_shader *shader)<br>
-{<br>
-   assign_var_locations(shader->inputs, &shader->num_inputs);<br>
-   assign_var_locations(shader->outputs, &shader->num_outputs);<br>
-   assign_var_locations(shader->uniforms, &shader->num_uniforms);<br>
-}<br>
-<br>
-static void<br>
-init_reg(nir_variable *var, nir_register *reg, struct hash_table *ht,<br>
-         bool add_names)<br>
-{<br>
-   if (!glsl_type_is_scalar(var->type) &&<br>
-       !glsl_type_is_vector(var->type)) {<br>
-      reg->is_packed = true;<br>
-      reg->num_components = 1;<br>
-      reg->num_array_elems = type_size(var->type);<br>
-   } else {<br>
-      reg->num_components = glsl_get_components(var->type);<br>
-   }<br>
-   if (add_names)<br>
-      reg->name = ralloc_strdup(reg, var->name);<br>
-   _mesa_hash_table_insert(ht, _mesa_hash_pointer(var), var, reg);<br>
-}<br>
-<br>
-static struct hash_table *<br>
-init_var_ht(nir_shader *shader, bool lower_globals, bool lower_io,<br>
-            bool add_names)<br>
-{<br>
-   struct hash_table *ht = _mesa_hash_table_create(NULL,<br>
-                                                   _mesa_key_pointer_equal);<br>
-<br>
-   if (lower_globals) {<br>
-      foreach_list_typed(nir_variable, var, node, &shader->globals) {<br>
-         nir_register *reg = nir_global_reg_create(shader);<br>
-         init_reg(var, reg, ht, add_names);<br>
-      }<br>
-   }<br>
-<br>
-   if (lower_io) {<br>
-      struct hash_entry *entry;<br>
-      hash_table_foreach(shader->outputs, entry) {<br>
-         nir_variable *var = (nir_variable *) entry->data;<br>
-         nir_register *reg = nir_global_reg_create(shader);<br>
-         init_reg(var, reg, ht, add_names);<br>
-      }<br>
-   }<br>
-<br>
-   nir_foreach_overload(shader, overload) {<br>
-      if (overload->impl) {<br>
-         nir_function_impl *impl = overload->impl;<br>
-<br>
-         foreach_list_typed(nir_variable, var, node, &impl->locals) {<br>
-            nir_register *reg = nir_local_reg_create(impl);<br>
-            init_reg(var, reg, ht, add_names);<br>
-         }<br>
-      }<br>
-   }<br>
-<br>
-   return ht;<br>
-}<br>
-<br>
-static bool<br>
-deref_has_indirect(nir_deref_var *deref_var)<br>
-{<br>
-   nir_deref *deref = &deref_var->deref;<br>
-<br>
-   while (deref->child != NULL) {<br>
-      deref = deref->child;<br>
-      if (deref->deref_type == nir_deref_type_array) {<br>
-         nir_deref_array *deref_array = nir_deref_as_array(deref);<br>
-         if (deref_array->deref_array_type == nir_deref_array_type_indirect)<br>
-            return true;<br>
-      }<br>
-   }<br>
-<br>
-   return false;<br>
-}<br>
-<br>
-static unsigned<br>
-get_deref_offset(nir_deref_var *deref_var, nir_instr *instr,<br>
-                 nir_function_impl *impl, bool native_integers,<br>
-                 nir_src *indirect)<br>
-{<br>
-   void *mem_ctx = ralloc_parent(instr);<br>
-<br>
-   bool first_indirect = true;<br>
-<br>
-   unsigned base_offset = 0;<br>
-   nir_deref *deref = &deref_var->deref;<br>
-   while (deref->child != NULL) {<br>
-      const struct glsl_type *parent_type = deref->type;<br>
-      deref = deref->child;<br>
-<br>
-      if (deref->deref_type == nir_deref_type_array) {<br>
-         nir_deref_array *deref_array = nir_deref_as_array(deref);<br>
-         unsigned size = type_size(deref->type);<br>
-<br>
-         base_offset += size * deref_array->base_offset;<br>
-<br>
-         if (deref_array->deref_array_type == nir_deref_array_type_indirect) {<br>
-            nir_src src;<br>
-            if (size == 1) {<br>
-               src = deref_array->indirect;<br>
-            } else {<br>
-               /* temp1 = size * deref_array->indirect */<br>
-<br>
-               nir_register *const_reg = nir_local_reg_create(impl);<br>
-               const_reg->num_components = 1;<br>
-<br>
-               nir_load_const_instr *load_const =<br>
-                  nir_load_const_instr_create(mem_ctx);<br>
-               load_const->dest.reg.reg = const_reg;<br>
-               load_const->num_components = 1;<br>
-               load_const->value.u[0] = size;<br>
-               nir_instr_insert_before(instr, &load_const->instr);<br>
-<br>
-               nir_register *reg = nir_local_reg_create(impl);<br>
-               reg->num_components = 1;<br>
-<br>
-               nir_op op;<br>
-               if (native_integers)<br>
-                  op = nir_op_imul;<br>
-               else<br>
-                  op = nir_op_fmul;<br>
-               nir_alu_instr *mul_instr = nir_alu_instr_create(mem_ctx, op);<br>
-               mul_instr->dest.write_mask = 1;<br>
-               mul_instr->dest.dest.reg.reg = reg;<br>
-               mul_instr->src[0].src = deref_array->indirect;<br>
-               mul_instr->src[1].src.reg.reg = const_reg;<br>
-               nir_instr_insert_before(instr, &mul_instr->instr);<br>
-<br>
-               src.is_ssa = false;<br>
-               src.reg.reg = reg;<br>
-               src.reg.base_offset = 0;<br>
-               src.reg.indirect = NULL;<br>
-            }<br>
-<br>
-            if (!first_indirect) {<br>
-               /* temp2 = indirect + temp1 */<br>
-<br>
-               nir_register *reg = nir_local_reg_create(impl);<br>
-               reg->num_components = 1;<br>
-<br>
-               nir_op op;<br>
-               if (native_integers)<br>
-                  op = nir_op_iadd;<br>
-               else<br>
-                  op = nir_op_fadd;<br>
-               nir_alu_instr *add_instr = nir_alu_instr_create(mem_ctx, op);<br>
-               add_instr->dest.write_mask = 1;<br>
-               add_instr->dest.dest.reg.reg = reg;<br>
-               add_instr->src[0].src = *indirect;<br>
-               add_instr->src[1].src = src;<br>
-               nir_instr_insert_before(instr, &add_instr->instr);<br>
-<br>
-               src.is_ssa = false;<br>
-               src.reg.reg = reg;<br>
-               src.reg.base_offset = 0;<br>
-               src.reg.indirect = NULL;<br>
-            }<br>
-<br>
-            /* indirect = tempX */<br>
-            *indirect = src;<br>
-            first_indirect = false;<br>
-         }<br>
-      } else {<br>
-         nir_deref_struct *deref_struct = nir_deref_as_struct(deref);<br>
-<br>
-         for (unsigned i = 0; i < deref_struct->index; i++)<br>
-            base_offset += type_size(glsl_get_struct_field(parent_type, i));<br>
-      }<br>
-   }<br>
-<br>
-   return base_offset;<br>
-}<br>
-<br>
-/*<br>
- * We cannot convert variables used in calls, so remove them from the hash<br>
- * table.<br>
- */<br>
-<br>
-static bool<br>
-remove_call_vars_cb(nir_block *block, void *state)<br>
-{<br>
-   struct hash_table *ht = (struct hash_table *) state;<br>
-<br>
-   nir_foreach_instr(block, instr) {<br>
-      if (instr->type == nir_instr_type_call) {<br>
-         nir_call_instr *call = nir_instr_as_call(instr);<br>
-         if (call->return_deref) {<br>
-            struct hash_entry *entry =<br>
-               _mesa_hash_table_search(ht,<br>
-                                       _mesa_hash_pointer(call->return_deref->var),<br>
-                                       call->return_deref->var);<br>
-            if (entry)<br>
-               _mesa_hash_table_remove(ht, entry);<br>
-         }<br>
-<br>
-         for (unsigned i = 0; i < call->num_params; i++) {<br>
-            struct hash_entry *entry =<br>
-               _mesa_hash_table_search(ht,<br>
-                                       _mesa_hash_pointer(call->params[i]->var),<br>
-                                       call->params[i]->var);<br>
-            if (entry)<br>
-               _mesa_hash_table_remove(ht, entry);<br>
-         }<br>
-      }<br>
-   }<br>
-<br>
-   return true;<br>
-}<br>
-<br>
-static void<br>
-remove_local_vars(nir_function_impl *impl, struct hash_table *ht)<br>
-{<br>
-   if (impl->return_var) {<br>
-      struct hash_entry *entry =<br>
-         _mesa_hash_table_search(ht, _mesa_hash_pointer(impl->return_var),<br>
-                                 impl->return_var);<br>
-<br>
-      if (entry)<br>
-         _mesa_hash_table_remove(ht, entry);<br>
-   }<br>
-<br>
-   for (unsigned i = 0; i < impl->num_params; i++) {<br>
-      struct hash_entry *entry =<br>
-         _mesa_hash_table_search(ht,<br>
-                                 _mesa_hash_pointer(impl->params[i]),<br>
-                                 impl->params[i]);<br>
-      if (entry)<br>
-         _mesa_hash_table_remove(ht, entry);<br>
-   }<br>
-<br>
-   nir_foreach_block(impl, remove_call_vars_cb, ht);<br>
-}<br>
-<br>
-static void<br>
-remove_local_vars_shader(nir_shader *shader, struct hash_table *ht)<br>
-{<br>
-   nir_foreach_overload(shader, overload) {<br>
-      if (overload->impl)<br>
-         remove_local_vars(overload->impl, ht);<br>
-   }<br>
-}<br>
-<br>
-static nir_deref *<br>
-get_deref_tail(nir_deref *deref)<br>
-{<br>
-   while (deref->child != NULL)<br>
-      deref = deref->child;<br>
-   return deref;<br>
-}<br>
-<br>
-/* helper for reg_const_load which emits a single instruction */<br>
-static void<br>
-reg_const_load_single_instr(nir_reg_dest reg, nir_constant *constant,<br>
-                            enum glsl_base_type base_type,<br>
-                            unsigned num_components, unsigned offset,<br>
-                            nir_function_impl *impl, void *mem_ctx)<br>
-{<br>
-   nir_load_const_instr *instr = nir_load_const_instr_create(mem_ctx);<br>
-   instr->num_components = num_components;<br>
-   for (unsigned i = 0; i < num_components; i++) {<br>
-      switch (base_type) {<br>
-      case GLSL_TYPE_FLOAT:<br>
-      case GLSL_TYPE_INT:<br>
-      case GLSL_TYPE_UINT:<br>
-         instr->value.u[i] = constant->value.u[i + offset];<br>
-         break;<br>
-      case GLSL_TYPE_BOOL:<br>
-         instr->value.u[i] = constant->value.u[i + offset] ?<br>
-                             NIR_TRUE : NIR_FALSE;<br>
-         break;<br>
-      default:<br>
-         unreachable("Invalid immediate type");<br>
-      }<br>
-   }<br>
-   instr->dest.reg = reg;<br>
-   instr->dest.reg.base_offset += offset;<br>
-<br>
-   nir_instr_insert_before_cf_list(&impl->body, &instr->instr);<br>
-}<br>
-<br>
-/* loads a constant value into a register */<br>
-static void<br>
-reg_const_load(nir_reg_dest reg, nir_constant *constant,<br>
-               const struct glsl_type *type, nir_function_impl *impl,<br>
-               void *mem_ctx)<br>
-{<br>
-   unsigned offset = 0;<br>
-   const struct glsl_type *subtype;<br>
-   unsigned subtype_size;<br>
-<br>
-   enum glsl_base_type base_type = glsl_get_base_type(type);<br>
-   switch (base_type) {<br>
-      case GLSL_TYPE_FLOAT:<br>
-      case GLSL_TYPE_INT:<br>
-      case GLSL_TYPE_UINT:<br>
-      case GLSL_TYPE_BOOL:<br>
-         if (glsl_type_is_matrix(type)) {<br>
-            for (unsigned i = 0; i < glsl_get_matrix_columns(type); i++) {<br>
-               reg_const_load_single_instr(reg, constant, base_type,<br>
-                                           glsl_get_vector_elements(type),<br>
-                                           i * glsl_get_vector_elements(type),<br>
-                                           impl, mem_ctx);<br>
-            }<br>
-         } else {<br>
-            reg_const_load_single_instr(reg, constant, base_type,<br>
-                                        glsl_get_vector_elements(type), 0,<br>
-                                        impl, mem_ctx);<br>
-         }<br>
-         break;<br>
-<br>
-      case GLSL_TYPE_STRUCT:<br>
-         for (unsigned i = 0; i < glsl_get_length(type); i++) {<br>
-            const struct glsl_type *field = glsl_get_struct_field(type, i);<br>
-            nir_reg_dest new_reg = reg;<br>
-            new_reg.base_offset += offset;<br>
-            reg_const_load(new_reg, constant->elements[i], field, impl,<br>
-                           mem_ctx);<br>
-            offset += type_size(field);<br>
-         }<br>
-         break;<br>
-<br>
-      case GLSL_TYPE_ARRAY:<br>
-         subtype = glsl_get_array_element(type);<br>
-         subtype_size = type_size(subtype);<br>
-         for (unsigned i = 0; i < glsl_get_length(type); i++) {<br>
-            nir_reg_dest new_reg = reg;<br>
-            new_reg.base_offset += subtype_size * i;<br>
-            reg_const_load(new_reg, constant->elements[i], subtype, impl,<br>
-                           mem_ctx);<br>
-         }<br>
-         break;<br>
-<br>
-      default:<br>
-         assert(0);<br>
-         break;<br>
-   }<br>
-}<br>
-<br>
-/* recursively emits a register <-> dereference block copy */<br>
-static void<br>
-var_reg_block_copy_impl(nir_reg_src reg, nir_deref_var *deref_head,<br>
-                        nir_src *predicate, const struct glsl_type *type,<br>
-                        nir_instr *after, bool var_dest, void *mem_ctx)<br>
-{<br>
-   unsigned offset;<br>
-<br>
-   switch (glsl_get_base_type(type)) {<br>
-      case GLSL_TYPE_FLOAT:<br>
-      case GLSL_TYPE_INT:<br>
-      case GLSL_TYPE_UINT:<br>
-      case GLSL_TYPE_BOOL:<br>
-         if (glsl_type_is_matrix(type)) {<br>
-            for (unsigned i = 0; i < glsl_get_matrix_columns(type); i++) {<br>
-               nir_deref_array *deref_array = nir_deref_array_create(mem_ctx);<br>
-               deref_array->base_offset = i;<br>
-               deref_array->deref.type = glsl_get_column_type(type);<br>
-<br>
-               nir_deref_var *new_deref_head =<br>
-                  nir_deref_as_var(nir_copy_deref(mem_ctx, &deref_head->deref));<br>
-               get_deref_tail(&new_deref_head->deref)->child =<br>
-                  &deref_array->deref;<br>
-<br>
-               nir_reg_src new_reg = reg;<br>
-               new_reg.base_offset += i * glsl_get_vector_elements(type);<br>
-<br>
-               var_reg_block_copy_impl(new_reg, new_deref_head, predicate,<br>
-                                       glsl_get_column_type(type), after,<br>
-                                       var_dest, mem_ctx);<br>
-            }<br>
-         } else {<br>
-            if (var_dest) {<br>
-               nir_intrinsic_op op;<br>
-               switch (glsl_get_vector_elements(type)) {<br>
-                  case 1: op = nir_intrinsic_store_var_vec1; break;<br>
-                  case 2: op = nir_intrinsic_store_var_vec2; break;<br>
-                  case 3: op = nir_intrinsic_store_var_vec3; break;<br>
-                  case 4: op = nir_intrinsic_store_var_vec4; break;<br>
-                  default: assert(0); break;<br>
-               }<br>
-<br>
-               nir_intrinsic_instr *store =<br>
-                  nir_intrinsic_instr_create(mem_ctx, op);<br>
-               store->variables[0] = deref_head;<br>
-               store->src[0].reg.reg = reg.reg;<br>
-               store->src[0].reg.base_offset = reg.base_offset;<br>
-               if (reg.indirect) {<br>
-                  store->src[0].reg.indirect = ralloc(mem_ctx, nir_src);<br>
-                  *store->src[0].reg.indirect = *reg.indirect;<br>
-               }<br>
-<br>
-               if (predicate) {<br>
-                  store->has_predicate = true;<br>
-                  store->predicate = nir_src_copy(*predicate, mem_ctx);<br>
-               }<br>
-<br>
-               nir_instr_insert_before(after, &store->instr);<br>
-            } else {<br>
-               nir_intrinsic_op op;<br>
-               switch (glsl_get_vector_elements(type)) {<br>
-                  case 1: op = nir_intrinsic_load_var_vec1; break;<br>
-                  case 2: op = nir_intrinsic_load_var_vec2; break;<br>
-                  case 3: op = nir_intrinsic_load_var_vec3; break;<br>
-                  case 4: op = nir_intrinsic_load_var_vec4; break;<br>
-                  default: assert(0); break;<br>
-               }<br>
-<br>
-               nir_intrinsic_instr *load =<br>
-                  nir_intrinsic_instr_create(mem_ctx, op);<br>
-               load->variables[0] = deref_head;<br>
-               load->dest.reg.reg = reg.reg;<br>
-               load->dest.reg.base_offset = reg.base_offset;<br>
-               if (reg.indirect) {<br>
-                  load->dest.reg.indirect = ralloc(mem_ctx, nir_src);<br>
-                  *load->dest.reg.indirect = *reg.indirect;<br>
-               }<br>
-<br>
-               if (predicate) {<br>
-                  load->has_predicate = true;<br>
-                  load->predicate = nir_src_copy(*predicate, mem_ctx);<br>
-               }<br>
-<br>
-               nir_instr_insert_before(after, &load->instr);<br>
-            }<br>
-         }<br>
-         break;<br>
-<br>
-      case GLSL_TYPE_STRUCT:<br>
-         offset = 0;<br>
-         for (unsigned i = 0; i < glsl_get_length(type); i++) {<br>
-            const struct glsl_type *field_type = glsl_get_struct_field(type, i);<br>
-<br>
-            nir_deref_struct *deref_struct = nir_deref_struct_create(mem_ctx, i);<br>
-            deref_struct->deref.type = field_type;<br>
-<br>
-            nir_deref_var *new_deref_head =<br>
-               nir_deref_as_var(nir_copy_deref(mem_ctx, &deref_head->deref));<br>
-            get_deref_tail(&new_deref_head->deref)->child =<br>
-               &deref_struct->deref;<br>
-<br>
-            nir_reg_src new_reg = reg;<br>
-            new_reg.base_offset += offset;<br>
-<br>
-            var_reg_block_copy_impl(new_reg, new_deref_head, predicate,<br>
-                                    field_type, after, var_dest, mem_ctx);<br>
-<br>
-            offset += type_size(field_type);<br>
-         }<br>
-         break;<br>
-<br>
-      case GLSL_TYPE_ARRAY:<br>
-         for (unsigned i = 0; i < glsl_get_length(type);<br>
-                  i++) {<br>
-            const struct glsl_type *elem_type = glsl_get_array_element(type);<br>
-<br>
-            nir_deref_array *deref_array = nir_deref_array_create(mem_ctx);<br>
-            deref_array->base_offset = i;<br>
-            deref_array->deref.type = elem_type;<br>
-<br>
-            nir_deref_var *new_deref_head =<br>
-               nir_deref_as_var(nir_copy_deref(mem_ctx, &deref_head->deref));<br>
-            get_deref_tail(&new_deref_head->deref)->child =<br>
-               &deref_array->deref;<br>
-<br>
-            nir_reg_src new_reg = reg;<br>
-            new_reg.base_offset += i * type_size(elem_type);<br>
-<br>
-            var_reg_block_copy_impl(new_reg, new_deref_head, predicate,<br>
-                                    elem_type, after, var_dest, mem_ctx);<br>
-         }<br>
-         break;<br>
-<br>
-      default:<br>
-         break;<br>
-   }<br>
-}<br>
-<br>
-static nir_intrinsic_op<br>
-get_load_op(nir_variable_mode mode, bool indirect, unsigned num_components)<br>
-{<br>
-   if (indirect) {<br>
-      switch (mode) {<br>
-         case nir_var_shader_in:<br>
-            switch (num_components) {<br>
-               case 1: return nir_intrinsic_load_input_vec1_indirect;<br>
-               case 2: return nir_intrinsic_load_input_vec2_indirect;<br>
-               case 3: return nir_intrinsic_load_input_vec3_indirect;<br>
-               case 4: return nir_intrinsic_load_input_vec4_indirect;<br>
-               default: assert(0); break;<br>
-            }<br>
-            break;<br>
-<br>
-         case nir_var_uniform:<br>
-            switch (num_components) {<br>
-               case 1: return nir_intrinsic_load_uniform_vec1_indirect;<br>
-               case 2: return nir_intrinsic_load_uniform_vec2_indirect;<br>
-               case 3: return nir_intrinsic_load_uniform_vec3_indirect;<br>
-               case 4: return nir_intrinsic_load_uniform_vec4_indirect;<br>
-               default: assert(0); break;<br>
-            }<br>
-            break;<br>
-<br>
-         default:<br>
-            assert(0);<br>
-            break;<br>
-      }<br>
-   } else {<br>
-      switch (mode) {<br>
-         case nir_var_shader_in:<br>
-            switch (num_components) {<br>
-               case 1: return nir_intrinsic_load_input_vec1;<br>
-               case 2: return nir_intrinsic_load_input_vec2;<br>
-               case 3: return nir_intrinsic_load_input_vec3;<br>
-               case 4: return nir_intrinsic_load_input_vec4;<br>
-               default: assert(0); break;<br>
-            }<br>
-            break;<br>
-<br>
-         case nir_var_uniform:<br>
-            switch (num_components) {<br>
-               case 1: return nir_intrinsic_load_uniform_vec1;<br>
-               case 2: return nir_intrinsic_load_uniform_vec2;<br>
-               case 3: return nir_intrinsic_load_uniform_vec3;<br>
-               case 4: return nir_intrinsic_load_uniform_vec4;<br>
-               default: assert(0); break;<br>
-            }<br>
-            break;<br>
-<br>
-         default:<br>
-            assert(0);<br>
-            break;<br>
-      }<br>
-   }<br>
-<br>
-   return nir_intrinsic_load_input_vec1;<br>
-}<br>
-<br>
-/* emits an input -> reg block copy */<br>
-<br>
-static void<br>
-reg_input_block_copy(nir_reg_dest dest, unsigned src_index, nir_src *indirect,<br>
-                     nir_src *predicate, unsigned size,<br>
-                     unsigned num_components, nir_variable_mode mode,<br>
-                     nir_instr *after, void *mem_ctx)<br>
-{<br>
-   nir_intrinsic_op op = get_load_op(mode, indirect != NULL, num_components);<br>
-<br>
-   nir_intrinsic_instr *load = nir_intrinsic_instr_create(mem_ctx, op);<br>
-   load->const_index[0] = src_index;<br>
-   load->const_index[1] = size;<br>
-   if (indirect)<br>
-      load->src[0] = *indirect;<br>
-   if (predicate) {<br>
-      load->has_predicate = true;<br>
-      load->predicate = nir_src_copy(*predicate, mem_ctx);<br>
-   }<br>
-   load->dest.reg = dest;<br>
-   nir_instr_insert_before(after, &load->instr);<br>
-}<br>
-<br>
-/* emits a variable/input -> register block copy */<br>
-<br>
-static void<br>
-var_reg_block_copy(nir_deref_var *src, nir_reg_dest dest, nir_src *predicate,<br>
-                   bool lower_io, nir_instr *after, nir_function_impl *impl,<br>
-                   bool native_integers, void *mem_ctx)<br>
-{<br>
-   const struct glsl_type *src_type = get_deref_tail(&src->deref)->type;<br>
-<br>
-   if (lower_io && (src->var->data.mode == nir_var_shader_in ||<br>
-       src->var->data.mode == nir_var_uniform)) {<br>
-      unsigned size, num_components;<br>
-      if (glsl_type_is_scalar(src_type) || glsl_type_is_vector(src_type)) {<br>
-         num_components = glsl_get_vector_elements(src_type);<br>
-         size = 1;<br>
-      } else {<br>
-         num_components = 1;<br>
-         size = type_size(src_type);<br>
-      }<br>
-      bool has_indirect = deref_has_indirect(src);<br>
-      nir_src indirect;<br>
-      nir_src *indirect_ptr = has_indirect ? &indirect : NULL;<br>
-      unsigned offset = get_deref_offset(src, after, impl, native_integers,<br>
-                                         indirect_ptr);<br>
-      offset += src->var->data.driver_location;<br>
-<br>
-      reg_input_block_copy(dest, offset, indirect_ptr, predicate, size,<br>
-                           num_components, src->var->data.mode, after,<br>
-                           mem_ctx);<br>
-   } else {<br>
-      nir_reg_src reg;<br>
-      reg.reg = dest.reg;<br>
-      reg.base_offset = dest.base_offset;<br>
-      reg.indirect = dest.indirect;<br>
-<br>
-      var_reg_block_copy_impl(reg, src, predicate, src_type, after, false,<br>
-                              mem_ctx);<br>
-   }<br>
-}<br>
-<br>
-/* emits a register -> variable copy */<br>
-static void<br>
-reg_var_block_copy(nir_reg_src src, nir_deref_var *dest, nir_src *predicate,<br>
-                   nir_instr *after, void *mem_ctx)<br>
-{<br>
-   const struct glsl_type *dest_type = get_deref_tail(&dest->deref)->type;<br>
-<br>
-   var_reg_block_copy_impl(src, dest, predicate, dest_type, after, true,<br>
-                           mem_ctx);<br>
-}<br>
-<br>
-/*<br>
- * emits an input -> variable block copy using an intermediate register<br>
- */<br>
-static void<br>
-var_var_block_copy(nir_deref_var *src, nir_deref_var *dest, nir_src *predicate,<br>
-                   nir_instr *after, nir_function_impl *impl,<br>
-                   bool native_integers, void *mem_ctx)<br>
-{<br>
-   const struct glsl_type *type = get_deref_tail(&dest->deref)->type;<br>
-   nir_register *reg = nir_local_reg_create(impl);<br>
-   if (glsl_type_is_scalar(type) || glsl_type_is_vector(type)) {<br>
-      reg->num_components = glsl_get_vector_elements(type);<br>
-   } else {<br>
-      reg->is_packed = true;<br>
-      reg->num_components = 1;<br>
-      reg->num_array_elems = type_size(type);<br>
-   }<br>
-<br>
-   nir_reg_src reg_src;<br>
-   reg_src.base_offset = 0;<br>
-   reg_src.indirect = NULL;<br>
-   reg_src.reg = reg;<br>
-<br>
-   nir_reg_dest reg_dest;<br>
-   reg_dest.base_offset = 0;<br>
-   reg_dest.indirect = NULL;<br>
-   reg_dest.reg = reg;<br>
-<br>
-   var_reg_block_copy(src, reg_dest, predicate, true, after, impl,<br>
-                      native_integers, mem_ctx);<br>
-   reg_var_block_copy(reg_src, dest, predicate, after, mem_ctx);<br>
-}<br>
-<br>
-/* emits a register -> register block copy */<br>
-static void<br>
-reg_reg_block_copy(nir_reg_dest dest, nir_reg_src src, nir_src *predicate,<br>
-                   const struct glsl_type *type, nir_instr *after,<br>
-                   void *mem_ctx)<br>
-{<br>
-   if (!dest.reg->is_packed && !src.reg->is_packed)<br>
-      assert(dest.reg->num_components == src.reg->num_components);<br>
-<br>
-   unsigned size, num_components;<br>
-   if (dest.reg->is_packed && src.reg->is_packed) {<br>
-      size = type_size(type);<br>
-      num_components = 1;<br>
-   } else {<br>
-      size = 1;<br>
-      if (dest.reg->is_packed)<br>
-         num_components = src.reg->num_components;<br>
-      else<br>
-         num_components = dest.reg->num_components;<br>
-   }<br>
-<br>
-   for (unsigned i = 0; i < size; i++) {<br>
-      nir_alu_instr *move = nir_alu_instr_create(mem_ctx, nir_op_imov);<br>
-      move->dest.write_mask = (1 << num_components) - 1;<br>
-<br>
-      move->dest.dest.reg.reg = dest.reg;<br>
-      move->dest.dest.reg.base_offset = dest.base_offset + i;<br>
-      if (dest.indirect != NULL) {<br>
-         move->dest.dest.reg.indirect = ralloc(mem_ctx, nir_src);<br>
-         *move->dest.dest.reg.indirect = *dest.indirect;<br>
-      }<br>
-<br>
-      if (predicate) {<br>
-         move->has_predicate = true;<br>
-         move->predicate = nir_src_copy(*predicate, mem_ctx);<br>
-      }<br>
-<br>
-      move->src[0].src.reg = src;<br>
-      move->src[0].src.reg.base_offset += i;<br>
-<br>
-      nir_instr_insert_before(after, &move->instr);<br>
-   }<br>
-}<br>
-<br>
-static nir_reg_dest<br>
-create_dest(nir_deref_var *deref, nir_instr *instr, nir_register *reg,<br>
-            nir_function_impl *impl, bool native_integers, void *mem_ctx)<br>
-{<br>
-   nir_reg_dest dest;<br>
-   if (deref_has_indirect(deref)) {<br>
-      dest.indirect = ralloc(mem_ctx, nir_src);<br>
-      dest.indirect->is_ssa = false;<br>
-      dest.base_offset = get_deref_offset(deref, instr,<br>
-                                          impl, native_integers,<br>
-                                          dest.indirect);<br>
-   } else {<br>
-      dest.base_offset = get_deref_offset(deref, instr,<br>
-                                          impl, native_integers, NULL);<br>
-      dest.indirect = NULL;<br>
-   }<br>
-   dest.reg = reg;<br>
-<br>
-   return dest;<br>
-}<br>
-<br>
-static nir_reg_src<br>
-create_src(nir_deref_var *deref, nir_instr *instr, nir_register *reg,<br>
-           nir_function_impl *impl, bool native_integers, void *mem_ctx)<br>
-{<br>
-   nir_reg_src src;<br>
-   if (deref_has_indirect(deref)) {<br>
-      src.indirect = ralloc(mem_ctx, nir_src);<br>
-      src.indirect->is_ssa = false;<br>
-      src.base_offset = get_deref_offset(deref, instr,<br>
-                                         impl, native_integers,<br>
-                                         src.indirect);<br>
-   } else {<br>
-      src.base_offset = get_deref_offset(deref, instr,<br>
-                                         impl, native_integers, NULL);<br>
-      src.indirect = NULL;<br>
-   }<br>
-   src.reg = reg;<br>
-<br>
-   return src;<br>
-}<br>
-<br>
-static void<br>
-handle_var_copy(nir_intrinsic_instr *instr, nir_function_impl *impl,<br>
-                bool native_integers, bool lower_io, struct hash_table *ht)<br>
-{<br>
-   void *mem_ctx = ralloc_parent(instr);<br>
-<br>
-   struct hash_entry *entry;<br>
-<br>
-   nir_variable *dest_var = instr->variables[0]->var;<br>
-   nir_variable *src_var = instr->variables[1]->var;<br>
-<br>
-   const struct glsl_type *type =<br>
-      get_deref_tail(&instr->variables[0]->deref)->type;<br>
-<br>
-   nir_src *predicate = instr->has_predicate ? &instr->predicate : NULL;<br>
-<br>
-   /*<br>
-    * The source can be either:<br>
-    * 1. a variable we're lowering to a register<br>
-    * 2. an input or uniform we're lowering to loads from an index<br>
-    * 3. a variable we can't lower yet<br>
-    *<br>
-    * and similarly, the destination can be either:<br>
-    * 1. a variable we're lowering to a register<br>
-    * 2. a variable we can't lower yet<br>
-    *<br>
-    * meaning that there are six cases, including the trivial one (where<br>
-    * source and destination are #3 and #2 respectively) where we can't do<br>
-    * anything.<br>
-    */<br>
-<br>
-   entry = _mesa_hash_table_search(ht, _mesa_hash_pointer(dest_var), dest_var);<br>
-   if (entry) {<br>
-      nir_reg_dest dest = create_dest(instr->variables[0], &instr->instr,<br>
-                                      (nir_register *) entry->data, impl,<br>
-                                      native_integers, mem_ctx);<br>
-<br>
-      entry = _mesa_hash_table_search(ht, _mesa_hash_pointer(src_var), src_var);<br>
-      if (entry) {<br>
-         nir_reg_src src = create_src(instr->variables[1], &instr->instr,<br>
-                                     (nir_register *) entry->data, impl,<br>
-                                     native_integers, mem_ctx);<br>
-<br>
-         reg_reg_block_copy(dest, src, predicate, type, &instr->instr, mem_ctx);<br>
-      } else {<br>
-         var_reg_block_copy(instr->variables[1], dest, predicate, lower_io,<br>
-                            &instr->instr, impl, native_integers, mem_ctx);<br>
-      }<br>
-   } else {<br>
-      entry = _mesa_hash_table_search(ht, _mesa_hash_pointer(src_var), src_var);<br>
-      if (entry) {<br>
-         nir_reg_src src = create_src(instr->variables[1], &instr->instr,<br>
-                                     (nir_register *) entry->data, impl,<br>
-                                     native_integers, mem_ctx);<br>
-<br>
-         reg_var_block_copy(src, instr->variables[0], predicate, &instr->instr,<br>
-                            mem_ctx);<br>
-      } else {<br>
-         if (!lower_io || (src_var->data.mode != nir_var_shader_in &&<br>
-             src_var->data.mode != nir_var_uniform)) {<br>
-            /* nothing to do here */<br>
-            return;<br>
-         }<br>
-<br>
-         var_var_block_copy(instr->variables[1], instr->variables[0], predicate,<br>
-                            &instr->instr, impl, native_integers, mem_ctx);<br>
-      }<br>
-   }<br>
-<br>
-   nir_instr_remove(&instr->instr);<br>
-}<br>
-<br>
-static void<br>
-handle_var_load(nir_intrinsic_instr *instr, nir_function_impl *impl,<br>
-                bool native_integers, bool lower_io, struct hash_table *ht)<br>
-{<br>
-   void *mem_ctx = ralloc_parent(instr);<br>
-<br>
-   struct hash_entry *entry =<br>
-      _mesa_hash_table_search(ht, _mesa_hash_pointer(instr->variables[0]->var),<br>
-                              instr->variables[0]->var);<br>
-<br>
-   if (entry == NULL) {<br>
-      nir_variable *src_var = instr->variables[0]->var;<br>
-<br>
-      if (lower_io && (src_var->data.mode == nir_var_shader_in ||<br>
-          src_var->data.mode == nir_var_uniform)) {<br>
-         bool has_indirect = deref_has_indirect(instr->variables[0]);<br>
-         unsigned num_components =<br>
-            nir_intrinsic_infos[instr->intrinsic].dest_components;<br>
-         nir_src indirect;<br>
-         unsigned offset = get_deref_offset(instr->variables[0], &instr->instr,<br>
-                                            impl, native_integers, &indirect);<br>
-         offset += src_var->data.driver_location;<br>
-<br>
-         nir_intrinsic_op op = get_load_op(src_var->data.mode, has_indirect,<br>
-                                           num_components);<br>
-         nir_intrinsic_instr *load = nir_intrinsic_instr_create(mem_ctx, op);<br>
-         load->dest = instr->dest;<br>
-         load->const_index[0] = (int) offset;<br>
-         load->const_index[1] = 1;<br>
-         if (has_indirect)<br>
-            load->src[0] = indirect;<br>
-<br>
-         if (instr->has_predicate) {<br>
-            load->has_predicate = true;<br>
-            load->predicate = nir_src_copy(instr->predicate, mem_ctx);<br>
-         }<br>
-<br>
-         nir_instr_insert_before(&instr->instr, &load->instr);<br>
-      } else {<br>
-         return;<br>
-      }<br>
-   } else {<br>
-      nir_register *reg = (nir_register *) entry->data;<br>
-<br>
-      nir_alu_instr *move = nir_alu_instr_create(mem_ctx, nir_op_imov);<br>
-      unsigned dest_components =<br>
-         nir_intrinsic_infos[instr->intrinsic].dest_components;<br>
-      move->dest.dest = instr->dest;<br>
-      move->dest.write_mask = (1 << dest_components) - 1;<br>
-      move->src[0].src.reg = create_src(instr->variables[0], &instr->instr,<br>
-                                        reg, impl, native_integers, mem_ctx);<br>
-      if (instr->has_predicate) {<br>
-         move->has_predicate = true;<br>
-         move->predicate = nir_src_copy(instr->predicate, mem_ctx);<br>
-      }<br>
-      nir_instr_insert_before(&instr->instr, &move->instr);<br>
-   }<br>
-<br>
-   nir_instr_remove(&instr->instr);<br>
-}<br>
-<br>
-static void<br>
-handle_var_store(nir_intrinsic_instr *instr, nir_function_impl *impl,<br>
-                 bool native_integers, bool lower_io, struct hash_table *ht)<br>
-{<br>
-   void *mem_ctx = ralloc_parent(instr);<br>
-<br>
-   struct hash_entry *entry =<br>
-      _mesa_hash_table_search(ht, _mesa_hash_pointer(instr->variables[0]->var),<br>
-                              instr->variables[0]->var);<br>
-   if (entry == NULL)<br>
-         return;<br>
-<br>
-   nir_register *reg = (nir_register *) entry->data;<br>
-<br>
-   nir_alu_instr *move = nir_alu_instr_create(mem_ctx, nir_op_imov);<br>
-   unsigned src_components =<br>
-      nir_intrinsic_infos[instr->intrinsic].src_components[0];<br>
-   move->dest.dest.reg = create_dest(instr->variables[0], &instr->instr,<br>
-                                       reg, impl, native_integers, mem_ctx);<br>
-   move->dest.write_mask = (1 << src_components) - 1;<br>
-   move->src[0].src = instr->src[0];<br>
-   if (instr->has_predicate) {<br>
-      move->has_predicate = true;<br>
-      move->predicate = nir_src_copy(instr->predicate, mem_ctx);<br>
-   }<br>
-   nir_instr_insert_before(&instr->instr, &move->instr);<br>
-   nir_instr_remove(&instr->instr);<br>
-}<br>
-<br>
-typedef struct {<br>
-   struct hash_table *ht;<br>
-   bool native_integers, lower_io;<br>
-   nir_function_impl *impl;<br>
-} rewrite_state;<br>
-<br>
-static bool<br>
-rewrite_block_cb(nir_block *block, void *_state)<br>
-{<br>
-   rewrite_state *state = (rewrite_state *) _state;<br>
-<br>
-   nir_foreach_instr_safe(block, instr) {<br>
-      if (instr->type == nir_instr_type_intrinsic) {<br>
-         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);<br>
-         switch (intrin->intrinsic) {<br>
-            case nir_intrinsic_load_var_vec1:<br>
-            case nir_intrinsic_load_var_vec2:<br>
-            case nir_intrinsic_load_var_vec3:<br>
-            case nir_intrinsic_load_var_vec4:<br>
-               handle_var_load(intrin, state->impl, state->native_integers,<br>
-                               state->lower_io, state->ht);<br>
-               break;<br>
-<br>
-            case nir_intrinsic_store_var_vec1:<br>
-            case nir_intrinsic_store_var_vec2:<br>
-            case nir_intrinsic_store_var_vec3:<br>
-            case nir_intrinsic_store_var_vec4:<br>
-               handle_var_store(intrin, state->impl, state->native_integers,<br>
-                                state->lower_io, state->ht);<br>
-               break;<br>
-<br>
-            case nir_intrinsic_copy_var:<br>
-               handle_var_copy(intrin, state->impl, state->native_integers,<br>
-                               state->lower_io, state->ht);<br>
-               break;<br>
-<br>
-            default:<br>
-               break;<br>
-         }<br>
-      }<br>
-   }<br>
-<br>
-   return true;<br>
-}<br>
-<br>
-static void<br>
-rewrite_impl(nir_function_impl *impl, struct hash_table *ht,<br>
-             bool native_integers, bool lower_io)<br>
-{<br>
-   rewrite_state state;<br>
-   <a href="http://state.ht" target="_blank">state.ht</a> = ht;<br>
-   state.native_integers = native_integers;<br>
-   state.lower_io = lower_io;<br>
-   state.impl = impl;<br>
-<br>
-   nir_foreach_block(impl, rewrite_block_cb, &state);<br>
-}<br>
-<br>
-static void<br>
-insert_load_const_impl(nir_function_impl *impl, struct exec_list *vars,<br>
-                       struct hash_table *ht)<br>
-{<br>
-   void *mem_ctx = ralloc_parent(impl);<br>
-<br>
-   foreach_list_typed(nir_variable, var, node, vars) {<br>
-      if (var->constant_initializer == NULL)<br>
-         continue;<br>
-<br>
-      struct hash_entry *entry =<br>
-         _mesa_hash_table_search(ht, _mesa_hash_pointer(var), var);<br>
-      if (entry) {<br>
-         nir_register *reg = (nir_register *) entry->data;<br>
-         nir_reg_dest dest;<br>
-         dest.reg = reg;<br>
-         dest.base_offset = 0;<br>
-         dest.indirect = NULL;<br>
-         reg_const_load(dest, var->constant_initializer, var->type, impl,<br>
-                        mem_ctx);<br>
-      }<br>
-   }<br>
-}<br>
-<br>
-static nir_intrinsic_op<br>
-get_store_op(bool indirect, unsigned num_components)<br>
-{<br>
-   if (indirect) {<br>
-      switch (num_components) {<br>
-         case 1: return nir_intrinsic_store_output_vec1_indirect;<br>
-         case 2: return nir_intrinsic_store_output_vec2_indirect;<br>
-         case 3: return nir_intrinsic_store_output_vec3_indirect;<br>
-         case 4: return nir_intrinsic_store_output_vec4_indirect;<br>
-         default: assert(0); break;<br>
-      }<br>
-   } else {<br>
-      switch (num_components) {<br>
-         case 1: return nir_intrinsic_store_output_vec1;<br>
-         case 2: return nir_intrinsic_store_output_vec2;<br>
-         case 3: return nir_intrinsic_store_output_vec3;<br>
-         case 4: return nir_intrinsic_store_output_vec4;<br>
-         default: assert(0); break;<br>
-      }<br>
-   }<br>
-<br>
-   return nir_intrinsic_store_output_vec1;<br>
-}<br>
-<br>
-/* emits a reg -> output block copy after a block */<br>
-static void<br>
-reg_output_block_copy_block(nir_reg_src src, unsigned dest_index,<br>
-                            unsigned num_components, unsigned size,<br>
-                            nir_block *block, void *mem_ctx)<br>
-{<br>
-   nir_intrinsic_op op = get_store_op(false, num_components);<br>
-<br>
-   nir_intrinsic_instr *store = nir_intrinsic_instr_create(mem_ctx, op);<br>
-   store->const_index[0] = dest_index;<br>
-   store->const_index[1] = (size == 0) ? 1 : size;<br>
-   store->src[0].reg = src;<br>
-   nir_instr_insert_after_block(block, &store->instr);<br>
-}<br>
-<br>
-/* emits a reg -> output copy after an instruction */<br>
-static void<br>
-reg_output_block_copy_instr(nir_reg_src src, unsigned dest_index,<br>
-                            unsigned num_components, unsigned size,<br>
-                            nir_instr *after, void *mem_ctx)<br>
-{<br>
-   nir_intrinsic_op op = get_store_op(false, num_components);<br>
-<br>
-   nir_intrinsic_instr *store = nir_intrinsic_instr_create(mem_ctx, op);<br>
-   store->const_index[0] = dest_index;<br>
-   store->const_index[1] = (size == 0) ? 1 : size;<br>
-   store->src[0].reg = src;<br>
-   nir_instr_insert_before(after, &store->instr);<br>
-}<br>
-<br>
-static nir_function_impl *<br>
-find_main(nir_shader *shader)<br>
-{<br>
-   foreach_list_typed(nir_function, func, node, &shader->functions) {<br>
-      if (strcmp(func->name, "main") == 0) {<br>
-         assert(exec_list_length(&func->overload_list) == 1);<br>
-         nir_function_overload *overload = nir_function_first_overload(func);<br>
-         return overload->impl;<br>
-      }<br>
-   }<br>
-<br>
-   assert(0);<br>
-   return NULL;<br>
-}<br>
-<br>
-static void<br>
-insert_output_reg_copies(nir_shader *shader, nir_block *block,<br>
-                         nir_instr *after, struct hash_table *ht)<br>
-{<br>
-   struct hash_entry *entry;<br>
-   hash_table_foreach(shader->outputs, entry) {<br>
-      nir_variable *var = (nir_variable *) entry->data;<br>
-<br>
-      struct hash_entry *entry2;<br>
-      entry2 = _mesa_hash_table_search(ht, _mesa_hash_pointer(var), var);<br>
-      if (entry2) {<br>
-         nir_register *reg = (nir_register *) entry2->data;<br>
-         nir_reg_src src;<br>
-         src.reg = reg;<br>
-         src.base_offset = 0;<br>
-         src.indirect = NULL;<br>
-<br>
-         if (after) {<br>
-            reg_output_block_copy_instr(src, var->data.driver_location,<br>
-                                        reg->num_components,<br>
-                                        reg->num_array_elems,<br>
-                                        after, shader);<br>
-         } else {<br>
-            reg_output_block_copy_block(src, var->data.driver_location,<br>
-                                        reg->num_components,<br>
-                                        reg->num_array_elems,<br>
-                                        block, shader);<br>
-         }<br>
-      }<br>
-   }<br>
-}<br>
-<br>
-typedef struct {<br>
-   struct hash_table *ht;<br>
-   nir_shader *shader;<br>
-   bool found_emit_vertex;<br>
-} reg_output_state;<br>
-<br>
-static bool<br>
-insert_output_reg_copies_emit_vertex(nir_block *block, void *_state)<br>
-{<br>
-   reg_output_state *state = (reg_output_state *) _state;<br>
-<br>
-   nir_foreach_instr(block, instr) {<br>
-      if (instr->type == nir_instr_type_intrinsic) {<br>
-         nir_intrinsic_instr *intrin_instr = nir_instr_as_intrinsic(instr);<br>
-         if (intrin_instr->intrinsic == nir_intrinsic_emit_vertex) {<br>
-            insert_output_reg_copies(state->shader, NULL, instr, state->ht);<br>
-            state->found_emit_vertex = true;<br>
-         }<br>
-      }<br>
-   }<br>
-<br>
-   return true;<br>
-}<br>
-<br>
-static void<br>
-insert_output_reg_copies_shader(nir_shader *shader, struct hash_table *ht)<br>
-{<br>
-   nir_function_impl *main_impl = find_main(shader);<br>
-<br>
-   reg_output_state state;<br>
-   state.shader = shader;<br>
-   <a href="http://state.ht" target="_blank">state.ht</a> = ht;<br>
-   state.found_emit_vertex = false;<br>
-   nir_foreach_block(main_impl, insert_output_reg_copies_emit_vertex, &state);<br>
-<br>
-   if (!state.found_emit_vertex) {<br>
-      struct set_entry *entry;<br>
-      set_foreach(main_impl->end_block->predecessors, entry) {<br>
-         nir_block *block = (nir_block *) entry->key;<br>
-         insert_output_reg_copies(shader, block, NULL, ht);<br>
-      }<br>
-   }<br>
-}<br>
-<br>
-static void<br>
-rewrite_shader(nir_shader *shader, struct hash_table *ht, bool native_integers,<br>
-               bool lower_globals, bool lower_io)<br>
-{<br>
-   nir_foreach_overload(shader, overload) {<br>
-      if (overload->impl) {<br>
-         insert_load_const_impl(overload->impl, &overload->impl->locals, ht);<br>
-         if (lower_globals && strcmp(overload->function->name, "main") == 0)<br>
-            insert_load_const_impl(overload->impl, &shader->globals, ht);<br>
-         rewrite_impl(overload->impl, ht, native_integers, lower_io);<br>
-      }<br>
-   }<br>
-}<br>
-<br>
-void<br>
-nir_lower_variables_scalar(nir_shader *shader, bool lower_globals,<br>
-                           bool lower_io, bool add_names, bool native_integers)<br>
-{<br>
-   if (lower_io)<br>
-      assign_var_locations_shader(shader);<br>
-   struct hash_table *ht = init_var_ht(shader, lower_globals, lower_io,<br>
-                                       add_names);<br>
-   remove_local_vars_shader(shader, ht);<br>
-   rewrite_shader(shader, ht, native_integers, lower_globals, lower_io);<br>
-   if (lower_io)<br>
-      insert_output_reg_copies_shader(shader, ht);<br>
-   _mesa_hash_table_destroy(ht, NULL);<br>
-}<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.2.0<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div>