<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>