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.
