Skip to content

Commit

Permalink
Make GPUAdapter GetInfo() a suitable replacement for GetProperties
Browse files Browse the repository at this point in the history
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]: webgpu-native/webgpu-headers#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 <[email protected]>
Commit-Queue: Kai Ninomiya <[email protected]>
  • Loading branch information
beaufortfrancois authored and Dawn LUCI CQ committed Jun 14, 2024
1 parent 88e0d75 commit 420c94d
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 42 deletions.
7 changes: 3 additions & 4 deletions include/dawn/native/DawnNative.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,12 @@ class DAWN_NATIVE_EXPORT Adapter {
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;

Expand Down
11 changes: 6 additions & 5 deletions src/dawn/dawn.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down Expand Up @@ -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"}
Expand Down Expand Up @@ -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"},
Expand All @@ -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"}
Expand All @@ -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"}
Expand Down
7 changes: 7 additions & 0 deletions src/dawn/native/Adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ wgpu::Status AdapterBase::APIGetLimits(SupportedLimits* limits) const {
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;
Expand Down Expand Up @@ -151,6 +157,7 @@ wgpu::Status AdapterBase::APIGetInfo(AdapterInfo* info) const {
info->adapterType = mPhysicalDevice->GetAdapterType();
info->vendorID = mPhysicalDevice->GetVendorId();
info->deviceID = mPhysicalDevice->GetDeviceId();
info->compatibilityMode = mFeatureLevel == FeatureLevel::Compatibility;

return wgpu::Status::Success;
}
Expand Down
4 changes: 4 additions & 0 deletions src/dawn/native/DawnNative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ Adapter& Adapter::operator=(const Adapter& other) {
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));
}
Expand Down
14 changes: 14 additions & 0 deletions src/dawn/tests/end2end/AdapterCreationTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@ TEST_P(AdapterCreationTest, Compatibility) {
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.
Expand All @@ -296,6 +300,10 @@ TEST_P(AdapterCreationTest, NonCompatibility) {
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.
Expand Down Expand Up @@ -561,6 +569,7 @@ TEST_P(AdapterCreationTest, InfoMoveAssign) {
wgpu::AdapterType adapterType = info1.adapterType;
uint32_t vendorID = info1.vendorID;
uint32_t deviceID = info1.deviceID;
bool compatibilityMode = info1.compatibilityMode;

info2 = std::move(info1);

Expand All @@ -573,6 +582,7 @@ TEST_P(AdapterCreationTest, InfoMoveAssign) {
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);
Expand All @@ -583,6 +593,7 @@ TEST_P(AdapterCreationTest, InfoMoveAssign) {
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.
Expand Down Expand Up @@ -613,6 +624,7 @@ TEST_P(AdapterCreationTest, InfoMoveConstruct) {
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));

Expand All @@ -625,6 +637,7 @@ TEST_P(AdapterCreationTest, InfoMoveConstruct) {
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);
Expand All @@ -635,6 +648,7 @@ TEST_P(AdapterCreationTest, InfoMoveConstruct) {
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.
Expand Down
23 changes: 17 additions & 6 deletions src/dawn/tests/end2end/AdapterPropertiesD3DTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,26 @@ class AdapterPropertiesD3DTest : public DawnTest {};
// 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,
Expand Down
24 changes: 18 additions & 6 deletions src/dawn/tests/end2end/AdapterPropertiesVkTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,26 @@ class AdapterPropertiesVkTest : public DawnTest {};
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());
Expand Down
55 changes: 34 additions & 21 deletions src/dawn/tests/end2end/MemoryHeapPropertiesTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,49 @@
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.

// 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);

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);
adapter.GetProperties(&properties);
CheckMemoryHeapProperties(memoryHeapProperties);
}
{
wgpu::AdapterInfo info;
wgpu::AdapterPropertiesMemoryHeaps memoryHeapProperties;
info.nextInChain = &memoryHeapProperties;

// Check the heap properies have at least one bit.
EXPECT_NE(uint32_t(memoryHeapProperties.heapInfo[i].properties), 0u);
adapter.GetInfo(&info);
CheckMemoryHeapProperties(memoryHeapProperties);
}
}

Expand Down
63 changes: 63 additions & 0 deletions src/dawn/wire/client/Adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,37 @@ void Adapter::SetFeatures(const WGPUFeatureName* features, uint32_t featuresCoun

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) {
Expand Down Expand Up @@ -197,6 +228,38 @@ void Adapter::SetProperties(const WGPUAdapterProperties* properties) {
}

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.
Expand Down

0 comments on commit 420c94d

Please sign in to comment.