pan/bi: Generalize swizzles to avoid extracts
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 9 Mar 2020 18:09:04 +0000 (14:09 -0400)
committerMarge Bot <eric+marge@anholt.net>
Tue, 10 Mar 2020 19:25:59 +0000 (19:25 +0000)
We'd really rather not emit extracts. We are approaching on a vector IR
anyway which is annoying but really necessary to handle I/O and fp16
correctly. So let's just go all the way and deal with swizzles and masks
within reason; it'll still be somewhat saner in the long-term.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4139>

src/panfrost/bifrost/bi_print.c
src/panfrost/bifrost/bifrost_compile.c
src/panfrost/bifrost/compiler.h

index cd266a9b00f39a91d0f79b383ab1ecd79b8e2ba8..58d0d75ba5188171e004caba4b47d10e2ade18ea 100644 (file)
@@ -118,7 +118,6 @@ bi_class_name(enum bi_class cl)
         case BI_CONVERT: return "convert";
         case BI_CSEL: return "csel";
         case BI_DISCARD: return "discard";
-        case BI_EXTRACT: return "extract";
         case BI_FMA: return "fma";
         case BI_FREXP: return "frexp";
         case BI_LOAD: return "load";
@@ -209,17 +208,16 @@ bi_print_alu_type(nir_alu_type t, FILE *fp)
 }
 
 static void
-bi_print_swizzle(bi_instruction *ins, FILE *fp)
+bi_print_swizzle(bi_instruction *ins, unsigned src, FILE *fp)
 {
-        unsigned size = nir_alu_type_get_type_size(ins->dest_type);
-        unsigned count = 32 / size;
-        assert(size == 8 || size == 16);
+        unsigned size = MAX2(nir_alu_type_get_type_size(ins->dest_type), 8);
+        unsigned count = (size == 64) ? 1 : (32 / size);
 
         fprintf(fp, ".");
 
         for (unsigned u = 0; u < count; ++u) {
-                assert(ins->swizzle[u] < size);
-                fputc("xyzw"[ins->swizzle[u]], fp);
+                assert(ins->swizzle[src][u] < 4);
+                fputc("xyzw"[ins->swizzle[src][u]], fp);
         }
 }
 
@@ -318,8 +316,8 @@ bi_print_instruction(bi_instruction *ins, FILE *fp)
         bi_foreach_src(ins, s) {
                 bi_print_src(fp, ins, s);
 
-                if (bi_is_src_swizzled(ins, s))
-                        bi_print_swizzle(ins, fp);
+                if (ins->src[s] && !(ins->src[s] & (BIR_INDEX_CONSTANT | BIR_INDEX_ZERO)))
+                        bi_print_swizzle(ins, s, fp);
 
                 bool is_convert = ins->type == BI_CONVERT && s == 0;
                 bool is_branch = ins->type == BI_BRANCH && s < 2 && ins->branch.cond != BI_COND_ALWAYS;
index 1c3a0f09db3f51b3cd7ebd2b3c1ef912fcb14b00..79164ac79a7ac0fc8eea5255f56c6e12f163f072 100644 (file)
@@ -106,6 +106,9 @@ bi_emit_frag_out(bi_context *ctx, nir_intrinsic_instr *instr)
                 .blend_location = nir_intrinsic_base(instr),
                 .src = {
                         bir_src_index(&instr->src[0])
+                },
+                .swizzle = {
+                        { 0, 1, 2, 3 }
                 }
         };
 
@@ -158,6 +161,9 @@ bi_emit_st_vary(bi_context *ctx, nir_intrinsic_instr *instr)
                 .src = {
                         address.dest,
                         bir_src_index(&instr->src[0])
+                },
+                .swizzle = {
+                        { 0, 1, 2, 3 }
                 }
         };
 
index 14e0bc87567053db68cf2777f5d3c3c86f7cd414..d0ca32a7a792488c5e8f80952da69edb29235541 100644 (file)
@@ -56,7 +56,6 @@ enum bi_class {
         BI_CONVERT,
         BI_CSEL,
         BI_DISCARD,
-        BI_EXTRACT,
         BI_FMA,
         BI_FREXP,
         BI_LOAD,
@@ -191,8 +190,7 @@ typedef struct {
         unsigned dest;
         unsigned src[BIR_SRC_COUNT];
 
-        /* If one of the sources has BIR_INDEX_CONSTANT... Also, for
-         * BI_EXTRACT, the component index is stored here. */
+        /* If one of the sources has BIR_INDEX_CONSTANT */
         union {
                 uint64_t u64;
                 uint32_t u32;
@@ -218,12 +216,11 @@ typedef struct {
         /* Source types if required by the class */
         nir_alu_type src_types[BIR_SRC_COUNT];
 
-        /* If the source type is 8-bit or 16-bit such that SIMD is possible, and
-         * the class has BI_SWIZZLABLE, this is a swizzle for the input. Swizzles
-         * in practice only occur with one-source arguments (conversions,
-         * dedicated swizzle ops) and as component selection on two-sources
-         * where it is unambiguous which is which. Bounds are 32/type_size. */
-        unsigned swizzle[4];
+        /* If the source type is 8-bit or 16-bit such that SIMD is possible,
+         * and the class has BI_SWIZZLABLE, this is a swizzle in the usual
+         * sense. On non-SIMD instructions, it can be used for component
+         * selection, so we don't have to special case extraction. */
+        uint8_t swizzle[BIR_SRC_COUNT][NIR_MAX_VEC_COMPONENTS];
 
         /* A class-specific op from which the actual opcode can be derived
          * (along with the above information) */