i965/gs: Allow src0 immediates in GS_OPCODE_SET_WRITE_OFFSET.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 25 Sep 2015 06:47:29 +0000 (23:47 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Sat, 26 Sep 2015 19:02:31 +0000 (12:02 -0700)
GS_OPCODE_SET_WRITE_OFFSET is a MUL with a constant src[1] and special
strides.  We can easily make the generator handle constant src[0]
arguments by instead generating a MOV with the product of both operands.

This isn't necessarily a win in and of itself - instead of a MUL, we
generate a MOV, which should be basically the same cost.  However, we
can probably avoid the earlier MOV to put src[0] into a register.

shader-db statistics for geometry shaders only:

total instructions in shared programs: 3207 -> 3173 (-1.06%)
instructions in affected programs:     3207 -> 3173 (-1.06%)
helped:                                11

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
src/mesa/drivers/dri/i965/brw_vec4_generator.cpp

index 5b6444e3210ee8777ca378a8a8184c39523536d1..610caef7dcee14bf590896454d8a64248a511c9d 100644 (file)
@@ -202,6 +202,13 @@ try_constant_propagate(const struct brw_device_info *devinfo,
         return true;
       }
       break;
+   case GS_OPCODE_SET_WRITE_OFFSET:
+      /* This is just a multiply by a constant with special strides.
+       * The generator will handle immediates in both arguments (generating
+       * a single MOV of the product).  So feel free to propagate in src0.
+       */
+      inst->src[arg] = value;
+      return true;
 
    case BRW_OPCODE_CMP:
       if (arg == 1) {
index 50f96632f7ffda279eec9321b421953fa1b57d52..dcacc90054056b206d0c60c221757fa3f5814692 100644 (file)
@@ -541,8 +541,13 @@ vec4_generator::generate_gs_set_write_offset(struct brw_reg dst,
           src1.file == BRW_IMMEDIATE_VALUE &&
           src1.type == BRW_REGISTER_TYPE_UD &&
           src1.dw1.ud <= USHRT_MAX);
-   brw_MUL(p, suboffset(stride(dst, 2, 2, 1), 3), stride(src0, 8, 2, 4),
-           retype(src1, BRW_REGISTER_TYPE_UW));
+   if (src0.file == IMM) {
+      brw_MOV(p, suboffset(stride(dst, 2, 2, 1), 3),
+              brw_imm_ud(src0.dw1.ud * src1.dw1.ud));
+   } else {
+      brw_MUL(p, suboffset(stride(dst, 2, 2, 1), 3), stride(src0, 8, 2, 4),
+              retype(src1, BRW_REGISTER_TYPE_UW));
+   }
    brw_set_default_access_mode(p, BRW_ALIGN_16);
    brw_pop_insn_state(p);
 }