Vulkan: Add support for LocalSizeId execution model

Vulkan version 1.2 supports Workgroup execution model. Vulkan 1.3
introduced the LocalSizeId execution model and has been backported in
the VK_KHR_maintenance4 extension. In future SPIR-V versions the
Workgroup execution model will be deprecated.

This PR checks the availability of VK_KHR_maintenance4 extension and
when enabled compile the shaders towards Vulkan 1.3. This would
automatically use the LocalSizeId execution model.

See https://registry.khronos.org/vulkan/specs/latest/man/html/WorkgroupSize.html

Pull Request: https://projects.blender.org/blender/blender/pulls/131663
This commit is contained in:
Jeroen Bakker
2024-12-10 11:06:12 +01:00
parent 5ed49184fe
commit ccab973556
3 changed files with 17 additions and 2 deletions

View File

@@ -347,6 +347,7 @@ void VKBackend::detect_workarounds(VKDevice &device)
workarounds.fragment_shader_barycentric = true;
workarounds.dynamic_rendering = true;
workarounds.dynamic_rendering_unused_attachments = true;
workarounds.local_size_execution_mode = true;
GCaps.render_pass_workaround = true;
@@ -387,6 +388,9 @@ void VKBackend::detect_workarounds(VKDevice &device)
workarounds.dynamic_rendering_unused_attachments = !device.supports_extension(
VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME);
workarounds.local_size_execution_mode = !device.supports_extension(
VK_KHR_MAINTENANCE_4_EXTENSION_NAME);
device.workarounds_ = workarounds;
}

View File

@@ -78,6 +78,14 @@ struct VKWorkarounds {
* Is the workarounds for devices that don't support Logic Ops enabled.
*/
bool logic_ops = false;
/**
* Is the workaround for devices that don't support LocalSizeId execution model enabled.
*
* This execution model has been introduced in VK_KHR_maintenance4, is core in 1.3. Previous
* (WorkgroupSize) execution model will be deprecated in SPIR-V 1.6.
*/
bool local_size_execution_mode = false;
};
/**

View File

@@ -199,10 +199,13 @@ static bool compile_ex(shaderc::Compiler &compiler,
if (read_spirv_from_disk(shader_module)) {
return true;
}
const VKDevice &device = VKBackend::get().device;
shaderc::CompileOptions options;
options.SetOptimizationLevel(shaderc_optimization_level_performance);
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_2);
options.SetTargetEnvironment(shaderc_target_env_vulkan,
device.workarounds_get().local_size_execution_mode ?
shaderc_env_version_vulkan_1_2 :
shaderc_env_version_vulkan_1_3);
if (G.debug & G_DEBUG_GPU_RENDERDOC) {
options.SetOptimizationLevel(shaderc_optimization_level_zero);
options.SetGenerateDebugInfo();