<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Dec 11, 2017 at 2:59 AM, Samuel Iglesias Gonsálvez <span dir="ltr"><<a href="mailto:siglesias@igalia.com" target="_blank">siglesias@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">We can write to the same output but in different components, like<br>
in this example:<br>
<br>
layout(location = 0, component = 0) out ivec2 dEQP_FragColor_0;<br>
layout(location = 0, component = 2) out ivec2 dEQP_FragColor_1;<br>
<br>
Therefore, they are not two different outputs but only one.<br>
<br>
Fixes:<br>
<br>
dEQP-VK.glsl.440.linkage.<wbr>varying.component.frag_out.*<br>
<br>
v3:<br>
- Remove FRAG_RESULT_MAX.<br>
- Add const and use sizeof (Ian).<br>
- Do three-pass to set properly the locations of fragment<br>
  outputs when having arrays (Jason).<br>
<br>
Signed-off-by: Samuel Iglesias Gonsálvez <<a href="mailto:siglesias@igalia.com">siglesias@igalia.com</a>><br>
---<br>
<br>
I wrote CL#2003 adding more tests to check this fix.<br>
<br>
 src/intel/vulkan/anv_pipeline.<wbr>c | 63 ++++++++++++++++++++++++++++--<wbr>-----------<br>
 1 file changed, 44 insertions(+), 19 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_<wbr>pipeline.c b/src/intel/vulkan/anv_<wbr>pipeline.c<br>
index f2d4d113219..407f2970199 100644<br>
--- a/src/intel/vulkan/anv_<wbr>pipeline.c<br>
+++ b/src/intel/vulkan/anv_<wbr>pipeline.c<br>
@@ -878,13 +878,51 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,<br>
       }<br>
<br>
       unsigned num_rts = 0;<br>
-      struct anv_pipeline_binding rt_bindings[8];<br>
+      const int max_rt = FRAG_RESULT_DATA7 - FRAG_RESULT_DATA0 + 1;<br>
+      struct anv_pipeline_binding rt_bindings[max_rt];<br>
       nir_function_impl *impl = nir_shader_get_entrypoint(nir)<wbr>;<br>
+      int rt_to_bindings[max_rt];<br>
+      memset(rt_to_bindings, -1, sizeof(rt_to_bindings));<br>
+      bool rt_used[max_rt];<br></blockquote><div><br></div><div>This could be a bitfield but I don't really care.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      memset(rt_used, 0, sizeof(rt_used));<br>
+<br>
+      /* Flag used render targets */<br>
+      nir_foreach_variable_safe(var, &nir->outputs) {<br>
+         if (var->data.location < FRAG_RESULT_DATA0)<br>
+            continue;<br>
+<br>
+         const unsigned rt = var->data.location - FRAG_RESULT_DATA0;<br>
+         /* Out-of-bounds */<br>
+         if (rt >= key.nr_color_regions)<br>
+            continue;<br>
+<br>
+         const unsigned array_len =<br>
+            glsl_type_is_array(var->type) ? glsl_get_length(var->type) : 1;<br>
+         assert(rt + array_len <= max_rt);<br>
+<br>
+         for (unsigned i = 0; i < array_len; i++)<br>
+            rt_used[rt + i] = true;<br>
+      }<br>
+<br>
+      /* Set new, compacted, location */<br>
+      for (unsigned i = 0; i < max_rt; i++) {<br>
+         if (!rt_used[i])<br>
+            continue;<br>
+<br>
+         rt_to_bindings[i] = num_rts;<br>
+         rt_bindings[rt_to_bindings[i]] = (struct anv_pipeline_binding) {<br>
+            .set = ANV_DESCRIPTOR_SET_COLOR_<wbr>ATTACHMENTS,<br>
+            .binding = 0,<br>
+            .index = i,<br>
+         };<br>
+         num_rts++;<br>
+      }<br>
+<br>
       nir_foreach_variable_safe(var, &nir->outputs) {<br>
          if (var->data.location < FRAG_RESULT_DATA0)<br>
             continue;<br>
<br>
-         unsigned rt = var->data.location - FRAG_RESULT_DATA0;<br>
+         const unsigned rt = var->data.location - FRAG_RESULT_DATA0;<br>
          if (rt >= key.nr_color_regions) {<br>
             /* Out-of-bounds, throw it away */<br>
             var->data.mode = nir_var_local;<br>
@@ -893,22 +931,9 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,<br>
             continue;<br>
          }<br>
<br>
-         /* Give it a new, compacted, location */<br>
-         var->data.location = FRAG_RESULT_DATA0 + num_rts;<br>
-<br>
-         unsigned array_len =<br>
-            glsl_type_is_array(var->type) ? glsl_get_length(var->type) : 1;<br>
-         assert(num_rts + array_len <= 8);<br>
-<br>
-         for (unsigned i = 0; i < array_len; i++) {<br>
-            rt_bindings[num_rts + i] = (struct anv_pipeline_binding) {<br>
-               .set = ANV_DESCRIPTOR_SET_COLOR_<wbr>ATTACHMENTS,<br>
-               .binding = 0,<br>
-               .index = rt + i,<br>
-            };<br>
-         }<br>
-<br>
-         num_rts += array_len;<br>
+         /* Give it the new location */<br>
+         assert(rt_to_bindings[rt] != -1);<br>
+         var->data.location = rt_to_bindings[rt] + FRAG_RESULT_DATA0;<br></blockquote><div><br></div><div>This should do the trick.</div><div><br></div><div>Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
       }<br>
<br>
       if (num_rts == 0) {<br>
@@ -921,7 +946,7 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,<br>
          num_rts = 1;<br>
       }<br>
<br>
-      assert(num_rts <= 8);<br>
+      assert(num_rts <= max_rt);<br>
       map.surface_to_descriptor -= num_rts;<br>
       map.surface_count += num_rts;<br>
       assert(map.surface_count <= 256);<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.11.0<br>
<br>
</font></span></blockquote></div><br></div></div>