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

Author: Joshua Ashton <[email protected]>
Date:   Wed Jun 28 18:34:31 2023 +0100

radv: Implement VK_EXT_pipeline_robustness

Funnel the data from the pNext into the new pipeline key members for buffer 
robustness

Signed-off-by: Joshua Ashton <[email protected]>
Reviewed-by: Friedrich Vock <[email protected]>
Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23912>

---

 src/amd/vulkan/radv_pipeline.c          | 58 +++++++++++++++++++++++++++++----
 src/amd/vulkan/radv_pipeline_compute.c  |  3 +-
 src/amd/vulkan/radv_pipeline_graphics.c |  4 +--
 src/amd/vulkan/radv_pipeline_rt.c       | 36 ++++++++++++++++++--
 src/amd/vulkan/radv_private.h           |  7 +++-
 src/amd/vulkan/radv_shader.h            |  8 +++--
 src/amd/vulkan/radv_shader_info.c       |  3 +-
 7 files changed, 101 insertions(+), 18 deletions(-)

diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index 4aebe72956b..67c08b92441 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -140,10 +140,27 @@ radv_pipeline_init_scratch(const struct radv_device 
*device, struct radv_pipelin
    pipeline->max_waves = MAX2(pipeline->max_waves, max_stage_waves);
 }
 
+static enum radv_buffer_robustness
+radv_convert_buffer_robustness(const struct radv_device *device, 
VkPipelineRobustnessBufferBehaviorEXT behaviour)
+{
+   switch (behaviour) {
+   case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT:
+      return device->buffer_robustness;
+   case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT:
+      return RADV_BUFFER_ROBUSTNESS_DISABLED;
+   case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT:
+      return RADV_BUFFER_ROBUSTNESS_1;
+   case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT:
+      return RADV_BUFFER_ROBUSTNESS_2;
+   default:
+      unreachable("Invalid pipeline robustness behavior");
+   }
+}
+
 struct radv_pipeline_key
 radv_generate_pipeline_key(const struct radv_device *device, const struct 
radv_pipeline *pipeline,
                            const VkPipelineShaderStageCreateInfo *stages, 
const unsigned num_stages,
-                           VkPipelineCreateFlags flags)
+                           VkPipelineCreateFlags flags, const void *pNext)
 {
    struct radv_pipeline_key key;
 
@@ -179,9 +196,38 @@ radv_generate_pipeline_key(const struct radv_device 
*device, const struct radv_p
       }
    }
 
-   key.storage_robustness = device->buffer_robustness;
-   key.uniform_robustness = device->buffer_robustness;
-   key.vertex_robustness = device->buffer_robustness;
+   const VkPipelineRobustnessCreateInfoEXT *pipeline_robust_info =
+      vk_find_struct_const(pNext, PIPELINE_ROBUSTNESS_CREATE_INFO_EXT);
+
+   for (uint32_t i = 0; i < num_stages; i++) {
+      gl_shader_stage stage = vk_to_mesa_shader_stage(stages[i].stage);
+      const VkPipelineRobustnessCreateInfoEXT *stage_robust_info =
+         vk_find_struct_const(stages[i].pNext, 
PIPELINE_ROBUSTNESS_CREATE_INFO_EXT);
+
+      /* map any hit to intersection as these shaders get merged */
+      if (stage == MESA_SHADER_ANY_HIT)
+         stage = MESA_SHADER_INTERSECTION;
+
+      enum radv_buffer_robustness storage_robustness = 
device->buffer_robustness;
+      enum radv_buffer_robustness uniform_robustness = 
device->buffer_robustness;
+      enum radv_buffer_robustness vertex_robustness = 
device->buffer_robustness;
+
+      const VkPipelineRobustnessCreateInfoEXT *robust_info =
+         stage_robust_info ? stage_robust_info : pipeline_robust_info;
+
+      if (robust_info) {
+         storage_robustness = radv_convert_buffer_robustness(device, 
robust_info->storageBuffers);
+         uniform_robustness = radv_convert_buffer_robustness(device, 
robust_info->uniformBuffers);
+         vertex_robustness = radv_convert_buffer_robustness(device, 
robust_info->vertexInputs);
+      }
+
+      if (storage_robustness >= RADV_BUFFER_ROBUSTNESS_2)
+         key.stage_info[stage].storage_robustness2 = 1;
+      if (uniform_robustness >= RADV_BUFFER_ROBUSTNESS_2)
+         key.stage_info[stage].uniform_robustness2 = 1;
+      if (stage == MESA_SHADER_VERTEX && vertex_robustness >= 
RADV_BUFFER_ROBUSTNESS_1)
+         key.vertex_robustness1 = 1u;
+   }
 
    return key;
 }
@@ -509,10 +555,10 @@ radv_postprocess_nir(struct radv_device *device, const 
struct radv_pipeline_layo
       .has_shared2_amd = gfx_level >= GFX7,
    };
 
-   if (pipeline_key->uniform_robustness >= RADV_BUFFER_ROBUSTNESS_2)
+   if (pipeline_key->stage_info[stage->stage].uniform_robustness2)
       vectorize_opts.robust_modes |= nir_var_mem_ubo;
 
-   if (pipeline_key->storage_robustness >= RADV_BUFFER_ROBUSTNESS_2)
+   if (pipeline_key->stage_info[stage->stage].storage_robustness2)
       vectorize_opts.robust_modes |= nir_var_mem_ssbo;
 
    if (!pipeline_key->optimisations_disabled) {
diff --git a/src/amd/vulkan/radv_pipeline_compute.c 
b/src/amd/vulkan/radv_pipeline_compute.c
index 4b015c15daf..dfb7b1994e5 100644
--- a/src/amd/vulkan/radv_pipeline_compute.c
+++ b/src/amd/vulkan/radv_pipeline_compute.c
@@ -116,7 +116,8 @@ static struct radv_pipeline_key
 radv_generate_compute_pipeline_key(const struct radv_device *device, struct 
radv_compute_pipeline *pipeline,
                                    const VkComputePipelineCreateInfo 
*pCreateInfo)
 {
-   return radv_generate_pipeline_key(device, &pipeline->base, 
&pCreateInfo->stage, 1, pCreateInfo->flags);
+   return radv_generate_pipeline_key(device, &pipeline->base, 
&pCreateInfo->stage, 1, pCreateInfo->flags,
+                                     pCreateInfo->pNext);
 }
 
 void
diff --git a/src/amd/vulkan/radv_pipeline_graphics.c 
b/src/amd/vulkan/radv_pipeline_graphics.c
index 5ca0732a427..57193c8d6ff 100644
--- a/src/amd/vulkan/radv_pipeline_graphics.c
+++ b/src/amd/vulkan/radv_pipeline_graphics.c
@@ -1817,8 +1817,8 @@ radv_generate_graphics_pipeline_key(const struct 
radv_device *device, const stru
                                     VkGraphicsPipelineLibraryFlagBitsEXT 
lib_flags)
 {
    const struct radv_physical_device *pdevice = device->physical_device;
-   struct radv_pipeline_key key = radv_generate_pipeline_key(device, 
&pipeline->base, pCreateInfo->pStages,
-                                                             
pCreateInfo->stageCount, pCreateInfo->flags);
+   struct radv_pipeline_key key = radv_generate_pipeline_key(
+      device, &pipeline->base, pCreateInfo->pStages, pCreateInfo->stageCount, 
pCreateInfo->flags, pCreateInfo->pNext);
 
    key.lib_flags = lib_flags;
    key.has_multiview_view_index = state->rp ? !!state->rp->view_mask : 0;
diff --git a/src/amd/vulkan/radv_pipeline_rt.c 
b/src/amd/vulkan/radv_pipeline_rt.c
index c7ece85a061..2219fad36fb 100644
--- a/src/amd/vulkan/radv_pipeline_rt.c
+++ b/src/amd/vulkan/radv_pipeline_rt.c
@@ -82,6 +82,30 @@ handle_from_stages(struct radv_device *device, struct 
radv_ray_tracing_stage *st
    return ret;
 }
 
+static struct radv_pipeline_key
+radv_generate_rt_pipeline_key(const struct radv_device *device, const struct 
radv_ray_tracing_pipeline *rt_pipeline,
+                              const VkRayTracingPipelineCreateInfoKHR 
*pCreateInfo)
+{
+   struct radv_pipeline_key key =
+      radv_generate_pipeline_key(device, &rt_pipeline->base.base, 
pCreateInfo->pStages, pCreateInfo->stageCount,
+                                 pCreateInfo->flags, pCreateInfo->pNext);
+
+   if (pCreateInfo->pLibraryInfo) {
+      for (unsigned i = 0; i < pCreateInfo->pLibraryInfo->libraryCount; ++i) {
+         RADV_FROM_HANDLE(radv_pipeline, pipeline, 
pCreateInfo->pLibraryInfo->pLibraries[i]);
+         struct radv_ray_tracing_pipeline *library_pipeline = 
radv_pipeline_to_ray_tracing(pipeline);
+         /* apply shader robustness from merged shaders */
+         if (library_pipeline->traversal_storage_robustness2)
+            key.stage_info[MESA_SHADER_INTERSECTION].storage_robustness2 = 
true;
+
+         if (library_pipeline->traversal_uniform_robustness2)
+            key.stage_info[MESA_SHADER_INTERSECTION].uniform_robustness2 = 
true;
+      }
+   }
+
+   return key;
+}
+
 static VkResult
 radv_create_group_handles(struct radv_device *device, const 
VkRayTracingPipelineCreateInfoKHR *pCreateInfo,
                           struct radv_ray_tracing_stage *stages, struct 
radv_ray_tracing_group *groups)
@@ -184,7 +208,7 @@ radv_rt_fill_group_info(struct radv_device *device, const 
VkRayTracingPipelineCr
 
 static void
 radv_rt_fill_stage_info(struct radv_device *device, const 
VkRayTracingPipelineCreateInfoKHR *pCreateInfo,
-                        struct radv_ray_tracing_stage *stages, const struct 
radv_pipeline_key *key)
+                        struct radv_ray_tracing_stage *stages, struct 
radv_pipeline_key *key)
 {
    uint32_t idx;
    for (idx = 0; idx < pCreateInfo->stageCount; idx++) {
@@ -549,8 +573,14 @@ radv_rt_pipeline_create(VkDevice _device, VkPipelineCache 
_cache, const VkRayTra
    pipeline->stages = stages;
    pipeline->groups = groups;
 
-   struct radv_pipeline_key key = radv_generate_pipeline_key(device, 
&pipeline->base.base, pCreateInfo->pStages,
-                                                             
pCreateInfo->stageCount, pCreateInfo->flags);
+   struct radv_pipeline_key key = radv_generate_rt_pipeline_key(device, 
pipeline, pCreateInfo);
+
+   /* cache robustness state for making merged shaders */
+   if (key.stage_info[MESA_SHADER_INTERSECTION].storage_robustness2)
+      pipeline->traversal_storage_robustness2 = true;
+
+   if (key.stage_info[MESA_SHADER_INTERSECTION].uniform_robustness2)
+      pipeline->traversal_uniform_robustness2 = true;
 
    radv_rt_fill_stage_info(device, pCreateInfo, stages, &key);
    result = radv_rt_fill_group_info(device, pCreateInfo, stages, 
pipeline->groups);
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 81969f84bf1..bae312e4812 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -2340,6 +2340,10 @@ struct radv_ray_tracing_pipeline {
 
    uint8_t sha1[SHA1_DIGEST_LENGTH];
    uint32_t stack_size;
+
+   /* set if any shaders from this pipeline require robustness2 in the merged 
traversal shader */
+   bool traversal_storage_robustness2 : 1;
+   bool traversal_uniform_robustness2 : 1;
 };
 
 struct radv_graphics_lib_pipeline {
@@ -2437,7 +2441,8 @@ struct radv_graphics_pipeline_create_info {
 struct radv_pipeline_key radv_generate_pipeline_key(const struct radv_device 
*device,
                                                     const struct radv_pipeline 
*pipeline,
                                                     const 
VkPipelineShaderStageCreateInfo *stages,
-                                                    const unsigned num_stages, 
VkPipelineCreateFlags flags);
+                                                    const unsigned num_stages, 
VkPipelineCreateFlags flags,
+                                                    const void *pNext);
 
 void radv_pipeline_init(struct radv_device *device, struct radv_pipeline 
*pipeline, enum radv_pipeline_type type);
 
diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h
index 12042740e43..b0438afa279 100644
--- a/src/amd/vulkan/radv_shader.h
+++ b/src/amd/vulkan/radv_shader.h
@@ -58,6 +58,9 @@ enum radv_required_subgroup_size {
 struct radv_shader_stage_key {
    uint8_t subgroup_required_size : 2; /* radv_required_subgroup_size */
    uint8_t subgroup_require_full : 1;  /* whether full subgroups are required 
*/
+
+   uint8_t storage_robustness2 : 1;
+   uint8_t uniform_robustness2 : 1;
 };
 
 struct radv_ps_epilog_key {
@@ -92,10 +95,9 @@ struct radv_pipeline_key {
    uint32_t enable_remove_point_size : 1;
    uint32_t unknown_rast_prim : 1;
 
+   uint32_t vertex_robustness1 : 1;
+
    struct radv_shader_stage_key stage_info[MESA_VULKAN_SHADER_STAGES];
-   uint32_t storage_robustness : 2;
-   uint32_t uniform_robustness : 2;
-   uint32_t vertex_robustness : 2;
 
    struct {
       uint32_t instance_rate_inputs;
diff --git a/src/amd/vulkan/radv_shader_info.c 
b/src/amd/vulkan/radv_shader_info.c
index 96474244b4e..ff8c99fb02f 100644
--- a/src/amd/vulkan/radv_shader_info.c
+++ b/src/amd/vulkan/radv_shader_info.c
@@ -414,8 +414,7 @@ gather_shader_info_vs(struct radv_device *device, const 
nir_shader *nir, const s
    }
 
    /* Use per-attribute vertex descriptors to prevent faults and for correct 
bounds checking. */
-   info->vs.use_per_attribute_vb_descs =
-      pipeline_key->vertex_robustness >= RADV_BUFFER_ROBUSTNESS_1 || 
info->vs.dynamic_inputs;
+   info->vs.use_per_attribute_vb_descs = pipeline_key->vertex_robustness1 || 
info->vs.dynamic_inputs;
 
    /* We have to ensure consistent input register assignments between the main 
shader and the
     * prolog.

Reply via email to