webgpu.h: Add subgroupMinSize and subgroupMaxSize to AdapterInfo
Spec PR: https://github.com/webgpu-native/webgpu-headers/pull/509
Change-Id: I5510a054304d802dfbcbfe1a03ef8f2e6db36032
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/223876
Reviewed-by: Alan Baker <alanbaker@google.com>
Commit-Queue: Fr <beaufort.francois@gmail.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 99561d5..cffc024 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -181,6 +181,8 @@
{"name": "adapter type", "type": "adapter type"},
{"name": "vendor ID", "type": "uint32_t"},
{"name": "device ID", "type": "uint32_t"},
+ {"name": "subgroup min size", "type": "uint32_t"},
+ {"name": "subgroup max size", "type": "uint32_t"},
{"name": "compatibility mode", "type": "bool", "default": "false", "tags": ["dawn", "emscripten"]}
]
},
diff --git a/src/dawn/native/Adapter.cpp b/src/dawn/native/Adapter.cpp
index 811c44c..48e5162 100644
--- a/src/dawn/native/Adapter.cpp
+++ b/src/dawn/native/Adapter.cpp
@@ -235,8 +235,15 @@
info->adapterType = mPhysicalDevice->GetAdapterType();
info->vendorID = mPhysicalDevice->GetVendorId();
info->deviceID = mPhysicalDevice->GetDeviceId();
+ info->subgroupMinSize = mPhysicalDevice->GetSubgroupMinSize();
+ info->subgroupMaxSize = mPhysicalDevice->GetSubgroupMaxSize();
info->compatibilityMode = mFeatureLevel == wgpu::FeatureLevel::Compatibility;
+ if (mPhysicalDevice->GetBackendType() == wgpu::BackendType::D3D12 &&
+ mTogglesState.IsEnabled(Toggle::D3D12RelaxMinSubgroupSizeTo8)) {
+ info->subgroupMinSize = std::min(info->subgroupMinSize, 8u);
+ }
+
return wgpu::Status::Success;
}
diff --git a/src/dawn/native/PhysicalDevice.cpp b/src/dawn/native/PhysicalDevice.cpp
index b0d3935..ba4a937 100644
--- a/src/dawn/native/PhysicalDevice.cpp
+++ b/src/dawn/native/PhysicalDevice.cpp
@@ -118,6 +118,14 @@
return mBackend;
}
+uint32_t PhysicalDeviceBase::GetSubgroupMinSize() const {
+ return mSubgroupMinSize;
+}
+
+uint32_t PhysicalDeviceBase::GetSubgroupMaxSize() const {
+ return mSubgroupMaxSize;
+}
+
bool PhysicalDeviceBase::IsFeatureSupportedWithToggles(wgpu::FeatureName feature,
const TogglesState& toggles) const {
return ValidateFeatureSupportedWithToggles(feature, toggles).success;
diff --git a/src/dawn/native/PhysicalDevice.h b/src/dawn/native/PhysicalDevice.h
index 89c36f7..38d2a62 100644
--- a/src/dawn/native/PhysicalDevice.h
+++ b/src/dawn/native/PhysicalDevice.h
@@ -88,6 +88,8 @@
const std::string& GetDriverDescription() const;
wgpu::AdapterType GetAdapterType() const;
wgpu::BackendType GetBackendType() const;
+ uint32_t GetSubgroupMinSize() const;
+ uint32_t GetSubgroupMaxSize() const;
MaybeError ResetInternalDeviceForTesting();
@@ -139,6 +141,8 @@
wgpu::AdapterType mAdapterType = wgpu::AdapterType::Unknown;
gpu_info::DriverVersion mDriverVersion;
std::string mDriverDescription;
+ uint32_t mSubgroupMinSize = 4;
+ uint32_t mSubgroupMaxSize = 128;
// Juat a wrapper of ValidateFeatureSupportedWithToggles, return true if a feature is supported
// by this adapter AND suitable with given toggles.
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
index 2fab350..69527ad 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
@@ -102,6 +102,13 @@
if (mAdapterType == wgpu::AdapterType::DiscreteGPU && mDeviceInfo.isUMA) {
mAdapterType = wgpu::AdapterType::IntegratedGPU;
}
+
+ mSubgroupMinSize = mDeviceInfo.waveLaneCountMin;
+ // Currently the WaveLaneCountMax queried from D3D12 API is not reliable and the meaning is
+ // unclear. Use 128 instead, which is the largest possible size. Reference:
+ // https://github.com/Microsoft/DirectXShaderCompiler/wiki/Wave-Intrinsics#:~:text=UINT%20WaveLaneCountMax
+ mSubgroupMaxSize = 128u;
+
return {};
}
diff --git a/src/dawn/native/metal/PhysicalDeviceMTL.mm b/src/dawn/native/metal/PhysicalDeviceMTL.mm
index 3649b2e..6014f19 100644
--- a/src/dawn/native/metal/PhysicalDeviceMTL.mm
+++ b/src/dawn/native/metal/PhysicalDeviceMTL.mm
@@ -314,6 +314,9 @@
NSString* osVersion = [[NSProcessInfo processInfo] operatingSystemVersionString];
mDriverDescription = "Metal driver on " + std::string(systemName) + [osVersion UTF8String];
+
+ mSubgroupMinSize = 4; // The 4 comes from the minimum derivative group.
+ mSubgroupMaxSize = 64; // In MSL, a ballot is a uint64, so the max subgroup size is 64.
}
bool PhysicalDevice::IsMetalValidationEnabled() const {
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
index 5e357e9..488c76c 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
@@ -165,6 +165,9 @@
break;
}
+ mSubgroupMinSize = mDeviceInfo.subgroupSizeControlProperties.minSubgroupSize;
+ mSubgroupMaxSize = mDeviceInfo.subgroupSizeControlProperties.maxSubgroupSize;
+
// Check for essential Vulkan extensions and features
// Needed for viewport Y-flip.
if (!mDeviceInfo.HasExt(DeviceExt::Maintenance1)) {
diff --git a/src/dawn/tests/end2end/SubgroupsTests.cpp b/src/dawn/tests/end2end/SubgroupsTests.cpp
index 494e471..620f320 100644
--- a/src/dawn/tests/end2end/SubgroupsTests.cpp
+++ b/src/dawn/tests/end2end/SubgroupsTests.cpp
@@ -55,10 +55,10 @@
return o;
}
-DAWN_TEST_PARAM_STRUCT(SubgroupsPropertiesTestsParams, RequestSubgroups);
+DAWN_TEST_PARAM_STRUCT(SubgroupsAdapterInfoParams, RequestSubgroups);
template <class Params>
-class SubgroupsPropertiesTestBase : public DawnTestWithParams<Params> {
+class SubgroupsAdapterInfoTestBase : public DawnTestWithParams<Params> {
public:
using DawnTestWithParams<Params>::GetParam;
using DawnTestWithParams<Params>::SupportsFeatures;
@@ -85,8 +85,9 @@
}
};
-using SubgroupsPropertiesTests = SubgroupsPropertiesTestBase<SubgroupsPropertiesTestsParams>;
+using SubgroupsPropertiesTests = SubgroupsAdapterInfoTestBase<SubgroupsAdapterInfoParams>;
+// Test that subgroupMinSize and subgroupMaxSize in wgpu::AdapterPropertiesSubgroups are valid.
TEST_P(SubgroupsPropertiesTests, FromAdapter) {
wgpu::AdapterPropertiesSubgroups subgroup_properties;
@@ -106,6 +107,7 @@
CheckValidSizes(subgroup_properties.subgroupMinSize, subgroup_properties.subgroupMaxSize);
}
+// Test that subgroupMinSize and subgroupMaxSize in wgpu::AdapterPropertiesSubgroups are valid.
TEST_P(SubgroupsPropertiesTests, FromDevice) {
wgpu::AdapterPropertiesSubgroups subgroup_properties;
wgpu::AdapterInfo info;
@@ -116,6 +118,8 @@
CheckValidSizes(subgroup_properties.subgroupMinSize, subgroup_properties.subgroupMaxSize);
}
+// Test that subgroupMinSize and subgroupMaxSize in wgpu::AdapterPropertiesSubgroups are the same
+// between adapter and device.
TEST_P(SubgroupsPropertiesTests, DeviceAndAdapterAgree) {
wgpu::AdapterPropertiesSubgroups adapter_subgroup_properties;
wgpu::AdapterInfo adapter_info;
@@ -138,6 +142,42 @@
VulkanBackend()},
{RequestSubgroups::WhenAvailable, RequestSubgroups::Never});
+using SubgroupsAdapterInfoTests = SubgroupsAdapterInfoTestBase<SubgroupsAdapterInfoParams>;
+
+// Test that subgroupMinSize and subgroupMaxSize in wgpu::AdapterInfo are valid.
+TEST_P(SubgroupsAdapterInfoTests, FromAdapter) {
+ wgpu::AdapterInfo info;
+ adapter.GetInfo(&info);
+
+ CheckValidSizes(info.subgroupMinSize, info.subgroupMaxSize);
+}
+
+// Test that subgroupMinSize and subgroupMaxSize in wgpu::AdapterInfo are valid.
+TEST_P(SubgroupsAdapterInfoTests, FromDevice) {
+ wgpu::AdapterInfo info;
+ device.GetAdapterInfo(&info);
+
+ CheckValidSizes(info.subgroupMinSize, info.subgroupMaxSize);
+}
+
+// Test that subgroupMinSize and subgroupMaxSize in wgpu::AdapterInfo are the same between adapter
+// and device.
+TEST_P(SubgroupsAdapterInfoTests, DeviceAndAdapterAgree) {
+ wgpu::AdapterInfo adapter_info;
+ adapter.GetInfo(&adapter_info);
+
+ wgpu::AdapterInfo device_info;
+ device.GetAdapterInfo(&device_info);
+
+ EXPECT_EQ(device_info.subgroupMinSize, adapter_info.subgroupMinSize);
+ EXPECT_EQ(device_info.subgroupMaxSize, adapter_info.subgroupMaxSize);
+}
+
+DAWN_INSTANTIATE_TEST_P(SubgroupsAdapterInfoTests,
+ {D3D12Backend(), D3D12Backend({}, {"use_dxc"}), MetalBackend(),
+ VulkanBackend()},
+ {RequestSubgroups::WhenAvailable, RequestSubgroups::Never});
+
template <class Params>
class SubgroupsTestsBase : public DawnTestWithParams<Params> {
public:
diff --git a/src/dawn/tests/unittests/wire/WireInstanceTests.cpp b/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
index f1a2738..cd17ea7 100644
--- a/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
@@ -127,6 +127,8 @@
fakeInfo.adapterType = WGPUAdapterType_IntegratedGPU;
fakeInfo.vendorID = 0x134;
fakeInfo.deviceID = 0x918;
+ fakeInfo.subgroupMinSize = 4;
+ fakeInfo.subgroupMaxSize = 128;
wgpu::SupportedLimits fakeLimits = {};
fakeLimits.limits.maxTextureDimension1D = 433;
@@ -186,6 +188,8 @@
EXPECT_EQ(info.adapterType, fakeInfo.adapterType);
EXPECT_EQ(info.vendorID, fakeInfo.vendorID);
EXPECT_EQ(info.deviceID, fakeInfo.deviceID);
+ EXPECT_EQ(info.subgroupMinSize, fakeInfo.subgroupMinSize);
+ EXPECT_EQ(info.subgroupMaxSize, fakeInfo.subgroupMaxSize);
wgpu::SupportedLimits limits = {};
EXPECT_EQ(adapter.GetLimits(&limits), wgpu::Status::Success);