[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