Mesa (main): vulkan: Add a vk_pipeline_hash_shader_stage() helper

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 28 09:37:15 UTC 2022


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

Author: Boris Brezillon <boris.brezillon at collabora.com>
Date:   Wed Jun 22 04:14:38 2022 -0700

vulkan: Add a vk_pipeline_hash_shader_stage() helper

All drivers implement some sort of shader hashing, but each of
them does it slightly differently. Let's provide a generic helper
to avoid new copies of the same logic and encourage new drivers
to use one of the already implemented function.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17186>

---

 src/vulkan/runtime/vk_pipeline.c | 60 ++++++++++++++++++++++++++++++++++++++++
 src/vulkan/runtime/vk_pipeline.h | 15 ++++++++++
 2 files changed, 75 insertions(+)

diff --git a/src/vulkan/runtime/vk_pipeline.c b/src/vulkan/runtime/vk_pipeline.c
index 9eac775b7f2..76d5d25aa91 100644
--- a/src/vulkan/runtime/vk_pipeline.c
+++ b/src/vulkan/runtime/vk_pipeline.c
@@ -28,6 +28,10 @@
 #include "vk_shader_module.h"
 #include "vk_util.h"
 
+#include "nir_serialize.h"
+
+#include "util/mesa-sha1.h"
+
 VkResult
 vk_pipeline_shader_stage_to_nir(struct vk_device *device,
                                 const VkPipelineShaderStageCreateInfo *info,
@@ -86,3 +90,59 @@ vk_pipeline_shader_stage_to_nir(struct vk_device *device,
 
    return VK_SUCCESS;
 }
+
+void
+vk_pipeline_hash_shader_stage(const VkPipelineShaderStageCreateInfo *info,
+                              unsigned char *stage_sha1)
+{
+   VK_FROM_HANDLE(vk_shader_module, module, info->module);
+
+   if (module && module->nir) {
+      /* Internal NIR module: serialize and hash the NIR shader.
+       * We don't need to hash other info fields since they should match the
+       * NIR data.
+       */
+      assert(module->nir->info.stage == vk_to_mesa_shader_stage(info->stage));
+      ASSERTED nir_function_impl *entrypoint = nir_shader_get_entrypoint(module->nir);
+      assert(strcmp(entrypoint->function->name, info->pName) == 0);
+      assert(info->pSpecializationInfo == NULL);
+
+      struct blob blob;
+
+      blob_init(&blob);
+      nir_serialize(&blob, module->nir, false);
+      assert(!blob.out_of_memory);
+      _mesa_sha1_compute(blob.data, blob.size, stage_sha1);
+      blob_finish(&blob);
+      return;
+   }
+
+   struct mesa_sha1 ctx;
+
+   _mesa_sha1_init(&ctx);
+   if (module) {
+      _mesa_sha1_update(&ctx, module->sha1, sizeof(module->sha1));
+   } else {
+      const VkShaderModuleCreateInfo *minfo =
+         vk_find_struct_const(info->pNext, SHADER_MODULE_CREATE_INFO);
+      unsigned char spirv_sha1[SHA1_DIGEST_LENGTH];
+
+      assert(minfo);
+      _mesa_sha1_compute(minfo->pCode, minfo->codeSize, spirv_sha1);
+      _mesa_sha1_update(&ctx, spirv_sha1, sizeof(spirv_sha1));
+   }
+
+   _mesa_sha1_update(&ctx, info->pName, strlen(info->pName));
+
+   assert(util_bitcount(info->stage) == 1);
+   _mesa_sha1_update(&ctx, &info->stage, sizeof(info->stage));
+
+   if (info->pSpecializationInfo) {
+      _mesa_sha1_update(&ctx, info->pSpecializationInfo->pMapEntries,
+                        info->pSpecializationInfo->mapEntryCount *
+                        sizeof(*info->pSpecializationInfo->pMapEntries));
+      _mesa_sha1_update(&ctx, info->pSpecializationInfo->pData,
+                        info->pSpecializationInfo->dataSize);
+   }
+   _mesa_sha1_final(&ctx, stage_sha1);
+}
diff --git a/src/vulkan/runtime/vk_pipeline.h b/src/vulkan/runtime/vk_pipeline.h
index 41f99880379..a5bff1d55e8 100644
--- a/src/vulkan/runtime/vk_pipeline.h
+++ b/src/vulkan/runtime/vk_pipeline.h
@@ -42,6 +42,21 @@ vk_pipeline_shader_stage_to_nir(struct vk_device *device,
                                 const struct nir_shader_compiler_options *nir_options,
                                 void *mem_ctx, struct nir_shader **nir_out);
 
+/** Hash VkPipelineShaderStageCreateInfo info
+ *
+ * Returns the hash of a VkPipelineShaderStageCreateInfo:
+ *    SHA1(info->module->sha1,
+ *         info->pName,
+ *         vk_stage_to_mesa_stage(info->stage),
+ *         info->pSpecializationInfo)
+ *
+ * Can only be used if VkPipelineShaderStageCreateInfo::module is a
+ * vk_shader_module object.
+ */
+void
+vk_pipeline_hash_shader_stage(const VkPipelineShaderStageCreateInfo *info,
+                              unsigned char *stage_sha1);
+
 #ifdef __cplusplus
 }
 #endif



More information about the mesa-commit mailing list