D3D11: skip waiting on the fence that is owned by the same queue.
It's not necessary to wait on the fence that was signaled by the same
queue. D3D11 runtime already tracks the dependencies between commands
internally.
Bug: 390598765
Change-Id: I35c575f579b65b9d34ddc7ada4bc65a151b86f87
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/222415
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Quyen Le <lehoangquyen@chromium.org>
diff --git a/src/dawn/native/d3d/PlatformFunctions.cpp b/src/dawn/native/d3d/PlatformFunctions.cpp
index 81f3fdb..f63bbeb 100644
--- a/src/dawn/native/d3d/PlatformFunctions.cpp
+++ b/src/dawn/native/d3d/PlatformFunctions.cpp
@@ -62,6 +62,7 @@
MaybeError PlatformFunctions::LoadFunctions() {
DAWN_TRY(LoadDXGI());
DAWN_TRY(LoadFXCompiler());
+ DAWN_TRY(LoadKernelBase());
InitWindowsVersion();
return {};
}
@@ -104,6 +105,19 @@
return {};
}
+MaybeError PlatformFunctions::LoadKernelBase() {
+#if DAWN_PLATFORM_IS(WINUWP)
+ compareObjectHandles = &CompareObjectHandles;
+#else
+ std::string error;
+ if (!mKernelBaseLib.Open("kernelbase.dll", &error) ||
+ !mKernelBaseLib.GetProc(&compareObjectHandles, "CompareObjectHandles", &error)) {
+ return DAWN_INTERNAL_ERROR(error.c_str());
+ }
+#endif
+ return {};
+}
+
void PlatformFunctions::InitWindowsVersion() {
// Currently we only care about the build number of Windows 10 and Windows 11.
if (!IsWindows10OrGreater()) {
diff --git a/src/dawn/native/d3d/PlatformFunctions.h b/src/dawn/native/d3d/PlatformFunctions.h
index e886f86..a8d3d14 100644
--- a/src/dawn/native/d3d/PlatformFunctions.h
+++ b/src/dawn/native/d3d/PlatformFunctions.h
@@ -64,13 +64,20 @@
pD3DCompile d3dCompile = nullptr;
pD3DDisassemble d3dDisassemble = nullptr;
+ // Functions from kernelbase.dll
+ using PFN_COMPARE_OBJECT_HANDLES = BOOL(WINAPI*)(HANDLE hFirstObjectHandle,
+ HANDLE hSecondObjectHandle);
+ PFN_COMPARE_OBJECT_HANDLES compareObjectHandles = nullptr;
+
private:
MaybeError LoadDXGI();
MaybeError LoadFXCompiler();
+ MaybeError LoadKernelBase();
void InitWindowsVersion();
DynamicLib mDXGILib;
DynamicLib mFXCompilerLib;
+ DynamicLib mKernelBaseLib;
uint64_t mCurrentBuildNumber;
};
diff --git a/src/dawn/native/d3d/SharedFenceD3D.h b/src/dawn/native/d3d/SharedFenceD3D.h
index 822598e..8287413 100644
--- a/src/dawn/native/d3d/SharedFenceD3D.h
+++ b/src/dawn/native/d3d/SharedFenceD3D.h
@@ -41,6 +41,8 @@
// TODO(sunnyps): Remove after ExternalImageDXGIImpl is gone.
HANDLE GetFenceHandle() const;
+ const SystemHandle& GetSystemHandle() const { return mHandle; }
+
protected:
SharedFence(Device* device, StringView label, SystemHandle ownedHandle);
diff --git a/src/dawn/native/d3d11/QueueD3D11.h b/src/dawn/native/d3d11/QueueD3D11.h
index 3f2c8d1..de88f1d 100644
--- a/src/dawn/native/d3d11/QueueD3D11.h
+++ b/src/dawn/native/d3d11/QueueD3D11.h
@@ -58,6 +58,8 @@
wgpu::MapMode mode,
ExecutionSerial readySerial);
+ const Ref<SharedFence>& GetSharedFence() const { return mSharedFence; }
+
protected:
using d3d::Queue::Queue;
diff --git a/src/dawn/native/d3d11/SharedFenceD3D11.cpp b/src/dawn/native/d3d11/SharedFenceD3D11.cpp
index 127e9b0..88df9a5 100644
--- a/src/dawn/native/d3d11/SharedFenceD3D11.cpp
+++ b/src/dawn/native/d3d11/SharedFenceD3D11.cpp
@@ -30,10 +30,23 @@
#include <utility>
#include "dawn/native/d3d/D3DError.h"
+#include "dawn/native/d3d/PlatformFunctions.h"
#include "dawn/native/d3d11/DeviceD3D11.h"
+#include "dawn/native/d3d11/QueueD3D11.h"
namespace dawn::native::d3d11 {
+namespace {
+bool IsSameHandle(DeviceBase* device, HANDLE handle, HANDLE other) {
+ if (handle == other) {
+ return true;
+ }
+
+ auto deviceD3D11 = ToBackend(device);
+ return deviceD3D11->GetFunctions()->compareObjectHandles(handle, other);
+}
+} // namespace
+
// static
ResultOrError<Ref<SharedFence>> SharedFence::Create(
Device* device,
@@ -41,6 +54,12 @@
const SharedFenceDXGISharedHandleDescriptor* descriptor) {
DAWN_INVALID_IF(descriptor->handle == nullptr, "shared HANDLE is missing.");
+ const auto& queueFence = ToBackend(device->GetQueue())->GetSharedFence();
+ if (queueFence &&
+ IsSameHandle(device, queueFence->GetSystemHandle().Get(), descriptor->handle)) {
+ return queueFence;
+ }
+
SystemHandle ownedHandle;
DAWN_TRY_ASSIGN(ownedHandle, SystemHandle::Duplicate(descriptor->handle));
diff --git a/src/dawn/native/d3d11/TextureD3D11.cpp b/src/dawn/native/d3d11/TextureD3D11.cpp
index 09d0019..9e70da5 100644
--- a/src/dawn/native/d3d11/TextureD3D11.cpp
+++ b/src/dawn/native/d3d11/TextureD3D11.cpp
@@ -420,12 +420,21 @@
MaybeError Texture::SynchronizeTextureBeforeUse(
const ScopedCommandRecordingContext* commandContext) {
if (auto* contents = GetSharedResourceMemoryContents()) {
+ const auto& queueFence = ToBackend(GetDevice()->GetQueue())->GetSharedFence();
+
SharedTextureMemoryBase::PendingFenceList fences;
contents->AcquirePendingFences(&fences);
for (const auto& fence : fences) {
- DAWN_TRY(CheckHRESULT(
- commandContext->Wait(ToBackend(fence.object)->GetD3DFence(), fence.signaledValue),
- "ID3D11DeviceContext4::Wait"));
+ auto d3dFence = ToBackend(fence.object);
+ if (d3dFence.Get() == queueFence.Get()) {
+ // We don't need to wait on the fence that we signaled (self-wait).
+ DAWN_ASSERT(ExecutionSerial(fence.signaledValue) <=
+ GetDevice()->GetQueue()->GetLastSubmittedCommandSerial());
+ continue;
+ }
+ DAWN_TRY(
+ CheckHRESULT(commandContext->Wait(d3dFence->GetD3DFence(), fence.signaledValue),
+ "ID3D11DeviceContext4::Wait"));
}
commandContext->SetNeedsFence();
}