From fd590c2593bda2e511ba688c8881fbdb2d564774 Mon Sep 17 00:00:00 2001 From: Conor McCarthy Date: Tue, 20 Jun 2023 15:16:52 +1000 Subject: [PATCH] vkd3d: Initialise wave ops feature options. Based in part on a vkd3d-proton patch by Philip Rebohle. --- libs/vkd3d/device.c | 36 ++++++++++++++++++++++++---- libs/vkd3d/state.c | 2 ++ tests/hlsl/wave-ops-uint.shader_test | 2 +- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index cb2b6ad0..3f3332dd 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -788,6 +788,11 @@ VkInstance vkd3d_instance_get_vk_instance(struct vkd3d_instance *instance) return instance->vk_instance; } +static bool d3d12_device_environment_is_vulkan_min_1_1(struct d3d12_device *device) +{ + return device->environment == VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_1; +} + struct vkd3d_physical_device_info { /* properties */ @@ -796,6 +801,7 @@ struct vkd3d_physical_device_info VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties; VkPhysicalDeviceTransformFeedbackPropertiesEXT xfb_properties; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertex_divisor_properties; + VkPhysicalDeviceSubgroupProperties subgroup_properties; VkPhysicalDeviceProperties2KHR properties2; @@ -838,6 +844,7 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i VkPhysicalDevice4444FormatsFeaturesEXT *formats4444_features; VkPhysicalDeviceTransformFeedbackFeaturesEXT *xfb_features; struct vkd3d_vulkan_info *vulkan_info = &device->vk_info; + VkPhysicalDeviceSubgroupProperties *subgroup_properties; memset(info, 0, sizeof(*info)); conditional_rendering_features = &info->conditional_rendering_features; @@ -857,6 +864,7 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i formats4444_features = &info->formats4444_features; xfb_features = &info->xfb_features; xfb_properties = &info->xfb_properties; + subgroup_properties = &info->subgroup_properties; info->features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; @@ -902,6 +910,9 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i vk_prepend_struct(&info->properties2, xfb_properties); vertex_divisor_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT; vk_prepend_struct(&info->properties2, vertex_divisor_properties); + subgroup_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES; + if (d3d12_device_environment_is_vulkan_min_1_1(device)) + vk_prepend_struct(&info->properties2, subgroup_properties); if (vulkan_info->KHR_get_physical_device_properties2) VK_CALL(vkGetPhysicalDeviceProperties2KHR(physical_device, &info->properties2)); @@ -1509,6 +1520,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, struct vkd3d_physical_device_info *physical_device_info, uint32_t *device_extension_count, bool **user_extension_supported) { + const VkPhysicalDeviceSubgroupProperties *subgroup_properties = &physical_device_info->subgroup_properties; const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs; VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT *fragment_shader_interlock; const struct vkd3d_optional_device_extensions_info *optional_extensions; @@ -1520,6 +1532,16 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, uint32_t count; VkResult vr; + /* SHUFFLE is required to implement WaveReadLaneAt with dynamically uniform index before SPIR-V 1.5 / Vulkan 1.2. */ + static const VkSubgroupFeatureFlags required_subgroup_features = VK_SUBGROUP_FEATURE_ARITHMETIC_BIT + | VK_SUBGROUP_FEATURE_BASIC_BIT + | VK_SUBGROUP_FEATURE_BALLOT_BIT + | VK_SUBGROUP_FEATURE_SHUFFLE_BIT + | VK_SUBGROUP_FEATURE_QUAD_BIT + | VK_SUBGROUP_FEATURE_VOTE_BIT; + + static const VkSubgroupFeatureFlags required_stages = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + *device_extension_count = 0; vkd3d_trace_physical_device(physical_device, physical_device_info, vk_procs); @@ -1583,10 +1605,12 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, device->feature_options.ResourceHeapTier = D3D12_RESOURCE_HEAP_TIER_2; /* Shader Model 6 support. */ - device->feature_options1.WaveOps = FALSE; - device->feature_options1.WaveLaneCountMin = 0; - device->feature_options1.WaveLaneCountMax = 0; - device->feature_options1.TotalLaneCount = 0; + device->feature_options1.WaveOps = subgroup_properties->subgroupSize >= 4 + && (subgroup_properties->supportedOperations & required_subgroup_features) == required_subgroup_features + && (subgroup_properties->supportedStages & required_stages) == required_stages; + device->feature_options1.WaveLaneCountMin = subgroup_properties->subgroupSize; + device->feature_options1.WaveLaneCountMax = subgroup_properties->subgroupSize; + device->feature_options1.TotalLaneCount = 32 * subgroup_properties->subgroupSize; /* approx. */ device->feature_options1.ExpandedComputeResourceStates = TRUE; device->feature_options1.Int64ShaderOps = features->shaderInt64; @@ -3434,7 +3458,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device9 TRACE("Request shader model %#x.\n", data->HighestShaderModel); +#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL + data->HighestShaderModel = D3D_SHADER_MODEL_6_0; +#else data->HighestShaderModel = D3D_SHADER_MODEL_5_1; +#endif TRACE("Shader model %#x.\n", data->HighestShaderModel); return S_OK; diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 6ba29c18..199d8043 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -2159,6 +2159,8 @@ static unsigned int feature_flags_compile_option(const struct d3d12_device *devi flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64; if (device->feature_options.DoublePrecisionFloatShaderOps) flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64; + if (device->feature_options1.WaveOps) + flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_WAVE_OPS; return flags; } diff --git a/tests/hlsl/wave-ops-uint.shader_test b/tests/hlsl/wave-ops-uint.shader_test index c04b3951..033ac45b 100644 --- a/tests/hlsl/wave-ops-uint.shader_test +++ b/tests/hlsl/wave-ops-uint.shader_test @@ -81,7 +81,7 @@ void main(uint id : SV_GroupIndex) } [test] -todo dispatch 4 1 1 +dispatch 4 1 1 probe uav 1 (0) rui (1) probe uav 1 (1) rui (1) probe uav 1 (2) rui (1)