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 <enga@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Jiawei Shao 2022-05-27 00:38:55 +00:00 committed by Dawn LUCI CQ
parent 8cb8c7add7
commit 57b93b4b6b
12 changed files with 53 additions and 26 deletions

View File

@ -201,8 +201,6 @@ DeviceBase::DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor)
mFormatTable = BuildFormatTable(this); mFormatTable = BuildFormatTable(this);
SetWGSLExtensionAllowList();
if (descriptor->label != nullptr && strlen(descriptor->label) != 0) { if (descriptor->label != nullptr && strlen(descriptor->label) != 0) {
mLabel = descriptor->label; mLabel = descriptor->label;
} }
@ -229,6 +227,8 @@ DeviceBase::~DeviceBase() {
} }
MaybeError DeviceBase::Initialize(Ref<QueueBase> defaultQueue) { MaybeError DeviceBase::Initialize(Ref<QueueBase> defaultQueue) {
SetWGSLExtensionAllowList();
mQueue = std::move(defaultQueue); mQueue = std::move(defaultQueue);
#if defined(DAWN_ENABLE_ASSERTS) #if defined(DAWN_ENABLE_ASSERTS)
@ -1284,16 +1284,7 @@ void DeviceBase::ApplyFeatures(const DeviceDescriptor* deviceDescriptor) {
} }
bool DeviceBase::IsFeatureEnabled(Feature feature) const { bool DeviceBase::IsFeatureEnabled(Feature feature) const {
if (mEnabledFeatures.IsEnabled(feature)) { return 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;
} }
void DeviceBase::SetWGSLExtensionAllowList() { void DeviceBase::SetWGSLExtensionAllowList() {

View File

@ -325,7 +325,6 @@ class DeviceBase : public RefCountedWithExternalCount {
std::vector<const char*> GetTogglesUsed() const; std::vector<const char*> GetTogglesUsed() const;
WGSLExtensionSet GetWGSLExtensionAllowList() const; WGSLExtensionSet GetWGSLExtensionAllowList() const;
bool IsFeatureEnabled(Feature feature) const;
bool IsToggleEnabled(Toggle toggle) const; bool IsToggleEnabled(Toggle toggle) const;
bool IsValidationEnabled() const; bool IsValidationEnabled() const;
bool IsRobustnessEnabled() const; bool IsRobustnessEnabled() const;
@ -366,6 +365,10 @@ class DeviceBase : public RefCountedWithExternalCount {
virtual bool ShouldDuplicateParametersForDrawIndirect( virtual bool ShouldDuplicateParametersForDrawIndirect(
const RenderPipelineBase* renderPipelineBase) const; 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; const CombinedLimits& GetLimits() const;
AsyncTaskManager* GetAsyncTaskManager() const; AsyncTaskManager* GetAsyncTaskManager() const;

View File

@ -781,6 +781,17 @@ bool Device::ShouldDuplicateNumWorkgroupsForDispatchIndirect(
return ToBackend(computePipeline)->UsesNumWorkgroups(); 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() { void Device::SetLabelImpl() {
SetDebugName(this, mD3d12Device.Get(), "Dawn_Device", GetLabel()); SetDebugName(this, mD3d12Device.Get(), "Dawn_Device", GetLabel());
} }

View File

@ -151,6 +151,8 @@ class Device final : public DeviceBase {
bool ShouldDuplicateParametersForDrawIndirect( bool ShouldDuplicateParametersForDrawIndirect(
const RenderPipelineBase* renderPipelineBase) const override; const RenderPipelineBase* renderPipelineBase) const override;
bool IsFeatureEnabled(Feature feature) const override;
// Dawn APIs // Dawn APIs
void SetLabelImpl() override; void SetLabelImpl() override;

View File

@ -163,6 +163,14 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
mSupportedFeatures.EnableFeature(Feature::Depth32FloatStencil8); 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) #if defined(DAWN_USE_SYNC_FDS)
// TODO(chromium:1258986): Precisely enable the feature by querying the device's format // TODO(chromium:1258986): Precisely enable the feature by querying the device's format
// features. // features.

View File

@ -14,6 +14,7 @@
#include "dawn/native/vulkan/BackendVk.h" #include "dawn/native/vulkan/BackendVk.h"
#include <algorithm>
#include <string> #include <string>
#include <utility> #include <utility>
@ -328,17 +329,7 @@ ResultOrError<VulkanGlobalKnobs> VulkanInstance::CreateVkInstance(const Instance
appInfo.applicationVersion = 0; appInfo.applicationVersion = 0;
appInfo.pEngineName = nullptr; appInfo.pEngineName = nullptr;
appInfo.engineVersion = 0; appInfo.engineVersion = 0;
// Vulkan 1.0 implementations were required to return VK_ERROR_INCOMPATIBLE_DRIVER if appInfo.apiVersion = std::min(mGlobalInfo.apiVersion, VK_MAKE_VERSION(1, 3, 0));
// 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);
}
VkInstanceCreateInfo createInfo; VkInstanceCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;

View File

@ -373,6 +373,16 @@ ResultOrError<VulkanDeviceKnobs> Device::CreateDevice(VkPhysicalDevice physicalD
featuresChain.Add(&usedKnobs.zeroInitializeWorkgroupMemoryFeatures); 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) { if (mDeviceInfo.features.samplerAnisotropy == VK_TRUE) {
usedKnobs.features.samplerAnisotropy = VK_TRUE; usedKnobs.features.samplerAnisotropy = VK_TRUE;
} }

View File

@ -152,6 +152,7 @@ static constexpr std::array<DeviceExtInfo, kDeviceExtCount> sDeviceExtInfos{{
{DeviceExt::ImageFormatList, "VK_KHR_image_format_list", VulkanVersion_1_2}, {DeviceExt::ImageFormatList, "VK_KHR_image_format_list", VulkanVersion_1_2},
{DeviceExt::ShaderFloat16Int8, "VK_KHR_shader_float16_int8", 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", {DeviceExt::ZeroInitializeWorkgroupMemory, "VK_KHR_zero_initialize_workgroup_memory",
VulkanVersion_1_3}, VulkanVersion_1_3},
@ -282,6 +283,7 @@ DeviceExtSet EnsureDependencies(const DeviceExtSet& advertisedExts,
hasDependencies = icdVersion >= VulkanVersion_1_1; hasDependencies = icdVersion >= VulkanVersion_1_1;
break; break;
case DeviceExt::ShaderIntegerDotProduct:
case DeviceExt::ZeroInitializeWorkgroupMemory: case DeviceExt::ZeroInitializeWorkgroupMemory:
hasDependencies = HasDep(DeviceExt::GetPhysicalDeviceProperties2); hasDependencies = HasDep(DeviceExt::GetPhysicalDeviceProperties2);
break; break;

View File

@ -92,6 +92,7 @@ enum class DeviceExt {
ShaderFloat16Int8, ShaderFloat16Int8,
// Promoted to 1.3 // Promoted to 1.3
ShaderIntegerDotProduct,
ZeroInitializeWorkgroupMemory, ZeroInitializeWorkgroupMemory,
// External* extensions // External* extensions

View File

@ -248,6 +248,12 @@ ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Adapter& adapter) {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES); 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 // If we have DeviceExt::GetPhysicalDeviceProperties2, use features2 and properties2 so
// that features no covered by VkPhysicalDevice{Features,Properties} can be queried. // that features no covered by VkPhysicalDevice{Features,Properties} can be queried.
// //

View File

@ -52,6 +52,7 @@ struct VulkanDeviceKnobs {
VkPhysicalDevice16BitStorageFeaturesKHR _16BitStorageFeatures; VkPhysicalDevice16BitStorageFeaturesKHR _16BitStorageFeatures;
VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroupSizeControlFeatures; VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroupSizeControlFeatures;
VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR zeroInitializeWorkgroupMemoryFeatures; VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR zeroInitializeWorkgroupMemoryFeatures;
VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR shaderIntegerDotProductFeatures;
bool HasExt(DeviceExt ext) const; bool HasExt(DeviceExt ext) const;
DeviceExtSet extensions; DeviceExtSet extensions;
@ -61,6 +62,7 @@ struct VulkanDeviceInfo : VulkanDeviceKnobs {
VkPhysicalDeviceProperties properties; VkPhysicalDeviceProperties properties;
VkPhysicalDeviceDriverProperties driverProperties; VkPhysicalDeviceDriverProperties driverProperties;
VkPhysicalDeviceSubgroupSizeControlPropertiesEXT subgroupSizeControlProperties; VkPhysicalDeviceSubgroupSizeControlPropertiesEXT subgroupSizeControlProperties;
VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR shaderIntegerDotProductProperties;
std::vector<VkQueueFamilyProperties> queueFamilies; std::vector<VkQueueFamilyProperties> queueFamilies;

View File

@ -68,7 +68,7 @@ TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) {
} }
)"; )";
if (!GetParam().mRequestDP4aExtension || !IsDP4aSupportedOnAdapter() || if (!GetParam().mRequestDP4aExtension || !IsDP4aSupportedOnAdapter() ||
!HasToggleEnabled("use_dxc")) { (IsD3D12() && !HasToggleEnabled("use_dxc"))) {
ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, computeShader)); ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, computeShader));
return; return;
} }
@ -102,5 +102,5 @@ TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) {
} }
DAWN_INSTANTIATE_TEST_P(ExperimentalDP4aTests, DAWN_INSTANTIATE_TEST_P(ExperimentalDP4aTests,
{D3D12Backend(), D3D12Backend({"use_dxc"})}, {D3D12Backend(), D3D12Backend({"use_dxc"}), VulkanBackend()},
{true, false}); {true, false});