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/dawn.json b/dawn.json
index be6bf53..aed6596 100644
--- a/dawn.json
+++ b/dawn.json
@@ -1784,6 +1784,14 @@
             {"name": "core window", "type": "void", "annotation": "*"}
         ]
     },
+    "surface descriptor from windows swap chain panel": {
+        "category": "structure",
+        "chained": true,
+        "javascript": false,
+        "members": [
+            {"name": "swap chain panel", "type": "void", "annotation": "*"}
+        ]
+    },
     "swap chain": {
         "category": "object",
         "methods": [
@@ -1827,7 +1835,8 @@
             {"value": 7, "name": "primitive depth clamping state"},
             {"value": 8, "name": "surface descriptor from windows core window"},
             {"value": 9, "name": "external texture binding entry"},
-            {"value": 10, "name": "external texture binding layout"}
+            {"value": 10, "name": "external texture binding layout"},
+            {"value": 11, "name": "surface descriptor from windows swap chain panel"}
         ]
     },
     "texture": {
diff --git a/dawn_wire.json b/dawn_wire.json
index 04dd836..ec270ab 100644
--- a/dawn_wire.json
+++ b/dawn_wire.json
@@ -141,7 +141,8 @@
             "SurfaceDescriptorFromMetalLayer",
             "SurfaceDescriptorFromWindowsHWND",
             "SurfaceDescriptorFromXlib",
-            "SurfaceDescriptorFromWindowsCoreWindow"
+            "SurfaceDescriptorFromWindowsCoreWindow",
+            "SurfaceDescriptorFromWindowsSwapChainPanel"
         ],
         "client_side_commands": [
             "BufferMapAsync",
diff --git a/src/common/windows_with_undefs.h b/src/common/windows_with_undefs.h
index 6d8649c..39c9cad 100644
--- a/src/common/windows_with_undefs.h
+++ b/src/common/windows_with_undefs.h
@@ -32,4 +32,7 @@
 // Macros defined to produce compiler intrinsics
 #undef MemoryBarrier
 
+// Macro defined as an alias of GetTickCount
+#undef GetCurrentTime
+
 #endif  // COMMON_WINDOWS_WITH_UNDEFS_H_
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;
diff --git a/src/dawn_native/Surface.h b/src/dawn_native/Surface.h
index bdab2b4..44864b5 100644
--- a/src/dawn_native/Surface.h
+++ b/src/dawn_native/Surface.h
@@ -50,7 +50,7 @@
         NewSwapChainBase* GetAttachedSwapChain();
 
         // These are valid to call on all Surfaces.
-        enum class Type { MetalLayer, WindowsHWND, WindowsCoreWindow, Xlib };
+        enum class Type { MetalLayer, WindowsHWND, WindowsCoreWindow, WindowsSwapChainPanel, Xlib };
         Type GetType() const;
         InstanceBase* GetInstance();
 
@@ -64,6 +64,9 @@
         // 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 WindowsXlib
         void* GetXDisplay() const;
         uint32_t GetXWindow() const;
@@ -87,6 +90,9 @@
 #if defined(DAWN_PLATFORM_WINDOWS)
         // WindowsCoreWindow
         ComPtr<IUnknown> mCoreWindow;
+
+        // WindowsSwapChainPanel
+        ComPtr<IUnknown> mSwapChainPanel;
 #endif  // defined(DAWN_PLATFORM_WINDOWS)
 
         // Xlib
diff --git a/src/dawn_native/d3d12/SwapChainD3D12.cpp b/src/dawn_native/d3d12/SwapChainD3D12.cpp
index d78c63d..3950988 100644
--- a/src/dawn_native/d3d12/SwapChainD3D12.cpp
+++ b/src/dawn_native/d3d12/SwapChainD3D12.cpp
@@ -21,6 +21,8 @@
 
 #include <dawn/dawn_wsi.h>
 
+#include <windows.ui.xaml.media.dxinterop.h>
+
 namespace dawn_native { namespace d3d12 {
     namespace {
 
@@ -261,6 +263,19 @@
                     "Creating the IDXGISwapChain1"));
                 break;
             }
+            case Surface::Type::WindowsSwapChainPanel: {
+                DAWN_TRY(CheckHRESULT(
+                    factory2->CreateSwapChainForComposition(device->GetCommandQueue().Get(),
+                                                            &swapChainDesc, nullptr, &swapChain1),
+                    "Creating the IDXGISwapChain1"));
+                ComPtr<ISwapChainPanelNative> swapChainPanelNative;
+                DAWN_TRY(CheckHRESULT(GetSurface()->GetSwapChainPanel()->QueryInterface(
+                                          IID_PPV_ARGS(&swapChainPanelNative)),
+                                      "Getting ISwapChainPanelNative"));
+                DAWN_TRY(CheckHRESULT(swapChainPanelNative->SetSwapChain(swapChain1.Get()),
+                                      "Setting SwapChain"));
+                break;
+            }
             default:
                 UNREACHABLE();
         }