From 79bde19ef9e13d5db30d0516d9e7eae6a3a8d32a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 20 Apr 2011 16:10:14 -0700 Subject: [PATCH] i965: Don't double-emit fragment.color writes for MRT with ARB_fp. --- src/mesa/drivers/dri/i965/brw_wm.h | 1 - src/mesa/drivers/dri/i965/brw_wm_fp.c | 53 +++++++++++++---------------------- 2 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 40659f2..5d1e404 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -218,7 +218,6 @@ struct brw_wm_compile { GLuint nr_fp_insns; GLuint fp_temp; GLuint fp_interp_emitted; - GLuint fp_fragcolor_emitted; struct prog_src_register pixel_xy; struct prog_src_register delta_xy; diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 4759b28..9ddbee2 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -961,35 +961,31 @@ static void emit_render_target_writes( struct brw_wm_compile *c ) struct prog_src_register outcolor; GLuint i; - struct prog_instruction *inst, *last_inst = NULL; + struct prog_instruction *inst = NULL; /* The inst->Aux field is used for FB write target and the EOT marker */ - if (c->key.nr_color_regions > 1) { - for (i = 0 ; i < c->key.nr_color_regions; i++) { - outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i); - last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0), - 0, outcolor, payload_r0_depth, outdepth); - inst->Aux = INST_AUX_TARGET(i); - if (c->fp_fragcolor_emitted) { - outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR); - last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0), - 0, outcolor, payload_r0_depth, outdepth); - inst->Aux = INST_AUX_TARGET(i); - } + for (i = 0; i < c->key.nr_color_regions; i++) { + if (c->fp->program.Base.OutputsWritten & (1 << FRAG_RESULT_COLOR)) { + outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR); + } else { + outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i); } - last_inst->Aux |= INST_AUX_EOT; + inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0), + 0, outcolor, payload_r0_depth, outdepth); + inst->Aux = INST_AUX_TARGET(i); } - else { - /* if gl_FragData[0] is written, use it, else use gl_FragColor */ - if (c->fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DATA0)) - outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0); - else - outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR); - inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0), - 0, outcolor, payload_r0_depth, outdepth); - inst->Aux = INST_AUX_EOT | INST_AUX_TARGET(0); + /* Mark the last FB write as final, or emit a dummy write if we had + * no render targets bound. + */ + if (c->key.nr_color_regions != 0) { + inst->Aux |= INST_AUX_EOT; + } else { + inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0), + 0, src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR), + payload_r0_depth, outdepth); + inst->Aux = INST_AUX_TARGET(0) | INST_AUX_EOT; } } @@ -1015,16 +1011,6 @@ static void validate_src_regs( struct brw_wm_compile *c, } } } - -static void validate_dst_regs( struct brw_wm_compile *c, - const struct prog_instruction *inst ) -{ - if (inst->DstReg.File == PROGRAM_OUTPUT) { - GLuint idx = inst->DstReg.Index; - if (idx == FRAG_RESULT_COLOR) - c->fp_fragcolor_emitted = 1; - } -} static void print_insns( const struct prog_instruction *insn, GLuint nr ) @@ -1083,7 +1069,6 @@ void brw_wm_pass_fp( struct brw_wm_compile *c ) for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) { const struct prog_instruction *inst = &fp->program.Base.Instructions[insn]; validate_src_regs(c, inst); - validate_dst_regs(c, inst); } /* Loop over all instructions doing assorted simplifications and -- 2.7.4