nir_lower_io_to_scalar: Support arrayed (per-vertex) I/O
authorJesse Natalie <jenatali@microsoft.com>
Sun, 17 Jul 2022 12:00:10 +0000 (05:00 -0700)
committerMarge Bot <emma+marge@anholt.net>
Sat, 23 Jul 2022 14:48:17 +0000 (14:48 +0000)
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17603>

src/compiler/nir/nir_lower_io_to_scalar.c

index 7f0d133..25153d3 100644 (file)
@@ -60,8 +60,9 @@ lower_load_input_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
       nir_intrinsic_set_component(chan_intr, nir_intrinsic_component(intr) + i);
       nir_intrinsic_set_dest_type(chan_intr, nir_intrinsic_dest_type(intr));
       set_io_semantics(chan_intr, intr, i);
-      /* offset */
-      nir_src_copy(&chan_intr->src[0], &intr->src[0]);
+      /* offset and vertex (if needed) */
+      for (unsigned j = 0; j < nir_intrinsic_infos[intr->intrinsic].num_srcs; ++j)
+         nir_src_copy(&chan_intr->src[j], &intr->src[j]);
 
       nir_builder_instr_insert(b, &chan_intr->instr);
 
@@ -141,33 +142,36 @@ lower_store_output_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
       nir_intrinsic_set_src_type(chan_intr, nir_intrinsic_src_type(intr));
       set_io_semantics(chan_intr, intr, i);
 
-      /* Scalarize transform feedback info. */
-      unsigned component = nir_intrinsic_component(chan_intr);
-
-      for (unsigned c = 0; c <= component; c++) {
-         nir_io_xfb xfb = c < 2 ? nir_intrinsic_io_xfb(intr) :
-                                  nir_intrinsic_io_xfb2(intr);
-
-         if (component < c + xfb.out[c % 2].num_components) {
-            nir_io_xfb scalar_xfb;
-
-            memset(&scalar_xfb, 0, sizeof(scalar_xfb));
-            scalar_xfb.out[component % 2].num_components = 1;
-            scalar_xfb.out[component % 2].buffer = xfb.out[c % 2].buffer;
-            scalar_xfb.out[component % 2].offset = xfb.out[c % 2].offset +
-                                                   component - c;
-            if (component < 2)
-               nir_intrinsic_set_io_xfb(chan_intr, scalar_xfb);
-            else
-               nir_intrinsic_set_io_xfb2(chan_intr, scalar_xfb);
-            break;
+      if (nir_intrinsic_has_io_xfb(intr)) {
+         /* Scalarize transform feedback info. */
+         unsigned component = nir_intrinsic_component(chan_intr);
+
+         for (unsigned c = 0; c <= component; c++) {
+            nir_io_xfb xfb = c < 2 ? nir_intrinsic_io_xfb(intr) :
+                                     nir_intrinsic_io_xfb2(intr);
+
+            if (component < c + xfb.out[c % 2].num_components) {
+               nir_io_xfb scalar_xfb;
+
+               memset(&scalar_xfb, 0, sizeof(scalar_xfb));
+               scalar_xfb.out[component % 2].num_components = 1;
+               scalar_xfb.out[component % 2].buffer = xfb.out[c % 2].buffer;
+               scalar_xfb.out[component % 2].offset = xfb.out[c % 2].offset +
+                                                      component - c;
+               if (component < 2)
+                  nir_intrinsic_set_io_xfb(chan_intr, scalar_xfb);
+               else
+                  nir_intrinsic_set_io_xfb2(chan_intr, scalar_xfb);
+               break;
+            }
          }
       }
 
       /* value */
       chan_intr->src[0] = nir_src_for_ssa(nir_channel(b, value, i));
-      /* offset */
-      nir_src_copy(&chan_intr->src[1], &intr->src[1]);
+      /* offset and vertex (if needed) */
+      for (unsigned j = 1; j < nir_intrinsic_infos[intr->intrinsic].num_srcs; ++j)
+         nir_src_copy(&chan_intr->src[j], &intr->src[j]);
 
       nir_builder_instr_insert(b, &chan_intr->instr);
    }
@@ -228,12 +232,19 @@ nir_lower_io_to_scalar_instr(nir_builder *b, nir_instr *instr, void *data)
    if (intr->num_components == 1)
       return false;
 
-   if (intr->intrinsic == nir_intrinsic_load_input &&
+   if ((intr->intrinsic == nir_intrinsic_load_input ||
+        intr->intrinsic == nir_intrinsic_load_per_vertex_input) &&
        (mask & nir_var_shader_in)) {
       lower_load_input_to_scalar(b, intr);
       return true;
    }
 
+   if (intr->intrinsic == nir_intrinsic_load_per_vertex_output &&
+      (mask & nir_var_shader_out)) {
+      lower_load_input_to_scalar(b, intr);
+      return true;
+   }
+
    if ((intr->intrinsic == nir_intrinsic_load_ubo && (mask & nir_var_mem_ubo)) ||
        (intr->intrinsic == nir_intrinsic_load_ssbo && (mask & nir_var_mem_ssbo)) ||
        (intr->intrinsic == nir_intrinsic_load_shared && (mask & nir_var_mem_shared))) {
@@ -241,7 +252,8 @@ nir_lower_io_to_scalar_instr(nir_builder *b, nir_instr *instr, void *data)
       return true;
    }
 
-   if (intr->intrinsic == nir_intrinsic_store_output &&
+   if ((intr->intrinsic == nir_intrinsic_store_output ||
+        intr->intrinsic == nir_intrinsic_store_per_vertex_output) &&
        mask & nir_var_shader_out) {
       lower_store_output_to_scalar(b, intr);
       return true;