From dca28a6355c2a4ad0661ecd7f8fe4af2feb59b32 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 8 Apr 2022 16:41:28 +0200 Subject: [PATCH] radv: drop the remaining uses of shader modules MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit With VK_EXT_graphics_pipeline_library, shader modules can be NULL and be passed via the pNext of VkPipelineShaderStageCreateInfo. To prepare for this, just store everything we need to radv_pipeline_stage. Signed-off-by: Samuel Pitoiset Reviewed-by: Timur Kristóf Reviewed-by: Mike Blumenkrantz Part-of: --- src/amd/vulkan/radv_pipeline.c | 70 +++++++++++++++++++++++---------------- src/amd/vulkan/radv_pipeline_rt.c | 12 ++----- src/amd/vulkan/radv_private.h | 12 ++++++- src/amd/vulkan/radv_shader.c | 22 ++++++------ 4 files changed, 66 insertions(+), 50 deletions(-) diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 473c588..69efd89 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -4105,6 +4105,37 @@ radv_pipeline_hash_shader(const unsigned char *spirv_sha1, const uint32_t spirv_ _mesa_sha1_final(&ctx, sha1_out); } +void +radv_pipeline_stage_init(const VkPipelineShaderStageCreateInfo *sinfo, + struct radv_pipeline_stage *out_stage, gl_shader_stage stage) +{ + struct vk_shader_module *module = vk_shader_module_from_handle(sinfo->module); + + memset(out_stage, 0, sizeof(*out_stage)); + + out_stage->stage = stage; + out_stage->entrypoint = sinfo->pName; + out_stage->spec_info = sinfo->pSpecializationInfo; + out_stage->feedback.flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT; + + out_stage->spirv.data = module->data; + out_stage->spirv.size = module->size; + out_stage->spirv.object = &module->base; + + if (module->nir) { + out_stage->internal_nir = module->nir; + _mesa_sha1_compute(module->nir->info.name, strlen(module->nir->info.name), + out_stage->spirv.sha1); + } else { + assert(sizeof(out_stage->spirv.sha1) == sizeof(module->sha1)); + memcpy(out_stage->spirv.sha1, module->sha1, sizeof(out_stage->spirv.sha1)); + } + + radv_pipeline_hash_shader(out_stage->spirv.sha1, sizeof(out_stage->spirv.sha1), + out_stage->entrypoint, stage, out_stage->spec_info, + out_stage->shader_sha1); +} + VkResult radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout *pipeline_layout, struct radv_device *device, struct radv_pipeline_cache *cache, @@ -4141,21 +4172,7 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout const VkPipelineShaderStageCreateInfo *sinfo = &pStages[i]; gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage); - stages[stage].stage = stage; - stages[stage].module = vk_shader_module_from_handle(sinfo->module); - stages[stage].entrypoint = sinfo->pName; - stages[stage].spec_info = sinfo->pSpecializationInfo; - stages[stage].feedback.flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT; - - if (stages[stage].module->nir) { - _mesa_sha1_compute(stages[stage].module->nir->info.name, - strlen(stages[stage].module->nir->info.name), - stages[stage].module->sha1); - } - - radv_pipeline_hash_shader(stages[stage].module->sha1, sizeof(stages[stage].module->sha1), - stages[stage].entrypoint, stage, stages[stage].spec_info, - stages[stage].shader_sha1); + radv_pipeline_stage_init(sinfo, &stages[stage], stage); pipeline->active_stages |= sinfo->stage; } @@ -4169,15 +4186,15 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout } ASSERTED bool primitive_shading = - stages[MESA_SHADER_VERTEX].module || stages[MESA_SHADER_TESS_CTRL].module || - stages[MESA_SHADER_TESS_EVAL].module || stages[MESA_SHADER_GEOMETRY].module; + stages[MESA_SHADER_VERTEX].entrypoint || stages[MESA_SHADER_TESS_CTRL].entrypoint || + stages[MESA_SHADER_TESS_EVAL].entrypoint || stages[MESA_SHADER_GEOMETRY].entrypoint; ASSERTED bool mesh_shading = - stages[MESA_SHADER_MESH].module; + stages[MESA_SHADER_MESH].entrypoint; /* Primitive and mesh shading must not be mixed in the same pipeline. */ assert(!primitive_shading || !mesh_shading); /* Mesh shaders are mandatory in mesh shading pipelines. */ - assert(mesh_shading == !!stages[MESA_SHADER_MESH].module); + assert(mesh_shading == !!stages[MESA_SHADER_MESH].entrypoint); /* Mesh shaders always need NGG. */ assert(!mesh_shading || pipeline_key->use_ngg); @@ -4208,13 +4225,12 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout goto done; } - if (!stages[MESA_SHADER_FRAGMENT].module && !stages[MESA_SHADER_COMPUTE].module) { + if (!stages[MESA_SHADER_FRAGMENT].entrypoint && !stages[MESA_SHADER_COMPUTE].entrypoint) { nir_builder fs_b = radv_meta_init_shader(MESA_SHADER_FRAGMENT, "noop_fs"); - fs_m = vk_shader_module_from_nir(fs_b.shader); stages[MESA_SHADER_FRAGMENT] = (struct radv_pipeline_stage) { .stage = MESA_SHADER_FRAGMENT, - .module = &fs_m, + .internal_nir = fs_b.shader, .entrypoint = noop_fs_entrypoint, .feedback = { .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, @@ -4537,14 +4553,12 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout if (!shader) continue; - struct vk_shader_module *module = stages[i].module; - - if (!module || module->nir) + if (!stages[i].spirv.size) continue; - shader->spirv = malloc(module->size); - memcpy(shader->spirv, module->data, module->size); - shader->spirv_size = module->size; + shader->spirv = malloc(stages[i].spirv.size); + memcpy(shader->spirv, stages[i].spirv.data, stages[i].spirv.size); + shader->spirv_size = stages[i].spirv.size; } } diff --git a/src/amd/vulkan/radv_pipeline_rt.c b/src/amd/vulkan/radv_pipeline_rt.c index 698b30c..2358a5a 100644 --- a/src/amd/vulkan/radv_pipeline_rt.c +++ b/src/amd/vulkan/radv_pipeline_rt.c @@ -794,15 +794,9 @@ parse_rt_stage(struct radv_device *device, const VkPipelineShaderStageCreateInfo struct radv_pipeline_key key; memset(&key, 0, sizeof(key)); - struct radv_pipeline_stage rt_stage = { - .stage = vk_to_mesa_shader_stage(sinfo->stage), - .module = vk_shader_module_from_handle(sinfo->module), - .entrypoint = sinfo->pName, - .spec_info = sinfo->pSpecializationInfo, - .feedback = { - .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, - }, - }; + struct radv_pipeline_stage rt_stage; + + radv_pipeline_stage_init(sinfo, &rt_stage, vk_to_mesa_shader_stage(sinfo->stage)); nir_shader *shader = radv_shader_compile_to_nir(device, &rt_stage, &key); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index c28aa18..49bb409 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1746,6 +1746,9 @@ struct radv_event { struct radv_pipeline_key; +void radv_pipeline_stage_init(const VkPipelineShaderStageCreateInfo *sinfo, + struct radv_pipeline_stage *out_stage, gl_shader_stage stage); + void radv_hash_shaders(unsigned char *hash, const struct radv_pipeline_stage *stages, const struct radv_pipeline_layout *layout, const struct radv_pipeline_key *key, uint32_t flags); @@ -1928,13 +1931,20 @@ struct radv_pipeline { struct radv_pipeline_stage { gl_shader_stage stage; - struct vk_shader_module *module; + struct { + const struct vk_object_base *object; + const char *data; + uint32_t size; + unsigned char sha1[20]; + } spirv; + const char *entrypoint; const VkSpecializationInfo *spec_info; unsigned char shader_sha1[20]; nir_shader *nir; + nir_shader *internal_nir; /* meta shaders */ struct radv_shader_info info; struct radv_shader_args args; diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index 1d0744c..c7e2c1b 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -250,7 +250,7 @@ shared_var_info(const struct glsl_type *type, unsigned *size, unsigned *align) struct radv_shader_debug_data { struct radv_device *device; - const struct vk_shader_module *module; + const struct vk_object_base *object; }; static void @@ -269,7 +269,7 @@ radv_spirv_nir_debug(void *private_data, enum nir_spirv_debug_level level, size_ snprintf(buffer, sizeof(buffer), "SPIR-V offset %lu: %s", (unsigned long)spirv_offset, message); - vk_debug_report(&instance->vk, vk_flags[level], &debug_data->module->base, 0, 0, "radv", buffer); + vk_debug_report(&instance->vk, vk_flags[level], debug_data->object, 0, 0, "radv", buffer); } static void @@ -556,8 +556,6 @@ nir_shader * radv_shader_compile_to_nir(struct radv_device *device, const struct radv_pipeline_stage *stage, const struct radv_pipeline_key *key) { - struct vk_shader_module *module = stage->module; - unsigned subgroup_size = 64, ballot_bit_size = 64; if (key->cs.compute_subgroup_size) { /* Only compute shaders currently support requiring a @@ -570,29 +568,29 @@ radv_shader_compile_to_nir(struct radv_device *device, const struct radv_pipelin nir_shader *nir; - if (module->nir) { + if (stage->internal_nir) { /* Some things such as our meta clear/blit code will give us a NIR * shader directly. In that case, we just ignore the SPIR-V entirely * and just use the NIR shader. We don't want to alter meta and RT * shaders IR directly, so clone it first. */ - nir = nir_shader_clone(NULL, module->nir); + nir = nir_shader_clone(NULL, stage->internal_nir); nir->options = &device->physical_device->nir_options[stage->stage]; nir_validate_shader(nir, "in internal shader"); assert(exec_list_length(&nir->functions) == 1); } else { - uint32_t *spirv = (uint32_t *)module->data; - assert(module->size % 4 == 0); + uint32_t *spirv = (uint32_t *)stage->spirv.data; + assert(stage->spirv.size % 4 == 0); if (device->instance->debug_flags & RADV_DEBUG_DUMP_SPIRV) - radv_print_spirv(module->data, module->size, stderr); + radv_print_spirv(stage->spirv.data, stage->spirv.size, stderr); uint32_t num_spec_entries = 0; struct nir_spirv_specialization *spec_entries = vk_spec_info_to_nir_spirv(stage->spec_info, &num_spec_entries); struct radv_shader_debug_data spirv_debug_data = { .device = device, - .module = module, + .object = stage->spirv.object, }; const struct spirv_to_nir_options spirv_options = { .caps = @@ -670,7 +668,7 @@ radv_shader_compile_to_nir(struct radv_device *device, const struct radv_pipelin .private_data = &spirv_debug_data, }, }; - nir = spirv_to_nir(spirv, module->size / 4, spec_entries, num_spec_entries, stage->stage, + nir = spirv_to_nir(spirv, stage->spirv.size / 4, spec_entries, num_spec_entries, stage->stage, stage->entrypoint, &spirv_options, &device->physical_device->nir_options[stage->stage]); assert(nir->info.stage == stage->stage); @@ -1955,7 +1953,7 @@ shader_compile(struct radv_device *device, struct nir_shader *const *shaders, in struct radv_shader_debug_data debug_data = { .device = device, - .module = NULL, + .object = NULL, }; options->family = chip_family; -- 2.7.4