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

Author: Bas Nieuwenhuizen <[email protected]>
Date:   Wed Jan 11 01:43:14 2023 +0100

radv: Hash group handles as part of RT pipeline key.

So that we can start varying them  to avoid collisions while keeping
handles stable.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21406>

---

 src/amd/vulkan/radv_pipeline_cache.c |   6 ++-
 src/amd/vulkan/radv_pipeline_rt.c    | 102 +++++++++++++++++++----------------
 src/amd/vulkan/radv_private.h        |   4 +-
 3 files changed, 64 insertions(+), 48 deletions(-)

diff --git a/src/amd/vulkan/radv_pipeline_cache.c 
b/src/amd/vulkan/radv_pipeline_cache.c
index d3c125ca8cc..e3e179df817 100644
--- a/src/amd/vulkan/radv_pipeline_cache.c
+++ b/src/amd/vulkan/radv_pipeline_cache.c
@@ -177,7 +177,8 @@ radv_hash_rt_stages(struct mesa_sha1 *ctx, const 
VkPipelineShaderStageCreateInfo
 
 void
 radv_hash_rt_shaders(unsigned char *hash, const 
VkRayTracingPipelineCreateInfoKHR *pCreateInfo,
-                     const struct radv_pipeline_key *key, uint32_t flags)
+                     const struct radv_pipeline_key *key,
+                     const struct radv_pipeline_group_handle *group_handles, 
uint32_t flags)
 {
    RADV_FROM_HANDLE(radv_pipeline_layout, layout, pCreateInfo->layout);
    struct mesa_sha1 ctx;
@@ -190,6 +191,9 @@ radv_hash_rt_shaders(unsigned char *hash, const 
VkRayTracingPipelineCreateInfoKH
 
    radv_hash_rt_stages(&ctx, pCreateInfo->pStages, pCreateInfo->stageCount);
 
+   _mesa_sha1_update(&ctx, group_handles,
+                     sizeof(struct radv_pipeline_group_handle) * 
pCreateInfo->groupCount);
+
    for (uint32_t i = 0; i < pCreateInfo->groupCount; i++) {
       _mesa_sha1_update(&ctx, &pCreateInfo->pGroups[i].type,
                         sizeof(pCreateInfo->pGroups[i].type));
diff --git a/src/amd/vulkan/radv_pipeline_rt.c 
b/src/amd/vulkan/radv_pipeline_rt.c
index 3160b5724a9..02c783295df 100644
--- a/src/amd/vulkan/radv_pipeline_rt.c
+++ b/src/amd/vulkan/radv_pipeline_rt.c
@@ -27,6 +27,57 @@
 #include "radv_private.h"
 #include "radv_shader.h"
 
+static VkResult
+radv_create_group_handles(const VkRayTracingPipelineCreateInfoKHR *pCreateInfo,
+                          struct radv_pipeline_group_handle **out_handles)
+{
+   struct radv_pipeline_group_handle *handles = calloc(sizeof(*handles), 
pCreateInfo->groupCount);
+   if (!handles) {
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
+   }
+
+   /* For General and ClosestHit shaders, we can use the shader ID directly as 
handle.
+    * As (potentially different) AnyHit shaders are inlined, for Intersection 
shaders
+    * we use the Group ID.
+    */
+   for (unsigned i = 0; i < pCreateInfo->groupCount; ++i) {
+      const VkRayTracingShaderGroupCreateInfoKHR *group_info = 
&pCreateInfo->pGroups[i];
+      switch (group_info->type) {
+      case VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR:
+         if (group_info->generalShader != VK_SHADER_UNUSED_KHR)
+            handles[i].general_index = group_info->generalShader + 2;
+         break;
+      case VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR:
+         if (group_info->closestHitShader != VK_SHADER_UNUSED_KHR)
+            handles[i].closest_hit_index = group_info->closestHitShader + 2;
+         if (group_info->intersectionShader != VK_SHADER_UNUSED_KHR)
+            handles[i].intersection_index = i + 2;
+         break;
+      case VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR:
+         if (group_info->closestHitShader != VK_SHADER_UNUSED_KHR)
+            handles[i].closest_hit_index = group_info->closestHitShader + 2;
+         if (group_info->anyHitShader != VK_SHADER_UNUSED_KHR)
+            handles[i].any_hit_index = i + 2;
+         break;
+      case VK_SHADER_GROUP_SHADER_MAX_ENUM_KHR:
+         unreachable("VK_SHADER_GROUP_SHADER_MAX_ENUM_KHR");
+      }
+
+      if (pCreateInfo->flags &
+          
VK_PIPELINE_CREATE_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR) {
+         if (group_info->pShaderGroupCaptureReplayHandle &&
+             memcmp(group_info->pShaderGroupCaptureReplayHandle, &handles[i], 
sizeof(handles[i])) !=
+                0) {
+            free(handles);
+            return VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS;
+         }
+      }
+   }
+
+   *out_handles = handles;
+   return VK_SUCCESS;
+}
+
 static VkRayTracingPipelineCreateInfoKHR
 radv_create_merged_rt_create_info(const VkRayTracingPipelineCreateInfoKHR 
*pCreateInfo)
 {
@@ -352,12 +403,16 @@ radv_rt_pipeline_create(VkDevice _device, VkPipelineCache 
_cache,
    radv_pipeline_init(device, &rt_pipeline->base.base, 
RADV_PIPELINE_RAY_TRACING);
    rt_pipeline->group_count = local_create_info.groupCount;
 
+   result = radv_create_group_handles(&local_create_info, 
&rt_pipeline->group_handles);
+   if (result != VK_SUCCESS)
+      goto pipeline_fail;
+
    const VkPipelineCreationFeedbackCreateInfo *creation_feedback =
       vk_find_struct_const(pCreateInfo->pNext, 
PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
 
    struct radv_pipeline_key key = radv_generate_rt_pipeline_key(rt_pipeline, 
pCreateInfo->flags);
 
-   radv_hash_rt_shaders(hash, &local_create_info, &key,
+   radv_hash_rt_shaders(hash, &local_create_info, &key, 
rt_pipeline->group_handles,
                         radv_get_hash_flags(device, keep_statistic_info));
 
    /* First check if we can get things from the cache before we take the 
expensive step of
@@ -391,53 +446,8 @@ radv_rt_pipeline_create(VkDevice _device, VkPipelineCache 
_cache,
 
    radv_compute_pipeline_init(&rt_pipeline->base, pipeline_layout);
 
-   rt_pipeline->group_handles =
-      calloc(sizeof(*rt_pipeline->group_handles), 
local_create_info.groupCount);
-   if (!rt_pipeline->group_handles) {
-      result = VK_ERROR_OUT_OF_HOST_MEMORY;
-      goto shader_fail;
-   }
-
    rt_pipeline->stack_size = compute_rt_stack_size(pCreateInfo, 
rt_pipeline->stack_sizes);
 
-   /* For General and ClosestHit shaders, we can use the shader ID directly as 
handle.
-    * As (potentially different) AnyHit shaders are inlined, for Intersection 
shaders
-    * we use the Group ID.
-    */
-   for (unsigned i = 0; i < local_create_info.groupCount; ++i) {
-      const VkRayTracingShaderGroupCreateInfoKHR *group_info = 
&local_create_info.pGroups[i];
-      switch (group_info->type) {
-      case VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR:
-         if (group_info->generalShader != VK_SHADER_UNUSED_KHR)
-            rt_pipeline->group_handles[i].general_index = 
group_info->generalShader + 2;
-         break;
-      case VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR:
-         if (group_info->closestHitShader != VK_SHADER_UNUSED_KHR)
-            rt_pipeline->group_handles[i].closest_hit_index = 
group_info->closestHitShader + 2;
-         if (group_info->intersectionShader != VK_SHADER_UNUSED_KHR)
-            rt_pipeline->group_handles[i].intersection_index = i + 2;
-         break;
-      case VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR:
-         if (group_info->closestHitShader != VK_SHADER_UNUSED_KHR)
-            rt_pipeline->group_handles[i].closest_hit_index = 
group_info->closestHitShader + 2;
-         if (group_info->anyHitShader != VK_SHADER_UNUSED_KHR)
-            rt_pipeline->group_handles[i].any_hit_index = i + 2;
-         break;
-      case VK_SHADER_GROUP_SHADER_MAX_ENUM_KHR:
-         unreachable("VK_SHADER_GROUP_SHADER_MAX_ENUM_KHR");
-      }
-
-      if (pCreateInfo->flags &
-          
VK_PIPELINE_CREATE_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR) {
-         if (group_info->pShaderGroupCaptureReplayHandle &&
-             memcmp(group_info->pShaderGroupCaptureReplayHandle, 
&rt_pipeline->group_handles[i],
-                    sizeof(rt_pipeline->group_handles[i])) != 0) {
-            result = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS;
-            goto shader_fail;
-         }
-      }
-   }
-
    *pPipeline = radv_pipeline_to_handle(&rt_pipeline->base.base);
 
 shader_fail:
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index c0a2e22b856..87fca8b5d51 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1983,6 +1983,7 @@ struct radv_event {
 #define RADV_HASH_SHADER_NO_FMASK              (1 << 19)
 #define RADV_HASH_SHADER_NGG_STREAMOUT         (1 << 20)
 
+struct radv_pipeline_group_handle;
 struct radv_pipeline_key;
 
 void radv_pipeline_stage_init(const VkPipelineShaderStageCreateInfo *sinfo,
@@ -1996,7 +1997,8 @@ void radv_hash_rt_stages(struct mesa_sha1 *ctx, const 
VkPipelineShaderStageCreat
                          unsigned stage_count);
 
 void radv_hash_rt_shaders(unsigned char *hash, const 
VkRayTracingPipelineCreateInfoKHR *pCreateInfo,
-                          const struct radv_pipeline_key *key, uint32_t flags);
+                          const struct radv_pipeline_key *key,
+                          const struct radv_pipeline_group_handle 
*group_handles, uint32_t flags);
 
 uint32_t radv_get_hash_flags(const struct radv_device *device, bool stats);
 

Reply via email to