i965: Collect GLSL src/dst regs up in generic code.
authorEric Anholt <eric@anholt.net>
Wed, 12 Aug 2009 19:56:35 +0000 (12:56 -0700)
committerEric Anholt <eric@anholt.net>
Sat, 7 Nov 2009 05:08:54 +0000 (21:08 -0800)
This matches brw_wm_emit.c, which we'll be using shortly.  There's a
possible penalty here in that we'll allocate registers for unused channels,
since we aren't doing ref tracking like brw_wm_pass*.c does.  However, my
measurements on GM965 don't show any for either OA or UT2004 with the GLSL
path forced.

src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_glsl.c

index 47aa4da306792bc4c91ac651ebf358ee81ca2665..f841d2587027502d366d7e910342eca4942ef556 100644 (file)
@@ -162,6 +162,8 @@ struct brw_wm_instruction {
 #define BRW_WM_MAX_CONST 256
 #define BRW_WM_MAX_SUBROUTINE 16
 
+/* used in masks next to WRITEMASK_*. */
+#define SATURATE (1<<5)
 
 
 /* New opcodes to track internal operations required for WM unit.
index 28d6d4eba5c8af87173492e1501abf901337a5e4..fd6d6c5602d8c78e821237e6b6a03bde843b81d3 100644 (file)
@@ -2771,6 +2771,21 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
         if (c->fp->use_const_buffer)
            fetch_constants(c, inst);
 
+       if (inst->Opcode != OPCODE_ARL) {
+          for (j = 0; j < 4; j++) {
+             if (inst->DstReg.WriteMask & (1 << j))
+                dst[j] = get_dst_reg(c, inst, j);
+             else
+                dst[j] = brw_null_reg();
+          }
+       }
+       for (j = 0; j < brw_wm_nr_args(inst->Opcode); j++)
+           get_argument_regs(c, inst, j, args[j], WRITEMASK_XYZW);
+
+       dst_flags = inst->DstReg.WriteMask;
+       if (inst->SaturateMode == SATURATE_ZERO_ONE)
+           dst_flags |= SATURATE;
+
        if (inst->CondUpdate)
            brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
        else
@@ -2866,13 +2881,6 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
                break;
            case OPCODE_DDX:
            case OPCODE_DDY:
-               for (j = 0; j < 4; j++) {
-                   if (inst->DstReg.WriteMask & (1 << j))
-                       dst[j] = get_dst_reg(c, inst, j);
-                   else
-                       dst[j] = brw_null_reg();
-               }
-               get_argument_regs(c, inst, 0, args[0], WRITEMASK_XYZW);
                emit_ddxy(p, dst, dst_flags, (inst->Opcode == OPCODE_DDX),
                          args[0]);
                 break;