Add test on the Windows named shared memory backend of host mapped pointer

This patch adds end2end test on the use of Windows named shared memory
as host mapped pointer. In Chromium the shared memory is based on named
shared memory on Windows.

Bug: 42240963
Change-Id: I79b6123d8de239744133ddf9d006e9a6b38a2bca
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/258214
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Loko Kung <lokokung@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/tests/end2end/BufferHostMappedPointerTests_win.cpp b/src/dawn/tests/end2end/BufferHostMappedPointerTests_win.cpp
index 4799f26..16bbdce 100644
--- a/src/dawn/tests/end2end/BufferHostMappedPointerTests_win.cpp
+++ b/src/dawn/tests/end2end/BufferHostMappedPointerTests_win.cpp
@@ -124,7 +124,7 @@
                                           NULL);                         // no template
         EXPECT_NE(tmpFileHandle, INVALID_HANDLE_VALUE);
 
-        LARGE_INTEGER largeSize;
+        LARGE_INTEGER largeSize = {};
         largeSize.QuadPart = size;
         HANDLE fileMappingHandle = CreateFileMapping(
             tmpFileHandle, nullptr, PAGE_READWRITE, largeSize.HighPart, largeSize.LowPart, nullptr);
@@ -172,10 +172,74 @@
     MutexProtected<testing::MockCallback<WGPUCallback>> mDisposeCallback;
 };
 
+class NamedSharedMemoryBackend : public BufferHostMappedPointerTestBackend {
+  public:
+    static BufferHostMappedPointerTestBackend* GetInstance() {
+        static NamedSharedMemoryBackend backend;
+        return &backend;
+    }
+
+    const char* Name() const override { return "NamedSharedMemoryMapping"; }
+
+    std::pair<wgpu::Buffer, void*> CreateHostMappedBuffer(
+        wgpu::Device device,
+        wgpu::BufferUsage usage,
+        size_t size,
+        std::function<void(void*)> Populate) override {
+        LARGE_INTEGER largeSize = {};
+        largeSize.QuadPart = size;
+        // Create a named shared memory object by using INVALID_HANDLE_VALUE as input file handle.
+        // See https://learn.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory.
+        HANDLE sharedMemoryHandle =
+            CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, largeSize.HighPart,
+                              largeSize.LowPart, nullptr);
+
+        EXPECT_NE(sharedMemoryHandle, nullptr);
+
+        void* ptr = MapViewOfFile(sharedMemoryHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
+        EXPECT_NE(ptr, nullptr);
+        Populate(ptr);
+
+        auto DeallocMemory = [=]() {
+            // Cleanup mapping and handle.
+            EXPECT_TRUE(UnmapViewOfFile(ptr));
+            CloseHandle(sharedMemoryHandle);
+        };
+
+        wgpu::BufferHostMappedPointer hostMappedDesc;
+        hostMappedDesc.pointer = ptr;
+        mDisposeCallback.Use([&](auto callback) {
+            hostMappedDesc.disposeCallback = callback->Callback();
+            hostMappedDesc.userdata = callback->MakeUserdata(ptr);
+        });
+
+        wgpu::BufferDescriptor bufferDesc;
+        bufferDesc.usage = usage;
+        bufferDesc.size = size;
+        bufferDesc.nextInChain = &hostMappedDesc;
+
+        wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);
+        if (dawn::native::CheckIsErrorForTesting(buffer.Get())) {
+            DeallocMemory();
+        } else {
+            mDisposeCallback.Use([&](auto callback) {
+                EXPECT_CALL(*callback, Call(ptr))
+                    .WillOnce(testing::InvokeWithoutArgs(DeallocMemory));
+            });
+        }
+
+        return std::make_pair(std::move(buffer), hostMappedDesc.pointer);
+    }
+
+  private:
+    MutexProtected<testing::MockCallback<WGPUCallback>> mDisposeCallback;
+};
+
 DAWN_INSTANTIATE_PREFIXED_TEST_P(Win,
                                  BufferHostMappedPointerTests,
                                  {D3D12Backend()},
-                                 {VMBackend::GetInstance(), MMapBackend::GetInstance()});
+                                 {VMBackend::GetInstance(), MMapBackend::GetInstance(),
+                                  NamedSharedMemoryBackend::GetInstance()});
 
 }  // anonymous namespace
 }  // namespace dawn