From 57b93b4b6bbd32c00d125eb9aaf2e90ed655dbe4 Mon Sep 17 00:00:00 2001 From: Jiawei Shao Date: Fri, 27 May 2022 00:38:55 +0000 Subject: [PATCH] Vulkan: Support feature chromium_experimental_dp4a This patch adds the support of the experimental feature chromium_experimental_dp4a on Vulkan. Currently this feature is enabled on Vulkan backend only when DP4a instructions are hardware-accelerated. Bug: tint:1497 Test: dawn_end2end_tests Change-Id: I5a63111a6b5972aa1934f0e7be984ebdb1e35080 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/91520 Reviewed-by: Austin Eng Commit-Queue: Jiawei Shao Reviewed-by: Corentin Wallez Kokoro: Kokoro --- src/dawn/native/Device.cpp | 15 +++------------ src/dawn/native/Device.h | 5 ++++- src/dawn/native/d3d12/DeviceD3D12.cpp | 11 +++++++++++ src/dawn/native/d3d12/DeviceD3D12.h | 2 ++ src/dawn/native/vulkan/AdapterVk.cpp | 8 ++++++++ src/dawn/native/vulkan/BackendVk.cpp | 13 ++----------- src/dawn/native/vulkan/DeviceVk.cpp | 10 ++++++++++ src/dawn/native/vulkan/VulkanExtensions.cpp | 2 ++ src/dawn/native/vulkan/VulkanExtensions.h | 1 + src/dawn/native/vulkan/VulkanInfo.cpp | 6 ++++++ src/dawn/native/vulkan/VulkanInfo.h | 2 ++ src/dawn/tests/end2end/ExperimentalDP4aTests.cpp | 4 ++-- 12 files changed, 53 insertions(+), 26 deletions(-) diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp index 84a9c3a500..79b94a4fb3 100644 --- a/src/dawn/native/Device.cpp +++ b/src/dawn/native/Device.cpp @@ -201,8 +201,6 @@ DeviceBase::DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor) mFormatTable = BuildFormatTable(this); - SetWGSLExtensionAllowList(); - if (descriptor->label != nullptr && strlen(descriptor->label) != 0) { mLabel = descriptor->label; } @@ -229,6 +227,8 @@ DeviceBase::~DeviceBase() { } MaybeError DeviceBase::Initialize(Ref defaultQueue) { + SetWGSLExtensionAllowList(); + mQueue = std::move(defaultQueue); #if defined(DAWN_ENABLE_ASSERTS) @@ -1284,16 +1284,7 @@ void DeviceBase::ApplyFeatures(const DeviceDescriptor* deviceDescriptor) { } bool DeviceBase::IsFeatureEnabled(Feature feature) const { - if (mEnabledFeatures.IsEnabled(feature)) { - // Currently we can only use DXC to compile HLSL shaders using float16, and - // ChromiumExperimentalDp4a is an experimental feature which can only be enabled with toggle - // "use_dxc". - if (feature == Feature::ChromiumExperimentalDp4a || feature == Feature::ShaderFloat16) { - return IsToggleEnabled(Toggle::UseDXC); - } - return true; - } - return false; + return mEnabledFeatures.IsEnabled(feature); } void DeviceBase::SetWGSLExtensionAllowList() { diff --git a/src/dawn/native/Device.h b/src/dawn/native/Device.h index af87647dcd..fd9ba57317 100644 --- a/src/dawn/native/Device.h +++ b/src/dawn/native/Device.h @@ -325,7 +325,6 @@ class DeviceBase : public RefCountedWithExternalCount { std::vector GetTogglesUsed() const; WGSLExtensionSet GetWGSLExtensionAllowList() const; - bool IsFeatureEnabled(Feature feature) const; bool IsToggleEnabled(Toggle toggle) const; bool IsValidationEnabled() const; bool IsRobustnessEnabled() const; @@ -366,6 +365,10 @@ class DeviceBase : public RefCountedWithExternalCount { virtual bool ShouldDuplicateParametersForDrawIndirect( const RenderPipelineBase* renderPipelineBase) const; + // TODO(crbug.com/dawn/1434): Make this function non-overridable when we support requesting + // Adapter with toggles. + virtual bool IsFeatureEnabled(Feature feature) const; + const CombinedLimits& GetLimits() const; AsyncTaskManager* GetAsyncTaskManager() const; diff --git a/src/dawn/native/d3d12/DeviceD3D12.cpp b/src/dawn/native/d3d12/DeviceD3D12.cpp index af021223c0..90ddc3041e 100644 --- a/src/dawn/native/d3d12/DeviceD3D12.cpp +++ b/src/dawn/native/d3d12/DeviceD3D12.cpp @@ -781,6 +781,17 @@ bool Device::ShouldDuplicateNumWorkgroupsForDispatchIndirect( return ToBackend(computePipeline)->UsesNumWorkgroups(); } +bool Device::IsFeatureEnabled(Feature feature) const { + // Currently we can only use DXC to compile HLSL shaders using float16, and + // ChromiumExperimentalDp4a is an experimental feature which can only be enabled with toggle + // "use_dxc". + if ((feature == Feature::ChromiumExperimentalDp4a || feature == Feature::ShaderFloat16) && + !IsToggleEnabled(Toggle::UseDXC)) { + return false; + } + return DeviceBase::IsFeatureEnabled(feature); +} + void Device::SetLabelImpl() { SetDebugName(this, mD3d12Device.Get(), "Dawn_Device", GetLabel()); } diff --git a/src/dawn/native/d3d12/DeviceD3D12.h b/src/dawn/native/d3d12/DeviceD3D12.h index 041bae1fdd..99b03e3964 100644 --- a/src/dawn/native/d3d12/DeviceD3D12.h +++ b/src/dawn/native/d3d12/DeviceD3D12.h @@ -151,6 +151,8 @@ class Device final : public DeviceBase { bool ShouldDuplicateParametersForDrawIndirect( const RenderPipelineBase* renderPipelineBase) const override; + bool IsFeatureEnabled(Feature feature) const override; + // Dawn APIs void SetLabelImpl() override; diff --git a/src/dawn/native/vulkan/AdapterVk.cpp b/src/dawn/native/vulkan/AdapterVk.cpp index c414c6240d..eae25ad0aa 100644 --- a/src/dawn/native/vulkan/AdapterVk.cpp +++ b/src/dawn/native/vulkan/AdapterVk.cpp @@ -163,6 +163,14 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() { mSupportedFeatures.EnableFeature(Feature::Depth32FloatStencil8); } + if (mDeviceInfo.HasExt(DeviceExt::ShaderIntegerDotProduct) && + mDeviceInfo.shaderIntegerDotProductProperties + .integerDotProduct4x8BitPackedSignedAccelerated == VK_TRUE && + mDeviceInfo.shaderIntegerDotProductProperties + .integerDotProduct4x8BitPackedUnsignedAccelerated == VK_TRUE) { + mSupportedFeatures.EnableFeature(Feature::ChromiumExperimentalDp4a); + } + #if defined(DAWN_USE_SYNC_FDS) // TODO(chromium:1258986): Precisely enable the feature by querying the device's format // features. diff --git a/src/dawn/native/vulkan/BackendVk.cpp b/src/dawn/native/vulkan/BackendVk.cpp index bc8efa9756..fc3e0e9944 100644 --- a/src/dawn/native/vulkan/BackendVk.cpp +++ b/src/dawn/native/vulkan/BackendVk.cpp @@ -14,6 +14,7 @@ #include "dawn/native/vulkan/BackendVk.h" +#include #include #include @@ -328,17 +329,7 @@ ResultOrError VulkanInstance::CreateVkInstance(const Instance appInfo.applicationVersion = 0; appInfo.pEngineName = nullptr; appInfo.engineVersion = 0; - // Vulkan 1.0 implementations were required to return VK_ERROR_INCOMPATIBLE_DRIVER if - // apiVersion was larger than 1.0. Meanwhile, as long as the instance supports at least - // Vulkan 1.1, an application can use different versions of Vulkan with an instance than - // it does with a device or physical device. So we should set apiVersion to Vulkan 1.0 - // if the instance only supports Vulkan 1.0. Otherwise we set apiVersion to Vulkan 1.2, - // treat 1.2 as the highest API version dawn targets. - if (mGlobalInfo.apiVersion == VK_MAKE_VERSION(1, 0, 0)) { - appInfo.apiVersion = VK_MAKE_VERSION(1, 0, 0); - } else { - appInfo.apiVersion = VK_MAKE_VERSION(1, 2, 0); - } + appInfo.apiVersion = std::min(mGlobalInfo.apiVersion, VK_MAKE_VERSION(1, 3, 0)); VkInstanceCreateInfo createInfo; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; diff --git a/src/dawn/native/vulkan/DeviceVk.cpp b/src/dawn/native/vulkan/DeviceVk.cpp index 2b13830093..3605dc027d 100644 --- a/src/dawn/native/vulkan/DeviceVk.cpp +++ b/src/dawn/native/vulkan/DeviceVk.cpp @@ -373,6 +373,16 @@ ResultOrError Device::CreateDevice(VkPhysicalDevice physicalD featuresChain.Add(&usedKnobs.zeroInitializeWorkgroupMemoryFeatures); } + if (mDeviceInfo.HasExt(DeviceExt::ShaderIntegerDotProduct)) { + ASSERT(usedKnobs.HasExt(DeviceExt::ShaderIntegerDotProduct)); + + usedKnobs.shaderIntegerDotProductFeatures.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES; + + usedKnobs.shaderIntegerDotProductFeatures.shaderIntegerDotProduct = VK_TRUE; + featuresChain.Add(&usedKnobs.shaderIntegerDotProductFeatures); + } + if (mDeviceInfo.features.samplerAnisotropy == VK_TRUE) { usedKnobs.features.samplerAnisotropy = VK_TRUE; } diff --git a/src/dawn/native/vulkan/VulkanExtensions.cpp b/src/dawn/native/vulkan/VulkanExtensions.cpp index 6f6ab1d3b0..b9e176ae66 100644 --- a/src/dawn/native/vulkan/VulkanExtensions.cpp +++ b/src/dawn/native/vulkan/VulkanExtensions.cpp @@ -152,6 +152,7 @@ static constexpr std::array sDeviceExtInfos{{ {DeviceExt::ImageFormatList, "VK_KHR_image_format_list", VulkanVersion_1_2}, {DeviceExt::ShaderFloat16Int8, "VK_KHR_shader_float16_int8", VulkanVersion_1_2}, + {DeviceExt::ShaderIntegerDotProduct, "VK_KHR_shader_integer_dot_product", VulkanVersion_1_3}, {DeviceExt::ZeroInitializeWorkgroupMemory, "VK_KHR_zero_initialize_workgroup_memory", VulkanVersion_1_3}, @@ -282,6 +283,7 @@ DeviceExtSet EnsureDependencies(const DeviceExtSet& advertisedExts, hasDependencies = icdVersion >= VulkanVersion_1_1; break; + case DeviceExt::ShaderIntegerDotProduct: case DeviceExt::ZeroInitializeWorkgroupMemory: hasDependencies = HasDep(DeviceExt::GetPhysicalDeviceProperties2); break; diff --git a/src/dawn/native/vulkan/VulkanExtensions.h b/src/dawn/native/vulkan/VulkanExtensions.h index 78189a13f4..c7c361a7b5 100644 --- a/src/dawn/native/vulkan/VulkanExtensions.h +++ b/src/dawn/native/vulkan/VulkanExtensions.h @@ -92,6 +92,7 @@ enum class DeviceExt { ShaderFloat16Int8, // Promoted to 1.3 + ShaderIntegerDotProduct, ZeroInitializeWorkgroupMemory, // External* extensions diff --git a/src/dawn/native/vulkan/VulkanInfo.cpp b/src/dawn/native/vulkan/VulkanInfo.cpp index ebcf3ea125..4d5ddeeb56 100644 --- a/src/dawn/native/vulkan/VulkanInfo.cpp +++ b/src/dawn/native/vulkan/VulkanInfo.cpp @@ -248,6 +248,12 @@ ResultOrError GatherDeviceInfo(const Adapter& adapter) { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES); } + if (info.extensions[DeviceExt::ShaderIntegerDotProduct]) { + propertiesChain.Add( + &info.shaderIntegerDotProductProperties, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR); + } + // If we have DeviceExt::GetPhysicalDeviceProperties2, use features2 and properties2 so // that features no covered by VkPhysicalDevice{Features,Properties} can be queried. // diff --git a/src/dawn/native/vulkan/VulkanInfo.h b/src/dawn/native/vulkan/VulkanInfo.h index 961a2adb33..39dd12d66c 100644 --- a/src/dawn/native/vulkan/VulkanInfo.h +++ b/src/dawn/native/vulkan/VulkanInfo.h @@ -52,6 +52,7 @@ struct VulkanDeviceKnobs { VkPhysicalDevice16BitStorageFeaturesKHR _16BitStorageFeatures; VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroupSizeControlFeatures; VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR zeroInitializeWorkgroupMemoryFeatures; + VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR shaderIntegerDotProductFeatures; bool HasExt(DeviceExt ext) const; DeviceExtSet extensions; @@ -61,6 +62,7 @@ struct VulkanDeviceInfo : VulkanDeviceKnobs { VkPhysicalDeviceProperties properties; VkPhysicalDeviceDriverProperties driverProperties; VkPhysicalDeviceSubgroupSizeControlPropertiesEXT subgroupSizeControlProperties; + VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR shaderIntegerDotProductProperties; std::vector queueFamilies; diff --git a/src/dawn/tests/end2end/ExperimentalDP4aTests.cpp b/src/dawn/tests/end2end/ExperimentalDP4aTests.cpp index e789c07c73..5e8900eac0 100644 --- a/src/dawn/tests/end2end/ExperimentalDP4aTests.cpp +++ b/src/dawn/tests/end2end/ExperimentalDP4aTests.cpp @@ -68,7 +68,7 @@ TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) { } )"; if (!GetParam().mRequestDP4aExtension || !IsDP4aSupportedOnAdapter() || - !HasToggleEnabled("use_dxc")) { + (IsD3D12() && !HasToggleEnabled("use_dxc"))) { ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, computeShader)); return; } @@ -102,5 +102,5 @@ TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) { } DAWN_INSTANTIATE_TEST_P(ExperimentalDP4aTests, - {D3D12Backend(), D3D12Backend({"use_dxc"})}, + {D3D12Backend(), D3D12Backend({"use_dxc"}), VulkanBackend()}, {true, false});