diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 25 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state_shaders.c | 52 |
3 files changed, 50 insertions, 29 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index d7f4f463340..79255004f28 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -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); diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 98bdb890a45..86d8f725cb6 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -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; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 8243d2c881f..6e7311807dd 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -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) |