summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/r600_shader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600/r600_shader.c')
-rw-r--r--src/gallium/drivers/r600/r600_shader.c25
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;