Add support for windows SwapChainPanel in SwapChain and Surface

Add SurfaceDescriptorFromWindowsSwapChainPanel structure in codegen.
Add WindowsSwapChainPanel surface type.
Add support for WindowsSwapChainPanel surface in SwapChain.

Bug: dawn:766
Change-Id: I1d59262b912ee445c90a7ec6e22b442f2fb1bf00
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/53840
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/Surface.cpp b/src/dawn_native/Surface.cpp
index d78f3f3..ba398fc 100644
--- a/src/dawn_native/Surface.cpp
+++ b/src/dawn_native/Surface.cpp
@@ -21,6 +21,7 @@
 
 #if defined(DAWN_PLATFORM_WINDOWS)
 #    include <windows.ui.core.h>
+#    include <windows.ui.xaml.controls.h>
 #endif  // defined(DAWN_PLATFORM_WINDOWS)
 
 #if defined(DAWN_USE_X11)
@@ -43,6 +44,7 @@
                                      wgpu::SType::SurfaceDescriptorFromMetalLayer,
                                      wgpu::SType::SurfaceDescriptorFromWindowsHWND,
                                      wgpu::SType::SurfaceDescriptorFromWindowsCoreWindow,
+                                     wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel,
                                      wgpu::SType::SurfaceDescriptorFromXlib));
 
 #if defined(DAWN_ENABLE_BACKEND_METAL)
@@ -80,6 +82,18 @@
             }
             return {};
         }
+        const SurfaceDescriptorFromWindowsSwapChainPanel* swapChainPanelDesc = nullptr;
+        FindInChain(descriptor->nextInChain, &swapChainPanelDesc);
+        if (swapChainPanelDesc) {
+            // Validate the swapChainPanel by querying for ISwapChainPanel interface
+            ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel;
+            if (swapChainPanelDesc->swapChainPanel == nullptr ||
+                FAILED(static_cast<IUnknown*>(swapChainPanelDesc->swapChainPanel)
+                           ->QueryInterface(IID_PPV_ARGS(&swapChainPanel)))) {
+                return DAWN_VALIDATION_ERROR("Invalid SwapChainPanel");
+            }
+            return {};
+        }
         return DAWN_VALIDATION_ERROR("Unsupported sType");
 #endif  // defined(DAWN_PLATFORM_WINDOWS)
 
@@ -114,10 +128,12 @@
         const SurfaceDescriptorFromMetalLayer* metalDesc = nullptr;
         const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr;
         const SurfaceDescriptorFromWindowsCoreWindow* coreWindowDesc = nullptr;
+        const SurfaceDescriptorFromWindowsSwapChainPanel* swapChainPanelDesc = nullptr;
         const SurfaceDescriptorFromXlib* xDesc = nullptr;
         FindInChain(descriptor->nextInChain, &metalDesc);
         FindInChain(descriptor->nextInChain, &hwndDesc);
         FindInChain(descriptor->nextInChain, &coreWindowDesc);
+        FindInChain(descriptor->nextInChain, &swapChainPanelDesc);
         FindInChain(descriptor->nextInChain, &xDesc);
         ASSERT(metalDesc || hwndDesc || xDesc);
         if (metalDesc) {
@@ -132,6 +148,11 @@
             mType = Type::WindowsCoreWindow;
             mCoreWindow = static_cast<IUnknown*>(coreWindowDesc->coreWindow);
 #endif  // defined(DAWN_PLATFORM_WINDOWS)
+        } else if (swapChainPanelDesc) {
+#if defined(DAWN_PLATFORM_WINDOWS)
+            mType = Type::WindowsSwapChainPanel;
+            mSwapChainPanel = static_cast<IUnknown*>(swapChainPanelDesc->swapChainPanel);
+#endif  // defined(DAWN_PLATFORM_WINDOWS)
         } else if (xDesc) {
             mType = Type::Xlib;
             mXDisplay = xDesc->display;
@@ -187,6 +208,15 @@
 #endif
     }
 
+    IUnknown* Surface::GetSwapChainPanel() const {
+        ASSERT(mType == Type::WindowsSwapChainPanel);
+#if defined(DAWN_PLATFORM_WINDOWS)
+        return mSwapChainPanel.Get();
+#else
+        return nullptr;
+#endif
+    }
+
     void* Surface::GetXDisplay() const {
         ASSERT(mType == Type::Xlib);
         return mXDisplay;