[Mesa-dev] [PATCH 13/21] i965/eu: Add new MUL assertions

Ben Widawsky benjamin.widawsky at intel.com
Mon Dec 22 19:29:23 PST 2014


There are lots of MUL quirks for gen8+. This patch is missing one assertion, "In
Align16 mode, format conversion from double-float to floats is not allowed when
source is immediate data" I don't believe we're using double floats, and I
wasn't actually sure what the best way to make the assertion was.

Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
---
 src/mesa/drivers/dri/i965/brw_eu_emit.c | 77 ++++++++++++++++++++++++++++++---
 1 file changed, 72 insertions(+), 5 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 1fc5a2f..c53e039 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -36,6 +36,15 @@
 
 #include "util/ralloc.h"
 
+static const int hstride_for_reg[] = {0, 1, 2, 4};
+static const int vstride_for_reg[] = {0, 1, 2, 4, 8, 16, 32};
+static const int width_for_reg[] = {1, 2, 4, 8, 16};
+static const int execsize_for_reg[] = {1, 2, 4, 8, 16};
+
+#define reg_vs(reg) vstride_for_reg[reg.vstride]
+#define reg_hs(reg) hstride_for_reg[reg.hstride]
+#define reg_wi(reg) width_for_reg[reg.width]
+
 /***********************************************************************
  * Internal helper for constructing instructions
  */
@@ -226,10 +235,6 @@ extern int reg_type_size[];
 static void
 validate_reg(const struct brw_context *brw, brw_inst *inst, struct brw_reg reg)
 {
-   const int hstride_for_reg[] = {0, 1, 2, 4};
-   const int vstride_for_reg[] = {0, 1, 2, 4, 8, 16, 32};
-   const int width_for_reg[] = {1, 2, 4, 8, 16};
-   const int execsize_for_reg[] = {1, 2, 4, 8, 16};
    int width, hstride, vstride, execsize;
 
    if (reg.file == BRW_IMMEDIATE_VALUE) {
@@ -1099,6 +1104,9 @@ brw_inst *
 brw_MUL(struct brw_compile *p, struct brw_reg dest,
         struct brw_reg src0, struct brw_reg src1)
 {
+   const struct brw_context *brw = p->brw;
+   brw_inst *insn = next_insn(p, BRW_OPCODE_MUL);
+
    /* 6.32.38: mul */
    if (type_is_dword(src0.type) || type_is_dword(src1.type)) {
       assert(dest.type != BRW_REGISTER_TYPE_F);
@@ -1121,7 +1129,66 @@ brw_MUL(struct brw_compile *p, struct brw_reg dest,
    assert(src1.file != BRW_ARCHITECTURE_REGISTER_FILE ||
 	  src1.nr != BRW_ARF_ACCUMULATOR);
 
-   return brw_alu2(p, BRW_OPCODE_MUL, dest, src0, src1);
+   /* When source or destination datatype is 64b or operation is integer DWord
+    * multiply, regioning in Align1 must follow these rules:
+    */
+   const bool chv_danger = (brw->is_cherryview /* TODO: next SoC */ &&
+       (brw_inst_access_mode(brw, p->current) == BRW_ALIGN_1) &&
+       ((type_is_dword(src0.type) && type_is_dword(src1.type)) ||
+       dest.type == BRW_REGISTER_TYPE_UQ || dest.type == BRW_REGISTER_TYPE_Q));
+
+   if (chv_danger) {
+         /* "Source and Destination horizontal stride must be aligned to the
+          * same qword."
+          *
+          * XXX: We don't support qword source yet, therefore this only implies
+          * that the source is a multiple of dest. It is assumed that scalars
+          * aren't considered.
+          */
+         assert(src0.hstride == 0 || reg_hs(dest) % reg_hs(src0) == 0);
+         assert(src1.hstride == 0 || reg_hs(dest) % reg_hs(src1) == 0);
+
+         /* "Regioning must ensure Src.Vstride = Src.Width * Src.Hstride" */
+         assert(reg_vs(src0) == reg_wi(src0) * reg_hs(src0));
+         assert(reg_vs(src1) == reg_wi(src1) * reg_hs(src1));
+
+         /* "Source and Destination offset must be the same, except the case of
+          * scalar source."
+          */
+         assert(is_scalar_region(src0) || src0.subnr == dest.subnr);
+         assert(is_scalar_region(src1) || src1.subnr == dest.subnr);
+
+         /* "Indirect addressing must not be used." */
+         assert(src0.address_mode != BRW_ADDRESS_REGISTER_INDIRECT_REGISTER &&
+                src1.address_mode != BRW_ADDRESS_REGISTER_INDIRECT_REGISTER &&
+                dest.address_mode != BRW_ADDRESS_REGISTER_INDIRECT_REGISTER);
+
+         /* "ARF registers must never be used." */
+         assert(dest.file != BRW_ARCHITECTURE_REGISTER_FILE &&
+                src0.file != BRW_ARCHITECTURE_REGISTER_FILE &&
+                src1.file != BRW_ARCHITECTURE_REGISTER_FILE);
+
+         /* "DepCtrl must not be used." */
+         assert(!brw_inst_no_dd_clear(brw, insn) &&
+                !brw_inst_no_dd_check(brw, insn));
+   } else if (brw->gen >= 8 && !brw->is_cherryview) {
+      if (brw->gen >= 10)
+         _mesa_warning(NULL, "May or may not have ALIGN16 restriction.\n");
+
+      /* If Align16 is required for an operation with QW destination and non-QW
+       * source datatypes, the execution size cannot exceed 2.
+       * XXX:We never use QW on Align16
+       */
+      assert(brw_inst_access_mode(brw, p->current) != BRW_ALIGN_16 ||
+            (dest.type != BRW_REGISTER_TYPE_UQ &&
+             dest.type != BRW_REGISTER_TYPE_Q));
+   }
+
+   brw_set_dest(p, insn, dest);
+   brw_set_src0(p, insn, src0);
+   brw_set_src1(p, insn, src1);
+
+   return insn;
 }
 
 brw_inst *
-- 
2.2.1



More information about the mesa-dev mailing list