d3d: move some external image related code to d3d namespace

Expect ExternalImageDXGIImpl, most external image related code can
be shared between d3d11 and d3d12. This CL move those code into
d3d namespace

Bug: dawn:1724
Change-Id: I6c32cfd36880d4d009b272886a9369dc99dffbe6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/130100
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Peng Huang 2023-04-28 16:53:28 +00:00 committed by Dawn LUCI CQ
parent 220aa01153
commit d7a4483148
15 changed files with 322 additions and 182 deletions

View File

@ -20,9 +20,6 @@
#include <windows.h>
#include <wrl/client.h>
#include <memory>
#include <vector>
#include "dawn/native/D3DBackend.h"
struct ID3D12Device;
@ -30,8 +27,13 @@ struct ID3D12Resource;
namespace dawn::native::d3d12 {
// TODO(dawn:1724): remove below once chrome is updated
using d3d::ExternalImageDescriptorDXGISharedHandle;
using d3d::ExternalImageDXGI;
using d3d::ExternalImageDXGIBeginAccessDescriptor;
using d3d::ExternalImageDXGIFenceDescriptor;
class Device;
class ExternalImageDXGIImpl;
DAWN_NATIVE_EXPORT Microsoft::WRL::ComPtr<ID3D12Device> GetD3D12Device(WGPUDevice device);
@ -44,62 +46,6 @@ DAWN_NATIVE_EXPORT uint64_t SetExternalMemoryReservation(WGPUDevice device,
uint64_t requestedReservationSize,
MemorySegment memorySegment);
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDXGISharedHandle : ExternalImageDescriptor {
public:
ExternalImageDescriptorDXGISharedHandle();
// Note: SharedHandle must be a handle to a texture object.
HANDLE sharedHandle = nullptr;
};
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 ExternalImageDescriptorDXGISharedHandle* 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;
};
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public d3d::AdapterDiscoveryOptions {
AdapterDiscoveryOptions();
explicit AdapterDiscoveryOptions(Microsoft::WRL::ComPtr<IDXGIAdapter> adapter);

View File

@ -19,15 +19,76 @@
#include <windows.h>
#include <wrl/client.h>
#include <memory>
#include <vector>
#include "dawn/native/DawnNative.h"
namespace dawn::native::d3d {
class ExternalImageDXGIImpl;
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptionsBase {
AdapterDiscoveryOptions(WGPUBackendType type, Microsoft::WRL::ComPtr<IDXGIAdapter> adapter);
Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter;
};
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDXGISharedHandle : ExternalImageDescriptor {
public:
ExternalImageDescriptorDXGISharedHandle();
// Note: SharedHandle must be a handle to a texture object.
HANDLE sharedHandle = nullptr;
};
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 ExternalImageDescriptorDXGISharedHandle* 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_

View File

@ -409,6 +409,8 @@ source_set("sources") {
"d3d/D3DError.h",
"d3d/DeviceD3D.cpp",
"d3d/DeviceD3D.h",
"d3d/ExternalImageDXGIImpl.cpp",
"d3d/ExternalImageDXGIImpl.h",
"d3d/Forward.h",
"d3d/PlatformFunctions.cpp",
"d3d/PlatformFunctions.h",
@ -495,8 +497,8 @@ source_set("sources") {
"d3d12/D3D12Info.h",
"d3d12/DeviceD3D12.cpp",
"d3d12/DeviceD3D12.h",
"d3d12/ExternalImageDXGIImpl.cpp",
"d3d12/ExternalImageDXGIImpl.h",
"d3d12/ExternalImageDXGIImplD3D12.cpp",
"d3d12/ExternalImageDXGIImplD3D12.h",
"d3d12/FenceD3D12.cpp",
"d3d12/FenceD3D12.h",
"d3d12/Forward.h",

View File

@ -266,6 +266,8 @@ if (DAWN_ENABLE_D3D11 OR DAWN_ENABLE_D3D12)
"d3d/D3DError.h"
"d3d/DeviceD3D.cpp"
"d3d/DeviceD3D.h"
"d3d/ExternalImageDXGIImpl.cpp"
"d3d/ExternalImageDXGIImpl.h"
"d3d/Forward.h"
"d3d/PlatformFunctions.cpp"
"d3d/PlatformFunctions.h"
@ -352,8 +354,8 @@ if (DAWN_ENABLE_D3D12)
"d3d12/D3D12Info.h"
"d3d12/DeviceD3D12.cpp"
"d3d12/DeviceD3D12.h"
"d3d12/ExternalImageDXGIImpl.cpp"
"d3d12/ExternalImageDXGIImpl.h"
"d3d12/ExternalImageDXGIImplD3D12.cpp"
"d3d12/ExternalImageDXGIImplD3D12.h"
"d3d12/FenceD3D12.cpp"
"d3d12/FenceD3D12.h"
"d3d12/Forward.h"

View File

@ -17,12 +17,57 @@
#include "dawn/native/D3DBackend.h"
#include <memory>
#include <utility>
#include "dawn/common/Log.h"
#include "dawn/native/d3d/DeviceD3D.h"
#include "dawn/native/d3d/ExternalImageDXGIImpl.h"
#include "dawn/native/d3d/Forward.h"
namespace dawn::native::d3d {
AdapterDiscoveryOptions::AdapterDiscoveryOptions(WGPUBackendType type,
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter)
: AdapterDiscoveryOptionsBase(type), dxgiAdapter(std::move(adapter)) {}
ExternalImageDescriptorDXGISharedHandle::ExternalImageDescriptorDXGISharedHandle()
: ExternalImageDescriptor(ExternalImageType::DXGISharedHandle) {}
ExternalImageDXGI::ExternalImageDXGI(std::unique_ptr<ExternalImageDXGIImpl> impl)
: mImpl(std::move(impl)) {
ASSERT(mImpl != nullptr);
}
ExternalImageDXGI::~ExternalImageDXGI() = default;
bool ExternalImageDXGI::IsValid() const {
return mImpl->IsValid();
}
WGPUTexture ExternalImageDXGI::BeginAccess(
const ExternalImageDXGIBeginAccessDescriptor* descriptor) {
return mImpl->BeginAccess(descriptor);
}
void ExternalImageDXGI::EndAccess(WGPUTexture texture,
ExternalImageDXGIFenceDescriptor* signalFence) {
mImpl->EndAccess(texture, signalFence);
}
// static
std::unique_ptr<ExternalImageDXGI> ExternalImageDXGI::Create(
WGPUDevice device,
const ExternalImageDescriptorDXGISharedHandle* 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

View File

@ -15,12 +15,15 @@
#ifndef SRC_DAWN_NATIVE_D3D_DEVICED3D_H_
#define SRC_DAWN_NATIVE_D3D_DEVICED3D_H_
#include "dawn/native/Device.h"
#include <memory>
#include "dawn/native/Device.h"
#include "dawn/native/d3d/d3d_platform.h"
namespace dawn::native::d3d {
struct ExternalImageDescriptorDXGISharedHandle;
class ExternalImageDXGIImpl;
class PlatformFunctions;
class Device : public DeviceBase {
@ -42,6 +45,9 @@ class Device : public DeviceBase {
ComPtr<IDxcLibrary> GetDxcLibrary() const;
ComPtr<IDxcCompiler> GetDxcCompiler() const;
ComPtr<IDxcValidator> GetDxcValidator() const;
virtual std::unique_ptr<ExternalImageDXGIImpl> CreateExternalImageDXGIImpl(
const ExternalImageDescriptorDXGISharedHandle* descriptor) = 0;
};
} // namespace dawn::native::d3d

View File

@ -0,0 +1,75 @@
// Copyright 2022 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn/native/d3d/ExternalImageDXGIImpl.h"
#include <utility>
#include <vector>
#include "dawn/common/Log.h"
#include "dawn/native/D3D12Backend.h"
#include "dawn/native/DawnNative.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
namespace dawn::native::d3d {
ExternalImageDXGIImpl::ExternalImageDXGIImpl(Device* backendDevice,
const TextureDescriptor* textureDescriptor)
: mBackendDevice(backendDevice),
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) {
ASSERT(mBackendDevice != nullptr);
ASSERT(!textureDescriptor->nextInChain || textureDescriptor->nextInChain->sType ==
wgpu::SType::DawnTextureInternalUsageDescriptor);
if (textureDescriptor->nextInChain) {
mUsageInternal = reinterpret_cast<const wgpu::DawnTextureInternalUsageDescriptor*>(
textureDescriptor->nextInChain)
->internalUsage;
}
}
ExternalImageDXGIImpl::~ExternalImageDXGIImpl() {
auto deviceLock(GetScopedDeviceLock());
DestroyInternal();
}
Mutex::AutoLock ExternalImageDXGIImpl::GetScopedDeviceLock() const {
if (mBackendDevice != nullptr) {
return mBackendDevice->GetScopedLock();
}
return Mutex::AutoLock();
}
bool ExternalImageDXGIImpl::IsValid() const {
auto deviceLock(GetScopedDeviceLock());
return IsInList();
}
void ExternalImageDXGIImpl::DestroyInternal() {
// Linked list is not thread safe. A mutex must already be locked before
// endtering this method. Either via Device::DestroyImpl() or ~ExternalImageDXGIImpl.
ASSERT(mBackendDevice == nullptr || mBackendDevice->IsLockedByCurrentThreadIfNeeded());
if (IsInList()) {
RemoveFromList();
}
}
} // namespace dawn::native::d3d

View File

@ -0,0 +1,72 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_DAWN_NATIVE_D3D_EXTERNALIMAGEDXGIIMPL_H_
#define SRC_DAWN_NATIVE_D3D_EXTERNALIMAGEDXGIIMPL_H_
#include <wrl/client.h>
#include <memory>
#include <vector>
#include "dawn/common/LinkedList.h"
#include "dawn/common/Mutex.h"
#include "dawn/native/Error.h"
#include "dawn/native/Forward.h"
#include "dawn/native/IntegerTypes.h"
#include "dawn/webgpu_cpp.h"
namespace dawn::native::d3d {
class Device;
struct ExternalImageDXGIBeginAccessDescriptor;
struct ExternalImageDXGIFenceDescriptor;
struct ExternalImageDescriptorDXGISharedHandle;
class ExternalImageDXGIImpl : public LinkNode<ExternalImageDXGIImpl> {
public:
ExternalImageDXGIImpl(Device* backendDevice, const TextureDescriptor* textureDescriptor);
virtual ~ExternalImageDXGIImpl();
ExternalImageDXGIImpl(const ExternalImageDXGIImpl&) = delete;
ExternalImageDXGIImpl& operator=(const ExternalImageDXGIImpl&) = delete;
bool IsValid() const;
virtual WGPUTexture BeginAccess(const ExternalImageDXGIBeginAccessDescriptor* descriptor) = 0;
virtual void EndAccess(WGPUTexture texture, ExternalImageDXGIFenceDescriptor* signalFence) = 0;
// This method should only be called by internal code. Don't call this from D3D12Backend side,
// or without locking.
virtual void DestroyInternal();
protected:
[[nodiscard]] Mutex::AutoLock GetScopedDeviceLock() const;
Ref<DeviceBase> mBackendDevice;
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_

View File

@ -411,6 +411,13 @@ float Device::GetTimestampPeriodInNS() const {
void Device::SetLabelImpl() {}
std::unique_ptr<d3d::ExternalImageDXGIImpl> Device::CreateExternalImageDXGIImpl(
const d3d::ExternalImageDescriptorDXGISharedHandle* descriptor) {
// TODO(dawn:1724): Implement this
UNREACHABLE();
return {};
}
bool Device::MayRequireDuplicationOfIndirectParameters() const {
return true;
}

View File

@ -79,6 +79,9 @@ class Device final : public d3d::Device {
uint64_t GetBufferCopyOffsetAlignmentForDepthStencil() const override;
void SetLabelImpl() override;
std::unique_ptr<d3d::ExternalImageDXGIImpl> CreateExternalImageDXGIImpl(
const d3d::ExternalImageDescriptorDXGISharedHandle* descriptor) override;
private:
using Base = d3d::Device;
using Base::Base;

View File

@ -23,7 +23,6 @@
#include "dawn/common/Log.h"
#include "dawn/common/Math.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
#include "dawn/native/d3d12/ExternalImageDXGIImpl.h"
#include "dawn/native/d3d12/ResidencyManagerD3D12.h"
#include "dawn/native/d3d12/TextureD3D12.h"
@ -33,45 +32,6 @@ ComPtr<ID3D12Device> GetD3D12Device(WGPUDevice device) {
return ToBackend(FromAPI(device))->GetD3D12Device();
}
ExternalImageDescriptorDXGISharedHandle::ExternalImageDescriptorDXGISharedHandle()
: ExternalImageDescriptor(ExternalImageType::DXGISharedHandle) {}
ExternalImageDXGI::ExternalImageDXGI(std::unique_ptr<ExternalImageDXGIImpl> impl)
: mImpl(std::move(impl)) {
ASSERT(mImpl != nullptr);
}
ExternalImageDXGI::~ExternalImageDXGI() = default;
bool ExternalImageDXGI::IsValid() const {
return mImpl->IsValid();
}
WGPUTexture ExternalImageDXGI::BeginAccess(
const ExternalImageDXGIBeginAccessDescriptor* descriptor) {
return mImpl->BeginAccess(descriptor);
}
void ExternalImageDXGI::EndAccess(WGPUTexture texture,
ExternalImageDXGIFenceDescriptor* signalFence) {
mImpl->EndAccess(texture, signalFence);
}
// static
std::unique_ptr<ExternalImageDXGI> ExternalImageDXGI::Create(
WGPUDevice device,
const ExternalImageDescriptorDXGISharedHandle* 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)));
}
uint64_t SetExternalMemoryReservation(WGPUDevice device,
uint64_t requestedReservationSize,
MemorySegment memorySegment) {

View File

@ -31,7 +31,7 @@
#include "dawn/native/d3d12/CommandAllocatorManager.h"
#include "dawn/native/d3d12/CommandBufferD3D12.h"
#include "dawn/native/d3d12/ComputePipelineD3D12.h"
#include "dawn/native/d3d12/ExternalImageDXGIImpl.h"
#include "dawn/native/d3d12/ExternalImageDXGIImplD3D12.h"
#include "dawn/native/d3d12/PipelineLayoutD3D12.h"
#include "dawn/native/d3d12/PlatformFunctionsD3D12.h"
#include "dawn/native/d3d12/QuerySetD3D12.h"
@ -545,8 +545,8 @@ ResultOrError<ResourceHeapAllocation> Device::AllocateMemory(
forceAllocateAsCommittedResource);
}
std::unique_ptr<ExternalImageDXGIImpl> Device::CreateExternalImageDXGIImpl(
const ExternalImageDescriptorDXGISharedHandle* descriptor) {
std::unique_ptr<d3d::ExternalImageDXGIImpl> Device::CreateExternalImageDXGIImpl(
const d3d::ExternalImageDescriptorDXGISharedHandle* 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.
@ -707,7 +707,7 @@ void Device::DestroyImpl() {
ASSERT(GetState() == State::Disconnected);
while (!mExternalImageList.empty()) {
ExternalImageDXGIImpl* externalImage = mExternalImageList.head()->value();
d3d::ExternalImageDXGIImpl* externalImage = mExternalImageList.head()->value();
// ExternalImageDXGIImpl::DestroyInternal() calls RemoveFromList().
externalImage->DestroyInternal();
}

View File

@ -25,11 +25,14 @@
#include "dawn/native/d3d12/Forward.h"
#include "dawn/native/d3d12/TextureD3D12.h"
namespace dawn::native::d3d {
struct ExternalImageDescriptorDXGISharedHandle;
class ExternalImageDXGIImpl;
} // namespace dawn::native::d3d
namespace dawn::native::d3d12 {
class CommandAllocatorManager;
struct ExternalImageDescriptorDXGISharedHandle;
class ExternalImageDXGIImpl;
class PlatformFunctions;
class ResidencyManager;
class ResourceAllocatorManager;
@ -134,8 +137,8 @@ class Device final : public d3d::Device {
StagingDescriptorAllocator* GetDepthStencilViewAllocator() const;
std::unique_ptr<ExternalImageDXGIImpl> CreateExternalImageDXGIImpl(
const ExternalImageDescriptorDXGISharedHandle* descriptor);
std::unique_ptr<d3d::ExternalImageDXGIImpl> CreateExternalImageDXGIImpl(
const d3d::ExternalImageDescriptorDXGISharedHandle* descriptor) override;
Ref<TextureBase> CreateD3D12ExternalTexture(const TextureDescriptor* descriptor,
ComPtr<ID3D12Resource> d3d12Texture,
@ -273,7 +276,7 @@ class Device final : public d3d::Device {
float mTimestampPeriod = 1.0f;
// List of external image resources opened using this device.
LinkedList<ExternalImageDXGIImpl> mExternalImageList;
LinkedList<d3d::ExternalImageDXGIImpl> mExternalImageList;
};
} // namespace dawn::native::d3d12

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn/native/d3d12/ExternalImageDXGIImpl.h"
#include "dawn/native/d3d12/ExternalImageDXGIImplD3D12.h"
#include <utility>
#include <vector>
@ -21,61 +21,24 @@
#include "dawn/native/D3D12Backend.h"
#include "dawn/native/DawnNative.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
#include "dawn/native/d3d12/Forward.h"
namespace dawn::native::d3d12 {
ExternalImageDXGIImpl::ExternalImageDXGIImpl(Device* backendDevice,
Microsoft::WRL::ComPtr<ID3D12Resource> d3d12Resource,
const TextureDescriptor* textureDescriptor)
: mBackendDevice(backendDevice),
mD3D12Resource(std::move(d3d12Resource)),
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) {
ASSERT(mBackendDevice != nullptr);
: Base(backendDevice, textureDescriptor), mD3D12Resource(std::move(d3d12Resource)) {
ASSERT(mD3D12Resource != nullptr);
ASSERT(!textureDescriptor->nextInChain || textureDescriptor->nextInChain->sType ==
wgpu::SType::DawnTextureInternalUsageDescriptor);
if (textureDescriptor->nextInChain) {
mUsageInternal = reinterpret_cast<const wgpu::DawnTextureInternalUsageDescriptor*>(
textureDescriptor->nextInChain)
->internalUsage;
}
}
ExternalImageDXGIImpl::~ExternalImageDXGIImpl() {
auto deviceLock(GetScopedDeviceLock());
DestroyInternal();
}
Mutex::AutoLock ExternalImageDXGIImpl::GetScopedDeviceLock() const {
if (mBackendDevice != nullptr) {
return mBackendDevice->GetScopedLock();
}
return Mutex::AutoLock();
}
bool ExternalImageDXGIImpl::IsValid() const {
auto deviceLock(GetScopedDeviceLock());
return IsInList();
}
ExternalImageDXGIImpl::~ExternalImageDXGIImpl() = default;
void ExternalImageDXGIImpl::DestroyInternal() {
// Linked list is not thread safe. A mutex must already be locked before
// endtering this method. Either via Device::DestroyImpl() or ~ExternalImageDXGIImpl.
ASSERT(mBackendDevice == nullptr || mBackendDevice->IsLockedByCurrentThreadIfNeeded());
if (IsInList()) {
RemoveFromList();
mD3D12Resource = nullptr;
// We don't set mBackendDevice to null here to let its mutex accessible until dtor. This
// also to avoid data racing with non-null check in GetScopedDeviceLock()
}
Base::DestroyInternal();
}
WGPUTexture ExternalImageDXGIImpl::BeginAccess(
@ -120,7 +83,7 @@ WGPUTexture ExternalImageDXGIImpl::BeginAccess(
// TODO(sunnyps): Use a fence cache instead of re-importing fences on each BeginAccess.
Ref<Fence> fence;
if (mBackendDevice->ConsumedError(
Fence::CreateFromHandle(mBackendDevice->GetD3D12Device(),
Fence::CreateFromHandle(ToBackend(mBackendDevice.Get())->GetD3D12Device(),
fenceDescriptor.fenceHandle, fenceDescriptor.fenceValue),
&fence)) {
dawn::ErrorLog() << "Unable to create D3D12 fence for external image";
@ -129,9 +92,10 @@ WGPUTexture ExternalImageDXGIImpl::BeginAccess(
waitFences.push_back(std::move(fence));
}
Ref<TextureBase> texture = mBackendDevice->CreateD3D12ExternalTexture(
&textureDescriptor, mD3D12Resource, std::move(waitFences), descriptor->isSwapChainTexture,
descriptor->isInitialized);
Ref<TextureBase> texture =
ToBackend(mBackendDevice.Get())
->CreateD3D12ExternalTexture(&textureDescriptor, mD3D12Resource, std::move(waitFences),
descriptor->isSwapChainTexture, descriptor->isInitialized);
return ToAPI(texture.Detach());
}
@ -155,7 +119,7 @@ void ExternalImageDXGIImpl::EndAccess(WGPUTexture texture,
dawn::ErrorLog() << "D3D12 fence end access failed";
return;
}
signalFence->fenceHandle = mBackendDevice->GetFenceHandle();
signalFence->fenceHandle = ToBackend(mBackendDevice.Get())->GetFenceHandle();
signalFence->fenceValue = static_cast<uint64_t>(fenceValue);
}

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_DAWN_NATIVE_D3D12_EXTERNALIMAGEDXGIIMPL_H_
#define SRC_DAWN_NATIVE_D3D12_EXTERNALIMAGEDXGIIMPL_H_
#ifndef SRC_DAWN_NATIVE_D3D12_EXTERNALIMAGEDXGIIMPLD3D12_H_
#define SRC_DAWN_NATIVE_D3D12_EXTERNALIMAGEDXGIIMPLD3D12_H_
#include <wrl/client.h>
@ -26,54 +26,48 @@
#include "dawn/native/Error.h"
#include "dawn/native/Forward.h"
#include "dawn/native/IntegerTypes.h"
#include "dawn/native/d3d/ExternalImageDXGIImpl.h"
#include "dawn/native/d3d12/FenceD3D12.h"
#include "dawn/webgpu_cpp.h"
struct ID3D12Resource;
struct ID3D12Fence;
namespace dawn::native::d3d {
struct ExternalImageDXGIBeginAccessDescriptor;
struct ExternalImageDescriptorDXGISharedHandle;
} // namespace dawn::native::d3d
namespace dawn::native::d3d12 {
class Device;
struct ExternalImageDXGIBeginAccessDescriptor;
struct ExternalImageDescriptorDXGISharedHandle;
class ExternalImageDXGIImpl : public LinkNode<ExternalImageDXGIImpl> {
class ExternalImageDXGIImpl : public d3d::ExternalImageDXGIImpl {
public:
ExternalImageDXGIImpl(Device* backendDevice,
Microsoft::WRL::ComPtr<ID3D12Resource> d3d12Resource,
const TextureDescriptor* textureDescriptor);
~ExternalImageDXGIImpl();
~ExternalImageDXGIImpl() override;
ExternalImageDXGIImpl(const ExternalImageDXGIImpl&) = delete;
ExternalImageDXGIImpl& operator=(const ExternalImageDXGIImpl&) = delete;
bool IsValid() const;
WGPUTexture BeginAccess(const ExternalImageDXGIBeginAccessDescriptor* descriptor);
WGPUTexture BeginAccess(const ExternalImageDXGIBeginAccessDescriptor* descriptor) override;
void EndAccess(WGPUTexture texture, ExternalImageDXGIFenceDescriptor* signalFence);
void EndAccess(WGPUTexture texture, ExternalImageDXGIFenceDescriptor* signalFence) override;
// This method should only be called by internal code. Don't call this from D3D12Backend side,
// or without locking.
void DestroyInternal();
void DestroyInternal() override;
private:
[[nodiscard]] Mutex::AutoLock GetScopedDeviceLock() const;
using Base = d3d::ExternalImageDXGIImpl;
Ref<Device> mBackendDevice;
Microsoft::WRL::ComPtr<ID3D12Resource> mD3D12Resource;
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::d3d12
#endif // SRC_DAWN_NATIVE_D3D12_EXTERNALIMAGEDXGIIMPL_H_
#endif // SRC_DAWN_NATIVE_D3D12_EXTERNALIMAGEDXGIIMPLD3D12_H_