Revert "D3D12: Move ExecutionQueue logic to the Queue."
This reverts commit a3dc7f4aff1c0c06046697a3531d175c63040067.
Reason for revert: Fails in CI only test suites.
Original change's description:
> D3D12: Move ExecutionQueue logic to the Queue.
>
> No functional changes intended but the Queue methods have been made to
> do slightly more than the equivalent methods on the device (for example
> checking if we actually need to do a wait or a submission).
>
> Bug: dawn:1413
> Change-Id: I56e1f3b996487e79aceeccb78aa5a2f676902f47
> Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/140401
> Kokoro: Kokoro <noreply+kokoro@google.com>
> Reviewed-by: Austin Eng <enga@chromium.org>
> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
> Reviewed-by: Loko Kung <lokokung@google.com>
TBR=cwallez@chromium.org,enga@chromium.org,noreply+kokoro@google.com,dawn-scoped@luci-project-accounts.iam.gserviceaccount.com,lokokung@google.com
Change-Id: I2c1dde3bb098b2fa710adb0db84554b10ccaa2c6
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: dawn:1413
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/165660
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
Kokoro: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/d3d12/CommandAllocatorManager.cpp b/src/dawn/native/d3d12/CommandAllocatorManager.cpp
index f3cd0ac..09e144b 100644
--- a/src/dawn/native/d3d12/CommandAllocatorManager.cpp
+++ b/src/dawn/native/d3d12/CommandAllocatorManager.cpp
@@ -29,14 +29,14 @@
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
-#include "dawn/native/d3d12/QueueD3D12.h"
#include "dawn/common/Assert.h"
#include "dawn/common/BitSetIterator.h"
namespace dawn::native::d3d12 {
-CommandAllocatorManager::CommandAllocatorManager(Queue* queue) : mQueue(queue), mAllocatorCount(0) {
+CommandAllocatorManager::CommandAllocatorManager(Device* device)
+ : device(device), mAllocatorCount(0) {
mFreeAllocators.set();
}
@@ -44,7 +44,7 @@
// If there are no free allocators, get the oldest serial in flight and wait on it
if (mFreeAllocators.none()) {
const ExecutionSerial firstSerial = mInFlightCommandAllocators.FirstSerial();
- DAWN_TRY(mQueue->WaitForSerial(firstSerial));
+ DAWN_TRY(device->WaitForSerial(firstSerial));
DAWN_TRY(Tick(firstSerial));
}
@@ -56,11 +56,9 @@
if (firstFreeIndex >= mAllocatorCount) {
DAWN_ASSERT(firstFreeIndex == mAllocatorCount);
mAllocatorCount++;
-
- ID3D12Device* d3d12Device = ToBackend(mQueue->GetDevice())->GetD3D12Device();
DAWN_TRY(CheckHRESULT(
- d3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
- IID_PPV_ARGS(&mCommandAllocators[firstFreeIndex])),
+ device->GetD3D12Device()->CreateCommandAllocator(
+ D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mCommandAllocators[firstFreeIndex])),
"D3D12 create command allocator"));
}
@@ -70,7 +68,7 @@
// Enqueue the command allocator. It will be scheduled for reset after the next
// ExecuteCommandLists
mInFlightCommandAllocators.Enqueue({mCommandAllocators[firstFreeIndex], firstFreeIndex},
- mQueue->GetPendingCommandSerial());
+ device->GetPendingCommandSerial());
return mCommandAllocators[firstFreeIndex].Get();
}
diff --git a/src/dawn/native/d3d12/CommandAllocatorManager.h b/src/dawn/native/d3d12/CommandAllocatorManager.h
index b0a29ed..f8e9d0d 100644
--- a/src/dawn/native/d3d12/CommandAllocatorManager.h
+++ b/src/dawn/native/d3d12/CommandAllocatorManager.h
@@ -38,11 +38,11 @@
namespace dawn::native::d3d12 {
-class Queue;
+class Device;
class CommandAllocatorManager {
public:
- explicit CommandAllocatorManager(Queue* queue);
+ explicit CommandAllocatorManager(Device* device);
// A CommandAllocator that is reserved must be used on the next ExecuteCommandLists
// otherwise its commands may be reset before execution has completed on the GPU
@@ -50,8 +50,7 @@
MaybeError Tick(ExecutionSerial lastCompletedSerial);
private:
- // The allocator manager is owned by the queue so the queue outlives it.
- Queue* mQueue;
+ Device* device;
// This must be at least 2 because the Device and Queue use separate command allocators
static constexpr unsigned int kMaxCommandAllocators = 32;
diff --git a/src/dawn/native/d3d12/CommandRecordingContext.cpp b/src/dawn/native/d3d12/CommandRecordingContext.cpp
index ba2b37b..6f88e28 100644
--- a/src/dawn/native/d3d12/CommandRecordingContext.cpp
+++ b/src/dawn/native/d3d12/CommandRecordingContext.cpp
@@ -78,73 +78,70 @@
return {};
}
-MaybeError CommandRecordingContext::ExecuteCommandList(Device* device,
- ID3D12CommandQueue* commandQueue) {
- if (!IsOpen()) {
- return {};
+MaybeError CommandRecordingContext::ExecuteCommandList(Device* device) {
+ if (IsOpen()) {
+ for (Texture* texture : mSharedTextures) {
+ DAWN_TRY(texture->SynchronizeImportedTextureBeforeUse());
+ }
+
+ MaybeError error =
+ CheckHRESULT(mD3d12CommandList->Close(), "D3D12 closing pending command list");
+ if (error.IsError()) {
+ Release();
+ DAWN_TRY(std::move(error));
+ }
+ DAWN_TRY(device->GetResidencyManager()->EnsureHeapsAreResident(mHeapsPendingUsage.data(),
+ mHeapsPendingUsage.size()));
+
+ if (device->IsToggleEnabled(Toggle::RecordDetailedTimingInTraceEvents)) {
+ uint64_t gpuTimestamp;
+ uint64_t cpuTimestamp;
+ FILETIME fileTimeNonPrecise;
+ SYSTEMTIME systemTimeNonPrecise;
+
+ // Both supported since Windows 2000, have a accuracy of 1ms
+ GetSystemTimeAsFileTime(&fileTimeNonPrecise);
+ GetSystemTime(&systemTimeNonPrecise);
+ // Query CPU and GPU timestamps at almost the same time
+ device->GetCommandQueue()->GetClockCalibration(&gpuTimestamp, &cpuTimestamp);
+
+ uint64_t gpuFrequency;
+ uint64_t cpuFrequency;
+ LARGE_INTEGER cpuFrequencyLargeInteger;
+ device->GetCommandQueue()->GetTimestampFrequency(&gpuFrequency);
+ QueryPerformanceFrequency(&cpuFrequencyLargeInteger); // Supported since Windows 2000
+ cpuFrequency = cpuFrequencyLargeInteger.QuadPart;
+
+ std::string timingInfo = absl::StrFormat(
+ "UTC Time: %u/%u/%u %02u:%02u:%02u.%03u, File Time: %u, CPU "
+ "Timestamp: %u, GPU Timestamp: %u, CPU Tick Frequency: %u, GPU Tick Frequency: "
+ "%u",
+ systemTimeNonPrecise.wYear, systemTimeNonPrecise.wMonth, systemTimeNonPrecise.wDay,
+ systemTimeNonPrecise.wHour, systemTimeNonPrecise.wMinute,
+ systemTimeNonPrecise.wSecond, systemTimeNonPrecise.wMilliseconds,
+ (static_cast<uint64_t>(fileTimeNonPrecise.dwHighDateTime) << 32) +
+ fileTimeNonPrecise.dwLowDateTime,
+ cpuTimestamp, gpuTimestamp, cpuFrequency, gpuFrequency);
+
+ TRACE_EVENT_INSTANT1(
+ device->GetPlatform(), General,
+ "d3d12::CommandRecordingContext::ExecuteCommandList Detailed Timing", "Timing",
+ timingInfo.c_str());
+ }
+
+ ID3D12CommandList* d3d12CommandList = GetCommandList();
+ device->GetCommandQueue()->ExecuteCommandLists(1, &d3d12CommandList);
+
+ for (Texture* texture : mSharedTextures) {
+ DAWN_TRY(texture->SynchronizeImportedTextureAfterUse());
+ }
+
+ mIsOpen = false;
+ mNeedsSubmit = false;
+ mSharedTextures.clear();
+ mHeapsPendingUsage.clear();
+ mTempBuffers.clear();
}
-
- for (Texture* texture : mSharedTextures) {
- DAWN_TRY(texture->SynchronizeImportedTextureBeforeUse());
- }
-
- MaybeError error =
- CheckHRESULT(mD3d12CommandList->Close(), "D3D12 closing pending command list");
- if (error.IsError()) {
- Release();
- DAWN_TRY(std::move(error));
- }
- DAWN_TRY(device->GetResidencyManager()->EnsureHeapsAreResident(mHeapsPendingUsage.data(),
- mHeapsPendingUsage.size()));
-
- if (device->IsToggleEnabled(Toggle::RecordDetailedTimingInTraceEvents)) {
- uint64_t gpuTimestamp;
- uint64_t cpuTimestamp;
- FILETIME fileTimeNonPrecise;
- SYSTEMTIME systemTimeNonPrecise;
-
- // Both supported since Windows 2000, have a accuracy of 1ms
- GetSystemTimeAsFileTime(&fileTimeNonPrecise);
- GetSystemTime(&systemTimeNonPrecise);
- // Query CPU and GPU timestamps at almost the same time
- commandQueue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp);
-
- uint64_t gpuFrequency;
- uint64_t cpuFrequency;
- LARGE_INTEGER cpuFrequencyLargeInteger;
- commandQueue->GetTimestampFrequency(&gpuFrequency);
- QueryPerformanceFrequency(&cpuFrequencyLargeInteger); // Supported since Windows 2000
- cpuFrequency = cpuFrequencyLargeInteger.QuadPart;
-
- std::string timingInfo = absl::StrFormat(
- "UTC Time: %u/%u/%u %02u:%02u:%02u.%03u, File Time: %u, CPU "
- "Timestamp: %u, GPU Timestamp: %u, CPU Tick Frequency: %u, GPU Tick Frequency: "
- "%u",
- systemTimeNonPrecise.wYear, systemTimeNonPrecise.wMonth, systemTimeNonPrecise.wDay,
- systemTimeNonPrecise.wHour, systemTimeNonPrecise.wMinute, systemTimeNonPrecise.wSecond,
- systemTimeNonPrecise.wMilliseconds,
- (static_cast<uint64_t>(fileTimeNonPrecise.dwHighDateTime) << 32) +
- fileTimeNonPrecise.dwLowDateTime,
- cpuTimestamp, gpuTimestamp, cpuFrequency, gpuFrequency);
-
- TRACE_EVENT_INSTANT1(device->GetPlatform(), General,
- "d3d12::CommandRecordingContext::ExecuteCommandList Detailed Timing",
- "Timing", timingInfo.c_str());
- }
-
- ID3D12CommandList* d3d12CommandList = GetCommandList();
- commandQueue->ExecuteCommandLists(1, &d3d12CommandList);
-
- for (Texture* texture : mSharedTextures) {
- DAWN_TRY(texture->SynchronizeImportedTextureAfterUse());
- }
-
- mIsOpen = false;
- mNeedsSubmit = false;
- mSharedTextures.clear();
- mHeapsPendingUsage.clear();
- mTempBuffers.clear();
-
return {};
}
diff --git a/src/dawn/native/d3d12/CommandRecordingContext.h b/src/dawn/native/d3d12/CommandRecordingContext.h
index 1ba4d47..1778813 100644
--- a/src/dawn/native/d3d12/CommandRecordingContext.h
+++ b/src/dawn/native/d3d12/CommandRecordingContext.h
@@ -53,7 +53,7 @@
bool NeedsSubmit() const;
void SetNeedsSubmit();
- MaybeError ExecuteCommandList(Device* device, ID3D12CommandQueue* commandQueue);
+ MaybeError ExecuteCommandList(Device* device);
void TrackHeapUsage(Heap* heap, ExecutionSerial serial);
diff --git a/src/dawn/native/d3d12/DeviceD3D12.cpp b/src/dawn/native/d3d12/DeviceD3D12.cpp
index ba296c6..90e448f 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/DeviceD3D12.cpp
@@ -91,8 +91,13 @@
DAWN_ASSERT(mD3d12Device != nullptr);
- Ref<Queue> queue;
- DAWN_TRY_ASSIGN(queue, Queue::Create(this, &descriptor->defaultQueue));
+ // Create device-global objects
+ D3D12_COMMAND_QUEUE_DESC queueDesc = {};
+ queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+ queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+ DAWN_TRY(
+ CheckHRESULT(mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)),
+ "D3D12 create command queue"));
if ((HasFeature(Feature::TimestampQuery) ||
HasFeature(Feature::ChromiumExperimentalTimestampQueryInsidePasses)) &&
@@ -102,18 +107,30 @@
// always support timestamps except where there are bugs in Windows container and vGPU
// implementations.
uint64_t frequency;
- DAWN_TRY(CheckHRESULT(queue->GetCommandQueue()->GetTimestampFrequency(&frequency),
+ DAWN_TRY(CheckHRESULT(mCommandQueue->GetTimestampFrequency(&frequency),
"D3D12 get timestamp frequency"));
// Calculate the period in nanoseconds by the frequency.
mTimestampPeriod = static_cast<float>(1e9) / frequency;
}
- DAWN_TRY(CheckHRESULT(mD3d12Device->CreateSharedHandle(queue->GetFence(), nullptr, GENERIC_ALL,
+ // If PIX is not attached, the QueryInterface fails. Hence, no need to check the return
+ // value.
+ mCommandQueue.As(&mD3d12SharingContract);
+
+ DAWN_TRY(CheckHRESULT(mD3d12Device->CreateFence(uint64_t(kBeginningOfGPUTime),
+ D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&mFence)),
+ "D3D12 create fence"));
+
+ mFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
+ DAWN_ASSERT(mFenceEvent != nullptr);
+
+ DAWN_TRY(CheckHRESULT(mD3d12Device->CreateSharedHandle(mFence.Get(), nullptr, GENERIC_ALL,
nullptr, &mFenceHandle),
"D3D12 create fence handle"));
DAWN_ASSERT(mFenceHandle != nullptr);
// Initialize backend services
+ mCommandAllocatorManager = std::make_unique<CommandAllocatorManager>(this);
// Zero sized allocator is never requested and does not need to exist.
for (uint32_t countIndex = 0; countIndex < kNumViewDescriptorAllocators; countIndex++) {
@@ -174,7 +191,10 @@
GetD3D12Device()->CreateCommandSignature(&programDesc, nullptr,
IID_PPV_ARGS(&mDrawIndexedIndirectSignature));
- DAWN_TRY(DeviceBase::Initialize(std::move(queue)));
+ DAWN_TRY(DeviceBase::Initialize(Queue::Create(this, &descriptor->defaultQueue)));
+ // Device shouldn't be used until after DeviceBase::Initialize so we must wait until after
+ // device initialization to call NextSerial
+ DAWN_TRY(NextSerial());
// Ensure DXC if use_dxc toggle is set.
DAWN_TRY(EnsureDXCIfRequired());
@@ -197,6 +217,18 @@
return mD3d12Device.Get();
}
+ID3D12Fence* Device::GetD3D12Fence() const {
+ return mFence.Get();
+}
+
+ComPtr<ID3D12CommandQueue> Device::GetCommandQueue() const {
+ return mCommandQueue;
+}
+
+ID3D12SharingContract* Device::GetSharingContract() const {
+ return mD3d12SharingContract.Get();
+}
+
ComPtr<ID3D12CommandSignature> Device::GetDispatchIndirectSignature() const {
return mDispatchIndirectSignature;
}
@@ -225,14 +257,25 @@
return ToBackend(GetPhysicalDevice())->GetBackend()->GetFunctions();
}
+CommandAllocatorManager* Device::GetCommandAllocatorManager() const {
+ return mCommandAllocatorManager.get();
+}
+
MutexProtected<ResidencyManager>& Device::GetResidencyManager() const {
return *mResidencyManager;
}
ResultOrError<CommandRecordingContext*> Device::GetPendingCommandContext(
Device::SubmitMode submitMode) {
- // TODO(dawn:1413): Make callers of this method use the queue directly.
- return ToBackend(GetQueue())->GetPendingCommandContext(submitMode);
+ // Callers of GetPendingCommandList do so to record commands. Only reserve a command
+ // allocator when it is needed so we don't submit empty command lists
+ if (!mPendingCommands.IsOpen()) {
+ DAWN_TRY(mPendingCommands.Open(mD3d12Device.Get(), mCommandAllocatorManager.get()));
+ }
+ if (submitMode == Device::SubmitMode::Normal) {
+ mPendingCommands.SetNeedsSubmit();
+ }
+ return &mPendingCommands;
}
MaybeError Device::CreateZeroBuffer() {
@@ -291,23 +334,83 @@
ExecutionSerial completedSerial = GetQueue()->GetCompletedCommandSerial();
(*mResourceAllocatorManager)->Tick(completedSerial);
+ DAWN_TRY(mCommandAllocatorManager->Tick(completedSerial));
(*mViewShaderVisibleDescriptorAllocator)->Tick(completedSerial);
(*mSamplerShaderVisibleDescriptorAllocator)->Tick(completedSerial);
(*mRenderTargetViewAllocator)->Tick(completedSerial);
(*mDepthStencilViewAllocator)->Tick(completedSerial);
mUsedComObjectRefs->ClearUpTo(completedSerial);
- DAWN_TRY(ToBackend(GetQueue())->SubmitPendingCommands());
+ if (mPendingCommands.IsOpen() && mPendingCommands.NeedsSubmit()) {
+ DAWN_TRY(ExecutePendingCommandContext());
+ DAWN_TRY(NextSerial());
+ }
DAWN_TRY(CheckDebugLayerAndGenerateErrors());
return {};
}
+MaybeError Device::NextSerial() {
+ GetQueue()->IncrementLastSubmittedCommandSerial();
+
+ TRACE_EVENT1(GetPlatform(), General, "D3D12Device::SignalFence", "serial",
+ uint64_t(GetLastSubmittedCommandSerial()));
+
+ return CheckHRESULT(
+ mCommandQueue->Signal(mFence.Get(), uint64_t(GetLastSubmittedCommandSerial())),
+ "D3D12 command queue signal fence");
+}
+
+MaybeError Device::WaitForSerial(ExecutionSerial serial) {
+ DAWN_TRY(GetQueue()->CheckPassedSerials());
+ if (GetQueue()->GetCompletedCommandSerial() < serial) {
+ DAWN_TRY(CheckHRESULT(mFence->SetEventOnCompletion(uint64_t(serial), mFenceEvent),
+ "D3D12 set event on completion"));
+ WaitForSingleObject(mFenceEvent, INFINITE);
+ DAWN_TRY(GetQueue()->CheckPassedSerials());
+ }
+ return {};
+}
+
+ResultOrError<ExecutionSerial> Device::CheckAndUpdateCompletedSerials() {
+ ExecutionSerial completedSerial = ExecutionSerial(mFence->GetCompletedValue());
+ if (DAWN_UNLIKELY(completedSerial == ExecutionSerial(UINT64_MAX))) {
+ // GetCompletedValue returns UINT64_MAX if the device was removed.
+ // Try to query the failure reason.
+ DAWN_TRY(CheckHRESULT(mD3d12Device->GetDeviceRemovedReason(),
+ "ID3D12Device::GetDeviceRemovedReason"));
+ // Otherwise, return a generic device lost error.
+ return DAWN_DEVICE_LOST_ERROR("Device lost");
+ }
+
+ if (completedSerial <= GetQueue()->GetCompletedCommandSerial()) {
+ return ExecutionSerial(0);
+ }
+
+ return completedSerial;
+}
+
void Device::ReferenceUntilUnused(ComPtr<IUnknown> object) {
mUsedComObjectRefs->Enqueue(std::move(object), GetPendingCommandSerial());
}
+bool Device::HasPendingCommands() const {
+ return mPendingCommands.NeedsSubmit();
+}
+
+void Device::ForceEventualFlushOfCommands() {
+ if (mPendingCommands.IsOpen()) {
+ mPendingCommands.SetNeedsSubmit();
+ }
+}
+
+MaybeError Device::ExecutePendingCommandContext() {
+ DAWN_ASSERT(IsLockedByCurrentThreadIfNeeded());
+
+ return mPendingCommands.ExecuteCommandList(this);
+}
+
ResultOrError<Ref<BindGroupBase>> Device::CreateBindGroupImpl(
const BindGroupDescriptor* descriptor) {
return BindGroup::Create(this, descriptor);
@@ -562,6 +665,17 @@
return ToBackend(GetPhysicalDevice())->GetDeviceInfo();
}
+MaybeError Device::WaitForIdleForDestruction() {
+ // Immediately forget about all pending commands
+ mPendingCommands.Release();
+
+ DAWN_TRY(NextSerial());
+ // Wait for all in-flight commands to finish executing
+ DAWN_TRY(WaitForSerial(GetLastSubmittedCommandSerial()));
+
+ return {};
+}
+
void AppendDebugLayerMessagesToError(ID3D12InfoQueue* infoQueue,
uint64_t totalErrors,
ErrorData* error) {
@@ -666,6 +780,14 @@
mZeroBuffer = nullptr;
+ // Immediately forget about all pending commands for the case where device is lost on its
+ // own and WaitForIdleForDestruction isn't called.
+ mPendingCommands.Release();
+
+ if (mFenceEvent != nullptr) {
+ ::CloseHandle(mFenceEvent);
+ }
+
// Release recycled resource heaps and all other objects waiting for deletion in the resource
// allocation manager.
mResourceAllocatorManager.reset();
@@ -674,6 +796,11 @@
mUsedComObjectRefs->ClearUpTo(std::numeric_limits<ExecutionSerial>::max());
DAWN_ASSERT(mUsedComObjectRefs->Empty());
+ DAWN_ASSERT(!mPendingCommands.IsOpen());
+
+ // Now that we've cleared out pending work from the queue, we can safely release it and reclaim
+ // memory.
+ mCommandQueue.Reset();
}
MutexProtected<ShaderVisibleDescriptorAllocator>& Device::GetViewShaderVisibleDescriptorAllocator()
diff --git a/src/dawn/native/d3d12/DeviceD3D12.h b/src/dawn/native/d3d12/DeviceD3D12.h
index edf0c8d..810e5ea 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.h
+++ b/src/dawn/native/d3d12/DeviceD3D12.h
@@ -76,11 +76,15 @@
MaybeError TickImpl() override;
ID3D12Device* GetD3D12Device() const;
+ ID3D12Fence* GetD3D12Fence() const;
+ ComPtr<ID3D12CommandQueue> GetCommandQueue() const;
+ ID3D12SharingContract* GetSharingContract() const;
ComPtr<ID3D12CommandSignature> GetDispatchIndirectSignature() const;
ComPtr<ID3D12CommandSignature> GetDrawIndirectSignature() const;
ComPtr<ID3D12CommandSignature> GetDrawIndexedIndirectSignature() const;
+ CommandAllocatorManager* GetCommandAllocatorManager() const;
MutexProtected<ResidencyManager>& GetResidencyManager() const;
const PlatformFunctions* GetFunctions() const;
@@ -95,8 +99,13 @@
const D3D12DeviceInfo& GetDeviceInfo() const;
+ MaybeError NextSerial();
+ MaybeError WaitForSerial(ExecutionSerial serial);
+
void ReferenceUntilUnused(ComPtr<IUnknown> object);
+ MaybeError ExecutePendingCommandContext();
+
MaybeError CopyFromStagingToBufferImpl(BufferBase* source,
uint64_t sourceOffset,
BufferBase* destination,
@@ -171,6 +180,12 @@
// Dawn APIs
void SetLabelImpl() override;
+ // TODO(dawn:1413) move these methods to the d3d12::Queue.
+ void ForceEventualFlushOfCommands();
+ bool HasPendingCommands() const;
+ ResultOrError<ExecutionSerial> CheckAndUpdateCompletedSerials();
+ MaybeError WaitForIdleForDestruction();
+
// Those DXC methods are needed by d3d12::ShaderModule
ComPtr<IDxcLibrary> GetDxcLibrary() const;
ComPtr<IDxcCompiler3> GetDxcCompiler() const;
@@ -231,14 +246,22 @@
MaybeError CreateZeroBuffer();
+ ComPtr<ID3D12Fence> mFence;
+ HANDLE mFenceEvent = nullptr;
+
ComPtr<ID3D12Device> mD3d12Device; // Device is owned by adapter and will not be outlived.
+ ComPtr<ID3D12CommandQueue> mCommandQueue;
+ ComPtr<ID3D12SharingContract> mD3d12SharingContract;
ComPtr<ID3D12CommandSignature> mDispatchIndirectSignature;
ComPtr<ID3D12CommandSignature> mDrawIndirectSignature;
ComPtr<ID3D12CommandSignature> mDrawIndexedIndirectSignature;
+ CommandRecordingContext mPendingCommands;
+
MutexProtected<SerialQueue<ExecutionSerial, ComPtr<IUnknown>>> mUsedComObjectRefs;
+ std::unique_ptr<CommandAllocatorManager> mCommandAllocatorManager;
std::unique_ptr<MutexProtected<ResourceAllocatorManager>> mResourceAllocatorManager;
std::unique_ptr<MutexProtected<ResidencyManager>> mResidencyManager;
diff --git a/src/dawn/native/d3d12/QueueD3D12.cpp b/src/dawn/native/d3d12/QueueD3D12.cpp
index 18ddf5c..4d2dc9f 100644
--- a/src/dawn/native/d3d12/QueueD3D12.cpp
+++ b/src/dawn/native/d3d12/QueueD3D12.cpp
@@ -34,7 +34,6 @@
#include "dawn/native/Commands.h"
#include "dawn/native/DynamicUploader.h"
#include "dawn/native/d3d/D3DError.h"
-#include "dawn/native/d3d12/CommandAllocatorManager.h"
#include "dawn/native/d3d12/CommandBufferD3D12.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
#include "dawn/native/d3d12/UtilsD3D12.h"
@@ -44,68 +43,21 @@
namespace dawn::native::d3d12 {
// static
-ResultOrError<Ref<Queue>> Queue::Create(Device* device, const QueueDescriptor* descriptor) {
+Ref<Queue> Queue::Create(Device* device, const QueueDescriptor* descriptor) {
Ref<Queue> queue = AcquireRef(new Queue(device, descriptor));
- DAWN_TRY(queue->Initialize());
+ queue->Initialize();
return queue;
}
-Queue::~Queue() {}
-
-MaybeError Queue::Initialize() {
+void Queue::Initialize() {
SetLabelImpl();
-
- ID3D12Device* d3d12Device = ToBackend(GetDevice())->GetD3D12Device();
-
- D3D12_COMMAND_QUEUE_DESC queueDesc = {};
- queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
- queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
- DAWN_TRY(CheckHRESULT(d3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)),
- "D3D12 create command queue"));
-
- // If PIX is not attached, the QueryInterface fails. Hence, no need to check the return
- // value.
- mCommandQueue.As(&mD3d12SharingContract);
-
- DAWN_TRY(CheckHRESULT(d3d12Device->CreateFence(uint64_t(kBeginningOfGPUTime),
- D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&mFence)),
- "D3D12 create fence"));
-
- mFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- DAWN_ASSERT(mFenceEvent != nullptr);
-
- // TODO(dawn:1413): Consider folding the command allocator manager in this class.
- mCommandAllocatorManager = std::make_unique<CommandAllocatorManager>(this);
- return {};
-}
-
-void Queue::Destroy() {
- // Immediately forget about all pending commands for the case where device is lost on its
- // own and WaitForIdleForDestruction isn't called.
- DAWN_ASSERT(!mPendingCommands.IsOpen());
- mPendingCommands.Release();
-
- if (mFenceEvent != nullptr) {
- ::CloseHandle(mFenceEvent);
- }
- mCommandQueue.Reset();
-}
-
-ID3D12Fence* Queue::GetFence() const {
- return mFence.Get();
-}
-
-ID3D12CommandQueue* Queue::GetCommandQueue() const {
- return mCommandQueue.Get();
-}
-
-ID3D12SharingContract* Queue::GetSharingContract() const {
- return mD3d12SharingContract.Get();
}
MaybeError Queue::SubmitImpl(uint32_t commandCount, CommandBufferBase* const* commands) {
+ Device* device = ToBackend(GetDevice());
+
CommandRecordingContext* commandContext;
- DAWN_TRY_ASSIGN(commandContext, GetPendingCommandContext());
+ DAWN_TRY_ASSIGN(commandContext, device->GetPendingCommandContext());
TRACE_EVENT_BEGIN1(GetDevice()->GetPlatform(), Recording, "CommandBufferD3D12::RecordCommands",
"serial", uint64_t(GetDevice()->GetPendingCommandSerial()));
@@ -115,111 +67,40 @@
TRACE_EVENT_END1(GetDevice()->GetPlatform(), Recording, "CommandBufferD3D12::RecordCommands",
"serial", uint64_t(GetDevice()->GetPendingCommandSerial()));
- return SubmitPendingCommands();
-}
+ DAWN_TRY(device->ExecutePendingCommandContext());
-MaybeError Queue::SubmitPendingCommands() {
- Device* device = ToBackend(GetDevice());
- DAWN_ASSERT(device->IsLockedByCurrentThreadIfNeeded());
+ DAWN_TRY(device->NextSerial());
- if (!mPendingCommands.IsOpen() || !mPendingCommands.NeedsSubmit()) {
- return {};
- }
-
- DAWN_TRY(mCommandAllocatorManager->Tick(GetCompletedCommandSerial()));
- DAWN_TRY(mPendingCommands.ExecuteCommandList(device, mCommandQueue.Get()););
- return NextSerial();
-}
-
-MaybeError Queue::NextSerial() {
- ForceEventualFlushOfCommands();
- DAWN_TRY(SubmitPendingCommands());
-
- IncrementLastSubmittedCommandSerial();
-
- TRACE_EVENT1(GetDevice()->GetPlatform(), General, "D3D12Device::SignalFence", "serial",
- uint64_t(GetLastSubmittedCommandSerial()));
-
- return CheckHRESULT(
- mCommandQueue->Signal(mFence.Get(), uint64_t(GetLastSubmittedCommandSerial())),
- "D3D12 command queue signal fence");
-}
-
-MaybeError Queue::WaitForSerial(ExecutionSerial serial) {
- if (GetCompletedCommandSerial() >= serial) {
- return {};
- }
- DAWN_TRY(CheckHRESULT(mFence->SetEventOnCompletion(uint64_t(serial), mFenceEvent),
- "D3D12 set event on completion"));
- WaitForSingleObject(mFenceEvent, INFINITE);
- DAWN_TRY(CheckPassedSerials());
return {};
}
bool Queue::HasPendingCommands() const {
- return mPendingCommands.NeedsSubmit();
+ return ToBackend(GetDevice())->HasPendingCommands();
}
ResultOrError<ExecutionSerial> Queue::CheckAndUpdateCompletedSerials() {
- ExecutionSerial completedSerial = ExecutionSerial(mFence->GetCompletedValue());
- if (DAWN_UNLIKELY(completedSerial == ExecutionSerial(UINT64_MAX))) {
- // GetCompletedValue returns UINT64_MAX if the device was removed.
- // Try to query the failure reason.
- ID3D12Device* d3d12Device = ToBackend(GetDevice())->GetD3D12Device();
- DAWN_TRY(CheckHRESULT(d3d12Device->GetDeviceRemovedReason(),
- "ID3D12Device::GetDeviceRemovedReason"));
- // Otherwise, return a generic device lost error.
- return DAWN_DEVICE_LOST_ERROR("Device lost");
- }
-
- if (completedSerial <= GetCompletedCommandSerial()) {
- return ExecutionSerial(0);
- }
-
- return completedSerial;
+ return ToBackend(GetDevice())->CheckAndUpdateCompletedSerials();
}
void Queue::ForceEventualFlushOfCommands() {
- if (mPendingCommands.IsOpen()) {
- mPendingCommands.SetNeedsSubmit();
- }
+ return ToBackend(GetDevice())->ForceEventualFlushOfCommands();
}
MaybeError Queue::WaitForIdleForDestruction() {
- // Immediately forget about all pending commands
- mPendingCommands.Release();
-
- DAWN_TRY(NextSerial());
- // Wait for all in-flight commands to finish executing
- DAWN_TRY(WaitForSerial(GetLastSubmittedCommandSerial()));
-
- return {};
-}
-
-ResultOrError<CommandRecordingContext*> Queue::GetPendingCommandContext(SubmitMode submitMode) {
- Device* device = ToBackend(GetDevice());
- ID3D12Device* d3d12Device = device->GetD3D12Device();
-
- // Callers of GetPendingCommandList do so to record commands. Only reserve a command
- // allocator when it is needed so we don't submit empty command lists
- if (!mPendingCommands.IsOpen()) {
- DAWN_TRY(mPendingCommands.Open(d3d12Device, mCommandAllocatorManager.get()));
- }
- if (submitMode == SubmitMode::Normal) {
- mPendingCommands.SetNeedsSubmit();
- }
- return &mPendingCommands;
+ return ToBackend(GetDevice())->WaitForIdleForDestruction();
}
void Queue::SetLabelImpl() {
Device* device = ToBackend(GetDevice());
// TODO(crbug.com/dawn/1344): When we start using multiple queues this needs to be adjusted
// so it doesn't always change the default queue's label.
- SetDebugName(device, mCommandQueue.Get(), "Dawn_Queue", GetLabel());
+ SetDebugName(device, device->GetCommandQueue().Get(), "Dawn_Queue", GetLabel());
}
void Queue::SetEventOnCompletion(ExecutionSerial serial, HANDLE event) {
- mFence->SetEventOnCompletion(static_cast<uint64_t>(serial), event);
+ ToBackend(GetDevice())
+ ->GetD3D12Fence()
+ ->SetEventOnCompletion(static_cast<uint64_t>(serial), event);
}
} // namespace dawn::native::d3d12
diff --git a/src/dawn/native/d3d12/QueueD3D12.h b/src/dawn/native/d3d12/QueueD3D12.h
index f545ee7..2d00586 100644
--- a/src/dawn/native/d3d12/QueueD3D12.h
+++ b/src/dawn/native/d3d12/QueueD3D12.h
@@ -28,8 +28,6 @@
#ifndef SRC_DAWN_NATIVE_D3D12_QUEUED3D12_H_
#define SRC_DAWN_NATIVE_D3D12_QUEUED3D12_H_
-#include <memory>
-
#include "dawn/common/MutexProtected.h"
#include "dawn/common/SerialMap.h"
#include "dawn/native/SystemEvent.h"
@@ -43,24 +41,12 @@
class Queue final : public d3d::Queue {
public:
- static ResultOrError<Ref<Queue>> Create(Device* device, const QueueDescriptor* descriptor);
-
- void Destroy();
-
- MaybeError NextSerial();
- MaybeError WaitForSerial(ExecutionSerial serial);
- ResultOrError<CommandRecordingContext*> GetPendingCommandContext(
- SubmitMode submitMode = SubmitMode::Normal);
- ID3D12Fence* GetFence() const;
- ID3D12CommandQueue* GetCommandQueue() const;
- ID3D12SharingContract* GetSharingContract() const;
- MaybeError SubmitPendingCommands();
+ static Ref<Queue> Create(Device* device, const QueueDescriptor* descriptor);
private:
using d3d::Queue::Queue;
- ~Queue() override;
- MaybeError Initialize();
+ void Initialize();
MaybeError SubmitImpl(uint32_t commandCount, CommandBufferBase* const* commands) override;
bool HasPendingCommands() const override;
@@ -72,15 +58,6 @@
// Dawn API
void SetLabelImpl() override;
-
- ComPtr<ID3D12Fence> mFence;
- HANDLE mFenceEvent = nullptr;
-
- CommandRecordingContext mPendingCommands;
- ComPtr<ID3D12CommandQueue> mCommandQueue;
- ComPtr<ID3D12SharingContract> mD3d12SharingContract;
-
- std::unique_ptr<CommandAllocatorManager> mCommandAllocatorManager;
};
} // namespace dawn::native::d3d12
diff --git a/src/dawn/native/d3d12/ResidencyManagerD3D12.cpp b/src/dawn/native/d3d12/ResidencyManagerD3D12.cpp
index b1b848e..c1b83b1 100644
--- a/src/dawn/native/d3d12/ResidencyManagerD3D12.cpp
+++ b/src/dawn/native/d3d12/ResidencyManagerD3D12.cpp
@@ -183,7 +183,9 @@
// We must ensure that any previous use of a resource has completed before the resource can
// be evicted.
- DAWN_TRY(ToBackend(mDevice->GetQueue())->WaitForSerial(lastSubmissionSerial));
+ if (lastSubmissionSerial > mDevice->GetQueue()->GetCompletedCommandSerial()) {
+ DAWN_TRY(mDevice->WaitForSerial(lastSubmissionSerial));
+ }
pageable->RemoveFromList();
return pageable;
diff --git a/src/dawn/native/d3d12/SwapChainD3D12.cpp b/src/dawn/native/d3d12/SwapChainD3D12.cpp
index 65c1d55..e5ae0f8 100644
--- a/src/dawn/native/d3d12/SwapChainD3D12.cpp
+++ b/src/dawn/native/d3d12/SwapChainD3D12.cpp
@@ -38,7 +38,6 @@
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d/UtilsD3D.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
-#include "dawn/native/d3d12/QueueD3D12.h"
#include "dawn/native/d3d12/TextureD3D12.h"
namespace dawn::native::d3d12 {
@@ -55,7 +54,7 @@
SwapChain::~SwapChain() = default;
IUnknown* SwapChain::GetD3DDeviceForCreatingSwapChain() {
- return ToBackend(GetDevice()->GetQueue())->GetCommandQueue();
+ return ToBackend(GetDevice())->GetCommandQueue().Get();
}
void SwapChain::ReuseBuffers(SwapChainBase* previousSwapChain) {
@@ -83,22 +82,22 @@
}
MaybeError SwapChain::PresentImpl() {
- Queue* queue = ToBackend(GetDevice()->GetQueue());
+ Device* device = ToBackend(GetDevice());
// Transition the texture to the present state as required by IDXGISwapChain1::Present()
// TODO(crbug.com/dawn/269): Remove the need for this by eagerly transitioning the
// presentable texture to present at the end of submits that use them.
CommandRecordingContext* commandContext;
- DAWN_TRY_ASSIGN(commandContext, queue->GetPendingCommandContext());
+ DAWN_TRY_ASSIGN(commandContext, device->GetPendingCommandContext());
mApiTexture->TrackUsageAndTransitionNow(commandContext, kPresentTextureUsage,
mApiTexture->GetAllSubresources());
- DAWN_TRY(queue->SubmitPendingCommands());
+ DAWN_TRY(device->ExecutePendingCommandContext());
DAWN_TRY(PresentDXGISwapChain());
// Record that "new" is the last time the buffer has been used.
- DAWN_TRY(queue->NextSerial());
- mBufferLastUsedSerials[mCurrentBuffer] = queue->GetPendingCommandSerial();
+ DAWN_TRY(device->NextSerial());
+ mBufferLastUsedSerials[mCurrentBuffer] = device->GetPendingCommandSerial();
mApiTexture->APIDestroy();
mApiTexture = nullptr;
@@ -107,14 +106,14 @@
}
ResultOrError<Ref<TextureBase>> SwapChain::GetCurrentTextureImpl() {
- Queue* queue = ToBackend(GetDevice()->GetQueue());
+ Device* device = ToBackend(GetDevice());
// Synchronously wait until previous operations on the next swapchain buffer are finished.
// This is the logic that performs frame pacing.
// TODO(crbug.com/dawn/269): Consider whether this should be lifted for Mailbox so that
// there is not frame pacing.
mCurrentBuffer = GetDXGISwapChain()->GetCurrentBackBufferIndex();
- DAWN_TRY(queue->WaitForSerial(mBufferLastUsedSerials[mCurrentBuffer]));
+ DAWN_TRY(device->WaitForSerial(mBufferLastUsedSerials[mCurrentBuffer]));
// Create the API side objects for this use of the swapchain's buffer.
TextureDescriptor descriptor = GetSwapChainBaseTextureDescriptor(this);
@@ -130,10 +129,10 @@
// SerialQueue with the current "pending serial" so that we don't destroy the texture
// before it is finished being used. Flush the commands and wait for that serial to be
// passed, then Tick the device to make sure the reference to the D3D12 texture is removed.
- Queue* queue = ToBackend(GetDevice()->GetQueue());
- DAWN_TRY(queue->NextSerial());
- DAWN_TRY(queue->WaitForSerial(queue->GetLastSubmittedCommandSerial()));
- return ToBackend(GetDevice())->TickImpl();
+ Device* device = ToBackend(GetDevice());
+ DAWN_TRY(device->NextSerial());
+ DAWN_TRY(device->WaitForSerial(device->GetLastSubmittedCommandSerial()));
+ return device->TickImpl();
}
void SwapChain::DetachFromSurfaceImpl() {
diff --git a/src/dawn/native/d3d12/TextureD3D12.cpp b/src/dawn/native/d3d12/TextureD3D12.cpp
index 8d1b810..c0e00ed 100644
--- a/src/dawn/native/d3d12/TextureD3D12.cpp
+++ b/src/dawn/native/d3d12/TextureD3D12.cpp
@@ -46,7 +46,6 @@
#include "dawn/native/d3d12/DeviceD3D12.h"
#include "dawn/native/d3d12/Forward.h"
#include "dawn/native/d3d12/HeapD3D12.h"
-#include "dawn/native/d3d12/QueueD3D12.h"
#include "dawn/native/d3d12/ResourceAllocatorManagerD3D12.h"
#include "dawn/native/d3d12/SharedFenceD3D12.h"
#include "dawn/native/d3d12/SharedTextureMemoryD3D12.h"
@@ -365,22 +364,23 @@
ResultOrError<ExecutionSerial> Texture::EndAccess() {
DAWN_ASSERT(mD3D12ResourceFlags & D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS);
- Queue* queue = ToBackend(GetDevice()->GetQueue());
-
+ Device* device = ToBackend(GetDevice());
// Synchronize if texture access wasn't synchronized already due to ExecuteCommandLists.
if (!mSignalFenceValue.has_value()) {
+ // Needed to ensure that command allocator doesn't get destroyed before pending commands
+ // are submitted due to calling NextSerial(). No-op if there are no pending commands.
+ DAWN_TRY(device->ExecutePendingCommandContext());
// If there were pending commands that used this texture mSignalFenceValue will be set,
// but if it's still not set, generate a signal fence after waiting on wait fences.
if (!mSignalFenceValue.has_value()) {
DAWN_TRY(SynchronizeImportedTextureBeforeUse());
DAWN_TRY(SynchronizeImportedTextureAfterUse());
}
- // Make the queue signal the fence in finite time.
- DAWN_TRY(queue->NextSerial());
+ DAWN_TRY(device->NextSerial());
+ DAWN_ASSERT(mSignalFenceValue.has_value());
}
-
ExecutionSerial ret = mSignalFenceValue.value();
- DAWN_ASSERT(ret <= queue->GetLastSubmittedCommandSerial());
+ DAWN_ASSERT(ret <= device->GetLastSubmittedCommandSerial());
// Explicitly call reset() since std::move() on optional doesn't make it std::nullopt.
mSignalFenceValue.reset();
return ret;
@@ -422,12 +422,11 @@
MaybeError Texture::SynchronizeImportedTextureBeforeUse() {
// Perform the wait only on the first call.
Device* device = ToBackend(GetDevice());
- ID3D12CommandQueue* commandQueue = ToBackend(device->GetQueue())->GetCommandQueue();
-
for (Ref<d3d::Fence>& fence : mWaitFences) {
- DAWN_TRY(CheckHRESULT(commandQueue->Wait(static_cast<Fence*>(fence.Get())->GetD3D12Fence(),
- fence->GetFenceValue()),
- "D3D12 fence wait"););
+ DAWN_TRY(CheckHRESULT(
+ device->GetCommandQueue()->Wait(
+ static_cast<Fence*>(fence.Get())->GetD3D12Fence(), fence->GetFenceValue()),
+ "D3D12 fence wait"););
// Keep D3D12 fence alive since we'll clear the waitFences list below.
device->ReferenceUntilUnused(static_cast<Fence*>(fence.Get())->GetD3D12Fence());
}
@@ -441,9 +440,9 @@
}
for (const auto& fence : fences) {
- DAWN_TRY(CheckHRESULT(
- commandQueue->Wait(ToBackend(fence.object)->GetD3DFence(), fence.signaledValue),
- "D3D12 fence wait"));
+ DAWN_TRY(CheckHRESULT(device->GetCommandQueue()->Wait(
+ ToBackend(fence.object)->GetD3DFence(), fence.signaledValue),
+ "D3D12 fence wait"));
// Keep D3D12 fence alive until commands complete.
device->ReferenceUntilUnused(ToBackend(fence.object)->GetD3DFence());
}
@@ -457,15 +456,15 @@
// If we know we're dealing with a swapbuffer texture, inform PIX we've
// "presented" the texture so it can determine frame boundaries and use its
// contents for the UI.
- Queue* queue = ToBackend(GetDevice()->GetQueue());
+ Device* device = ToBackend(GetDevice());
if (mSwapChainTexture) {
- ID3D12SharingContract* d3dSharingContract = queue->GetSharingContract();
+ ID3D12SharingContract* d3dSharingContract = device->GetSharingContract();
if (d3dSharingContract != nullptr) {
d3dSharingContract->Present(mResourceAllocation.GetD3D12Resource(), 0, 0);
}
}
// NextSerial() will be called after this - this is also checked in EndAccess().
- mSignalFenceValue = queue->GetPendingCommandSerial();
+ mSignalFenceValue = device->GetPendingCommandSerial();
return {};
}
diff --git a/src/dawn/tests/white_box/D3D12DescriptorHeapTests.cpp b/src/dawn/tests/white_box/D3D12DescriptorHeapTests.cpp
index 37eae0c..921a851 100644
--- a/src/dawn/tests/white_box/D3D12DescriptorHeapTests.cpp
+++ b/src/dawn/tests/white_box/D3D12DescriptorHeapTests.cpp
@@ -257,7 +257,7 @@
// CheckPassedSerials() will update the last internally completed serial.
EXPECT_TRUE(mD3DQueue->CheckPassedSerials().IsSuccess());
// NextSerial() will increment the last internally submitted serial.
- EXPECT_TRUE(mD3DQueue->NextSerial().IsSuccess());
+ EXPECT_TRUE(mD3DDevice->NextSerial().IsSuccess());
}
// Repeat up to |kFrameDepth| again but ensure heaps are the same in the expected order
@@ -269,7 +269,7 @@
EXPECT_TRUE(heaps.front() == heap);
heaps.pop_front();
EXPECT_TRUE(mD3DQueue->CheckPassedSerials().IsSuccess());
- EXPECT_TRUE(mD3DQueue->NextSerial().IsSuccess());
+ EXPECT_TRUE(mD3DDevice->NextSerial().IsSuccess());
}
EXPECT_TRUE(heaps.empty());
@@ -1064,7 +1064,7 @@
EXPECT_TRUE(gpuAllocator->IsAllocationStillValid(gpuHeapDescAllocation));
- EXPECT_TRUE(mD3DQueue->NextSerial().IsSuccess());
+ EXPECT_TRUE(d3dDevice->NextSerial().IsSuccess());
EXPECT_FALSE(gpuAllocator->IsAllocationStillValid(gpuHeapDescAllocation));
}
diff --git a/src/dawn/tests/white_box/GPUTimestampCalibrationTests_D3D12.cpp b/src/dawn/tests/white_box/GPUTimestampCalibrationTests_D3D12.cpp
index 07ca216..7df95ed 100644
--- a/src/dawn/tests/white_box/GPUTimestampCalibrationTests_D3D12.cpp
+++ b/src/dawn/tests/white_box/GPUTimestampCalibrationTests_D3D12.cpp
@@ -28,7 +28,6 @@
#include <memory>
#include "dawn/native/d3d12/DeviceD3D12.h"
-#include "dawn/native/d3d12/QueueD3D12.h"
#include "dawn/tests/white_box/GPUTimestampCalibrationTests.h"
namespace dawn {
@@ -38,20 +37,18 @@
public:
explicit GPUTimestampCalibrationTestsD3D12(const wgpu::Device& device) {
mBackendDevice = native::d3d12::ToBackend(native::FromAPI(device.Get()));
- mBackendQueue = native::d3d12::ToBackend(mBackendDevice->GetQueue());
}
bool IsSupported() const override { return true; }
void GetTimestampCalibration(uint64_t* gpuTimestamp, uint64_t* cpuTimestamp) override {
- mBackendQueue->GetCommandQueue()->GetClockCalibration(gpuTimestamp, cpuTimestamp);
+ mBackendDevice->GetCommandQueue()->GetClockCalibration(gpuTimestamp, cpuTimestamp);
}
float GetTimestampPeriod() const override { return mBackendDevice->GetTimestampPeriodInNS(); }
private:
native::d3d12::Device* mBackendDevice;
- native::d3d12::Queue* mBackendQueue;
};
} // anonymous namespace