Add AdapterPropertiesD3D
This allows Chrome to query the Adapter's D3D shader model and do
its own blocklisting instead of relying on Dawn.
Bug: dawn:1254
Change-Id: I376021f066d03c26623a3ed86c1b7bf55c7d8cb5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/170563
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/docs/dawn/features/adapter_properties.md b/docs/dawn/features/adapter_properties.md
index c4d348b..147b239 100644
--- a/docs/dawn/features/adapter_properties.md
+++ b/docs/dawn/features/adapter_properties.md
@@ -27,3 +27,17 @@
```
`wgpu::MemoryHeapInfo::size` is the size that should be allocated out of this heap. Allocating more than this may result in poor performance or may deterministically run out of memory.
+
+
+## D3D
+
+`wgpu::FeatureName::AdapterPropertiesD3D` allows querying D3D information from the adapter.
+
+`wgpu::AdapterPropertiesD3D` may be chained on `wgpu::AdapterProperties` in a call to `wgpu::Adapter::GetProperties` in order to query D3D information on that adapter.
+
+Adds `wgpu::AdapterPropertiesD3D` which is a struct describing the D3D adapter.
+```
+struct AdapterPropertiesD3D {
+ uint32_t shaderModel; // The D3D shader model
+};
+```
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index e4f23b1..2106708 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -1973,6 +1973,7 @@
{"value": 1025, "name": "framebuffer fetch", "tags": ["dawn"]},
{"value": 1026, "name": "buffer map extended usages", "tags": ["dawn"]},
{"value": 1027, "name": "adapter properties memory heaps", "tags": ["dawn"]},
+ {"value": 1028, "name": "adapter properties D3D", "tags": ["dawn"]},
{"value": 1100, "name": "shared texture memory vk dedicated allocation", "tags": ["dawn", "native"]},
{"value": 1101, "name": "shared texture memory a hardware buffer", "tags": ["dawn", "native"]},
@@ -3383,9 +3384,10 @@
{"value": 1017, "name": "buffer host mapped pointer", "tags": ["dawn"]},
{"value": 1018, "name": "dawn experimental subgroup limits", "tags": ["dawn"]},
{"value": 1019, "name": "adapter properties memory heaps", "tags": ["dawn"]},
- {"value": 1020, "name": "dawn compute pipeline full subgroups", "tags": ["dawn"]},
- {"value": 1021, "name": "dawn wire WGSL control", "tags": ["dawn"]},
- {"value": 1022, "name": "dawn WGSL blocklist", "tags": ["dawn", "native"]},
+ {"value": 1020, "name": "adapter properties D3D", "tags": ["dawn"]},
+ {"value": 1021, "name": "dawn compute pipeline full subgroups", "tags": ["dawn"]},
+ {"value": 1022, "name": "dawn wire WGSL control", "tags": ["dawn"]},
+ {"value": 1023, "name": "dawn WGSL blocklist", "tags": ["dawn", "native"]},
{"value": 1100, "name": "shared texture memory vk image descriptor", "tags": ["dawn", "native"]},
{"value": 1101, "name": "shared texture memory vk dedicated allocation descriptor", "tags": ["dawn", "native"]},
@@ -3909,6 +3911,15 @@
{"name": "heap info", "type": "memory heap info", "annotation": "const*", "length": "heap count"}
]
},
+ "adapter properties D3D": {
+ "category": "structure",
+ "chained": "out",
+ "chain roots": ["adapter properties"],
+ "tags": ["dawn"],
+ "members": [
+ {"name": "shader model", "type": "uint32_t"}
+ ]
+ },
"dawn buffer descriptor error info from wire client": {
"category": "structure",
"chained": "in",
diff --git a/src/dawn/native/Adapter.cpp b/src/dawn/native/Adapter.cpp
index 6af2145..d37b727 100644
--- a/src/dawn/native/Adapter.cpp
+++ b/src/dawn/native/Adapter.cpp
@@ -114,17 +114,22 @@
return;
}
- if (auto* memoryHeaps = unpacked.Get<AdapterPropertiesMemoryHeaps>()) {
- if (!mSupportedFeatures.IsEnabled(wgpu::FeatureName::AdapterPropertiesMemoryHeaps)) {
- mPhysicalDevice->GetInstance()->ConsumedError(
- DAWN_VALIDATION_ERROR("Feature AdapterPropertiesMemoryHeaps is not available."));
- }
- mPhysicalDevice->PopulateMemoryHeapInfo(memoryHeaps);
+ if (unpacked.Get<AdapterPropertiesMemoryHeaps>() != nullptr &&
+ !mSupportedFeatures.IsEnabled(wgpu::FeatureName::AdapterPropertiesMemoryHeaps)) {
+ instance->ConsumedError(
+ DAWN_VALIDATION_ERROR("Feature AdapterPropertiesMemoryHeaps is not available."));
+ }
+ if (unpacked.Get<AdapterPropertiesD3D>() != nullptr &&
+ !mSupportedFeatures.IsEnabled(wgpu::FeatureName::AdapterPropertiesD3D)) {
+ instance->ConsumedError(
+ DAWN_VALIDATION_ERROR("Feature AdapterPropertiesD3D is not available."));
}
if (auto* powerPreferenceDesc = unpacked.Get<DawnAdapterPropertiesPowerPreference>()) {
powerPreferenceDesc->powerPreference = mPowerPreference;
}
+ mPhysicalDevice->PopulateBackendProperties(unpacked);
+
properties->vendorID = mPhysicalDevice->GetVendorId();
properties->deviceID = mPhysicalDevice->GetDeviceId();
properties->adapterType = mPhysicalDevice->GetAdapterType();
diff --git a/src/dawn/native/Features.cpp b/src/dawn/native/Features.cpp
index f6f24b7..fb09b14 100644
--- a/src/dawn/native/Features.cpp
+++ b/src/dawn/native/Features.cpp
@@ -290,6 +290,11 @@
"https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/"
"adapter_properties.md",
FeatureInfo::FeatureState::Stable}},
+ {Feature::AdapterPropertiesD3D,
+ {"Support querying D3D info from the adapter.",
+ "https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/"
+ "adapter_properties.md",
+ FeatureInfo::FeatureState::Stable}},
};
} // anonymous namespace
diff --git a/src/dawn/native/PhysicalDevice.h b/src/dawn/native/PhysicalDevice.h
index 2d56f42..d509f4e 100644
--- a/src/dawn/native/PhysicalDevice.h
+++ b/src/dawn/native/PhysicalDevice.h
@@ -107,10 +107,8 @@
FeatureValidationResult ValidateFeatureSupportedWithToggles(wgpu::FeatureName feature,
const TogglesState& toggles) const;
- // Populate information about the memory heaps. Ownership of allocations written to
- // `memoryHeapProperties` are owned by the caller.
- virtual void PopulateMemoryHeapInfo(
- AdapterPropertiesMemoryHeaps* memoryHeapProperties) const = 0;
+ // Populate backend properties. Ownership of allocations written are owned by the caller.
+ virtual void PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const = 0;
protected:
uint32_t mVendorId = 0xFFFFFFFF;
diff --git a/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp b/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
index 59e887c..d1efb23 100644
--- a/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
+++ b/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
@@ -190,6 +190,7 @@
EnableFeature(Feature::DualSourceBlending);
EnableFeature(Feature::Norm16TextureFormats);
EnableFeature(Feature::AdapterPropertiesMemoryHeaps);
+ EnableFeature(Feature::AdapterPropertiesD3D);
// To import multi planar textures, we need to at least tier 2 support.
if (mDeviceInfo.supportsSharedResourceCapabilityTier2) {
@@ -329,32 +330,37 @@
return {};
}
-void PhysicalDevice::PopulateMemoryHeapInfo(
- AdapterPropertiesMemoryHeaps* memoryHeapProperties) const {
- // https://microsoft.github.io/DirectX-Specs/d3d/D3D12GPUUploadHeaps.html describes
- // the properties of D3D12 Default/Upload/Readback heaps. The assumption is that these are
- // roughly how D3D11 allocates memory has well.
- if (mDeviceInfo.isUMA) {
- auto* heapInfo = new MemoryHeapInfo[1];
- memoryHeapProperties->heapCount = 1;
- memoryHeapProperties->heapInfo = heapInfo;
+void PhysicalDevice::PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const {
+ if (auto* memoryHeapProperties = properties.Get<AdapterPropertiesMemoryHeaps>()) {
+ // https://microsoft.github.io/DirectX-Specs/d3d/D3D12GPUUploadHeaps.html describes
+ // the properties of D3D12 Default/Upload/Readback heaps. The assumption is that these are
+ // roughly how D3D11 allocates memory has well.
+ if (mDeviceInfo.isUMA) {
+ auto* heapInfo = new MemoryHeapInfo[1];
+ memoryHeapProperties->heapCount = 1;
+ memoryHeapProperties->heapInfo = heapInfo;
- heapInfo[0].size =
- std::max(mDeviceInfo.dedicatedVideoMemory, mDeviceInfo.sharedSystemMemory);
- heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
- wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
- } else {
- auto* heapInfo = new MemoryHeapInfo[2];
- memoryHeapProperties->heapCount = 2;
- memoryHeapProperties->heapInfo = heapInfo;
+ heapInfo[0].size =
+ std::max(mDeviceInfo.dedicatedVideoMemory, mDeviceInfo.sharedSystemMemory);
+ heapInfo[0].properties =
+ wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
+ wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
+ } else {
+ auto* heapInfo = new MemoryHeapInfo[2];
+ memoryHeapProperties->heapCount = 2;
+ memoryHeapProperties->heapInfo = heapInfo;
- heapInfo[0].size = mDeviceInfo.dedicatedVideoMemory;
- heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal;
+ heapInfo[0].size = mDeviceInfo.dedicatedVideoMemory;
+ heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal;
- heapInfo[1].size = mDeviceInfo.sharedSystemMemory;
- heapInfo[1].properties = wgpu::HeapProperty::HostVisible |
- wgpu::HeapProperty::HostCoherent |
- wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
+ heapInfo[1].size = mDeviceInfo.sharedSystemMemory;
+ heapInfo[1].properties =
+ wgpu::HeapProperty::HostVisible | wgpu::HeapProperty::HostCoherent |
+ wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
+ }
+ }
+ if (auto* d3dProperties = properties.Get<AdapterPropertiesD3D>()) {
+ d3dProperties->shaderModel = GetDeviceInfo().shaderModel;
}
}
diff --git a/src/dawn/native/d3d11/PhysicalDeviceD3D11.h b/src/dawn/native/d3d11/PhysicalDeviceD3D11.h
index 9b2efa8..01e28fc 100644
--- a/src/dawn/native/d3d11/PhysicalDeviceD3D11.h
+++ b/src/dawn/native/d3d11/PhysicalDeviceD3D11.h
@@ -75,7 +75,7 @@
wgpu::FeatureName feature,
const TogglesState& toggles) const override;
- void PopulateMemoryHeapInfo(AdapterPropertiesMemoryHeaps* memoryHeapProperties) const override;
+ void PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const override;
const bool mIsSharedD3D11Device;
ComPtr<ID3D11Device> mD3D11Device;
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
index 34fa781..204f704 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
@@ -144,6 +144,7 @@
EnableFeature(Feature::DualSourceBlending);
EnableFeature(Feature::Norm16TextureFormats);
EnableFeature(Feature::AdapterPropertiesMemoryHeaps);
+ EnableFeature(Feature::AdapterPropertiesD3D);
if (AreTimestampQueriesSupported()) {
EnableFeature(Feature::TimestampQuery);
@@ -724,39 +725,43 @@
return {};
}
-void PhysicalDevice::PopulateMemoryHeapInfo(
- AdapterPropertiesMemoryHeaps* memoryHeapProperties) const {
- // https://microsoft.github.io/DirectX-Specs/d3d/D3D12GPUUploadHeaps.html describes
- // the properties of D3D12 Default/Upload/Readback heaps.
- if (mDeviceInfo.isUMA) {
- auto* heapInfo = new MemoryHeapInfo[1];
- memoryHeapProperties->heapCount = 1;
- memoryHeapProperties->heapInfo = heapInfo;
+void PhysicalDevice::PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const {
+ if (auto* memoryHeapProperties = properties.Get<AdapterPropertiesMemoryHeaps>()) {
+ // https://microsoft.github.io/DirectX-Specs/d3d/D3D12GPUUploadHeaps.html describes
+ // the properties of D3D12 Default/Upload/Readback heaps.
+ if (mDeviceInfo.isUMA) {
+ auto* heapInfo = new MemoryHeapInfo[1];
+ memoryHeapProperties->heapCount = 1;
+ memoryHeapProperties->heapInfo = heapInfo;
- heapInfo[0].size =
- std::max(mDeviceInfo.dedicatedVideoMemory, mDeviceInfo.sharedSystemMemory);
+ heapInfo[0].size =
+ std::max(mDeviceInfo.dedicatedVideoMemory, mDeviceInfo.sharedSystemMemory);
- if (mDeviceInfo.isCacheCoherentUMA) {
- heapInfo[0].properties =
- wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
- wgpu::HeapProperty::HostCoherent | wgpu::HeapProperty::HostCached;
+ if (mDeviceInfo.isCacheCoherentUMA) {
+ heapInfo[0].properties =
+ wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
+ wgpu::HeapProperty::HostCoherent | wgpu::HeapProperty::HostCached;
+ } else {
+ heapInfo[0].properties =
+ wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
+ wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
+ }
} else {
- heapInfo[0].properties =
- wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
+ auto* heapInfo = new MemoryHeapInfo[2];
+ memoryHeapProperties->heapCount = 2;
+ memoryHeapProperties->heapInfo = heapInfo;
+
+ heapInfo[0].size = mDeviceInfo.dedicatedVideoMemory;
+ heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal;
+
+ heapInfo[1].size = mDeviceInfo.sharedSystemMemory;
+ heapInfo[1].properties =
+ wgpu::HeapProperty::HostVisible | wgpu::HeapProperty::HostCoherent |
wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
}
- } else {
- auto* heapInfo = new MemoryHeapInfo[2];
- memoryHeapProperties->heapCount = 2;
- memoryHeapProperties->heapInfo = heapInfo;
-
- heapInfo[0].size = mDeviceInfo.dedicatedVideoMemory;
- heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal;
-
- heapInfo[1].size = mDeviceInfo.sharedSystemMemory;
- heapInfo[1].properties = wgpu::HeapProperty::HostVisible |
- wgpu::HeapProperty::HostCoherent |
- wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
+ }
+ if (auto* d3dProperties = properties.Get<AdapterPropertiesD3D>()) {
+ d3dProperties->shaderModel = GetDeviceInfo().shaderModel;
}
}
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.h b/src/dawn/native/d3d12/PhysicalDeviceD3D12.h
index 9a978a5..96f6974 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.h
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.h
@@ -76,7 +76,7 @@
MaybeError InitializeDebugLayerFilters();
void CleanUpDebugLayerFilters();
- void PopulateMemoryHeapInfo(AdapterPropertiesMemoryHeaps* memoryHeapProperties) const override;
+ void PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const override;
ComPtr<ID3D12Device> mD3d12Device;
diff --git a/src/dawn/native/metal/BackendMTL.mm b/src/dawn/native/metal/BackendMTL.mm
index 8df96d4..ac41c1b 100644
--- a/src/dawn/native/metal/BackendMTL.mm
+++ b/src/dawn/native/metal/BackendMTL.mm
@@ -891,49 +891,51 @@
return {};
}
- void PopulateMemoryHeapInfo(AdapterPropertiesMemoryHeaps* memoryHeapProperties) const override {
- if ([*mDevice hasUnifiedMemory]) {
- auto* heapInfo = new MemoryHeapInfo[1];
- memoryHeapProperties->heapCount = 1;
- memoryHeapProperties->heapInfo = heapInfo;
+ void PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const override {
+ if (auto* memoryHeapProperties = properties.Get<AdapterPropertiesMemoryHeaps>()) {
+ if ([*mDevice hasUnifiedMemory]) {
+ auto* heapInfo = new MemoryHeapInfo[1];
+ memoryHeapProperties->heapCount = 1;
+ memoryHeapProperties->heapInfo = heapInfo;
- heapInfo[0].properties =
- wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
- wgpu::HeapProperty::HostCoherent | wgpu::HeapProperty::HostCached;
+ heapInfo[0].properties =
+ wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
+ wgpu::HeapProperty::HostCoherent | wgpu::HeapProperty::HostCached;
// TODO(dawn:2249): Enable on iOS. Some XCode or SDK versions seem to not match the docs.
#if DAWN_PLATFORM_IS(MACOS)
- if (@available(macOS 10.12, iOS 16.0, *)) {
- heapInfo[0].size = [*mDevice recommendedMaxWorkingSetSize];
- } else
+ if (@available(macOS 10.12, iOS 16.0, *)) {
+ heapInfo[0].size = [*mDevice recommendedMaxWorkingSetSize];
+ } else
#endif
- {
- // Since AdapterPropertiesMemoryHeaps is already gated on the
- // availability and #ifdef above, we should never reach this case, however
- // excluding the conditional causes build errors.
- DAWN_UNREACHABLE();
- }
- } else {
+ {
+ // Since AdapterPropertiesMemoryHeaps is already gated on the
+ // availability and #ifdef above, we should never reach this case, however
+ // excluding the conditional causes build errors.
+ DAWN_UNREACHABLE();
+ }
+ } else {
#if DAWN_PLATFORM_IS(MACOS)
- auto* heapInfo = new MemoryHeapInfo[2];
- memoryHeapProperties->heapCount = 2;
- memoryHeapProperties->heapInfo = heapInfo;
+ auto* heapInfo = new MemoryHeapInfo[2];
+ memoryHeapProperties->heapCount = 2;
+ memoryHeapProperties->heapInfo = heapInfo;
- heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal;
- heapInfo[0].size = [*mDevice recommendedMaxWorkingSetSize];
+ heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal;
+ heapInfo[0].size = [*mDevice recommendedMaxWorkingSetSize];
- mach_msg_type_number_t hostBasicInfoMsg = HOST_BASIC_INFO_COUNT;
- host_basic_info_data_t hostInfo{};
- DAWN_CHECK(host_info(mach_host_self(), HOST_BASIC_INFO,
- reinterpret_cast<host_info_t>(&hostInfo),
- &hostBasicInfoMsg) == KERN_SUCCESS);
+ mach_msg_type_number_t hostBasicInfoMsg = HOST_BASIC_INFO_COUNT;
+ host_basic_info_data_t hostInfo{};
+ DAWN_CHECK(host_info(mach_host_self(), HOST_BASIC_INFO,
+ reinterpret_cast<host_info_t>(&hostInfo),
+ &hostBasicInfoMsg) == KERN_SUCCESS);
- heapInfo[1].properties = wgpu::HeapProperty::HostVisible |
- wgpu::HeapProperty::HostCoherent |
- wgpu::HeapProperty::HostCached;
- heapInfo[1].size = hostInfo.max_mem;
+ heapInfo[1].properties = wgpu::HeapProperty::HostVisible |
+ wgpu::HeapProperty::HostCoherent |
+ wgpu::HeapProperty::HostCached;
+ heapInfo[1].size = hostInfo.max_mem;
#else
- DAWN_UNREACHABLE();
+ DAWN_UNREACHABLE();
#endif
+ }
}
}
diff --git a/src/dawn/native/null/DeviceNull.cpp b/src/dawn/native/null/DeviceNull.cpp
index fc3cbd8..0568e9e 100644
--- a/src/dawn/native/null/DeviceNull.cpp
+++ b/src/dawn/native/null/DeviceNull.cpp
@@ -95,15 +95,19 @@
return Device::Create(adapter, descriptor, deviceToggles);
}
-void PhysicalDevice::PopulateMemoryHeapInfo(
- AdapterPropertiesMemoryHeaps* memoryHeapProperties) const {
- auto* heapInfo = new MemoryHeapInfo[1];
- memoryHeapProperties->heapCount = 1;
- memoryHeapProperties->heapInfo = heapInfo;
+void PhysicalDevice::PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const {
+ if (auto* memoryHeapProperties = properties.Get<AdapterPropertiesMemoryHeaps>()) {
+ auto* heapInfo = new MemoryHeapInfo[1];
+ memoryHeapProperties->heapCount = 1;
+ memoryHeapProperties->heapInfo = heapInfo;
- heapInfo[0].size = 1024 * 1024 * 1024;
- heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
- wgpu::HeapProperty::HostCached;
+ heapInfo[0].size = 1024 * 1024 * 1024;
+ heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
+ wgpu::HeapProperty::HostCached;
+ }
+ if (auto* d3dProperties = properties.Get<AdapterPropertiesD3D>()) {
+ d3dProperties->shaderModel = 0;
+ }
}
FeatureValidationResult PhysicalDevice::ValidateFeatureSupportedWithTogglesImpl(
diff --git a/src/dawn/native/null/DeviceNull.h b/src/dawn/native/null/DeviceNull.h
index 153a6b2..3dc298f 100644
--- a/src/dawn/native/null/DeviceNull.h
+++ b/src/dawn/native/null/DeviceNull.h
@@ -211,7 +211,7 @@
const UnpackedPtr<DeviceDescriptor>& descriptor,
const TogglesState& deviceToggles) override;
- void PopulateMemoryHeapInfo(AdapterPropertiesMemoryHeaps* memoryHeapProperties) const override;
+ void PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const override;
};
// Helper class so |BindGroup| can allocate memory for its binding data,
diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.cpp b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
index 21fbb2b..4d95453 100644
--- a/src/dawn/native/opengl/PhysicalDeviceGL.cpp
+++ b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
@@ -428,9 +428,6 @@
return {};
}
-void PhysicalDevice::PopulateMemoryHeapInfo(
- AdapterPropertiesMemoryHeaps* memoryHeapProperties) const {
- DAWN_UNREACHABLE();
-}
+void PhysicalDevice::PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const {}
} // namespace dawn::native::opengl
diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.h b/src/dawn/native/opengl/PhysicalDeviceGL.h
index 4af8540..e2f4771 100644
--- a/src/dawn/native/opengl/PhysicalDeviceGL.h
+++ b/src/dawn/native/opengl/PhysicalDeviceGL.h
@@ -65,7 +65,7 @@
const UnpackedPtr<DeviceDescriptor>& descriptor,
const TogglesState& deviceToggles) override;
- void PopulateMemoryHeapInfo(AdapterPropertiesMemoryHeaps* memoryHeapProperties) const override;
+ void PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const override;
OpenGLFunctions mFunctions;
EGLDisplay mDisplay;
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
index f9e98d0..2530f43 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
@@ -815,31 +815,32 @@
return mDefaultComputeSubgroupSize;
}
-void PhysicalDevice::PopulateMemoryHeapInfo(
- AdapterPropertiesMemoryHeaps* memoryHeapProperties) const {
- size_t count = mDeviceInfo.memoryHeaps.size();
- auto* heapInfo = new MemoryHeapInfo[count];
- memoryHeapProperties->heapCount = count;
- memoryHeapProperties->heapInfo = heapInfo;
+void PhysicalDevice::PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const {
+ if (auto* memoryHeapProperties = properties.Get<AdapterPropertiesMemoryHeaps>()) {
+ size_t count = mDeviceInfo.memoryHeaps.size();
+ auto* heapInfo = new MemoryHeapInfo[count];
+ memoryHeapProperties->heapCount = count;
+ memoryHeapProperties->heapInfo = heapInfo;
- for (size_t i = 0; i < count; ++i) {
- heapInfo[i].size = mDeviceInfo.memoryHeaps[i].size;
- heapInfo[i].properties = {};
- if (mDeviceInfo.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
- heapInfo[i].properties |= wgpu::HeapProperty::DeviceLocal;
+ for (size_t i = 0; i < count; ++i) {
+ heapInfo[i].size = mDeviceInfo.memoryHeaps[i].size;
+ heapInfo[i].properties = {};
+ if (mDeviceInfo.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
+ heapInfo[i].properties |= wgpu::HeapProperty::DeviceLocal;
+ }
}
- }
- for (const auto& memoryType : mDeviceInfo.memoryTypes) {
- if (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
- heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostVisible;
- }
- if (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
- heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostCoherent;
- }
- if (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
- heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostCached;
- } else {
- heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostUncached;
+ for (const auto& memoryType : mDeviceInfo.memoryTypes) {
+ if (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
+ heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostVisible;
+ }
+ if (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
+ heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostCoherent;
+ }
+ if (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
+ heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostCached;
+ } else {
+ heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostUncached;
+ }
}
}
}
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.h b/src/dawn/native/vulkan/PhysicalDeviceVk.h
index 2c8038b..8da4917 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.h
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.h
@@ -80,7 +80,7 @@
bool CheckSemaphoreSupport(DeviceExt deviceExt,
VkExternalSemaphoreHandleTypeFlagBits handleType) const;
- void PopulateMemoryHeapInfo(AdapterPropertiesMemoryHeaps* memoryHeapProperties) const override;
+ void PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const override;
VkPhysicalDevice mVkPhysicalDevice;
Ref<VulkanInstance> mVulkanInstance;
diff --git a/src/dawn/tests/BUILD.gn b/src/dawn/tests/BUILD.gn
index 49583af2..a5ffcab 100644
--- a/src/dawn/tests/BUILD.gn
+++ b/src/dawn/tests/BUILD.gn
@@ -573,6 +573,7 @@
sources = [
"end2end/AdapterCreationTests.cpp",
"end2end/AdapterEnumerationTests.cpp",
+ "end2end/AdapterPropertiesD3DTests.cpp",
"end2end/BasicTests.cpp",
"end2end/BindGroupTests.cpp",
"end2end/BufferHostMappedPointerTests.cpp",
diff --git a/src/dawn/tests/end2end/AdapterPropertiesD3DTests.cpp b/src/dawn/tests/end2end/AdapterPropertiesD3DTests.cpp
new file mode 100644
index 0000000..f480dc5
--- /dev/null
+++ b/src/dawn/tests/end2end/AdapterPropertiesD3DTests.cpp
@@ -0,0 +1,61 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "dawn/tests/DawnTest.h"
+
+namespace dawn {
+namespace {
+
+class AdapterPropertiesD3DTest : public DawnTest {};
+
+// TODO(dawn:2257) test that is is invalid to request AdapterPropertiesD3D if the
+// feature is not available.
+
+// 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;
+
+ adapter.GetProperties(&properties);
+
+ // This is the minimum D3D shader model Dawn supports.
+ EXPECT_GE(d3dProperties.shaderModel, 50u);
+}
+
+DAWN_INSTANTIATE_TEST(AdapterPropertiesD3DTest,
+ D3D11Backend(),
+ D3D12Backend(),
+ MetalBackend(),
+ OpenGLBackend(),
+ OpenGLESBackend(),
+ VulkanBackend());
+
+} // anonymous namespace
+} // namespace dawn
diff --git a/src/dawn/tests/unittests/wire/WireAdapterTests.cpp b/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
index 1f6b889..97d08c3 100644
--- a/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
@@ -77,9 +77,7 @@
apiAdapter = api.GetNewAdapter();
EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), NotNull(), NotNull()))
.WillOnce(InvokeWithoutArgs([&] {
- EXPECT_CALL(api, AdapterHasFeature(apiAdapter,
- WGPUFeatureName_AdapterPropertiesMemoryHeaps))
- .WillOnce(Return(false));
+ EXPECT_CALL(api, AdapterHasFeature(apiAdapter, _)).WillRepeatedly(Return(false));
EXPECT_CALL(api, AdapterGetProperties(apiAdapter, NotNull()))
.WillOnce(WithArg<1>(Invoke([&](WGPUAdapterProperties* properties) {
diff --git a/src/dawn/tests/unittests/wire/WireInstanceTests.cpp b/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
index 2caf2e0..7357998 100644
--- a/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
@@ -207,8 +207,8 @@
});
}
-// Test that RequestAdapter forwards the memory heap properties to the client.
-TEST_P(WireInstanceTests, RequestAdapterPassesMemoryHeapProperties) {
+// Test that RequestAdapter forwards all chained properties to the client.
+TEST_P(WireInstanceTests, RequestAdapterPassesChainedProperties) {
WGPURequestAdapterOptions options = {};
InstanceRequestAdapter(instance, &options, nullptr);
@@ -223,17 +223,22 @@
fakeMemoryHeapProperties.heapCount = 3;
fakeMemoryHeapProperties.heapInfo = fakeHeapInfo;
+ WGPUAdapterPropertiesD3D fakeD3DProperties = {};
+ fakeD3DProperties.chain.sType = WGPUSType_AdapterPropertiesD3D;
+ fakeD3DProperties.shaderModel = 61;
+
std::initializer_list<WGPUFeatureName> fakeFeatures = {
WGPUFeatureName_AdapterPropertiesMemoryHeaps,
+ WGPUFeatureName_AdapterPropertiesD3D,
};
// Expect the server to receive the message. Then, mock a fake reply.
WGPUAdapter apiAdapter = api.GetNewAdapter();
EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), NotNull(), NotNull()))
.WillOnce(InvokeWithoutArgs([&] {
- EXPECT_CALL(api,
- AdapterHasFeature(apiAdapter, WGPUFeatureName_AdapterPropertiesMemoryHeaps))
- .WillOnce(Return(true));
+ for (WGPUFeatureName feature : fakeFeatures) {
+ EXPECT_CALL(api, AdapterHasFeature(apiAdapter, feature)).WillOnce(Return(true));
+ }
EXPECT_CALL(api, AdapterGetProperties(apiAdapter, NotNull()))
.WillOnce(WithArg<1>(Invoke([&](WGPUAdapterProperties* properties) {
@@ -242,10 +247,27 @@
properties->name = "fake adapter";
properties->driverDescription = "hello world";
- EXPECT_EQ(properties->nextInChain->sType,
- WGPUSType_AdapterPropertiesMemoryHeaps);
- *reinterpret_cast<WGPUAdapterPropertiesMemoryHeaps*>(properties->nextInChain) =
- fakeMemoryHeapProperties;
+ WGPUChainedStructOut* chain = properties->nextInChain;
+ while (chain != nullptr) {
+ auto* next = chain->next;
+ switch (chain->sType) {
+ case WGPUSType_AdapterPropertiesMemoryHeaps:
+ *reinterpret_cast<WGPUAdapterPropertiesMemoryHeaps*>(chain) =
+ fakeMemoryHeapProperties;
+ break;
+ case WGPUSType_AdapterPropertiesD3D:
+ *reinterpret_cast<WGPUAdapterPropertiesD3D*>(chain) =
+ fakeD3DProperties;
+ break;
+ default:
+ FAIL() << "Unexpected chain";
+ }
+ // update next pointer back to the original since it would be overwritten
+ // in the switch statement
+ chain->next = next;
+
+ chain = next;
+ }
})));
EXPECT_CALL(api, AdapterGetLimits(apiAdapter, NotNull()))
@@ -295,6 +317,14 @@
EXPECT_EQ(memoryHeapProperties.heapInfo[i].size,
fakeMemoryHeapProperties.heapInfo[i].size);
}
+
+ // Get the D3D properties.
+ WGPUAdapterPropertiesD3D d3dProperties = {};
+ d3dProperties.chain.sType = WGPUSType_AdapterPropertiesD3D;
+ properties.nextInChain = &d3dProperties.chain;
+ wgpuAdapterGetProperties(adapter, &properties);
+ // Expect them to match.
+ EXPECT_EQ(d3dProperties.shaderModel, fakeD3DProperties.shaderModel);
})));
FlushCallbacks();
diff --git a/src/dawn/wire/SupportedFeatures.cpp b/src/dawn/wire/SupportedFeatures.cpp
index 1526eb8..1a9a893 100644
--- a/src/dawn/wire/SupportedFeatures.cpp
+++ b/src/dawn/wire/SupportedFeatures.cpp
@@ -93,6 +93,7 @@
case WGPUFeatureName_Norm16TextureFormats:
case WGPUFeatureName_FramebufferFetch:
case WGPUFeatureName_AdapterPropertiesMemoryHeaps:
+ case WGPUFeatureName_AdapterPropertiesD3D:
return true;
}
diff --git a/src/dawn/wire/client/Adapter.cpp b/src/dawn/wire/client/Adapter.cpp
index 7537079..20c9dae 100644
--- a/src/dawn/wire/client/Adapter.cpp
+++ b/src/dawn/wire/client/Adapter.cpp
@@ -151,6 +151,11 @@
memoryHeapProperties->heapInfo + memoryHeapProperties->heapCount};
break;
}
+ case WGPUSType_AdapterPropertiesD3D: {
+ auto* d3dProperties = reinterpret_cast<WGPUAdapterPropertiesD3D*>(chain);
+ mD3DProperties.shaderModel = d3dProperties->shaderModel;
+ break;
+ }
default:
DAWN_UNREACHABLE();
break;
@@ -176,6 +181,11 @@
memoryHeapProperties->heapInfo = heapInfo;
break;
}
+ case WGPUSType_AdapterPropertiesD3D: {
+ auto* d3dProperties = reinterpret_cast<WGPUAdapterPropertiesD3D*>(chain);
+ d3dProperties->shaderModel = mD3DProperties.shaderModel;
+ break;
+ }
default:
break;
}
diff --git a/src/dawn/wire/client/Adapter.h b/src/dawn/wire/client/Adapter.h
index 79021e9..c200053 100644
--- a/src/dawn/wire/client/Adapter.h
+++ b/src/dawn/wire/client/Adapter.h
@@ -68,6 +68,7 @@
LimitsAndFeatures mLimitsAndFeatures;
WGPUAdapterProperties mProperties;
std::vector<WGPUMemoryHeapInfo> mMemoryHeapInfo;
+ WGPUAdapterPropertiesD3D mD3DProperties;
struct RequestDeviceData {
WGPURequestDeviceCallback callback = nullptr;
diff --git a/src/dawn/wire/server/ServerInstance.cpp b/src/dawn/wire/server/ServerInstance.cpp
index 24a69a2..bb09833 100644
--- a/src/dawn/wire/server/ServerInstance.cpp
+++ b/src/dawn/wire/server/ServerInstance.cpp
@@ -88,12 +88,22 @@
// Query and report the adapter properties.
WGPUAdapterProperties properties = {};
+ WGPUChainedStructOut** propertiesChain = &properties.nextInChain;
// Query AdapterPropertiesMemoryHeaps if the feature is supported.
WGPUAdapterPropertiesMemoryHeaps memoryHeapProperties = {};
memoryHeapProperties.chain.sType = WGPUSType_AdapterPropertiesMemoryHeaps;
if (mProcs.adapterHasFeature(adapter, WGPUFeatureName_AdapterPropertiesMemoryHeaps)) {
- properties.nextInChain = &memoryHeapProperties.chain;
+ *propertiesChain = &memoryHeapProperties.chain;
+ propertiesChain = &(*propertiesChain)->next;
+ }
+
+ // Query AdapterPropertiesD3D if the feature is supported.
+ WGPUAdapterPropertiesD3D d3dProperties = {};
+ d3dProperties.chain.sType = WGPUSType_AdapterPropertiesD3D;
+ if (mProcs.adapterHasFeature(adapter, WGPUFeatureName_AdapterPropertiesD3D)) {
+ *propertiesChain = &d3dProperties.chain;
+ propertiesChain = &(*propertiesChain)->next;
}
mProcs.adapterGetProperties(adapter, &properties);