[Mesa-dev] [PATCH 5/5] anv/pipeline: Cache the pre-lowered NIR
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Thu Nov 22 16:21:27 UTC 2018
On 13/10/2018 01:08, Jason Ekstrand wrote:
> This adds a second level of caching for the pre-lowered NIR that's only
> based off of the shader module, entrypoint and specialization constants.
> This is enough for spirv_to_nir as well as our first round of lowering
> and optimization. Caching at this level should allow for faster shader
> recompiles due to state changes.
>
> The NIR caching does not get serialized to disk via either the
> VkPipelineCache serialization mechanism or the transparent on-disk
> cache. We could but it's usually not that expensive to fall back to
> SPIR-V for the odd cache miss especially if it only happens once for
> several misses and it simplifies the cache.
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
> ---
> src/intel/vulkan/anv_pipeline.c | 49 ++++++++++++++++++++++++++-------
> 1 file changed, 39 insertions(+), 10 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
> index 481921840f3..cb204f62902 100644
> --- a/src/intel/vulkan/anv_pipeline.c
> +++ b/src/intel/vulkan/anv_pipeline.c
> @@ -478,6 +478,41 @@ anv_pipeline_hash_compute(struct anv_pipeline *pipeline,
> _mesa_sha1_final(&ctx, sha1_out);
> }
>
> +static nir_shader *
> +anv_pipeline_stage_get_nir(struct anv_pipeline *pipeline,
> + struct anv_pipeline_cache *cache,
> + void *mem_ctx,
> + struct anv_pipeline_stage *stage)
> +{
> + const struct brw_compiler *compiler =
> + pipeline->device->instance->physicalDevice.compiler;
> + const nir_shader_compiler_options *nir_options =
> + compiler->glsl_compiler_options[stage->stage].NirOptions;
> + nir_shader *nir;
> +
> + nir = anv_device_search_for_nir(pipeline->device, cache,
> + nir_options,
> + stage->shader_sha1,
> + mem_ctx);
> + if (nir) {
> + assert(nir->info.stage == stage->stage);
> + return nir;
> + }
> +
> + nir = anv_shader_compile_to_nir(pipeline->device,
> + mem_ctx,
> + stage->module,
> + stage->entrypoint,
> + stage->stage,
> + stage->spec_info);
> + if (nir) {
> + anv_device_upload_nir(pipeline->device, cache, nir, stage->shader_sha1);
> + return nir;
> + }
> +
> + return NULL;
> +}
> +
> static void
> anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
> void *mem_ctx,
> @@ -985,11 +1020,9 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
> .sampler_to_descriptor = stages[s].sampler_to_descriptor
> };
>
> - stages[s].nir = anv_shader_compile_to_nir(pipeline->device, pipeline_ctx,
> - stages[s].module,
> - stages[s].entrypoint,
> - stages[s].stage,
> - stages[s].spec_info);
> + stages[s].nir = anv_pipeline_stage_get_nir(pipeline, cache,
> + pipeline_ctx,
> + &stages[s]);
> if (stages[s].nir == NULL) {
> result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
> goto fail;
> @@ -1158,11 +1191,7 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
>
> void *mem_ctx = ralloc_context(NULL);
>
> - stage.nir = anv_shader_compile_to_nir(pipeline->device, mem_ctx,
> - stage.module,
> - stage.entrypoint,
> - stage.stage,
> - stage.spec_info);
> + stage.nir = anv_pipeline_stage_get_nir(pipeline, cache, mem_ctx, &stage);
> if (stage.nir == NULL) {
> ralloc_free(mem_ctx);
> return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
More information about the mesa-dev
mailing list