broadcom/compiler: disable TMU pipelining if we fail to register allocate
authorIago Toral Quiroga <itoral@igalia.com>
Mon, 1 Feb 2021 10:01:47 +0000 (11:01 +0100)
committerMarge Bot <eric+marge@anholt.net>
Thu, 4 Feb 2021 10:33:10 +0000 (10:33 +0000)
TMU pipelining can severely reduce our capacity to emit TMU spills,
causing us to fail to compile a shader we may otherwise be able to
compile. This is because pipelining extends the liveness of TMU
sequences by posponing the thread switch and LDTMU until a result
is needed, and we can't emit TMU spills while in the middle of a
TMU sequence.

Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8825>

src/broadcom/compiler/nir_to_vir.c
src/broadcom/compiler/v3d_compiler.h
src/broadcom/compiler/vir.c

index 2ed84146735d64827a4767590d89a6ce437e1d61..48e9c9b9255056e2bbd45ac7f0b2742bb465d5e6 100644 (file)
@@ -286,6 +286,9 @@ ntq_add_pending_tmu_flush(struct v3d_compile *c,
         c->tmu.flush[c->tmu.flush_count].dest = dest;
         c->tmu.flush[c->tmu.flush_count].component_mask = component_mask;
         c->tmu.flush_count++;
+
+        if (c->disable_tmu_pipelining)
+                ntq_flush_tmu(c);
 }
 
 enum emit_mode {
index d75a6203ba9a46bfd841939fa0e5eecb855924df..5353fe0a1c31d2bb8f1c35906861f14e0e79cdbe 100644 (file)
@@ -627,6 +627,12 @@ struct v3d_compile {
          */
         bool fallback_scheduler;
 
+        /* Disable TMU pipelining. This may increase the chances of being able
+         * to compile shaders with high register pressure that require to emit
+         * TMU spills.
+         */
+        bool disable_tmu_pipelining;
+
         /* State for whether we're executing on each channel currently.  0 if
          * yes, otherwise a block number + 1 that the channel jumped to.
          */
index 92f36a99aee33aba505e439bbbf2e7a27b0c2065..3f14b8fcb83df7243a7db84d06afcfcb840c2feb 100644 (file)
@@ -512,6 +512,7 @@ vir_compile_init(const struct v3d_compiler *compiler,
                                       void *debug_output_data),
                  void *debug_output_data,
                  int program_id, int variant_id,
+                 bool disable_tmu_pipelining,
                  bool fallback_scheduler)
 {
         struct v3d_compile *c = rzalloc(NULL, struct v3d_compile);
@@ -526,6 +527,7 @@ vir_compile_init(const struct v3d_compiler *compiler,
         c->debug_output_data = debug_output_data;
         c->compilation_result = V3D_COMPILATION_SUCCEEDED;
         c->fallback_scheduler = fallback_scheduler;
+        c->disable_tmu_pipelining = disable_tmu_pipelining;
 
         s = nir_shader_clone(c, s);
         c->s = s;
@@ -1237,22 +1239,32 @@ uint64_t *v3d_compile(const struct v3d_compiler *compiler,
 {
         struct v3d_compile *c;
 
-        for (int i = 0; true; i++) {
+        static const char *strategies[] = {
+                "default",
+                "disable TMU pipelining",
+                "fallback scheduler"
+        };
+
+        for (int i = 0; i < ARRAY_SIZE(strategies); i++) {
                 c = vir_compile_init(compiler, key, s,
                                      debug_output, debug_output_data,
                                      program_id, variant_id,
-                                     i > 0 /* fallback_scheduler */);
+                                     i > 0, /* Disable TMU pipelining */
+                                     i > 1  /* Fallback_scheduler */);
 
                 v3d_attempt_compile(c);
 
-                if (i > 0 ||
+                if (i >= ARRAY_SIZE(strategies) - 1 ||
                     c->compilation_result !=
-                    V3D_COMPILATION_FAILED_REGISTER_ALLOCATION)
+                    V3D_COMPILATION_FAILED_REGISTER_ALLOCATION) {
                         break;
+                }
 
+                /* Fallback strategy */
                 char *debug_msg;
                 int ret = asprintf(&debug_msg,
-                                   "Using fallback scheduler for %s",
+                                   "Falling back to strategy '%s' for %s",
+                                   strategies[i + 1],
                                    vir_get_stage_name(c));
 
                 if (ret >= 0) {