Remove ExternalImageDXGI
This CL removes ExternalImageDXGI as we have switched to using
SharedTextureMemory.
Bug: chromium:335003893
Change-Id: I8ecdcdfa03a780f6fc7ece8846368bc736f696b1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/187426
Reviewed-by: Peng Huang <penghuang@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
diff --git a/include/dawn/native/D3DBackend.h b/include/dawn/native/D3DBackend.h
index d6bf080..cafbdf7 100644
--- a/include/dawn/native/D3DBackend.h
+++ b/include/dawn/native/D3DBackend.h
@@ -54,73 +54,6 @@
// Chrome uses 0 as acquire key.
static constexpr UINT64 kDXGIKeyedMutexAcquireKey = 0;
-struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDXGISharedHandle : ExternalImageDescriptor {
- public:
- ExternalImageDescriptorDXGISharedHandle();
-
- // Note: SharedHandle must be a handle to a texture object.
- HANDLE sharedHandle = nullptr;
-
- // Whether the underlying texture has a keyed mutex which should be used for synchronization.
- bool useKeyedMutex = false;
-};
-
-struct DAWN_NATIVE_EXPORT ExternalImageDescriptorD3D11Texture : ExternalImageDescriptor {
- public:
- ExternalImageDescriptorD3D11Texture();
-
- // Texture is used for creating ExternalImageDXGI with d3d11 backend. It must be an
- // ID3D11Texture2D object and created from the same ID3D11Device used in the WGPUDevice.
- Microsoft::WRL::ComPtr<IUnknown> texture;
-};
-
-struct DAWN_NATIVE_EXPORT ExternalImageDXGIFenceDescriptor {
- // Shared handle for the fence. This never passes ownership to the callee (when used as an input
- // parameter) or to the caller (when used as a return value or output parameter).
- HANDLE fenceHandle = nullptr;
-
- // The value that was previously signaled on this fence and should be waited on.
- uint64_t fenceValue = 0;
-};
-
-struct DAWN_NATIVE_EXPORT ExternalImageDXGIBeginAccessDescriptor {
- bool isInitialized = false; // Whether the texture is initialized on import
- WGPUTextureUsageFlags usage = WGPUTextureUsage_None;
-
- // A list of fences to wait on before accessing the texture.
- std::vector<ExternalImageDXGIFenceDescriptor> waitFences;
-
- // Whether the texture is for a WebGPU swap chain.
- bool isSwapChainTexture = false;
-};
-
-class DAWN_NATIVE_EXPORT ExternalImageDXGI {
- public:
- ~ExternalImageDXGI();
-
- static std::unique_ptr<ExternalImageDXGI> Create(WGPUDevice device,
- const ExternalImageDescriptor* descriptor);
-
- // Returns true if the external image resources are still valid, otherwise BeginAccess() is
- // guaranteed to fail e.g. after device destruction.
- bool IsValid() const;
-
- // Creates WGPUTexture wrapping the DXGI shared handle. The provided wait fences will be
- // synchronized before using the texture in any command lists. Empty fences (nullptr handle) are
- // ignored for convenience (EndAccess can return such fences).
- WGPUTexture BeginAccess(const ExternalImageDXGIBeginAccessDescriptor* descriptor);
-
- // Returns the signalFence that the client must wait on for correct synchronization. Can return
- // an empty fence (nullptr handle) if the texture wasn't accessed by Dawn.
- // Note that merely calling Destroy() on the WGPUTexture does not ensure synchronization.
- void EndAccess(WGPUTexture texture, ExternalImageDXGIFenceDescriptor* signalFence);
-
- private:
- explicit ExternalImageDXGI(std::unique_ptr<ExternalImageDXGIImpl> impl);
-
- std::unique_ptr<ExternalImageDXGIImpl> mImpl;
-};
-
} // namespace dawn::native::d3d
#endif // INCLUDE_DAWN_NATIVE_D3DBACKEND_H_
diff --git a/include/dawn/native/DawnNative.h b/include/dawn/native/DawnNative.h
index f0a9ffe..4b5e9e3 100644
--- a/include/dawn/native/DawnNative.h
+++ b/include/dawn/native/DawnNative.h
@@ -234,8 +234,6 @@
OpaqueFD,
DmaBuf,
IOSurface,
- DXGISharedHandle,
- D3D11Texture,
EGLImage,
GLTexture,
AHardwareBuffer,
diff --git a/src/dawn/native/BUILD.gn b/src/dawn/native/BUILD.gn
index 450a056..80d6bae 100644
--- a/src/dawn/native/BUILD.gn
+++ b/src/dawn/native/BUILD.gn
@@ -454,8 +454,6 @@
"d3d/D3DError.h",
"d3d/DeviceD3D.cpp",
"d3d/DeviceD3D.h",
- "d3d/ExternalImageDXGIImpl.cpp",
- "d3d/ExternalImageDXGIImpl.h",
"d3d/Forward.h",
"d3d/KeyedMutex.cpp",
"d3d/KeyedMutex.h",
diff --git a/src/dawn/native/CMakeLists.txt b/src/dawn/native/CMakeLists.txt
index a2f4274..427f338 100644
--- a/src/dawn/native/CMakeLists.txt
+++ b/src/dawn/native/CMakeLists.txt
@@ -313,8 +313,6 @@
"d3d/D3DError.h"
"d3d/DeviceD3D.cpp"
"d3d/DeviceD3D.h"
- "d3d/ExternalImageDXGIImpl.cpp"
- "d3d/ExternalImageDXGIImpl.h"
"d3d/Forward.h"
"d3d/KeyedMutex.cpp"
"d3d/KeyedMutex.h"
diff --git a/src/dawn/native/d3d/D3DBackend.cpp b/src/dawn/native/d3d/D3DBackend.cpp
index ceb30b9..4947317 100644
--- a/src/dawn/native/d3d/D3DBackend.cpp
+++ b/src/dawn/native/d3d/D3DBackend.cpp
@@ -36,7 +36,6 @@
#include "dawn/common/Log.h"
#include "dawn/native/Adapter.h"
#include "dawn/native/d3d/DeviceD3D.h"
-#include "dawn/native/d3d/ExternalImageDXGIImpl.h"
#include "dawn/native/d3d/Forward.h"
#include "dawn/native/d3d/PhysicalDeviceD3D.h"
@@ -50,53 +49,4 @@
return ToBackend(FromAPI(adapter)->GetPhysicalDevice())->GetHardwareAdapter();
}
-ExternalImageDescriptorDXGISharedHandle::ExternalImageDescriptorDXGISharedHandle()
- : ExternalImageDescriptor(ExternalImageType::DXGISharedHandle) {}
-
-ExternalImageDescriptorD3D11Texture::ExternalImageDescriptorD3D11Texture()
- : ExternalImageDescriptor(ExternalImageType::D3D11Texture) {}
-
-ExternalImageDXGI::ExternalImageDXGI(std::unique_ptr<ExternalImageDXGIImpl> impl)
- : mImpl(std::move(impl)) {
- DAWN_ASSERT(mImpl != nullptr);
-}
-
-ExternalImageDXGI::~ExternalImageDXGI() {
- auto deviceLock = mImpl->GetScopedDeviceLock();
- mImpl = nullptr;
-}
-
-bool ExternalImageDXGI::IsValid() const {
- auto deviceLock = mImpl->GetScopedDeviceLock();
- return mImpl->IsValid();
-}
-
-WGPUTexture ExternalImageDXGI::BeginAccess(
- const ExternalImageDXGIBeginAccessDescriptor* descriptor) {
- auto deviceLock = mImpl->GetScopedDeviceLock();
- return mImpl->BeginAccess(descriptor);
-}
-
-void ExternalImageDXGI::EndAccess(WGPUTexture texture,
- ExternalImageDXGIFenceDescriptor* signalFence) {
- auto deviceLock = mImpl->GetScopedDeviceLock();
- mImpl->EndAccess(texture, signalFence);
-}
-
-// static
-std::unique_ptr<ExternalImageDXGI> ExternalImageDXGI::Create(
- WGPUDevice device,
- const ExternalImageDescriptor* descriptor) {
- Device* backendDevice = ToBackend(FromAPI(device));
- auto deviceLock = backendDevice->GetScopedLock();
-
- std::unique_ptr<ExternalImageDXGIImpl> impl =
- backendDevice->CreateExternalImageDXGIImpl(descriptor);
- if (!impl) {
- dawn::ErrorLog() << "Failed to create DXGI external image";
- return nullptr;
- }
- return std::unique_ptr<ExternalImageDXGI>(new ExternalImageDXGI(std::move(impl)));
-}
-
} // namespace dawn::native::d3d
diff --git a/src/dawn/native/d3d/DeviceD3D.cpp b/src/dawn/native/d3d/DeviceD3D.cpp
index 02d0621..bc5608e 100644
--- a/src/dawn/native/d3d/DeviceD3D.cpp
+++ b/src/dawn/native/d3d/DeviceD3D.cpp
@@ -30,7 +30,6 @@
#include <utility>
#include "dawn/native/d3d/BackendD3D.h"
-#include "dawn/native/d3d/ExternalImageDXGIImpl.h"
#include "dawn/native/d3d/Forward.h"
#include "dawn/native/d3d/PhysicalDeviceD3D.h"
#include "dawn/native/d3d/SharedFenceD3D.h"
@@ -47,20 +46,7 @@
Destroy();
}
-void Device::DestroyImpl() {
- // TODO(crbug.com/dawn/831): DestroyImpl is called from two places.
- // - It may be called if the device is explicitly destroyed with APIDestroy.
- // This case is NOT thread-safe and needs proper synchronization with other
- // simultaneous uses of the device.
- // - It may be called when the last ref to the device is dropped and the device
- // is implicitly destroyed. This case is thread-safe because there are no
- // other threads using the device since there are no other live refs.
- while (!mExternalImageList.empty()) {
- d3d::ExternalImageDXGIImpl* externalImage = mExternalImageList.head()->value();
- // ExternalImageDXGIImpl::DestroyInternal() calls RemoveFromList().
- externalImage->DestroyInternal();
- }
-}
+void Device::DestroyImpl() {}
ResultOrError<wgpu::TextureUsage> Device::GetSupportedSurfaceUsageImpl(
const Surface* surface) const {
@@ -78,14 +64,4 @@
return ToBackend(GetPhysicalDevice())->GetBackend()->GetFactory();
}
-std::unique_ptr<ExternalImageDXGIImpl> Device::CreateExternalImageDXGIImpl(
- const ExternalImageDescriptor* descriptor) {
- std::unique_ptr<ExternalImageDXGIImpl> externalImage;
- if (!ConsumedError(CreateExternalImageDXGIImplImpl(descriptor), &externalImage)) {
- mExternalImageList.Append(externalImage.get());
- return externalImage;
- }
- return {};
-}
-
} // namespace dawn::native::d3d
diff --git a/src/dawn/native/d3d/DeviceD3D.h b/src/dawn/native/d3d/DeviceD3D.h
index 272abd9..a752cd2 100644
--- a/src/dawn/native/d3d/DeviceD3D.h
+++ b/src/dawn/native/d3d/DeviceD3D.h
@@ -36,11 +36,6 @@
namespace dawn::native::d3d {
-struct ExternalImageDescriptorDXGISharedHandle;
-struct ExternalImageDXGIFenceDescriptor;
-class ExternalImageDXGIImpl;
-class Fence;
-class KeyedMutex;
class PlatformFunctions;
class Device : public DeviceBase {
@@ -57,31 +52,10 @@
const PlatformFunctions* GetFunctions() const;
ComPtr<IDXGIFactory4> GetFactory() const;
- std::unique_ptr<ExternalImageDXGIImpl> CreateExternalImageDXGIImpl(
- const ExternalImageDescriptor* descriptor);
-
- virtual ResultOrError<FenceAndSignalValue> CreateFence(
- const ExternalImageDXGIFenceDescriptor* descriptor) = 0;
-
- virtual Ref<TextureBase> CreateD3DExternalTexture(
- const UnpackedPtr<TextureDescriptor>& descriptor,
- ComPtr<IUnknown> d3dTexture,
- Ref<KeyedMutex> keyedMutex,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture,
- bool isInitialized) = 0;
-
virtual void DisposeKeyedMutex(ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex) = 0;
protected:
void DestroyImpl() override;
-
- virtual ResultOrError<std::unique_ptr<ExternalImageDXGIImpl>> CreateExternalImageDXGIImplImpl(
- const ExternalImageDescriptor* descriptor) = 0;
-
- private:
- // List of external image resources opened using this device.
- LinkedList<d3d::ExternalImageDXGIImpl> mExternalImageList;
};
} // namespace dawn::native::d3d
diff --git a/src/dawn/native/d3d/ExternalImageDXGIImpl.cpp b/src/dawn/native/d3d/ExternalImageDXGIImpl.cpp
deleted file mode 100644
index 531b331..0000000
--- a/src/dawn/native/d3d/ExternalImageDXGIImpl.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright 2022 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 "dawn/native/d3d/ExternalImageDXGIImpl.h"
-
-#include <utility>
-#include <vector>
-
-#include "dawn/common/Log.h"
-#include "dawn/native/ChainUtils.h"
-#include "dawn/native/D3D12Backend.h"
-#include "dawn/native/DawnNative.h"
-#include "dawn/native/d3d/DeviceD3D.h"
-#include "dawn/native/d3d/Forward.h"
-#include "dawn/native/d3d/KeyedMutex.h"
-#include "dawn/native/d3d/QueueD3D.h"
-#include "dawn/native/d3d/SharedFenceD3D.h"
-#include "dawn/native/d3d/TextureD3D.h"
-
-namespace dawn::native::d3d {
-
-MaybeError ValidateTextureDescriptorCanBeWrapped(const UnpackedPtr<TextureDescriptor>& descriptor) {
- DAWN_INVALID_IF(descriptor->dimension != wgpu::TextureDimension::e2D,
- "Texture dimension (%s) is not %s.", descriptor->dimension,
- wgpu::TextureDimension::e2D);
-
- DAWN_INVALID_IF(descriptor->mipLevelCount != 1, "Mip level count (%u) is not 1.",
- descriptor->mipLevelCount);
-
- DAWN_INVALID_IF(descriptor->size.depthOrArrayLayers != 1, "Array layer count (%u) is not 1.",
- descriptor->size.depthOrArrayLayers);
-
- DAWN_INVALID_IF(descriptor->sampleCount != 1, "Sample count (%u) is not 1.",
- descriptor->sampleCount);
-
- return {};
-}
-
-ExternalImageDXGIImpl::ExternalImageDXGIImpl(
- Device* backendDevice,
- ComPtr<IUnknown> d3dResource,
- Ref<d3d::KeyedMutex> keyedMutex,
- const UnpackedPtr<TextureDescriptor>& textureDescriptor)
- : mBackendDevice(backendDevice),
- mD3DResource(std::move(d3dResource)),
- mKeyedMutex(std::move(keyedMutex)),
- mUsage(textureDescriptor->usage),
- mDimension(textureDescriptor->dimension),
- mSize(textureDescriptor->size),
- mFormat(textureDescriptor->format),
- mMipLevelCount(textureDescriptor->mipLevelCount),
- mSampleCount(textureDescriptor->sampleCount),
- mViewFormats(textureDescriptor->viewFormats,
- textureDescriptor->viewFormats + textureDescriptor->viewFormatCount) {
- DAWN_ASSERT(mBackendDevice->IsLockedByCurrentThreadIfNeeded());
- DAWN_ASSERT(mBackendDevice != nullptr);
- DAWN_ASSERT(!textureDescriptor->nextInChain ||
- textureDescriptor->nextInChain->sType ==
- wgpu::SType::DawnTextureInternalUsageDescriptor);
- if (textureDescriptor->nextInChain) {
- mUsageInternal = reinterpret_cast<const wgpu::DawnTextureInternalUsageDescriptor*>(
- textureDescriptor->nextInChain)
- ->internalUsage;
- }
-}
-
-ExternalImageDXGIImpl::~ExternalImageDXGIImpl() {
- DAWN_ASSERT(mBackendDevice->IsLockedByCurrentThreadIfNeeded());
- DestroyInternal();
-}
-
-Mutex::AutoLock ExternalImageDXGIImpl::GetScopedDeviceLock() const {
- return mBackendDevice->GetScopedLock();
-}
-
-bool ExternalImageDXGIImpl::IsValid() const {
- DAWN_ASSERT(mBackendDevice->IsLockedByCurrentThreadIfNeeded());
- return IsInList();
-}
-
-void ExternalImageDXGIImpl::DestroyInternal() {
- DAWN_ASSERT(mBackendDevice->IsLockedByCurrentThreadIfNeeded());
- if (IsInList()) {
- mKeyedMutex = nullptr;
- mD3DResource = nullptr;
- }
-
- if (IsInList()) {
- RemoveFromList();
- }
-}
-
-WGPUTexture ExternalImageDXGIImpl::BeginAccess(
- const d3d::ExternalImageDXGIBeginAccessDescriptor* descriptor) {
- DAWN_ASSERT(mBackendDevice->IsLockedByCurrentThreadIfNeeded());
- DAWN_ASSERT(descriptor != nullptr);
-
- if (!IsInList()) {
- dawn::ErrorLog() << "Cannot use external image after device destruction";
- return nullptr;
- }
-
- // Ensure the texture usage is allowed
- if (!IsSubset(descriptor->usage, static_cast<WGPUTextureUsageFlags>(mUsage))) {
- dawn::ErrorLog() << "Texture usage is not valid for external image";
- return nullptr;
- }
-
- DAWN_ASSERT(mBackendDevice != nullptr);
- if (mBackendDevice->GetValidInternalFormat(mFormat).IsMultiPlanar() &&
- !descriptor->isInitialized) {
- [[maybe_unused]] bool consumed = mBackendDevice->ConsumedError(DAWN_VALIDATION_ERROR(
- "External textures with multiplanar formats must be initialized."));
- return nullptr;
- }
-
- TextureDescriptor textureDescriptor = {};
- textureDescriptor.usage = static_cast<wgpu::TextureUsage>(descriptor->usage);
- textureDescriptor.dimension = mDimension;
- textureDescriptor.size = {mSize.width, mSize.height, mSize.depthOrArrayLayers};
- textureDescriptor.format = mFormat;
- textureDescriptor.mipLevelCount = mMipLevelCount;
- textureDescriptor.sampleCount = mSampleCount;
- textureDescriptor.viewFormats = mViewFormats.data();
- textureDescriptor.viewFormatCount = mViewFormats.size();
-
- DawnTextureInternalUsageDescriptor internalDesc = {};
- if (mUsageInternal != wgpu::TextureUsage::None) {
- textureDescriptor.nextInChain = &internalDesc;
- internalDesc.internalUsage = mUsageInternal;
- }
-
- std::vector<FenceAndSignalValue> waitFences;
- for (const d3d::ExternalImageDXGIFenceDescriptor& fenceDescriptor : descriptor->waitFences) {
- FenceAndSignalValue fence;
- if (mBackendDevice->ConsumedError(
- ToBackend(mBackendDevice.Get())->CreateFence(&fenceDescriptor), &fence)) {
- dawn::ErrorLog() << "Unable to create D3D11 fence for external image";
- return nullptr;
- }
- waitFences.push_back(std::move(fence));
- }
-
- Ref<TextureBase> texture =
- ToBackend(mBackendDevice.Get())
- ->CreateD3DExternalTexture(Unpack(&textureDescriptor), mD3DResource, mKeyedMutex,
- std::move(waitFences), descriptor->isSwapChainTexture,
- descriptor->isInitialized);
- return ToAPI(ReturnToAPI(std::move(texture)));
-}
-
-void ExternalImageDXGIImpl::EndAccess(WGPUTexture texture,
- d3d::ExternalImageDXGIFenceDescriptor* signalFence) {
- DAWN_ASSERT(mBackendDevice->IsLockedByCurrentThreadIfNeeded());
-
- if (!IsInList()) {
- dawn::ErrorLog() << "Cannot use external image after device destruction";
- return;
- }
-
- DAWN_ASSERT(mBackendDevice != nullptr);
- DAWN_ASSERT(signalFence != nullptr);
-
- Texture* backendTexture = ToBackend(FromAPI(texture));
- DAWN_ASSERT(backendTexture != nullptr);
-
- Ref<SharedFence> sharedFence;
- if (mBackendDevice->ConsumedError(
- ToBackend(mBackendDevice->GetQueue())->GetOrCreateSharedFence(), &sharedFence)) {
- dawn::ErrorLog() << "Could not retrieve device shared fence";
- return;
- }
-
- ExecutionSerial fenceValue;
- if (mBackendDevice->ConsumedError(backendTexture->EndAccess(), &fenceValue)) {
- dawn::ErrorLog() << "D3D texture end access failed";
- return;
- }
-
- signalFence->fenceHandle = sharedFence->GetFenceHandle();
- signalFence->fenceValue = static_cast<uint64_t>(fenceValue);
-}
-
-} // namespace dawn::native::d3d
diff --git a/src/dawn/native/d3d/ExternalImageDXGIImpl.h b/src/dawn/native/d3d/ExternalImageDXGIImpl.h
deleted file mode 100644
index ae73715..0000000
--- a/src/dawn/native/d3d/ExternalImageDXGIImpl.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2023 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.
-
-#ifndef SRC_DAWN_NATIVE_D3D_EXTERNALIMAGEDXGIIMPL_H_
-#define SRC_DAWN_NATIVE_D3D_EXTERNALIMAGEDXGIIMPL_H_
-
-#include <wrl/client.h>
-
-#include <memory>
-#include <optional>
-#include <utility>
-#include <vector>
-
-#include "dawn/common/LinkedList.h"
-#include "dawn/common/Mutex.h"
-#include "dawn/common/NonCopyable.h"
-#include "dawn/native/Error.h"
-#include "dawn/native/Forward.h"
-#include "dawn/native/IntegerTypes.h"
-#include "dawn/native/d3d/d3d_platform.h"
-#include "dawn/webgpu_cpp.h"
-
-namespace dawn::native::d3d {
-
-class Device;
-class KeyedMutex;
-struct ExternalImageDXGIBeginAccessDescriptor;
-struct ExternalImageDXGIFenceDescriptor;
-struct ExternalImageDescriptorDXGISharedHandle;
-
-MaybeError ValidateTextureDescriptorCanBeWrapped(const UnpackedPtr<TextureDescriptor>& descriptor);
-
-class ExternalImageDXGIImpl : public LinkNode<ExternalImageDXGIImpl> {
- public:
- ExternalImageDXGIImpl(Device* backendDevice,
- ComPtr<IUnknown> d3dResource,
- Ref<d3d::KeyedMutex> keyedMutex,
- const UnpackedPtr<TextureDescriptor>& textureDescriptor);
- ~ExternalImageDXGIImpl();
-
- ExternalImageDXGIImpl(const ExternalImageDXGIImpl&) = delete;
- ExternalImageDXGIImpl& operator=(const ExternalImageDXGIImpl&) = delete;
-
- bool IsValid() const;
-
- WGPUTexture BeginAccess(const ExternalImageDXGIBeginAccessDescriptor* descriptor);
- void EndAccess(WGPUTexture texture, ExternalImageDXGIFenceDescriptor* signalFence);
-
- // This method should only be called by internal code. Don't call this from D3D12Backend side,
- // or without locking.
- void DestroyInternal();
-
- [[nodiscard]] Mutex::AutoLock GetScopedDeviceLock() const;
-
- protected:
- Ref<DeviceBase> mBackendDevice;
- ComPtr<IUnknown> mD3DResource;
- Ref<d3d::KeyedMutex> mKeyedMutex;
- wgpu::TextureUsage mUsage;
- wgpu::TextureUsage mUsageInternal = wgpu::TextureUsage::None;
- wgpu::TextureDimension mDimension;
- Extent3D mSize;
- wgpu::TextureFormat mFormat;
- uint32_t mMipLevelCount;
- uint32_t mSampleCount;
- std::vector<wgpu::TextureFormat> mViewFormats;
-};
-
-} // namespace dawn::native::d3d
-
-#endif // SRC_DAWN_NATIVE_D3D_EXTERNALIMAGEDXGIIMPL_H_
diff --git a/src/dawn/native/d3d11/DeviceD3D11.cpp b/src/dawn/native/d3d11/DeviceD3D11.cpp
index 896245ef..f9907eb 100644
--- a/src/dawn/native/d3d11/DeviceD3D11.cpp
+++ b/src/dawn/native/d3d11/DeviceD3D11.cpp
@@ -38,7 +38,6 @@
#include "dawn/native/DynamicUploader.h"
#include "dawn/native/Instance.h"
#include "dawn/native/d3d/D3DError.h"
-#include "dawn/native/d3d/ExternalImageDXGIImpl.h"
#include "dawn/native/d3d/KeyedMutex.h"
#include "dawn/native/d3d/UtilsD3D.h"
#include "dawn/native/d3d11/BackendD3D11.h"
@@ -394,89 +393,6 @@
void Device::SetLabelImpl() {}
-ResultOrError<FenceAndSignalValue> Device::CreateFence(
- const d3d::ExternalImageDXGIFenceDescriptor* externalImageFenceDesc) {
- SharedFenceDXGISharedHandleDescriptor sharedFenceDesc;
- sharedFenceDesc.handle = externalImageFenceDesc->fenceHandle;
-
- Ref<SharedFence> fence;
- DAWN_TRY_ASSIGN(fence, SharedFence::Create(this, "Imported DXGI fence", &sharedFenceDesc));
-
- return FenceAndSignalValue{std::move(fence), externalImageFenceDesc->fenceValue};
-}
-
-ResultOrError<std::unique_ptr<d3d::ExternalImageDXGIImpl>> Device::CreateExternalImageDXGIImplImpl(
- const ExternalImageDescriptor* descriptor) {
- // ExternalImageDXGIImpl holds a weak reference to the device. If the device is destroyed before
- // the image is created, the image will have a dangling reference to the device which can cause
- // a use-after-free.
- DAWN_TRY(ValidateIsAlive());
-
- ComPtr<ID3D11Resource> d3d11Resource;
- ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex;
- switch (descriptor->GetType()) {
- case ExternalImageType::DXGISharedHandle: {
- const auto* sharedHandleDescriptor =
- static_cast<const d3d::ExternalImageDescriptorDXGISharedHandle*>(descriptor);
- DAWN_TRY(CheckHRESULT(
- mD3d11Device5->OpenSharedResource1(sharedHandleDescriptor->sharedHandle,
- IID_PPV_ARGS(&d3d11Resource)),
- "D3D11 OpenSharedResource1"));
- if (sharedHandleDescriptor->useKeyedMutex) {
- d3d11Resource.As(&dxgiKeyedMutex);
- DAWN_INVALID_IF(!dxgiKeyedMutex,
- "Failed to retrieve DXGI keyed mutex when expected");
- }
- break;
- }
- case ExternalImageType::D3D11Texture: {
- const auto* d3d11TextureDescriptor =
- static_cast<const d3d::ExternalImageDescriptorD3D11Texture*>(descriptor);
- DAWN_TRY(CheckHRESULT(d3d11TextureDescriptor->texture.As(&d3d11Resource),
- "Cannot get ID3D11Resource from texture"));
- ComPtr<ID3D11Device> textureDevice;
- d3d11Resource->GetDevice(textureDevice.GetAddressOf());
- DAWN_INVALID_IF(
- textureDevice.Get() != mD3d11Device.Get(),
- "The D3D11 device of the texture and the D3D11 device of the WebGPU device "
- "must be same.");
- d3d11Resource.As(&dxgiKeyedMutex);
- break;
- }
- default: {
- return DAWN_VALIDATION_ERROR("descriptor type (%d) is not supported",
- static_cast<int>(descriptor->GetType()));
- }
- }
-
- UnpackedPtr<TextureDescriptor> textureDescriptor;
- DAWN_TRY_ASSIGN(textureDescriptor, ValidateAndUnpack(FromAPI(descriptor->cTextureDescriptor)));
- DAWN_TRY(
- ValidateTextureDescriptor(this, textureDescriptor, AllowMultiPlanarTextureFormat::Yes));
-
- DAWN_TRY_CONTEXT(d3d::ValidateTextureDescriptorCanBeWrapped(textureDescriptor),
- "validating that a D3D11 external image can be wrapped with %s",
- textureDescriptor);
-
- DAWN_TRY(ValidateTextureCanBeWrapped(d3d11Resource.Get(), textureDescriptor));
-
- // Shared handle is assumed to support resource sharing capability. The resource
- // shared capability tier must agree to share resources between D3D devices.
- const Format* format = GetInternalFormat(textureDescriptor->format).AcquireSuccess();
- if (format->IsMultiPlanar() && descriptor->GetType() == ExternalImageType::DXGISharedHandle) {
- DAWN_TRY(ValidateVideoTextureCanBeShared(
- this, d3d::DXGITextureFormat(textureDescriptor->format)));
- }
-
- Ref<d3d::KeyedMutex> keyedMutex;
- if (dxgiKeyedMutex) {
- keyedMutex = AcquireRef(new d3d::KeyedMutex(this, std::move(dxgiKeyedMutex)));
- }
-
- return std::make_unique<d3d::ExternalImageDXGIImpl>(this, std::move(d3d11Resource),
- std::move(keyedMutex), textureDescriptor);
-}
-
void Device::DisposeKeyedMutex(ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex) {
// Nothing to do, the ComPtr will release the keyed mutex.
}
@@ -493,22 +409,6 @@
return true;
}
-Ref<TextureBase> Device::CreateD3DExternalTexture(const UnpackedPtr<TextureDescriptor>& descriptor,
- ComPtr<IUnknown> d3dTexture,
- Ref<d3d::KeyedMutex> keyedMutex,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture,
- bool isInitialized) {
- Ref<Texture> dawnTexture;
- if (ConsumedError(Texture::CreateExternalImage(this, descriptor, std::move(d3dTexture),
- std::move(keyedMutex), std::move(waitFences),
- isSwapChainTexture, isInitialized),
- &dawnTexture)) {
- return nullptr;
- }
- return {dawnTexture};
-}
-
uint32_t Device::GetUAVSlotCount() const {
return ToBackend(GetPhysicalDevice())->GetUAVSlotCount();
}
diff --git a/src/dawn/native/d3d11/DeviceD3D11.h b/src/dawn/native/d3d11/DeviceD3D11.h
index 8d8b80e..c13f12b 100644
--- a/src/dawn/native/d3d11/DeviceD3D11.h
+++ b/src/dawn/native/d3d11/DeviceD3D11.h
@@ -56,12 +56,6 @@
const DeviceInfo& GetDeviceInfo() const;
void ReferenceUntilUnused(ComPtr<IUnknown> object);
- Ref<TextureBase> CreateD3DExternalTexture(const UnpackedPtr<TextureDescriptor>& descriptor,
- ComPtr<IUnknown> d3dTexture,
- Ref<d3d::KeyedMutex> keyedMutex,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture,
- bool isInitialized) override;
ResultOrError<Ref<CommandBufferBase>> CreateCommandBuffer(
CommandEncoder* encoder,
@@ -84,12 +78,6 @@
bool IsResolveTextureBlitWithDrawSupported() const override;
void SetLabelImpl() override;
- ResultOrError<FenceAndSignalValue> CreateFence(
- const d3d::ExternalImageDXGIFenceDescriptor* descriptor) override;
-
- ResultOrError<std::unique_ptr<d3d::ExternalImageDXGIImpl>> CreateExternalImageDXGIImplImpl(
- const ExternalImageDescriptor* descriptor) override;
-
void DisposeKeyedMutex(ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex) override;
uint32_t GetUAVSlotCount() const;
diff --git a/src/dawn/native/d3d11/TextureD3D11.cpp b/src/dawn/native/d3d11/TextureD3D11.cpp
index 5ef307f..d052901 100644
--- a/src/dawn/native/d3d11/TextureD3D11.cpp
+++ b/src/dawn/native/d3d11/TextureD3D11.cpp
@@ -226,40 +226,6 @@
}
// static
-ResultOrError<Ref<Texture>> Texture::CreateExternalImage(
- Device* device,
- const UnpackedPtr<TextureDescriptor>& descriptor,
- ComPtr<IUnknown> d3dTexture,
- Ref<d3d::KeyedMutex> keyedMutex,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture,
- bool isInitialized) {
- Ref<Texture> dawnTexture = AcquireRef(new Texture(device, descriptor, Kind::Normal));
- DAWN_TRY(
- dawnTexture->InitializeAsExternalTexture(std::move(d3dTexture), std::move(keyedMutex)));
-
- auto commandContext =
- ToBackend(device->GetQueue())
- ->GetScopedPendingCommandContext(ExecutionQueueBase::SubmitMode::Normal);
- for (const auto& fence : waitFences) {
- DAWN_TRY(CheckHRESULT(
- commandContext.Wait(ToBackend(fence.object)->GetD3DFence(), fence.signaledValue),
- "ID3D11DeviceContext4::Wait"));
- }
-
- // Importing a multi-planar format must be initialized. This is required because
- // a shared multi-planar format cannot be initialized by Dawn.
- DAWN_INVALID_IF(
- !isInitialized && dawnTexture->GetFormat().IsMultiPlanar(),
- "Cannot create a texture with a multi-planar format (%s) with uninitialized data.",
- dawnTexture->GetFormat().format);
-
- dawnTexture->SetIsSubresourceContentInitialized(isInitialized,
- dawnTexture->GetAllSubresources());
- return std::move(dawnTexture);
-}
-
-// static
ResultOrError<Ref<Texture>> Texture::CreateFromSharedTextureMemory(
SharedTextureMemory* memory,
const UnpackedPtr<TextureDescriptor>& descriptor) {
diff --git a/src/dawn/native/d3d11/TextureD3D11.h b/src/dawn/native/d3d11/TextureD3D11.h
index 7afca35..58cf57c 100644
--- a/src/dawn/native/d3d11/TextureD3D11.h
+++ b/src/dawn/native/d3d11/TextureD3D11.h
@@ -64,14 +64,6 @@
static ResultOrError<Ref<Texture>> Create(Device* device,
const UnpackedPtr<TextureDescriptor>& descriptor,
ComPtr<ID3D11Resource> d3d11Texture);
- static ResultOrError<Ref<Texture>> CreateExternalImage(
- Device* device,
- const UnpackedPtr<TextureDescriptor>& descriptor,
- ComPtr<IUnknown> d3dTexture,
- Ref<d3d::KeyedMutex> keyedMutex,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture,
- bool isInitialized);
static ResultOrError<Ref<Texture>> CreateFromSharedTextureMemory(
SharedTextureMemory* memory,
const UnpackedPtr<TextureDescriptor>& descriptor);
diff --git a/src/dawn/native/d3d12/DeviceD3D12.cpp b/src/dawn/native/d3d12/DeviceD3D12.cpp
index a8e9231..3fc0cc4 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/DeviceD3D12.cpp
@@ -38,7 +38,6 @@
#include "dawn/native/DynamicUploader.h"
#include "dawn/native/Instance.h"
#include "dawn/native/d3d/D3DError.h"
-#include "dawn/native/d3d/ExternalImageDXGIImpl.h"
#include "dawn/native/d3d/KeyedMutex.h"
#include "dawn/native/d3d12/BackendD3D12.h"
#include "dawn/native/d3d12/BindGroupD3D12.h"
@@ -562,76 +561,6 @@
forceAllocateAsCommittedResource);
}
-ResultOrError<FenceAndSignalValue> Device::CreateFence(
- const d3d::ExternalImageDXGIFenceDescriptor* externalImageFenceDesc) {
- SharedFenceDXGISharedHandleDescriptor sharedFenceDesc;
- sharedFenceDesc.handle = externalImageFenceDesc->fenceHandle;
-
- Ref<SharedFence> fence;
- DAWN_TRY_ASSIGN(fence, SharedFence::Create(this, "Imported DXGI fence", &sharedFenceDesc));
-
- return FenceAndSignalValue{std::move(fence), externalImageFenceDesc->fenceValue};
-}
-
-ResultOrError<std::unique_ptr<d3d::ExternalImageDXGIImpl>> Device::CreateExternalImageDXGIImplImpl(
- const ExternalImageDescriptor* descriptor) {
- // ExternalImageDXGIImpl holds a weak reference to the device. If the device is destroyed before
- // the image is created, the image will have a dangling reference to the device which can cause
- // a use-after-free.
- DAWN_TRY(ValidateIsAlive());
-
- DAWN_INVALID_IF(descriptor->GetType() != ExternalImageType::DXGISharedHandle,
- "descriptor is not an ExternalImageDescriptorDXGISharedHandle");
-
- const d3d::ExternalImageDescriptorDXGISharedHandle* sharedHandleDescriptor =
- static_cast<const d3d::ExternalImageDescriptorDXGISharedHandle*>(descriptor);
-
- Microsoft::WRL::ComPtr<ID3D12Resource> d3d12Resource;
- Ref<d3d::KeyedMutex> keyedMutex;
- DAWN_TRY(ImportSharedHandleResource(sharedHandleDescriptor->sharedHandle,
- sharedHandleDescriptor->useKeyedMutex, d3d12Resource,
- keyedMutex));
-
- UnpackedPtr<TextureDescriptor> textureDescriptor;
- DAWN_TRY_ASSIGN(textureDescriptor,
- ValidateAndUnpack(FromAPI(sharedHandleDescriptor->cTextureDescriptor)));
- DAWN_TRY(
- ValidateTextureDescriptor(this, textureDescriptor, AllowMultiPlanarTextureFormat::Yes));
-
- DAWN_TRY_CONTEXT(d3d::ValidateTextureDescriptorCanBeWrapped(textureDescriptor),
- "validating that a D3D12 external image can be wrapped with %s",
- textureDescriptor);
-
- DAWN_TRY(ValidateTextureCanBeWrapped(d3d12Resource.Get(), textureDescriptor));
-
- // Shared handle is assumed to support resource sharing capability. The resource
- // shared capability tier must agree to share resources between D3D devices.
- const Format* format = GetInternalFormat(textureDescriptor->format).AcquireSuccess();
- if (format->IsMultiPlanar()) {
- DAWN_TRY(ValidateVideoTextureCanBeShared(
- this, d3d::DXGITextureFormat(textureDescriptor->format)));
- }
-
- return std::make_unique<d3d::ExternalImageDXGIImpl>(this, std::move(d3d12Resource),
- std::move(keyedMutex), textureDescriptor);
-}
-
-Ref<TextureBase> Device::CreateD3DExternalTexture(const UnpackedPtr<TextureDescriptor>& descriptor,
- ComPtr<IUnknown> d3dTexture,
- Ref<d3d::KeyedMutex> keyedMutex,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture,
- bool isInitialized) {
- Ref<Texture> dawnTexture;
- if (ConsumedError(Texture::CreateExternalImage(this, descriptor, std::move(d3dTexture),
- std::move(keyedMutex), std::move(waitFences),
- isSwapChainTexture, isInitialized),
- &dawnTexture)) {
- return nullptr;
- }
- return {dawnTexture};
-}
-
MaybeError Device::ImportSharedHandleResource(HANDLE handle,
bool useKeyedMutex,
ComPtr<ID3D12Resource>& d3d12Resource,
diff --git a/src/dawn/native/d3d12/DeviceD3D12.h b/src/dawn/native/d3d12/DeviceD3D12.h
index 9ac8aa3..a46bf8f 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.h
+++ b/src/dawn/native/d3d12/DeviceD3D12.h
@@ -139,19 +139,6 @@
MutexProtected<StagingDescriptorAllocator>& GetDepthStencilViewAllocator() const;
- ResultOrError<FenceAndSignalValue> CreateFence(
- const d3d::ExternalImageDXGIFenceDescriptor* descriptor) override;
-
- ResultOrError<std::unique_ptr<d3d::ExternalImageDXGIImpl>> CreateExternalImageDXGIImplImpl(
- const ExternalImageDescriptor* descriptor) override;
-
- Ref<TextureBase> CreateD3DExternalTexture(const UnpackedPtr<TextureDescriptor>& descriptor,
- ComPtr<IUnknown> d3dTexture,
- Ref<d3d::KeyedMutex> keyedMutex,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture,
- bool isInitialized) override;
-
void DisposeKeyedMutex(ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex) override;
MaybeError ImportSharedHandleResource(HANDLE handle,
diff --git a/src/dawn/native/d3d12/TextureD3D12.cpp b/src/dawn/native/d3d12/TextureD3D12.cpp
index 9a6fd16..530f257 100644
--- a/src/dawn/native/d3d12/TextureD3D12.cpp
+++ b/src/dawn/native/d3d12/TextureD3D12.cpp
@@ -196,31 +196,6 @@
}
// static
-ResultOrError<Ref<Texture>> Texture::CreateExternalImage(
- Device* device,
- const UnpackedPtr<TextureDescriptor>& descriptor,
- ComPtr<IUnknown> d3dTexture,
- Ref<d3d::KeyedMutex> keyedMutex,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture,
- bool isInitialized) {
- Ref<Texture> dawnTexture = AcquireRef(new Texture(device, descriptor));
- DAWN_TRY(dawnTexture->InitializeAsExternalTexture(std::move(d3dTexture), std::move(keyedMutex),
- std::move(waitFences), isSwapChainTexture));
-
- // Importing a multi-planar format must be initialized. This is required because
- // a shared multi-planar format cannot be initialized by Dawn.
- DAWN_INVALID_IF(
- !isInitialized && dawnTexture->GetFormat().IsMultiPlanar(),
- "Cannot create a texture with a multi-planar format (%s) with uninitialized data.",
- dawnTexture->GetFormat().format);
-
- dawnTexture->SetIsSubresourceContentInitialized(isInitialized,
- dawnTexture->GetAllSubresources());
- return std::move(dawnTexture);
-}
-
-// static
ResultOrError<Ref<Texture>> Texture::Create(Device* device,
const UnpackedPtr<TextureDescriptor>& descriptor,
ComPtr<ID3D12Resource> d3d12Texture) {
diff --git a/src/dawn/native/d3d12/TextureD3D12.h b/src/dawn/native/d3d12/TextureD3D12.h
index 4dc1dce..476e51b 100644
--- a/src/dawn/native/d3d12/TextureD3D12.h
+++ b/src/dawn/native/d3d12/TextureD3D12.h
@@ -59,14 +59,6 @@
public:
static ResultOrError<Ref<Texture>> Create(Device* device,
const UnpackedPtr<TextureDescriptor>& descriptor);
- static ResultOrError<Ref<Texture>> CreateExternalImage(
- Device* device,
- const UnpackedPtr<TextureDescriptor>& descriptor,
- ComPtr<IUnknown> d3dTexture,
- Ref<d3d::KeyedMutex> keyedMutex,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture,
- bool isInitialized);
static ResultOrError<Ref<Texture>> Create(Device* device,
const UnpackedPtr<TextureDescriptor>& descriptor,
ComPtr<ID3D12Resource> d3d12Texture);
diff --git a/src/dawn/tests/BUILD.gn b/src/dawn/tests/BUILD.gn
index de09e9c..37963f1 100644
--- a/src/dawn/tests/BUILD.gn
+++ b/src/dawn/tests/BUILD.gn
@@ -682,10 +682,7 @@
"dxgi.lib",
]
- sources += [
- "end2end/D3DResourceWrappingTests.cpp",
- "end2end/VideoViewsTests_win.cpp",
- ]
+ sources += [ "end2end/VideoViewsTests_win.cpp" ]
}
if (dawn_enable_d3d12) {
diff --git a/src/dawn/tests/end2end/D3DResourceWrappingTests.cpp b/src/dawn/tests/end2end/D3DResourceWrappingTests.cpp
deleted file mode 100644
index b45a1d9..0000000
--- a/src/dawn/tests/end2end/D3DResourceWrappingTests.cpp
+++ /dev/null
@@ -1,1300 +0,0 @@
-// Copyright 2019 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 <d3d11.h>
-#include <d3d11_4.h>
-#include <d3d12.h>
-#include <dxgi1_4.h>
-#include <wrl/client.h>
-
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <utility>
-#include <vector>
-
-#include "dawn/native/D3D11Backend.h"
-#include "dawn/native/D3D12Backend.h"
-#include "dawn/tests/DawnTest.h"
-#include "dawn/utils/ComboRenderPipelineDescriptor.h"
-#include "dawn/utils/WGPUHelpers.h"
-
-using Microsoft::WRL::ComPtr;
-
-namespace dawn {
-namespace {
-
-enum class ExternalImageType {
- kSharedHandle,
- kD3D11Texture,
-};
-
-std::ostream& operator<<(std::ostream& o, const ExternalImageType& t) {
- switch (t) {
- case ExternalImageType::kSharedHandle:
- o << "SharedHandle";
- break;
- case ExternalImageType::kD3D11Texture:
- o << "D3D11Texture";
- break;
- }
- return o;
-}
-
-DAWN_TEST_PARAM_STRUCT(D3D12ResourceTestParams, ExternalImageType);
-
-class D3DResourceTestBase : public DawnTestWithParams<D3D12ResourceTestParams> {
- protected:
- std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
- return {wgpu::FeatureName::DawnInternalUsages};
- }
-
- public:
- void SetUp() override {
- DawnTestWithParams<D3D12ResourceTestParams>::SetUp();
-
- DAWN_TEST_UNSUPPORTED_IF(UsesWire());
-
- // D3D11Texture external image type is only supported on D3D11
- DAWN_TEST_UNSUPPORTED_IF(IsD3D11Texture() && !IsD3D11());
-
- mD3d11Device = IsD3D11Texture() ? dawn::native::d3d11::GetD3D11Device(device.Get())
- : CreateD3D11Device();
- mD3d11Device->GetImmediateContext(&mD3d11DeviceContext);
-
- baseDawnDescriptor.dimension = wgpu::TextureDimension::e2D;
- baseDawnDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
- baseDawnDescriptor.size = {kTestWidth, kTestHeight, 1};
- baseDawnDescriptor.sampleCount = 1;
- baseDawnDescriptor.mipLevelCount = 1;
- baseDawnDescriptor.usage =
- wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc |
- wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopyDst;
-
- baseD3dDescriptor.Width = kTestWidth;
- baseD3dDescriptor.Height = kTestHeight;
- baseD3dDescriptor.MipLevels = 1;
- baseD3dDescriptor.ArraySize = 1;
- baseD3dDescriptor.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- baseD3dDescriptor.SampleDesc.Count = 1;
- baseD3dDescriptor.SampleDesc.Quality = 0;
- baseD3dDescriptor.Usage = D3D11_USAGE_DEFAULT;
- baseD3dDescriptor.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
- baseD3dDescriptor.CPUAccessFlags = 0;
- baseD3dDescriptor.MiscFlags =
- D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED;
- }
-
- protected:
- bool IsSharedHandle() const {
- return GetParam().mExternalImageType == ExternalImageType::kSharedHandle;
- }
-
- bool IsD3D11Texture() const {
- return GetParam().mExternalImageType == ExternalImageType::kD3D11Texture;
- }
-
- ComPtr<ID3D11Device> CreateD3D11Device() {
- // Create the D3D11 device/contexts that will be used in subsequent tests
- ComPtr<IDXGIAdapter> dxgiAdapter = native::d3d::GetDXGIAdapter(device.GetAdapter().Get());
- DXGI_ADAPTER_DESC adapterDesc;
-
- HRESULT hr = dxgiAdapter->GetDesc(&adapterDesc);
- DAWN_ASSERT(hr == S_OK);
-
- ComPtr<IDXGIFactory4> dxgiFactory;
- hr = ::CreateDXGIFactory2(0, IID_PPV_ARGS(&dxgiFactory));
- DAWN_ASSERT(hr == S_OK);
-
- dxgiAdapter = nullptr;
- hr = dxgiFactory->EnumAdapterByLuid(adapterDesc.AdapterLuid, IID_PPV_ARGS(&dxgiAdapter));
- DAWN_ASSERT(hr == S_OK);
-
- ComPtr<ID3D11Device> d3d11Device;
- D3D_FEATURE_LEVEL d3dFeatureLevel;
- hr = ::D3D11CreateDevice(dxgiAdapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0, nullptr, 0,
- D3D11_SDK_VERSION, &d3d11Device, &d3dFeatureLevel, nullptr);
- DAWN_ASSERT(hr == S_OK);
- return d3d11Device;
- }
-
- std::unique_ptr<native::d3d::ExternalImageDXGI> CreateExternalImage(
- WGPUDevice targetDevice,
- ID3D11Texture2D* d3d11Texture,
- const wgpu::TextureDescriptor* dawnDesc,
- bool usingSharedHandle) const {
- if (usingSharedHandle) {
- ComPtr<IDXGIResource1> dxgiResource;
- EXPECT_EQ(d3d11Texture->QueryInterface(IID_PPV_ARGS(&dxgiResource)), S_OK);
-
- HANDLE textureSharedHandle = nullptr;
- EXPECT_EQ(dxgiResource->CreateSharedHandle(
- nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, nullptr,
- &textureSharedHandle),
- S_OK);
-
- native::d3d::ExternalImageDescriptorDXGISharedHandle externalImageDesc;
- externalImageDesc.cTextureDescriptor =
- reinterpret_cast<const WGPUTextureDescriptor*>(dawnDesc);
- externalImageDesc.sharedHandle = textureSharedHandle;
-
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage =
- native::d3d::ExternalImageDXGI::Create(targetDevice, &externalImageDesc);
-
- // Now that we've created all of our resources, we can close the handle
- // since we no longer need it.
- ::CloseHandle(textureSharedHandle);
-
- return externalImage;
- } else {
- native::d3d::ExternalImageDescriptorD3D11Texture externalImageDesc;
- externalImageDesc.cTextureDescriptor =
- reinterpret_cast<const WGPUTextureDescriptor*>(dawnDesc);
- externalImageDesc.texture = d3d11Texture;
-
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage =
- native::d3d::ExternalImageDXGI::Create(targetDevice, &externalImageDesc);
-
- return externalImage;
- }
- }
-
- void Wrap(const wgpu::TextureDescriptor* dawnDesc,
- const D3D11_TEXTURE2D_DESC* d3dDesc,
- wgpu::Texture* dawnTexture,
- ID3D11Texture2D** d3d11TextureOut,
- std::unique_ptr<native::d3d::ExternalImageDXGI>* externalImageOut) const {
- if (IsSharedHandle()) {
- WrapSharedHandle(dawnDesc, d3dDesc, dawnTexture, d3d11TextureOut, externalImageOut);
- } else {
- WrapD3D11Texture(dawnDesc, d3dDesc, dawnTexture, d3d11TextureOut, externalImageOut);
- }
- }
-
- void WrapSharedHandle(const wgpu::TextureDescriptor* dawnDesc,
- const D3D11_TEXTURE2D_DESC* d3dDesc,
- wgpu::Texture* dawnTexture,
- ID3D11Texture2D** d3d11TextureOut,
- std::unique_ptr<native::d3d::ExternalImageDXGI>* externalImageOut) const {
- ComPtr<ID3D11Texture2D> d3d11Texture;
- HRESULT hr = mD3d11Device->CreateTexture2D(d3dDesc, nullptr, &d3d11Texture);
- ASSERT_EQ(hr, S_OK);
-
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage = CreateExternalImage(
- device.Get(), d3d11Texture.Get(), dawnDesc, /*usingSharedHandle=*/true);
-
- // Cannot access a non-existent external image (ex. validation error).
- if (externalImage == nullptr) {
- return;
- }
-
- native::d3d::ExternalImageDXGIBeginAccessDescriptor externalAccessDesc;
- externalAccessDesc.usage = static_cast<WGPUTextureUsageFlags>(dawnDesc->usage);
-
- *dawnTexture = wgpu::Texture::Acquire(externalImage->BeginAccess(&externalAccessDesc));
- *d3d11TextureOut = d3d11Texture.Detach();
-
- if (externalImageOut != nullptr) {
- *externalImageOut = std::move(externalImage);
- }
- }
-
- void WrapD3D11Texture(const wgpu::TextureDescriptor* dawnDesc,
- const D3D11_TEXTURE2D_DESC* d3dDesc,
- wgpu::Texture* dawnTexture,
- ID3D11Texture2D** d3d11TextureOut,
- std::unique_ptr<native::d3d::ExternalImageDXGI>* externalImageOut) const {
- // Use the D3D11Device from WGPUDevice to create a D3D11Texture2D. So the D3D11Texture2D can
- // be wrapped.
- ComPtr<ID3D11Device> d3d11Device = native::d3d11::GetD3D11Device(device.Get());
-
- ComPtr<ID3D11Texture2D> d3d11Texture;
- HRESULT hr = d3d11Device->CreateTexture2D(d3dDesc, nullptr, &d3d11Texture);
- ASSERT_EQ(hr, S_OK);
-
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage = CreateExternalImage(
- device.Get(), d3d11Texture.Get(), dawnDesc, /*usingSharedHandle=*/false);
-
- // Cannot access a non-existent external image (ex. validation error).
- if (externalImage == nullptr) {
- return;
- }
-
- native::d3d::ExternalImageDXGIBeginAccessDescriptor externalAccessDesc;
- externalAccessDesc.usage = static_cast<WGPUTextureUsageFlags>(dawnDesc->usage);
-
- *dawnTexture = wgpu::Texture::Acquire(externalImage->BeginAccess(&externalAccessDesc));
- *d3d11TextureOut = d3d11Texture.Detach();
-
- if (externalImageOut != nullptr) {
- *externalImageOut = std::move(externalImage);
- }
- }
-
- static constexpr size_t kTestWidth = 10;
- static constexpr size_t kTestHeight = 10;
-
- ComPtr<ID3D11Device> mD3d11Device;
- ComPtr<ID3D11DeviceContext> mD3d11DeviceContext;
-
- D3D11_TEXTURE2D_DESC baseD3dDescriptor;
- wgpu::TextureDescriptor baseDawnDescriptor;
-};
-
-// A small fixture used to initialize default data for the D3DResource validation tests.
-// These tests are skipped if the harness is using the wire.
-class D3DExternalImageValidation : public D3DResourceTestBase {};
-
-// Test a successful wrapping of an D3DResource in a texture
-TEST_P(D3DExternalImageValidation, Success) {
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage);
-
- ASSERT_NE(texture.Get(), nullptr);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
-}
-
-// Test a successful wrapping of an D3DResource with DawnTextureInternalUsageDescriptor
-TEST_P(D3DExternalImageValidation, SuccessWithInternalUsageDescriptor) {
- wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
- baseDawnDescriptor.nextInChain = &internalDesc;
- internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
- internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor;
-
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage);
-
- ASSERT_NE(texture.Get(), nullptr);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
-}
-
-// Test an error occurs if an invalid sType is the nextInChain
-TEST_P(D3DExternalImageValidation, InvalidTextureDescriptor) {
- wgpu::ChainedStruct chainedDescriptor;
- chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel;
- baseDawnDescriptor.nextInChain = &chainedDescriptor;
-
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- ASSERT_DEVICE_ERROR(
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage));
-
- ASSERT_EQ(texture.Get(), nullptr);
-}
-
-// Test an error occurs if the descriptor mip level count isn't 1
-TEST_P(D3DExternalImageValidation, InvalidMipLevelCount) {
- baseDawnDescriptor.mipLevelCount = 2;
-
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- ASSERT_DEVICE_ERROR(
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage));
-
- ASSERT_EQ(texture.Get(), nullptr);
-}
-
-// Test an error occurs if the descriptor depth isn't 1
-TEST_P(D3DExternalImageValidation, InvalidDepth) {
- baseDawnDescriptor.size.depthOrArrayLayers = 2;
-
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- ASSERT_DEVICE_ERROR(
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage));
-
- ASSERT_EQ(texture.Get(), nullptr);
-}
-
-// Test an error occurs if the descriptor sample count isn't 1
-TEST_P(D3DExternalImageValidation, InvalidSampleCount) {
- baseDawnDescriptor.sampleCount = 4;
-
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- ASSERT_DEVICE_ERROR(
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage));
-
- ASSERT_EQ(texture.Get(), nullptr);
-}
-
-// Test an error occurs if the descriptor width doesn't match the texture's
-TEST_P(D3DExternalImageValidation, InvalidWidth) {
- baseDawnDescriptor.size.width = kTestWidth + 1;
-
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- ASSERT_DEVICE_ERROR(
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage));
-
- ASSERT_EQ(texture.Get(), nullptr);
-}
-
-// Test an error occurs if the descriptor height doesn't match the texture's
-TEST_P(D3DExternalImageValidation, InvalidHeight) {
- baseDawnDescriptor.size.height = kTestHeight + 1;
-
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- ASSERT_DEVICE_ERROR(
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage));
-
- ASSERT_EQ(texture.Get(), nullptr);
-}
-
-// Test an error occurs if the descriptor format isn't compatible with the D3D Resource
-TEST_P(D3DExternalImageValidation, InvalidFormat) {
- baseDawnDescriptor.format = wgpu::TextureFormat::R8Unorm;
-
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- ASSERT_DEVICE_ERROR(
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage));
-
- ASSERT_EQ(texture.Get(), nullptr);
-}
-
-// Test an error occurs if the number of D3D mip levels is greater than 1.
-TEST_P(D3DExternalImageValidation, InvalidNumD3DMipLevels) {
- baseD3dDescriptor.MipLevels = 2;
-
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- ASSERT_DEVICE_ERROR(
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage));
-
- ASSERT_EQ(texture.Get(), nullptr);
-}
-
-// Test an error occurs if the number of array levels is greater than 1.
-TEST_P(D3DExternalImageValidation, InvalidD3DArraySize) {
- baseD3dDescriptor.ArraySize = 2;
-
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- ASSERT_DEVICE_ERROR(
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage));
-
- ASSERT_EQ(texture.Get(), nullptr);
-}
-
-class D3DExternalImageUsageTests : public D3DResourceTestBase {
- protected:
- // Submits a 1x1x1 copy from source to destination
- void SimpleCopyTextureToTexture(wgpu::Texture source, wgpu::Texture destination) {
- wgpu::ImageCopyTexture copySrc = utils::CreateImageCopyTexture(source, 0, {0, 0, 0});
- wgpu::ImageCopyTexture copyDst = utils::CreateImageCopyTexture(destination, 0, {0, 0, 0});
-
- wgpu::Extent3D copySize = {1, 1, 1};
-
- wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
- encoder.CopyTextureToTexture(©Src, ©Dst, ©Size);
- wgpu::CommandBuffer commands = encoder.Finish();
-
- queue.Submit(1, &commands);
- }
-
- // Clear a texture on a given device
- void ClearImage(wgpu::Texture wrappedTexture,
- const wgpu::Color& clearColor,
- wgpu::Device wgpuDevice) {
- wgpu::TextureView wrappedView = wrappedTexture.CreateView();
-
- // Submit a clear operation
- utils::ComboRenderPassDescriptor renderPassDescriptor({wrappedView}, {});
- renderPassDescriptor.cColorAttachments[0].clearValue = clearColor;
-
- wgpu::CommandEncoder encoder = wgpuDevice.CreateCommandEncoder();
- wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDescriptor);
- pass.End();
-
- wgpu::CommandBuffer commands = encoder.Finish();
- wgpu::Queue queue = wgpuDevice.GetQueue();
- queue.Submit(1, &commands);
- }
-
- void CreateSharedD3D11Texture(const D3D11_TEXTURE2D_DESC& d3dDescriptor,
- ID3D11Texture2D** d3d11TextureOut,
- ID3D11Fence** d3d11FenceOut,
- HANDLE* sharedHandleOut,
- HANDLE* fenceSharedHandleOut) const {
- ComPtr<ID3D11Texture2D> d3d11Texture;
- HRESULT hr = mD3d11Device->CreateTexture2D(&d3dDescriptor, nullptr, &d3d11Texture);
- ASSERT_EQ(hr, S_OK);
-
- ComPtr<IDXGIResource1> dxgiResource;
- hr = d3d11Texture.As(&dxgiResource);
- ASSERT_EQ(hr, S_OK);
-
- HANDLE sharedHandle;
- hr = dxgiResource->CreateSharedHandle(
- nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, nullptr,
- &sharedHandle);
- ASSERT_EQ(hr, S_OK);
-
- HANDLE fenceSharedHandle = nullptr;
- ComPtr<ID3D11Fence> d3d11Fence;
-
- ComPtr<ID3D11Device5> d3d11Device5;
- hr = mD3d11Device.As(&d3d11Device5);
- ASSERT_EQ(hr, S_OK);
-
- hr = d3d11Device5->CreateFence(0, D3D11_FENCE_FLAG_SHARED, IID_PPV_ARGS(&d3d11Fence));
- ASSERT_EQ(hr, S_OK);
-
- hr = d3d11Fence->CreateSharedHandle(nullptr, GENERIC_ALL, nullptr, &fenceSharedHandle);
- ASSERT_EQ(hr, S_OK);
-
- *d3d11TextureOut = d3d11Texture.Detach();
- *d3d11FenceOut = d3d11Fence.Detach();
- *sharedHandleOut = sharedHandle;
- *fenceSharedHandleOut = fenceSharedHandle;
- }
-
- void ClearD3D11Texture(const wgpu::Color& clearColor,
- ID3D11Texture2D* d3d11TexturePtr,
- ID3D11Fence* d3d11Fence,
- uint64_t fenceSignalValue) const {
- ComPtr<ID3D11Texture2D> d3d11Texture = d3d11TexturePtr;
-
- ComPtr<IDXGIResource1> dxgiResource;
- HRESULT hr = d3d11Texture.As(&dxgiResource);
- ASSERT_EQ(hr, S_OK);
-
- ComPtr<ID3D11RenderTargetView> d3d11RTV;
- hr = mD3d11Device->CreateRenderTargetView(d3d11Texture.Get(), nullptr, &d3d11RTV);
- ASSERT_EQ(hr, S_OK);
-
- const float colorRGBA[] = {
- static_cast<float>(clearColor.r), static_cast<float>(clearColor.g),
- static_cast<float>(clearColor.b), static_cast<float>(clearColor.a)};
- mD3d11DeviceContext->ClearRenderTargetView(d3d11RTV.Get(), colorRGBA);
-
- ComPtr<ID3D11DeviceContext4> d3d11DeviceContext4;
- hr = mD3d11DeviceContext.As(&d3d11DeviceContext4);
- ASSERT_EQ(hr, S_OK);
- // The fence starts with 0 signaled, but that won't capture the render target view clear
- // above, so signal explicitly with 1 and make the next Dawn access wait on 1.
- d3d11DeviceContext4->Signal(d3d11Fence, fenceSignalValue);
- }
-
- void WaitAndWrapD3D11Texture(const wgpu::TextureDescriptor& dawnDescriptor,
- ID3D11Texture2D* d3d11TexturePtr,
- HANDLE sharedHandle,
- HANDLE fenceSharedHandle,
- uint64_t fenceWaitValue,
- wgpu::Texture* dawnTextureOut,
- std::unique_ptr<native::d3d::ExternalImageDXGI>* externalImageOut,
- bool isInitialized) const {
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- if (IsSharedHandle()) {
- native::d3d::ExternalImageDescriptorDXGISharedHandle externalImageDesc = {};
- externalImageDesc.sharedHandle = sharedHandle;
- externalImageDesc.cTextureDescriptor =
- reinterpret_cast<const WGPUTextureDescriptor*>(&dawnDescriptor);
-
- externalImage =
- native::d3d::ExternalImageDXGI::Create(device.Get(), &externalImageDesc);
- } else {
- native::d3d::ExternalImageDescriptorD3D11Texture externalImageDesc = {};
- externalImageDesc.texture = d3d11TexturePtr;
- externalImageDesc.cTextureDescriptor =
- reinterpret_cast<const WGPUTextureDescriptor*>(&dawnDescriptor);
-
- externalImage =
- native::d3d::ExternalImageDXGI::Create(device.Get(), &externalImageDesc);
- }
-
- native::d3d::ExternalImageDXGIBeginAccessDescriptor externalAccessDesc;
- externalAccessDesc.isInitialized = isInitialized;
- externalAccessDesc.usage = static_cast<WGPUTextureUsageFlags>(dawnDescriptor.usage);
- if (fenceSharedHandle != nullptr) {
- externalAccessDesc.waitFences.push_back({fenceSharedHandle, fenceWaitValue});
- }
-
- *dawnTextureOut = wgpu::Texture::Acquire(externalImage->BeginAccess(&externalAccessDesc));
- *externalImageOut = std::move(externalImage);
- }
-
- void WrapAndClearD3D11Texture(const wgpu::TextureDescriptor& dawnDescriptor,
- const D3D11_TEXTURE2D_DESC& d3dDescriptor,
- const wgpu::Color& clearColor,
- wgpu::Texture* dawnTextureOut,
- ID3D11Texture2D** d3d11TextureOut,
- std::unique_ptr<native::d3d::ExternalImageDXGI>* externalImageOut,
- bool isInitialized = true) const {
- ComPtr<ID3D11Texture2D> d3d11Texture;
- ComPtr<ID3D11Fence> d3d11Fence;
- HANDLE sharedHandle = nullptr;
- HANDLE fenceSharedHandle = nullptr;
- CreateSharedD3D11Texture(d3dDescriptor, &d3d11Texture, &d3d11Fence, &sharedHandle,
- &fenceSharedHandle);
-
- constexpr uint64_t kFenceSignalValue = 1;
- ClearD3D11Texture(clearColor, d3d11Texture.Get(), d3d11Fence.Get(), kFenceSignalValue);
-
- WaitAndWrapD3D11Texture(dawnDescriptor, d3d11Texture.Get(), sharedHandle, fenceSharedHandle,
- /*fenceWaitValue=*/kFenceSignalValue, dawnTextureOut,
- externalImageOut, isInitialized);
-
- *d3d11TextureOut = d3d11Texture.Detach();
-
- if (fenceSharedHandle != nullptr) {
- ::CloseHandle(fenceSharedHandle);
- }
- }
-
- void ExpectPixelRGBA8EQ(ID3D11Texture2D* d3d11Texture,
- const wgpu::Color& color,
- const native::d3d::ExternalImageDXGIFenceDescriptor* waitFence) {
- D3D11_TEXTURE2D_DESC texture2DDesc;
- d3d11Texture->GetDesc(&texture2DDesc);
-
- const CD3D11_TEXTURE2D_DESC texture2DStagingDesc(
- texture2DDesc.Format, // Format
- texture2DDesc.Width, // Width
- texture2DDesc.Height, // Height
- 1, // ArraySize
- 1, // MipLevels
- 0, // BindFlags
- D3D11_USAGE_STAGING, // Usage
- D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE); // CPUAccessFlags
-
- ComPtr<ID3D11Texture2D> spD3DTextureStaging;
- HRESULT hr =
- mD3d11Device->CreateTexture2D(&texture2DStagingDesc, nullptr, &spD3DTextureStaging);
- ASSERT_EQ(hr, S_OK);
-
- D3D11_BOX d3dRc;
- d3dRc.back = 1;
- d3dRc.front = 0;
- d3dRc.top = 0;
- d3dRc.left = 0;
- d3dRc.bottom = texture2DDesc.Height;
- d3dRc.right = texture2DDesc.Width;
-
- if (waitFence->fenceHandle != nullptr) {
- ComPtr<ID3D11Device5> d3d11Device5;
- mD3d11Device.As(&d3d11Device5);
- ASSERT_EQ(hr, S_OK);
-
- ComPtr<ID3D11Fence> d3d11Fence;
- hr = d3d11Device5->OpenSharedFence(waitFence->fenceHandle, IID_PPV_ARGS(&d3d11Fence));
- ASSERT_EQ(hr, S_OK);
-
- ComPtr<ID3D11DeviceContext4> d3d11DeviceContext4;
- hr = mD3d11DeviceContext.As(&d3d11DeviceContext4);
- ASSERT_EQ(hr, S_OK);
-
- hr = d3d11DeviceContext4->Wait(d3d11Fence.Get(), waitFence->fenceValue);
- ASSERT_EQ(hr, S_OK);
- }
-
- mD3d11DeviceContext->CopySubresourceRegion(spD3DTextureStaging.Get(), // pDstResource
- 0, // DstSubresource
- 0, // DstX
- 0, // DstY
- 0, // DstZ
- d3d11Texture, // pSrcResource
- 0, // SrcSubresource
- &d3dRc); // pSrcBox
-
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- hr = mD3d11DeviceContext->Map(spD3DTextureStaging.Get(), 0, D3D11_MAP_READ_WRITE, 0,
- &mappedResource);
- ASSERT_EQ(hr, S_OK);
-
- const uint8_t* colorData = static_cast<uint8_t*>(mappedResource.pData);
- EXPECT_EQ(colorData[0], color.r * 255u);
- EXPECT_EQ(colorData[1], color.g * 255u);
- EXPECT_EQ(colorData[2], color.b * 255u);
- EXPECT_EQ(colorData[3], color.a * 255u);
-
- mD3d11DeviceContext->Unmap(spD3DTextureStaging.Get(), 0);
- }
-};
-
-// 1. Create and clear a D3D11 texture
-// 2. Copy the wrapped texture to another dawn texture
-// 3. Readback the copied texture and ensure the color matches the original clear color.
-TEST_P(D3DExternalImageUsageTests, ClearInD3D11CopyAndReadbackInD3D) {
- const wgpu::Color clearColor{1.0f, 1.0f, 0.0f, 1.0f};
- wgpu::Texture dawnSrcTexture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WrapAndClearD3D11Texture(baseDawnDescriptor, baseD3dDescriptor, clearColor, &dawnSrcTexture,
- &d3d11Texture, &externalImage);
- ASSERT_NE(dawnSrcTexture.Get(), nullptr);
-
- // Create a texture on the device and copy the source texture to it.
- wgpu::Texture dawnCopyDestTexture = device.CreateTexture(&baseDawnDescriptor);
- SimpleCopyTextureToTexture(dawnSrcTexture, dawnCopyDestTexture);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(dawnSrcTexture.Get(), &signalFence);
- dawnSrcTexture.Destroy();
-
- // Readback the destination texture and ensure it contains the colors we used
- // to clear the source texture on the D3D device.
- EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8(clearColor.r * 255u, clearColor.g * 255u,
- clearColor.b * 255u, clearColor.a * 255u),
- dawnCopyDestTexture, 0, 0);
-}
-
-// 1. Create and clear a D3D11 texture
-// 2. Readback the wrapped texture and ensure the color matches the original clear color.
-TEST_P(D3DExternalImageUsageTests, ClearInD3D11ReadbackInD3D) {
- const wgpu::Color clearColor{1.0f, 1.0f, 0.0f, 1.0f};
- wgpu::Texture dawnTexture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WrapAndClearD3D11Texture(baseDawnDescriptor, baseD3dDescriptor, clearColor, &dawnTexture,
- &d3d11Texture, &externalImage);
- ASSERT_NE(dawnTexture.Get(), nullptr);
-
- // Readback the destination texture and ensure it contains the colors we used
- // to clear the source texture on the D3D device.
- EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8(clearColor.r * 255, clearColor.g * 255, clearColor.b * 255,
- clearColor.a * 255),
- dawnTexture, 0, 0);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(dawnTexture.Get(), &signalFence);
- dawnTexture.Destroy();
-}
-
-// 1. Create and clear a D3D11 texture
-// 2. Wrap it in a Dawn texture and clear it to a different color
-// 3. Readback the texture with D3D11 and ensure we receive the color we cleared with Dawn.
-TEST_P(D3DExternalImageUsageTests, ClearInD3DReadbackInD3D11) {
- // TODO(crbug.com/dawn/735): This test appears to hang for
- // D3D12_Microsoft_Basic_Render_Driver_CPU when validation is enabled.
- DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsWARP() && IsBackendValidationEnabled());
-
- const wgpu::Color d3d11ClearColor{1.0f, 1.0f, 0.0f, 1.0f};
- wgpu::Texture dawnTexture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WrapAndClearD3D11Texture(baseDawnDescriptor, baseD3dDescriptor, d3d11ClearColor, &dawnTexture,
- &d3d11Texture, &externalImage, /*isInitialized=*/true);
- ASSERT_NE(dawnTexture.Get(), nullptr);
-
- const wgpu::Color d3dClearColor{0.0f, 0.0f, 1.0f, 1.0f};
- ClearImage(dawnTexture, d3dClearColor, device);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(dawnTexture.Get(), &signalFence);
- dawnTexture.Destroy();
-
- // Now that Dawn (via D3D) has finished writing to the texture, we should be
- // able to read it back by copying it to a staging texture and verifying the
- // color matches the D3D12 clear color.
- ExpectPixelRGBA8EQ(d3d11Texture.Get(), d3dClearColor, &signalFence);
-}
-
-// 1. Create and clear a D3D11 texture
-// 2. Wrap it in a Dawn texture and clear the texture to two different colors.
-// 3. Readback the texture with D3D11.
-// 4. Verify the readback color was the final color cleared.
-TEST_P(D3DExternalImageUsageTests, ClearTwiceInD3DReadbackInD3D11) {
- // TODO(crbug.com/dawn/735): This test appears to hang for
- // D3D12_Microsoft_Basic_Render_Driver_CPU when validation is enabled.
- DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsWARP() && IsBackendValidationEnabled());
-
- const wgpu::Color d3d11ClearColor{1.0f, 1.0f, 0.0f, 1.0f};
- wgpu::Texture dawnTexture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WrapAndClearD3D11Texture(baseDawnDescriptor, baseD3dDescriptor, d3d11ClearColor, &dawnTexture,
- &d3d11Texture, &externalImage, /*isInitialized=*/true);
- ASSERT_NE(dawnTexture.Get(), nullptr);
-
- const wgpu::Color d3dClearColor1{0.0f, 0.0f, 1.0f, 1.0f};
- ClearImage(dawnTexture, d3dClearColor1, device);
-
- const wgpu::Color d3dClearColor2{0.0f, 1.0f, 1.0f, 1.0f};
- ClearImage(dawnTexture, d3dClearColor2, device);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(dawnTexture.Get(), &signalFence);
- dawnTexture.Destroy();
-
- // Now that Dawn (via D3D) has finished writing to the texture, we should be
- // able to read it back by copying it to a staging texture and verifying the
- // color matches the last D3D12 clear color.
- ExpectPixelRGBA8EQ(d3d11Texture.Get(), d3dClearColor2, &signalFence);
-}
-
-// 1. Create and clear a D3D11 texture with clearColor
-// 2. Import the texture with isInitialized = false
-// 3. Verify clearColor is not visible in wrapped texture
-TEST_P(D3DExternalImageUsageTests, UninitializedTextureIsCleared) {
- const wgpu::Color clearColor{1.0f, 0.0f, 0.0f, 1.0f};
- wgpu::Texture dawnTexture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WrapAndClearD3D11Texture(baseDawnDescriptor, baseD3dDescriptor, clearColor, &dawnTexture,
- &d3d11Texture, &externalImage, /*isInitialized=*/false);
- ASSERT_NE(dawnTexture.Get(), nullptr);
-
- // Readback the destination texture and ensure it contains the colors we used
- // to clear the source texture on the D3D device.
- EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8(0, 0, 0, 0), dawnTexture, 0, 0);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(dawnTexture.Get(), &signalFence);
- dawnTexture.Destroy();
-}
-
-// 1. Create an external image from the DX11 texture.
-// 2. Produce two Dawn textures from the external image.
-// 3. Clear each Dawn texture and verify the texture was cleared to a unique color.
-TEST_P(D3DExternalImageUsageTests, ReuseExternalImage) {
- // Create the first Dawn texture then clear it to red.
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WrapSharedHandle(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture,
- &externalImage);
- {
- const wgpu::Color solidRed{1.0f, 0.0f, 0.0f, 1.0f};
- ASSERT_NE(texture.Get(), nullptr);
- ClearImage(texture.Get(), solidRed, device);
-
- EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8(0xFF, 0, 0, 0xFF), texture.Get(), 0, 0);
- }
-
- // Once finished with the first texture, destroy it so we may re-acquire the external image
- // again.
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
-
- // Create another Dawn texture then clear it with another color.
- native::d3d::ExternalImageDXGIBeginAccessDescriptor externalAccessDesc;
- externalAccessDesc.isInitialized = true;
- externalAccessDesc.usage = static_cast<WGPUTextureUsageFlags>(baseDawnDescriptor.usage);
- externalAccessDesc.waitFences.push_back(signalFence);
-
- texture = wgpu::Texture::Acquire(externalImage->BeginAccess(&externalAccessDesc));
-
- // Check again that the new texture is still red
- EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8(0xFF, 0, 0, 0xFF), texture.Get(), 0, 0);
-
- // Clear the new texture to blue
- {
- const wgpu::Color solidBlue{0.0f, 0.0f, 1.0f, 1.0f};
- ASSERT_NE(texture.Get(), nullptr);
- ClearImage(texture.Get(), solidBlue, device);
-
- EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8(0, 0, 0xFF, 0xFF), texture.Get(), 0, 0);
- }
-
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
-}
-
-TEST_P(D3DExternalImageUsageTests, ConcurrentExternalImageReadAccess) {
- wgpu::Device device2 = CreateDevice();
- EXPECT_NE(device2, nullptr);
-
- wgpu::Device device3 = CreateDevice();
- EXPECT_NE(device3, nullptr);
-
- wgpu::Device device4 = CreateDevice();
- EXPECT_NE(device4, nullptr);
-
- wgpu::Device device5 = CreateDevice();
- EXPECT_NE(device5, nullptr);
-
- // Create Dawn texture with write access, then clear it to red.
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WrapSharedHandle(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture,
- &externalImage);
-
- // Clear to red.
- {
- const wgpu::Color solidRed{1.0f, 0.0f, 0.0f, 1.0f};
- ASSERT_NE(texture.Get(), nullptr);
- ClearImage(texture.Get(), solidRed, device);
- }
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
-
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage2 = CreateExternalImage(
- device2.Get(), d3d11Texture.Get(), &baseDawnDescriptor, /*usingSharedHandle=*/true);
- EXPECT_NE(externalImage2, nullptr);
-
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage3 = CreateExternalImage(
- device3.Get(), d3d11Texture.Get(), &baseDawnDescriptor, /*usingSharedHandle=*/true);
- EXPECT_NE(externalImage3, nullptr);
-
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage4 = CreateExternalImage(
- device4.Get(), d3d11Texture.Get(), &baseDawnDescriptor, /*usingSharedHandle=*/true);
- EXPECT_NE(externalImage4, nullptr);
-
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage5 = CreateExternalImage(
- device5.Get(), d3d11Texture.Get(), &baseDawnDescriptor, /*usingSharedHandle=*/true);
- EXPECT_NE(externalImage5, nullptr);
-
- // Create two Dawn textures for concurrent read on second device.
- native::d3d::ExternalImageDXGIBeginAccessDescriptor externalAccessDesc;
- externalAccessDesc.isInitialized = true;
- externalAccessDesc.usage = WGPUTextureUsage_CopySrc;
- externalAccessDesc.waitFences = {signalFence};
-
- // Concurrent read access on device 2 and 3.
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence2;
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence3;
- {
- wgpu::Texture texture2 =
- wgpu::Texture::Acquire(externalImage2->BeginAccess(&externalAccessDesc));
- EXPECT_NE(texture2, nullptr);
-
- wgpu::Texture texture3 =
- wgpu::Texture::Acquire(externalImage3->BeginAccess(&externalAccessDesc));
- EXPECT_NE(texture3, nullptr);
-
- // Check again that the new textures are also red.
- const utils::RGBA8 solidRed(0xFF, 0, 0, 0xFF);
- EXPECT_TEXTURE_EQ(device2, solidRed, texture2.Get(), {0, 0});
- EXPECT_TEXTURE_EQ(device3, solidRed, texture3.Get(), {0, 0});
-
- externalImage2->EndAccess(texture2.Get(), &signalFence2);
- texture2.Destroy();
-
- externalImage3->EndAccess(texture3.Get(), &signalFence3);
- texture3.Destroy();
- }
-
- externalAccessDesc.usage = static_cast<WGPUTextureUsageFlags>(baseDawnDescriptor.usage);
- externalAccessDesc.waitFences = {signalFence2, signalFence3};
-
- // Exclusive read-write access on device 4.
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence4;
- {
- wgpu::Texture texture4 =
- wgpu::Texture::Acquire(externalImage4->BeginAccess(&externalAccessDesc));
- EXPECT_NE(texture4, nullptr);
-
- const utils::RGBA8 solidRed(0xFF, 0, 0, 0xFF);
- EXPECT_TEXTURE_EQ(device4, solidRed, texture4.Get(), {0, 0});
-
- // Clear to blue.
- const wgpu::Color solidBlue{0.0f, 0.0f, 1.0f, 1.0f};
- ASSERT_NE(texture4.Get(), nullptr);
- ClearImage(texture4.Get(), solidBlue, device4);
-
- externalImage4->EndAccess(texture4.Get(), &signalFence4);
- texture4.Destroy();
- }
-
- externalAccessDesc.waitFences = {signalFence4};
-
- // Import texture on device 5, but do nothing with it.
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence5;
- {
- wgpu::Texture texture5 =
- wgpu::Texture::Acquire(externalImage5->BeginAccess(&externalAccessDesc));
- EXPECT_NE(texture5, nullptr);
- externalImage5->EndAccess(texture5.Get(), &signalFence5);
- texture5.Destroy();
- }
-
- externalAccessDesc.usage = WGPUTextureUsage_CopySrc;
- externalAccessDesc.waitFences = {signalFence5};
-
- // Concurrent read access on device 1 (twice), 2 and 3.
- {
- texture = wgpu::Texture::Acquire(externalImage->BeginAccess(&externalAccessDesc));
- EXPECT_NE(texture, nullptr);
-
- wgpu::Texture texture1 =
- wgpu::Texture::Acquire(externalImage->BeginAccess(&externalAccessDesc));
- EXPECT_NE(texture1, nullptr);
-
- wgpu::Texture texture2 =
- wgpu::Texture::Acquire(externalImage2->BeginAccess(&externalAccessDesc));
- EXPECT_NE(texture2, nullptr);
-
- wgpu::Texture texture3 =
- wgpu::Texture::Acquire(externalImage3->BeginAccess(&externalAccessDesc));
- EXPECT_NE(texture3, nullptr);
-
- // Check again that the new textures are now blue.
- const utils::RGBA8 solidBlue(0, 0, 0xFF, 0xFF);
- EXPECT_TEXTURE_EQ(device, solidBlue, texture.Get(), {0, 0});
- EXPECT_TEXTURE_EQ(device, solidBlue, texture1.Get(), {0, 0});
- EXPECT_TEXTURE_EQ(device2, solidBlue, texture2.Get(), {0, 0});
- EXPECT_TEXTURE_EQ(device3, solidBlue, texture3.Get(), {0, 0});
-
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
-
- externalImage->EndAccess(texture1.Get(), &signalFence);
- texture1.Destroy();
-
- externalImage2->EndAccess(texture2.Get(), &signalFence2);
- texture2.Destroy();
-
- externalImage3->EndAccess(texture3.Get(), &signalFence3);
- texture3.Destroy();
- }
-}
-
-// Produce a new texture with a usage not specified in the external image.
-TEST_P(D3DExternalImageUsageTests, ExternalImageUsage) {
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WrapSharedHandle(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture,
- &externalImage);
- ASSERT_NE(texture.Get(), nullptr);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
-
- native::d3d::ExternalImageDXGIBeginAccessDescriptor externalAccessDesc;
- externalAccessDesc.isInitialized = true;
- externalAccessDesc.usage = WGPUTextureUsage_StorageBinding;
- externalAccessDesc.waitFences.push_back(signalFence);
- texture = wgpu::Texture::Acquire(externalImage->BeginAccess(&externalAccessDesc));
- ASSERT_EQ(texture.Get(), nullptr);
-
- externalAccessDesc.usage = WGPUTextureUsage_TextureBinding;
- texture = wgpu::Texture::Acquire(externalImage->BeginAccess(&externalAccessDesc));
- ASSERT_NE(texture.Get(), nullptr);
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
-}
-
-// Verify external image cannot be used after its creating device is destroyed.
-TEST_P(D3DExternalImageUsageTests, InvalidateExternalImageOnDestroyDevice) {
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
-
- // Create the Dawn texture then clear it to red.
- WrapSharedHandle(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture,
- &externalImage);
- const wgpu::Color solidRed{1.0f, 0.0f, 0.0f, 1.0f};
- ASSERT_NE(texture.Get(), nullptr);
- ClearImage(texture.Get(), solidRed, device);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
-
- // Do not readback pixels since that requires device to be alive during DawnTest::TearDown().
- DestroyDevice();
-
- native::d3d::ExternalImageDXGIBeginAccessDescriptor externalAccessDesc;
- externalAccessDesc.isInitialized = true;
- externalAccessDesc.usage = static_cast<WGPUTextureUsageFlags>(baseDawnDescriptor.usage);
-
- EXPECT_EQ(wgpu::Texture::Acquire(externalImage->BeginAccess(&externalAccessDesc)), nullptr);
-}
-
-// Verify external image cannot be created after the target device is destroyed.
-TEST_P(D3DExternalImageUsageTests, DisallowExternalImageAfterDestroyDevice) {
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
-
- DestroyDevice();
-
- WrapSharedHandle(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture,
- &externalImage);
-
- EXPECT_EQ(externalImage, nullptr);
- EXPECT_EQ(texture, nullptr);
-}
-
-// Verify there is no error generated when we destroy an external image with CommandRecordingContext
-// open.
-TEST_P(D3DExternalImageUsageTests, CallWriteBufferBeforeDestroyingExternalImage) {
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WrapSharedHandle(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture,
- &externalImage);
-
- // In utils::CreateBufferFromData() we will call queue.WriteBuffer(), which will make a
- // recording context pending.
- constexpr uint32_t kExpected = 1u;
- wgpu::Buffer buffer = utils::CreateBufferFromData(
- device, wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst, {kExpected});
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
- externalImage = nullptr;
-
- EXPECT_BUFFER_U32_EQ(kExpected, buffer, 0);
-}
-
-// Test that texture descriptor view formats are passed to the backend for wrapped external
-// textures, and that contents may be reinterpreted as sRGB.
-TEST_P(D3DExternalImageUsageTests, SRGBReinterpretation) {
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
-
- // The texture will be reinterpreted as sRGB.
- wgpu::TextureViewDescriptor viewDesc = {};
- viewDesc.format = wgpu::TextureFormat::RGBA8UnormSrgb;
-
- wgpu::TextureDescriptor textureDesc = baseDawnDescriptor;
- textureDesc.viewFormatCount = 1;
- textureDesc.viewFormats = &viewDesc.format;
- // Check that the base format is not sRGB.
- ASSERT_EQ(textureDesc.format, wgpu::TextureFormat::RGBA8Unorm);
-
- // Wrap a shared handle as a Dawn texture.
- WrapSharedHandle(&textureDesc, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage);
- ASSERT_NE(texture.Get(), nullptr);
-
- // Submit a clear operation to sRGB value rgb(234, 51, 35).
- {
- utils::ComboRenderPassDescriptor renderPassDescriptor({texture.CreateView(&viewDesc)}, {});
- renderPassDescriptor.cColorAttachments[0].clearValue = {234.0 / 255.0, 51.0 / 255.0,
- 35.0 / 255.0, 1.0};
- wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
- encoder.BeginRenderPass(&renderPassDescriptor).End();
-
- wgpu::CommandBuffer commands = encoder.Finish();
- queue.Submit(1, &commands);
- }
-
- // Expect the contents to be approximately rgb(246 124 104)
- EXPECT_PIXEL_RGBA8_BETWEEN( //
- utils::RGBA8(245, 123, 103, 255), //
- utils::RGBA8(247, 125, 105, 255), texture, 0, 0);
-}
-
-class D3DExternalImageMultithreadTests : public D3DExternalImageUsageTests {
- protected:
- std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
- std::vector<wgpu::FeatureName> features;
- // TODO(crbug.com/dawn/1678): DawnWire doesn't support thread safe API yet.
- if (!UsesWire()) {
- features.push_back(wgpu::FeatureName::ImplicitDeviceSynchronization);
- }
- return features;
- }
-
- void SetUp() override {
- D3DExternalImageUsageTests::SetUp();
- // TODO(crbug.com/dawn/1678): DawnWire doesn't support thread safe API yet.
- DAWN_TEST_UNSUPPORTED_IF(UsesWire());
-
- if (IsD3D11() && IsD3D11Texture()) {
- // For this configuration, the d3d1Device will be used from more than one thread.
- auto d3d11Device = dawn::native::d3d11::GetD3D11Device(device.Get());
- ComPtr<ID3D11Multithread> multithread;
- d3d11Device.As(&multithread);
- multithread->SetMultithreadProtected(TRUE);
- }
- }
-};
-
-// Test the destroy device before destroying the external image won't cause deadlock.
-TEST_P(D3DExternalImageMultithreadTests, DestroyDeviceBeforeImageNoDeadLock) {
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage);
-
- ASSERT_NE(texture.Get(), nullptr);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(texture.Get(), &signalFence);
- EXPECT_TRUE(externalImage->IsValid());
-
- // Destroy device, it should destroy image internally.
- device.Destroy();
- EXPECT_FALSE(externalImage->IsValid());
-}
-
-// Test that using the external image and destroying the device simultaneously on different threads
-// won't race.
-TEST_P(D3DExternalImageMultithreadTests, DestroyDeviceAndUseImageInParallel) {
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- Wrap(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage);
-
- ASSERT_NE(texture.Get(), nullptr);
- EXPECT_TRUE(externalImage->IsValid());
-
- std::thread thread1([&] {
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(texture.Get(), &signalFence);
- });
-
- std::thread thread2([&] {
- // Destroy device, it should destroy image internally.
- device.Destroy();
- EXPECT_FALSE(externalImage->IsValid());
- });
-
- thread1.join();
- thread2.join();
-}
-
-// 1. Create and clear a D3D11 texture
-// 2. On 2nd thread: Wrap it in a Dawn texture and clear it to a different color
-// 3. Readback the texture with D3D11 and ensure we receive the color we cleared with Dawn.
-TEST_P(D3DExternalImageMultithreadTests, ClearInD3D12ReadbackInD3D11_TwoThreads) {
- // TODO(crbug.com/dawn/735): This test appears to hang for
- // D3D12_Microsoft_Basic_Render_Driver_CPU when validation is enabled.
- DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsWARP() && IsBackendValidationEnabled());
-
- const wgpu::Color d3d11ClearColor{1.0f, 1.0f, 0.0f, 1.0f};
- const wgpu::Color d3dClearColor{0.0f, 0.0f, 1.0f, 1.0f};
-
- constexpr uint64_t kD3D11FenceSignalValue = 1;
-
- ComPtr<ID3D11Texture2D> d3d11Texture;
- ComPtr<ID3D11Fence> d3d11Fence;
- HANDLE sharedHandle = nullptr;
- HANDLE fenceSharedHandle = nullptr;
- CreateSharedD3D11Texture(baseD3dDescriptor, &d3d11Texture, &d3d11Fence, &sharedHandle,
- &fenceSharedHandle);
-
- native::d3d::ExternalImageDXGIFenceDescriptor d3dSignalFence;
-
- std::thread d3dThread([=, &d3dSignalFence] {
- wgpu::Texture dawnTexture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WaitAndWrapD3D11Texture(baseDawnDescriptor, d3d11Texture.Get(), sharedHandle,
- fenceSharedHandle,
- /*fenceWaitValue=*/kD3D11FenceSignalValue, &dawnTexture,
- &externalImage, /*isInitialized=*/true);
-
- ASSERT_NE(dawnTexture.Get(), nullptr);
-
- EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8(d3d11ClearColor.r * 255, d3d11ClearColor.g * 255,
- d3d11ClearColor.b * 255, d3d11ClearColor.a * 255),
- dawnTexture, 0, 0);
-
- ClearImage(dawnTexture, d3dClearColor, device);
-
- externalImage->EndAccess(dawnTexture.Get(), &d3dSignalFence);
-
- dawnTexture.Destroy();
- });
-
- ClearD3D11Texture(d3d11ClearColor, d3d11Texture.Get(), d3d11Fence.Get(),
- /*fenceSignalValue=*/kD3D11FenceSignalValue);
-
- d3dThread.join();
- // Now that Dawn (via D3D12) has finished writing to the texture, we should be
- // able to read it back by copying it to a staging texture and verifying the
- // color matches the D3D12 clear color.
- ExpectPixelRGBA8EQ(d3d11Texture.Get(), d3dClearColor, &d3dSignalFence);
-
- if (sharedHandle != nullptr) {
- ::CloseHandle(sharedHandle);
- }
-
- if (fenceSharedHandle != nullptr) {
- ::CloseHandle(fenceSharedHandle);
- }
-}
-
-class D3DExternalImageD3D11TextureValidation : public D3DResourceTestBase {};
-
-// Test a successful wrapping of an D3D11Texture2D in a texture
-TEST_P(D3DExternalImageD3D11TextureValidation, Success) {
- wgpu::Texture texture;
- ComPtr<ID3D11Texture2D> d3d11Texture;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage;
- WrapD3D11Texture(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture,
- &externalImage);
-
- ASSERT_NE(texture.Get(), nullptr);
-
- native::d3d::ExternalImageDXGIFenceDescriptor signalFence;
- externalImage->EndAccess(texture.Get(), &signalFence);
- texture.Destroy();
-}
-
-TEST_P(D3DExternalImageD3D11TextureValidation, InvalidD3D11Texture) {
- ComPtr<ID3D11Device> d3d11Device = CreateD3D11Device();
- ComPtr<ID3D11Texture2D> d3d11Texture;
- HRESULT hr = d3d11Device->CreateTexture2D(&baseD3dDescriptor, nullptr, &d3d11Texture);
- ASSERT_EQ(hr, S_OK);
-
- // Import texture created from other device will fail.
- ASSERT_DEVICE_ERROR({
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage = CreateExternalImage(
- device.Get(), d3d11Texture.Get(), &baseDawnDescriptor, /*usingSharedHandle=*/false);
-
- ASSERT_EQ(externalImage.get(), nullptr);
- });
-}
-
-DAWN_INSTANTIATE_TEST_P(D3DExternalImageValidation,
- {D3D11Backend(), D3D12Backend()},
- {ExternalImageType::kSharedHandle, ExternalImageType::kD3D11Texture});
-DAWN_INSTANTIATE_TEST_P(D3DExternalImageUsageTests,
- {D3D11Backend(), D3D12Backend()},
- {ExternalImageType::kSharedHandle, ExternalImageType::kD3D11Texture});
-DAWN_INSTANTIATE_TEST_P(D3DExternalImageMultithreadTests,
- {D3D11Backend(), D3D12Backend()},
- {ExternalImageType::kSharedHandle, ExternalImageType::kD3D11Texture});
-DAWN_INSTANTIATE_TEST_P(D3DExternalImageD3D11TextureValidation,
- {D3D11Backend()},
- {ExternalImageType::kD3D11Texture});
-
-} // anonymous namespace
-} // namespace dawn
diff --git a/src/dawn/tests/end2end/VideoViewsTests.cpp b/src/dawn/tests/end2end/VideoViewsTests.cpp
index 71bad9e..20f6af9 100644
--- a/src/dawn/tests/end2end/VideoViewsTests.cpp
+++ b/src/dawn/tests/end2end/VideoViewsTests.cpp
@@ -75,6 +75,17 @@
requiredFeatures.push_back(wgpu::FeatureName::SharedFenceMTLSharedEvent);
}
+ // Required for the Win tests.
+ if (SupportsFeatures({wgpu::FeatureName::SharedTextureMemoryD3D11Texture2D})) {
+ requiredFeatures.push_back(wgpu::FeatureName::SharedTextureMemoryD3D11Texture2D);
+ }
+ if (SupportsFeatures({wgpu::FeatureName::SharedTextureMemoryDXGISharedHandle})) {
+ requiredFeatures.push_back(wgpu::FeatureName::SharedTextureMemoryDXGISharedHandle);
+ }
+ if (SupportsFeatures({wgpu::FeatureName::SharedFenceDXGISharedHandle})) {
+ requiredFeatures.push_back(wgpu::FeatureName::SharedFenceDXGISharedHandle);
+ }
+
mIsMultiPlanarFormatP010Supported =
SupportsFeatures({wgpu::FeatureName::MultiPlanarFormatP010});
if (mIsMultiPlanarFormatP010Supported) {
@@ -513,7 +524,7 @@
DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported());
mBackend = VideoViewsTestBackend::Create();
- mBackend->OnSetUp(device.Get());
+ mBackend->OnSetUp(device);
}
void TearDown() override {
@@ -1465,12 +1476,19 @@
// Tests creating a texture with a multi-plane format.
TEST_P(VideoViewsValidationTests, RenderAttachmentInvalid) {
+ // "Invalid Texture" error is expected if failed to create the video texture.
+ EXPECT_CALL(mDeviceErrorCallback, Call(testing::Ne(WGPUErrorType_NoError),
+ testing::HasSubstr("Invalid Texture"), device.Get()))
+ .Times(testing::AnyNumber());
+
// multi-planar formats are NOT allowed to be renderable by default and require
// Feature::MultiPlanarRenderTargets.
- ASSERT_DEVICE_ERROR(auto platformTexture = mBackend->CreateVideoTextureForTest(
- GetFormat(), wgpu::TextureUsage::RenderAttachment,
- /*isCheckerboard*/ true,
- /*initialized*/ true));
+ // "RenderAttachment is incompatible with the non-renderable format" error is expected.
+ ASSERT_DEVICE_ERROR_MSG(auto platformTexture = mBackend->CreateVideoTextureForTest(
+ GetFormat(), wgpu::TextureUsage::RenderAttachment,
+ /*isCheckerboard*/ true,
+ /*initialized*/ true),
+ testing::HasSubstr("is incompatible"));
mBackend->DestroyVideoTextureForTest(std::move(platformTexture));
}
diff --git a/src/dawn/tests/end2end/VideoViewsTests.h b/src/dawn/tests/end2end/VideoViewsTests.h
index 7afa002..f498443 100644
--- a/src/dawn/tests/end2end/VideoViewsTests.h
+++ b/src/dawn/tests/end2end/VideoViewsTests.h
@@ -47,7 +47,7 @@
virtual ~VideoViewsTestBackend();
- virtual void OnSetUp(WGPUDevice device) = 0;
+ virtual void OnSetUp(const wgpu::Device& device) = 0;
virtual void OnTearDown() {}
class PlatformTexture {
diff --git a/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp b/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp
index 7538390..a290726 100644
--- a/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp
+++ b/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp
@@ -79,8 +79,8 @@
class VideoViewsTestBackendGbm : public VideoViewsTestBackend {
public:
- void OnSetUp(WGPUDevice device) override {
- mWGPUDevice = device;
+ void OnSetUp(const wgpu::Device& device) override {
+ mWGPUDevice = device.Get();
mGbmDevice = CreateGbmDevice();
}
diff --git a/src/dawn/tests/end2end/VideoViewsTests_mac.cpp b/src/dawn/tests/end2end/VideoViewsTests_mac.cpp
index 135bd76..1d5ca65 100644
--- a/src/dawn/tests/end2end/VideoViewsTests_mac.cpp
+++ b/src/dawn/tests/end2end/VideoViewsTests_mac.cpp
@@ -56,7 +56,7 @@
class VideoViewsTestBackendIOSurface : public VideoViewsTestBackend {
public:
- void OnSetUp(WGPUDevice device) override { mWGPUDevice = device; }
+ void OnSetUp(const wgpu::Device& device) override { mWGPUDevice = device; }
private:
std::unique_ptr<VideoViewsTestBackend::PlatformTexture> CreateVideoTextureForTest(
@@ -110,19 +110,9 @@
wgpu::SharedTextureMemoryDescriptor desc;
desc.nextInChain = &ioSurfaceDesc;
- auto device = wgpu::Device(mWGPUDevice);
- auto sharedTextureMemory = device.ImportSharedTextureMemory(&desc);
+ auto sharedTextureMemory = mWGPUDevice.ImportSharedTextureMemory(&desc);
- // Some tests create a texture that is invalid in some way and verify
- // that an error is seen. These tests fail if multiple errors are seen,
- // so swallow any error that is generated by creating the texture in
- // favor of surfacing errors generated by the BeginAccess() call below.
- // Any error generated when creating the texture will be resurfaced when
- // calling BeginAccess() as the texture will be invalid, but there are
- // also errors that surface only on the BeginAccess() call.
- device.PushErrorScope(wgpu::ErrorFilter::Validation);
auto texture = sharedTextureMemory.CreateTexture(&textureDesc);
- device.PopErrorScope([](WGPUErrorType type, const char*, void* userdataPtr) {}, nullptr);
// Invoke BeginAccess() on the texture to ensure that it can be used by
// the test. We will end the access when the texture is destroyed
@@ -130,31 +120,17 @@
wgpu::SharedTextureMemoryBeginAccessDescriptor beginAccessDesc;
beginAccessDesc.initialized = initialized;
beginAccessDesc.fenceCount = 0;
- sharedTextureMemory.BeginAccess(texture, &beginAccessDesc);
+ bool success = sharedTextureMemory.BeginAccess(texture, &beginAccessDesc);
- return std::make_unique<PlatformTextureIOSurface>(std::move(texture),
- std::move(sharedTextureMemory));
+ return success ? std::make_unique<PlatformTextureIOSurface>(std::move(texture),
+ std::move(sharedTextureMemory))
+ : nullptr;
}
void DestroyVideoTextureForTest(
- std::unique_ptr<VideoViewsTestBackend::PlatformTexture>&& platformTexture) override {
- auto device = wgpu::Device(mWGPUDevice);
- auto platformTextureIOSurface =
- static_cast<PlatformTextureIOSurface*>(platformTexture.get());
- wgpu::SharedTextureMemoryEndAccessState endAccessState;
+ std::unique_ptr<VideoViewsTestBackend::PlatformTexture>&& platformTexture) override {}
- // Tests of error cases will pass invalid textures here, for which the
- // below EndAccess() call will generate an error. However, the tests do
- // not listen for an error happening in this call (and errors are not
- // generated on other platforms that are not using SharedTextureMemory).
- // Hence, we swallow the error here to avoid spurious test failures.
- device.PushErrorScope(wgpu::ErrorFilter::Validation);
- platformTextureIOSurface->mSharedTextureMemory.EndAccess(platformTexture->wgpuTexture,
- &endAccessState);
- device.PopErrorScope([](WGPUErrorType type, const char*, void* userdataPtr) {}, nullptr);
- }
-
- WGPUDevice mWGPUDevice = nullptr;
+ wgpu::Device mWGPUDevice = nullptr;
};
} // anonymous namespace
diff --git a/src/dawn/tests/end2end/VideoViewsTests_win.cpp b/src/dawn/tests/end2end/VideoViewsTests_win.cpp
index 03ad4a0..4f2054e 100644
--- a/src/dawn/tests/end2end/VideoViewsTests_win.cpp
+++ b/src/dawn/tests/end2end/VideoViewsTests_win.cpp
@@ -38,7 +38,7 @@
#include "VideoViewsTests.h"
#include "dawn/common/Assert.h"
-#include "dawn/native/D3D12Backend.h"
+#include "dawn/native/D3DBackend.h"
#include "dawn/utils/TextureUtils.h"
namespace dawn {
@@ -58,12 +58,12 @@
public:
~VideoViewsTestBackendWin() override = default;
- void OnSetUp(WGPUDevice device) override {
+ void OnSetUp(const wgpu::Device& device) override {
mWGPUDevice = device;
// Create the D3D11 device/contexts that will be used in subsequent tests
ComPtr<IDXGIAdapter> dxgiAdapter =
- native::d3d::GetDXGIAdapter(wgpuDeviceGetAdapter(device));
+ native::d3d::GetDXGIAdapter(wgpuDeviceGetAdapter(device.Get()));
ComPtr<ID3D11Device> d3d11Device;
D3D_FEATURE_LEVEL d3dFeatureLevel;
@@ -203,45 +203,42 @@
DAWN_ASSERT(hr == S_OK);
// Open the DX11 texture in Dawn from the shared handle and return it as a WebGPU texture.
- native::d3d::ExternalImageDescriptorDXGISharedHandle externalImageDesc;
- externalImageDesc.cTextureDescriptor =
- reinterpret_cast<const WGPUTextureDescriptor*>(&textureDesc);
- externalImageDesc.sharedHandle = sharedHandle;
+ wgpu::SharedTextureMemoryDXGISharedHandleDescriptor sharedHandleDesc{};
+ sharedHandleDesc.handle = sharedHandle;
- std::unique_ptr<native::d3d::ExternalImageDXGI> externalImage =
- native::d3d::ExternalImageDXGI::Create(mWGPUDevice, &externalImageDesc);
+ wgpu::SharedTextureMemoryDescriptor desc;
+ desc.nextInChain = &sharedHandleDesc;
+ auto sharedTextureMemory = mWGPUDevice.ImportSharedTextureMemory(&desc);
// Handle is no longer needed once resources are created.
::CloseHandle(sharedHandle);
- if (!externalImage) {
- // Failed to create external image. Return early and close outstanding handles.
- // Otherwise we'll dereference a nullptr below.
- ::CloseHandle(fenceSharedHandle);
- return nullptr;
- }
+ wgpu::SharedFenceDXGISharedHandleDescriptor dxgiFenceDesc{};
+ dxgiFenceDesc.handle = fenceSharedHandle;
+ wgpu::SharedFenceDescriptor fenceDesc{};
+ fenceDesc.nextInChain = &dxgiFenceDesc;
+ auto wgpuFence = mWGPUDevice.ImportSharedFence(&fenceDesc);
+ uint64_t signaled_value = 1;
- native::d3d::ExternalImageDXGIFenceDescriptor fenceDesc;
- fenceDesc.fenceHandle = fenceSharedHandle;
- fenceDesc.fenceValue = 1;
+ wgpu::SharedTextureMemoryBeginAccessDescriptor beginDesc{};
+ beginDesc.initialized = initialized;
+ beginDesc.concurrentRead = false;
+ beginDesc.fenceCount = 1;
+ beginDesc.fences = &wgpuFence;
+ beginDesc.signaledValues = &signaled_value;
- native::d3d::ExternalImageDXGIBeginAccessDescriptor externalAccessDesc;
- externalAccessDesc.isInitialized = initialized;
- externalAccessDesc.usage = static_cast<WGPUTextureUsageFlags>(textureDesc.usage);
- externalAccessDesc.waitFences = {};
-
- auto wgpuTexture = wgpu::Texture::Acquire(externalImage->BeginAccess(&externalAccessDesc));
-
+ auto wgpuTexture = sharedTextureMemory.CreateTexture(&textureDesc);
+ bool success = sharedTextureMemory.BeginAccess(wgpuTexture, &beginDesc);
// Fence handle is no longer needed after begin access.
::CloseHandle(fenceSharedHandle);
- return std::make_unique<PlatformTextureWin>(std::move(wgpuTexture));
+ return success ? std::make_unique<PlatformTextureWin>(std::move(wgpuTexture)) : nullptr;
}
void DestroyVideoTextureForTest(
- std::unique_ptr<VideoViewsTestBackend::PlatformTexture>&& PlatformTexture) override {}
+ std::unique_ptr<VideoViewsTestBackend::PlatformTexture>&& platformTexture) override {}
- WGPUDevice mWGPUDevice = nullptr;
+ wgpu::Device mWGPUDevice = nullptr;
ComPtr<ID3D11Device> mD3d11Device;
};