From 855ff47d365abfc0d97061f1084f68bcff961743 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 22 Nov 2018 02:55:27 -0800 Subject: [PATCH] iris: Enable precompiles --- src/gallium/drivers/iris/iris_program.c | 158 ++++++++++++++++++++++-- src/gallium/drivers/iris/iris_screen.c | 3 + src/gallium/drivers/iris/iris_screen.h | 3 + src/gallium/drivers/iris/iris_state.c | 20 --- 4 files changed, 157 insertions(+), 27 deletions(-) diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c index 663a45c4a21..8ccbe866158 100644 --- a/src/gallium/drivers/iris/iris_program.c +++ b/src/gallium/drivers/iris/iris_program.c @@ -42,6 +42,29 @@ #include "intel/compiler/brw_nir.h" #include "iris_context.h" +#define ALL_SAMPLERS_XYZW .tex.swizzles[0 ... MAX_SAMPLERS - 1] = 0x688 +#define KEY_INIT .program_string_id = ish->program_id, ALL_SAMPLERS_XYZW + +static struct iris_compiled_shader * +iris_compile_vs(struct iris_context *, struct iris_uncompiled_shader *, + const struct brw_vs_prog_key *); +static struct iris_compiled_shader * +iris_compile_tcs(struct iris_context *, struct iris_uncompiled_shader *, + const struct brw_tcs_prog_key *); +static struct iris_compiled_shader * +iris_compile_tes(struct iris_context *, struct iris_uncompiled_shader *, + const struct brw_tes_prog_key *); +static struct iris_compiled_shader * +iris_compile_gs(struct iris_context *, struct iris_uncompiled_shader *, + const struct brw_gs_prog_key *); +static struct iris_compiled_shader * +iris_compile_fs(struct iris_context *, struct iris_uncompiled_shader *, + const struct brw_wm_prog_key *, struct brw_vue_map *); +static struct iris_compiled_shader * +iris_compile_cs(struct iris_context *, struct iris_uncompiled_shader *, + const struct brw_cs_prog_key *); + + static unsigned get_new_program_id(struct iris_screen *screen) { @@ -66,6 +89,9 @@ struct iris_uncompiled_shader { /** Bitfield of (1 << IRIS_NOS_*) flags. */ unsigned nos; + + /** Have any shader variants been compiled yet? */ + bool compiled_once; }; static nir_ssa_def * @@ -229,12 +255,20 @@ static void * iris_create_vs_state(struct pipe_context *ctx, const struct pipe_shader_state *state) { + struct iris_context *ice = (void *) ctx; + struct iris_screen *screen = (void *) ctx->screen; struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state); /* User clip planes */ if (ish->nir->info.clip_distance_array_size == 0) ish->nos |= IRIS_NOS_RASTERIZER; + if (screen->precompile) { + struct brw_vs_prog_key key = { KEY_INIT }; + + iris_compile_vs(ice, ish, &key); + } + return ish; } @@ -242,10 +276,28 @@ static void * iris_create_tcs_state(struct pipe_context *ctx, const struct pipe_shader_state *state) { + struct iris_context *ice = (void *) ctx; + struct iris_screen *screen = (void *) ctx->screen; struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state); + struct shader_info *info = &ish->nir->info; // XXX: NOS? + if (screen->precompile) { + const unsigned _GL_TRIANGLES = 0x0004; + struct brw_tcs_prog_key key = { + KEY_INIT, + // XXX: make sure the linker fills this out from the TES... + .tes_primitive_mode = + info->tess.primitive_mode ? info->tess.primitive_mode + : _GL_TRIANGLES, + .outputs_written = info->outputs_written, + .patch_outputs_written = info->patch_outputs_written, + }; + + iris_compile_tcs(ice, ish, &key); + } + return ish; } @@ -253,10 +305,24 @@ static void * iris_create_tes_state(struct pipe_context *ctx, const struct pipe_shader_state *state) { + struct iris_context *ice = (void *) ctx; + struct iris_screen *screen = (void *) ctx->screen; struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state); + struct shader_info *info = &ish->nir->info; // XXX: NOS? + if (screen->precompile) { + struct brw_tes_prog_key key = { + KEY_INIT, + // XXX: not ideal, need TCS output/TES input unification + .inputs_read = info->inputs_read, + .patch_inputs_read = info->patch_inputs_read, + }; + + iris_compile_tes(ice, ish, &key); + } + return ish; } @@ -264,10 +330,18 @@ static void * iris_create_gs_state(struct pipe_context *ctx, const struct pipe_shader_state *state) { + struct iris_context *ice = (void *) ctx; + struct iris_screen *screen = (void *) ctx->screen; struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state); // XXX: NOS? + if (screen->precompile) { + struct brw_gs_prog_key key = { KEY_INIT }; + + iris_compile_gs(ice, ish, &key); + } + return ish; } @@ -275,7 +349,10 @@ static void * iris_create_fs_state(struct pipe_context *ctx, const struct pipe_shader_state *state) { + struct iris_context *ice = (void *) ctx; + struct iris_screen *screen = (void *) ctx->screen; struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state); + struct shader_info *info = &ish->nir->info; ish->nos |= IRIS_NOS_FRAMEBUFFER | IRIS_NOS_DEPTH_STENCIL_ALPHA | @@ -288,6 +365,26 @@ iris_create_fs_state(struct pipe_context *ctx, ish->nos |= IRIS_NOS_LAST_VUE_MAP; } + if (screen->precompile) { + const uint64_t color_outputs = info->outputs_written & + ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) | + BITFIELD64_BIT(FRAG_RESULT_STENCIL) | + BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)); + + bool can_rearrange_varyings = + util_bitcount64(info->inputs_read & BRW_FS_VARYING_INPUT_MASK) <= 16; + + struct brw_wm_prog_key key = { + KEY_INIT, + .nr_color_regions = util_bitcount(color_outputs), + .coherent_fb_fetch = true, + .input_slots_valid = + can_rearrange_varyings ? 0 : info->inputs_read | VARYING_BIT_POS, + }; + + iris_compile_fs(ice, ish, &key, NULL); + } + return ish; } @@ -297,11 +394,19 @@ iris_create_compute_state(struct pipe_context *ctx, { assert(state->ir_type == PIPE_SHADER_IR_NIR); - // XXX: disallow more than 64KB of shared variables - + struct iris_context *ice = (void *) ctx; + struct iris_screen *screen = (void *) ctx->screen; struct iris_uncompiled_shader *ish = iris_create_uncompiled_shader(ctx, (void *) state->prog, NULL); + // XXX: disallow more than 64KB of shared variables + + if (screen->precompile) { + struct brw_cs_prog_key key = { KEY_INIT }; + + iris_compile_cs(ice, ish, &key); + } + return ish; } @@ -668,6 +773,12 @@ iris_compile_vs(struct iris_context *ice, iris_upload_shader(ice, IRIS_CACHE_VS, sizeof(*key), key, program, prog_data, so_decls, system_values, num_system_values); + if (ish->compiled_once) { + perf_debug(&ice->dbg, "Recompiling vertex shader\n"); + } else { + ish->compiled_once = true; + } + ralloc_free(mem_ctx); return shader; } @@ -683,7 +794,7 @@ iris_update_compiled_vs(struct iris_context *ice) struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[MESA_SHADER_VERTEX]; - struct brw_vs_prog_key key = { .program_string_id = ish->program_id }; + struct brw_vs_prog_key key = { KEY_INIT }; ice->vtbl.populate_vs_key(ice, &ish->nir->info, &key); struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_VS]; @@ -817,6 +928,14 @@ iris_compile_tcs(struct iris_context *ice, iris_upload_shader(ice, IRIS_CACHE_TCS, sizeof(*key), key, program, prog_data, NULL, system_values, num_system_values); + if (ish) { + if (ish->compiled_once) { + perf_debug(&ice->dbg, "Recompiling tessellation control shader\n"); + } else { + ish->compiled_once = true; + } + } + ralloc_free(mem_ctx); return shader; } @@ -835,6 +954,7 @@ iris_update_compiled_tcs(struct iris_context *ice) const struct shader_info *tes_info = iris_get_shader_info(ice, MESA_SHADER_TESS_EVAL); struct brw_tcs_prog_key key = { + ALL_SAMPLERS_XYZW, .program_string_id = tcs ? tcs->program_id : 0, .tes_primitive_mode = tes_info->tess.primitive_mode, .input_vertices = ice->state.vertices_per_patch, @@ -908,6 +1028,12 @@ iris_compile_tes(struct iris_context *ice, iris_upload_shader(ice, IRIS_CACHE_TES, sizeof(*key), key, program, prog_data, so_decls, system_values, num_system_values); + if (ish->compiled_once) { + perf_debug(&ice->dbg, "Recompiling tessellation evaluation shader\n"); + } else { + ish->compiled_once = true; + } + ralloc_free(mem_ctx); return shader; } @@ -923,7 +1049,7 @@ iris_update_compiled_tes(struct iris_context *ice) struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL]; - struct brw_tes_prog_key key = { .program_string_id = ish->program_id }; + struct brw_tes_prog_key key = { KEY_INIT }; get_unified_tess_slots(ice, &key.inputs_read, &key.patch_inputs_read); ice->vtbl.populate_tes_key(ice, &key); @@ -991,6 +1117,12 @@ iris_compile_gs(struct iris_context *ice, iris_upload_shader(ice, IRIS_CACHE_GS, sizeof(*key), key, program, prog_data, so_decls, system_values, num_system_values); + if (ish->compiled_once) { + perf_debug(&ice->dbg, "Recompiling geometry shader\n"); + } else { + ish->compiled_once = true; + } + ralloc_free(mem_ctx); return shader; } @@ -1009,7 +1141,7 @@ iris_update_compiled_gs(struct iris_context *ice) struct iris_compiled_shader *shader = NULL; if (ish) { - struct brw_gs_prog_key key = { .program_string_id = ish->program_id }; + struct brw_gs_prog_key key = { KEY_INIT }; ice->vtbl.populate_gs_key(ice, &key); shader = @@ -1070,6 +1202,12 @@ iris_compile_fs(struct iris_context *ice, iris_upload_shader(ice, IRIS_CACHE_FS, sizeof(*key), key, program, prog_data, NULL, system_values, num_system_values); + if (ish->compiled_once) { + perf_debug(&ice->dbg, "Recompiling fragment shader\n"); + } else { + ish->compiled_once = true; + } + ralloc_free(mem_ctx); return shader; } @@ -1084,7 +1222,7 @@ iris_update_compiled_fs(struct iris_context *ice) { struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[MESA_SHADER_FRAGMENT]; - struct brw_wm_prog_key key = { .program_string_id = ish->program_id }; + struct brw_wm_prog_key key = { KEY_INIT }; ice->vtbl.populate_fs_key(ice, &key); if (ish->nos & IRIS_NOS_LAST_VUE_MAP) @@ -1283,6 +1421,12 @@ iris_compile_cs(struct iris_context *ice, iris_upload_shader(ice, IRIS_CACHE_CS, sizeof(*key), key, program, prog_data, NULL, system_values, num_system_values); + if (ish->compiled_once) { + perf_debug(&ice->dbg, "Recompiling compute shader\n"); + } else { + ish->compiled_once = true; + } + ralloc_free(mem_ctx); return shader; } @@ -1293,7 +1437,7 @@ iris_update_compiled_compute_shader(struct iris_context *ice) struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[MESA_SHADER_COMPUTE]; - struct brw_cs_prog_key key = { .program_string_id = ish->program_id }; + struct brw_cs_prog_key key = { KEY_INIT }; ice->vtbl.populate_cs_key(ice, &key); struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_CS]; diff --git a/src/gallium/drivers/iris/iris_screen.c b/src/gallium/drivers/iris/iris_screen.c index 1216933c66d..9e1147ffc80 100644 --- a/src/gallium/drivers/iris/iris_screen.c +++ b/src/gallium/drivers/iris/iris_screen.c @@ -37,6 +37,7 @@ #include "pipe/p_state.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" +#include "util/debug.h" #include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_upload_mgr.h" @@ -565,6 +566,8 @@ iris_screen_create(int fd) brw_process_intel_debug_variable(); + screen->precompile = env_var_as_boolean("shader_precompile", true); + bool hw_has_swizzling = false; // XXX: detect? isl_device_init(&screen->isl_dev, &screen->devinfo, hw_has_swizzling); diff --git a/src/gallium/drivers/iris/iris_screen.h b/src/gallium/drivers/iris/iris_screen.h index aa510efed18..8bf10996c3f 100644 --- a/src/gallium/drivers/iris/iris_screen.h +++ b/src/gallium/drivers/iris/iris_screen.h @@ -51,6 +51,9 @@ struct iris_screen { /** Global program_string_id counter (see get_program_string_id()) */ unsigned program_id; + /** Precompile shaders at link time? (Can be disabled for debugging.) */ + bool precompile; + unsigned subslice_total; struct gen_device_info devinfo; diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 5ead5650f91..a13e6cd0b0e 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -2997,18 +2997,6 @@ iris_emit_sbe(struct iris_batch *batch, const struct iris_context *ice) /* ------------------------------------------------------------------- */ -/** - * Set sampler-related program key fields based on the current state. - */ -static void -iris_populate_sampler_key(const struct iris_context *ice, - struct brw_sampler_prog_key_data *key) -{ - for (int i = 0; i < MAX_SAMPLERS; i++) { - key->swizzles[i] = 0x688; /* XYZW */ - } -} - /** * Populate VS program key fields based on the current state. */ @@ -3019,8 +3007,6 @@ iris_populate_vs_key(const struct iris_context *ice, { const struct iris_rasterizer_state *cso_rast = ice->state.cso_rast; - iris_populate_sampler_key(ice, &key->tex); - if (info->clip_distance_array_size == 0 && (info->outputs_written & (VARYING_BIT_POS | VARYING_BIT_CLIP_VERTEX))) key->nr_userclip_plane_consts = cso_rast->num_clip_plane_consts; @@ -3033,7 +3019,6 @@ static void iris_populate_tcs_key(const struct iris_context *ice, struct brw_tcs_prog_key *key) { - iris_populate_sampler_key(ice, &key->tex); } /** @@ -3043,7 +3028,6 @@ static void iris_populate_tes_key(const struct iris_context *ice, struct brw_tes_prog_key *key) { - iris_populate_sampler_key(ice, &key->tex); } /** @@ -3053,7 +3037,6 @@ static void iris_populate_gs_key(const struct iris_context *ice, struct brw_gs_prog_key *key) { - iris_populate_sampler_key(ice, &key->tex); } /** @@ -3063,8 +3046,6 @@ static void iris_populate_fs_key(const struct iris_context *ice, struct brw_wm_prog_key *key) { - iris_populate_sampler_key(ice, &key->tex); - /* XXX: dirty flags? */ const struct pipe_framebuffer_state *fb = &ice->state.framebuffer; const struct iris_depth_stencil_alpha_state *zsa = ice->state.cso_zsa; @@ -3096,7 +3077,6 @@ static void iris_populate_cs_key(const struct iris_context *ice, struct brw_cs_prog_key *key) { - iris_populate_sampler_key(ice, &key->tex); } #if 0 -- 2.30.2