Create SharedTextureMemory from D3D12 resource

Adds support for creating SharedTextureMemory from a D3D12Resource
without the need for a shared handle - through a new
SharedTextureMemoryD3D12ResourceDescriptor.

Change-Id: Ib9ad171eb1e0892c11dbe1524d7dce792dfdc92c
Bug: 425864542
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/268055
Reviewed-by: Rafael Cintron <rafael.cintron@microsoft.com>
Commit-Queue: Sahir Vellani <sahir.vellani@microsoft.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/include/dawn/native/D3D12Backend.h b/include/dawn/native/D3D12Backend.h
index b5ef2d6..753f056 100644
--- a/include/dawn/native/D3D12Backend.h
+++ b/include/dawn/native/D3D12Backend.h
@@ -86,6 +86,17 @@
     constexpr static uint32_t kRequiredAlignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
 };
 
+// May be chained on SharedTextureMemoryDescriptor.
+struct DAWN_NATIVE_EXPORT SharedTextureMemoryD3D12ResourceDescriptor : wgpu::ChainedStruct {
+    SharedTextureMemoryD3D12ResourceDescriptor() {
+        sType = static_cast<wgpu::SType>(WGPUSType_SharedTextureMemoryD3D12ResourceDescriptor);
+    }
+
+    // This ID3D12Resource object must be created from the same ID3D12Device used in the
+    // WGPUDevice.
+    Microsoft::WRL::ComPtr<ID3D12Resource> resource;
+};
+
 }  // namespace dawn::native::d3d12
 
 #endif  // INCLUDE_DAWN_NATIVE_D3D12BACKEND_H_
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 5d66333..bee511e 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -2453,7 +2453,8 @@
             {"value": 57, "name": "dawn device allocator control", "tags": ["dawn"]},
             {"value": 58, "name": "chromium experimental bindless", "tags": ["dawn"]},
             {"value": 59, "name": "adapter properties WGPU", "tags": ["dawn"]},
-            {"value": 60, "name": "shared buffer memory D3D12 shared memory file mapping handle", "tags": ["dawn"]}
+            {"value": 60, "name": "shared buffer memory D3D12 shared memory file mapping handle", "tags": ["dawn"]},
+            {"value": 61, "name": "shared texture memory D3D12 resource", "tags": ["dawn", "native"]}
         ]
     },
     "filter mode": {
@@ -3973,7 +3974,9 @@
             {"value": 77, "name": "texel buffer binding layout", "tags": ["dawn"]},
             {"value": 78, "name": "shared texture memory metal end access state", "tags": ["dawn", "native"]},
             {"value": 79, "name": "adapter properties WGPU", "tags": ["dawn"]},
-            {"value": 80, "name": "shared buffer memory D3D12 shared memory file mapping handle descriptor", "tags": ["dawn", "native"]}
+            {"value": 80, "name": "shared buffer memory D3D12 shared memory file mapping handle descriptor", "tags": ["dawn", "native"]},
+            {"value": 81, "name": "shared texture memory D3D12 resource descriptor", "tags": ["dawn", "native"]}
+
         ]
     },
     "texture": {
diff --git a/src/dawn/native/ChainUtilsImpl.inl b/src/dawn/native/ChainUtilsImpl.inl
index 8c54c56..b28b49a 100644
--- a/src/dawn/native/ChainUtilsImpl.inl
+++ b/src/dawn/native/ChainUtilsImpl.inl
@@ -44,6 +44,7 @@
 namespace d3d12 {
 struct SharedBufferMemoryD3D12ResourceDescriptor;
 struct SharedBufferMemoryD3D12SharedMemoryFileHandleDescriptor;
+struct SharedTextureMemoryD3D12ResourceDescriptor;
 }
 
 namespace opengl {
@@ -89,9 +90,14 @@
     wgpu::SType(WGPUSType_SharedTextureMemoryD3D11Texture2DDescriptor);
 
 template <>
+constexpr inline wgpu::SType STypeForImpl<d3d12::SharedTextureMemoryD3D12ResourceDescriptor> =
+    wgpu::SType(WGPUSType_SharedTextureMemoryD3D12ResourceDescriptor);
+
+template <>
 struct AdditionalExtensions<SharedTextureMemoryDescriptor> {
     using List =
-        AdditionalExtensionsList<const d3d11::SharedTextureMemoryD3D11Texture2DDescriptor*>;
+        AdditionalExtensionsList<const d3d11::SharedTextureMemoryD3D11Texture2DDescriptor*,
+                                  const d3d12::SharedTextureMemoryD3D12ResourceDescriptor*>;
 };
 
 template <>
diff --git a/src/dawn/native/Features.cpp b/src/dawn/native/Features.cpp
index 488380f..494de28 100644
--- a/src/dawn/native/Features.cpp
+++ b/src/dawn/native/Features.cpp
@@ -442,6 +442,10 @@
     {Feature::SharedBufferMemoryD3D12SharedMemoryFileMappingHandle,
      {"Supports importing a shared memory file mapping handle as shared buffer memory.",
       "https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/shared_buffer.md",
+      FeatureInfo::FeatureState::Experimental}},
+    {Feature::SharedTextureMemoryD3D12Resource,
+     {"Support importing ID3D12Resource as shared texture memory.",
+      "https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/shared_texture.md",
       FeatureInfo::FeatureState::Experimental}}};
 
 }  // anonymous namespace
diff --git a/src/dawn/native/d3d12/DeviceD3D12.cpp b/src/dawn/native/d3d12/DeviceD3D12.cpp
index 7909de0..df1d8f3 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/DeviceD3D12.cpp
@@ -491,7 +491,8 @@
 
     wgpu::SType type;
     DAWN_TRY_ASSIGN(
-        type, (unpacked.ValidateBranches<Branch<SharedTextureMemoryDXGISharedHandleDescriptor>>()));
+        type, (unpacked.ValidateBranches<Branch<SharedTextureMemoryDXGISharedHandleDescriptor>,
+                                         Branch<SharedTextureMemoryD3D12ResourceDescriptor>>()));
 
     switch (type) {
         case wgpu::SType::SharedTextureMemoryDXGISharedHandleDescriptor:
@@ -501,6 +502,13 @@
             return SharedTextureMemory::Create(
                 this, descriptor->label,
                 unpacked.Get<SharedTextureMemoryDXGISharedHandleDescriptor>());
+        case wgpu::SType::SharedTextureMemoryD3D12ResourceDescriptor:
+            DAWN_INVALID_IF(!HasFeature(Feature::SharedTextureMemoryD3D12Resource),
+                            "%s is not enabled.",
+                            wgpu::FeatureName::SharedTextureMemoryD3D12Resource);
+            return SharedTextureMemory::Create(
+                this, descriptor->label,
+                unpacked.Get<SharedTextureMemoryD3D12ResourceDescriptor>());
         default:
             DAWN_UNREACHABLE();
     }
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
index be3cfee..315012b 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
@@ -212,6 +212,7 @@
     }
 
     EnableFeature(Feature::SharedTextureMemoryDXGISharedHandle);
+    EnableFeature(Feature::SharedTextureMemoryD3D12Resource);
     EnableFeature(Feature::SharedFenceDXGISharedHandle);
 
     if (SupportsBufferMapExtendedUsages()) {
diff --git a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
index 8a5ec77..5b7eb4f 100644
--- a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
+++ b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
@@ -30,6 +30,7 @@
 #include <utility>
 
 #include "dawn/native/ChainUtils.h"
+#include "dawn/native/D3D12Backend.h"
 #include "dawn/native/d3d/D3DError.h"
 #include "dawn/native/d3d/KeyedMutex.h"
 #include "dawn/native/d3d/UtilsD3D.h"
@@ -49,7 +50,35 @@
     Ref<d3d::KeyedMutex> keyedMutex;
     DAWN_TRY(device->ImportSharedHandleResource(descriptor->handle, descriptor->useKeyedMutex,
                                                 d3d12Resource, keyedMutex));
+    return CreateSharedTextureMemoryFromD3D12Resource(device, label, d3d12Resource, keyedMutex);
+}
 
+// static
+ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
+    Device* device,
+    StringView label,
+    const SharedTextureMemoryD3D12ResourceDescriptor* descriptor) {
+    DAWN_INVALID_IF(descriptor->resource == nullptr, "D3D12Resource is missing.");
+    ComPtr<ID3D12Resource> d3d12Resource = descriptor->resource;
+    return CreateSharedTextureMemoryFromD3D12Resource(device, label, d3d12Resource, nullptr);
+}
+
+SharedTextureMemory::SharedTextureMemory(Device* device,
+                                         StringView label,
+                                         SharedTextureMemoryProperties properties,
+                                         ComPtr<ID3D12Resource> resource,
+                                         Ref<d3d::KeyedMutex> keyedMutex)
+    : d3d::SharedTextureMemory(device, label, properties),
+      mResource(std::move(resource)),
+      mKeyedMutex(std::move(keyedMutex)) {}
+
+// static
+ResultOrError<Ref<SharedTextureMemory>>
+SharedTextureMemory::CreateSharedTextureMemoryFromD3D12Resource(
+    Device* device,
+    StringView label,
+    ComPtr<ID3D12Resource> d3d12Resource,
+    Ref<d3d::KeyedMutex> keyedMutex) {
     D3D12_RESOURCE_DESC desc = d3d12Resource->GetDesc();
     DAWN_INVALID_IF(desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D,
                     "Resource dimension (%d) was not Texture2D", desc.Dimension);
@@ -98,15 +127,6 @@
     return result;
 }
 
-SharedTextureMemory::SharedTextureMemory(Device* device,
-                                         StringView label,
-                                         SharedTextureMemoryProperties properties,
-                                         ComPtr<ID3D12Resource> resource,
-                                         Ref<d3d::KeyedMutex> keyedMutex)
-    : d3d::SharedTextureMemory(device, label, properties),
-      mResource(std::move(resource)),
-      mKeyedMutex(std::move(keyedMutex)) {}
-
 void SharedTextureMemory::DestroyImpl() {
     ToBackend(GetDevice())->ReferenceUntilUnused(std::move(mResource));
     mKeyedMutex = nullptr;
diff --git a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.h b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.h
index 2ab48ea..eb96cdb 100644
--- a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.h
+++ b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.h
@@ -39,6 +39,7 @@
 
 namespace d3d12 {
 class Device;
+struct SharedTextureMemoryD3D12ResourceDescriptor;
 
 class SharedTextureMemory final : public d3d::SharedTextureMemory {
   public:
@@ -47,6 +48,11 @@
         StringView label,
         const SharedTextureMemoryDXGISharedHandleDescriptor* descriptor);
 
+    static ResultOrError<Ref<SharedTextureMemory>> Create(
+        Device* device,
+        StringView label,
+        const SharedTextureMemoryD3D12ResourceDescriptor* descriptor);
+
     ID3D12Resource* GetD3DResource() const;
 
     d3d::KeyedMutex* GetKeyedMutex() const;
@@ -58,6 +64,12 @@
                         ComPtr<ID3D12Resource> resource,
                         Ref<d3d::KeyedMutex> keyedMutex);
 
+    static ResultOrError<Ref<SharedTextureMemory>> CreateSharedTextureMemoryFromD3D12Resource(
+        Device* device,
+        StringView label,
+        ComPtr<ID3D12Resource> d3d12Resource,
+        Ref<d3d::KeyedMutex> keyedMutex);
+
     void DestroyImpl() override;
 
     ResultOrError<Ref<TextureBase>> CreateTextureImpl(
diff --git a/src/dawn/node/binding/Converter.cpp b/src/dawn/node/binding/Converter.cpp
index 2468e79..2efe08d 100644
--- a/src/dawn/node/binding/Converter.cpp
+++ b/src/dawn/node/binding/Converter.cpp
@@ -1752,6 +1752,7 @@
         case wgpu::FeatureName::ChromiumExperimentalBindless:
         case wgpu::FeatureName::AdapterPropertiesWGPU:
         case wgpu::FeatureName::SharedBufferMemoryD3D12SharedMemoryFileMappingHandle:
+        case wgpu::FeatureName::SharedTextureMemoryD3D12Resource:
             return false;
     }
     return false;
diff --git a/src/dawn/tests/BUILD.gn b/src/dawn/tests/BUILD.gn
index a5b23cf..d3d4275 100644
--- a/src/dawn/tests/BUILD.gn
+++ b/src/dawn/tests/BUILD.gn
@@ -834,6 +834,7 @@
     sources += [
       "white_box/SharedBufferMemoryTests_win.cpp",
       "white_box/SharedTextureMemoryTests_win.cpp",
+      "white_box/SharedTextureMemoryTests_win_d3d12.cpp",
     ]
   }
 
diff --git a/src/dawn/tests/end2end/ArchTierLimitsExhaustive.cpp b/src/dawn/tests/end2end/ArchTierLimitsExhaustive.cpp
index cf8e1d0..ac272dc 100644
--- a/src/dawn/tests/end2end/ArchTierLimitsExhaustive.cpp
+++ b/src/dawn/tests/end2end/ArchTierLimitsExhaustive.cpp
@@ -368,6 +368,7 @@
     ChromiumExperimentalBindless,
     AdapterPropertiesWGPU,
     SharedBufferMemoryD3D12SharedMemoryFileMappingHandle,
+    SharedTextureMemoryD3D12Resource,
     };
 
 
@@ -392,61 +393,61 @@
     };
 
 // AMD
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, "Metal_AMD_Radeon_Pro_5300M");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, "Metal_AMD_Radeon_Pro_555X");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, "Metal_AMD_Radeon_Pro_560X");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, "Metal_AMD_Radeon_Pro_5300M");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, "Metal_AMD_Radeon_Pro_555X");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, "Metal_AMD_Radeon_Pro_560X");
 
 // Apple
-AddDevice({1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 }, "Metal_Apple_M2");
+AddDevice({1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, "Metal_Apple_M2");
 
 // ARM
 
 // Intel
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, "D3D11_Intel_R__UHD_Graphics_630");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1 }, "D3D12_Intel_R__UHD_Graphics_630");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1 }, "D3D12_Intel_R__UHD_Graphics_630");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, "Metal_Intel_R__UHD_Graphics_630");
-AddDevice({0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, "OpenGLES_ANGLE__Intel__Intel_R__UHD_Graphics_630__0x00009BC5__Direct3D11_vs_5_0_ps_5_0__D3D11_31_0_101_2127__compat");
-AddDevice({1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_Intel_R__UHD_Graphics_630");
-AddDevice({1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_Intel_R__UHD_Graphics_630__CML_GT2");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, "D3D11_Intel_R__UHD_Graphics_770");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, "D3D11_Intel_R__UHD_Graphics_770");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1 }, "D3D12_Intel_R__UHD_Graphics_770");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1 }, "D3D12_Intel_R__UHD_Graphics_770");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1 }, "D3D12_Intel_R__UHD_Graphics_770");
-AddDevice({0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, "OpenGLES_ANGLE__Intel__Intel_R__UHD_Graphics_770__0x00004680__Direct3D11_vs_5_0_ps_5_0__D3D11_31_0_101_5333__compat");
-AddDevice({0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, "OpenGLES_ANGLE__Intel__Intel_R__UHD_Graphics_770__0x00004680__Direct3D11_vs_5_0_ps_5_0__D3D11_31_0_101_5333__compat");
-AddDevice({1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_Intel_R__UHD_Graphics_770");
-AddDevice({1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_Intel_R__UHD_Graphics_770__ADL_S_GT1");
-AddDevice({1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_Intel_R__Iris_R__Xe_Graphics__TGL_GT2");
-AddDevice({1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_Intel_R__Iris_R__Xe_Graphics__TGL_GT2");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, "D3D11_Intel_R__UHD_Graphics_630");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 }, "D3D12_Intel_R__UHD_Graphics_630");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 }, "D3D12_Intel_R__UHD_Graphics_630");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, "Metal_Intel_R__UHD_Graphics_630");
+AddDevice({0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, "OpenGLES_ANGLE__Intel__Intel_R__UHD_Graphics_630__0x00009BC5__Direct3D11_vs_5_0_ps_5_0__D3D11_31_0_101_2127__compat");
+AddDevice({1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_Intel_R__UHD_Graphics_630");
+AddDevice({1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_Intel_R__UHD_Graphics_630__CML_GT2");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, "D3D11_Intel_R__UHD_Graphics_770");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, "D3D11_Intel_R__UHD_Graphics_770");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 }, "D3D12_Intel_R__UHD_Graphics_770");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 }, "D3D12_Intel_R__UHD_Graphics_770");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 }, "D3D12_Intel_R__UHD_Graphics_770");
+AddDevice({0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, "OpenGLES_ANGLE__Intel__Intel_R__UHD_Graphics_770__0x00004680__Direct3D11_vs_5_0_ps_5_0__D3D11_31_0_101_5333__compat");
+AddDevice({0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, "OpenGLES_ANGLE__Intel__Intel_R__UHD_Graphics_770__0x00004680__Direct3D11_vs_5_0_ps_5_0__D3D11_31_0_101_5333__compat");
+AddDevice({1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_Intel_R__UHD_Graphics_770");
+AddDevice({1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_Intel_R__UHD_Graphics_770__ADL_S_GT1");
+AddDevice({1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_Intel_R__Iris_R__Xe_Graphics__TGL_GT2");
+AddDevice({1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_Intel_R__Iris_R__Xe_Graphics__TGL_GT2");
 
 // llvmpipe
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_llvmpipe__LLVM_19_1_7__256_bits");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_llvmpipe__LLVM_19_1_7__256_bits");
 
 // Microsoft
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, "D3D11_Microsoft_Basic_Render_Driver_Integrated_GPU");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1 }, "D3D12_Microsoft_Basic_Render_Driver_Integrated_GPU");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1 }, "D3D12_Microsoft_Basic_Render_Driver_Integrated_GPU");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, "D3D11_Microsoft_Basic_Render_Driver_Integrated_GPU");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 }, "D3D12_Microsoft_Basic_Render_Driver_Integrated_GPU");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 }, "D3D12_Microsoft_Basic_Render_Driver_Integrated_GPU");
 
 // NVIDIA
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, "D3D11_NVIDIA_GeForce_GTX_1660");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0 }, "D3D12_NVIDIA_GeForce_GTX_1660");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0 }, "D3D12_NVIDIA_GeForce_GTX_1660");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_GeForce_GTX_1660");
-AddDevice({0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, "OpenGLES_ANGLE__NVIDIA__NVIDIA_GeForce_GTX_1660__0x00002184__Direct3D11_vs_5_0_ps_5_0__D3D11_31_0_15_4601__compat");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_NVIDIA_GeForce_GTX_1660");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_NVIDIA_GeForce_GTX_1660");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_NVIDIA_GeForce_GTX_1660");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, "D3D11_NVIDIA_GeForce_GTX_1660");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 }, "D3D12_NVIDIA_GeForce_GTX_1660");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 }, "D3D12_NVIDIA_GeForce_GTX_1660");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_GeForce_GTX_1660");
+AddDevice({0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, "OpenGLES_ANGLE__NVIDIA__NVIDIA_GeForce_GTX_1660__0x00002184__Direct3D11_vs_5_0_ps_5_0__D3D11_31_0_15_4601__compat");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_NVIDIA_GeForce_GTX_1660");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_NVIDIA_GeForce_GTX_1660");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_NVIDIA_GeForce_GTX_1660");
 
 // Qualcomm
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, "D3D11_Qualcomm_R__Adreno_TM__X1_85_GPU");
-AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0 }, "D3D12_Qualcomm_R__Adreno_TM__X1_85_GPU");
-AddDevice({1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0 }, "Vulkan_Qualcomm_R__Adreno_TM__X1_85_GPU");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, "D3D11_Qualcomm_R__Adreno_TM__X1_85_GPU");
+AddDevice({1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, "D3D12_Qualcomm_R__Adreno_TM__X1_85_GPU");
+AddDevice({1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0 }, "Vulkan_Qualcomm_R__Adreno_TM__X1_85_GPU");
 
 // SwiftShader
-AddDevice({0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, "OpenGLES_ANGLE__Google__Vulkan_1_3_0__SwiftShader_Device__Subzero___0x0000C0DE____SwiftShader_driver_5_0_0__compat");
-AddDevice({0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, "OpenGLES_ANGLE__Google__Vulkan_1_3_0__SwiftShader_Device__Subzero___0x0000C0DE____SwiftShader_driver_5_0_0__compat");
+AddDevice({0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, "OpenGLES_ANGLE__Google__Vulkan_1_3_0__SwiftShader_Device__Subzero___0x0000C0DE____SwiftShader_driver_5_0_0__compat");
+AddDevice({0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, "OpenGLES_ANGLE__Google__Vulkan_1_3_0__SwiftShader_Device__Subzero___0x0000C0DE____SwiftShader_driver_5_0_0__compat");
 
 auto supported_features = this->GetSupportedFeatures();
 
diff --git a/src/dawn/tests/white_box/SharedTextureMemoryTests_win.cpp b/src/dawn/tests/white_box/SharedTextureMemoryTests_win.cpp
index 02576f8..faed01a 100644
--- a/src/dawn/tests/white_box/SharedTextureMemoryTests_win.cpp
+++ b/src/dawn/tests/white_box/SharedTextureMemoryTests_win.cpp
@@ -389,6 +389,8 @@
 
 // Test that it is an error to import a shared fence without enabling the feature.
 TEST_P(SharedTextureMemoryNoFeatureTests, SharedFenceImportWithoutFeature) {
+    DAWN_TEST_UNSUPPORTED_IF(IsD3D12());
+
     auto backend = static_cast<Backend*>(GetParam().mBackend);
     DAWN_TEST_UNSUPPORTED_IF(!backend->HasFenceSupport(device));
 
@@ -418,6 +420,8 @@
 
 // Test that a shared handle can be imported, and then exported.
 TEST_P(SharedTextureMemoryTests, SharedFenceSuccessfulImportExport) {
+    DAWN_TEST_UNSUPPORTED_IF(IsD3D12());
+
     auto backend = static_cast<Backend*>(GetParam().mBackend);
     DAWN_TEST_UNSUPPORTED_IF(!backend->HasFenceSupport(device));
 
@@ -507,6 +511,8 @@
 // Test exporting info from a shared fence with no chained struct.
 // It should be valid and the fence type is exported.
 TEST_P(SharedTextureMemoryTests, SharedFenceExportInfoNoChainedStruct) {
+    DAWN_TEST_UNSUPPORTED_IF(IsD3D12());
+
     auto backend = static_cast<Backend*>(GetParam().mBackend);
     DAWN_TEST_UNSUPPORTED_IF(!backend->HasFenceSupport(device));
 
@@ -543,6 +549,8 @@
 // Test exporting info from a shared fence with an invalid chained struct.
 // It should not be valid, but the fence type should still be exported.
 TEST_P(SharedTextureMemoryTests, SharedFenceExportInfoInvalidChainedStruct) {
+    DAWN_TEST_UNSUPPORTED_IF(IsD3D12());
+
     auto backend = static_cast<Backend*>(GetParam().mBackend);
     DAWN_TEST_UNSUPPORTED_IF(!backend->HasFenceSupport(device));
 
diff --git a/src/dawn/tests/white_box/SharedTextureMemoryTests_win_d3d12.cpp b/src/dawn/tests/white_box/SharedTextureMemoryTests_win_d3d12.cpp
new file mode 100644
index 0000000..80f1133
--- /dev/null
+++ b/src/dawn/tests/white_box/SharedTextureMemoryTests_win_d3d12.cpp
@@ -0,0 +1,460 @@
+// Copyright 2025 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 <d3d12.h>
+#include <dxgi1_4.h>
+#include <webgpu/webgpu_cpp.h>
+#include <wrl/client.h>
+
+#include <memory>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "dawn/native/D3D12Backend.h"
+#include "dawn/native/D3DBackend.h"
+#include "dawn/native/DawnNative.h"
+#include "dawn/tests/white_box/SharedTextureMemoryTests.h"
+
+namespace dawn {
+namespace {
+
+using Microsoft::WRL::ComPtr;
+
+enum class Mode {
+    // TODO(crbug.com/454827192): Add tests for shared handle to D3D12Resources.
+    // DXGISharedHandle,
+    D3D12Resource,
+};
+
+// Backend for testing SharedTextureMemory backed by D3D12 resources. This test
+// setup is adapted from SharedTextureMemoryTests_win.cpp.
+class BackendD3D12 : public SharedTextureMemoryTestBackend {
+  public:
+    template <Mode kMode>
+    static BackendD3D12* GetInstance() {
+        static BackendD3D12 b(kMode);
+        return &b;
+    }
+
+    std::string Name() const override {
+        std::ostringstream ss;
+        switch (mMode) {
+            case Mode::D3D12Resource: {
+                ss << "D3D12Resource";
+            } break;
+        }
+
+        return ss.str();
+    }
+
+    bool SupportsConcurrentRead() const override { return true; }
+
+    ComPtr<ID3D12Device> MakeD3D12Device(const wgpu::Device& device) {
+        ComPtr<ID3D12Device> d3d12Device = native::d3d12::GetD3D12Device(device.Get());
+        return d3d12Device;
+    }
+
+    std::vector<wgpu::FeatureName> RequiredFeatures(const wgpu::Adapter& adapter) const override {
+        std::vector<wgpu::FeatureName> features;
+        if (adapter.HasFeature(wgpu::FeatureName::SharedFenceDXGISharedHandle)) {
+            features.push_back(wgpu::FeatureName::SharedFenceDXGISharedHandle);
+        }
+
+        switch (mMode) {
+            case Mode::D3D12Resource: {
+                features.push_back(wgpu::FeatureName::SharedTextureMemoryD3D12Resource);
+                break;
+            }
+        }
+
+        return features;
+    }
+
+    bool UseSharedHandle() const { return false; }
+
+    std::string LabelName(DXGI_FORMAT format, size_t size) const {
+        std::stringstream ss;
+        ss << "format 0x" << std::hex << format << " size " << size << "x" << size;
+        return ss.str();
+    }
+
+    wgpu::SharedTextureMemory CreateSharedTextureMemory(const wgpu::Device& device,
+                                                        int layerCount) override {
+        ComPtr<ID3D12Device> d3d12Device = MakeD3D12Device(device);
+
+        // Create a DX12 resource.
+        D3D12_RESOURCE_DESC texDesc = {};
+        texDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+        texDesc.Alignment = 0;
+        texDesc.Width = 16;
+        texDesc.Height = 16;
+        texDesc.DepthOrArraySize = layerCount;
+        texDesc.MipLevels = 1;
+        texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+        texDesc.SampleDesc.Count = 1;
+        texDesc.SampleDesc.Quality = 0;
+        texDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
+        texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET |
+                        D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS |
+                        D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS;
+
+        D3D12_HEAP_PROPERTIES heapProps = {};
+        heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+        heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+        heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+        heapProps.CreationNodeMask = 0;
+        heapProps.VisibleNodeMask = 0;
+
+        D3D12_CLEAR_VALUE clearValue = {};
+        clearValue.Format = texDesc.Format;
+        clearValue.Color[0] = 0.0f;
+        clearValue.Color[1] = 0.0f;
+        clearValue.Color[2] = 0.0f;
+        clearValue.Color[3] = 0.0f;
+
+        ComPtr<ID3D12Resource> d3d12Resource;
+        HRESULT hr = d3d12Device->CreateCommittedResource(
+            &heapProps, D3D12_HEAP_FLAG_NONE, &texDesc, D3D12_RESOURCE_STATE_COMMON, &clearValue,
+            IID_PPV_ARGS(&d3d12Resource));
+        DAWN_ASSERT(hr == S_OK);
+
+        switch (mMode) {
+            case Mode::D3D12Resource: {
+                wgpu::SharedTextureMemoryDescriptor desc;
+                native::d3d12::SharedTextureMemoryD3D12ResourceDescriptor bufferDesc;
+                bufferDesc.resource = d3d12Resource.Get();
+                desc.nextInChain = &bufferDesc;
+                desc.label = "D3D12Resource Texture";
+                return device.ImportSharedTextureMemory(&desc);
+            }
+        }
+    }
+
+    std::vector<std::vector<wgpu::SharedTextureMemory>> CreatePerDeviceSharedTextureMemories(
+        const std::vector<wgpu::Device>& devices,
+        int layerCount) override {
+        std::vector<std::vector<wgpu::SharedTextureMemory>> memories;
+        ComPtr<ID3D12Device> d3d12Device = MakeD3D12Device(devices[0]);
+
+        // Check for D3D12 NV12 sharing support.
+        bool supportsNV12Sharing = false;
+        D3D12_FEATURE_DATA_D3D12_OPTIONS4 opts4 = {};
+        d3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4, &opts4, sizeof(opts4));
+        if (opts4.SharedResourceCompatibilityTier >= D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2) {
+            supportsNV12Sharing = true;
+        }
+
+        struct D3DFormat {
+            DXGI_FORMAT format;
+            wgpu::FeatureName requiredFeature = wgpu::FeatureName(0u);
+        };
+        std::vector<D3DFormat> formats = {{
+            {DXGI_FORMAT_R16G16B16A16_FLOAT},
+            {DXGI_FORMAT_R16G16_FLOAT},
+            {DXGI_FORMAT_R16_FLOAT},
+            {DXGI_FORMAT_R8G8B8A8_UNORM},
+            {DXGI_FORMAT_B8G8R8A8_UNORM},
+            {DXGI_FORMAT_R10G10B10A2_UNORM},
+            {DXGI_FORMAT_R16G16_UNORM, wgpu::FeatureName::Unorm16TextureFormats},
+            {DXGI_FORMAT_R16_UNORM, wgpu::FeatureName::Unorm16TextureFormats},
+            {DXGI_FORMAT_R8G8_UNORM},
+            {DXGI_FORMAT_R8_UNORM},
+        }};
+
+        if (supportsNV12Sharing) {
+            formats.push_back({DXGI_FORMAT_NV12});
+        }
+
+        for (auto f : formats) {
+            for (uint32_t size : {4, 64}) {
+                // Create a DX12 resource.
+                D3D12_RESOURCE_DESC texDesc = {};
+                texDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+                texDesc.Alignment = 0;
+                texDesc.Width = size;
+                texDesc.Height = size;
+                texDesc.DepthOrArraySize = layerCount;
+                texDesc.MipLevels = 1;
+                texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+                texDesc.SampleDesc.Count = 1;
+                texDesc.SampleDesc.Quality = 0;
+                texDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
+                texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET |
+                                D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS |
+                                D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS;
+
+                D3D12_HEAP_PROPERTIES heapProps = {};
+                heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+                heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+                heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+                heapProps.CreationNodeMask = 0;
+                heapProps.VisibleNodeMask = 0;
+
+                D3D12_CLEAR_VALUE clearValue = {};
+                clearValue.Format = texDesc.Format;
+                clearValue.Color[0] = 0.0f;
+                clearValue.Color[1] = 0.0f;
+                clearValue.Color[2] = 0.0f;
+                clearValue.Color[3] = 0.0f;
+
+                ComPtr<ID3D12Resource> d3d12Resource;
+                HRESULT hr = d3d12Device->CreateCommittedResource(
+                    &heapProps, D3D12_HEAP_FLAG_NONE, &texDesc, D3D12_RESOURCE_STATE_COMMON,
+                    &clearValue, IID_PPV_ARGS(&d3d12Resource));
+                DAWN_ASSERT(hr == S_OK);
+
+                std::vector<wgpu::SharedTextureMemory> perDeviceMemories;
+                switch (mMode) {
+                    case Mode::D3D12Resource: {
+                        wgpu::SharedTextureMemoryDescriptor desc;
+                        native::d3d12::SharedTextureMemoryD3D12ResourceDescriptor bufferDesc;
+                        bufferDesc.resource = d3d12Resource.Get();
+                        desc.nextInChain = &bufferDesc;
+                        std::string label = LabelName(f.format, size);
+                        desc.label = label.c_str();
+
+                        for (auto& deviceObj : devices) {
+                            if (f.requiredFeature != wgpu::FeatureName(0u) &&
+                                !deviceObj.HasFeature(f.requiredFeature)) {
+                                continue;
+                            }
+                            perDeviceMemories.push_back(deviceObj.ImportSharedTextureMemory(&desc));
+                        }
+                        break;
+                    }
+                }
+                if (!perDeviceMemories.empty()) {
+                    memories.push_back(std::move(perDeviceMemories));
+                }
+            }
+        }
+        return memories;
+    }
+
+  private:
+    explicit BackendD3D12(Mode mode) : mMode(mode) {}
+
+    const Mode mMode;
+};
+
+// Test that it is an error to import a shared fence without enabling the feature (D3D12 fence
+// path).
+TEST_P(SharedTextureMemoryNoFeatureTests, SharedFenceImportWithoutFeatureD3D12) {
+    DAWN_TEST_UNSUPPORTED_IF(!IsD3D12());
+    auto backend = static_cast<BackendD3D12*>(GetParam().mBackend);
+    ComPtr<ID3D12Device> d3d12Device = backend->MakeD3D12Device(device);
+
+    // Create a shareable D3D12 fence.
+    ComPtr<ID3D12Fence> d3d12Fence;
+    HRESULT hr = d3d12Device->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&d3d12Fence));
+    ASSERT_EQ(hr, S_OK);
+
+    // Create a shared handle for the fence.
+    HANDLE fenceSharedHandle = nullptr;
+    hr = d3d12Device->CreateSharedHandle(d3d12Fence.Get(), nullptr, GENERIC_ALL, nullptr,
+                                         &fenceSharedHandle);
+    ASSERT_EQ(hr, S_OK);
+
+    // Attempt to import without the feature enabled; should be a device error.
+    wgpu::SharedFenceDXGISharedHandleDescriptor sharedHandleDesc;
+    sharedHandleDesc.handle = fenceSharedHandle;
+
+    wgpu::SharedFenceDescriptor fenceDesc;
+    fenceDesc.nextInChain = &sharedHandleDesc;
+
+    ASSERT_DEVICE_ERROR_MSG(wgpu::SharedFence fence = device.ImportSharedFence(&fenceDesc),
+                            testing::HasSubstr("is not enabled"));
+
+    ::CloseHandle(fenceSharedHandle);
+}
+
+// Test that a shared handle can be imported, and then exported, using a D3D12 fence.
+TEST_P(SharedTextureMemoryTests, SharedFenceSuccessfulImportExportD3D12) {
+    DAWN_TEST_UNSUPPORTED_IF(!IsD3D12());
+    auto backend = static_cast<BackendD3D12*>(GetParam().mBackend);
+    ComPtr<ID3D12Device> d3d12Device = backend->MakeD3D12Device(device);
+
+    // Create a D3D12 fence that can be shared.
+    ComPtr<ID3D12Fence> d3d12Fence;
+    HRESULT hr = d3d12Device->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&d3d12Fence));
+    ASSERT_EQ(hr, S_OK);
+
+    // Export a shared handle for the fence.
+    HANDLE fenceSharedHandle = nullptr;
+    hr = d3d12Device->CreateSharedHandle(d3d12Fence.Get(), nullptr, GENERIC_ALL, nullptr,
+                                         &fenceSharedHandle);
+    ASSERT_EQ(hr, S_OK);
+
+    // Import into Dawn as a shared fence.
+    wgpu::SharedFenceDXGISharedHandleDescriptor sharedHandleDesc;
+    sharedHandleDesc.handle = fenceSharedHandle;
+
+    wgpu::SharedFenceDescriptor fenceDesc;
+    fenceDesc.nextInChain = &sharedHandleDesc;
+
+    wgpu::SharedFence fence = device.ImportSharedFence(&fenceDesc);
+
+    // We can close our local HANDLE after import (ownership transferred / duplicated internally).
+    ::CloseHandle(fenceSharedHandle);
+
+    // Export info back out.
+    wgpu::SharedFenceDXGISharedHandleExportInfo sharedHandleInfo;
+    wgpu::SharedFenceExportInfo exportInfo;
+    exportInfo.nextInChain = &sharedHandleInfo;
+    fence.ExportInfo(&exportInfo);
+
+    EXPECT_EQ(exportInfo.type, wgpu::SharedFenceType::DXGISharedHandle);
+
+    // Open the exported handle again as a second D3D12 fence object.
+    ComPtr<ID3D12Fence> d3d12Fence2;
+    hr = d3d12Device->OpenSharedHandle(sharedHandleInfo.handle, IID_PPV_ARGS(&d3d12Fence2));
+    ASSERT_EQ(hr, S_OK);
+
+    // Verify both fence objects report the same initial completed value.
+    uint64_t fenceValue = d3d12Fence->GetCompletedValue();
+    EXPECT_EQ(fenceValue, d3d12Fence2->GetCompletedValue());
+
+    // Create a command queue to signal the fence.
+    D3D12_COMMAND_QUEUE_DESC queueDesc = {};
+    queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+    queueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
+    queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+    queueDesc.NodeMask = 0;
+
+    ComPtr<ID3D12CommandQueue> queue;
+    hr = d3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&queue));
+    ASSERT_EQ(hr, S_OK);
+
+    // Signal the fence to a new value.
+    hr = queue->Signal(d3d12Fence.Get(), fenceValue + 1);
+    ASSERT_EQ(hr, S_OK);
+
+    // Wait on the fence via event.
+    HANDLE ev = ::CreateEvent(nullptr, TRUE, FALSE, TEXT("FenceCompleteD3D12"));
+    ASSERT_NE(ev, (HANDLE) nullptr);
+    hr = d3d12Fence->SetEventOnCompletion(fenceValue + 1, ev);
+    ASSERT_EQ(hr, S_OK);
+    ::WaitForSingleObject(ev, INFINITE);
+    ::CloseHandle(ev);
+
+    // Both fence objects should now report the updated value.
+    EXPECT_EQ(fenceValue + 1, d3d12Fence->GetCompletedValue());
+    EXPECT_EQ(fenceValue + 1, d3d12Fence2->GetCompletedValue());
+}
+
+// Test exporting info from a shared fence created from a D3D12 fence with no chained struct.
+// It should be valid and the fence type is exported.
+TEST_P(SharedTextureMemoryTests, SharedFenceExportInfoNoChainedStructD3D12) {
+    DAWN_TEST_UNSUPPORTED_IF(!IsD3D12());
+    auto backend = static_cast<BackendD3D12*>(GetParam().mBackend);
+    ComPtr<ID3D12Device> d3d12Device = backend->MakeD3D12Device(device);
+
+    // Create a shareable D3D12 fence.
+    ComPtr<ID3D12Fence> d3d12Fence;
+    HRESULT hr = d3d12Device->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&d3d12Fence));
+    ASSERT_EQ(hr, S_OK);
+
+    // Create a shared handle for the fence.
+    HANDLE fenceSharedHandle = nullptr;
+    hr = d3d12Device->CreateSharedHandle(d3d12Fence.Get(), nullptr, GENERIC_ALL, nullptr,
+                                         &fenceSharedHandle);
+    ASSERT_EQ(hr, S_OK);
+
+    // Import into Dawn.
+    wgpu::SharedFenceDXGISharedHandleDescriptor sharedHandleDesc;
+    sharedHandleDesc.handle = fenceSharedHandle;
+
+    wgpu::SharedFenceDescriptor fenceDesc;
+    fenceDesc.nextInChain = &sharedHandleDesc;
+
+    wgpu::SharedFence fence = device.ImportSharedFence(&fenceDesc);
+
+    // Close our local handle after import.
+    ::CloseHandle(fenceSharedHandle);
+
+    // Export info with no chained struct.
+    wgpu::SharedFenceExportInfo exportInfo;
+    exportInfo.nextInChain = nullptr;
+
+    fence.ExportInfo(&exportInfo);
+    EXPECT_EQ(exportInfo.type, wgpu::SharedFenceType::DXGISharedHandle);
+}
+
+// Test exporting info from a shared fence created from a D3D12 fence with an invalid chained
+// struct. It should trigger a device error, but the fence type would still be known internally.
+TEST_P(SharedTextureMemoryTests, SharedFenceExportInfoInvalidChainedStructD3D12) {
+    DAWN_TEST_UNSUPPORTED_IF(!IsD3D12());
+    auto backend = static_cast<BackendD3D12*>(GetParam().mBackend);
+    ComPtr<ID3D12Device> d3d12Device = backend->MakeD3D12Device(device);
+
+    // Create a shareable D3D12 fence.
+    ComPtr<ID3D12Fence> d3d12Fence;
+    HRESULT hr = d3d12Device->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&d3d12Fence));
+    ASSERT_EQ(hr, S_OK);
+
+    // Create a shared handle for the fence.
+    HANDLE fenceSharedHandle = nullptr;
+    hr = d3d12Device->CreateSharedHandle(d3d12Fence.Get(), nullptr, GENERIC_ALL, nullptr,
+                                         &fenceSharedHandle);
+    ASSERT_EQ(hr, S_OK);
+
+    // Import into Dawn.
+    wgpu::SharedFenceDXGISharedHandleDescriptor sharedHandleDesc;
+    sharedHandleDesc.handle = fenceSharedHandle;
+
+    wgpu::SharedFenceDescriptor fenceDesc;
+    fenceDesc.nextInChain = &sharedHandleDesc;
+
+    wgpu::SharedFence fence = device.ImportSharedFence(&fenceDesc);
+
+    // Close our local handle after import.
+    ::CloseHandle(fenceSharedHandle);
+
+    // Provide an invalid chained struct to ExportInfo.
+    wgpu::ChainedStructOut otherStruct;
+    wgpu::SharedFenceExportInfo exportInfo;
+    exportInfo.nextInChain = &otherStruct;
+
+    ASSERT_DEVICE_ERROR(fence.ExportInfo(&exportInfo));
+}
+
+DAWN_INSTANTIATE_PREFIXED_TEST_P(D3D12,
+                                 SharedTextureMemoryNoFeatureTests,
+                                 {D3D12Backend()},
+                                 {BackendD3D12::GetInstance<Mode::D3D12Resource>()},
+                                 {1});
+
+DAWN_INSTANTIATE_PREFIXED_TEST_P(D3D12,
+                                 SharedTextureMemoryTests,
+                                 {D3D12Backend()},
+                                 {BackendD3D12::GetInstance<Mode::D3D12Resource>()},
+                                 {1});
+
+}  // anonymous namespace
+}  // namespace dawn
diff --git a/src/dawn/wire/SupportedFeatures.cpp b/src/dawn/wire/SupportedFeatures.cpp
index d079c8ed..dfff2f3 100644
--- a/src/dawn/wire/SupportedFeatures.cpp
+++ b/src/dawn/wire/SupportedFeatures.cpp
@@ -56,6 +56,7 @@
         case WGPUFeatureName_SharedTextureMemoryZirconHandle:
         case WGPUFeatureName_SharedTextureMemoryDXGISharedHandle:
         case WGPUFeatureName_SharedTextureMemoryD3D11Texture2D:
+        case WGPUFeatureName_SharedTextureMemoryD3D12Resource:
         case WGPUFeatureName_SharedTextureMemoryIOSurface:
         case WGPUFeatureName_SharedTextureMemoryEGLImage:
         case WGPUFeatureName_SharedFenceVkSemaphoreOpaqueFD: