i965: Fix up VS DP4 sequences to avoid dependency control.
authorEric Anholt <eric@anholt.net>
Thu, 11 Mar 2010 01:16:39 +0000 (17:16 -0800)
committerEric Anholt <eric@anholt.net>
Fri, 12 Mar 2010 23:12:01 +0000 (15:12 -0800)
This is recommended by the B-Spec.  I wasn't able to measure any
difference in ETQW.

src/mesa/drivers/dri/i965/Makefile
src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_optimize.c [new file with mode: 0644]
src/mesa/drivers/dri/i965/brw_vs_emit.c

index a242580273f1cb45c1af8ec419fc31ad7af17ba1..842d4b7aa104c52e51f5e736e028cc06ffe7c9f0 100644 (file)
@@ -54,6 +54,7 @@ DRIVER_SOURCES = \
        brw_gs_emit.c \
        brw_gs_state.c \
        brw_misc_state.c \
+       brw_optimize.c \
        brw_program.c \
        brw_queryobj.c \
        brw_sf.c \
index 8e9117b6440b8770676968cb71384463097597e2..4f55158e8f38287a62672550aae44d27085a9e45 100644 (file)
@@ -966,4 +966,9 @@ void brw_math_invert( struct brw_compile *p,
 
 void brw_set_src1( struct brw_instruction *insn,
                           struct brw_reg reg );
+
+
+/* brw_optimize.c */
+void brw_optimize(struct brw_compile *p);
+
 #endif
diff --git a/src/mesa/drivers/dri/i965/brw_optimize.c b/src/mesa/drivers/dri/i965/brw_optimize.c
new file mode 100644 (file)
index 0000000..57df9ea
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include "main/macros.h"
+#include "shader/program.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_eu.h"
+
+static GLboolean
+is_single_channel_dp4(struct brw_instruction *insn)
+{
+   if (insn->header.opcode != BRW_OPCODE_DP4 ||
+       insn->header.execution_size != BRW_EXECUTE_8 ||
+       insn->header.access_mode != BRW_ALIGN_16 ||
+       insn->bits1.da1.dest_reg_file != BRW_GENERAL_REGISTER_FILE)
+      return GL_FALSE;
+
+   if (!is_power_of_two(insn->bits1.da16.dest_writemask))
+      return GL_FALSE;
+
+   return GL_TRUE;
+}
+
+/**
+ * Sets the dependency control fields on DP4 instructions.
+ *
+ * The hardware only tracks dependencies on a register basis, so when
+ * you do:
+ *
+ * DP4 dst.x src1 src2
+ * DP4 dst.y src1 src3
+ * DP4 dst.z src1 src4
+ * DP4 dst.w src1 src5
+ *
+ * It will wait to do the DP4 dst.y until the dst.x is resolved, etc.
+ * We can examine our instruction stream and set the dependency
+ * control fields to tell the hardware when to do it.
+ *
+ * We may want to extend this to other instructions that are used to
+ * fill in a channel at a time of the destination register.
+ */
+static void
+brw_set_dp4_dependency_control(struct brw_compile *p)
+{
+   int i;
+
+   for (i = 1; i < p->nr_insn; i++) {
+      struct brw_instruction *insn = &p->store[i];
+      struct brw_instruction *prev = &p->store[i - 1];
+
+      if (!is_single_channel_dp4(prev))
+        continue;
+
+      if (!is_single_channel_dp4(insn)) {
+        i++;
+        continue;
+      }
+
+      /* Only avoid hw dep control if the write masks are different
+       * channels of one reg.
+       */
+      if (insn->bits1.da16.dest_writemask == prev->bits1.da16.dest_writemask)
+        continue;
+      if (insn->bits1.da16.dest_reg_nr != prev->bits1.da16.dest_reg_nr)
+        continue;
+
+      /* Check if the second instruction depends on the previous one
+       * for a src.
+       */
+      if (insn->bits1.da1.src0_reg_file == BRW_GENERAL_REGISTER_FILE &&
+         (insn->bits2.da1.src0_address_mode != BRW_ADDRESS_DIRECT ||
+          insn->bits2.da1.src0_reg_nr == insn->bits1.da16.dest_reg_nr))
+         continue;
+      if (insn->bits1.da1.src1_reg_file == BRW_GENERAL_REGISTER_FILE &&
+         (insn->bits3.da1.src1_address_mode != BRW_ADDRESS_DIRECT ||
+          insn->bits3.da1.src1_reg_nr == insn->bits1.da16.dest_reg_nr))
+         continue;
+
+      prev->header.dependency_control |= BRW_DEPENDENCY_NOTCLEARED;
+      insn->header.dependency_control |= BRW_DEPENDENCY_NOTCHECKED;
+   }
+}
+
+void
+brw_optimize(struct brw_compile *p)
+{
+   brw_set_dp4_dependency_control(p);
+}
index a48804a660fb93d2735af5a6c45fdba3b7028bc1..14c3b936b7eb03abb088148e51ed7e2ae91e0e3b 100644 (file)
@@ -1825,6 +1825,8 @@ void brw_vs_emit(struct brw_vs_compile *c )
 
    post_vs_emit(c, end_inst, last_inst);
 
+   brw_optimize(p);
+
    if (INTEL_DEBUG & DEBUG_VS) {
       int i;