[v4,36/40] intel/compiler: skip validating restrictions on operand types for mixed float

Submitted by Iago Toral Quiroga on Feb. 12, 2019, 11:56 a.m.

Details

Message ID 20190212115607.21467-37-itoral@igalia.com
State New
Headers show
Series "intel: VK_KHR_shader_float16_int8 implementation" ( rev: 16 15 14 13 12 11 10 9 8 7 6 ) in Mesa

Not browsing as part of any series.

Commit Message

Iago Toral Quiroga Feb. 12, 2019, 11:56 a.m.
Mixed float instructions are those that use both F and HF operands as their
sources or destination, except for regular conversions.

There are specific rules for mixed float operation mode with its own set
of restrictions, which involve rules that are incompatible with general
restrictions. For example:

   "In Align1, destination stride can be smaller than execution type"

Instead, we will implement validation for mixed float mode instructions
separately in a follow-up patch.
---
 src/intel/compiler/brw_eu_validate.c | 50 ++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

Patch hide | download patch | download mbox

diff --git a/src/intel/compiler/brw_eu_validate.c b/src/intel/compiler/brw_eu_validate.c
index b1fdd1ce941..ed9c8fe59dd 100644
--- a/src/intel/compiler/brw_eu_validate.c
+++ b/src/intel/compiler/brw_eu_validate.c
@@ -461,6 +461,53 @@  is_packed(unsigned vstride, unsigned width, unsigned hstride)
    return false;
 }
 
+/**
+ * Returns whether a combination of two types would qualify as mixed float
+ * operation mode
+ */
+static inline bool
+types_are_mixed_float(enum brw_reg_type t0, enum brw_reg_type t1)
+{
+   return (t0 == BRW_REGISTER_TYPE_F && t1 == BRW_REGISTER_TYPE_HF) ||
+          (t1 == BRW_REGISTER_TYPE_F && t0 == BRW_REGISTER_TYPE_HF);
+}
+
+/**
+ * Returns whether an instruction is using mixed float operation mode
+ */
+static bool
+is_mixed_float(const struct gen_device_info *devinfo, const brw_inst *inst)
+{
+   if (devinfo->gen < 8)
+      return false;
+
+   if (inst_is_send(devinfo, inst))
+      return false;
+
+   unsigned opcode = brw_inst_opcode(devinfo, inst);
+   const struct opcode_desc *desc = brw_opcode_desc(devinfo, opcode);
+   if (desc->ndst == 0)
+      return false;
+
+   /* FIXME: support 3-src instructions */
+   unsigned num_sources = num_sources_from_inst(devinfo, inst);
+   assert(num_sources < 3);
+
+   enum brw_reg_type dst_type = brw_inst_dst_type(devinfo, inst);
+   enum brw_reg_type src0_type = brw_inst_src0_type(devinfo, inst);
+
+   if (num_sources == 1) {
+      return opcode == BRW_OPCODE_MATH &&
+             types_are_mixed_float(src0_type, dst_type);
+   }
+
+   enum brw_reg_type src1_type = brw_inst_src1_type(devinfo, inst);
+
+   return types_are_mixed_float(src0_type, src1_type) ||
+          types_are_mixed_float(src0_type, dst_type) ||
+          types_are_mixed_float(src1_type, dst_type);
+}
+
 /**
  * Checks restrictions listed in "General Restrictions Based on Operand Types"
  * in the "Register Region Restrictions" section.
@@ -487,6 +534,9 @@  general_restrictions_based_on_operand_types(const struct gen_device_info *devinf
    if (desc->ndst == 0)
       return (struct string){};
 
+   if (is_mixed_float(devinfo, inst))
+      return (struct string){};
+
    /* The PRMs say:
     *
     *    Where n is the largest element size in bytes for any source or