Added few more stubs so that control reaches to DestroyDevice().
[mesa.git] / src / gallium / drivers / freedreno / ir3 / ir3_gallium.c
index b52328e2f069d7e384462cd5140572ed08cee7b5..810c3b2051ef35b023722725d1f3321747fd8520 100644 (file)
@@ -44,8 +44,7 @@
 #include "ir3/ir3_nir.h"
 
 static void
-dump_shader_info(struct ir3_shader_variant *v, bool binning_pass,
-               struct pipe_debug_callback *debug)
+dump_shader_info(struct ir3_shader_variant *v, struct pipe_debug_callback *debug)
 {
        if (!unlikely(fd_mesa_debug & FD_DBG_SHADERDB))
                return;
@@ -53,6 +52,7 @@ dump_shader_info(struct ir3_shader_variant *v, bool binning_pass,
        pipe_debug_message(debug, SHADER_INFO,
                        "%s shader: %u inst, %u nops, %u non-nops, %u mov, %u cov, "
                        "%u dwords, %u last-baryf, %u half, %u full, %u constlen, "
+                       "%u cat0, %u cat1, %u cat2, %u cat3, %u cat4, %u cat5, %u cat6, %u cat7, "
                        "%u sstall, %u (ss), %u (sy), %d max_sun, %d loops\n",
                        ir3_shader_stage(v),
                        v->info.instrs_count,
@@ -65,11 +65,40 @@ dump_shader_info(struct ir3_shader_variant *v, bool binning_pass,
                        v->info.max_half_reg + 1,
                        v->info.max_reg + 1,
                        v->constlen,
+                       v->info.instrs_per_cat[0],
+                       v->info.instrs_per_cat[1],
+                       v->info.instrs_per_cat[2],
+                       v->info.instrs_per_cat[3],
+                       v->info.instrs_per_cat[4],
+                       v->info.instrs_per_cat[5],
+                       v->info.instrs_per_cat[6],
+                       v->info.instrs_per_cat[7],
                        v->info.sstall,
                        v->info.ss, v->info.sy,
                        v->max_sun, v->loops);
 }
 
+static void
+upload_shader_variant(struct ir3_shader_variant *v)
+{
+       struct shader_info *info = &v->shader->nir->info;
+       struct ir3_compiler *compiler = v->shader->compiler;
+
+       assert(!v->bo);
+
+       unsigned sz = v->info.sizedwords * 4;
+
+       v->bo = fd_bo_new(compiler->dev, sz,
+                       DRM_FREEDRENO_GEM_CACHE_WCOMBINE |
+                       DRM_FREEDRENO_GEM_TYPE_KMEM,
+                       "%s:%s", ir3_shader_stage(v), info->name);
+
+       /* Always include shaders in kernel crash dumps. */
+       fd_bo_mark_for_dump(v->bo);
+
+       memcpy(fd_bo_map(v->bo), v->bin, sz);
+}
+
 struct ir3_shader_variant *
 ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key,
                bool binning_pass, struct pipe_debug_callback *debug)
@@ -77,16 +106,34 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key,
        struct ir3_shader_variant *v;
        bool created = false;
 
-       /* some shader key values only apply to vertex or frag shader,
-        * so normalize the key to avoid constructing multiple identical
-        * variants:
+       /* Some shader key values may not be used by a given ir3_shader (for
+        * example, fragment shader saturates in the vertex shader), so clean out
+        * those flags to avoid recompiling.
         */
-       ir3_normalize_key(&key, shader->type);
+       ir3_key_clear_unused(&key, shader);
 
        v = ir3_shader_get_variant(shader, &key, binning_pass, &created);
 
        if (created) {
-               dump_shader_info(v, binning_pass, debug);
+               if (shader->initial_variants_done) {
+                       pipe_debug_message(debug, SHADER_INFO,
+                                       "%s shader: recompiling at draw time: global 0x%08x, vsats %x/%x/%x, fsats %x/%x/%x, vfsamples %x/%x, astc %x/%x\n",
+                                       ir3_shader_stage(v),
+                                       key.global,
+                                       key.vsaturate_s, key.vsaturate_t, key.vsaturate_r,
+                                       key.fsaturate_s, key.fsaturate_t, key.fsaturate_r,
+                                       key.vsamples, key.fsamples,
+                                       key.vastc_srgb, key.fastc_srgb);
+
+               }
+
+               dump_shader_info(v, debug);
+               upload_shader_variant(v);
+
+               if (v->binning) {
+                       upload_shader_variant(v->binning);
+                       dump_shader_info(v->binning, debug);
+               }
        }
 
        return v;
@@ -128,26 +175,71 @@ ir3_shader_create(struct ir3_compiler *compiler,
                if (ir3_shader_debug & IR3_DBG_DISASM) {
                        tgsi_dump(cso->tokens, 0);
                }
-               nir = tgsi_to_nir(cso->tokens, screen);
+               nir = tgsi_to_nir(cso->tokens, screen, false);
        }
 
        struct ir3_stream_output_info stream_output;
        copy_stream_out(&stream_output, &cso->stream_output);
 
-       struct ir3_shader *shader = ir3_shader_from_nir(compiler, nir, &stream_output);
+       struct ir3_shader *shader = ir3_shader_from_nir(compiler, nir, 0, &stream_output);
+
+       /* Compile standard variants immediately to try to avoid draw-time stalls
+        * to run the compiler.
+        */
+       struct ir3_shader_key key = {
+               .tessellation = IR3_TESS_NONE,
+               .msaa = true,
+       };
+
+       switch (nir->info.stage) {
+       case MESA_SHADER_TESS_EVAL:
+               key.tessellation = ir3_tess_mode(nir->info.tess.primitive_mode);
+               break;
 
-       if (fd_mesa_debug & FD_DBG_SHADERDB) {
-               /* if shader-db run, create a standard variant immediately
-                * (as otherwise nothing will trigger the shader to be
-                * actually compiled)
+       case MESA_SHADER_TESS_CTRL:
+               /* The primitive_mode field, while it exists for TCS, is not
+                * populated (since separable shaders between TCS/TES are legal,
+                * so TCS wouldn't have access to TES's declaration).  Make a
+                * guess so that we shader-db something plausible for TCS.
                 */
-               static struct ir3_shader_key key; /* static is implicitly zeroed */
+               if (nir->info.outputs_written & VARYING_BIT_TESS_LEVEL_INNER)
+                       key.tessellation = IR3_TESS_TRIANGLES;
+               else
+                       key.tessellation = IR3_TESS_ISOLINES;
+               break;
+
+       case MESA_SHADER_GEOMETRY:
+               key.has_gs = true;
+               break;
+
+       default:
+               break;
+       }
+
+       key.safe_constlen = false;
+       struct ir3_shader_variant *v = ir3_shader_variant(shader, key, false, debug);
+       if (!v)
+               return NULL;
+
+       if (v->constlen > compiler->max_const_safe) {
+               key.safe_constlen = true;
                ir3_shader_variant(shader, key, false, debug);
+       }
+
+       if (nir->info.stage == MESA_SHADER_VERTEX) {
+               key.safe_constlen = false;
+               v = ir3_shader_variant(shader, key, true, debug);
+               if (!v)
+                       return NULL;
 
-               if (nir->info.stage != MESA_SHADER_FRAGMENT)
+               if (v->constlen > compiler->max_const_safe) {
+                       key.safe_constlen = true;
                        ir3_shader_variant(shader, key, true, debug);
+               }
        }
 
+       shader->initial_variants_done = true;
+
        return shader;
 }
 
@@ -169,24 +261,24 @@ ir3_shader_create_compute(struct ir3_compiler *compiler,
                if (ir3_shader_debug & IR3_DBG_DISASM) {
                        tgsi_dump(cso->prog, 0);
                }
-               nir = tgsi_to_nir(cso->prog, screen);
+               nir = tgsi_to_nir(cso->prog, screen, false);
        }
 
-       struct ir3_shader *shader = ir3_shader_from_nir(compiler, nir, NULL);
+       struct ir3_shader *shader = ir3_shader_from_nir(compiler, nir, 0, NULL);
 
-       if (fd_mesa_debug & FD_DBG_SHADERDB) {
-               /* if shader-db run, create a standard variant immediately
-                * (as otherwise nothing will trigger the shader to be
-                * actually compiled)
-                */
-               static struct ir3_shader_key key; /* static is implicitly zeroed */
-               ir3_shader_variant(shader, key, false, debug);
-       }
+       /* Immediately compile a standard variant.  We have so few variants in our
+        * shaders, that doing so almost eliminates draw-time recompiles.  (This
+        * is also how we get data from shader-db's ./run)
+        */
+       static struct ir3_shader_key key; /* static is implicitly zeroed */
+       ir3_shader_variant(shader, key, false, debug);
+
+       shader->initial_variants_done = true;
 
        return shader;
 }
 
-static void *
+void *
 ir3_shader_state_create(struct pipe_context *pctx, const struct pipe_shader_state *cso)
 {
        struct fd_context *ctx = fd_context(pctx);
@@ -194,13 +286,35 @@ ir3_shader_state_create(struct pipe_context *pctx, const struct pipe_shader_stat
        return ir3_shader_create(compiler, cso, &ctx->debug, pctx->screen);
 }
 
-static void
+void
 ir3_shader_state_delete(struct pipe_context *pctx, void *hwcso)
 {
        struct ir3_shader *so = hwcso;
+
+       /* free the uploaded shaders, since this is handled outside of the
+        * shared ir3 code (ie. not used by turnip):
+        */
+       for (struct ir3_shader_variant *v = so->variants; v; v = v->next) {
+               fd_bo_del(v->bo);
+               v->bo = NULL;
+
+               if (v->binning && v->binning->bo) {
+                       fd_bo_del(v->binning->bo);
+                       v->binning->bo = NULL;
+               }
+       }
+
        ir3_shader_destroy(so);
 }
 
+static void
+ir3_screen_finalize_nir(struct pipe_screen *pscreen, void *nir, bool optimize)
+{
+       struct fd_screen *screen = fd_screen(pscreen);
+
+       ir3_finalize_nir(screen->compiler, nir);
+}
+
 void
 ir3_prog_init(struct pipe_context *pctx)
 {
@@ -219,3 +333,9 @@ ir3_prog_init(struct pipe_context *pctx)
        pctx->create_fs_state = ir3_shader_state_create;
        pctx->delete_fs_state = ir3_shader_state_delete;
 }
+
+void
+ir3_screen_init(struct pipe_screen *pscreen)
+{
+       pscreen->finalize_nir = ir3_screen_finalize_nir;
+}