<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jan 4, 2015 at 8:29 PM, Connor Abbott <span dir="ltr"><<a href="mailto:cwabbott0@gmail.com" target="_blank">cwabbott0@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I'd also like to rename or at least note that this is a scalar-only thing for now... otherwise,</div></blockquote><div><br></div><div>Sure, I'll add a note to the comment at the top of the file.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>Reviewed-by: Connor Abbott <<a href="mailto:cwabbott0@gmail.com" target="_blank">cwabbott0@gmail.com</a>></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">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></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">---<br>
src/glsl/Makefile.sources | 1 +<br>
src/glsl/nir/nir.h | 2 +<br>
src/glsl/nir/nir_lower_io.c | 388 ++++++++++++++++++++++++++++++++++++++++++++<br>
3 files changed, 391 insertions(+)<br>
create mode 100644 src/glsl/nir/nir_lower_io.c<br>
<br>
diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources<br>
index 6230f49..53c3e98 100644<br>
--- a/src/glsl/Makefile.sources<br>
+++ b/src/glsl/Makefile.sources<br>
@@ -23,6 +23,7 @@ NIR_FILES = \<br>
$(GLSL_SRCDIR)/nir/nir_live_variables.c \<br>
$(GLSL_SRCDIR)/nir/nir_lower_atomics.c \<br>
$(GLSL_SRCDIR)/nir/nir_lower_locals_to_regs.c \<br>
+ $(GLSL_SRCDIR)/nir/nir_lower_io.c \<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>
diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h<br>
index 7d7aec7..ec9ce07 100644<br>
--- a/src/glsl/nir/nir.h<br>
+++ b/src/glsl/nir/nir.h<br>
@@ -1360,6 +1360,8 @@ void nir_split_var_copies(nir_shader *shader);<br>
<br>
void nir_lower_locals_to_regs(nir_shader *shader);<br>
<br>
+void nir_lower_io(nir_shader *shader);<br>
+<br>
void nir_lower_variables(nir_shader *shader);<br>
<br>
void nir_lower_variables_scalar(nir_shader *shader, bool lower_globals,<br>
diff --git a/src/glsl/nir/nir_lower_io.c b/src/glsl/nir/nir_lower_io.c<br>
new file mode 100644<br>
index 0000000..a3b8186<br>
--- /dev/null<br>
+++ b/src/glsl/nir/nir_lower_io.c<br>
@@ -0,0 +1,388 @@<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" target="_blank">cwabbott0@gmail.com</a>)<br>
+ * Jason Ekstrand (<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>)<br>
+ *<br>
+ */<br>
+<br>
+/*<br>
+ * This lowering pass converts references to input/output variables with<br>
+ * loads/stores to actual input/output intrinsics.<br>
+ */<br>
+<br>
+#include "nir.h"<br>
+<br>
+struct lower_io_state {<br>
+ void *mem_ctx;<br>
+};<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>
+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 bool<br>
+deref_has_indirect(nir_deref_var *deref)<br>
+{<br>
+ for (nir_deref *tail = deref->deref.child; tail; tail = tail->child) {<br>
+ if (tail->deref_type == nir_deref_type_array) {<br>
+ nir_deref_array *arr = nir_deref_as_array(tail);<br>
+ if (arr->deref_array_type == nir_deref_array_type_indirect)<br>
+ return true;<br>
+ }<br>
+ }<br>
+<br>
+ return false;<br>
+}<br>
+<br>
+static unsigned<br>
+get_io_offset(nir_deref_var *deref, nir_instr *instr, nir_src *indirect,<br>
+ struct lower_io_state *state)<br>
+{<br>
+ bool found_indirect = false;<br>
+ unsigned base_offset = 0;<br>
+<br>
+ nir_deref *tail = &deref->deref;<br>
+ while (tail->child != NULL) {<br>
+ const struct glsl_type *parent_type = tail->type;<br>
+ tail = tail->child;<br>
+<br>
+ if (tail->deref_type == nir_deref_type_array) {<br>
+ nir_deref_array *deref_array = nir_deref_as_array(tail);<br>
+ unsigned size = type_size(tail->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_load_const_instr *load_const =<br>
+ nir_load_const_instr_create(state->mem_ctx);<br>
+ load_const->num_components = 1;<br>
+ load_const->value.u[0] = size;<br>
+ load_const->dest.is_ssa = true;<br>
+ nir_ssa_def_init(&load_const->instr, &load_const->dest.ssa,<br>
+ 1, NULL);<br>
+ nir_instr_insert_before(instr, &load_const->instr);<br>
+<br>
+ nir_alu_instr *mul = nir_alu_instr_create(state->mem_ctx,<br>
+ nir_op_imul);<br>
+ mul->src[0].src.is_ssa = true;<br>
+ mul->src[0].src.ssa = &load_const->dest.ssa;<br>
+ mul->src[1].src = nir_src_copy(deref_array->indirect,<br>
+ state->mem_ctx);<br>
+ mul->dest.write_mask = 1;<br>
+ mul->dest.dest.is_ssa = true;<br>
+ nir_ssa_def_init(&mul->instr, &mul->dest.dest.ssa, 1, NULL);<br>
+ nir_instr_insert_before(instr, &mul->instr);<br>
+<br>
+ if (found_indirect) {<br>
+ nir_alu_instr *add = nir_alu_instr_create(state->mem_ctx,<br>
+ nir_op_iadd);<br>
+ add->src[0].src = *indirect;<br>
+ add->src[1].src.is_ssa = true;<br>
+ add->src[1].src.ssa = &mul->dest.dest.ssa;<br>
+ add->dest.write_mask = 1;<br>
+ add->dest.dest.is_ssa = true;<br>
+ nir_ssa_def_init(&add->instr, &add->dest.dest.ssa, 1, NULL);<br>
+ nir_instr_insert_before(instr, &add->instr);<br>
+<br>
+ indirect->is_ssa = true;<br>
+ indirect->ssa = &add->dest.dest.ssa;<br>
+ } else {<br>
+ indirect->is_ssa = true;<br>
+ indirect->ssa = &mul->dest.dest.ssa;<br>
+ found_indirect = true;<br>
+ }<br>
+ }<br>
+ } else if (tail->deref_type == nir_deref_type_struct) {<br>
+ nir_deref_struct *deref_struct = nir_deref_as_struct(tail);<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>
+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: unreachable("Invalid number of components"); 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: unreachable("Invalid number of components"); break;<br>
+ }<br>
+ break;<br>
+<br>
+ default:<br>
+ unreachable("Invalid input type");<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: unreachable("Invalid number of components"); 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: unreachable("Invalid number of components"); break;<br>
+ }<br>
+ break;<br>
+<br>
+ default:<br>
+ unreachable("Invalid input type");<br>
+ break;<br>
+ }<br>
+ }<br>
+<br>
+ return nir_intrinsic_load_input_vec1;<br>
+}<br>
+<br>
+static bool<br>
+nir_lower_io_block(nir_block *block, void *void_state)<br>
+{<br>
+ struct lower_io_state *state = void_state;<br>
+<br>
+ nir_foreach_instr_safe(block, instr) {<br>
+ if (instr->type != nir_instr_type_intrinsic)<br>
+ continue;<br>
+<br>
+ nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);<br>
+<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>
+ nir_variable_mode mode = intrin->variables[0]->var->data.mode;<br>
+ if (mode != nir_var_shader_in && mode != nir_var_uniform)<br>
+ continue;<br>
+<br>
+ bool has_indirect = deref_has_indirect(intrin->variables[0]);<br>
+ unsigned num_components =<br>
+ nir_intrinsic_infos[intrin->intrinsic].dest_components;<br>
+<br>
+ nir_intrinsic_op load_op = get_load_op(mode, has_indirect,<br>
+ num_components);<br>
+ nir_intrinsic_instr *load = nir_intrinsic_instr_create(state->mem_ctx,<br>
+ load_op);<br>
+<br>
+ nir_src indirect;<br>
+ unsigned offset = get_io_offset(intrin->variables[0],<br>
+ &intrin->instr, &indirect, state);<br>
+ offset += intrin->variables[0]->var->data.driver_location;<br>
+<br>
+ load->const_index[0] = offset;<br>
+ load->const_index[1] = 1;<br>
+<br>
+ if (has_indirect)<br>
+ load->src[0] = indirect;<br>
+<br>
+ if (intrin->dest.is_ssa) {<br>
+ load->dest.is_ssa = true;<br>
+ nir_ssa_def_init(&load->instr, &load->dest.ssa,<br>
+ num_components, NULL);<br>
+<br>
+ nir_src new_src = {<br>
+ .is_ssa = true,<br>
+ .ssa = &load->dest.ssa,<br>
+ };<br>
+<br>
+ nir_ssa_def_rewrite_uses(&intrin->dest.ssa, new_src,<br>
+ state->mem_ctx);<br>
+ } else {<br>
+ load->dest = nir_dest_copy(intrin->dest, state->mem_ctx);<br>
+ }<br>
+<br>
+ nir_instr_insert_before(&intrin->instr, &load->instr);<br>
+ nir_instr_remove(&intrin->instr);<br>
+ break;<br>
+ }<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>
+ if (intrin->variables[0]->var->data.mode != nir_var_shader_out)<br>
+ continue;<br>
+<br>
+ bool has_indirect = deref_has_indirect(intrin->variables[0]);<br>
+ unsigned num_components =<br>
+ nir_intrinsic_infos[intrin->intrinsic].src_components[0];<br>
+<br>
+ nir_intrinsic_op store_op;<br>
+ if (has_indirect) {<br>
+ switch (num_components) {<br>
+ case 1: store_op = nir_intrinsic_store_output_vec1_indirect; break;<br>
+ case 2: store_op = nir_intrinsic_store_output_vec2_indirect; break;<br>
+ case 3: store_op = nir_intrinsic_store_output_vec3_indirect; break;<br>
+ case 4: store_op = nir_intrinsic_store_output_vec4_indirect; break;<br>
+ default: unreachable("Invalid number of components"); break;<br>
+ }<br>
+ } else {<br>
+ switch (num_components) {<br>
+ case 1: store_op = nir_intrinsic_store_output_vec1; break;<br>
+ case 2: store_op = nir_intrinsic_store_output_vec2; break;<br>
+ case 3: store_op = nir_intrinsic_store_output_vec3; break;<br>
+ case 4: store_op = nir_intrinsic_store_output_vec4; break;<br>
+ default: unreachable("Invalid number of components"); break;<br>
+ }<br>
+ }<br>
+<br>
+ nir_intrinsic_instr *store = nir_intrinsic_instr_create(state->mem_ctx,<br>
+ store_op);<br>
+<br>
+ nir_src indirect;<br>
+ unsigned offset = get_io_offset(intrin->variables[0],<br>
+ &intrin->instr, &indirect, state);<br>
+ offset += intrin->variables[0]->var->data.driver_location;<br>
+<br>
+ store->const_index[0] = offset;<br>
+ store->const_index[1] = 1;<br>
+<br>
+ store->src[0] = nir_src_copy(intrin->src[0], state->mem_ctx);<br>
+<br>
+ if (has_indirect)<br>
+ store->src[1] = indirect;<br>
+<br>
+ nir_instr_insert_before(&intrin->instr, &store->instr);<br>
+ nir_instr_remove(&intrin->instr);<br>
+ break;<br>
+ }<br>
+<br>
+ default:<br>
+ break;<br>
+ }<br>
+ }<br>
+<br>
+ return true;<br>
+}<br>
+<br>
+static void<br>
+nir_lower_io_impl(nir_function_impl *impl)<br>
+{<br>
+ struct lower_io_state state;<br>
+<br>
+ state.mem_ctx = ralloc_parent(impl);<br>
+<br>
+ nir_foreach_block(impl, nir_lower_io_block, &state);<br>
+}<br>
+<br>
+void<br>
+nir_lower_io(nir_shader *shader)<br>
+{<br>
+ assign_var_locations_shader(shader);<br>
+<br>
+ nir_foreach_overload(shader, overload) {<br>
+ if (overload->impl)<br>
+ nir_lower_io_impl(overload->impl);<br>
+ }<br>
+}<br>
</div></div><span class="HOEnZb"><font color="#888888"><span><font color="#888888">--<br>
2.2.0<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">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></font></span></blockquote></div><br></div>
</blockquote></div><br></div></div>