Fixes assert in glsl-1.50-gs-max-output-components piglit test.

Note that the double handling will only work for doubles that
don't take up multiple slots i.e. double and dvec2. However
dual slot double handling is an existing bug which is made no
worse by this patch.
---
 src/gallium/drivers/radeonsi/si_shader_nir.c | 56 +++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c 
b/src/gallium/drivers/radeonsi/si_shader_nir.c
index 3294019cea..7b10410dd7 100644
--- a/src/gallium/drivers/radeonsi/si_shader_nir.c
+++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
@@ -462,21 +462,35 @@ void si_nir_scan_shader(const struct nir_shader *nir,
                }
 
                i = variable->data.driver_location;
-               if (processed_outputs & ((uint64_t)1 << i))
-                       continue;
-
-               processed_outputs |= ((uint64_t)1 << i);
-               num_outputs++;
-
-               info->output_semantic_name[i] = semantic_name;
-               info->output_semantic_index[i] = semantic_index;
-               info->output_usagemask[i] = TGSI_WRITEMASK_XYZW;
 
                unsigned num_components = 4;
                unsigned vector_elements = 
glsl_get_vector_elements(glsl_without_array(variable->type));
                if (vector_elements)
                        num_components = vector_elements;
 
+               if (glsl_type_is_64bit(glsl_without_array(variable->type)))
+                       num_components = MIN2(num_components * 2, 4);
+
+               ubyte usagemask = 0;
+               for (unsigned j = 0; j < num_components; j++) {
+                       switch (j + variable->data.location_frac) {
+                               case 0:
+                                       usagemask |= TGSI_WRITEMASK_X;
+                                       break;
+                               case 1:
+                                       usagemask |= TGSI_WRITEMASK_Y;
+                                       break;
+                               case 2:
+                                       usagemask |= TGSI_WRITEMASK_Z;
+                                       break;
+                               case 3:
+                                       usagemask |= TGSI_WRITEMASK_W;
+                                       break;
+                               default:
+                                       unreachable("error calculating 
component index");
+                       }
+               }
+
                unsigned gs_out_streams;
                if (variable->data.stream & (1u << 31)) {
                        gs_out_streams = variable->data.stream & ~(1u << 31);
@@ -492,23 +506,39 @@ void si_nir_scan_shader(const struct nir_shader *nir,
                unsigned streamz = (gs_out_streams >> 4) & 3;
                unsigned streamw = (gs_out_streams >> 6) & 3;
 
-               if (info->output_usagemask[i] & TGSI_WRITEMASK_X) {
+               if (usagemask & TGSI_WRITEMASK_X) {
+                       info->output_usagemask[i] |= TGSI_WRITEMASK_X;
                        info->output_streams[i] |= streamx;
                        info->num_stream_output_components[streamx]++;
                }
-               if (info->output_usagemask[i] & TGSI_WRITEMASK_Y) {
+               if (usagemask & TGSI_WRITEMASK_Y) {
+                       info->output_usagemask[i] |= TGSI_WRITEMASK_Y;
                        info->output_streams[i] |= streamy << 2;
                        info->num_stream_output_components[streamy]++;
                }
-               if (info->output_usagemask[i] & TGSI_WRITEMASK_Z) {
+               if (usagemask & TGSI_WRITEMASK_Z) {
+                       info->output_usagemask[i] |= TGSI_WRITEMASK_Z;
                        info->output_streams[i] |= streamz << 4;
                        info->num_stream_output_components[streamz]++;
                }
-               if (info->output_usagemask[i] & TGSI_WRITEMASK_W) {
+               if (usagemask & TGSI_WRITEMASK_W) {
+                       info->output_usagemask[i] |= TGSI_WRITEMASK_W;
                        info->output_streams[i] |= streamw << 6;
                        info->num_stream_output_components[streamw]++;
                }
 
+               /* make sure we only count this location once against the
+                * num_outputs counter.
+                */
+               if (processed_outputs & ((uint64_t)1 << i))
+                       continue;
+
+               processed_outputs |= ((uint64_t)1 << i);
+               num_outputs++;
+
+               info->output_semantic_name[i] = semantic_name;
+               info->output_semantic_index[i] = semantic_index;
+
                switch (semantic_name) {
                case TGSI_SEMANTIC_PRIMID:
                        info->writes_primid = true;
-- 
2.14.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to