d3d11: Tighten keyed mutex acquire scope
Acquire and release keyed mutex in tight texture synchronization scope
to allow co-operative "concurrent" use with other clients. Keyed mutexes
are acquired in SynchronizeTextureBeforeUse and released on submit.
Bug: dawn:2311
Change-Id: I782c667f7b1d4aec84f1adadb7a97fb990554ae4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/168121
Auto-Submit: Sunny Sachanandani <sunnyps@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/include/dawn/native/D3DBackend.h b/include/dawn/native/D3DBackend.h
index a0ba6cc..bf1979e 100644
--- a/include/dawn/native/D3DBackend.h
+++ b/include/dawn/native/D3DBackend.h
@@ -51,6 +51,9 @@
::LUID adapterLUID;
};
+// Chrome uses 0 as acquire key.
+static constexpr UINT64 kDXGIKeyedMutexAcquireKey = 0;
+
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDXGISharedHandle : ExternalImageDescriptor {
public:
ExternalImageDescriptorDXGISharedHandle();
diff --git a/src/dawn/native/d3d/DeviceD3D.h b/src/dawn/native/d3d/DeviceD3D.h
index 9e0776b..cd1dd7b 100644
--- a/src/dawn/native/d3d/DeviceD3D.h
+++ b/src/dawn/native/d3d/DeviceD3D.h
@@ -40,6 +40,7 @@
struct ExternalImageDXGIFenceDescriptor;
class ExternalImageDXGIImpl;
class Fence;
+class KeyedMutex;
class PlatformFunctions;
class Device : public DeviceBase {
@@ -64,6 +65,7 @@
virtual Ref<TextureBase> CreateD3DExternalTexture(
const UnpackedPtr<TextureDescriptor>& descriptor,
ComPtr<IUnknown> d3dTexture,
+ ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex,
std::vector<FenceAndSignalValue> waitFences,
bool isSwapChainTexture,
bool isInitialized) = 0;
diff --git a/src/dawn/native/d3d/ExternalImageDXGIImpl.cpp b/src/dawn/native/d3d/ExternalImageDXGIImpl.cpp
index bad0e62..c485413 100644
--- a/src/dawn/native/d3d/ExternalImageDXGIImpl.cpp
+++ b/src/dawn/native/d3d/ExternalImageDXGIImpl.cpp
@@ -83,15 +83,12 @@
textureDescriptor->nextInChain)
->internalUsage;
}
-
// If the resource has IDXGIKeyedMutex interface, it will be used for synchronization.
- // TODO(dawn:1906): remove the mDXGIKeyedMutex when it is not used in chrome.
mD3DResource.As(&mDXGIKeyedMutex);
}
ExternalImageDXGIImpl::~ExternalImageDXGIImpl() {
DAWN_ASSERT(mBackendDevice->IsLockedByCurrentThreadIfNeeded());
- mDXGIKeyedMutexReleaser.reset();
DestroyInternal();
}
@@ -169,20 +166,9 @@
Ref<TextureBase> texture =
ToBackend(mBackendDevice.Get())
- ->CreateD3DExternalTexture(Unpack(&textureDescriptor), mD3DResource,
+ ->CreateD3DExternalTexture(Unpack(&textureDescriptor), mD3DResource, mDXGIKeyedMutex,
std::move(waitFences), descriptor->isSwapChainTexture,
descriptor->isInitialized);
-
- if (mDXGIKeyedMutex && mAccessCount == 0) {
- HRESULT hr = mDXGIKeyedMutex->AcquireSync(kDXGIKeyedMutexAcquireKey, INFINITE);
- if (FAILED(hr)) {
- dawn::ErrorLog() << "Failed to acquire keyed mutex for external image";
- return nullptr;
- }
- mDXGIKeyedMutexReleaser.emplace(mDXGIKeyedMutex);
- }
- ++mAccessCount;
-
return ToAPI(ReturnToAPI(std::move(texture)));
}
@@ -216,11 +202,6 @@
signalFence->fenceHandle = sharedFence->GetFenceHandle();
signalFence->fenceValue = static_cast<uint64_t>(fenceValue);
-
- --mAccessCount;
- if (mDXGIKeyedMutexReleaser && mAccessCount == 0) {
- mDXGIKeyedMutexReleaser.reset();
- }
}
} // namespace dawn::native::d3d
diff --git a/src/dawn/native/d3d/ExternalImageDXGIImpl.h b/src/dawn/native/d3d/ExternalImageDXGIImpl.h
index f8cbc08..6a76eb5 100644
--- a/src/dawn/native/d3d/ExternalImageDXGIImpl.h
+++ b/src/dawn/native/d3d/ExternalImageDXGIImpl.h
@@ -47,6 +47,7 @@
namespace dawn::native::d3d {
class Device;
+class KeyedMutex;
struct ExternalImageDXGIBeginAccessDescriptor;
struct ExternalImageDXGIFenceDescriptor;
struct ExternalImageDescriptorDXGISharedHandle;
@@ -86,20 +87,6 @@
uint32_t mMipLevelCount;
uint32_t mSampleCount;
std::vector<wgpu::TextureFormat> mViewFormats;
- uint32_t mAccessCount = 0;
-
- // Chrome uses 0 as acquire key.
- static constexpr UINT64 kDXGIKeyedMutexAcquireKey = 0;
- class KeyedMutexReleaser : public NonCopyable {
- public:
- explicit KeyedMutexReleaser(ComPtr<IDXGIKeyedMutex> keyedMutex)
- : mDXGIKeyedMutex(std::move(keyedMutex)) {}
- ~KeyedMutexReleaser() { mDXGIKeyedMutex->ReleaseSync(kDXGIKeyedMutexAcquireKey); }
-
- private:
- const ComPtr<IDXGIKeyedMutex> mDXGIKeyedMutex;
- };
- std::optional<KeyedMutexReleaser> mDXGIKeyedMutexReleaser;
};
} // namespace dawn::native::d3d
diff --git a/src/dawn/native/d3d/SharedTextureMemoryD3D.cpp b/src/dawn/native/d3d/SharedTextureMemoryD3D.cpp
index 58e2ec1..d83751f 100644
--- a/src/dawn/native/d3d/SharedTextureMemoryD3D.cpp
+++ b/src/dawn/native/d3d/SharedTextureMemoryD3D.cpp
@@ -40,13 +40,8 @@
SharedTextureMemory::SharedTextureMemory(d3d::Device* device,
const char* label,
- SharedTextureMemoryProperties properties,
- IUnknown* resource)
- : SharedTextureMemoryBase(device, label, properties) {
- // If the resource has IDXGIKeyedMutex interface, it will be used for synchronization.
- // TODO(dawn:1906): remove the mDXGIKeyedMutex when it is not used in chrome.
- resource->QueryInterface(IID_PPV_ARGS(&mDXGIKeyedMutex));
-}
+ SharedTextureMemoryProperties properties)
+ : SharedTextureMemoryBase(device, label, properties) {}
MaybeError SharedTextureMemory::BeginAccessImpl(
TextureBase* texture,
@@ -68,13 +63,6 @@
return DAWN_VALIDATION_ERROR("Unsupported fence type %s.", exportInfo.type);
}
}
-
- // Acquire keyed mutex for the first access.
- if (mDXGIKeyedMutex &&
- (HasWriteAccess() || HasExclusiveReadAccess() || GetReadAccessCount() == 1)) {
- DAWN_TRY(CheckHRESULT(mDXGIKeyedMutex->AcquireSync(kDXGIKeyedMutexAcquireKey, INFINITE),
- "Acquire keyed mutex"));
- }
return {};
}
@@ -86,12 +74,6 @@
"Required feature (%s) is missing.",
wgpu::FeatureName::SharedFenceDXGISharedHandle);
- // Release keyed mutex for the last access.
- if (mDXGIKeyedMutex && !HasWriteAccess() && !HasExclusiveReadAccess() &&
- GetReadAccessCount() == 0) {
- mDXGIKeyedMutex->ReleaseSync(kDXGIKeyedMutexAcquireKey);
- }
-
Ref<SharedFence> sharedFence;
DAWN_TRY_ASSIGN(sharedFence, ToBackend(GetDevice()->GetQueue())->GetOrCreateSharedFence());
diff --git a/src/dawn/native/d3d/SharedTextureMemoryD3D.h b/src/dawn/native/d3d/SharedTextureMemoryD3D.h
index 3a2c305..cfdf697 100644
--- a/src/dawn/native/d3d/SharedTextureMemoryD3D.h
+++ b/src/dawn/native/d3d/SharedTextureMemoryD3D.h
@@ -39,21 +39,12 @@
protected:
SharedTextureMemory(Device* device,
const char* label,
- SharedTextureMemoryProperties properties,
- IUnknown* resource);
+ SharedTextureMemoryProperties properties);
- protected:
MaybeError BeginAccessImpl(TextureBase* texture,
const UnpackedPtr<BeginAccessDescriptor>& descriptor) override;
ResultOrError<FenceAndSignalValue> EndAccessImpl(TextureBase* texture,
UnpackedPtr<EndAccessState>& state) override;
-
- private:
- // If the resource has IDXGIKeyedMutex interface, it will be used for synchronization.
- // TODO(dawn:1906): remove the mDXGIKeyedMutex when it is not used in chrome.
- ComPtr<IDXGIKeyedMutex> mDXGIKeyedMutex;
- // Chrome uses 0 as acquire key.
- static constexpr UINT64 kDXGIKeyedMutexAcquireKey = 0;
};
} // namespace dawn::native::d3d
diff --git a/src/dawn/native/d3d/d3d_platform.h b/src/dawn/native/d3d/d3d_platform.h
index e1944ed..06b63ac 100644
--- a/src/dawn/native/d3d/d3d_platform.h
+++ b/src/dawn/native/d3d/d3d_platform.h
@@ -44,6 +44,17 @@
#include <DXProgrammableCapture.h> // NOLINT(build/include_order)
#include <dxgidebug.h> // NOLINT(build/include_order)
+#include <functional> // NOLINT(build/include_order)
+#include <utility> // NOLINT(build/include_order)
+
using Microsoft::WRL::ComPtr;
+template <typename T>
+struct std::hash<ComPtr<T>> {
+ std::size_t operator()(const ComPtr<T>& v) const noexcept { return std::hash<T*>{}(v.Get()); }
+};
+template <typename T, typename H>
+H AbslHashValue(H state, const ComPtr<T>& v) {
+ return H::combine(std::move(state), v.Get());
+}
#endif // SRC_DAWN_NATIVE_D3D_D3D_PLATFORM_H_
diff --git a/src/dawn/native/d3d11/CommandBufferD3D11.cpp b/src/dawn/native/d3d11/CommandBufferD3D11.cpp
index 5f6e03f..eaa105f 100644
--- a/src/dawn/native/d3d11/CommandBufferD3D11.cpp
+++ b/src/dawn/native/d3d11/CommandBufferD3D11.cpp
@@ -245,6 +245,9 @@
}
for (const SyncScopeResourceUsage& scope :
GetResourceUsages().computePasses[nextComputePassNumber].dispatchUsages) {
+ for (TextureBase* texture : scope.textures) {
+ DAWN_TRY(ToBackend(texture)->SynchronizeTextureBeforeUse(commandContext));
+ }
DAWN_TRY(LazyClearSyncScope(scope));
}
DAWN_TRY(ExecuteComputePass(commandContext));
diff --git a/src/dawn/native/d3d11/CommandRecordingContextD3D11.cpp b/src/dawn/native/d3d11/CommandRecordingContextD3D11.cpp
index 7d79769..d062143 100644
--- a/src/dawn/native/d3d11/CommandRecordingContextD3D11.cpp
+++ b/src/dawn/native/d3d11/CommandRecordingContextD3D11.cpp
@@ -30,6 +30,7 @@
#include <string>
#include <utility>
+#include "dawn/native/D3DBackend.h"
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d11/BufferD3D11.h"
#include "dawn/native/d3d11/DeviceD3D11.h"
@@ -129,6 +130,16 @@
return {};
}
+MaybeError ScopedCommandRecordingContext::AcquireKeyedMutex(
+ ComPtr<IDXGIKeyedMutex> dxgikeyedMutex) const {
+ if (!Get()->mAcquiredKeyedMutexes.contains(dxgikeyedMutex)) {
+ DAWN_TRY(CheckHRESULT(dxgikeyedMutex->AcquireSync(d3d::kDXGIKeyedMutexAcquireKey, INFINITE),
+ "Failed to acquire keyed mutex for external image"));
+ Get()->mAcquiredKeyedMutexes.emplace(std::move(dxgikeyedMutex));
+ }
+ return {};
+}
+
ScopedSwapStateCommandRecordingContext::ScopedSwapStateCommandRecordingContext(
CommandRecordingContextGuard&& guard)
: ScopedCommandRecordingContext(std::move(guard)),
@@ -201,6 +212,27 @@
return {};
}
+void CommandRecordingContext::Destroy() {
+ DAWN_ASSERT(mDevice->IsLockedByCurrentThreadIfNeeded());
+ mIsOpen = false;
+ mUniformBuffer = nullptr;
+ mDevice = nullptr;
+
+ if (mD3D11DeviceContext4) {
+ ID3D11Buffer* nullBuffer = nullptr;
+ mD3D11DeviceContext4->VSSetConstantBuffers(PipelineLayout::kReservedConstantBufferSlot, 1,
+ &nullBuffer);
+ mD3D11DeviceContext4->CSSetConstantBuffers(PipelineLayout::kReservedConstantBufferSlot, 1,
+ &nullBuffer);
+ }
+
+ ReleaseKeyedMutexes();
+
+ mD3D11DeviceContextState = nullptr;
+ mD3D11DeviceContext4 = nullptr;
+ mD3D11Device = nullptr;
+}
+
// static
ResultOrError<Ref<BufferBase>> CommandRecordingContext::CreateInternalUniformBuffer(
DeviceBase* device) {
@@ -229,21 +261,11 @@
&bufferPtr);
}
-void CommandRecordingContext::Release() {
- if (mIsOpen) {
- DAWN_ASSERT(mDevice->IsLockedByCurrentThreadIfNeeded());
- mIsOpen = false;
- mUniformBuffer = nullptr;
- mDevice = nullptr;
- ID3D11Buffer* nullBuffer = nullptr;
- mD3D11DeviceContext4->VSSetConstantBuffers(PipelineLayout::kReservedConstantBufferSlot, 1,
- &nullBuffer);
- mD3D11DeviceContext4->CSSetConstantBuffers(PipelineLayout::kReservedConstantBufferSlot, 1,
- &nullBuffer);
- mD3D11DeviceContextState = nullptr;
- mD3D11DeviceContext4 = nullptr;
- mD3D11Device = nullptr;
+void CommandRecordingContext::ReleaseKeyedMutexes() {
+ for (auto& dxgikeyedMutex : mAcquiredKeyedMutexes) {
+ dxgikeyedMutex->ReleaseSync(d3d::kDXGIKeyedMutexAcquireKey);
}
+ mAcquiredKeyedMutexes.clear();
}
} // namespace dawn::native::d3d11
diff --git a/src/dawn/native/d3d11/CommandRecordingContextD3D11.h b/src/dawn/native/d3d11/CommandRecordingContextD3D11.h
index b56bdca..f0e1a05 100644
--- a/src/dawn/native/d3d11/CommandRecordingContextD3D11.h
+++ b/src/dawn/native/d3d11/CommandRecordingContextD3D11.h
@@ -28,6 +28,7 @@
#ifndef SRC_DAWN_NATIVE_D3D11_COMMANDRECORDINGCONTEXT_D3D11_H_
#define SRC_DAWN_NATIVE_D3D11_COMMANDRECORDINGCONTEXT_D3D11_H_
+#include "absl/container/flat_hash_set.h"
#include "dawn/common/MutexProtected.h"
#include "dawn/common/NonCopyable.h"
#include "dawn/common/Ref.h"
@@ -77,11 +78,12 @@
::dawn::detail::MutexProtectedTraits<CommandRecordingContext>>;
MaybeError Initialize(Device* device);
+ void Destroy();
static ResultOrError<Ref<BufferBase>> CreateInternalUniformBuffer(DeviceBase* device);
void SetInternalUniformBuffer(Ref<BufferBase> uniformBuffer);
- void Release();
+ void ReleaseKeyedMutexes();
private:
template <typename Ctx, typename Traits>
@@ -104,6 +106,8 @@
std::array<uint32_t, kMaxNumBuiltinElements> mUniformBufferData;
bool mUniformBufferDirty = true;
+ absl::flat_hash_set<ComPtr<IDXGIKeyedMutex>> mAcquiredKeyedMutexes;
+
Ref<Device> mDevice;
};
@@ -149,6 +153,8 @@
// Write the built-in variable value to the uniform buffer.
void WriteUniformBuffer(uint32_t offset, uint32_t element) const;
MaybeError FlushUniformBuffer() const;
+
+ MaybeError AcquireKeyedMutex(ComPtr<IDXGIKeyedMutex> dxgikeyedMutex) const;
};
// For using ID3D11DeviceContext directly. It swaps and resets ID3DDeviceContextState of
diff --git a/src/dawn/native/d3d11/DeviceD3D11.cpp b/src/dawn/native/d3d11/DeviceD3D11.cpp
index be3bc98..7c8de7b 100644
--- a/src/dawn/native/d3d11/DeviceD3D11.cpp
+++ b/src/dawn/native/d3d11/DeviceD3D11.cpp
@@ -481,14 +481,15 @@
Ref<TextureBase> Device::CreateD3DExternalTexture(const UnpackedPtr<TextureDescriptor>& descriptor,
ComPtr<IUnknown> d3dTexture,
+ ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex,
std::vector<FenceAndSignalValue> waitFences,
bool isSwapChainTexture,
bool isInitialized) {
Ref<Texture> dawnTexture;
- if (ConsumedError(
- Texture::CreateExternalImage(this, descriptor, std::move(d3dTexture),
- std::move(waitFences), isSwapChainTexture, isInitialized),
- &dawnTexture)) {
+ if (ConsumedError(Texture::CreateExternalImage(this, descriptor, std::move(d3dTexture),
+ std::move(dxgiKeyedMutex), std::move(waitFences),
+ isSwapChainTexture, isInitialized),
+ &dawnTexture)) {
return nullptr;
}
return {dawnTexture};
diff --git a/src/dawn/native/d3d11/DeviceD3D11.h b/src/dawn/native/d3d11/DeviceD3D11.h
index 67795f8..7ce600f 100644
--- a/src/dawn/native/d3d11/DeviceD3D11.h
+++ b/src/dawn/native/d3d11/DeviceD3D11.h
@@ -57,6 +57,7 @@
void ReferenceUntilUnused(ComPtr<IUnknown> object);
Ref<TextureBase> CreateD3DExternalTexture(const UnpackedPtr<TextureDescriptor>& descriptor,
ComPtr<IUnknown> d3dTexture,
+ ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex,
std::vector<FenceAndSignalValue> waitFences,
bool isSwapChainTexture,
bool isInitialized) override;
diff --git a/src/dawn/native/d3d11/QueueD3D11.cpp b/src/dawn/native/d3d11/QueueD3D11.cpp
index fff390d..14dec3e 100644
--- a/src/dawn/native/d3d11/QueueD3D11.cpp
+++ b/src/dawn/native/d3d11/QueueD3D11.cpp
@@ -91,7 +91,7 @@
mSharedFence = nullptr;
mPendingCommands.Use([&](auto pendingCommands) {
- pendingCommands->Release();
+ pendingCommands->Destroy();
mPendingCommandsNeedSubmit.store(false, std::memory_order_release);
});
}
@@ -124,10 +124,14 @@
}
MaybeError Queue::SubmitPendingCommands() {
- if (!mPendingCommandsNeedSubmit.exchange(false, std::memory_order_acq_rel)) {
- return {};
+ bool needsSubmit = mPendingCommands.Use([&](auto pendingCommands) {
+ pendingCommands->ReleaseKeyedMutexes();
+ return mPendingCommandsNeedSubmit.exchange(false, std::memory_order_acq_rel);
+ });
+ if (needsSubmit) {
+ return NextSerial();
}
- return NextSerial();
+ return {};
}
MaybeError Queue::SubmitImpl(uint32_t commandCount, CommandBufferBase* const* commands) {
diff --git a/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp b/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp
index de12ed9..0dfffb6 100644
--- a/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp
+++ b/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp
@@ -145,10 +145,12 @@
const char* label,
SharedTextureMemoryProperties properties,
ComPtr<ID3D11Resource> resource)
- : d3d::SharedTextureMemory(device, label, properties, resource.Get()),
- mResource(std::move(resource)) {}
+ : d3d::SharedTextureMemory(device, label, properties), mResource(std::move(resource)) {
+ mResource.As(&mKeyedMutex);
+}
void SharedTextureMemory::DestroyImpl() {
+ mKeyedMutex = nullptr;
mResource = nullptr;
}
@@ -156,6 +158,10 @@
return mResource.Get();
}
+IDXGIKeyedMutex* SharedTextureMemory::GetKeyedMutex() const {
+ return mKeyedMutex.Get();
+}
+
ResultOrError<Ref<TextureBase>> SharedTextureMemory::CreateTextureImpl(
const UnpackedPtr<TextureDescriptor>& descriptor) {
return Texture::CreateFromSharedTextureMemory(this, descriptor);
diff --git a/src/dawn/native/d3d11/SharedTextureMemoryD3D11.h b/src/dawn/native/d3d11/SharedTextureMemoryD3D11.h
index 7b310f0..576b248 100644
--- a/src/dawn/native/d3d11/SharedTextureMemoryD3D11.h
+++ b/src/dawn/native/d3d11/SharedTextureMemoryD3D11.h
@@ -51,6 +51,8 @@
ID3D11Resource* GetD3DResource() const;
+ IDXGIKeyedMutex* GetKeyedMutex() const;
+
private:
SharedTextureMemory(Device* device,
const char* label,
@@ -63,6 +65,7 @@
const UnpackedPtr<TextureDescriptor>& descriptor) override;
ComPtr<ID3D11Resource> mResource;
+ ComPtr<IDXGIKeyedMutex> mKeyedMutex;
};
} // namespace dawn::native::d3d11
diff --git a/src/dawn/native/d3d11/TextureD3D11.cpp b/src/dawn/native/d3d11/TextureD3D11.cpp
index ba3dbb7..d4ea2aa 100644
--- a/src/dawn/native/d3d11/TextureD3D11.cpp
+++ b/src/dawn/native/d3d11/TextureD3D11.cpp
@@ -43,6 +43,7 @@
#include "dawn/native/ToBackend.h"
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d/UtilsD3D.h"
+#include "dawn/native/d3d11/CommandRecordingContextD3D11.h"
#include "dawn/native/d3d11/DeviceD3D11.h"
#include "dawn/native/d3d11/Forward.h"
#include "dawn/native/d3d11/QueueD3D11.h"
@@ -229,12 +230,22 @@
Device* device,
const UnpackedPtr<TextureDescriptor>& descriptor,
ComPtr<IUnknown> d3dTexture,
+ ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex,
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(waitFences),
- isSwapChainTexture));
+ DAWN_TRY(
+ dawnTexture->InitializeAsExternalTexture(std::move(d3dTexture), std::move(dxgiKeyedMutex)));
+
+ 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.
@@ -254,7 +265,8 @@
const UnpackedPtr<TextureDescriptor>& descriptor) {
Device* device = ToBackend(memory->GetDevice());
Ref<Texture> texture = AcquireRef(new Texture(device, descriptor, Kind::Normal));
- DAWN_TRY(texture->InitializeAsExternalTexture(memory->GetD3DResource(), {}, false));
+ DAWN_TRY(
+ texture->InitializeAsExternalTexture(memory->GetD3DResource(), memory->GetKeyedMutex()));
texture->mSharedTextureMemoryContents = memory->GetContents();
return texture;
}
@@ -367,19 +379,11 @@
}
MaybeError Texture::InitializeAsExternalTexture(ComPtr<IUnknown> d3dTexture,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture) {
+ ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex) {
ComPtr<ID3D11Resource> d3d11Texture;
DAWN_TRY(CheckHRESULT(d3dTexture.As(&d3d11Texture), "Query ID3D11Resource from IUnknown"));
-
- auto commandContext = ToBackend(GetDevice()->GetQueue())
- ->GetScopedPendingCommandContext(QueueBase::SubmitMode::Normal);
- for (const auto& fence : waitFences) {
- DAWN_TRY(CheckHRESULT(
- commandContext.Wait(ToBackend(fence.object)->GetD3DFence(), fence.signaledValue),
- "ID3D11DeviceContext4::Wait"));
- }
mD3d11Resource = std::move(d3d11Texture);
+ mDxgiKeyedMutex = std::move(dxgiKeyedMutex);
SetLabelHelper("Dawn_ExternalTexture");
return {};
}
@@ -498,17 +502,19 @@
MaybeError Texture::SynchronizeTextureBeforeUse(
const ScopedCommandRecordingContext* commandContext) {
- if (SharedTextureMemoryContents* contents = GetSharedTextureMemoryContents()) {
+ if (auto* contents = GetSharedTextureMemoryContents()) {
SharedTextureMemoryBase::PendingFenceList fences;
contents->AcquirePendingFences(&fences);
contents->SetLastUsageSerial(GetDevice()->GetQueue()->GetPendingCommandSerial());
-
- for (auto& fence : fences) {
+ for (const auto& fence : fences) {
DAWN_TRY(CheckHRESULT(
commandContext->Wait(ToBackend(fence.object)->GetD3DFence(), fence.signaledValue),
"ID3D11DeviceContext4::Wait"));
}
}
+ if (mDxgiKeyedMutex) {
+ DAWN_TRY(commandContext->AcquireKeyedMutex(mDxgiKeyedMutex));
+ }
mLastUsageSerial = GetDevice()->GetQueue()->GetPendingCommandSerial();
return {};
}
diff --git a/src/dawn/native/d3d11/TextureD3D11.h b/src/dawn/native/d3d11/TextureD3D11.h
index 99854fc..69d5ad8 100644
--- a/src/dawn/native/d3d11/TextureD3D11.h
+++ b/src/dawn/native/d3d11/TextureD3D11.h
@@ -67,6 +67,7 @@
Device* device,
const UnpackedPtr<TextureDescriptor>& descriptor,
ComPtr<IUnknown> d3dTexture,
+ ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex,
std::vector<FenceAndSignalValue> waitFences,
bool isSwapChainTexture,
bool isInitialized);
@@ -141,8 +142,7 @@
MaybeError InitializeAsInternalTexture();
MaybeError InitializeAsSwapChainTexture(ComPtr<ID3D11Resource> d3d11Texture);
MaybeError InitializeAsExternalTexture(ComPtr<IUnknown> d3dTexture,
- std::vector<FenceAndSignalValue> waitFences,
- bool isSwapChainTexture);
+ ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex);
void SetLabelHelper(const char* prefix);
// Dawn API
@@ -195,6 +195,7 @@
const Kind mKind = Kind::Normal;
ComPtr<ID3D11Resource> mD3d11Resource;
+ ComPtr<IDXGIKeyedMutex> mDxgiKeyedMutex;
// TODO(crbug.com/1515640): Remove this once Chromium has migrated to SharedTextureMemory.
std::optional<ExecutionSerial> mLastUsageSerial;
diff --git a/src/dawn/native/d3d12/DeviceD3D12.cpp b/src/dawn/native/d3d12/DeviceD3D12.cpp
index 014f1d9..746e308 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/DeviceD3D12.cpp
@@ -544,9 +544,12 @@
Ref<TextureBase> Device::CreateD3DExternalTexture(const UnpackedPtr<TextureDescriptor>& descriptor,
ComPtr<IUnknown> d3dTexture,
+ ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex,
std::vector<FenceAndSignalValue> waitFences,
bool isSwapChainTexture,
bool isInitialized) {
+ // TODO(sunnyps): Reintroduce keyed mutex support.
+ DAWN_ASSERT(dxgiKeyedMutex == nullptr);
Ref<Texture> dawnTexture;
if (ConsumedError(
Texture::CreateExternalImage(this, descriptor, std::move(d3dTexture),
diff --git a/src/dawn/native/d3d12/DeviceD3D12.h b/src/dawn/native/d3d12/DeviceD3D12.h
index 12f37fa..b0ff361 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.h
+++ b/src/dawn/native/d3d12/DeviceD3D12.h
@@ -146,6 +146,7 @@
Ref<TextureBase> CreateD3DExternalTexture(const UnpackedPtr<TextureDescriptor>& descriptor,
ComPtr<IUnknown> d3dTexture,
+ ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex,
std::vector<FenceAndSignalValue> waitFences,
bool isSwapChainTexture,
bool isInitialized) override;
diff --git a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
index b767915..6c6e035 100644
--- a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
+++ b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
@@ -101,8 +101,7 @@
const char* label,
SharedTextureMemoryProperties properties,
ComPtr<ID3D12Resource> resource)
- : d3d::SharedTextureMemory(device, label, properties, resource.Get()),
- mResource(std::move(resource)) {}
+ : d3d::SharedTextureMemory(device, label, properties), mResource(std::move(resource)) {}
void SharedTextureMemory::DestroyImpl() {
ToBackend(GetDevice())->ReferenceUntilUnused(std::move(mResource));