st/glsl_to_nir: enable NIR link time opts
[mesa.git] / src / gallium / drivers / radeonsi / si_shader_nir.c
index 5d82715f7a7c8aea226165992729de1d2965f873..979361a74ee9f994ed65e92a7df7ae8e68b36efa 100644 (file)
@@ -136,9 +136,6 @@ void si_nir_scan_shader(const struct nir_shader *nir,
        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;
@@ -147,6 +144,8 @@ void si_nir_scan_shader(const struct nir_shader *nir,
        }
 
        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,
@@ -167,9 +166,18 @@ void si_nir_scan_shader(const struct nir_shader *nir,
                        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);
 
@@ -235,11 +243,16 @@ void si_nir_scan_shader(const struct nir_shader *nir,
                        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;
 
@@ -251,6 +264,13 @@ void si_nir_scan_shader(const struct nir_shader *nir,
                                                     &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;
@@ -327,10 +347,10 @@ void si_nir_scan_shader(const struct nir_shader *nir,
                                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 =
@@ -444,21 +464,18 @@ si_lower_nir(struct si_shader_selector* sel)
 }
 
 static void declare_nir_input_vs(struct si_shader_context *ctx,
-                                struct nir_variable *variable, unsigned rel,
+                                struct nir_variable *variable,
                                 LLVMValueRef out[4])
 {
-       si_llvm_load_input_vs(ctx, variable->data.driver_location / 4 + rel, out);
+       si_llvm_load_input_vs(ctx, variable->data.driver_location / 4, out);
 }
 
 static void declare_nir_input_fs(struct si_shader_context *ctx,
-                                struct nir_variable *variable, unsigned rel,
-                                unsigned *fs_attr_idx,
+                                struct nir_variable *variable,
+                                unsigned input_index,
                                 LLVMValueRef out[4])
 {
-       unsigned slot = variable->data.location + rel;
-
-       assert(variable->data.location >= VARYING_SLOT_VAR0 || rel == 0);
-
+       unsigned slot = variable->data.location;
        if (slot == VARYING_SLOT_POS) {
                out[0] = LLVMGetParam(ctx->main_fn, SI_PARAM_POS_X_FLOAT);
                out[1] = LLVMGetParam(ctx->main_fn, SI_PARAM_POS_Y_FLOAT);
@@ -468,8 +485,7 @@ static void declare_nir_input_fs(struct si_shader_context *ctx,
                return;
        }
 
-       si_llvm_load_input_fs(ctx, *fs_attr_idx, out);
-       (*fs_attr_idx)++;
+       si_llvm_load_input_fs(ctx, input_index, out);
 }
 
 static LLVMValueRef
@@ -523,25 +539,33 @@ bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *nir)
 {
        struct tgsi_shader_info *info = &ctx->shader->selector->info;
 
-       unsigned fs_attr_idx = 0;
+       uint64_t processed_inputs = 0;
        nir_foreach_variable(variable, &nir->inputs) {
                unsigned attrib_count = glsl_count_attribute_slots(variable->type,
                                                                   nir->info.stage == MESA_SHADER_VERTEX);
                unsigned input_idx = variable->data.driver_location;
 
-               for (unsigned i = 0; i < attrib_count; ++i) {
-                       LLVMValueRef data[4];
+               assert(attrib_count == 1);
 
-                       if (nir->info.stage == MESA_SHADER_VERTEX)
-                               declare_nir_input_vs(ctx, variable, i, data);
-                       else if (nir->info.stage == MESA_SHADER_FRAGMENT)
-                               declare_nir_input_fs(ctx, variable, i, &fs_attr_idx, data);
+               LLVMValueRef data[4];
+               unsigned loc = variable->data.location;
 
-                       for (unsigned chan = 0; chan < 4; chan++) {
-                               ctx->inputs[input_idx + chan] =
-                                       LLVMBuildBitCast(ctx->ac.builder, data[chan], ctx->ac.i32, "");
-                       }
+               /* Packed components share the same location so skip
+                * them if we have already processed the location.
+                */
+               if (processed_inputs & ((uint64_t)1 << loc))
+                       continue;
+
+               if (nir->info.stage == MESA_SHADER_VERTEX)
+                       declare_nir_input_vs(ctx, variable, data);
+               else if (nir->info.stage == MESA_SHADER_FRAGMENT)
+                       declare_nir_input_fs(ctx, variable, input_idx / 4, data);
+
+               for (unsigned chan = 0; chan < 4; chan++) {
+                       ctx->inputs[input_idx + chan] =
+                               LLVMBuildBitCast(ctx->ac.builder, data[chan], ctx->ac.i32, "");
                }
+               processed_inputs |= ((uint64_t)1 << loc);
        }
 
        ctx->abi.inputs = &ctx->inputs[0];