diff options
Diffstat (limited to 'src/gallium/drivers/r600/r600_shader.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index f690c10fd7c..32d5a78758f 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -800,6 +800,12 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx) ctx->cv_output = i; break; } + } else if (ctx->type == TGSI_PROCESSOR_FRAGMENT) { + switch (d->Semantic.Name) { + case TGSI_SEMANTIC_COLOR: + ctx->shader->nr_ps_max_color_exports++; + break; + } } break; case TGSI_FILE_CONSTANT: @@ -1152,8 +1158,10 @@ static int r600_shader_from_tgsi(struct r600_context * rctx, struct r600_pipe_sh ctx.colors_used = 0; ctx.clip_vertex_write = 0; + shader->nr_ps_color_exports = 0; + shader->nr_ps_max_color_exports = 0; + shader->two_side = (ctx.type == TGSI_PROCESSOR_FRAGMENT) && rctx->two_side; - shader->nr_cbufs = rctx->nr_cbufs; /* register allocations */ /* Values [0,127] correspond to GPR[0..127]. @@ -1288,6 +1296,9 @@ static int r600_shader_from_tgsi(struct r600_context * rctx, struct r600_pipe_sh } } + if (shader->fs_write_all && rctx->chip_class >= EVERGREEN) + shader->nr_ps_max_color_exports = 8; + if (ctx.fragcoord_input >= 0) { if (ctx.bc->chip_class == CAYMAN) { for (j = 0 ; j < 4; j++) { @@ -1527,10 +1538,17 @@ static int r600_shader_from_tgsi(struct r600_context * rctx, struct r600_pipe_sh break; case TGSI_PROCESSOR_FRAGMENT: if (shader->output[i].name == TGSI_SEMANTIC_COLOR) { + /* never export more colors than the number of CBs */ + if (next_pixel_base && next_pixel_base >= (rctx->nr_cbufs + rctx->dual_src_blend * 1)) { + /* skip export */ + j--; + continue; + } output[j].array_base = next_pixel_base++; output[j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + shader->nr_ps_color_exports++; if (shader->fs_write_all && (rctx->chip_class >= EVERGREEN)) { - for (k = 1; k < shader->nr_cbufs; k++) { + for (k = 1; k < rctx->nr_cbufs; k++) { j++; memset(&output[j], 0, sizeof(struct r600_bytecode_output)); output[j].gpr = shader->output[i].gpr; @@ -1544,6 +1562,7 @@ static int r600_shader_from_tgsi(struct r600_context * rctx, struct r600_pipe_sh output[j].array_base = next_pixel_base++; output[j].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT); output[j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + shader->nr_ps_color_exports++; } } } else if (shader->output[i].name == TGSI_SEMANTIC_POSITION) { @@ -1594,7 +1613,7 @@ static int r600_shader_from_tgsi(struct r600_context * rctx, struct r600_pipe_sh } /* add fake pixel export */ - if (ctx.type == TGSI_PROCESSOR_FRAGMENT && j == 0) { + if (ctx.type == TGSI_PROCESSOR_FRAGMENT && next_pixel_base == 0) { memset(&output[j], 0, sizeof(struct r600_bytecode_output)); output[j].gpr = 0; output[j].elem_size = 3; |