Mesa (main): radv: drop the remaining uses of shader modules

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Apr 12 06:30:38 UTC 2022


Module: Mesa
Branch: main
Commit: dca28a6355c2a4ad0661ecd7f8fe4af2feb59b32
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=dca28a6355c2a4ad0661ecd7f8fe4af2feb59b32

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Fri Apr  8 16:41:28 2022 +0200

radv: drop the remaining uses of shader modules

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 <samuel.pitoiset at gmail.com>
Reviewed-by: Timur Kristóf <timur.kristof at gmail.com>
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15847>

---

 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 473c5887459..69efd890996 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 698b30ce3a1..2358a5a781a 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 c28aa186847..49bb409ea8d 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 1d0744c015b..c7e2c1bde08 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;



More information about the mesa-commit mailing list