i965: Don't double-emit fragment.color writes for MRT with ARB_fp.
authorEric Anholt <eric@anholt.net>
Wed, 20 Apr 2011 23:10:14 +0000 (16:10 -0700)
committerEric Anholt <eric@anholt.net>
Sat, 23 Apr 2011 20:21:57 +0000 (13:21 -0700)
src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_fp.c

index 40659f2602532905f2176f6bbb209f7a29bb6a00..5d1e4045928dc8ebd17d4dbca79ff27e001c35a2 100644 (file)
@@ -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;
index 4759b289a0c87496cadda4b41da83fc0328c6edd..9ddbee2edf41669c0978e4055fa723c28cf91c23 100644 (file)
@@ -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