Otherwise we overflow the tgsi array because nir uses a separate
var for component packing of varyings, while tgsi expects everything
to be vec4.

We also need to do our own count of the total number of varyings.
---
 src/gallium/drivers/radeonsi/si_shader_nir.c | 34 ++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c 
b/src/gallium/drivers/radeonsi/si_shader_nir.c
index ec748c9679..2e0e3725f7 100644
--- a/src/gallium/drivers/radeonsi/si_shader_nir.c
+++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
@@ -129,54 +129,62 @@ void si_nir_scan_shader(const struct nir_shader *nir,
        nir_function *func;
        unsigned i;
 
        assert(nir->info.stage == MESA_SHADER_VERTEX ||
               nir->info.stage == MESA_SHADER_FRAGMENT);
 
        info->processor = pipe_shader_type_from_mesa(nir->info.stage);
        info->num_tokens = 2; /* indicate that the shader is non-empty */
        info->num_instructions = 2;
 
-       info->num_inputs = nir->num_inputs;
-       info->num_outputs = nir->num_outputs;
-
        if (nir->info.stage == MESA_SHADER_GEOMETRY) {
                info->properties[TGSI_PROPERTY_GS_INPUT_PRIM] = 
nir->info.gs.input_primitive;
                info->properties[TGSI_PROPERTY_GS_OUTPUT_PRIM] = 
nir->info.gs.output_primitive;
                info->properties[TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES] = 
nir->info.gs.vertices_out;
                info->properties[TGSI_PROPERTY_GS_INVOCATIONS] = 
nir->info.gs.invocations;
        }
 
        i = 0;
+       uint64_t processed_inputs = 0;
+       unsigned num_inputs = 0;
        nir_foreach_variable(variable, &nir->inputs) {
                unsigned semantic_name, semantic_index;
                unsigned attrib_count = 
glsl_count_attribute_slots(variable->type,
                                                                   
nir->info.stage == MESA_SHADER_VERTEX);
 
                assert(attrib_count == 1 && "not implemented");
 
                /* Vertex shader inputs don't have semantics. The state
                 * tracker has already mapped them to attributes via
                 * variable->data.driver_location.
                 */
                if (nir->info.stage == MESA_SHADER_VERTEX)
                        continue;
 
                /* Fragment shader position is a system value. */
                if (nir->info.stage == MESA_SHADER_FRAGMENT &&
                    variable->data.location == VARYING_SLOT_POS) {
                        if (variable->data.pixel_center_integer)
                                
info->properties[TGSI_PROPERTY_FS_COORD_PIXEL_CENTER] =
                                        TGSI_FS_COORD_PIXEL_CENTER_INTEGER;
+
+                       num_inputs++;
                        continue;
                }
 
+               i = variable->data.driver_location;
+               if (processed_inputs & ((uint64_t)1 << i))
+                       continue;
+
+               processed_inputs |= ((uint64_t)1 << i);
+               num_inputs++;
+
                tgsi_get_gl_varying_semantic(variable->data.location, true,
                                             &semantic_name, &semantic_index);
 
                info->input_semantic_name[i] = semantic_name;
                info->input_semantic_index[i] = semantic_index;
 
                if (variable->data.sample)
                        info->input_interpolate_loc[i] = 
TGSI_INTERPOLATE_LOC_SAMPLE;
                else if (variable->data.centroid)
                        info->input_interpolate_loc[i] = 
TGSI_INTERPOLATE_LOC_CENTROID;
@@ -228,36 +236,48 @@ void si_nir_scan_shader(const struct nir_shader *nir,
                case INTERP_MODE_FLAT:
                        info->input_interpolate[i] = TGSI_INTERPOLATE_CONSTANT;
                        break;
                }
 
                /* TODO make this more precise */
                if (variable->data.location == VARYING_SLOT_COL0)
                        info->colors_read |= 0x0f;
                else if (variable->data.location == VARYING_SLOT_COL1)
                        info->colors_read |= 0xf0;
-
-               i++;
        }
 
+       if (nir->info.stage != MESA_SHADER_VERTEX)
+               info->num_inputs = num_inputs;
+       else
+               info->num_inputs = nir->num_inputs;
+
        i = 0;
+       uint64_t processed_outputs = 0;
+       unsigned num_outputs = 0;
        nir_foreach_variable(variable, &nir->outputs) {
                unsigned semantic_name, semantic_index;
 
                if (nir->info.stage == MESA_SHADER_FRAGMENT) {
                        
tgsi_get_gl_frag_result_semantic(variable->data.location,
                                &semantic_name, &semantic_index);
                } else {
                        tgsi_get_gl_varying_semantic(variable->data.location, 
true,
                                                     &semantic_name, 
&semantic_index);
                }
 
+               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;
 
                unsigned gs_out_streams;
@@ -320,24 +340,24 @@ void si_nir_scan_shader(const struct nir_shader *nir,
                case TGSI_SEMANTIC_EDGEFLAG:
                        info->writes_edgeflag = true;
                        break;
                case TGSI_SEMANTIC_POSITION:
                        if (info->processor == PIPE_SHADER_FRAGMENT)
                                info->writes_z = true;
                        else
                                info->writes_position = true;
                        break;
                }
-
-               i++;
        }
 
+       info->num_outputs = num_outputs;
+
        nir_foreach_variable(variable, &nir->uniforms) {
                const struct glsl_type *type = variable->type;
                enum glsl_base_type base_type =
                        glsl_get_base_type(glsl_without_array(type));
                unsigned aoa_size = MAX2(1, glsl_get_aoa_size(type));
 
                /* We rely on the fact that nir_lower_samplers_as_deref has
                 * eliminated struct dereferences.
                 */
                if (base_type == GLSL_TYPE_SAMPLER)
-- 
2.14.3

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to