pan/mdg: Ensure we don't DCE into impossible masks
[mesa.git] / src / panfrost / midgard / midgard_emit.c
index f26685f6d02e1f7e60f20889ded27e570f467f2b..cf283dd3ed5b1650f1f8f756ec0be125ca0b3cf1 100644 (file)
@@ -171,17 +171,22 @@ mir_pack_mask_alu(midgard_instruction *ins)
          * override to the lower or upper half, shifting the effective mask in
          * the latter, so AAAA.... becomes AAAA */
 
-        unsigned upper_shift = mir_upper_override(ins);
+        unsigned inst_size = 8 << ins->alu.reg_mode;
+        signed upper_shift = mir_upper_override(ins, inst_size);
 
-        if (upper_shift) {
+        if (upper_shift >= 0) {
                 effective >>= upper_shift;
-                ins->alu.dest_override = midgard_dest_override_upper;
+                ins->alu.dest_override = upper_shift ?
+                        midgard_dest_override_upper :
+                        midgard_dest_override_lower;
+        } else {
+                ins->alu.dest_override = midgard_dest_override_none;
         }
 
         if (ins->alu.reg_mode == midgard_reg_mode_32)
-                ins->alu.mask = expand_writemask(effective, 4);
-        else if (ins->alu.reg_mode == midgard_reg_mode_64)
                 ins->alu.mask = expand_writemask(effective, 2);
+        else if (ins->alu.reg_mode == midgard_reg_mode_64)
+                ins->alu.mask = expand_writemask(effective, 1);
         else
                 ins->alu.mask = effective;
 }
@@ -195,7 +200,8 @@ mir_pack_swizzle(unsigned mask, unsigned *swizzle,
         unsigned sz = nir_alu_type_get_type_size(T);
 
         if (reg_mode == midgard_reg_mode_64) {
-                unsigned components = 64 / sz;
+                assert(sz == 64 || sz == 32);
+                unsigned components = (sz == 32) ? 4 : 2;
 
                 packed = mir_pack_swizzle_64(swizzle, components);
 
@@ -252,9 +258,12 @@ mir_pack_swizzle(unsigned mask, unsigned *swizzle,
                 /* Replicate for now.. should really pick a side for
                  * dot products */
 
-                if (reg_mode == midgard_reg_mode_16) {
+                if (reg_mode == midgard_reg_mode_16 && sz == 16) {
                         *rep_low = !upper;
                         *rep_high = upper;
+                } else if (reg_mode == midgard_reg_mode_16 && sz == 8) {
+                        *rep_low = upper;
+                        *rep_high = upper;
                 } else if (reg_mode == midgard_reg_mode_32) {
                         *rep_low = upper;
                 } else {
@@ -590,7 +599,20 @@ emit_binary_bundle(compiler_context *ctx,
 
                 ins->texture.type = bundle->tag;
                 ins->texture.next_type = next_tag;
-                ins->texture.mask = ins->mask;
+
+                /* Nothing else to pack for barriers */
+                if (ins->texture.op == TEXTURE_OP_BARRIER) {
+                        ins->texture.cont = ins->texture.last = 1;
+                        util_dynarray_append(emission, midgard_texture_word, ins->texture);
+                        return;
+                }
+
+                signed override = mir_upper_override(ins, 32);
+
+                ins->texture.mask = override > 0 ?
+                        ins->mask >> override :
+                        ins->mask;
+
                 mir_pack_swizzle_tex(ins);
 
                 unsigned osz = nir_alu_type_get_type_size(ins->dest_type);
@@ -600,6 +622,7 @@ emit_binary_bundle(compiler_context *ctx,
                 assert(isz == 32 || isz == 16);
 
                 ins->texture.out_full = (osz == 32);
+                ins->texture.out_upper = override > 0;
                 ins->texture.in_reg_full = (isz == 32);
                 ins->texture.sampler_type = midgard_sampler_type(ins->dest_type);