Add WinUI SwapChainPanel support
Change-Id: I0cd6fc9a56912095fb7ef3b8b2ecdd26c143f4f9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/234055
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index e1d9ed2..50861d5 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -3696,7 +3696,16 @@
{"name": "core window", "type": "void", "annotation": "*"}
]
},
- "surface descriptor from windows swap chain panel": {
+ "surface descriptor from windows UWP swap chain panel": {
+ "category": "structure",
+ "chained": "in",
+ "chain roots": ["surface descriptor"],
+ "tags": ["dawn"],
+ "members": [
+ {"name": "swap chain panel", "type": "void", "annotation": "*"}
+ ]
+ },
+ "surface descriptor from windows WinUI swap chain panel": {
"category": "structure",
"chained": "in",
"chain roots": ["surface descriptor"],
@@ -3763,7 +3772,7 @@
{"value": 0, "name": "surface descriptor from windows core window", "tags": ["dawn"]},
{"value": 1, "name": "external texture binding entry", "tags": ["dawn"]},
{"value": 2, "name": "external texture binding layout", "tags": ["dawn"]},
- {"value": 3, "name": "surface descriptor from windows swap chain panel", "tags": ["dawn"]},
+ {"value": 3, "name": "surface descriptor from windows UWP swap chain panel", "tags": ["dawn"]},
{"value": 4, "name": "dawn texture internal usage descriptor", "tags": ["dawn"]},
{"value": 5, "name": "dawn encoder internal usage descriptor", "tags": ["dawn"]},
{"value": 6, "name": "dawn instance descriptor", "tags": ["dawn", "native"]},
@@ -3825,7 +3834,8 @@
{"value": 61, "name": "shared fence EGL sync export info", "tags": ["dawn", "native"]},
{"value": 62, "name": "dawn injected invalid s type", "tags": ["dawn"]},
{"value": 63, "name": "dawn compilation message utf16", "tags": ["dawn", "emscripten"]},
- {"value": 64, "name": "dawn fake buffer OOM for testing", "tags": ["dawn"]}
+ {"value": 64, "name": "dawn fake buffer OOM for testing", "tags": ["dawn"]},
+ {"value": 65, "name": "surface descriptor from windows WinUI swap chain panel", "tags": ["dawn"]}
]
},
"texture": {
diff --git a/src/dawn/dawn_wire.json b/src/dawn/dawn_wire.json
index 01d17e2..aeceb9b 100644
--- a/src/dawn/dawn_wire.json
+++ b/src/dawn/dawn_wire.json
@@ -221,7 +221,8 @@
"client_side_structures": [
"FutureWaitInfo",
"SurfaceDescriptorFromWindowsCoreWindow",
- "SurfaceDescriptorFromWindowsSwapChainPanel",
+ "SurfaceDescriptorFromWindowsUWPSwapChainPanel",
+ "SurfaceDescriptorFromWindowsWinUISwapChainPanel",
"SurfaceSourceMetalLayer",
"SurfaceSourceWindowsHWND",
"SurfaceSourceXlibWindow",
diff --git a/src/dawn/native/Surface.cpp b/src/dawn/native/Surface.cpp
index 01d4c74..d0b30ae 100644
--- a/src/dawn/native/Surface.cpp
+++ b/src/dawn/native/Surface.cpp
@@ -76,8 +76,11 @@
case Surface::Type::WindowsCoreWindow:
s->Append("WindowsCoreWindow");
break;
- case Surface::Type::WindowsSwapChainPanel:
- s->Append("WindowsSwapChainPanel");
+ case Surface::Type::WindowsUWPSwapChainPanel:
+ s->Append("WindowsUWPSwapChainPanel");
+ break;
+ case Surface::Type::WindowsWinUISwapChainPanel:
+ s->Append("WindowsWinUISwapChainPanel");
break;
case Surface::Type::XlibWindow:
s->Append("XlibWindow");
@@ -104,7 +107,8 @@
type, (descriptor.ValidateBranches<
Branch<SurfaceSourceAndroidNativeWindow>, Branch<SurfaceSourceMetalLayer>,
Branch<SurfaceSourceWindowsHWND>, Branch<SurfaceDescriptorFromWindowsCoreWindow>,
- Branch<SurfaceDescriptorFromWindowsSwapChainPanel>,
+ Branch<SurfaceDescriptorFromWindowsUWPSwapChainPanel>,
+ Branch<SurfaceDescriptorFromWindowsWinUISwapChainPanel>,
Branch<SurfaceSourceXlibWindow>, Branch<SurfaceSourceWaylandSurface>>()));
switch (type) {
#if DAWN_PLATFORM_IS(ANDROID)
@@ -145,8 +149,8 @@
"Invalid CoreWindow");
return descriptor;
}
- case wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel: {
- auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsSwapChainPanel>();
+ case wgpu::SType::SurfaceDescriptorFromWindowsUWPSwapChainPanel: {
+ auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsUWPSwapChainPanel>();
DAWN_ASSERT(subDesc != nullptr);
// Validate the swapChainPanel by querying for ISwapChainPanel interface
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel;
@@ -156,6 +160,15 @@
"Invalid SwapChainPanel");
return descriptor;
}
+ case wgpu::SType::SurfaceDescriptorFromWindowsWinUISwapChainPanel: {
+ auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsWinUISwapChainPanel>();
+ DAWN_ASSERT(subDesc != nullptr);
+ // Unfortunately, checking whether this is a valid
+ // Microsoft.UI.Xaml.Controls.SwapChainPanel would require the WindowsAppSDK as a
+ // dependency, which is not trivial. So we'll only check for nullptr here.
+ DAWN_INVALID_IF(subDesc->swapChainPanel == nullptr, "SwapChainPanel is nullptr.");
+ return descriptor;
+ }
#endif // defined(DAWN_USE_WINDOWS_UI)
#if defined(DAWN_USE_WAYLAND)
case wgpu::SType::SurfaceSourceWaylandSurface: {
@@ -283,8 +296,9 @@
.ValidateBranches<
Branch<SurfaceSourceAndroidNativeWindow>, Branch<SurfaceSourceMetalLayer>,
Branch<SurfaceSourceWindowsHWND>, Branch<SurfaceDescriptorFromWindowsCoreWindow>,
- Branch<SurfaceDescriptorFromWindowsSwapChainPanel>, Branch<SurfaceSourceXlibWindow>,
- Branch<SurfaceSourceWaylandSurface>>()
+ Branch<SurfaceDescriptorFromWindowsUWPSwapChainPanel>,
+ Branch<SurfaceDescriptorFromWindowsWinUISwapChainPanel>,
+ Branch<SurfaceSourceXlibWindow>, Branch<SurfaceSourceWaylandSurface>>()
.AcquireSuccess();
switch (type) {
case wgpu::SType::SurfaceSourceAndroidNativeWindow: {
@@ -313,10 +327,16 @@
mCoreWindow = static_cast<IUnknown*>(subDesc->coreWindow);
break;
}
- case wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel: {
- auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsSwapChainPanel>();
- mType = Type::WindowsSwapChainPanel;
- mSwapChainPanel = static_cast<IUnknown*>(subDesc->swapChainPanel);
+ case wgpu::SType::SurfaceDescriptorFromWindowsUWPSwapChainPanel: {
+ auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsUWPSwapChainPanel>();
+ mType = Type::WindowsUWPSwapChainPanel;
+ mUWPSwapChainPanel = static_cast<IUnknown*>(subDesc->swapChainPanel);
+ break;
+ }
+ case wgpu::SType::SurfaceDescriptorFromWindowsWinUISwapChainPanel: {
+ auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsWinUISwapChainPanel>();
+ mType = Type::WindowsWinUISwapChainPanel;
+ mWinUISwapChainPanel = static_cast<IUnknown*>(subDesc->swapChainPanel);
break;
}
#endif // defined(DAWN_USE_WINDOWS_UI)
@@ -406,11 +426,21 @@
#endif
}
-IUnknown* Surface::GetSwapChainPanel() const {
+IUnknown* Surface::GetUWPSwapChainPanel() const {
DAWN_ASSERT(!IsError());
- DAWN_ASSERT(mType == Type::WindowsSwapChainPanel);
+ DAWN_ASSERT(mType == Type::WindowsUWPSwapChainPanel);
#if defined(DAWN_USE_WINDOWS_UI)
- return mSwapChainPanel.Get();
+ return mUWPSwapChainPanel.Get();
+#else
+ return nullptr;
+#endif
+}
+
+IUnknown* Surface::GetWinUISwapChainPanel() const {
+ DAWN_ASSERT(!IsError());
+ DAWN_ASSERT(mType == Type::WindowsWinUISwapChainPanel);
+#if defined(DAWN_USE_WINDOWS_UI)
+ return mWinUISwapChainPanel.Get();
#else
return nullptr;
#endif
diff --git a/src/dawn/native/Surface.h b/src/dawn/native/Surface.h
index eaabd5a..4b075b9 100644
--- a/src/dawn/native/Surface.h
+++ b/src/dawn/native/Surface.h
@@ -83,7 +83,8 @@
WaylandSurface,
WindowsHWND,
WindowsCoreWindow,
- WindowsSwapChainPanel,
+ WindowsUWPSwapChainPanel,
+ WindowsWinUISwapChainPanel,
XlibWindow,
};
Type GetType() const;
@@ -107,8 +108,11 @@
// Valid to call if the type is WindowsCoreWindow
IUnknown* GetCoreWindow() const;
- // Valid to call if the type is WindowsSwapChainPanel
- IUnknown* GetSwapChainPanel() const;
+ // Valid to call if the type is WindowsUWPSwapChainPanel
+ IUnknown* GetUWPSwapChainPanel() const;
+
+ // Valid to call if the type is WindowsWinUISwapChainPanel
+ IUnknown* GetWinUISwapChainPanel() const;
// Valid to call if the type is WindowsXlib
void* GetXDisplay() const;
@@ -169,8 +173,11 @@
// WindowsCoreWindow
ComPtr<IUnknown> mCoreWindow;
- // WindowsSwapChainPanel
- ComPtr<IUnknown> mSwapChainPanel;
+ // WindowsUWPSwapChainPanel
+ ComPtr<IUnknown> mUWPSwapChainPanel;
+
+ // WindowsWinUISwapChainPanel
+ ComPtr<IUnknown> mWinUISwapChainPanel;
#endif // defined(DAWN_USE_WINDOWS_UI)
// Xlib
diff --git a/src/dawn/native/d3d/SwapChainD3D.cpp b/src/dawn/native/d3d/SwapChainD3D.cpp
index eb9a69f..55a452d 100644
--- a/src/dawn/native/d3d/SwapChainD3D.cpp
+++ b/src/dawn/native/d3d/SwapChainD3D.cpp
@@ -101,6 +101,17 @@
return dxgiUsage;
}
+#if defined(DAWN_USE_WINDOWS_UI)
+// Interface from microsoft.ui.xaml.media.dxinterop.h
+MIDL_INTERFACE("63aad0b8-7c24-40ff-85a8-640d944cc325")
+IWinUISwapChainPanelNative : public IUnknown {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE SetSwapChain(
+ /* [annotation][in] */
+ _In_ IDXGISwapChain * swapChain) = 0;
+};
+#endif // defined(DAWN_USE_WINDOWS_UI)
+
} // namespace
SwapChain::~SwapChain() = default;
@@ -109,7 +120,11 @@
// nullptr. If it is not nullptr it means that it is the swapchain previously in use on the
// surface and that we have a chance to reuse it's underlying IDXGISwapChain and "buffers".
MaybeError SwapChain::Initialize(SwapChainBase* previousSwapChain) {
- DAWN_ASSERT(GetSurface()->GetType() == Surface::Type::WindowsHWND);
+ Surface::Type surfaceType = GetSurface()->GetType();
+ DAWN_ASSERT(surfaceType == Surface::Type::WindowsHWND ||
+ surfaceType == Surface::Type::WindowsCoreWindow ||
+ surfaceType == Surface::Type::WindowsUWPSwapChainPanel ||
+ surfaceType == Surface::Type::WindowsWinUISwapChainPanel);
// Precompute the configuration parameters we want for the DXGI swapchain.
mConfig.bufferCount = PresentModeToBufferCount(GetPresentMode());
@@ -224,13 +239,26 @@
break;
}
#if defined(DAWN_USE_WINDOWS_UI)
- case Surface::Type::WindowsSwapChainPanel: {
+ case Surface::Type::WindowsUWPSwapChainPanel: {
DAWN_TRY(CheckHRESULT(
factory2->CreateSwapChainForComposition(GetD3DDeviceForCreatingSwapChain(),
&swapChainDesc, nullptr, &swapChain1),
"Creating the IDXGISwapChain1"));
ComPtr<ISwapChainPanelNative> swapChainPanelNative;
- DAWN_TRY(CheckHRESULT(GetSurface()->GetSwapChainPanel()->QueryInterface(
+ DAWN_TRY(CheckHRESULT(GetSurface()->GetUWPSwapChainPanel()->QueryInterface(
+ IID_PPV_ARGS(&swapChainPanelNative)),
+ "Getting ISwapChainPanelNative"));
+ DAWN_TRY(CheckHRESULT(swapChainPanelNative->SetSwapChain(swapChain1.Get()),
+ "Setting SwapChain"));
+ break;
+ }
+ case Surface::Type::WindowsWinUISwapChainPanel: {
+ DAWN_TRY(CheckHRESULT(
+ factory2->CreateSwapChainForComposition(GetD3DDeviceForCreatingSwapChain(),
+ &swapChainDesc, nullptr, &swapChain1),
+ "Creating the IDXGISwapChain1"));
+ ComPtr<IWinUISwapChainPanelNative> swapChainPanelNative;
+ DAWN_TRY(CheckHRESULT(GetSurface()->GetWinUISwapChainPanel()->QueryInterface(
IID_PPV_ARGS(&swapChainPanelNative)),
"Getting ISwapChainPanelNative"));
DAWN_TRY(CheckHRESULT(swapChainPanelNative->SetSwapChain(swapChain1.Get()),
diff --git a/src/dawn/tests/white_box/EGLImageWrappingTests.cpp b/src/dawn/tests/white_box/EGLImageWrappingTests.cpp
index 2631e14..8dd7100 100644
--- a/src/dawn/tests/white_box/EGLImageWrappingTests.cpp
+++ b/src/dawn/tests/white_box/EGLImageWrappingTests.cpp
@@ -228,7 +228,7 @@
DAWN_TEST_UNSUPPORTED_IF(UsesWire());
wgpu::ChainedStruct chainedDescriptor;
- chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel;
+ chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsUWPSwapChainPanel;
descriptor.nextInChain = &chainedDescriptor;
ScopedEGLImage image = CreateDefaultEGLImage();
diff --git a/src/dawn/tests/white_box/GLTextureWrappingTests.cpp b/src/dawn/tests/white_box/GLTextureWrappingTests.cpp
index 3154020..fb31458 100644
--- a/src/dawn/tests/white_box/GLTextureWrappingTests.cpp
+++ b/src/dawn/tests/white_box/GLTextureWrappingTests.cpp
@@ -179,7 +179,7 @@
// Test an error occurs if an invalid sType is the nextInChain
TEST_P(GLTextureValidationTests, InvalidTextureDescriptor) {
wgpu::ChainedStruct chainedDescriptor;
- chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel;
+ chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsUWPSwapChainPanel;
descriptor.nextInChain = &chainedDescriptor;
ScopedGLTexture glTexture = CreateDefaultGLTexture();
diff --git a/src/dawn/tests/white_box/VulkanImageWrappingTests.cpp b/src/dawn/tests/white_box/VulkanImageWrappingTests.cpp
index ffb0e52..b011061 100644
--- a/src/dawn/tests/white_box/VulkanImageWrappingTests.cpp
+++ b/src/dawn/tests/white_box/VulkanImageWrappingTests.cpp
@@ -219,7 +219,7 @@
// Test an error occurs if an invalid sType is the nextInChain
TEST_P(VulkanImageWrappingValidationTests, InvalidTextureDescriptor) {
wgpu::ChainedStruct chainedDescriptor;
- chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel;
+ chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsUWPSwapChainPanel;
defaultDescriptor.nextInChain = &chainedDescriptor;
ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(device, &defaultDescriptor,