i965: Disable hardware blending if advanced blending is in use.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_eu.c
index 6961a88c6a8318c45b48e002aa2051ca0cb2d83f..3a309dce8faeb2dbe7d90dac501e657422b3fe07 100644 (file)
@@ -187,8 +187,6 @@ void
 brw_set_default_compression_control(struct brw_codegen *p,
                            enum brw_compression compression_control)
 {
-   p->compressed = (compression_control == BRW_COMPRESSION_COMPRESSED);
-
    if (p->devinfo->gen >= 6) {
       /* Since we don't use the SIMD32 support in gen6, we translate
        * the pre-gen6 compression control here.
@@ -218,6 +216,75 @@ brw_set_default_compression_control(struct brw_codegen *p,
    }
 }
 
+/**
+ * Enable or disable instruction compression on the given instruction leaving
+ * the currently selected channel enable group untouched.
+ */
+void
+brw_inst_set_compression(const struct brw_device_info *devinfo,
+                         brw_inst *inst, bool on)
+{
+   if (devinfo->gen >= 6) {
+      /* No-op, the EU will figure out for us whether the instruction needs to
+       * be compressed.
+       */
+   } else {
+      /* The channel group and compression controls are non-orthogonal, there
+       * are two possible representations for uncompressed instructions and we
+       * may need to preserve the current one to avoid changing the selected
+       * channel group inadvertently.
+       */
+      if (on)
+         brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_COMPRESSED);
+      else if (brw_inst_qtr_control(devinfo, inst)
+               == BRW_COMPRESSION_COMPRESSED)
+         brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_NONE);
+   }
+}
+
+void
+brw_set_default_compression(struct brw_codegen *p, bool on)
+{
+   brw_inst_set_compression(p->devinfo, p->current, on);
+}
+
+/**
+ * Apply the range of channel enable signals given by
+ * [group, group + exec_size) to the instruction passed as argument.
+ */
+void
+brw_inst_set_group(const struct brw_device_info *devinfo,
+                   brw_inst *inst, unsigned group)
+{
+   if (devinfo->gen >= 7) {
+      assert(group % 4 == 0 && group < 32);
+      brw_inst_set_qtr_control(devinfo, inst, group / 8);
+      brw_inst_set_nib_control(devinfo, inst, (group / 4) % 2);
+
+   } else if (devinfo->gen == 6) {
+      assert(group % 8 == 0 && group < 32);
+      brw_inst_set_qtr_control(devinfo, inst, group / 8);
+
+   } else {
+      assert(group % 8 == 0 && group < 16);
+      /* The channel group and compression controls are non-orthogonal, there
+       * are two possible representations for group zero and we may need to
+       * preserve the current one to avoid changing the selected compression
+       * enable inadvertently.
+       */
+      if (group == 8)
+         brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_2NDHALF);
+      else if (brw_inst_qtr_control(devinfo, inst) == BRW_COMPRESSION_2NDHALF)
+         brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_NONE);
+   }
+}
+
+void
+brw_set_default_group(struct brw_codegen *p, unsigned group)
+{
+   brw_inst_set_group(p->devinfo, p->current, group);
+}
+
 void brw_set_default_mask_control( struct brw_codegen *p, unsigned value )
 {
    brw_inst_set_mask_control(p->devinfo, p->current, value);
@@ -238,7 +305,6 @@ void brw_push_insn_state( struct brw_codegen *p )
 {
    assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
    memcpy(p->current + 1, p->current, sizeof(brw_inst));
-   p->compressed_stack[p->current - p->stack] = p->compressed;
    p->current++;
 }
 
@@ -246,7 +312,6 @@ void brw_pop_insn_state( struct brw_codegen *p )
 {
    assert(p->current != p->stack);
    p->current--;
-   p->compressed = p->compressed_stack[p->current - p->stack];
 }
 
 
@@ -268,7 +333,6 @@ brw_init_codegen(const struct brw_device_info *devinfo,
    p->store = rzalloc_array(mem_ctx, brw_inst, p->store_size);
    p->nr_insn = 0;
    p->current = p->stack;
-   p->compressed = false;
    memset(p->current, 0, sizeof(p->current[0]));
 
    p->mem_ctx = mem_ctx;
@@ -339,3 +403,318 @@ brw_disassemble(const struct brw_device_info *devinfo,
       brw_disassemble_inst(out, devinfo, insn, compacted);
    }
 }
+
+enum gen {
+   GEN4  = (1 << 0),
+   GEN45 = (1 << 1),
+   GEN5  = (1 << 2),
+   GEN6  = (1 << 3),
+   GEN7  = (1 << 4),
+   GEN75 = (1 << 5),
+   GEN8  = (1 << 6),
+   GEN9  = (1 << 7),
+   GEN_ALL = ~0
+};
+
+#define GEN_LT(gen) ((gen) - 1)
+#define GEN_GE(gen) (~GEN_LT(gen))
+#define GEN_LE(gen) (GEN_LT(gen) | (gen))
+
+static const struct opcode_desc opcode_10_descs[] = {
+   { .name = "dim",   .nsrc = 1, .ndst = 1, .gens = GEN75 },
+   { .name = "smov",  .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN8) },
+};
+
+static const struct opcode_desc opcode_35_descs[] = {
+   { .name = "iff",   .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
+   { .name = "brc",   .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN7) },
+};
+
+static const struct opcode_desc opcode_38_descs[] = {
+   { .name = "do",    .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
+   { .name = "case",  .nsrc = 0, .ndst = 0, .gens = GEN6 },
+};
+
+static const struct opcode_desc opcode_44_descs[] = {
+   { .name = "msave", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
+   { .name = "call",  .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN6) },
+};
+
+static const struct opcode_desc opcode_45_descs[] = {
+   { .name = "mrest", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
+   { .name = "ret",   .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN6) },
+};
+
+static const struct opcode_desc opcode_46_descs[] = {
+   { .name = "push",  .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
+   { .name = "fork",  .nsrc = 0, .ndst = 0, .gens = GEN6 },
+   { .name = "goto",  .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN8) },
+};
+
+static const struct opcode_desc opcode_descs[128] = {
+   [BRW_OPCODE_ILLEGAL] = {
+      .name = "illegal", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_MOV] = {
+      .name = "mov",     .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_SEL] = {
+      .name = "sel",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_MOVI] = {
+      .name = "movi",    .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN45),
+   },
+   [BRW_OPCODE_NOT] = {
+      .name = "not",     .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_AND] = {
+      .name = "and",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_OR] = {
+      .name = "or",      .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_XOR] = {
+      .name = "xor",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_SHR] = {
+      .name = "shr",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_SHL] = {
+      .name = "shl",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [10] = {
+      .table = opcode_10_descs, .size = ARRAY_SIZE(opcode_10_descs),
+   },
+   /* Reserved - 11 */
+   [BRW_OPCODE_ASR] = {
+      .name = "asr",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   /* Reserved - 13-15 */
+   [BRW_OPCODE_CMP] = {
+      .name = "cmp",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_CMPN] = {
+      .name = "cmpn",    .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_CSEL] = {
+      .name = "csel",    .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN8),
+   },
+   [BRW_OPCODE_F32TO16] = {
+      .name = "f32to16", .nsrc = 1, .ndst = 1, .gens = GEN7 | GEN75,
+   },
+   [BRW_OPCODE_F16TO32] = {
+      .name = "f16to32", .nsrc = 1, .ndst = 1, .gens = GEN7 | GEN75,
+   },
+   /* Reserved - 21-22 */
+   [BRW_OPCODE_BFREV] = {
+      .name = "bfrev",   .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
+   },
+   [BRW_OPCODE_BFE] = {
+      .name = "bfe",     .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN7),
+   },
+   [BRW_OPCODE_BFI1] = {
+      .name = "bfi1",    .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN7),
+   },
+   [BRW_OPCODE_BFI2] = {
+      .name = "bfi2",    .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN7),
+   },
+   /* Reserved - 27-31 */
+   [BRW_OPCODE_JMPI] = {
+      .name = "jmpi",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
+   },
+   [33] = {
+      .name = "brd",     .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN7),
+   },
+   [BRW_OPCODE_IF] = {
+      .name = "if",      .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
+   },
+   [35] = {
+      .table = opcode_35_descs, .size = ARRAY_SIZE(opcode_35_descs),
+   },
+   [BRW_OPCODE_ELSE] = {
+      .name = "else",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_ENDIF] = {
+      .name = "endif",   .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
+   },
+   [38] = {
+      .table = opcode_38_descs, .size = ARRAY_SIZE(opcode_38_descs),
+   },
+   [BRW_OPCODE_WHILE] = {
+      .name = "while",   .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_BREAK] = {
+      .name = "break",   .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_CONTINUE] = {
+      .name = "cont",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_HALT] = {
+      .name = "halt",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
+   },
+   [43] = {
+      .name = "calla",   .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN75),
+   },
+   [44] = {
+      .table = opcode_44_descs, .size = ARRAY_SIZE(opcode_44_descs),
+   },
+   [45] = {
+      .table = opcode_45_descs, .size = ARRAY_SIZE(opcode_45_descs),
+   },
+   [46] = {
+      .table = opcode_46_descs, .size = ARRAY_SIZE(opcode_46_descs),
+   },
+   [47] = {
+      .name = "pop",     .nsrc = 2, .ndst = 0, .gens = GEN_LE(GEN5),
+   },
+   [BRW_OPCODE_WAIT] = {
+      .name = "wait",    .nsrc = 1, .ndst = 0, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_SEND] = {
+      .name = "send",    .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_SENDC] = {
+      .name = "sendc",   .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_SENDS] = {
+      .name = "sends",   .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN9),
+   },
+   [BRW_OPCODE_SENDSC] = {
+      .name = "sendsc",  .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN9),
+   },
+   /* Reserved 53-55 */
+   [BRW_OPCODE_MATH] = {
+      .name = "math",    .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN6),
+   },
+   /* Reserved 57-63 */
+   [BRW_OPCODE_ADD] = {
+      .name = "add",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_MUL] = {
+      .name = "mul",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_AVG] = {
+      .name = "avg",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_FRC] = {
+      .name = "frc",     .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_RNDU] = {
+      .name = "rndu",    .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_RNDD] = {
+      .name = "rndd",    .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_RNDE] = {
+      .name = "rnde",    .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_RNDZ] = {
+      .name = "rndz",    .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_MAC] = {
+      .name = "mac",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_MACH] = {
+      .name = "mach",    .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_LZD] = {
+      .name = "lzd",     .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_FBH] = {
+      .name = "fbh",     .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
+   },
+   [BRW_OPCODE_FBL] = {
+      .name = "fbl",     .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
+   },
+   [BRW_OPCODE_CBIT] = {
+      .name = "cbit",    .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
+   },
+   [BRW_OPCODE_ADDC] = {
+      .name = "addc",    .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN7),
+   },
+   [BRW_OPCODE_SUBB] = {
+      .name = "subb",    .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN7),
+   },
+   [BRW_OPCODE_SAD2] = {
+      .name = "sad2",    .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_SADA2] = {
+      .name = "sada2",   .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   /* Reserved 82-83 */
+   [BRW_OPCODE_DP4] = {
+      .name = "dp4",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_DPH] = {
+      .name = "dph",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_DP3] = {
+      .name = "dp3",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_DP2] = {
+      .name = "dp2",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   /* Reserved 88 */
+   [BRW_OPCODE_LINE] = {
+      .name = "line",    .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+   },
+   [BRW_OPCODE_PLN] = {
+      .name = "pln",     .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN45),
+   },
+   [BRW_OPCODE_MAD] = {
+      .name = "mad",     .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN6),
+   },
+   [BRW_OPCODE_LRP] = {
+      .name = "lrp",     .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN6),
+   },
+   [93] = {
+      .name = "madm",    .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN8),
+   },
+   /* Reserved 94-124 */
+   [BRW_OPCODE_NENOP] = {
+      .name = "nenop",   .nsrc = 0, .ndst = 0, .gens = GEN45,
+   },
+   [BRW_OPCODE_NOP] = {
+      .name = "nop",     .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
+   },
+};
+
+static enum gen
+gen_from_devinfo(const struct brw_device_info *devinfo)
+{
+   switch (devinfo->gen) {
+   case 4: return devinfo->is_g4x ? GEN45 : GEN4;
+   case 5: return GEN5;
+   case 6: return GEN6;
+   case 7: return devinfo->is_haswell ? GEN75 : GEN7;
+   case 8: return GEN8;
+   case 9: return GEN9;
+   default:
+      unreachable("not reached");
+   }
+}
+
+/* Return the matching opcode_desc for the specified opcode number and
+ * hardware generation, or NULL if the opcode is not supported by the device.
+ */
+const struct opcode_desc *
+brw_opcode_desc(const struct brw_device_info *devinfo, enum opcode opcode)
+{
+   if (opcode >= ARRAY_SIZE(opcode_descs))
+      return NULL;
+
+   enum gen gen = gen_from_devinfo(devinfo);
+   if (opcode_descs[opcode].gens != 0) {
+      if ((opcode_descs[opcode].gens & gen) != 0) {
+         return &opcode_descs[opcode];
+      }
+   } else if (opcode_descs[opcode].table != NULL) {
+      const struct opcode_desc *table = opcode_descs[opcode].table;
+      for (unsigned i = 0; i < opcode_descs[opcode].size; i++) {
+         if ((table[i].gens & gen) != 0) {
+            return &table[i];
+         }
+      }
+   }
+   return NULL;
+}