Make GPUAdapter GetInfo() a suitable replacement for GetProperties
Following up on a webgpu.h change[1], this CL adds support for
adapter properties memory heaps, adapter properties D3D,
adapter properties vk, dawn adapter properties power preference,
and compatibility mode to GPUAdapter GetInfo() method so
that Chrome can start the migration[2].
Once done, the GPUAdapter GetProperties() method will be marked
as deprecated and we'll start using only GetInfo() in Dawn.
Finally, we'll remove the GPUAdapter GetProperties() method.
[1]: https://github.com/webgpu-native/webgpu-headers/pull/305
[2]: https://chromium-review.googlesource.com/c/chromium/src/+/5626172
Bug: 335383516
Change-Id: I720581c1c5594d8997dc794e228fe14efb8d20cd
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/193461
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
diff --git a/include/dawn/native/DawnNative.h b/include/dawn/native/DawnNative.h
index 36104ed..9cbe83f 100644
--- a/include/dawn/native/DawnNative.h
+++ b/include/dawn/native/DawnNative.h
@@ -87,13 +87,12 @@
Adapter(const Adapter& other);
Adapter& operator=(const Adapter& other);
+ // TODO(crbug.com/347047627): These methods are historical duplicates of
+ // those in webgpu_cpp.h. Update uses of these methods and remove them.
+ wgpu::Status GetInfo(wgpu::AdapterInfo* info) const;
wgpu::Status GetInfo(WGPUAdapterInfo* info) const;
-
- // Essentially webgpu.h's wgpuAdapterGetProperties while we don't have WGPUAdapter in
- // dawn.json
wgpu::Status GetProperties(wgpu::AdapterProperties* properties) const;
wgpu::Status GetProperties(WGPUAdapterProperties* properties) const;
-
std::vector<const char*> GetSupportedFeatures() const;
wgpu::ConvertibleStatus GetLimits(WGPUSupportedLimits* limits) const;
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index b161138..e73502e 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -217,7 +217,8 @@
{"name": "backend type", "type": "backend type"},
{"name": "adapter type", "type": "adapter type"},
{"name": "vendor ID", "type": "uint32_t"},
- {"name": "device ID", "type": "uint32_t"}
+ {"name": "device ID", "type": "uint32_t"},
+ {"name": "compatibility mode", "type": "bool", "default": "false", "tags": ["dawn", "emscripten"]}
]
},
"adapter properties": {
@@ -4477,7 +4478,7 @@
"dawn adapter properties power preference": {
"category": "structure",
"chained": "out",
- "chain roots": ["adapter properties"],
+ "chain roots": ["adapter info", "adapter properties"],
"tags": ["dawn"],
"members": [
{"name": "power preference", "type": "power preference", "default": "undefined"}
@@ -4506,7 +4507,7 @@
"adapter properties memory heaps": {
"category": "structure",
"chained": "out",
- "chain roots": ["adapter properties"],
+ "chain roots": ["adapter info", "adapter properties"],
"tags": ["dawn"],
"members": [
{"name": "heap count", "type": "size_t"},
@@ -4516,7 +4517,7 @@
"adapter properties D3D": {
"category": "structure",
"chained": "out",
- "chain roots": ["adapter properties"],
+ "chain roots": ["adapter info", "adapter properties"],
"tags": ["dawn"],
"members": [
{"name": "shader model", "type": "uint32_t"}
@@ -4525,7 +4526,7 @@
"adapter properties vk": {
"category": "structure",
"chained": "out",
- "chain roots": ["adapter properties"],
+ "chain roots": ["adapter info", "adapter properties"],
"tags": ["dawn"],
"members": [
{"name": "driver version", "type": "uint32_t"}
diff --git a/src/dawn/native/Adapter.cpp b/src/dawn/native/Adapter.cpp
index 442a52f..1879fc1 100644
--- a/src/dawn/native/Adapter.cpp
+++ b/src/dawn/native/Adapter.cpp
@@ -122,6 +122,12 @@
wgpu::Status AdapterBase::APIGetInfo(AdapterInfo* info) const {
DAWN_ASSERT(info != nullptr);
+ AdapterProperties properties = {};
+ properties.nextInChain = info->nextInChain;
+ if (APIGetProperties(&properties) == wgpu::Status::Error) {
+ return wgpu::Status::Error;
+ }
+
// Get lengths, with null terminators.
size_t vendorCLen = mPhysicalDevice->GetVendorName().length() + 1;
size_t architectureCLen = mPhysicalDevice->GetArchitectureName().length() + 1;
@@ -151,6 +157,7 @@
info->adapterType = mPhysicalDevice->GetAdapterType();
info->vendorID = mPhysicalDevice->GetVendorId();
info->deviceID = mPhysicalDevice->GetDeviceId();
+ info->compatibilityMode = mFeatureLevel == FeatureLevel::Compatibility;
return wgpu::Status::Success;
}
diff --git a/src/dawn/native/DawnNative.cpp b/src/dawn/native/DawnNative.cpp
index 6416645..f48acf5 100644
--- a/src/dawn/native/DawnNative.cpp
+++ b/src/dawn/native/DawnNative.cpp
@@ -89,6 +89,10 @@
return *this;
}
+wgpu::Status Adapter::GetInfo(wgpu::AdapterInfo* info) const {
+ return GetInfo(reinterpret_cast<WGPUAdapterInfo*>(info));
+}
+
wgpu::Status Adapter::GetInfo(WGPUAdapterInfo* info) const {
return mImpl->APIGetInfo(FromAPI(info));
}
diff --git a/src/dawn/tests/end2end/AdapterCreationTests.cpp b/src/dawn/tests/end2end/AdapterCreationTests.cpp
index c52fcf4..d75cd01 100644
--- a/src/dawn/tests/end2end/AdapterCreationTests.cpp
+++ b/src/dawn/tests/end2end/AdapterCreationTests.cpp
@@ -277,6 +277,10 @@
wgpu::AdapterProperties properties;
adapter.GetProperties(&properties);
EXPECT_TRUE(properties.compatibilityMode);
+
+ wgpu::AdapterInfo info;
+ adapter.GetInfo(&info);
+ EXPECT_TRUE(info.compatibilityMode);
}
// Test that requesting a Non-Compatibility adapter is supported and is default.
@@ -296,6 +300,10 @@
wgpu::AdapterProperties properties;
adapter.GetProperties(&properties);
EXPECT_FALSE(properties.compatibilityMode);
+
+ wgpu::AdapterInfo info;
+ adapter.GetInfo(&info);
+ EXPECT_FALSE(info.compatibilityMode);
}
// Test that GetInstance() returns the correct Instance.
@@ -561,6 +569,7 @@
wgpu::AdapterType adapterType = info1.adapterType;
uint32_t vendorID = info1.vendorID;
uint32_t deviceID = info1.deviceID;
+ bool compatibilityMode = info1.compatibilityMode;
info2 = std::move(info1);
@@ -573,6 +582,7 @@
EXPECT_EQ(info2.adapterType, adapterType);
EXPECT_EQ(info2.vendorID, vendorID);
EXPECT_EQ(info2.deviceID, deviceID);
+ EXPECT_EQ(info2.compatibilityMode, compatibilityMode);
// Expect info1 to be empty.
EXPECT_EQ(info1.vendor, nullptr);
@@ -583,6 +593,7 @@
EXPECT_EQ(info1.adapterType, static_cast<wgpu::AdapterType>(0));
EXPECT_EQ(info1.vendorID, 0u);
EXPECT_EQ(info1.deviceID, 0u);
+ EXPECT_EQ(info1.compatibilityMode, false);
}
// Test move construction of the adapter info.
@@ -613,6 +624,7 @@
wgpu::AdapterType adapterType = info1.adapterType;
uint32_t vendorID = info1.vendorID;
uint32_t deviceID = info1.deviceID;
+ bool compatibilityMode = info1.compatibilityMode;
wgpu::AdapterInfo info2(std::move(info1));
@@ -625,6 +637,7 @@
EXPECT_EQ(info2.adapterType, adapterType);
EXPECT_EQ(info2.vendorID, vendorID);
EXPECT_EQ(info2.deviceID, deviceID);
+ EXPECT_EQ(info2.compatibilityMode, compatibilityMode);
// Expect info1 to be empty.
EXPECT_EQ(info1.vendor, nullptr);
@@ -635,6 +648,7 @@
EXPECT_EQ(info1.adapterType, static_cast<wgpu::AdapterType>(0));
EXPECT_EQ(info1.vendorID, 0u);
EXPECT_EQ(info1.deviceID, 0u);
+ EXPECT_EQ(info1.compatibilityMode, false);
}
// Test that the adapter info can outlive the adapter.
diff --git a/src/dawn/tests/end2end/AdapterPropertiesD3DTests.cpp b/src/dawn/tests/end2end/AdapterPropertiesD3DTests.cpp
index f480dc5..22b812d 100644
--- a/src/dawn/tests/end2end/AdapterPropertiesD3DTests.cpp
+++ b/src/dawn/tests/end2end/AdapterPropertiesD3DTests.cpp
@@ -38,15 +38,26 @@
// Test that it is possible to query the d3d properties, and it is populated with a valid data.
TEST_P(AdapterPropertiesD3DTest, GetD3DProperties) {
DAWN_TEST_UNSUPPORTED_IF(!adapter.HasFeature(wgpu::FeatureName::AdapterPropertiesD3D));
+ {
+ wgpu::AdapterProperties properties;
+ wgpu::AdapterPropertiesD3D d3dProperties;
+ properties.nextInChain = &d3dProperties;
- wgpu::AdapterProperties properties;
- wgpu::AdapterPropertiesD3D d3dProperties;
- properties.nextInChain = &d3dProperties;
+ adapter.GetProperties(&properties);
- adapter.GetProperties(&properties);
+ // This is the minimum D3D shader model Dawn supports.
+ EXPECT_GE(d3dProperties.shaderModel, 50u);
+ }
+ {
+ wgpu::AdapterInfo info;
+ wgpu::AdapterPropertiesD3D d3dProperties;
+ info.nextInChain = &d3dProperties;
- // This is the minimum D3D shader model Dawn supports.
- EXPECT_GE(d3dProperties.shaderModel, 50u);
+ adapter.GetInfo(&info);
+
+ // This is the minimum D3D shader model Dawn supports.
+ EXPECT_GE(d3dProperties.shaderModel, 50u);
+ }
}
DAWN_INSTANTIATE_TEST(AdapterPropertiesD3DTest,
diff --git a/src/dawn/tests/end2end/AdapterPropertiesVkTests.cpp b/src/dawn/tests/end2end/AdapterPropertiesVkTests.cpp
index 79f1b11..d6baf2a 100644
--- a/src/dawn/tests/end2end/AdapterPropertiesVkTests.cpp
+++ b/src/dawn/tests/end2end/AdapterPropertiesVkTests.cpp
@@ -39,14 +39,26 @@
TEST_P(AdapterPropertiesVkTest, GetVkProperties) {
DAWN_TEST_UNSUPPORTED_IF(!adapter.HasFeature(wgpu::FeatureName::AdapterPropertiesVk));
- wgpu::AdapterProperties properties;
- wgpu::AdapterPropertiesVk vkProperties;
- properties.nextInChain = &vkProperties;
+ {
+ wgpu::AdapterProperties properties;
+ wgpu::AdapterPropertiesVk vkProperties;
+ properties.nextInChain = &vkProperties;
- adapter.GetProperties(&properties);
+ adapter.GetProperties(&properties);
- // The driver version should be set to something but it depends on the hardware.
- EXPECT_NE(vkProperties.driverVersion, 0u);
+ // The driver version should be set to something but it depends on the hardware.
+ EXPECT_NE(vkProperties.driverVersion, 0u);
+ }
+ {
+ wgpu::AdapterInfo info;
+ wgpu::AdapterPropertiesVk vkProperties;
+ info.nextInChain = &vkProperties;
+
+ adapter.GetInfo(&info);
+
+ // The driver version should be set to something but it depends on the hardware.
+ EXPECT_NE(vkProperties.driverVersion, 0u);
+ }
}
DAWN_INSTANTIATE_TEST(AdapterPropertiesVkTest, VulkanBackend());
diff --git a/src/dawn/tests/end2end/MemoryHeapPropertiesTests.cpp b/src/dawn/tests/end2end/MemoryHeapPropertiesTests.cpp
index 532207e..97e2b70 100644
--- a/src/dawn/tests/end2end/MemoryHeapPropertiesTests.cpp
+++ b/src/dawn/tests/end2end/MemoryHeapPropertiesTests.cpp
@@ -32,7 +32,27 @@
namespace dawn {
namespace {
-class MemoryHeapPropertiesTest : public DawnTest {};
+class MemoryHeapPropertiesTest : public DawnTest {
+ protected:
+ void CheckMemoryHeapProperties(const wgpu::AdapterPropertiesMemoryHeaps& memoryHeapProperties) {
+ EXPECT_GT(memoryHeapProperties.heapCount, 0u);
+ for (size_t i = 0; i < memoryHeapProperties.heapCount; ++i) {
+ // Check the heap is non-zero in size.
+ EXPECT_GT(memoryHeapProperties.heapInfo[i].size, 0ull);
+
+ constexpr wgpu::HeapProperty kValidProps =
+ wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
+ wgpu::HeapProperty::HostCoherent | wgpu::HeapProperty::HostUncached |
+ wgpu::HeapProperty::HostCached;
+
+ // Check the heap properties only contain the set of valid enums.
+ EXPECT_EQ(memoryHeapProperties.heapInfo[i].properties & ~kValidProps, 0u);
+
+ // Check the heap properties have at least one bit.
+ EXPECT_NE(uint32_t(memoryHeapProperties.heapInfo[i].properties), 0u);
+ }
+ }
+};
// TODO(dawn:2257) test that is is invalid to request AdapterPropertiesMemoryHeaps if the
// feature is not available.
@@ -40,28 +60,21 @@
// Test that it is possible to query the memory, and it is populated with valid enums.
TEST_P(MemoryHeapPropertiesTest, GetMemoryHeapProperties) {
DAWN_TEST_UNSUPPORTED_IF(!adapter.HasFeature(wgpu::FeatureName::AdapterPropertiesMemoryHeaps));
+ {
+ wgpu::AdapterProperties properties;
+ wgpu::AdapterPropertiesMemoryHeaps memoryHeapProperties;
+ properties.nextInChain = &memoryHeapProperties;
- wgpu::AdapterProperties properties;
- wgpu::AdapterPropertiesMemoryHeaps memoryHeapProperties;
- properties.nextInChain = &memoryHeapProperties;
+ adapter.GetProperties(&properties);
+ CheckMemoryHeapProperties(memoryHeapProperties);
+ }
+ {
+ wgpu::AdapterInfo info;
+ wgpu::AdapterPropertiesMemoryHeaps memoryHeapProperties;
+ info.nextInChain = &memoryHeapProperties;
- adapter.GetProperties(&properties);
-
- EXPECT_GT(memoryHeapProperties.heapCount, 0u);
- for (size_t i = 0; i < memoryHeapProperties.heapCount; ++i) {
- // Check the heap is non-zero in size.
- EXPECT_GT(memoryHeapProperties.heapInfo[i].size, 0ull);
-
- constexpr wgpu::HeapProperty kValidProps =
- wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
- wgpu::HeapProperty::HostCoherent | wgpu::HeapProperty::HostUncached |
- wgpu::HeapProperty::HostCached;
-
- // Check the heap properties only contain the set of valid enums.
- EXPECT_EQ(memoryHeapProperties.heapInfo[i].properties & ~kValidProps, 0u);
-
- // Check the heap properies have at least one bit.
- EXPECT_NE(uint32_t(memoryHeapProperties.heapInfo[i].properties), 0u);
+ adapter.GetInfo(&info);
+ CheckMemoryHeapProperties(memoryHeapProperties);
}
}
diff --git a/src/dawn/wire/client/Adapter.cpp b/src/dawn/wire/client/Adapter.cpp
index 4b90183..548df55 100644
--- a/src/dawn/wire/client/Adapter.cpp
+++ b/src/dawn/wire/client/Adapter.cpp
@@ -159,6 +159,37 @@
void Adapter::SetInfo(const WGPUAdapterInfo* info) {
mInfo = *info;
+ mInfo.nextInChain = nullptr;
+
+ // Loop through the chained struct.
+ WGPUChainedStructOut* chain = info->nextInChain;
+ while (chain != nullptr) {
+ switch (chain->sType) {
+ case WGPUSType_AdapterPropertiesMemoryHeaps: {
+ // Make a copy of the heap info in `mMemoryHeapInfo`.
+ const auto* memoryHeapProperties =
+ reinterpret_cast<const WGPUAdapterPropertiesMemoryHeaps*>(chain);
+ mMemoryHeapInfo = {
+ memoryHeapProperties->heapInfo,
+ memoryHeapProperties->heapInfo + memoryHeapProperties->heapCount};
+ break;
+ }
+ case WGPUSType_AdapterPropertiesD3D: {
+ auto* d3dProperties = reinterpret_cast<WGPUAdapterPropertiesD3D*>(chain);
+ mD3DProperties.shaderModel = d3dProperties->shaderModel;
+ break;
+ }
+ case WGPUSType_AdapterPropertiesVk: {
+ auto* vkProperties = reinterpret_cast<WGPUAdapterPropertiesVk*>(chain);
+ mVkProperties.driverVersion = vkProperties->driverVersion;
+ break;
+ }
+ default:
+ DAWN_UNREACHABLE();
+ break;
+ }
+ chain = chain->next;
+ }
}
void Adapter::SetProperties(const WGPUAdapterProperties* properties) {
@@ -197,6 +228,38 @@
}
WGPUStatus Adapter::GetInfo(WGPUAdapterInfo* info) const {
+ // Loop through the chained struct.
+ WGPUChainedStructOut* chain = info->nextInChain;
+ while (chain != nullptr) {
+ switch (chain->sType) {
+ case WGPUSType_AdapterPropertiesMemoryHeaps: {
+ // Copy `mMemoryHeapInfo` into a new allocation.
+ auto* memoryHeapProperties =
+ reinterpret_cast<WGPUAdapterPropertiesMemoryHeaps*>(chain);
+ size_t heapCount = mMemoryHeapInfo.size();
+ auto* heapInfo = new WGPUMemoryHeapInfo[heapCount];
+ memcpy(heapInfo, mMemoryHeapInfo.data(), sizeof(WGPUMemoryHeapInfo) * heapCount);
+ // Write out the pointer and count to the heap properties out-struct.
+ memoryHeapProperties->heapCount = heapCount;
+ memoryHeapProperties->heapInfo = heapInfo;
+ break;
+ }
+ case WGPUSType_AdapterPropertiesD3D: {
+ auto* d3dProperties = reinterpret_cast<WGPUAdapterPropertiesD3D*>(chain);
+ d3dProperties->shaderModel = mD3DProperties.shaderModel;
+ break;
+ }
+ case WGPUSType_AdapterPropertiesVk: {
+ auto* vkProperties = reinterpret_cast<WGPUAdapterPropertiesVk*>(chain);
+ vkProperties->driverVersion = mVkProperties.driverVersion;
+ break;
+ }
+ default:
+ break;
+ }
+ chain = chain->next;
+ }
+
*info = mInfo;
// Get lengths, with null terminators.