radeonsi: move BCOLOR PS input locations after all other inputs
authorMarek Olšák <marek.olsak@amd.com>
Sat, 2 Jan 2016 01:54:29 +0000 (02:54 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 9 Feb 2016 20:19:51 +0000 (21:19 +0100)
BCOLOR inputs were immediately after COLOR inputs. Thus, all following inputs
were offset by 1 if color_two_side was enabled, and not offset if it was not
enabled, which is a variation that's problematic if we want to have 1 variant
per shader and the variant doesn't care about color_two_side (that should be
handled by other bytecode attached at the beginning).

Instead, move BCOLOR inputs after all other inputs, so BCOLOR0 is at location
"num_inputs" if it's present. BCOLOR1 is next.

This also allows removing si_shader::nparam and
si_shader::ps_input_param_offset, which are useless now.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_shader.h
src/gallium/drivers/radeonsi/si_state_shaders.c

index d7f4f463340f4321e644786aeabcfeb73a2acc6f..79255004f28168ab30bceea5cc362032733ceca3 100644 (file)
@@ -912,9 +912,7 @@ static void declare_input_fs(
 
        unsigned chan;
 
-       shader->ps_input_param_offset[input_index] = shader->nparam++;
-       attr_number = lp_build_const_int32(gallivm,
-                                          shader->ps_input_param_offset[input_index]);
+       attr_number = lp_build_const_int32(gallivm, input_index);
 
        shader->ps_input_interpolate[input_index] = decl->Interp.Interpolate;
        interp_param_idx = lookup_interp_param_index(decl->Interp.Interpolate,
@@ -938,11 +936,19 @@ static void declare_input_fs(
 
        if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
            si_shader_ctx->shader->key.ps.color_two_side) {
+               struct tgsi_shader_info *info = &shader->selector->info;
                LLVMValueRef args[4];
                LLVMValueRef face, is_face_positive;
-               LLVMValueRef back_attr_number =
-                       lp_build_const_int32(gallivm,
-                                            shader->ps_input_param_offset[input_index] + 1);
+               LLVMValueRef back_attr_number;
+
+               /* If BCOLOR0 is used, BCOLOR1 is at offset "num_inputs + 1",
+                * otherwise it's at offset "num_inputs".
+                */
+               unsigned back_attr_offset = shader->selector->info.num_inputs;
+               if (decl->Semantic.Index == 1 && info->colors_read & 0xf)
+                       back_attr_offset += 1;
+
+               back_attr_number = lp_build_const_int32(gallivm, back_attr_offset);
 
                face = LLVMGetParam(main_fn, SI_PARAM_FRONT_FACE);
 
@@ -974,8 +980,6 @@ static void declare_input_fs(
                                                back,
                                                "");
                }
-
-               shader->nparam++;
        } else if (decl->Semantic.Name == TGSI_SEMANTIC_FOG) {
                LLVMValueRef args[4];
 
@@ -3280,8 +3284,7 @@ static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
        else
                interp_param = NULL;
 
-       attr_number = lp_build_const_int32(gallivm,
-                                          shader->ps_input_param_offset[input_index]);
+       attr_number = lp_build_const_int32(gallivm, input_index);
 
        if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET ||
            inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE) {
@@ -4337,8 +4340,6 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
                si_dump_streamout(&sel->so);
        }
 
-       assert(shader->nparam == 0);
-
        si_init_shader_ctx(&si_shader_ctx, sscreen, shader, tm,
                           poly_stipple ? &stipple_shader_info : &sel->info);
 
index 98bdb890a45c7ec34f6795f3176b9a6e18bfbaf2..86d8f725cb63afe58045f25ff8c195610ac6eb9e 100644 (file)
@@ -290,9 +290,7 @@ struct si_shader {
        struct radeon_shader_binary     binary;
        struct si_shader_config         config;
 
-       unsigned                nparam;
        unsigned                vs_output_param_offset[PIPE_MAX_SHADER_OUTPUTS];
-       unsigned                ps_input_param_offset[PIPE_MAX_SHADER_INPUTS];
        unsigned                ps_input_interpolate[PIPE_MAX_SHADER_INPUTS];
        bool                    uses_instanceid;
        unsigned                nr_pos_exports;
index 8243d2c881f33e1366dd53889828b3d5440f58a4..6e7311807ddd7dd2c87e0c968c855b082041c5a7 100644 (file)
@@ -404,6 +404,18 @@ static void si_shader_vs(struct si_shader *shader, struct si_shader *gs)
                si_set_tesseval_regs(shader, pm4);
 }
 
+static unsigned si_get_ps_num_interp(struct si_shader *ps)
+{
+       struct tgsi_shader_info *info = &ps->selector->info;
+       unsigned num_colors = !!(info->colors_read & 0x0f) +
+                             !!(info->colors_read & 0xf0);
+       unsigned num_interp = ps->selector->info.num_inputs +
+                             (ps->key.ps.color_two_side ? num_colors : 0);
+
+       assert(num_interp <= 32);
+       return MIN2(num_interp, 32);
+}
+
 static unsigned si_get_spi_shader_col_format(struct si_shader *shader)
 {
        unsigned value = shader->key.ps.spi_shader_col_format;
@@ -507,7 +519,7 @@ static void si_shader_ps(struct si_shader *shader)
        has_centroid = G_0286CC_PERSP_CENTROID_ENA(shader->config.spi_ps_input_ena) ||
                       G_0286CC_LINEAR_CENTROID_ENA(shader->config.spi_ps_input_ena);
 
-       spi_ps_in_control = S_0286D8_NUM_INTERP(shader->nparam) |
+       spi_ps_in_control = S_0286D8_NUM_INTERP(si_get_ps_num_interp(shader)) |
                            S_0286D8_BC_OPTIMIZE_DISABLE(has_centroid);
 
        /* Set registers. */
@@ -1129,34 +1141,44 @@ static void si_emit_spi_map(struct si_context *sctx, struct r600_atom *atom)
        struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
        struct si_shader *ps = sctx->ps_shader.current;
        struct si_shader *vs = si_get_vs_state(sctx);
-       struct tgsi_shader_info *psinfo;
-       unsigned i, num_written = 0;
+       struct tgsi_shader_info *psinfo = ps ? &ps->selector->info : NULL;
+       unsigned i, num_interp, num_written = 0, bcol_interp[2];
 
-       if (!ps || !ps->nparam)
+       if (!ps || !ps->selector->info.num_inputs)
                return;
 
-       psinfo = &ps->selector->info;
-
-       radeon_set_context_reg_seq(cs, R_028644_SPI_PS_INPUT_CNTL_0, ps->nparam);
+       num_interp = si_get_ps_num_interp(ps);
+       assert(num_interp > 0);
+       radeon_set_context_reg_seq(cs, R_028644_SPI_PS_INPUT_CNTL_0, num_interp);
 
        for (i = 0; i < psinfo->num_inputs; i++) {
                unsigned name = psinfo->input_semantic_name[i];
                unsigned index = psinfo->input_semantic_index[i];
                unsigned interpolate = psinfo->input_interpolate[i];
-               unsigned param_offset = ps->ps_input_param_offset[i];
-bcolor:
+
                radeon_emit(cs, si_get_ps_input_cntl(sctx, vs, name, index,
                                                     interpolate));
                num_written++;
 
-               if (name == TGSI_SEMANTIC_COLOR &&
-                   ps->key.ps.color_two_side) {
-                       name = TGSI_SEMANTIC_BCOLOR;
-                       param_offset++;
-                       goto bcolor;
+               if (name == TGSI_SEMANTIC_COLOR) {
+                       assert(index < ARRAY_SIZE(bcol_interp));
+                       bcol_interp[index] = interpolate;
+               }
+       }
+
+       if (ps->key.ps.color_two_side) {
+               unsigned bcol = TGSI_SEMANTIC_BCOLOR;
+
+               for (i = 0; i < 2; i++) {
+                       if (!(psinfo->colors_read & (0xf << (i * 4))))
+                               continue;
+
+                       radeon_emit(cs, si_get_ps_input_cntl(sctx, vs, bcol,
+                                                            i, bcol_interp[i]));
+                       num_written++;
                }
        }
-       assert(ps->nparam == num_written);
+       assert(num_interp == num_written);
 }
 
 static void si_emit_spi_ps_input(struct si_context *sctx, struct r600_atom *atom)