Use typed integers for the ExecutionSerial

This will prevent mixing it up with other serial types in the future.

Bug: dawn:442
Change-Id: I74e964708acc62eb0f33127cc48f1b9a7b171d11
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28923
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Corentin Wallez 2020-09-28 19:35:14 +00:00 committed by Commit Bot service account
parent ad4a66ec8f
commit 62139fcca7
59 changed files with 204 additions and 217 deletions

View File

@ -172,7 +172,6 @@ if (is_win || is_linux || is_chromeos || is_mac || is_fuchsia || is_android) {
"RefCounted.h", "RefCounted.h",
"Result.cpp", "Result.cpp",
"Result.h", "Result.h",
"Serial.h",
"SerialMap.h", "SerialMap.h",
"SerialQueue.h", "SerialQueue.h",
"SerialStorage.h", "SerialStorage.h",

View File

@ -35,7 +35,6 @@ target_sources(dawn_common PRIVATE
"RefCounted.h" "RefCounted.h"
"Result.cpp" "Result.cpp"
"Result.h" "Result.h"
"Serial.h"
"SerialMap.h" "SerialMap.h"
"SerialQueue.h" "SerialQueue.h"
"SerialStorage.h" "SerialStorage.h"

View File

@ -1,22 +0,0 @@
// Copyright 2017 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 COMMON_SERIAL_H_
#define COMMON_SERIAL_H_
#include <cstdint>
using Serial = uint64_t;
#endif // COMMON_SERIAL_H_

View File

@ -16,7 +16,6 @@
#define COMMON_SERIALSTORAGE_H_ #define COMMON_SERIALSTORAGE_H_
#include "common/Assert.h" #include "common/Assert.h"
#include "common/Serial.h"
#include <cstdint> #include <cstdint>
#include <utility> #include <utility>

View File

@ -326,15 +326,15 @@ namespace dawn_native {
return mMapRequestTracker.get(); return mMapRequestTracker.get();
} }
Serial DeviceBase::GetCompletedCommandSerial() const { ExecutionSerial DeviceBase::GetCompletedCommandSerial() const {
return mCompletedSerial; return mCompletedSerial;
} }
Serial DeviceBase::GetLastSubmittedCommandSerial() const { ExecutionSerial DeviceBase::GetLastSubmittedCommandSerial() const {
return mLastSubmittedSerial; return mLastSubmittedSerial;
} }
Serial DeviceBase::GetFutureCallbackSerial() const { ExecutionSerial DeviceBase::GetFutureCallbackSerial() const {
return mFutureCallbackSerial; return mFutureCallbackSerial;
} }
@ -343,28 +343,29 @@ namespace dawn_native {
} }
void DeviceBase::AssumeCommandsComplete() { void DeviceBase::AssumeCommandsComplete() {
Serial maxSerial = std::max(mLastSubmittedSerial + 1, mFutureCallbackSerial); ExecutionSerial maxSerial = ExecutionSerial(
std::max(mLastSubmittedSerial + ExecutionSerial(1), mFutureCallbackSerial));
mLastSubmittedSerial = maxSerial; mLastSubmittedSerial = maxSerial;
mCompletedSerial = maxSerial; mCompletedSerial = maxSerial;
} }
Serial DeviceBase::GetPendingCommandSerial() const { ExecutionSerial DeviceBase::GetPendingCommandSerial() const {
return mLastSubmittedSerial + 1; return mLastSubmittedSerial + ExecutionSerial(1);
} }
void DeviceBase::AddFutureCallbackSerial(Serial serial) { void DeviceBase::AddFutureCallbackSerial(ExecutionSerial serial) {
if (serial > mFutureCallbackSerial) { if (serial > mFutureCallbackSerial) {
mFutureCallbackSerial = serial; mFutureCallbackSerial = serial;
} }
} }
void DeviceBase::CheckPassedSerials() { void DeviceBase::CheckPassedSerials() {
Serial completedSerial = CheckAndUpdateCompletedSerials(); ExecutionSerial completedSerial = CheckAndUpdateCompletedSerials();
ASSERT(completedSerial <= mLastSubmittedSerial); ASSERT(completedSerial <= mLastSubmittedSerial);
// completedSerial should not be less than mCompletedSerial unless it is 0. // completedSerial should not be less than mCompletedSerial unless it is 0.
// It can be 0 when there's no fences to check. // It can be 0 when there's no fences to check.
ASSERT(completedSerial >= mCompletedSerial || completedSerial == 0); ASSERT(completedSerial >= mCompletedSerial || completedSerial == ExecutionSerial(0));
if (completedSerial > mCompletedSerial) { if (completedSerial > mCompletedSerial) {
mCompletedSerial = completedSerial; mCompletedSerial = completedSerial;

View File

@ -15,7 +15,6 @@
#ifndef DAWNNATIVE_DEVICE_H_ #ifndef DAWNNATIVE_DEVICE_H_
#define DAWNNATIVE_DEVICE_H_ #define DAWNNATIVE_DEVICE_H_
#include "common/Serial.h"
#include "dawn_native/Commands.h" #include "dawn_native/Commands.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/Extensions.h" #include "dawn_native/Extensions.h"
@ -89,10 +88,10 @@ namespace dawn_native {
CommandEncoder* encoder, CommandEncoder* encoder,
const CommandBufferDescriptor* descriptor) = 0; const CommandBufferDescriptor* descriptor) = 0;
Serial GetCompletedCommandSerial() const; ExecutionSerial GetCompletedCommandSerial() const;
Serial GetLastSubmittedCommandSerial() const; ExecutionSerial GetLastSubmittedCommandSerial() const;
Serial GetFutureCallbackSerial() const; ExecutionSerial GetFutureCallbackSerial() const;
Serial GetPendingCommandSerial() const; ExecutionSerial GetPendingCommandSerial() const;
virtual MaybeError TickImpl() = 0; virtual MaybeError TickImpl() = 0;
// Many Dawn objects are completely immutable once created which means that if two // Many Dawn objects are completely immutable once created which means that if two
@ -226,7 +225,7 @@ namespace dawn_native {
size_t GetDeprecationWarningCountForTesting(); size_t GetDeprecationWarningCountForTesting();
void EmitDeprecationWarning(const char* warning); void EmitDeprecationWarning(const char* warning);
void LoseForTesting(); void LoseForTesting();
void AddFutureCallbackSerial(Serial serial); void AddFutureCallbackSerial(ExecutionSerial serial);
virtual uint32_t GetOptimalBytesPerRowAlignment() const = 0; virtual uint32_t GetOptimalBytesPerRowAlignment() const = 0;
virtual uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const = 0; virtual uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const = 0;
@ -313,7 +312,7 @@ namespace dawn_native {
// Each backend should implement to check their passed fences if there are any and return a // Each backend should implement to check their passed fences if there are any and return a
// completed serial. Return 0 should indicate no fences to check. // completed serial. Return 0 should indicate no fences to check.
virtual Serial CheckAndUpdateCompletedSerials() = 0; virtual ExecutionSerial CheckAndUpdateCompletedSerials() = 0;
// During shut down of device, some operations might have been started since the last submit // During shut down of device, some operations might have been started since the last submit
// and waiting on a serial that doesn't have a corresponding fence enqueued. Fake serials to // and waiting on a serial that doesn't have a corresponding fence enqueued. Fake serials to
// make all commands look completed. // make all commands look completed.
@ -326,9 +325,9 @@ namespace dawn_native {
// stale serials. // stale serials.
// mFutureCallbackSerial tracks the largest serial we need to tick to for the callbacks to // mFutureCallbackSerial tracks the largest serial we need to tick to for the callbacks to
// fire // fire
Serial mCompletedSerial = 0; ExecutionSerial mCompletedSerial = ExecutionSerial(0);
Serial mLastSubmittedSerial = 0; ExecutionSerial mLastSubmittedSerial = ExecutionSerial(0);
Serial mFutureCallbackSerial = 0; ExecutionSerial mFutureCallbackSerial = ExecutionSerial(0);
// ShutDownImpl is used to clean up and release resources used by device, does not wait for // ShutDownImpl is used to clean up and release resources used by device, does not wait for
// GPU or check errors. // GPU or check errors.

View File

@ -29,7 +29,7 @@ namespace dawn_native {
} }
ResultOrError<UploadHandle> DynamicUploader::AllocateInternal(uint64_t allocationSize, ResultOrError<UploadHandle> DynamicUploader::AllocateInternal(uint64_t allocationSize,
Serial serial) { ExecutionSerial serial) {
// Disable further sub-allocation should the request be too large. // Disable further sub-allocation should the request be too large.
if (allocationSize > kRingBufferSize) { if (allocationSize > kRingBufferSize) {
std::unique_ptr<StagingBufferBase> stagingBuffer; std::unique_ptr<StagingBufferBase> stagingBuffer;
@ -95,7 +95,7 @@ namespace dawn_native {
return uploadHandle; return uploadHandle;
} }
void DynamicUploader::Deallocate(Serial lastCompletedSerial) { void DynamicUploader::Deallocate(ExecutionSerial lastCompletedSerial) {
// Reclaim memory within the ring buffers by ticking (or removing requests no longer // Reclaim memory within the ring buffers by ticking (or removing requests no longer
// in-flight). // in-flight).
for (size_t i = 0; i < mRingBuffers.size(); ++i) { for (size_t i = 0; i < mRingBuffers.size(); ++i) {
@ -113,7 +113,7 @@ namespace dawn_native {
// TODO(dawn:512): Optimize this function so that it doesn't allocate additional memory // TODO(dawn:512): Optimize this function so that it doesn't allocate additional memory
// when it's not necessary. // when it's not necessary.
ResultOrError<UploadHandle> DynamicUploader::Allocate(uint64_t allocationSize, ResultOrError<UploadHandle> DynamicUploader::Allocate(uint64_t allocationSize,
Serial serial, ExecutionSerial serial,
uint64_t offsetAlignment) { uint64_t offsetAlignment) {
ASSERT(offsetAlignment > 0); ASSERT(offsetAlignment > 0);
UploadHandle uploadHandle; UploadHandle uploadHandle;

View File

@ -16,6 +16,7 @@
#define DAWNNATIVE_DYNAMICUPLOADER_H_ #define DAWNNATIVE_DYNAMICUPLOADER_H_
#include "dawn_native/Forward.h" #include "dawn_native/Forward.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/RingBufferAllocator.h" #include "dawn_native/RingBufferAllocator.h"
#include "dawn_native/StagingBuffer.h" #include "dawn_native/StagingBuffer.h"
@ -41,9 +42,9 @@ namespace dawn_native {
void ReleaseStagingBuffer(std::unique_ptr<StagingBufferBase> stagingBuffer); void ReleaseStagingBuffer(std::unique_ptr<StagingBufferBase> stagingBuffer);
ResultOrError<UploadHandle> Allocate(uint64_t allocationSize, ResultOrError<UploadHandle> Allocate(uint64_t allocationSize,
Serial serial, ExecutionSerial serial,
uint64_t offsetAlignment); uint64_t offsetAlignment);
void Deallocate(Serial lastCompletedSerial); void Deallocate(ExecutionSerial lastCompletedSerial);
private: private:
static constexpr uint64_t kRingBufferSize = 4 * 1024 * 1024; static constexpr uint64_t kRingBufferSize = 4 * 1024 * 1024;
@ -53,10 +54,11 @@ namespace dawn_native {
RingBufferAllocator mAllocator; RingBufferAllocator mAllocator;
}; };
ResultOrError<UploadHandle> AllocateInternal(uint64_t allocationSize, Serial serial); ResultOrError<UploadHandle> AllocateInternal(uint64_t allocationSize,
ExecutionSerial serial);
std::vector<std::unique_ptr<RingBuffer>> mRingBuffers; std::vector<std::unique_ptr<RingBuffer>> mRingBuffers;
SerialQueue<Serial, std::unique_ptr<StagingBufferBase>> mReleasedStagingBuffers; SerialQueue<ExecutionSerial, std::unique_ptr<StagingBufferBase>> mReleasedStagingBuffers;
DeviceBase* mDevice; DeviceBase* mDevice;
}; };
} // namespace dawn_native } // namespace dawn_native

View File

@ -28,11 +28,10 @@ namespace dawn_native {
// The tracker is destroyed when the Device is destroyed. We need to // The tracker is destroyed when the Device is destroyed. We need to
// call Destroy on all in-flight error scopes so they resolve their callbacks // call Destroy on all in-flight error scopes so they resolve their callbacks
// with UNKNOWN. // with UNKNOWN.
constexpr Serial maxSerial = std::numeric_limits<Serial>::max(); for (Ref<ErrorScope>& scope : mScopesInFlight.IterateUpTo(kMaxExecutionSerial)) {
for (Ref<ErrorScope>& scope : mScopesInFlight.IterateUpTo(maxSerial)) {
scope->UnlinkForShutdown(); scope->UnlinkForShutdown();
} }
Tick(maxSerial); Tick(kMaxExecutionSerial);
} }
void ErrorScopeTracker::TrackUntilLastSubmitComplete(ErrorScope* scope) { void ErrorScopeTracker::TrackUntilLastSubmitComplete(ErrorScope* scope) {
@ -40,7 +39,7 @@ namespace dawn_native {
mDevice->AddFutureCallbackSerial(mDevice->GetPendingCommandSerial()); mDevice->AddFutureCallbackSerial(mDevice->GetPendingCommandSerial());
} }
void ErrorScopeTracker::Tick(Serial completedSerial) { void ErrorScopeTracker::Tick(ExecutionSerial completedSerial) {
mScopesInFlight.ClearUpTo(completedSerial); mScopesInFlight.ClearUpTo(completedSerial);
} }

View File

@ -17,6 +17,7 @@
#include "common/RefCounted.h" #include "common/RefCounted.h"
#include "common/SerialQueue.h" #include "common/SerialQueue.h"
#include "dawn_native/IntegerTypes.h"
namespace dawn_native { namespace dawn_native {
@ -30,11 +31,11 @@ namespace dawn_native {
void TrackUntilLastSubmitComplete(ErrorScope* scope); void TrackUntilLastSubmitComplete(ErrorScope* scope);
void Tick(Serial completedSerial); void Tick(ExecutionSerial completedSerial);
protected: protected:
DeviceBase* mDevice; DeviceBase* mDevice;
SerialQueue<Serial, Ref<ErrorScope>> mScopesInFlight; SerialQueue<ExecutionSerial, Ref<ErrorScope>> mScopesInFlight;
}; };
} // namespace dawn_native } // namespace dawn_native

View File

@ -34,7 +34,7 @@ namespace dawn_native {
mDevice->AddFutureCallbackSerial(mDevice->GetPendingCommandSerial()); mDevice->AddFutureCallbackSerial(mDevice->GetPendingCommandSerial());
} }
void FenceSignalTracker::Tick(Serial finishedSerial) { void FenceSignalTracker::Tick(ExecutionSerial finishedSerial) {
for (auto& fenceInFlight : mFencesInFlight.IterateUpTo(finishedSerial)) { for (auto& fenceInFlight : mFencesInFlight.IterateUpTo(finishedSerial)) {
fenceInFlight.fence->SetCompletedValue(fenceInFlight.value); fenceInFlight.fence->SetCompletedValue(fenceInFlight.value);
} }

View File

@ -36,11 +36,11 @@ namespace dawn_native {
void UpdateFenceOnComplete(Fence* fence, FenceAPISerial value); void UpdateFenceOnComplete(Fence* fence, FenceAPISerial value);
void Tick(Serial finishedSerial); void Tick(ExecutionSerial finishedSerial);
private: private:
DeviceBase* mDevice; DeviceBase* mDevice;
SerialQueue<Serial, FenceInFlight> mFencesInFlight; SerialQueue<ExecutionSerial, FenceInFlight> mFencesInFlight;
}; };
} // namespace dawn_native } // namespace dawn_native

View File

@ -57,6 +57,13 @@ namespace dawn_native {
// The type for the WebGPU API fence serial values. // The type for the WebGPU API fence serial values.
using FenceAPISerial = TypedInteger<struct FenceAPISerialT, uint64_t>; using FenceAPISerial = TypedInteger<struct FenceAPISerialT, uint64_t>;
// A serial used to watch the progression of GPU execution on a queue, each time operations
// that need to be followed individually are scheduled for execution on a queue, the serial
// is incremented by one. This way to know if something is done executing, we just need to
// compare its serial with the currently completed serial.
using ExecutionSerial = TypedInteger<struct QueueSerialT, uint64_t>;
constexpr ExecutionSerial kMaxExecutionSerial = ExecutionSerial(~uint64_t(0));
} // namespace dawn_native } // namespace dawn_native
#endif // DAWNNATIVE_INTEGERTYPES_H_ #endif // DAWNNATIVE_INTEGERTYPES_H_

View File

@ -35,7 +35,7 @@ namespace dawn_native {
mDevice->AddFutureCallbackSerial(mDevice->GetPendingCommandSerial()); mDevice->AddFutureCallbackSerial(mDevice->GetPendingCommandSerial());
} }
void MapRequestTracker::Tick(Serial finishedSerial) { void MapRequestTracker::Tick(ExecutionSerial finishedSerial) {
for (auto& request : mInflightRequests.IterateUpTo(finishedSerial)) { for (auto& request : mInflightRequests.IterateUpTo(finishedSerial)) {
request.buffer->OnMapRequestCompleted(request.id); request.buffer->OnMapRequestCompleted(request.id);
} }

View File

@ -28,7 +28,7 @@ namespace dawn_native {
~MapRequestTracker(); ~MapRequestTracker();
void Track(BufferBase* buffer, MapRequestID mapID); void Track(BufferBase* buffer, MapRequestID mapID);
void Tick(Serial finishedSerial); void Tick(ExecutionSerial finishedSerial);
private: private:
DeviceBase* mDevice; DeviceBase* mDevice;
@ -37,7 +37,7 @@ namespace dawn_native {
Ref<BufferBase> buffer; Ref<BufferBase> buffer;
MapRequestID id; MapRequestID id;
}; };
SerialQueue<Serial, Request> mInflightRequests; SerialQueue<ExecutionSerial, Request> mInflightRequests;
}; };
} // namespace dawn_native } // namespace dawn_native

View File

@ -32,7 +32,7 @@ namespace dawn_native {
RingBufferAllocator::RingBufferAllocator(uint64_t maxSize) : mMaxBlockSize(maxSize) { RingBufferAllocator::RingBufferAllocator(uint64_t maxSize) : mMaxBlockSize(maxSize) {
} }
void RingBufferAllocator::Deallocate(Serial lastCompletedSerial) { void RingBufferAllocator::Deallocate(ExecutionSerial lastCompletedSerial) {
// Reclaim memory from previously recorded blocks. // Reclaim memory from previously recorded blocks.
for (Request& request : mInflightRequests.IterateUpTo(lastCompletedSerial)) { for (Request& request : mInflightRequests.IterateUpTo(lastCompletedSerial)) {
mUsedStartOffset = request.endOffset; mUsedStartOffset = request.endOffset;
@ -62,7 +62,7 @@ namespace dawn_native {
// queue, which identifies an existing (or new) frames-worth of resources. Internally, the // queue, which identifies an existing (or new) frames-worth of resources. Internally, the
// ring-buffer maintains offsets of 3 "memory" states: Free, Reclaimed, and Used. This is done // ring-buffer maintains offsets of 3 "memory" states: Free, Reclaimed, and Used. This is done
// in FIFO order as older frames would free resources before newer ones. // in FIFO order as older frames would free resources before newer ones.
uint64_t RingBufferAllocator::Allocate(uint64_t allocationSize, Serial serial) { uint64_t RingBufferAllocator::Allocate(uint64_t allocationSize, ExecutionSerial serial) {
// Check if the buffer is full by comparing the used size. // Check if the buffer is full by comparing the used size.
// If the buffer is not split where waste occurs (e.g. cannot fit new sub-alloc in front), a // If the buffer is not split where waste occurs (e.g. cannot fit new sub-alloc in front), a
// subsequent sub-alloc could fail where the used size was previously adjusted to include // subsequent sub-alloc could fail where the used size was previously adjusted to include

View File

@ -16,6 +16,7 @@
#define DAWNNATIVE_RINGBUFFERALLOCATOR_H_ #define DAWNNATIVE_RINGBUFFERALLOCATOR_H_
#include "common/SerialQueue.h" #include "common/SerialQueue.h"
#include "dawn_native/IntegerTypes.h"
#include <limits> #include <limits>
#include <memory> #include <memory>
@ -29,8 +30,8 @@ namespace dawn_native {
RingBufferAllocator(uint64_t maxSize); RingBufferAllocator(uint64_t maxSize);
~RingBufferAllocator() = default; ~RingBufferAllocator() = default;
uint64_t Allocate(uint64_t allocationSize, Serial serial); uint64_t Allocate(uint64_t allocationSize, ExecutionSerial serial);
void Deallocate(Serial lastCompletedSerial); void Deallocate(ExecutionSerial lastCompletedSerial);
uint64_t GetSize() const; uint64_t GetSize() const;
bool Empty() const; bool Empty() const;
@ -44,7 +45,8 @@ namespace dawn_native {
uint64_t size; uint64_t size;
}; };
SerialQueue<Serial, Request> mInflightRequests; // Queue of the recorded sub-alloc requests SerialQueue<ExecutionSerial, Request>
mInflightRequests; // Queue of the recorded sub-alloc requests
// (e.g. frame of resources). // (e.g. frame of resources).
uint64_t mUsedEndOffset = 0; // Tail of used sub-alloc requests (in bytes). uint64_t mUsedEndOffset = 0; // Tail of used sub-alloc requests (in bytes).

View File

@ -16,7 +16,6 @@
#define DAWNNATIVE_D3D12_BINDGROUPD3D12_H_ #define DAWNNATIVE_D3D12_BINDGROUPD3D12_H_
#include "common/PlacementAllocated.h" #include "common/PlacementAllocated.h"
#include "common/Serial.h"
#include "dawn_native/BindGroup.h" #include "dawn_native/BindGroup.h"
#include "dawn_native/d3d12/CPUDescriptorHeapAllocationD3D12.h" #include "dawn_native/d3d12/CPUDescriptorHeapAllocationD3D12.h"
#include "dawn_native/d3d12/GPUDescriptorHeapAllocationD3D12.h" #include "dawn_native/d3d12/GPUDescriptorHeapAllocationD3D12.h"

View File

@ -240,7 +240,8 @@ namespace dawn_native { namespace d3d12 {
// occur. When that buffer is used again, the previously recorded serial must be compared to // occur. When that buffer is used again, the previously recorded serial must be compared to
// the last completed serial to determine if the buffer has implicity decayed to the common // the last completed serial to determine if the buffer has implicity decayed to the common
// state. // state.
const Serial pendingCommandSerial = ToBackend(GetDevice())->GetPendingCommandSerial(); const ExecutionSerial pendingCommandSerial =
ToBackend(GetDevice())->GetPendingCommandSerial();
if (pendingCommandSerial > mLastUsedSerial) { if (pendingCommandSerial > mLastUsedSerial) {
lastState = D3D12_RESOURCE_STATE_COMMON; lastState = D3D12_RESOURCE_STATE_COMMON;
mLastUsedSerial = pendingCommandSerial; mLastUsedSerial = pendingCommandSerial;

View File

@ -17,7 +17,6 @@
#include "dawn_native/Buffer.h" #include "dawn_native/Buffer.h"
#include "common/Serial.h"
#include "dawn_native/d3d12/ResourceHeapAllocationD3D12.h" #include "dawn_native/d3d12/ResourceHeapAllocationD3D12.h"
#include "dawn_native/d3d12/d3d12_platform.h" #include "dawn_native/d3d12/d3d12_platform.h"
@ -72,7 +71,7 @@ namespace dawn_native { namespace d3d12 {
ResourceHeapAllocation mResourceAllocation; ResourceHeapAllocation mResourceAllocation;
bool mFixedResourceState = false; bool mFixedResourceState = false;
wgpu::BufferUsage mLastUsage = wgpu::BufferUsage::None; wgpu::BufferUsage mLastUsage = wgpu::BufferUsage::None;
Serial mLastUsedSerial = UINT64_MAX; ExecutionSerial mLastUsedSerial = std::numeric_limits<ExecutionSerial>::max();
D3D12_RANGE mWrittenMappedRange = {0, 0}; D3D12_RANGE mWrittenMappedRange = {0, 0};
void* mMappedData = nullptr; void* mMappedData = nullptr;

View File

@ -30,7 +30,7 @@ namespace dawn_native { namespace d3d12 {
ResultOrError<ID3D12CommandAllocator*> CommandAllocatorManager::ReserveCommandAllocator() { ResultOrError<ID3D12CommandAllocator*> CommandAllocatorManager::ReserveCommandAllocator() {
// If there are no free allocators, get the oldest serial in flight and wait on it // If there are no free allocators, get the oldest serial in flight and wait on it
if (mFreeAllocators.none()) { if (mFreeAllocators.none()) {
const uint64_t firstSerial = mInFlightCommandAllocators.FirstSerial(); const ExecutionSerial firstSerial = mInFlightCommandAllocators.FirstSerial();
DAWN_TRY(device->WaitForSerial(firstSerial)); DAWN_TRY(device->WaitForSerial(firstSerial));
DAWN_TRY(Tick(firstSerial)); DAWN_TRY(Tick(firstSerial));
} }
@ -59,7 +59,7 @@ namespace dawn_native { namespace d3d12 {
return mCommandAllocators[firstFreeIndex].Get(); return mCommandAllocators[firstFreeIndex].Get();
} }
MaybeError CommandAllocatorManager::Tick(uint64_t lastCompletedSerial) { MaybeError CommandAllocatorManager::Tick(ExecutionSerial lastCompletedSerial) {
// Reset all command allocators that are no longer in flight // Reset all command allocators that are no longer in flight
for (auto it : mInFlightCommandAllocators.IterateUpTo(lastCompletedSerial)) { for (auto it : mInFlightCommandAllocators.IterateUpTo(lastCompletedSerial)) {
DAWN_TRY(CheckHRESULT(it.commandAllocator->Reset(), "D3D12 reset command allocator")); DAWN_TRY(CheckHRESULT(it.commandAllocator->Reset(), "D3D12 reset command allocator"));

View File

@ -19,6 +19,7 @@
#include "common/SerialQueue.h" #include "common/SerialQueue.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/IntegerTypes.h"
#include <bitset> #include <bitset>
@ -33,7 +34,7 @@ namespace dawn_native { namespace d3d12 {
// A CommandAllocator that is reserved must be used on the next ExecuteCommandLists // 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 // otherwise its commands may be reset before execution has completed on the GPU
ResultOrError<ID3D12CommandAllocator*> ReserveCommandAllocator(); ResultOrError<ID3D12CommandAllocator*> ReserveCommandAllocator();
MaybeError Tick(uint64_t lastCompletedSerial); MaybeError Tick(ExecutionSerial lastCompletedSerial);
private: private:
Device* device; Device* device;
@ -49,7 +50,7 @@ namespace dawn_native { namespace d3d12 {
ComPtr<ID3D12CommandAllocator> mCommandAllocators[kMaxCommandAllocators]; ComPtr<ID3D12CommandAllocator> mCommandAllocators[kMaxCommandAllocators];
std::bitset<kMaxCommandAllocators> mFreeAllocators; std::bitset<kMaxCommandAllocators> mFreeAllocators;
SerialQueue<Serial, IndexedCommandAllocator> mInFlightCommandAllocators; SerialQueue<ExecutionSerial, IndexedCommandAllocator> mInFlightCommandAllocators;
}; };
}} // namespace dawn_native::d3d12 }} // namespace dawn_native::d3d12

View File

@ -83,7 +83,7 @@ namespace dawn_native { namespace d3d12 {
return {}; return {};
} }
void CommandRecordingContext::TrackHeapUsage(Heap* heap, Serial serial) { void CommandRecordingContext::TrackHeapUsage(Heap* heap, ExecutionSerial serial) {
// Before tracking the heap, check the last serial it was recorded on to ensure we aren't // Before tracking the heap, check the last serial it was recorded on to ensure we aren't
// tracking it more than once. // tracking it more than once.
if (heap->GetLastUsage() < serial) { if (heap->GetLastUsage() < serial) {

View File

@ -37,7 +37,7 @@ namespace dawn_native { namespace d3d12 {
MaybeError ExecuteCommandList(Device* device); MaybeError ExecuteCommandList(Device* device);
void TrackHeapUsage(Heap* heap, Serial serial); void TrackHeapUsage(Heap* heap, ExecutionSerial serial);
private: private:
ComPtr<ID3D12GraphicsCommandList> mD3d12CommandList; ComPtr<ID3D12GraphicsCommandList> mD3d12CommandList;

View File

@ -82,7 +82,7 @@ namespace dawn_native { namespace d3d12 {
mCommandQueue.As(&mD3d12SharingContract); mCommandQueue.As(&mD3d12SharingContract);
DAWN_TRY( DAWN_TRY(
CheckHRESULT(mD3d12Device->CreateFence(GetLastSubmittedCommandSerial(), CheckHRESULT(mD3d12Device->CreateFence(uint64_t(GetLastSubmittedCommandSerial()),
D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence)), D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence)),
"D3D12 create fence")); "D3D12 create fence"));
@ -219,7 +219,7 @@ namespace dawn_native { namespace d3d12 {
MaybeError Device::TickImpl() { MaybeError Device::TickImpl() {
// Perform cleanup operations to free unused objects // Perform cleanup operations to free unused objects
Serial completedSerial = GetCompletedCommandSerial(); ExecutionSerial completedSerial = GetCompletedCommandSerial();
mResourceAllocatorManager->Tick(completedSerial); mResourceAllocatorManager->Tick(completedSerial);
DAWN_TRY(mCommandAllocatorManager->Tick(completedSerial)); DAWN_TRY(mCommandAllocatorManager->Tick(completedSerial));
@ -239,14 +239,15 @@ namespace dawn_native { namespace d3d12 {
MaybeError Device::NextSerial() { MaybeError Device::NextSerial() {
IncrementLastSubmittedCommandSerial(); IncrementLastSubmittedCommandSerial();
return CheckHRESULT(mCommandQueue->Signal(mFence.Get(), GetLastSubmittedCommandSerial()), return CheckHRESULT(
mCommandQueue->Signal(mFence.Get(), uint64_t(GetLastSubmittedCommandSerial())),
"D3D12 command queue signal fence"); "D3D12 command queue signal fence");
} }
MaybeError Device::WaitForSerial(uint64_t serial) { MaybeError Device::WaitForSerial(ExecutionSerial serial) {
CheckPassedSerials(); CheckPassedSerials();
if (GetCompletedCommandSerial() < serial) { if (GetCompletedCommandSerial() < serial) {
DAWN_TRY(CheckHRESULT(mFence->SetEventOnCompletion(serial, mFenceEvent), DAWN_TRY(CheckHRESULT(mFence->SetEventOnCompletion(uint64_t(serial), mFenceEvent),
"D3D12 set event on completion")); "D3D12 set event on completion"));
WaitForSingleObject(mFenceEvent, INFINITE); WaitForSingleObject(mFenceEvent, INFINITE);
CheckPassedSerials(); CheckPassedSerials();
@ -254,8 +255,8 @@ namespace dawn_native { namespace d3d12 {
return {}; return {};
} }
Serial Device::CheckAndUpdateCompletedSerials() { ExecutionSerial Device::CheckAndUpdateCompletedSerials() {
return mFence->GetCompletedValue(); return ExecutionSerial(mFence->GetCompletedValue());
} }
void Device::ReferenceUntilUnused(ComPtr<IUnknown> object) { void Device::ReferenceUntilUnused(ComPtr<IUnknown> object) {
@ -576,7 +577,7 @@ namespace dawn_native { namespace d3d12 {
} }
// We need to handle clearing up com object refs that were enqeued after TickImpl // We need to handle clearing up com object refs that were enqeued after TickImpl
mUsedComObjectRefs.ClearUpTo(std::numeric_limits<Serial>::max()); mUsedComObjectRefs.ClearUpTo(std::numeric_limits<ExecutionSerial>::max());
ASSERT(mUsedComObjectRefs.Empty()); ASSERT(mUsedComObjectRefs.Empty());
ASSERT(!mPendingCommands.IsOpen()); ASSERT(!mPendingCommands.IsOpen());

View File

@ -80,7 +80,7 @@ namespace dawn_native { namespace d3d12 {
const D3D12DeviceInfo& GetDeviceInfo() const; const D3D12DeviceInfo& GetDeviceInfo() const;
MaybeError NextSerial(); MaybeError NextSerial();
MaybeError WaitForSerial(Serial serial); MaybeError WaitForSerial(ExecutionSerial serial);
void ReferenceUntilUnused(ComPtr<IUnknown> object); void ReferenceUntilUnused(ComPtr<IUnknown> object);
@ -180,7 +180,7 @@ namespace dawn_native { namespace d3d12 {
ComPtr<ID3D12Fence> mFence; ComPtr<ID3D12Fence> mFence;
HANDLE mFenceEvent = nullptr; HANDLE mFenceEvent = nullptr;
Serial CheckAndUpdateCompletedSerials() override; ExecutionSerial CheckAndUpdateCompletedSerials() override;
ComPtr<ID3D12Device> mD3d12Device; // Device is owned by adapter and will not be outlived. ComPtr<ID3D12Device> mD3d12Device; // Device is owned by adapter and will not be outlived.
ComPtr<ID3D12CommandQueue> mCommandQueue; ComPtr<ID3D12CommandQueue> mCommandQueue;
@ -196,7 +196,7 @@ namespace dawn_native { namespace d3d12 {
CommandRecordingContext mPendingCommands; CommandRecordingContext mPendingCommands;
SerialQueue<Serial, ComPtr<IUnknown>> mUsedComObjectRefs; SerialQueue<ExecutionSerial, ComPtr<IUnknown>> mUsedComObjectRefs;
std::unique_ptr<CommandAllocatorManager> mCommandAllocatorManager; std::unique_ptr<CommandAllocatorManager> mCommandAllocatorManager;
std::unique_ptr<ResourceAllocatorManager> mResourceAllocatorManager; std::unique_ptr<ResourceAllocatorManager> mResourceAllocatorManager;

View File

@ -18,7 +18,7 @@ namespace dawn_native { namespace d3d12 {
GPUDescriptorHeapAllocation::GPUDescriptorHeapAllocation( GPUDescriptorHeapAllocation::GPUDescriptorHeapAllocation(
D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor, D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor,
Serial lastUsageSerial, ExecutionSerial lastUsageSerial,
HeapVersionID heapSerial) HeapVersionID heapSerial)
: mBaseDescriptor(baseDescriptor), : mBaseDescriptor(baseDescriptor),
mLastUsageSerial(lastUsageSerial), mLastUsageSerial(lastUsageSerial),
@ -29,7 +29,7 @@ namespace dawn_native { namespace d3d12 {
return mBaseDescriptor; return mBaseDescriptor;
} }
Serial GPUDescriptorHeapAllocation::GetLastUsageSerial() const { ExecutionSerial GPUDescriptorHeapAllocation::GetLastUsageSerial() const {
return mLastUsageSerial; return mLastUsageSerial;
} }

View File

@ -15,7 +15,7 @@
#ifndef DAWNNATIVE_D3D12_GPUDESCRIPTORHEAPALLOCATION_H_ #ifndef DAWNNATIVE_D3D12_GPUDESCRIPTORHEAPALLOCATION_H_
#define DAWNNATIVE_D3D12_GPUDESCRIPTORHEAPALLOCATION_H_ #define DAWNNATIVE_D3D12_GPUDESCRIPTORHEAPALLOCATION_H_
#include "common/Serial.h" #include "dawn_native/IntegerTypes.h"
#include "dawn_native/d3d12/IntegerTypes.h" #include "dawn_native/d3d12/IntegerTypes.h"
#include "dawn_native/d3d12/d3d12_platform.h" #include "dawn_native/d3d12/d3d12_platform.h"
@ -26,16 +26,16 @@ namespace dawn_native { namespace d3d12 {
public: public:
GPUDescriptorHeapAllocation() = default; GPUDescriptorHeapAllocation() = default;
GPUDescriptorHeapAllocation(D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor, GPUDescriptorHeapAllocation(D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor,
Serial lastUsageSerial, ExecutionSerial lastUsageSerial,
HeapVersionID heapSerial); HeapVersionID heapSerial);
D3D12_GPU_DESCRIPTOR_HANDLE GetBaseDescriptor() const; D3D12_GPU_DESCRIPTOR_HANDLE GetBaseDescriptor() const;
Serial GetLastUsageSerial() const; ExecutionSerial GetLastUsageSerial() const;
HeapVersionID GetHeapSerial() const; HeapVersionID GetHeapSerial() const;
private: private:
D3D12_GPU_DESCRIPTOR_HANDLE mBaseDescriptor = {0}; D3D12_GPU_DESCRIPTOR_HANDLE mBaseDescriptor = {0};
Serial mLastUsageSerial = 0; ExecutionSerial mLastUsageSerial = ExecutionSerial(0);
HeapVersionID mHeapSerial = HeapVersionID(0); HeapVersionID mHeapSerial = HeapVersionID(0);
}; };

View File

@ -86,7 +86,7 @@ namespace dawn_native { namespace d3d12 {
// Set the initial serial of buffers to 0 so that we don't wait on them when they are first // Set the initial serial of buffers to 0 so that we don't wait on them when they are first
// used // used
mBufferSerials.resize(kFrameCount, 0); mBufferSerials.resize(kFrameCount, ExecutionSerial(0));
return DAWN_SWAP_CHAIN_NO_ERROR; return DAWN_SWAP_CHAIN_NO_ERROR;
} }

View File

@ -18,6 +18,7 @@
#include "dawn_native/d3d12/d3d12_platform.h" #include "dawn_native/d3d12/d3d12_platform.h"
#include "dawn/dawn_wsi.h" #include "dawn/dawn_wsi.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
#include <vector> #include <vector>
@ -50,7 +51,7 @@ namespace dawn_native { namespace d3d12 {
ComPtr<IDXGISwapChain3> mSwapChain = nullptr; ComPtr<IDXGISwapChain3> mSwapChain = nullptr;
std::vector<ComPtr<ID3D12Resource>> mBuffers; std::vector<ComPtr<ID3D12Resource>> mBuffers;
std::vector<uint64_t> mBufferSerials; std::vector<ExecutionSerial> mBufferSerials;
uint32_t mCurrentBuffer; uint32_t mCurrentBuffer;
}; };

View File

@ -34,19 +34,19 @@ namespace dawn_native { namespace d3d12 {
return mD3d12Pageable.Get(); return mD3d12Pageable.Get();
} }
Serial Pageable::GetLastUsage() const { ExecutionSerial Pageable::GetLastUsage() const {
return mLastUsage; return mLastUsage;
} }
void Pageable::SetLastUsage(Serial serial) { void Pageable::SetLastUsage(ExecutionSerial serial) {
mLastUsage = serial; mLastUsage = serial;
} }
uint64_t Pageable::GetLastSubmission() const { ExecutionSerial Pageable::GetLastSubmission() const {
return mLastSubmission; return mLastSubmission;
} }
void Pageable::SetLastSubmission(Serial serial) { void Pageable::SetLastSubmission(ExecutionSerial serial) {
mLastSubmission = serial; mLastSubmission = serial;
} }

View File

@ -16,8 +16,8 @@
#define DAWNNATIVE_D3D12_PAGEABLED3D12_H_ #define DAWNNATIVE_D3D12_PAGEABLED3D12_H_
#include "common/LinkedList.h" #include "common/LinkedList.h"
#include "common/Serial.h"
#include "dawn_native/D3D12Backend.h" #include "dawn_native/D3D12Backend.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/d3d12/d3d12_platform.h" #include "dawn_native/d3d12/d3d12_platform.h"
namespace dawn_native { namespace d3d12 { namespace dawn_native { namespace d3d12 {
@ -36,14 +36,14 @@ namespace dawn_native { namespace d3d12 {
// We set mLastRecordingSerial to denote the serial this pageable was last recorded to be // We set mLastRecordingSerial to denote the serial this pageable was last recorded to be
// used. We must check this serial against the current serial when recording usages to // used. We must check this serial against the current serial when recording usages to
// ensure we do not process residency for this pageable multiple times. // ensure we do not process residency for this pageable multiple times.
Serial GetLastUsage() const; ExecutionSerial GetLastUsage() const;
void SetLastUsage(Serial serial); void SetLastUsage(ExecutionSerial serial);
// The residency manager must know the last serial that any portion of the pageable was // The residency manager must know the last serial that any portion of the pageable was
// submitted to be used so that we can ensure this pageable stays resident in memory at // submitted to be used so that we can ensure this pageable stays resident in memory at
// least until that serial has completed. // least until that serial has completed.
uint64_t GetLastSubmission() const; ExecutionSerial GetLastSubmission() const;
void SetLastSubmission(Serial serial); void SetLastSubmission(ExecutionSerial serial);
MemorySegment GetMemorySegment() const; MemorySegment GetMemorySegment() const;
@ -63,14 +63,14 @@ namespace dawn_native { namespace d3d12 {
private: private:
// mLastUsage denotes the last time this pageable was recorded for use. // mLastUsage denotes the last time this pageable was recorded for use.
Serial mLastUsage = 0; ExecutionSerial mLastUsage = ExecutionSerial(0);
// mLastSubmission denotes the last time this pageable was submitted to the GPU. Note that // mLastSubmission denotes the last time this pageable was submitted to the GPU. Note that
// although this variable often contains the same value as mLastUsage, it can differ in some // although this variable often contains the same value as mLastUsage, it can differ in some
// situations. When some asynchronous APIs (like WriteBuffer) are called, mLastUsage is // situations. When some asynchronous APIs (like WriteBuffer) are called, mLastUsage is
// updated upon the call, but the backend operation is deferred until the next submission // updated upon the call, but the backend operation is deferred until the next submission
// to the GPU. This makes mLastSubmission unique from mLastUsage, and allows us to // to the GPU. This makes mLastSubmission unique from mLastUsage, and allows us to
// accurately identify when a pageable can be evicted. // accurately identify when a pageable can be evicted.
Serial mLastSubmission = 0; ExecutionSerial mLastSubmission = ExecutionSerial(0);
MemorySegment mMemorySegment; MemorySegment mMemorySegment;
uint32_t mResidencyLockRefCount = 0; uint32_t mResidencyLockRefCount = 0;
uint64_t mSize = 0; uint64_t mSize = 0;

View File

@ -156,7 +156,7 @@ namespace dawn_native { namespace d3d12 {
Pageable* pageable = memorySegment->lruCache.head()->value(); Pageable* pageable = memorySegment->lruCache.head()->value();
Serial lastSubmissionSerial = pageable->GetLastSubmission(); ExecutionSerial lastSubmissionSerial = pageable->GetLastSubmission();
// If the next candidate for eviction was inserted into the LRU during the current serial, // If the next candidate for eviction was inserted into the LRU during the current serial,
// it is because more memory is being used in a single command list than is available. // it is because more memory is being used in a single command list than is available.
@ -243,7 +243,7 @@ namespace dawn_native { namespace d3d12 {
uint64_t localSizeToMakeResident = 0; uint64_t localSizeToMakeResident = 0;
uint64_t nonLocalSizeToMakeResident = 0; uint64_t nonLocalSizeToMakeResident = 0;
Serial pendingCommandSerial = mDevice->GetPendingCommandSerial(); ExecutionSerial pendingCommandSerial = mDevice->GetPendingCommandSerial();
for (size_t i = 0; i < heapCount; i++) { for (size_t i = 0; i < heapCount; i++) {
Heap* heap = heaps[i]; Heap* heap = heaps[i];

View File

@ -16,7 +16,6 @@
#define DAWNNATIVE_D3D12_RESIDENCYMANAGERD3D12_H_ #define DAWNNATIVE_D3D12_RESIDENCYMANAGERD3D12_H_
#include "common/LinkedList.h" #include "common/LinkedList.h"
#include "common/Serial.h"
#include "dawn_native/D3D12Backend.h" #include "dawn_native/D3D12Backend.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"

View File

@ -219,7 +219,7 @@ namespace dawn_native { namespace d3d12 {
return DAWN_OUT_OF_MEMORY_ERROR("Allocation failed"); return DAWN_OUT_OF_MEMORY_ERROR("Allocation failed");
} }
void ResourceAllocatorManager::Tick(Serial completedSerial) { void ResourceAllocatorManager::Tick(ExecutionSerial completedSerial) {
for (ResourceHeapAllocation& allocation : for (ResourceHeapAllocation& allocation :
mAllocationsToDelete.IterateUpTo(completedSerial)) { mAllocationsToDelete.IterateUpTo(completedSerial)) {
if (allocation.GetInfo().mMethod == AllocationMethod::kSubAllocated) { if (allocation.GetInfo().mMethod == AllocationMethod::kSubAllocated) {

View File

@ -17,6 +17,7 @@
#include "common/SerialQueue.h" #include "common/SerialQueue.h"
#include "dawn_native/BuddyMemoryAllocator.h" #include "dawn_native/BuddyMemoryAllocator.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/PooledResourceMemoryAllocator.h" #include "dawn_native/PooledResourceMemoryAllocator.h"
#include "dawn_native/d3d12/HeapAllocatorD3D12.h" #include "dawn_native/d3d12/HeapAllocatorD3D12.h"
#include "dawn_native/d3d12/ResourceHeapAllocationD3D12.h" #include "dawn_native/d3d12/ResourceHeapAllocationD3D12.h"
@ -66,7 +67,7 @@ namespace dawn_native { namespace d3d12 {
void DeallocateMemory(ResourceHeapAllocation& allocation); void DeallocateMemory(ResourceHeapAllocation& allocation);
void Tick(Serial lastCompletedSerial); void Tick(ExecutionSerial lastCompletedSerial);
void DestroyPool(); void DestroyPool();
@ -98,7 +99,7 @@ namespace dawn_native { namespace d3d12 {
std::array<std::unique_ptr<PooledResourceMemoryAllocator>, ResourceHeapKind::EnumCount> std::array<std::unique_ptr<PooledResourceMemoryAllocator>, ResourceHeapKind::EnumCount>
mPooledHeapAllocators; mPooledHeapAllocators;
SerialQueue<Serial, ResourceHeapAllocation> mAllocationsToDelete; SerialQueue<ExecutionSerial, ResourceHeapAllocation> mAllocationsToDelete;
}; };
}} // namespace dawn_native::d3d12 }} // namespace dawn_native::d3d12

View File

@ -94,7 +94,7 @@ namespace dawn_native { namespace d3d12 {
bool ShaderVisibleDescriptorAllocator::AllocateGPUDescriptors( bool ShaderVisibleDescriptorAllocator::AllocateGPUDescriptors(
uint32_t descriptorCount, uint32_t descriptorCount,
Serial pendingSerial, ExecutionSerial pendingSerial,
D3D12_CPU_DESCRIPTOR_HANDLE* baseCPUDescriptor, D3D12_CPU_DESCRIPTOR_HANDLE* baseCPUDescriptor,
GPUDescriptorHeapAllocation* allocation) { GPUDescriptorHeapAllocation* allocation) {
ASSERT(mHeap != nullptr); ASSERT(mHeap != nullptr);
@ -128,7 +128,7 @@ namespace dawn_native { namespace d3d12 {
return mHeap->GetD3D12DescriptorHeap(); return mHeap->GetD3D12DescriptorHeap();
} }
void ShaderVisibleDescriptorAllocator::Tick(uint64_t completedSerial) { void ShaderVisibleDescriptorAllocator::Tick(ExecutionSerial completedSerial) {
mAllocator.Deallocate(completedSerial); mAllocator.Deallocate(completedSerial);
} }

View File

@ -55,11 +55,11 @@ namespace dawn_native { namespace d3d12 {
// Returns true if the allocation was successful, when false is returned the current heap is // Returns true if the allocation was successful, when false is returned the current heap is
// full and AllocateAndSwitchShaderVisibleHeap() must be called. // full and AllocateAndSwitchShaderVisibleHeap() must be called.
bool AllocateGPUDescriptors(uint32_t descriptorCount, bool AllocateGPUDescriptors(uint32_t descriptorCount,
Serial pendingSerial, ExecutionSerial pendingSerial,
D3D12_CPU_DESCRIPTOR_HANDLE* baseCPUDescriptor, D3D12_CPU_DESCRIPTOR_HANDLE* baseCPUDescriptor,
GPUDescriptorHeapAllocation* allocation); GPUDescriptorHeapAllocation* allocation);
void Tick(uint64_t completedSerial); void Tick(ExecutionSerial completedSerial);
ID3D12DescriptorHeap* GetShaderVisibleHeap() const; ID3D12DescriptorHeap* GetShaderVisibleHeap() const;
MaybeError AllocateAndSwitchShaderVisibleHeap(); MaybeError AllocateAndSwitchShaderVisibleHeap();
@ -75,7 +75,7 @@ namespace dawn_native { namespace d3d12 {
private: private:
struct SerialDescriptorHeap { struct SerialDescriptorHeap {
Serial heapSerial; ExecutionSerial heapSerial;
std::unique_ptr<ShaderVisibleDescriptorHeap> heap; std::unique_ptr<ShaderVisibleDescriptorHeap> heap;
}; };

View File

@ -140,7 +140,7 @@ namespace dawn_native { namespace d3d12 {
return allocation; return allocation;
} }
void StagingDescriptorAllocator::Tick(Serial completedSerial) { void StagingDescriptorAllocator::Tick(ExecutionSerial completedSerial) {
for (CPUDescriptorHeapAllocation& allocation : for (CPUDescriptorHeapAllocation& allocation :
mAllocationsToDelete.IterateUpTo(completedSerial)) { mAllocationsToDelete.IterateUpTo(completedSerial)) {
Deallocate(&allocation); Deallocate(&allocation);

View File

@ -52,7 +52,7 @@ namespace dawn_native { namespace d3d12 {
uint32_t GetSizeIncrement() const; uint32_t GetSizeIncrement() const;
void Tick(Serial completedSerial); void Tick(ExecutionSerial completedSerial);
private: private:
using Index = uint16_t; using Index = uint16_t;
@ -77,7 +77,7 @@ namespace dawn_native { namespace d3d12 {
D3D12_DESCRIPTOR_HEAP_TYPE mHeapType; D3D12_DESCRIPTOR_HEAP_TYPE mHeapType;
SerialQueue<Serial, CPUDescriptorHeapAllocation> mAllocationsToDelete; SerialQueue<ExecutionSerial, CPUDescriptorHeapAllocation> mAllocationsToDelete;
}; };
}} // namespace dawn_native::d3d12 }} // namespace dawn_native::d3d12

View File

@ -489,7 +489,7 @@ namespace dawn_native { namespace d3d12 {
: TextureBase(device, descriptor, state), : TextureBase(device, descriptor, state),
mSubresourceStateAndDecay( mSubresourceStateAndDecay(
GetSubresourceCount(), GetSubresourceCount(),
{D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_COMMON, UINT64_MAX, false}) { {D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_COMMON, kMaxExecutionSerial, false}) {
} }
Texture::Texture(Device* device, Texture::Texture(Device* device,
@ -607,7 +607,7 @@ namespace dawn_native { namespace d3d12 {
void Texture::TransitionSingleOrAllSubresources(std::vector<D3D12_RESOURCE_BARRIER>* barriers, void Texture::TransitionSingleOrAllSubresources(std::vector<D3D12_RESOURCE_BARRIER>* barriers,
uint32_t index, uint32_t index,
D3D12_RESOURCE_STATES newState, D3D12_RESOURCE_STATES newState,
const Serial pendingCommandSerial, ExecutionSerial pendingCommandSerial,
bool allSubresources) { bool allSubresources) {
StateAndDecay* state = &mSubresourceStateAndDecay[index]; StateAndDecay* state = &mSubresourceStateAndDecay[index];
// Reuse the subresource(s) directly and avoid transition when it isn't needed, and // Reuse the subresource(s) directly and avoid transition when it isn't needed, and
@ -702,7 +702,8 @@ namespace dawn_native { namespace d3d12 {
const SubresourceRange& range) { const SubresourceRange& range) {
HandleTransitionSpecialCases(commandContext); HandleTransitionSpecialCases(commandContext);
const Serial pendingCommandSerial = ToBackend(GetDevice())->GetPendingCommandSerial(); const ExecutionSerial pendingCommandSerial =
ToBackend(GetDevice())->GetPendingCommandSerial();
// This transitions assume it is a 2D texture // This transitions assume it is a 2D texture
ASSERT(GetDimension() == wgpu::TextureDimension::e2D); ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
@ -751,7 +752,8 @@ namespace dawn_native { namespace d3d12 {
HandleTransitionSpecialCases(commandContext); HandleTransitionSpecialCases(commandContext);
const Serial pendingCommandSerial = ToBackend(GetDevice())->GetPendingCommandSerial(); const ExecutionSerial pendingCommandSerial =
ToBackend(GetDevice())->GetPendingCommandSerial();
uint32_t subresourceCount = GetSubresourceCount(); uint32_t subresourceCount = GetSubresourceCount();
ASSERT(textureUsages.subresourceUsages.size() == subresourceCount); ASSERT(textureUsages.subresourceUsages.size() == subresourceCount);
// This transitions assume it is a 2D texture // This transitions assume it is a 2D texture

View File

@ -15,10 +15,10 @@
#ifndef DAWNNATIVE_D3D12_TEXTURED3D12_H_ #ifndef DAWNNATIVE_D3D12_TEXTURED3D12_H_
#define DAWNNATIVE_D3D12_TEXTURED3D12_H_ #define DAWNNATIVE_D3D12_TEXTURED3D12_H_
#include "common/Serial.h"
#include "dawn_native/Texture.h" #include "dawn_native/Texture.h"
#include "dawn_native/DawnNative.h" #include "dawn_native/DawnNative.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/PassResourceUsage.h" #include "dawn_native/PassResourceUsage.h"
#include "dawn_native/d3d12/IntegerTypes.h" #include "dawn_native/d3d12/IntegerTypes.h"
#include "dawn_native/d3d12/ResourceHeapAllocationD3D12.h" #include "dawn_native/d3d12/ResourceHeapAllocationD3D12.h"
@ -103,7 +103,7 @@ namespace dawn_native { namespace d3d12 {
void TransitionSingleOrAllSubresources(std::vector<D3D12_RESOURCE_BARRIER>* barriers, void TransitionSingleOrAllSubresources(std::vector<D3D12_RESOURCE_BARRIER>* barriers,
uint32_t index, uint32_t index,
D3D12_RESOURCE_STATES subresourceNewState, D3D12_RESOURCE_STATES subresourceNewState,
const Serial pendingCommandSerial, ExecutionSerial pendingCommandSerial,
bool allSubresources); bool allSubresources);
void HandleTransitionSpecialCases(CommandRecordingContext* commandContext); void HandleTransitionSpecialCases(CommandRecordingContext* commandContext);
@ -111,7 +111,7 @@ namespace dawn_native { namespace d3d12 {
struct StateAndDecay { struct StateAndDecay {
D3D12_RESOURCE_STATES lastState; D3D12_RESOURCE_STATES lastState;
Serial lastDecaySerial; ExecutionSerial lastDecaySerial;
bool isValidToDecay; bool isValidToDecay;
}; };
std::vector<StateAndDecay> mSubresourceStateAndDecay; std::vector<StateAndDecay> mSubresourceStateAndDecay;

View File

@ -17,7 +17,6 @@
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
#include "common/Serial.h"
#include "dawn_native/Commands.h" #include "dawn_native/Commands.h"
#include "dawn_native/Device.h" #include "dawn_native/Device.h"
#include "dawn_native/metal/CommandRecordingContext.h" #include "dawn_native/metal/CommandRecordingContext.h"
@ -107,7 +106,7 @@ namespace dawn_native { namespace metal {
void InitTogglesFromDriver(); void InitTogglesFromDriver();
void ShutDownImpl() override; void ShutDownImpl() override;
MaybeError WaitForIdleForDestruction() override; MaybeError WaitForIdleForDestruction() override;
Serial CheckAndUpdateCompletedSerials() override; ExecutionSerial CheckAndUpdateCompletedSerials() override;
id<MTLDevice> mMtlDevice = nil; id<MTLDevice> mMtlDevice = nil;
id<MTLCommandQueue> mCommandQueue = nil; id<MTLCommandQueue> mCommandQueue = nil;

View File

@ -174,16 +174,16 @@ namespace dawn_native { namespace metal {
return new TextureView(texture, descriptor); return new TextureView(texture, descriptor);
} }
Serial Device::CheckAndUpdateCompletedSerials() { ExecutionSerial Device::CheckAndUpdateCompletedSerials() {
if (GetCompletedCommandSerial() > mCompletedSerial) { uint64_t frontendCompletedSerial{GetCompletedCommandSerial()};
if (frontendCompletedSerial > mCompletedSerial) {
// sometimes we increase the serials, in which case the completed serial in // sometimes we increase the serials, in which case the completed serial in
// the device base will surpass the completed serial we have in the metal backend, so we // the device base will surpass the completed serial we have in the metal backend, so we
// must update ours when we see that the completed serial from device base has // must update ours when we see that the completed serial from device base has
// increased. // increased.
mCompletedSerial = GetCompletedCommandSerial(); mCompletedSerial = frontendCompletedSerial;
} }
static_assert(std::is_same<Serial, uint64_t>::value, ""); return ExecutionSerial(mCompletedSerial.load());
return mCompletedSerial.load();
} }
MaybeError Device::TickImpl() { MaybeError Device::TickImpl() {
@ -241,17 +241,17 @@ namespace dawn_native { namespace metal {
// Update the completed serial once the completed handler is fired. Make a local copy of // Update the completed serial once the completed handler is fired. Make a local copy of
// mLastSubmittedSerial so it is captured by value. // mLastSubmittedSerial so it is captured by value.
Serial pendingSerial = GetLastSubmittedCommandSerial(); ExecutionSerial pendingSerial = GetLastSubmittedCommandSerial();
// this ObjC block runs on a different thread // this ObjC block runs on a different thread
[pendingCommands addCompletedHandler:^(id<MTLCommandBuffer>) { [pendingCommands addCompletedHandler:^(id<MTLCommandBuffer>) {
TRACE_EVENT_ASYNC_END0(GetPlatform(), GPUWork, "DeviceMTL::SubmitPendingCommandBuffer", TRACE_EVENT_ASYNC_END0(GetPlatform(), GPUWork, "DeviceMTL::SubmitPendingCommandBuffer",
pendingSerial); uint64_t(pendingSerial));
ASSERT(pendingSerial > mCompletedSerial.load()); ASSERT(uint64_t(pendingSerial) > mCompletedSerial.load());
this->mCompletedSerial = pendingSerial; this->mCompletedSerial = uint64_t(pendingSerial);
}]; }];
TRACE_EVENT_ASYNC_BEGIN0(GetPlatform(), GPUWork, "DeviceMTL::SubmitPendingCommandBuffer", TRACE_EVENT_ASYNC_BEGIN0(GetPlatform(), GPUWork, "DeviceMTL::SubmitPendingCommandBuffer",
pendingSerial); uint64_t(pendingSerial));
[pendingCommands commit]; [pendingCommands commit];
[pendingCommands release]; [pendingCommands release];
} }

View File

@ -219,7 +219,7 @@ namespace dawn_native { namespace null {
return {}; return {};
} }
Serial Device::CheckAndUpdateCompletedSerials() { ExecutionSerial Device::CheckAndUpdateCompletedSerials() {
return GetLastSubmittedCommandSerial(); return GetLastSubmittedCommandSerial();
} }

View File

@ -148,7 +148,7 @@ namespace dawn_native { namespace null {
TextureBase* texture, TextureBase* texture,
const TextureViewDescriptor* descriptor) override; const TextureViewDescriptor* descriptor) override;
Serial CheckAndUpdateCompletedSerials() override; ExecutionSerial CheckAndUpdateCompletedSerials() override;
void ShutDownImpl() override; void ShutDownImpl() override;
MaybeError WaitForIdleForDestruction() override; MaybeError WaitForIdleForDestruction() override;

View File

@ -160,11 +160,11 @@ namespace dawn_native { namespace opengl {
return {}; return {};
} }
Serial Device::CheckAndUpdateCompletedSerials() { ExecutionSerial Device::CheckAndUpdateCompletedSerials() {
Serial fenceSerial = 0; ExecutionSerial fenceSerial{0};
while (!mFencesInFlight.empty()) { while (!mFencesInFlight.empty()) {
GLsync sync = mFencesInFlight.front().first; GLsync sync = mFencesInFlight.front().first;
Serial tentativeSerial = mFencesInFlight.front().second; ExecutionSerial tentativeSerial = mFencesInFlight.front().second;
// Fence are added in order, so we can stop searching as soon // Fence are added in order, so we can stop searching as soon
// as we see one that's not ready. // as we see one that's not ready.

View File

@ -105,11 +105,11 @@ namespace dawn_native { namespace opengl {
const TextureViewDescriptor* descriptor) override; const TextureViewDescriptor* descriptor) override;
void InitTogglesFromDriver(); void InitTogglesFromDriver();
Serial CheckAndUpdateCompletedSerials() override; ExecutionSerial CheckAndUpdateCompletedSerials() override;
void ShutDownImpl() override; void ShutDownImpl() override;
MaybeError WaitForIdleForDestruction() override; MaybeError WaitForIdleForDestruction() override;
std::queue<std::pair<GLsync, Serial>> mFencesInFlight; std::queue<std::pair<GLsync, ExecutionSerial>> mFencesInFlight;
GLFormatTable mFormatTable; GLFormatTable mFormatTable;
}; };

View File

@ -174,7 +174,7 @@ namespace dawn_native { namespace vulkan {
mBindGroupAllocator.Deallocate(bindGroup); mBindGroupAllocator.Deallocate(bindGroup);
} }
void BindGroupLayout::FinishDeallocation(Serial completedSerial) { void BindGroupLayout::FinishDeallocation(ExecutionSerial completedSerial) {
mDescriptorSetAllocator->FinishDeallocation(completedSerial); mDescriptorSetAllocator->FinishDeallocation(completedSerial);
} }

View File

@ -17,7 +17,6 @@
#include "dawn_native/BindGroupLayout.h" #include "dawn_native/BindGroupLayout.h"
#include "common/Serial.h"
#include "common/SlabAllocator.h" #include "common/SlabAllocator.h"
#include "common/vulkan_platform.h" #include "common/vulkan_platform.h"
@ -57,7 +56,7 @@ namespace dawn_native { namespace vulkan {
const BindGroupDescriptor* descriptor); const BindGroupDescriptor* descriptor);
void DeallocateBindGroup(BindGroup* bindGroup, void DeallocateBindGroup(BindGroup* bindGroup,
DescriptorSetAllocation* descriptorSetAllocation); DescriptorSetAllocation* descriptorSetAllocation);
void FinishDeallocation(Serial completedSerial); void FinishDeallocation(ExecutionSerial completedSerial);
private: private:
~BindGroupLayout() override; ~BindGroupLayout() override;

View File

@ -102,7 +102,7 @@ namespace dawn_native { namespace vulkan {
// documentation for vkCmdBindDescriptorSets that the set may be consumed any time between // documentation for vkCmdBindDescriptorSets that the set may be consumed any time between
// host execution of the command and the end of the draw/dispatch. // host execution of the command and the end of the draw/dispatch.
Device* device = ToBackend(mLayout->GetDevice()); Device* device = ToBackend(mLayout->GetDevice());
const Serial serial = device->GetPendingCommandSerial(); const ExecutionSerial serial = device->GetPendingCommandSerial();
mPendingDeallocations.Enqueue({allocationInfo->poolIndex, allocationInfo->setIndex}, mPendingDeallocations.Enqueue({allocationInfo->poolIndex, allocationInfo->setIndex},
serial); serial);
@ -115,7 +115,7 @@ namespace dawn_native { namespace vulkan {
*allocationInfo = {}; *allocationInfo = {};
} }
void DescriptorSetAllocator::FinishDeallocation(Serial completedSerial) { void DescriptorSetAllocator::FinishDeallocation(ExecutionSerial completedSerial) {
for (const Deallocation& dealloc : mPendingDeallocations.IterateUpTo(completedSerial)) { for (const Deallocation& dealloc : mPendingDeallocations.IterateUpTo(completedSerial)) {
ASSERT(dealloc.poolIndex < mDescriptorPools.size()); ASSERT(dealloc.poolIndex < mDescriptorPools.size());

View File

@ -18,6 +18,7 @@
#include "common/SerialQueue.h" #include "common/SerialQueue.h"
#include "common/vulkan_platform.h" #include "common/vulkan_platform.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/vulkan/DescriptorSetAllocation.h" #include "dawn_native/vulkan/DescriptorSetAllocation.h"
#include <map> #include <map>
@ -38,7 +39,7 @@ namespace dawn_native { namespace vulkan {
ResultOrError<DescriptorSetAllocation> Allocate(); ResultOrError<DescriptorSetAllocation> Allocate();
void Deallocate(DescriptorSetAllocation* allocationInfo); void Deallocate(DescriptorSetAllocation* allocationInfo);
void FinishDeallocation(Serial completedSerial); void FinishDeallocation(ExecutionSerial completedSerial);
private: private:
MaybeError AllocateDescriptorPool(); MaybeError AllocateDescriptorPool();
@ -61,8 +62,8 @@ namespace dawn_native { namespace vulkan {
PoolIndex poolIndex; PoolIndex poolIndex;
SetIndex setIndex; SetIndex setIndex;
}; };
SerialQueue<Serial, Deallocation> mPendingDeallocations; SerialQueue<ExecutionSerial, Deallocation> mPendingDeallocations;
Serial mLastDeallocationSerial = 0; ExecutionSerial mLastDeallocationSerial = ExecutionSerial(0);
}; };
}} // namespace dawn_native::vulkan }} // namespace dawn_native::vulkan

View File

@ -161,7 +161,7 @@ namespace dawn_native { namespace vulkan {
MaybeError Device::TickImpl() { MaybeError Device::TickImpl() {
RecycleCompletedCommands(); RecycleCompletedCommands();
Serial completedSerial = GetCompletedCommandSerial(); ExecutionSerial completedSerial = GetCompletedCommandSerial();
for (Ref<BindGroupLayout>& bgl : for (Ref<BindGroupLayout>& bgl :
mBindGroupLayoutsPendingDeallocation.IterateUpTo(completedSerial)) { mBindGroupLayoutsPendingDeallocation.IterateUpTo(completedSerial)) {
@ -254,7 +254,7 @@ namespace dawn_native { namespace vulkan {
} }
IncrementLastSubmittedCommandSerial(); IncrementLastSubmittedCommandSerial();
Serial lastSubmittedSerial = GetLastSubmittedCommandSerial(); ExecutionSerial lastSubmittedSerial = GetLastSubmittedCommandSerial();
mFencesInFlight.emplace(fence, lastSubmittedSerial); mFencesInFlight.emplace(fence, lastSubmittedSerial);
CommandPoolAndBuffer submittedCommands = {mRecordingContext.commandPool, CommandPoolAndBuffer submittedCommands = {mRecordingContext.commandPool,
@ -498,11 +498,11 @@ namespace dawn_native { namespace vulkan {
return fence; return fence;
} }
Serial Device::CheckAndUpdateCompletedSerials() { ExecutionSerial Device::CheckAndUpdateCompletedSerials() {
Serial fenceSerial = 0; ExecutionSerial fenceSerial(0);
while (!mFencesInFlight.empty()) { while (!mFencesInFlight.empty()) {
VkFence fence = mFencesInFlight.front().first; VkFence fence = mFencesInFlight.front().first;
Serial tentativeSerial = mFencesInFlight.front().second; ExecutionSerial tentativeSerial = mFencesInFlight.front().second;
VkResult result = VkResult::WrapUnsafe( VkResult result = VkResult::WrapUnsafe(
INJECT_ERROR_OR_RUN(fn.GetFenceStatus(mVkDevice, fence), VK_ERROR_DEVICE_LOST)); INJECT_ERROR_OR_RUN(fn.GetFenceStatus(mVkDevice, fence), VK_ERROR_DEVICE_LOST));
// TODO: Handle DeviceLost error. // TODO: Handle DeviceLost error.
@ -824,7 +824,7 @@ namespace dawn_native { namespace vulkan {
// Make sure all fences are complete by explicitly waiting on them all // Make sure all fences are complete by explicitly waiting on them all
while (!mFencesInFlight.empty()) { while (!mFencesInFlight.empty()) {
VkFence fence = mFencesInFlight.front().first; VkFence fence = mFencesInFlight.front().first;
Serial fenceSerial = mFencesInFlight.front().second; ExecutionSerial fenceSerial = mFencesInFlight.front().second;
ASSERT(fenceSerial > GetCompletedCommandSerial()); ASSERT(fenceSerial > GetCompletedCommandSerial());
VkResult result = VkResult::WrapUnsafe(VK_TIMEOUT); VkResult result = VkResult::WrapUnsafe(VK_TIMEOUT);
@ -919,7 +919,7 @@ namespace dawn_native { namespace vulkan {
// force all operations to look as if they were completed, and delete all objects before // force all operations to look as if they were completed, and delete all objects before
// destroying the Deleter and vkDevice. // destroying the Deleter and vkDevice.
ASSERT(mDeleter != nullptr); ASSERT(mDeleter != nullptr);
mDeleter->Tick(std::numeric_limits<Serial>::max()); mDeleter->Tick(kMaxExecutionSerial);
mDeleter = nullptr; mDeleter = nullptr;
// VkQueues are destroyed when the VkDevice is destroyed // VkQueues are destroyed when the VkDevice is destroyed

View File

@ -17,7 +17,6 @@
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
#include "common/Serial.h"
#include "common/SerialQueue.h" #include "common/SerialQueue.h"
#include "dawn_native/Commands.h" #include "dawn_native/Commands.h"
#include "dawn_native/Device.h" #include "dawn_native/Device.h"
@ -161,7 +160,7 @@ namespace dawn_native { namespace vulkan {
VkQueue mQueue = VK_NULL_HANDLE; VkQueue mQueue = VK_NULL_HANDLE;
uint32_t mComputeSubgroupSize = 0; uint32_t mComputeSubgroupSize = 0;
SerialQueue<Serial, Ref<BindGroupLayout>> mBindGroupLayoutsPendingDeallocation; SerialQueue<ExecutionSerial, Ref<BindGroupLayout>> mBindGroupLayoutsPendingDeallocation;
std::unique_ptr<FencedDeleter> mDeleter; std::unique_ptr<FencedDeleter> mDeleter;
std::unique_ptr<ResourceMemoryAllocator> mResourceMemoryAllocator; std::unique_ptr<ResourceMemoryAllocator> mResourceMemoryAllocator;
std::unique_ptr<RenderPassCache> mRenderPassCache; std::unique_ptr<RenderPassCache> mRenderPassCache;
@ -170,13 +169,13 @@ namespace dawn_native { namespace vulkan {
std::unique_ptr<external_semaphore::Service> mExternalSemaphoreService; std::unique_ptr<external_semaphore::Service> mExternalSemaphoreService;
ResultOrError<VkFence> GetUnusedFence(); ResultOrError<VkFence> GetUnusedFence();
Serial CheckAndUpdateCompletedSerials() override; ExecutionSerial CheckAndUpdateCompletedSerials() override;
// We track which operations are in flight on the GPU with an increasing serial. // We track which operations are in flight on the GPU with an increasing serial.
// This works only because we have a single queue. Each submit to a queue is associated // This works only because we have a single queue. Each submit to a queue is associated
// to a serial and a fence, such that when the fence is "ready" we know the operations // to a serial and a fence, such that when the fence is "ready" we know the operations
// have finished. // have finished.
std::queue<std::pair<VkFence, Serial>> mFencesInFlight; std::queue<std::pair<VkFence, ExecutionSerial>> mFencesInFlight;
// Fences in the unused list aren't reset yet. // Fences in the unused list aren't reset yet.
std::vector<VkFence> mUnusedFences; std::vector<VkFence> mUnusedFences;
@ -187,7 +186,7 @@ namespace dawn_native { namespace vulkan {
VkCommandPool pool = VK_NULL_HANDLE; VkCommandPool pool = VK_NULL_HANDLE;
VkCommandBuffer commandBuffer = VK_NULL_HANDLE; VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
}; };
SerialQueue<Serial, CommandPoolAndBuffer> mCommandsInFlight; SerialQueue<ExecutionSerial, CommandPoolAndBuffer> mCommandsInFlight;
// Command pools in the unused list haven't been reset yet. // Command pools in the unused list haven't been reset yet.
std::vector<CommandPoolAndBuffer> mUnusedCommands; std::vector<CommandPoolAndBuffer> mUnusedCommands;
// There is always a valid recording context stored in mRecordingContext // There is always a valid recording context stored in mRecordingContext

View File

@ -99,7 +99,7 @@ namespace dawn_native { namespace vulkan {
mSwapChainsToDelete.Enqueue(swapChain, mDevice->GetPendingCommandSerial()); mSwapChainsToDelete.Enqueue(swapChain, mDevice->GetPendingCommandSerial());
} }
void FencedDeleter::Tick(Serial completedSerial) { void FencedDeleter::Tick(ExecutionSerial completedSerial) {
VkDevice vkDevice = mDevice->GetVkDevice(); VkDevice vkDevice = mDevice->GetVkDevice();
VkInstance instance = mDevice->GetVkInstance(); VkInstance instance = mDevice->GetVkInstance();

View File

@ -17,6 +17,7 @@
#include "common/SerialQueue.h" #include "common/SerialQueue.h"
#include "common/vulkan_platform.h" #include "common/vulkan_platform.h"
#include "dawn_native/IntegerTypes.h"
namespace dawn_native { namespace vulkan { namespace dawn_native { namespace vulkan {
@ -43,25 +44,25 @@ namespace dawn_native { namespace vulkan {
void DeleteWhenUnused(VkSurfaceKHR surface); void DeleteWhenUnused(VkSurfaceKHR surface);
void DeleteWhenUnused(VkSwapchainKHR swapChain); void DeleteWhenUnused(VkSwapchainKHR swapChain);
void Tick(Serial completedSerial); void Tick(ExecutionSerial completedSerial);
private: private:
Device* mDevice = nullptr; Device* mDevice = nullptr;
SerialQueue<Serial, VkBuffer> mBuffersToDelete; SerialQueue<ExecutionSerial, VkBuffer> mBuffersToDelete;
SerialQueue<Serial, VkDescriptorPool> mDescriptorPoolsToDelete; SerialQueue<ExecutionSerial, VkDescriptorPool> mDescriptorPoolsToDelete;
SerialQueue<Serial, VkDeviceMemory> mMemoriesToDelete; SerialQueue<ExecutionSerial, VkDeviceMemory> mMemoriesToDelete;
SerialQueue<Serial, VkFramebuffer> mFramebuffersToDelete; SerialQueue<ExecutionSerial, VkFramebuffer> mFramebuffersToDelete;
SerialQueue<Serial, VkImage> mImagesToDelete; SerialQueue<ExecutionSerial, VkImage> mImagesToDelete;
SerialQueue<Serial, VkImageView> mImageViewsToDelete; SerialQueue<ExecutionSerial, VkImageView> mImageViewsToDelete;
SerialQueue<Serial, VkPipeline> mPipelinesToDelete; SerialQueue<ExecutionSerial, VkPipeline> mPipelinesToDelete;
SerialQueue<Serial, VkPipelineLayout> mPipelineLayoutsToDelete; SerialQueue<ExecutionSerial, VkPipelineLayout> mPipelineLayoutsToDelete;
SerialQueue<Serial, VkQueryPool> mQueryPoolsToDelete; SerialQueue<ExecutionSerial, VkQueryPool> mQueryPoolsToDelete;
SerialQueue<Serial, VkRenderPass> mRenderPassesToDelete; SerialQueue<ExecutionSerial, VkRenderPass> mRenderPassesToDelete;
SerialQueue<Serial, VkSampler> mSamplersToDelete; SerialQueue<ExecutionSerial, VkSampler> mSamplersToDelete;
SerialQueue<Serial, VkSemaphore> mSemaphoresToDelete; SerialQueue<ExecutionSerial, VkSemaphore> mSemaphoresToDelete;
SerialQueue<Serial, VkShaderModule> mShaderModulesToDelete; SerialQueue<ExecutionSerial, VkShaderModule> mShaderModulesToDelete;
SerialQueue<Serial, VkSurfaceKHR> mSurfacesToDelete; SerialQueue<ExecutionSerial, VkSurfaceKHR> mSurfacesToDelete;
SerialQueue<Serial, VkSwapchainKHR> mSwapChainsToDelete; SerialQueue<ExecutionSerial, VkSwapchainKHR> mSwapChainsToDelete;
}; };
}} // namespace dawn_native::vulkan }} // namespace dawn_native::vulkan

View File

@ -198,7 +198,7 @@ namespace dawn_native { namespace vulkan {
allocation->Invalidate(); allocation->Invalidate();
} }
void ResourceMemoryAllocator::Tick(Serial completedSerial) { void ResourceMemoryAllocator::Tick(ExecutionSerial completedSerial) {
for (const ResourceMemoryAllocation& allocation : for (const ResourceMemoryAllocation& allocation :
mSubAllocationsToDelete.IterateUpTo(completedSerial)) { mSubAllocationsToDelete.IterateUpTo(completedSerial)) {
ASSERT(allocation.GetInfo().mMethod == AllocationMethod::kSubAllocated); ASSERT(allocation.GetInfo().mMethod == AllocationMethod::kSubAllocated);

View File

@ -18,6 +18,7 @@
#include "common/SerialQueue.h" #include "common/SerialQueue.h"
#include "common/vulkan_platform.h" #include "common/vulkan_platform.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/PooledResourceMemoryAllocator.h" #include "dawn_native/PooledResourceMemoryAllocator.h"
#include "dawn_native/ResourceMemoryAllocation.h" #include "dawn_native/ResourceMemoryAllocation.h"
@ -39,7 +40,7 @@ namespace dawn_native { namespace vulkan {
void DestroyPool(); void DestroyPool();
void Tick(Serial completedSerial); void Tick(ExecutionSerial completedSerial);
int FindBestTypeIndex(VkMemoryRequirements requirements, bool mappable); int FindBestTypeIndex(VkMemoryRequirements requirements, bool mappable);
@ -49,7 +50,7 @@ namespace dawn_native { namespace vulkan {
class SingleTypeAllocator; class SingleTypeAllocator;
std::vector<std::unique_ptr<SingleTypeAllocator>> mAllocatorsPerType; std::vector<std::unique_ptr<SingleTypeAllocator>> mAllocatorsPerType;
SerialQueue<Serial, ResourceMemoryAllocation> mSubAllocationsToDelete; SerialQueue<ExecutionSerial, ResourceMemoryAllocation> mSubAllocationsToDelete;
}; };
}} // namespace dawn_native::vulkan }} // namespace dawn_native::vulkan

View File

@ -31,14 +31,15 @@ TEST(RingBufferAllocatorTests, BasicTest) {
ASSERT_EQ(allocator.GetSize(), sizeInBytes); ASSERT_EQ(allocator.GetSize(), sizeInBytes);
// Ensure failure upon sub-allocating an oversized request. // Ensure failure upon sub-allocating an oversized request.
ASSERT_EQ(allocator.Allocate(sizeInBytes + 1, 0), RingBufferAllocator::kInvalidOffset); ASSERT_EQ(allocator.Allocate(sizeInBytes + 1, ExecutionSerial(0)),
RingBufferAllocator::kInvalidOffset);
// Fill the entire buffer with two requests of equal size. // Fill the entire buffer with two requests of equal size.
ASSERT_EQ(allocator.Allocate(sizeInBytes / 2, 1), 0u); ASSERT_EQ(allocator.Allocate(sizeInBytes / 2, ExecutionSerial(1)), 0u);
ASSERT_EQ(allocator.Allocate(sizeInBytes / 2, 2), 32000u); ASSERT_EQ(allocator.Allocate(sizeInBytes / 2, ExecutionSerial(2)), 32000u);
// Ensure the buffer is full. // Ensure the buffer is full.
ASSERT_EQ(allocator.Allocate(1, 3), RingBufferAllocator::kInvalidOffset); ASSERT_EQ(allocator.Allocate(1, ExecutionSerial(3)), RingBufferAllocator::kInvalidOffset);
} }
// Tests that several ringbuffer allocations do not fail. // Tests that several ringbuffer allocations do not fail.
@ -49,9 +50,9 @@ TEST(RingBufferAllocatorTests, RingBufferManyAlloc) {
RingBufferAllocator allocator(maxNumOfFrames * frameSizeInBytes); RingBufferAllocator allocator(maxNumOfFrames * frameSizeInBytes);
size_t offset = 0; size_t offset = 0;
for (size_t i = 0; i < maxNumOfFrames; ++i) { for (ExecutionSerial i(0); i < ExecutionSerial(maxNumOfFrames); ++i) {
offset = allocator.Allocate(frameSizeInBytes, i); offset = allocator.Allocate(frameSizeInBytes, i);
ASSERT_EQ(offset, i * frameSizeInBytes); ASSERT_EQ(offset, uint64_t(i) * frameSizeInBytes);
} }
} }
@ -64,22 +65,22 @@ TEST(RingBufferAllocatorTests, AllocInSameFrame) {
// F1 // F1
// [xxxx|--------] // [xxxx|--------]
size_t offset = allocator.Allocate(frameSizeInBytes, 1); size_t offset = allocator.Allocate(frameSizeInBytes, ExecutionSerial(1));
// F1 F2 // F1 F2
// [xxxx|xxxx|----] // [xxxx|xxxx|----]
offset = allocator.Allocate(frameSizeInBytes, 2); offset = allocator.Allocate(frameSizeInBytes, ExecutionSerial(2));
// F1 F2 // F1 F2
// [xxxx|xxxxxxxx] // [xxxx|xxxxxxxx]
offset = allocator.Allocate(frameSizeInBytes, 2); offset = allocator.Allocate(frameSizeInBytes, ExecutionSerial(2));
ASSERT_EQ(offset, 8u); ASSERT_EQ(offset, 8u);
ASSERT_EQ(allocator.GetUsedSize(), frameSizeInBytes * 3); ASSERT_EQ(allocator.GetUsedSize(), frameSizeInBytes * 3);
allocator.Deallocate(2); allocator.Deallocate(ExecutionSerial(2));
ASSERT_EQ(allocator.GetUsedSize(), 0u); ASSERT_EQ(allocator.GetUsedSize(), 0u);
EXPECT_TRUE(allocator.Empty()); EXPECT_TRUE(allocator.Empty());
@ -93,10 +94,10 @@ TEST(RingBufferAllocatorTests, RingBufferSubAlloc) {
RingBufferAllocator allocator(maxNumOfFrames * frameSizeInBytes); RingBufferAllocator allocator(maxNumOfFrames * frameSizeInBytes);
// Sub-alloc the first eight frames. // Sub-alloc the first eight frames.
Serial serial = 1; ExecutionSerial serial(0);
for (size_t i = 0; i < 8; ++i) { while (serial < ExecutionSerial(8)) {
allocator.Allocate(frameSizeInBytes, serial); allocator.Allocate(frameSizeInBytes, serial);
serial += 1; serial++;
} }
// Each frame corrresponds to the serial number (for simplicity). // Each frame corrresponds to the serial number (for simplicity).
@ -106,12 +107,12 @@ TEST(RingBufferAllocatorTests, RingBufferSubAlloc) {
// //
// Ensure an oversized allocation fails (only 8 bytes left) // Ensure an oversized allocation fails (only 8 bytes left)
ASSERT_EQ(allocator.Allocate(frameSizeInBytes * 3, serial + 1), ASSERT_EQ(allocator.Allocate(frameSizeInBytes * 3, serial),
RingBufferAllocator::kInvalidOffset); RingBufferAllocator::kInvalidOffset);
ASSERT_EQ(allocator.GetUsedSize(), frameSizeInBytes * 8); ASSERT_EQ(allocator.GetUsedSize(), frameSizeInBytes * 8);
// Reclaim the first 3 frames. // Reclaim the first 3 frames.
allocator.Deallocate(3); allocator.Deallocate(ExecutionSerial(2));
// F4 F5 F6 F7 F8 // F4 F5 F6 F7 F8
// [------------|xxxx|xxxx|xxxx|xxxx|xxxx|--------] // [------------|xxxx|xxxx|xxxx|xxxx|xxxx|--------]
@ -119,7 +120,7 @@ TEST(RingBufferAllocatorTests, RingBufferSubAlloc) {
ASSERT_EQ(allocator.GetUsedSize(), frameSizeInBytes * 5); ASSERT_EQ(allocator.GetUsedSize(), frameSizeInBytes * 5);
// Re-try the over-sized allocation. // Re-try the over-sized allocation.
size_t offset = allocator.Allocate(frameSizeInBytes * 3, serial); size_t offset = allocator.Allocate(frameSizeInBytes * 3, ExecutionSerial(serial));
// F9 F4 F5 F6 F7 F8 // F9 F4 F5 F6 F7 F8
// [xxxxxxxxxxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxxxxxx] // [xxxxxxxxxxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxxxxxx]
@ -133,11 +134,10 @@ TEST(RingBufferAllocatorTests, RingBufferSubAlloc) {
ASSERT_EQ(allocator.GetUsedSize(), frameSizeInBytes * maxNumOfFrames); ASSERT_EQ(allocator.GetUsedSize(), frameSizeInBytes * maxNumOfFrames);
// Ensure we are full. // Ensure we are full.
ASSERT_EQ(allocator.Allocate(frameSizeInBytes, serial + 1), ASSERT_EQ(allocator.Allocate(frameSizeInBytes, serial), RingBufferAllocator::kInvalidOffset);
RingBufferAllocator::kInvalidOffset);
// Reclaim the next two frames. // Reclaim the next two frames.
allocator.Deallocate(5); allocator.Deallocate(ExecutionSerial(4));
// F9 F4 F5 F6 F7 F8 // F9 F4 F5 F6 F7 F8
// [xxxxxxxxxxxx|----|----|xxxx|xxxx|xxxx|xxxxxxxx] // [xxxxxxxxxxxx|----|----|xxxx|xxxx|xxxx|xxxxxxxx]
@ -145,7 +145,7 @@ TEST(RingBufferAllocatorTests, RingBufferSubAlloc) {
ASSERT_EQ(allocator.GetUsedSize(), frameSizeInBytes * 8); ASSERT_EQ(allocator.GetUsedSize(), frameSizeInBytes * 8);
// Sub-alloc the chunk in the middle. // Sub-alloc the chunk in the middle.
serial += 1; serial++;
offset = allocator.Allocate(frameSizeInBytes * 2, serial); offset = allocator.Allocate(frameSizeInBytes * 2, serial);
ASSERT_EQ(offset, frameSizeInBytes * 3); ASSERT_EQ(offset, frameSizeInBytes * 3);
@ -156,22 +156,19 @@ TEST(RingBufferAllocatorTests, RingBufferSubAlloc) {
// //
// Ensure we are full. // Ensure we are full.
ASSERT_EQ(allocator.Allocate(frameSizeInBytes, serial + 1), ASSERT_EQ(allocator.Allocate(frameSizeInBytes, serial), RingBufferAllocator::kInvalidOffset);
RingBufferAllocator::kInvalidOffset);
// Reclaim all. // Reclaim all.
allocator.Deallocate(maxNumOfFrames); allocator.Deallocate(kMaxExecutionSerial);
EXPECT_TRUE(allocator.Empty()); EXPECT_TRUE(allocator.Empty());
} }
// Checks if ringbuffer sub-allocation does not overflow. // Checks if ringbuffer sub-allocation does not overflow.
TEST(RingBufferAllocatorTests, RingBufferOverflow) { TEST(RingBufferAllocatorTests, RingBufferOverflow) {
Serial serial = 1;
RingBufferAllocator allocator(std::numeric_limits<uint64_t>::max()); RingBufferAllocator allocator(std::numeric_limits<uint64_t>::max());
ASSERT_EQ(allocator.Allocate(1, serial), 0u); ASSERT_EQ(allocator.Allocate(1, ExecutionSerial(1)), 0u);
ASSERT_EQ(allocator.Allocate(std::numeric_limits<uint64_t>::max(), serial + 1), ASSERT_EQ(allocator.Allocate(std::numeric_limits<uint64_t>::max(), ExecutionSerial(1)),
RingBufferAllocator::kInvalidOffset); RingBufferAllocator::kInvalidOffset);
} }