vkd3d/device: Require VK_KHR_zero_initialize_workgroup_memory when appropriate.

That extension (and the corresponding feature) must be enabled when
the Initializer operand is used for workgroup variables.
This commit is contained in:
Giovanni Mascellani
2025-02-21 14:55:24 +01:00
committed by Henri Verbeet
parent e746a4c12f
commit 8297ea9aa6
Notes: Henri Verbeet 2025-02-26 16:18:05 +01:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1390
5 changed files with 24 additions and 0 deletions

View File

@@ -249,6 +249,10 @@ enum vkd3d_shader_compile_option_feature_flags
* QUAD bits set. * QUAD bits set.
* - supportedStages include COMPUTE and FRAGMENT. \since 1.12 */ * - supportedStages include COMPUTE and FRAGMENT. \since 1.12 */
VKD3D_SHADER_COMPILE_OPTION_FEATURE_WAVE_OPS = 0x00000004, VKD3D_SHADER_COMPILE_OPTION_FEATURE_WAVE_OPS = 0x00000004,
/** The SPIR-V target environment supports zero-initializing workgroup
* memory. This corresponds to the "shaderZeroInitializeWorkgroupMemory"
* Vulkan feature. \since 1.16 */
VKD3D_SHADER_COMPILE_OPTION_FEATURE_ZERO_INITIALIZE_WORKGROUP_MEMORY = 0x00000008,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS), VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS),
}; };

View File

@@ -6905,6 +6905,13 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler
const SpvStorageClass storage_class = SpvStorageClassWorkgroup; const SpvStorageClass storage_class = SpvStorageClassWorkgroup;
struct vkd3d_symbol reg_symbol; struct vkd3d_symbol reg_symbol;
if (zero_init && !(compiler->features & VKD3D_SHADER_COMPILE_OPTION_FEATURE_ZERO_INITIALIZE_WORKGROUP_MEMORY))
{
WARN("Unsupported zero-initialized workgroup memory.\n");
spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE,
"The target environment does not support zero-initialized workgroup memory.");
}
/* Alignment is supported only in the Kernel execution model. */ /* Alignment is supported only in the Kernel execution model. */
if (alignment) if (alignment)
TRACE("Ignoring alignment %u.\n", alignment); TRACE("Ignoring alignment %u.\n", alignment);

View File

@@ -97,6 +97,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor), VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor),
VK_EXTENSION(KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, KHR_sampler_mirror_clamp_to_edge), VK_EXTENSION(KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, KHR_sampler_mirror_clamp_to_edge),
VK_EXTENSION(KHR_TIMELINE_SEMAPHORE, KHR_timeline_semaphore), VK_EXTENSION(KHR_TIMELINE_SEMAPHORE, KHR_timeline_semaphore),
VK_EXTENSION(KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY, KHR_zero_initialize_workgroup_memory),
/* EXT extensions */ /* EXT extensions */
VK_EXTENSION(EXT_4444_FORMATS, EXT_4444_formats), VK_EXTENSION(EXT_4444_FORMATS, EXT_4444_formats),
VK_EXTENSION(EXT_CALIBRATED_TIMESTAMPS, EXT_calibrated_timestamps), VK_EXTENSION(EXT_CALIBRATED_TIMESTAMPS, EXT_calibrated_timestamps),
@@ -835,6 +836,7 @@ struct vkd3d_physical_device_info
VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_semaphore_features; VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_semaphore_features;
VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT mutable_features; VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT mutable_features;
VkPhysicalDevice4444FormatsFeaturesEXT formats4444_features; VkPhysicalDevice4444FormatsFeaturesEXT formats4444_features;
VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR zero_initialize_workgroup_memory_features;
VkPhysicalDeviceFeatures2 features2; VkPhysicalDeviceFeatures2 features2;
}; };
@@ -870,6 +872,8 @@ static void vkd3d_chain_physical_device_info_structures(struct vkd3d_physical_de
vk_prepend_struct(&info->features2, &info->mutable_features); vk_prepend_struct(&info->features2, &info->mutable_features);
if (vulkan_info->EXT_4444_formats) if (vulkan_info->EXT_4444_formats)
vk_prepend_struct(&info->features2, &info->formats4444_features); vk_prepend_struct(&info->features2, &info->formats4444_features);
if (vulkan_info->KHR_zero_initialize_workgroup_memory)
vk_prepend_struct(&info->features2, &info->zero_initialize_workgroup_memory_features);
info->properties2.pNext = NULL; info->properties2.pNext = NULL;
@@ -908,6 +912,7 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
info->timeline_semaphore_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR; info->timeline_semaphore_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR;
info->mutable_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT; info->mutable_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT;
info->formats4444_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; info->formats4444_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT;
info->zero_initialize_workgroup_memory_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR;
info->properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; info->properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
info->maintenance3_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES; info->maintenance3_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
@@ -1418,6 +1423,9 @@ static void vkd3d_init_feature_level(struct vkd3d_vulkan_info *vk_info,
else if (!vk_info->vertex_attrib_zero_divisor) else if (!vk_info->vertex_attrib_zero_divisor)
WARN("Vertex attribute instance rate zero divisor is not supported.\n"); WARN("Vertex attribute instance rate zero divisor is not supported.\n");
if (!vk_info->KHR_zero_initialize_workgroup_memory)
WARN("Shader zero initialize workgroup memory is not supported.\n");
#undef CHECK_MIN_REQUIREMENT #undef CHECK_MIN_REQUIREMENT
#undef CHECK_MAX_REQUIREMENT #undef CHECK_MAX_REQUIREMENT
#undef CHECK_FEATURE #undef CHECK_FEATURE
@@ -1834,6 +1842,8 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
vulkan_info->EXT_mutable_descriptor_type = false; vulkan_info->EXT_mutable_descriptor_type = false;
if (!physical_device_info->timeline_semaphore_features.timelineSemaphore) if (!physical_device_info->timeline_semaphore_features.timelineSemaphore)
vulkan_info->KHR_timeline_semaphore = false; vulkan_info->KHR_timeline_semaphore = false;
if (!physical_device_info->zero_initialize_workgroup_memory_features.shaderZeroInitializeWorkgroupMemory)
vulkan_info->KHR_zero_initialize_workgroup_memory = false;
physical_device_info->formats4444_features.formatA4B4G4R4 = VK_FALSE; physical_device_info->formats4444_features.formatA4B4G4R4 = VK_FALSE;

View File

@@ -2370,6 +2370,8 @@ static unsigned int feature_flags_compile_option(const struct d3d12_device *devi
flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64; flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64;
if (device->feature_options1.WaveOps) if (device->feature_options1.WaveOps)
flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_WAVE_OPS; flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_WAVE_OPS;
if (device->vk_info.KHR_zero_initialize_workgroup_memory)
flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_ZERO_INITIALIZE_WORKGROUP_MEMORY;
return flags; return flags;
} }

View File

@@ -132,6 +132,7 @@ struct vkd3d_vulkan_info
bool KHR_push_descriptor; bool KHR_push_descriptor;
bool KHR_sampler_mirror_clamp_to_edge; bool KHR_sampler_mirror_clamp_to_edge;
bool KHR_timeline_semaphore; bool KHR_timeline_semaphore;
bool KHR_zero_initialize_workgroup_memory;
/* EXT device extensions */ /* EXT device extensions */
bool EXT_4444_formats; bool EXT_4444_formats;
bool EXT_calibrated_timestamps; bool EXT_calibrated_timestamps;