On Sun, Oct 15, 2017 at 1:36 AM, Timothy Arceri <[email protected]> wrote:
> From: Bas Nieuwenhuizen <[email protected]>
>
> This is a combined shader creation helper than will help us to
> create the shaders for each stage at once. This will allow us to
> do some link time optimisations.
>
> Signed-off-by: Timothy Arceri <[email protected]>
> ---
>  src/amd/vulkan/radv_pipeline.c       | 130 
> +++++++++++++++++++++++++++++++++++
>  src/amd/vulkan/radv_pipeline_cache.c |   3 +-
>  2 files changed, 132 insertions(+), 1 deletion(-)
>
> diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
> index 415a6cd62b..f923027036 100644
> --- a/src/amd/vulkan/radv_pipeline.c
> +++ b/src/amd/vulkan/radv_pipeline.c
> @@ -1736,20 +1736,150 @@ static void calculate_ps_inputs(struct radv_pipeline 
> *pipeline)
>
>                 flat_shade = !!(ps->info.fs.flat_shaded_mask & (1u << 
> ps_offset));
>
>                 pipeline->graphics.ps_input_cntl[ps_offset] = 
> offset_to_ps_input(vs_offset, flat_shade);
>                 ++ps_offset;
>         }
>
>         pipeline->graphics.ps_input_cntl_num = ps_offset;
>  }
>
> +static
> +void radv_create_shaders(struct radv_pipeline *pipeline,
> +                         struct radv_device *device,
> +                         struct radv_pipeline_cache *cache,
> +                         struct ac_shader_variant_key *keys,
> +                         const VkPipelineShaderStageCreateInfo **pStages)
> +{
> +       struct radv_shader_module fs_m = {0};
> +       struct radv_shader_module *modules[MESA_SHADER_STAGES] = { 0, };
> +       nir_shader *nir[MESA_SHADER_STAGES] = {0};
> +       void *codes[MESA_SHADER_STAGES] = {0};
> +       unsigned code_sizes[MESA_SHADER_STAGES] = {0};
> +       unsigned char hash[20], gs_copy_hash[20];
> +
> +       for (unsigned i = 0; i < MESA_SHADER_STAGES; ++i) {
> +               if (pStages[i]) {
> +                       modules[i] = 
> radv_shader_module_from_handle(pStages[i]->module);
> +                       if (modules[i]->nir)
> +                               _mesa_sha1_compute(modules[i]->nir->info.name,
> +                                                  
> strlen(modules[i]->nir->info.name),
> +                                                  modules[i]->sha1);
> +               }
> +       }
> +
> +       radv_hash_shaders(hash, pStages, pipeline->layout, keys, 
> get_hash_flags(device));
> +       memcpy(gs_copy_hash, hash, 20);
> +       gs_copy_hash[0] ^= 1;
> +
> +       if (modules[MESA_SHADER_GEOMETRY]) {
> +               pipeline->gs_copy_shader =
> +                       radv_create_shader_variant_from_pipeline_cache(
> +                               pipeline->device,
> +                               cache,
> +                               gs_copy_hash);
> +       }
> +
> +       if (radv_create_shader_variants_from_pipeline_cache(device, cache, 
> hash, pipeline->shaders) &&
> +           (!modules[MESA_SHADER_GEOMETRY] || pipeline->gs_copy_shader))
> +               return;
> +
> +       if (!modules[MESA_SHADER_FRAGMENT]) {
> +               nir_builder fs_b;
> +               nir_builder_init_simple_shader(&fs_b, NULL, 
> MESA_SHADER_FRAGMENT, NULL);
> +               fs_b.shader->info.name = ralloc_strdup(fs_b.shader, 
> "noop_fs");
> +               fs_m.nir = fs_b.shader;
> +               modules[MESA_SHADER_FRAGMENT] = &fs_m;
> +       }
> +
> +       for (unsigned i = 0; i < MESA_SHADER_STAGES; ++i) {
> +               const VkPipelineShaderStageCreateInfo *stage = pStages[i];
> +
> +               if (!modules[i])
> +                       continue;
> +
> +               nir[i] = radv_shader_compile_to_nir(device, modules[i],
> +                                                   stage ? stage->pName : 
> "main", i,
> +                                                   stage ? 
> stage->pSpecializationInfo : NULL);
> +               pipeline->active_stages |= mesa_to_vk_shader_stage(i);
> +       }
> +
> +       if (nir[MESA_SHADER_TESS_CTRL]) {
> +               /* TODO: This is no longer used as a key we should refactor 
> this */
> +               if (keys)
> +                       keys[MESA_SHADER_TESS_CTRL].tcs.primitive_mode = 
> nir[MESA_SHADER_TESS_EVAL]->info.tess.primitive_mode;
> +
> +               nir_lower_tes_patch_vertices(nir[MESA_SHADER_TESS_EVAL], 
> nir[MESA_SHADER_TESS_CTRL]->info.tess.tcs_vertices_out);
> +       }
> +
> +       if (nir[MESA_SHADER_FRAGMENT]) {
> +               pipeline->shaders[MESA_SHADER_FRAGMENT] =
> +                       radv_shader_variant_create(device, 
> modules[MESA_SHADER_FRAGMENT], nir[MESA_SHADER_FRAGMENT],
> +                                                  pipeline->layout, keys ? 
> keys + MESA_SHADER_FRAGMENT : 0,
> +                                                  
> &codes[MESA_SHADER_FRAGMENT], &code_sizes[MESA_SHADER_FRAGMENT]);
> +
> +               /* TODO: These are no longer used as keys we should refactor 
> this */
> +               if (keys) {
> +                       keys[MESA_SHADER_VERTEX].vs.export_prim_id =
> +                               
> pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input;
> +                       keys[MESA_SHADER_TESS_EVAL].tes.export_prim_id =
> +                               
> pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input;
> +               }
> +
> +               pipeline->active_stages |= 
> mesa_to_vk_shader_stage(MESA_SHADER_FRAGMENT);
> +       }
> +
> +       for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
> +               if(modules[i] && !pipeline->shaders[i]) {
> +                       pipeline->shaders[i] = 
> radv_shader_variant_create(device, modules[i], nir[i],
> +                                                                         
> pipeline->layout,
> +                                                                         
> keys ? keys + i : 0, &codes[i],
> +                                                                         
> &code_sizes[i]);
> +
> +               pipeline->active_stages |= mesa_to_vk_shader_stage(i);
> +               }
> +       }
> +
> +       if(modules[MESA_SHADER_GEOMETRY]) {
> +               void *gs_copy_code = NULL;
> +               unsigned gs_copy_code_size = 0;
> +               if (!pipeline->gs_copy_shader) {
> +                       pipeline->gs_copy_shader = radv_create_gs_copy_shader(
> +                                       device, nir[MESA_SHADER_GEOMETRY], 
> &gs_copy_code,
> +                                       &gs_copy_code_size,
> +                                       
> keys[MESA_SHADER_GEOMETRY].has_multiview_view_index);
> +               }
> +
> +               if (pipeline->gs_copy_shader) {
> +                       pipeline->gs_copy_shader =
> +                               radv_pipeline_cache_insert_shader(device, 
> cache,
> +                                                                 
> gs_copy_hash,
> +                                                                 
> pipeline->gs_copy_shader,
> +                                                                 
> gs_copy_code,
> +                                                                 
> gs_copy_code_size);
> +               }
> +               free(gs_copy_code);
> +       }
> +
> +       radv_pipeline_cache_insert_shaders(device, cache, hash, 
> pipeline->shaders,
> +                                          (const void**)codes, code_sizes);
> +
> +       for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
> +               free(codes[i]);
> +               if (modules[i] && !modules[i]->nir)
> +                       ralloc_free(nir[i]);
> +       }
> +
> +       if (fs_m.nir)
> +               ralloc_free(fs_m.nir);
> +}
> +
>  static VkResult
>  radv_pipeline_init(struct radv_pipeline *pipeline,
>                    struct radv_device *device,
>                    struct radv_pipeline_cache *cache,
>                    const VkGraphicsPipelineCreateInfo *pCreateInfo,
>                    const struct radv_graphics_pipeline_create_info *extra,
>                    const VkAllocationCallbacks *alloc)
>  {
>         struct radv_shader_module fs_m = {0};
>         VkResult result;
> diff --git a/src/amd/vulkan/radv_pipeline_cache.c 
> b/src/amd/vulkan/radv_pipeline_cache.c
> index feffb4e77b..7924be0c90 100644
> --- a/src/amd/vulkan/radv_pipeline_cache.c
> +++ b/src/amd/vulkan/radv_pipeline_cache.c
> @@ -470,21 +470,22 @@ radv_pipeline_cache_insert_shaders(struct radv_device 
> *device,
>         pthread_mutex_lock(&cache->mutex);
>         struct cache_entry *entry = 
> radv_pipeline_cache_search_unlocked(cache, sha1);
>         if (entry) {
>                 for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
>                         if (entry->variants[i]) {
>                                 radv_shader_variant_destroy(cache->device, 
> variants[i]);
>                                 variants[i] = entry->variants[i];
>                         } else {
>                                 entry->variants[i] = variants[i];
>                         }
> -                       p_atomic_inc(&variants[i]->ref_count);
> +                       if (variants[i])
> +                               p_atomic_inc(&variants[i]->ref_count);

I think this needs to move to an earlier patch.

>                 }
>                 pthread_mutex_unlock(&cache->mutex);
>                 return;
>         }
>         size_t size = sizeof(*entry);
>         for (int i = 0; i < MESA_SHADER_STAGES; ++i)
>                 if (variants[i])
>                         size += sizeof(struct cache_entry_variant_info) + 
> code_sizes[i];
>
>
> --
> 2.13.6
>
> _______________________________________________
> mesa-dev mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to