Refactor MapRequestTracker to be its own class file.

All the buffer backend files had basically the same implemenations
of MapRequestTracker and the tracker was owned by device backends.
This refactor puts MapRequestTracker into its own file
and has the tracker be owned by DeviceBase and BufferBase.

Bug: dawn:400
Change-Id: Id28422b575e9c04d4435d5f119e0ffe08c2d1ce8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/21760
Commit-Queue: Natasha Lee <natlee@microsoft.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Natasha Lee 2020-05-19 01:29:32 +00:00 committed by Commit Bot service account
parent 2ae84e9461
commit 949f1e45f1
25 changed files with 176 additions and 237 deletions

View File

@ -215,6 +215,8 @@ source_set("dawn_native_sources") {
"Forward.h",
"Instance.cpp",
"Instance.h",
"MapRequestTracker.cpp",
"MapRequestTracker.h",
"ObjectBase.cpp",
"ObjectBase.h",
"PassResourceUsage.h",

View File

@ -18,6 +18,7 @@
#include "dawn_native/Device.h"
#include "dawn_native/DynamicUploader.h"
#include "dawn_native/ErrorData.h"
#include "dawn_native/MapRequestTracker.h"
#include "dawn_native/ValidationUtils_autogen.h"
#include <cstdio>
@ -73,6 +74,9 @@ namespace dawn_native {
UNREACHABLE();
return {};
}
void* GetMappedPointerImpl() override {
return mFakeMappedData.get();
}
void UnmapImpl() override {
UNREACHABLE();
}
@ -267,8 +271,12 @@ namespace dawn_native {
mState = BufferState::Mapped;
if (GetDevice()->ConsumedError(MapReadAsyncImpl(mMapSerial))) {
// TODO(natlee@microsoft.com): if map op fails fire callback with DEVICE_LOST status
return;
}
MapRequestTracker* tracker = GetDevice()->GetMapRequestTracker();
tracker->Track(this, mMapSerial, false);
}
MaybeError BufferBase::SetSubDataImpl(uint32_t start, uint32_t count, const void* data) {
@ -304,8 +312,12 @@ namespace dawn_native {
mState = BufferState::Mapped;
if (GetDevice()->ConsumedError(MapWriteAsyncImpl(mMapSerial))) {
// TODO(natlee@microsoft.com): if map op fails fire callback with DEVICE_LOST status
return;
}
MapRequestTracker* tracker = GetDevice()->GetMapRequestTracker();
tracker->Track(this, mMapSerial, true);
}
void BufferBase::Destroy() {
@ -467,4 +479,13 @@ namespace dawn_native {
return mState == BufferState::Mapped;
}
void BufferBase::OnMapCommandSerialFinished(uint32_t mapSerial, bool isWrite) {
void* data = GetMappedPointerImpl();
if (isWrite) {
CallMapWriteCallback(mapSerial, WGPUBufferMapAsyncStatus_Success, data, GetSize());
} else {
CallMapReadCallback(mapSerial, WGPUBufferMapAsyncStatus_Success, data, GetSize());
}
}
} // namespace dawn_native

View File

@ -50,6 +50,7 @@ namespace dawn_native {
wgpu::BufferUsage GetUsage() const;
MaybeError MapAtCreation(uint8_t** mappedPointer);
void OnMapCommandSerialFinished(uint32_t mapSerial, bool isWrite);
MaybeError ValidateCanUseInSubmitNow() const;
@ -84,6 +85,7 @@ namespace dawn_native {
virtual MaybeError MapWriteAsyncImpl(uint32_t serial) = 0;
virtual void UnmapImpl() = 0;
virtual void DestroyImpl() = 0;
virtual void* GetMappedPointerImpl() = 0;
virtual bool IsMapWritable() const = 0;
MaybeError CopyFromStagingBuffer();

View File

@ -87,6 +87,8 @@ target_sources(dawn_native PRIVATE
"Forward.h"
"Instance.cpp"
"Instance.h"
"MapRequestTracker.cpp"
"MapRequestTracker.h"
"ObjectBase.cpp"
"ObjectBase.h"
"PassResourceUsage.h"

View File

@ -30,6 +30,7 @@
#include "dawn_native/Fence.h"
#include "dawn_native/FenceSignalTracker.h"
#include "dawn_native/Instance.h"
#include "dawn_native/MapRequestTracker.h"
#include "dawn_native/PipelineLayout.h"
#include "dawn_native/Queue.h"
#include "dawn_native/RenderBundleEncoder.h"
@ -102,6 +103,7 @@ namespace dawn_native {
mCaches = std::make_unique<DeviceBase::Caches>();
mErrorScopeTracker = std::make_unique<ErrorScopeTracker>(this);
mFenceSignalTracker = std::make_unique<FenceSignalTracker>(this);
mMapRequestTracker = std::make_unique<MapRequestTracker>(this);
mDynamicUploader = std::make_unique<DynamicUploader>(this);
mDeprecationWarnings = std::make_unique<DeprecationWarnings>();
@ -146,6 +148,7 @@ namespace dawn_native {
// pending callbacks.
mErrorScopeTracker->Tick(GetCompletedCommandSerial());
mFenceSignalTracker->Tick(GetCompletedCommandSerial());
mMapRequestTracker->Tick(GetCompletedCommandSerial());
}
// At this point GPU operations are always finished, so we are in the disconnected state.
@ -155,6 +158,7 @@ namespace dawn_native {
mCurrentErrorScope->UnlinkForShutdown();
mFenceSignalTracker = nullptr;
mDynamicUploader = nullptr;
mMapRequestTracker = nullptr;
// Tell the backend that it can free all the objects now that the GPU timeline is empty.
ShutDownImpl();
@ -301,6 +305,10 @@ namespace dawn_native {
return mFenceSignalTracker.get();
}
MapRequestTracker* DeviceBase::GetMapRequestTracker() const {
return mMapRequestTracker.get();
}
Serial DeviceBase::GetCompletedCommandSerial() const {
return mCompletedSerial;
}
@ -711,6 +719,7 @@ namespace dawn_native {
mDynamicUploader->Deallocate(GetCompletedCommandSerial());
mErrorScopeTracker->Tick(GetCompletedCommandSerial());
mFenceSignalTracker->Tick(GetCompletedCommandSerial());
mMapRequestTracker->Tick(GetCompletedCommandSerial());
}
void DeviceBase::Reference() {

View File

@ -37,6 +37,7 @@ namespace dawn_native {
class ErrorScope;
class ErrorScopeTracker;
class FenceSignalTracker;
class MapRequestTracker;
class StagingBufferBase;
class DeviceBase {
@ -71,6 +72,7 @@ namespace dawn_native {
ErrorScopeTracker* GetErrorScopeTracker() const;
FenceSignalTracker* GetFenceSignalTracker() const;
MapRequestTracker* GetMapRequestTracker() const;
// Returns the Format corresponding to the wgpu::TextureFormat or an error if the format
// isn't a valid wgpu::TextureFormat or isn't supported by this device.
@ -331,6 +333,7 @@ namespace dawn_native {
std::unique_ptr<DynamicUploader> mDynamicUploader;
std::unique_ptr<ErrorScopeTracker> mErrorScopeTracker;
std::unique_ptr<FenceSignalTracker> mFenceSignalTracker;
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
Ref<QueueBase> mDefaultQueue;
struct DeprecationWarnings;

View File

@ -0,0 +1,45 @@
// Copyright 2020 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn_native/MapRequestTracker.h"
#include "dawn_native/Buffer.h"
#include "dawn_native/Device.h"
namespace dawn_native {
struct Request;
class DeviceBase;
MapRequestTracker::MapRequestTracker(DeviceBase* device) : mDevice(device) {
}
MapRequestTracker::~MapRequestTracker() {
ASSERT(mInflightRequests.Empty());
}
void MapRequestTracker::Track(BufferBase* buffer, uint32_t mapSerial, bool isWrite) {
Request request;
request.buffer = buffer;
request.mapSerial = mapSerial;
request.isWrite = isWrite;
mInflightRequests.Enqueue(std::move(request), mDevice->GetPendingCommandSerial());
}
void MapRequestTracker::Tick(Serial finishedSerial) {
for (auto& request : mInflightRequests.IterateUpTo(finishedSerial)) {
request.buffer->OnMapCommandSerialFinished(request.mapSerial, request.isWrite);
}
mInflightRequests.ClearUpTo(finishedSerial);
}
} // namespace dawn_native

View File

@ -0,0 +1,44 @@
// Copyright 2020 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 DAWNNATIVE_MAPREQUESTTRACKER_H_
#define DAWNNATIVE_MAPREQUESTTRACKER_H_
#include "common/SerialQueue.h"
#include "dawn_native/Device.h"
namespace dawn_native {
class MapRequestTracker {
public:
MapRequestTracker(DeviceBase* device);
~MapRequestTracker();
void Track(BufferBase* buffer, uint32_t mapSerial, bool isWrite);
void Tick(Serial finishedSerial);
private:
DeviceBase* mDevice;
struct Request {
Ref<BufferBase> buffer;
uint32_t mapSerial;
bool isWrite;
};
SerialQueue<Request> mInflightRequests;
};
} // namespace dawn_native
#endif // DAWNNATIVE_MAPREQUESTTRACKER_H

View File

@ -233,14 +233,6 @@ namespace dawn_native { namespace d3d12 {
return mResourceAllocation.GetGPUPointer();
}
void Buffer::OnMapCommandSerialFinished(uint32_t mapSerial, void* data, bool isWrite) {
if (isWrite) {
CallMapWriteCallback(mapSerial, WGPUBufferMapAsyncStatus_Success, data, GetSize());
} else {
CallMapReadCallback(mapSerial, WGPUBufferMapAsyncStatus_Success, data, GetSize());
}
}
bool Buffer::IsMapWritable() const {
// TODO(enga): Handle CPU-visible memory on UMA
return (GetUsage() & (wgpu::BufferUsage::MapRead | wgpu::BufferUsage::MapWrite)) != 0;
@ -256,6 +248,7 @@ namespace dawn_native { namespace d3d12 {
DAWN_TRY(CheckHRESULT(GetD3D12Resource()->Map(0, &mWrittenMappedRange,
reinterpret_cast<void**>(mappedPointer)),
"D3D12 map at creation"));
mMappedData = reinterpret_cast<char*>(mappedPointer);
return {};
}
@ -267,14 +260,11 @@ namespace dawn_native { namespace d3d12 {
mWrittenMappedRange = {};
D3D12_RANGE readRange = {0, static_cast<size_t>(GetSize())};
char* data = nullptr;
DAWN_TRY(
CheckHRESULT(GetD3D12Resource()->Map(0, &readRange, reinterpret_cast<void**>(&data)),
"D3D12 map read async"));
DAWN_TRY(CheckHRESULT(
GetD3D12Resource()->Map(0, &readRange, reinterpret_cast<void**>(&mMappedData)),
"D3D12 map read async"));
// There is no need to transition the resource to a new state: D3D12 seems to make the GPU
// writes available when the fence is passed.
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapRequestTracker();
tracker->Track(this, serial, data, false);
return {};
}
@ -285,14 +275,11 @@ namespace dawn_native { namespace d3d12 {
DAWN_TRY(ToBackend(GetDevice())->GetResidencyManager()->LockHeap(heap));
mWrittenMappedRange = {0, static_cast<size_t>(GetSize())};
char* data = nullptr;
DAWN_TRY(CheckHRESULT(
GetD3D12Resource()->Map(0, &mWrittenMappedRange, reinterpret_cast<void**>(&data)),
"D3D12 map write async"));
DAWN_TRY(CheckHRESULT(GetD3D12Resource()->Map(0, &mWrittenMappedRange,
reinterpret_cast<void**>(&mMappedData)),
"D3D12 map write async"));
// There is no need to transition the resource to a new state: D3D12 seems to make the CPU
// writes available on queue submission.
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapRequestTracker();
tracker->Track(this, serial, data, true);
return {};
}
@ -303,6 +290,11 @@ namespace dawn_native { namespace d3d12 {
Heap* heap = ToBackend(mResourceAllocation.GetResourceHeap());
ToBackend(GetDevice())->GetResidencyManager()->UnlockHeap(heap);
mWrittenMappedRange = {};
mMappedData = nullptr;
}
void* Buffer::GetMappedPointerImpl() {
return mMappedData;
}
void Buffer::DestroyImpl() {
@ -325,29 +317,4 @@ namespace dawn_native { namespace d3d12 {
return mResourceAllocation.GetInfo().mMethod == allocationMethod;
}
MapRequestTracker::MapRequestTracker(Device* device) : mDevice(device) {
}
MapRequestTracker::~MapRequestTracker() {
ASSERT(mInflightRequests.Empty());
}
void MapRequestTracker::Track(Buffer* buffer, uint32_t mapSerial, void* data, bool isWrite) {
Request request;
request.buffer = buffer;
request.mapSerial = mapSerial;
request.data = data;
request.isWrite = isWrite;
mInflightRequests.Enqueue(std::move(request), mDevice->GetPendingCommandSerial());
}
void MapRequestTracker::Tick(Serial finishedSerial) {
for (auto& request : mInflightRequests.IterateUpTo(finishedSerial)) {
request.buffer->OnMapCommandSerialFinished(request.mapSerial, request.data,
request.isWrite);
}
mInflightRequests.ClearUpTo(finishedSerial);
}
}} // namespace dawn_native::d3d12

View File

@ -34,7 +34,6 @@ namespace dawn_native { namespace d3d12 {
ComPtr<ID3D12Resource> GetD3D12Resource() const;
D3D12_GPU_VIRTUAL_ADDRESS GetVA() const;
void OnMapCommandSerialFinished(uint32_t mapSerial, void* data, bool isWrite);
bool TrackUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
D3D12_RESOURCE_BARRIER* barrier,
@ -55,6 +54,7 @@ namespace dawn_native { namespace d3d12 {
bool IsMapWritable() const override;
virtual MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
void* GetMappedPointerImpl() override;
bool TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
D3D12_RESOURCE_BARRIER* barrier,
@ -65,26 +65,7 @@ namespace dawn_native { namespace d3d12 {
wgpu::BufferUsage mLastUsage = wgpu::BufferUsage::None;
Serial mLastUsedSerial = UINT64_MAX;
D3D12_RANGE mWrittenMappedRange;
};
class MapRequestTracker {
public:
MapRequestTracker(Device* device);
~MapRequestTracker();
void Track(Buffer* buffer, uint32_t mapSerial, void* data, bool isWrite);
void Tick(Serial finishedSerial);
private:
Device* mDevice;
struct Request {
Ref<Buffer> buffer;
uint32_t mapSerial;
void* data;
bool isWrite;
};
SerialQueue<Request> mInflightRequests;
char* mMappedData = nullptr;
};
}} // namespace dawn_native::d3d12

View File

@ -112,7 +112,6 @@ namespace dawn_native { namespace d3d12 {
mSamplerHeapCache = std::make_unique<SamplerHeapCache>(this);
mMapRequestTracker = std::make_unique<MapRequestTracker>(this);
mResidencyManager = std::make_unique<ResidencyManager>(this);
mResourceAllocatorManager = std::make_unique<ResourceAllocatorManager>(this);
@ -189,10 +188,6 @@ namespace dawn_native { namespace d3d12 {
return ToBackend(GetAdapter())->GetBackend()->GetFunctions();
}
MapRequestTracker* Device::GetMapRequestTracker() const {
return mMapRequestTracker.get();
}
CommandAllocatorManager* Device::GetCommandAllocatorManager() const {
return mCommandAllocatorManager.get();
}
@ -222,7 +217,6 @@ namespace dawn_native { namespace d3d12 {
mSamplerShaderVisibleDescriptorAllocator->Tick(completedSerial);
mRenderTargetViewAllocator->Tick(completedSerial);
mDepthStencilViewAllocator->Tick(completedSerial);
mMapRequestTracker->Tick(completedSerial);
mUsedComObjectRefs.ClearUpTo(completedSerial);
DAWN_TRY(ExecutePendingCommandContext());
DAWN_TRY(NextSerial());

View File

@ -31,7 +31,6 @@ namespace dawn_native { namespace d3d12 {
class CommandAllocatorManager;
class DescriptorHeapAllocator;
class MapRequestTracker;
class PlatformFunctions;
class ResidencyManager;
class ResourceAllocatorManager;
@ -66,7 +65,6 @@ namespace dawn_native { namespace d3d12 {
ComPtr<ID3D12CommandSignature> GetDrawIndirectSignature() const;
ComPtr<ID3D12CommandSignature> GetDrawIndexedIndirectSignature() const;
MapRequestTracker* GetMapRequestTracker() const;
CommandAllocatorManager* GetCommandAllocatorManager() const;
ResidencyManager* GetResidencyManager() const;
@ -179,7 +177,6 @@ namespace dawn_native { namespace d3d12 {
SerialQueue<ComPtr<IUnknown>> mUsedComObjectRefs;
std::unique_ptr<CommandAllocatorManager> mCommandAllocatorManager;
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
std::unique_ptr<ResourceAllocatorManager> mResourceAllocatorManager;
std::unique_ptr<ResidencyManager> mResidencyManager;

View File

@ -29,8 +29,6 @@ namespace dawn_native { namespace metal {
static ResultOrError<Buffer*> Create(Device* device, const BufferDescriptor* descriptor);
id<MTLBuffer> GetMTLBuffer() const;
void OnMapCommandSerialFinished(uint32_t mapSerial, bool isWrite);
private:
using BufferBase::BufferBase;
MaybeError Initialize();
@ -40,6 +38,7 @@ namespace dawn_native { namespace metal {
MaybeError MapWriteAsyncImpl(uint32_t serial) override;
void UnmapImpl() override;
void DestroyImpl() override;
void* GetMappedPointerImpl() override;
bool IsMapWritable() const override;
MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
@ -47,25 +46,6 @@ namespace dawn_native { namespace metal {
id<MTLBuffer> mMtlBuffer = nil;
};
class MapRequestTracker {
public:
MapRequestTracker(Device* device);
~MapRequestTracker();
void Track(Buffer* buffer, uint32_t mapSerial, bool isWrite);
void Tick(Serial finishedSerial);
private:
Device* mDevice;
struct Request {
Ref<Buffer> buffer;
uint32_t mapSerial;
bool isWrite;
};
SerialQueue<Request> mInflightRequests;
};
}} // namespace dawn_native::metal
#endif // DAWNNATIVE_METAL_BUFFERMTL_H_

View File

@ -67,15 +67,6 @@ namespace dawn_native { namespace metal {
return mMtlBuffer;
}
void Buffer::OnMapCommandSerialFinished(uint32_t mapSerial, bool isWrite) {
char* data = reinterpret_cast<char*>([mMtlBuffer contents]);
if (isWrite) {
CallMapWriteCallback(mapSerial, WGPUBufferMapAsyncStatus_Success, data, GetSize());
} else {
CallMapReadCallback(mapSerial, WGPUBufferMapAsyncStatus_Success, data, GetSize());
}
}
bool Buffer::IsMapWritable() const {
// TODO(enga): Handle CPU-visible memory on UMA
return (GetUsage() & (wgpu::BufferUsage::MapRead | wgpu::BufferUsage::MapWrite)) != 0;
@ -87,17 +78,17 @@ namespace dawn_native { namespace metal {
}
MaybeError Buffer::MapReadAsyncImpl(uint32_t serial) {
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapTracker();
tracker->Track(this, serial, false);
return {};
}
MaybeError Buffer::MapWriteAsyncImpl(uint32_t serial) {
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapTracker();
tracker->Track(this, serial, true);
return {};
}
void* Buffer::GetMappedPointerImpl() {
return reinterpret_cast<uint8_t*>([mMtlBuffer contents]);
}
void Buffer::UnmapImpl() {
// Nothing to do, Metal StorageModeShared buffers are always mapped.
}
@ -107,29 +98,4 @@ namespace dawn_native { namespace metal {
mMtlBuffer = nil;
}
MapRequestTracker::MapRequestTracker(Device* device) : mDevice(device) {
}
MapRequestTracker::~MapRequestTracker() {
ASSERT(mInflightRequests.Empty());
}
void MapRequestTracker::Track(Buffer* buffer,
uint32_t mapSerial,
bool isWrite) {
Request request;
request.buffer = buffer;
request.mapSerial = mapSerial;
request.isWrite = isWrite;
mInflightRequests.Enqueue(std::move(request), mDevice->GetPendingCommandSerial());
}
void MapRequestTracker::Tick(Serial finishedSerial) {
for (auto& request : mInflightRequests.IterateUpTo(finishedSerial)) {
request.buffer->OnMapCommandSerialFinished(request.mapSerial, request.isWrite);
}
mInflightRequests.ClearUpTo(finishedSerial);
}
}} // namespace dawn_native::metal

View File

@ -32,8 +32,6 @@
namespace dawn_native { namespace metal {
class MapRequestTracker;
class Device : public DeviceBase {
public:
static ResultOrError<Device*> Create(AdapterBase* adapter,
@ -54,8 +52,6 @@ namespace dawn_native { namespace metal {
CommandRecordingContext* GetPendingCommandContext();
void SubmitPendingCommandBuffer();
MapRequestTracker* GetMapTracker() const;
TextureBase* CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
IOSurfaceRef ioSurface,
uint32_t plane);
@ -104,7 +100,6 @@ namespace dawn_native { namespace metal {
id<MTLDevice> mMtlDevice = nil;
id<MTLCommandQueue> mCommandQueue = nil;
std::unique_ptr<MapRequestTracker> mMapTracker;
CommandRecordingContext mCommandContext;

View File

@ -51,7 +51,6 @@ namespace dawn_native { namespace metal {
const DeviceDescriptor* descriptor)
: DeviceBase(adapter, descriptor),
mMtlDevice([mtlDevice retain]),
mMapTracker(new MapRequestTracker(this)),
mCompletedSerial(0) {
[mMtlDevice retain];
}
@ -170,8 +169,6 @@ namespace dawn_native { namespace metal {
CheckPassedSerials();
Serial completedSerial = GetCompletedCommandSerial();
mMapTracker->Tick(completedSerial);
if (mCommandContext.GetCommands() != nil) {
SubmitPendingCommandBuffer();
} else if (completedSerial == GetLastSubmittedCommandSerial()) {
@ -245,10 +242,6 @@ namespace dawn_native { namespace metal {
[pendingCommands release];
}
MapRequestTracker* Device::GetMapTracker() const {
return mMapTracker.get();
}
ResultOrError<std::unique_ptr<StagingBufferBase>> Device::CreateStagingBuffer(size_t size) {
std::unique_ptr<StagingBufferBase> stagingBuffer =
std::make_unique<StagingBuffer>(size, this);
@ -323,8 +316,6 @@ namespace dawn_native { namespace metal {
[mCommandContext.AcquireCommands() release];
mMapTracker = nullptr;
[mCommandQueue release];
mCommandQueue = nil;

View File

@ -266,7 +266,7 @@ namespace dawn_native { namespace null {
struct BufferMapOperation : PendingOperation {
virtual void Execute() {
buffer->MapOperationCompleted(serial, ptr, isWrite);
buffer->OnMapCommandSerialFinished(serial, isWrite);
}
Ref<Buffer> buffer;
@ -296,14 +296,6 @@ namespace dawn_native { namespace null {
return {};
}
void Buffer::MapOperationCompleted(uint32_t serial, void* ptr, bool isWrite) {
if (isWrite) {
CallMapWriteCallback(serial, WGPUBufferMapAsyncStatus_Success, ptr, GetSize());
} else {
CallMapReadCallback(serial, WGPUBufferMapAsyncStatus_Success, ptr, GetSize());
}
}
void Buffer::CopyFromStaging(StagingBufferBase* staging,
uint64_t sourceOffset,
uint64_t destinationOffset,
@ -341,6 +333,10 @@ namespace dawn_native { namespace null {
ToBackend(GetDevice())->AddPendingOperation(std::move(operation));
}
void* Buffer::GetMappedPointerImpl() {
return mBackingData.get();
}
void Buffer::UnmapImpl() {
}

View File

@ -182,7 +182,6 @@ namespace dawn_native { namespace null {
public:
Buffer(Device* device, const BufferDescriptor* descriptor);
void MapOperationCompleted(uint32_t serial, void* ptr, bool isWrite);
void CopyFromStaging(StagingBufferBase* staging,
uint64_t sourceOffset,
uint64_t destinationOffset,
@ -201,6 +200,7 @@ namespace dawn_native { namespace null {
bool IsMapWritable() const override;
MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
void MapAsyncImplCommon(uint32_t serial, bool isWrite);
void* GetMappedPointerImpl() override;
std::unique_ptr<uint8_t[]> mBackingData;
};

View File

@ -45,8 +45,8 @@ namespace dawn_native { namespace opengl {
const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
gl.BindBuffer(GL_ARRAY_BUFFER, mBuffer);
void* data = gl.MapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
*mappedPointer = reinterpret_cast<uint8_t*>(data);
mMappedData = gl.MapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
*mappedPointer = reinterpret_cast<uint8_t*>(mMappedData);
return {};
}
@ -64,8 +64,7 @@ namespace dawn_native { namespace opengl {
// TODO(cwallez@chromium.org): this does GPU->CPU synchronization, we could require a high
// version of OpenGL that would let us map the buffer unsynchronized.
gl.BindBuffer(GL_ARRAY_BUFFER, mBuffer);
void* data = gl.MapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
CallMapReadCallback(serial, WGPUBufferMapAsyncStatus_Success, data, GetSize());
mMappedData = gl.MapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
return {};
}
@ -75,16 +74,20 @@ namespace dawn_native { namespace opengl {
// TODO(cwallez@chromium.org): this does GPU->CPU synchronization, we could require a high
// version of OpenGL that would let us map the buffer unsynchronized.
gl.BindBuffer(GL_ARRAY_BUFFER, mBuffer);
void* data = gl.MapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
CallMapWriteCallback(serial, WGPUBufferMapAsyncStatus_Success, data, GetSize());
mMappedData = gl.MapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
return {};
}
void* Buffer::GetMappedPointerImpl() {
return mMappedData;
}
void Buffer::UnmapImpl() {
const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
gl.BindBuffer(GL_ARRAY_BUFFER, mBuffer);
gl.UnmapBuffer(GL_ARRAY_BUFFER);
mMappedData = nullptr;
}
void Buffer::DestroyImpl() {

View File

@ -40,8 +40,10 @@ namespace dawn_native { namespace opengl {
bool IsMapWritable() const override;
MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
void* GetMappedPointerImpl() override;
GLuint mBuffer = 0;
void* mMappedData = nullptr;
};
}} // namespace dawn_native::opengl

View File

@ -153,6 +153,11 @@ namespace dawn_native { namespace opengl {
MaybeError Device::TickImpl() {
CheckPassedSerials();
if (GetCompletedCommandSerial() == GetLastSubmittedCommandSerial()) {
// If there's no GPU work in flight we still need to artificially increment the serial
// so that CPU operations waiting on GPU completion can know they don't have to wait.
ArtificiallyIncrementSerials();
}
return {};
}

View File

@ -236,12 +236,6 @@ namespace dawn_native { namespace vulkan {
CommandRecordingContext* recordingContext = device->GetPendingRecordingContext();
TransitionUsageNow(recordingContext, wgpu::BufferUsage::MapRead);
uint8_t* memory = mMemoryAllocation.GetMappedPointer();
ASSERT(memory != nullptr);
MapRequestTracker* tracker = device->GetMapRequestTracker();
tracker->Track(this, serial, memory, false);
return {};
}
@ -250,12 +244,6 @@ namespace dawn_native { namespace vulkan {
CommandRecordingContext* recordingContext = device->GetPendingRecordingContext();
TransitionUsageNow(recordingContext, wgpu::BufferUsage::MapWrite);
uint8_t* memory = mMemoryAllocation.GetMappedPointer();
ASSERT(memory != nullptr);
MapRequestTracker* tracker = device->GetMapRequestTracker();
tracker->Track(this, serial, memory, true);
return {};
}
@ -263,6 +251,12 @@ namespace dawn_native { namespace vulkan {
// No need to do anything, we keep CPU-visible memory mapped at all time.
}
void* Buffer::GetMappedPointerImpl() {
uint8_t* memory = mMemoryAllocation.GetMappedPointer();
ASSERT(memory != nullptr);
return memory;
}
void Buffer::DestroyImpl() {
ToBackend(GetDevice())->DeallocateMemory(&mMemoryAllocation);
@ -272,34 +266,4 @@ namespace dawn_native { namespace vulkan {
}
}
// MapRequestTracker
MapRequestTracker::MapRequestTracker(Device* device) : mDevice(device) {
}
MapRequestTracker::~MapRequestTracker() {
ASSERT(mInflightRequests.Empty());
}
void MapRequestTracker::Track(Buffer* buffer, uint32_t mapSerial, void* data, bool isWrite) {
Request request;
request.buffer = buffer;
request.mapSerial = mapSerial;
request.data = data;
request.isWrite = isWrite;
mInflightRequests.Enqueue(std::move(request), mDevice->GetPendingCommandSerial());
}
void MapRequestTracker::Tick(Serial finishedSerial) {
for (auto& request : mInflightRequests.IterateUpTo(finishedSerial)) {
if (request.isWrite) {
request.buffer->OnMapWriteCommandSerialFinished(request.mapSerial, request.data);
} else {
request.buffer->OnMapReadCommandSerialFinished(request.mapSerial, request.data);
}
}
mInflightRequests.ClearUpTo(finishedSerial);
}
}} // namespace dawn_native::vulkan

View File

@ -53,6 +53,7 @@ namespace dawn_native { namespace vulkan {
bool IsMapWritable() const override;
MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
void* GetMappedPointerImpl() override;
VkBuffer mHandle = VK_NULL_HANDLE;
ResourceMemoryAllocation mMemoryAllocation;
@ -60,26 +61,6 @@ namespace dawn_native { namespace vulkan {
wgpu::BufferUsage mLastUsage = wgpu::BufferUsage::None;
};
class MapRequestTracker {
public:
MapRequestTracker(Device* device);
~MapRequestTracker();
void Track(Buffer* buffer, uint32_t mapSerial, void* data, bool isWrite);
void Tick(Serial finishedSerial);
private:
Device* mDevice;
struct Request {
Ref<Buffer> buffer;
uint32_t mapSerial;
void* data;
bool isWrite;
};
SerialQueue<Request> mInflightRequests;
};
}} // namespace dawn_native::vulkan
#endif // DAWNNATIVE_VULKAN_BUFFERVK_H_

View File

@ -82,7 +82,6 @@ namespace dawn_native { namespace vulkan {
mDeleter = std::make_unique<FencedDeleter>(this);
}
mMapRequestTracker = std::make_unique<MapRequestTracker>(this);
mRenderPassCache = std::make_unique<RenderPassCache>(this);
mResourceMemoryAllocator = std::make_unique<ResourceMemoryAllocator>(this);
@ -167,7 +166,6 @@ namespace dawn_native { namespace vulkan {
}
mBindGroupLayoutsPendingDeallocation.ClearUpTo(completedSerial);
mMapRequestTracker->Tick(completedSerial);
mResourceMemoryAllocator->Tick(completedSerial);
mDeleter->Tick(completedSerial);
@ -201,10 +199,6 @@ namespace dawn_native { namespace vulkan {
return mQueue;
}
MapRequestTracker* Device::GetMapRequestTracker() const {
return mMapRequestTracker.get();
}
FencedDeleter* Device::GetFencedDeleter() const {
return mDeleter.get();
}
@ -802,8 +796,6 @@ namespace dawn_native { namespace vulkan {
// Call Tick() again to clear them before releasing the deleter.
mDeleter->Tick(GetCompletedCommandSerial());
mMapRequestTracker = nullptr;
// The VkRenderPasses in the cache can be destroyed immediately since all commands referring
// to them are guaranteed to be finished executing.
mRenderPassCache = nullptr;

View File

@ -37,7 +37,6 @@ namespace dawn_native { namespace vulkan {
class BindGroupLayout;
class BufferUploader;
class FencedDeleter;
class MapRequestTracker;
class RenderPassCache;
class ResourceMemoryAllocator;
@ -59,7 +58,6 @@ namespace dawn_native { namespace vulkan {
BufferUploader* GetBufferUploader() const;
FencedDeleter* GetFencedDeleter() const;
MapRequestTracker* GetMapRequestTracker() const;
RenderPassCache* GetRenderPassCache() const;
CommandRecordingContext* GetPendingRecordingContext();
@ -147,7 +145,6 @@ namespace dawn_native { namespace vulkan {
SerialQueue<Ref<BindGroupLayout>> mBindGroupLayoutsPendingDeallocation;
std::unique_ptr<FencedDeleter> mDeleter;
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
std::unique_ptr<ResourceMemoryAllocator> mResourceMemoryAllocator;
std::unique_ptr<RenderPassCache> mRenderPassCache;