v3d: Add a "precompile" debug flag for shader-db.
authorEric Anholt <eric@anholt.net>
Thu, 20 Dec 2018 01:22:41 +0000 (17:22 -0800)
committerEric Anholt <eric@anholt.net>
Sat, 29 Dec 2018 21:52:09 +0000 (13:52 -0800)
I've been using my apitrace-based shader-db so far, but it's slow
(apitrace decompression), intrusive (apitrace windows spamming the
screen), and doesn't have much coverage.  The original shader-db provides
a lot more coverage and compiles faster, at the expense of not having the
actual runtime variant key.  As v3d has a lot less runtime variation than
vc4 did, this tradeoff makes more sense.

src/broadcom/common/v3d_debug.c
src/broadcom/common/v3d_debug.h
src/gallium/drivers/v3d/v3d_program.c

index 97404448e58946a0ef4d08fb71b4e228155417b0..4a20dd26e413cab1e3c9ba23686e137fcf9b3a85 100644 (file)
@@ -54,6 +54,7 @@ static const struct debug_control debug_control[] = {
         { "vs",          V3D_DEBUG_VS},
         { "cs",          V3D_DEBUG_CS},
         { "always_flush", V3D_DEBUG_ALWAYS_FLUSH},
+        { "precompile",  V3D_DEBUG_PRECOMPILE},
         { NULL,    0 }
 };
 
index d9f5255e216fb1555b8c48048ba0ef64fb036bb0..83c368e35e95003f50277078eaff9e059e53ca9a 100644 (file)
@@ -55,6 +55,7 @@ extern uint32_t V3D_DEBUG;
 #define V3D_DEBUG_NORAST               (1 << 11)
 #define V3D_DEBUG_ALWAYS_FLUSH         (1 << 12)
 #define V3D_DEBUG_CLIF                 (1 << 13)
+#define V3D_DEBUG_PRECOMPILE           (1 << 14)
 
 #ifdef HAVE_ANDROID_PLATFORM
 #define LOG_TAG "BROADCOM-MESA"
index 5047ff75c55bebaeaff1f2c55888a0c5da2a00bd..d635068293697d0a283c51561a33f9057e95c416 100644 (file)
 #include "broadcom/cle/v3d_packet_v33_pack.h"
 #include "mesa/state_tracker/st_glsl_types.h"
 
+static struct v3d_compiled_shader *
+v3d_get_compiled_shader(struct v3d_context *v3d, struct v3d_key *key);
+static void
+v3d_setup_shared_precompile_key(struct v3d_uncompiled_shader *uncompiled,
+                                struct v3d_key *key);
+
 static gl_varying_slot
 v3d_get_slot_for_driver_location(nir_shader *s, uint32_t driver_location)
 {
@@ -175,6 +181,56 @@ uniforms_type_size(const struct glsl_type *type)
         return st_glsl_storage_type_size(type, false);
 }
 
+/**
+ * Precompiles a shader variant at shader state creation time if
+ * V3D_DEBUG=precompile is set.  Used for shader-db
+ * (https://gitlab.freedesktop.org/mesa/shader-db)
+ */
+static void
+v3d_shader_precompile(struct v3d_context *v3d,
+                      struct v3d_uncompiled_shader *so)
+{
+        nir_shader *s = so->base.ir.nir;
+
+        if (s->info.stage == MESA_SHADER_FRAGMENT) {
+                struct v3d_fs_key key = {
+                        .base.shader_state = so,
+                };
+
+                v3d_setup_shared_precompile_key(so, &key.base);
+                v3d_get_compiled_shader(v3d, &key.base);
+        } else {
+                struct v3d_vs_key key = {
+                        .base.shader_state = so,
+                };
+
+                v3d_setup_shared_precompile_key(so, &key.base);
+
+                /* Compile VS: All outputs */
+                for (int vary = 0; vary < 64; vary++) {
+                        if (!(s->info.outputs_written & (1ull << vary)))
+                                continue;
+                        for (int i = 0; i < 4; i++) {
+                                key.fs_inputs[key.num_fs_inputs++] =
+                                        v3d_slot_from_slot_and_component(vary,
+                                                                         i);
+                        }
+                }
+
+                v3d_get_compiled_shader(v3d, &key.base);
+
+                /* Compile VS bin shader: only position (XXX: include TF) */
+                key.is_coord = true;
+                key.num_fs_inputs = 0;
+                for (int i = 0; i < 4; i++) {
+                        key.fs_inputs[key.num_fs_inputs++] =
+                                v3d_slot_from_slot_and_component(VARYING_SLOT_POS,
+                                                                 i);
+                }
+                v3d_get_compiled_shader(v3d, &key.base);
+        }
+}
+
 static void *
 v3d_shader_state_create(struct pipe_context *pctx,
                         const struct pipe_shader_state *cso)
@@ -245,6 +301,9 @@ v3d_shader_state_create(struct pipe_context *pctx,
                 fprintf(stderr, "\n");
         }
 
+        if (V3D_DEBUG & V3D_DEBUG_PRECOMPILE)
+                v3d_shader_precompile(v3d, so);
+
         return so;
 }
 
@@ -398,6 +457,23 @@ v3d_setup_shared_key(struct v3d_context *v3d, struct v3d_key *key,
         key->ucp_enables = v3d->rasterizer->base.clip_plane_enable;
 }
 
+static void
+v3d_setup_shared_precompile_key(struct v3d_uncompiled_shader *uncompiled,
+                                struct v3d_key *key)
+{
+        nir_shader *s = uncompiled->base.ir.nir;
+
+        for (int i = 0; i < s->info.num_textures; i++) {
+                key->tex[i].return_size = 16;
+                key->tex[i].return_channels = 2;
+
+                key->tex[i].swizzle[0] = PIPE_SWIZZLE_X;
+                key->tex[i].swizzle[1] = PIPE_SWIZZLE_Y;
+                key->tex[i].swizzle[2] = PIPE_SWIZZLE_Z;
+                key->tex[i].swizzle[3] = PIPE_SWIZZLE_W;
+        }
+}
+
 static void
 v3d_update_compiled_fs(struct v3d_context *v3d, uint8_t prim_mode)
 {