pan/midgard: Introduce quirks checks
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 20 Nov 2019 01:55:42 +0000 (20:55 -0500)
committerTomeu Vizoso <tomeu.vizoso@collabora.com>
Wed, 20 Nov 2019 06:41:39 +0000 (07:41 +0100)
Rather than open-coding checks on gpu_id in the compiler, let's track
quirks applying to whatever we're compiling for, to allow us to manage
the complexity of many heterogenous GPUs in the compiler.

It was discovered that a workaround used on T720 is also required on
T820 (and presumably T830), so let's fix this. This will also decrease
friction as we continue improving T720 support.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
src/panfrost/midgard/compiler.h
src/panfrost/midgard/disassemble.c
src/panfrost/midgard/midgard_compile.c
src/panfrost/midgard/midgard_quirks.h [new file with mode: 0644]
src/panfrost/midgard/midgard_ra.c

index b308552e7c9c227630b2d148d4cdc7cdd538657a..7a203da902a18f1d04f120687f47f36a5173cb9b 100644 (file)
@@ -294,7 +294,8 @@ typedef struct compiler_context {
         /* Bitmask of valid metadata */
         unsigned metadata;
 
-        unsigned gpu_id;
+        /* Model-specific quirk set */
+        uint32_t quirks;
 } compiler_context;
 
 /* Per-block live_in/live_out */
index 94a8166674bed0733872bafba76e3fe9844dafeb..784dba9a9c910ee7c416038d18d32dc0050d8443 100644 (file)
@@ -34,6 +34,7 @@
 #include "midgard.h"
 #include "midgard-parse.h"
 #include "midgard_ops.h"
+#include "midgard_quirks.h"
 #include "disassemble.h"
 #include "helpers.h"
 #include "util/half_float.h"
@@ -1514,11 +1515,12 @@ disassemble_midgard(uint8_t *code, size_t size, unsigned gpu_id, gl_shader_stage
 
                 switch (midgard_word_types[tag]) {
                 case midgard_word_type_texture: {
-                        /* Texturing uses ldst/work space on T720 */
-                        bool has_texture_pipeline = gpu_id != 0x0720;
+                        bool interpipe_aliasing =
+                                midgard_get_quirks(gpu_id) & MIDGARD_INTERPIPE_REG_ALIASING;
+
                         print_texture_word(&words[i], tabs,
-                                        has_texture_pipeline ? REG_TEX_BASE : 0,
-                                        has_texture_pipeline ? REG_TEX_BASE : REGISTER_LDST_BASE);
+                                        interpipe_aliasing ? 0 : REG_TEX_BASE,
+                                        interpipe_aliasing ? REGISTER_LDST_BASE : REG_TEX_BASE);
                         break;
                 }
 
index da7d995acd065bb7d61882b1c47e5aab74a9f3d1..731485fbc2e9008595edf17669bd213a2879f75d 100644 (file)
@@ -48,6 +48,7 @@
 #include "midgard_ops.h"
 #include "helpers.h"
 #include "compiler.h"
+#include "midgard_quirks.h"
 
 #include "disassemble.h"
 
@@ -1493,7 +1494,7 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
                  * different semantics than T760 and up */
 
                 midgard_instruction ld = m_ld_color_buffer_8(reg, 0);
-                bool old_blend = ctx->gpu_id < 0x750;
+                bool old_blend = ctx->quirks & MIDGARD_OLD_BLEND;
 
                 if (instr->intrinsic == nir_intrinsic_load_output_u8_as_fp16_pan) {
                         ld.load_store.op = old_blend ?
@@ -1815,7 +1816,7 @@ emit_tex(compiler_context *ctx, nir_tex_instr *instr)
 
         bool is_vertex = ctx->stage == MESA_SHADER_VERTEX;
 
-        if (is_vertex && instr->op == nir_texop_tex && ctx->gpu_id >= 0x750)
+        if (is_vertex && instr->op == nir_texop_tex && ctx->quirks & MIDGARD_EXPLICIT_LOD)
                 instr->op = nir_texop_txl;
 
         switch (instr->op) {
@@ -2414,7 +2415,7 @@ midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_bl
         ctx->stage = nir->info.stage;
         ctx->is_blend = is_blend;
         ctx->alpha_ref = program->alpha_ref;
-        ctx->gpu_id = gpu_id;
+        ctx->quirks = midgard_get_quirks(gpu_id);
 
         /* Start off with a safe cutoff, allowing usage of all 16 work
          * registers. Later, we'll promote uniform reads to uniform registers
diff --git a/src/panfrost/midgard/midgard_quirks.h b/src/panfrost/midgard/midgard_quirks.h
new file mode 100644 (file)
index 0000000..d076605
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __MDG_QUIRKS_H
+#define __MDG_QUIRKS_H
+
+/* Model-specific quirks requiring compiler workarounds/etc. Quirks
+ * may be errata requiring a workaround, or features. We're trying to be
+ * quirk-positive here; quirky is the best! */
+
+/* Whether an explicit LOD is required via textureLod in a vertex shader. If
+ * set, vertex texturing will *always* textureLod. If unset, normal texture ops
+ * may be emitted in a vertex shader */
+
+#define MIDGARD_EXPLICIT_LOD (1 << 0)
+
+/* Whether output texture registers (normally r28/r29) overlap with work
+ * registers r0/r1 and input texture registers (also normally r28/r29) overlap
+ * with load/store registers r26/r27. This constrains register allocation
+ * considerably but is a space-saving measure on small Midgards. It's worth
+ * noting if you try to access r28/r29, it may still work, but you'll mess up
+ * the interference. Corresponds to BASE_HW_FEATURE_INTERPIPE_REG_ALIASING in
+ * kbase. */
+
+#define MIDGARD_INTERPIPE_REG_ALIASING (1 << 1)
+
+/* Whether we should use old-style blend opcodes */
+
+#define MIDGARD_OLD_BLEND (1 << 2)
+
+static inline unsigned
+midgard_get_quirks(unsigned gpu_id)
+{
+        switch (gpu_id) {
+        case 0x600:
+        case 0x620:
+                return MIDGARD_OLD_BLEND;
+
+        case 0x720:
+                return MIDGARD_INTERPIPE_REG_ALIASING | 
+                        MIDGARD_OLD_BLEND;
+
+        case 0x820:
+        case 0x830:
+                return MIDGARD_INTERPIPE_REG_ALIASING;
+
+        case 0x750:
+        case 0x860:
+        case 0x880:
+                return MIDGARD_EXPLICIT_LOD;
+
+        default:
+                unreachable("Invalid Midgard GPU ID");
+        }
+}
+
+#endif
index c2c1874aa821209d21a0a1052ec1e5f9d8bb781f..1005a8ba8052e9749d550336b66c772867286e4d 100644 (file)
@@ -27,6 +27,7 @@
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "lcra.h"
+#include "midgard_quirks.h"
 
 struct phys_reg {
         /* Physical register: 0-31 */
@@ -441,12 +442,12 @@ allocate_registers(compiler_context *ctx, bool *spilled)
 
         lcra_set_disjoint_class(l, REG_CLASS_TEXR, REG_CLASS_TEXW);
 
-        /* To save space on T720, we don't have real texture registers.
+        /* To save space on T*20, we don't have real texture registers.
          * Instead, tex inputs reuse the load/store pipeline registers, and
          * tex outputs use work r0/r1. Note we still use TEXR/TEXW classes,
          * noting that this handles interferences and sizes correctly. */
 
-        if (ctx->gpu_id == 0x0720) {
+        if (ctx->quirks & MIDGARD_INTERPIPE_REG_ALIASING) {
                 l->class_start[REG_CLASS_TEXR] = l->class_start[REG_CLASS_LDST];
                 l->class_start[REG_CLASS_TEXW] = l->class_start[REG_CLASS_WORK];
         }