Memory manager: buffer uploads (Metal+refactor) - Part 3
Manages a single persistently mapped GPU heap which is sub-allocated inside of ring-buffer for uploads. To handle larger buffers without additional unused heaps, ring buffers are created on-demand. BUG=dawn:28 TEST=dawn_unittests Change-Id: If4d3e717186895b1409502c1dea5ab751a4776b2 Reviewed-on: https://dawn-review.googlesource.com/c/4440 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
This commit is contained in:
parent
695b68d100
commit
67a73bd9fa
4
BUILD.gn
4
BUILD.gn
|
@ -587,12 +587,12 @@ source_set("libdawn_native_sources") {
|
||||||
"src/dawn_native/metal/QueueMTL.mm",
|
"src/dawn_native/metal/QueueMTL.mm",
|
||||||
"src/dawn_native/metal/RenderPipelineMTL.h",
|
"src/dawn_native/metal/RenderPipelineMTL.h",
|
||||||
"src/dawn_native/metal/RenderPipelineMTL.mm",
|
"src/dawn_native/metal/RenderPipelineMTL.mm",
|
||||||
"src/dawn_native/metal/ResourceUploader.h",
|
|
||||||
"src/dawn_native/metal/ResourceUploader.mm",
|
|
||||||
"src/dawn_native/metal/SamplerMTL.h",
|
"src/dawn_native/metal/SamplerMTL.h",
|
||||||
"src/dawn_native/metal/SamplerMTL.mm",
|
"src/dawn_native/metal/SamplerMTL.mm",
|
||||||
"src/dawn_native/metal/ShaderModuleMTL.h",
|
"src/dawn_native/metal/ShaderModuleMTL.h",
|
||||||
"src/dawn_native/metal/ShaderModuleMTL.mm",
|
"src/dawn_native/metal/ShaderModuleMTL.mm",
|
||||||
|
"src/dawn_native/metal/StagingBufferMTL.h",
|
||||||
|
"src/dawn_native/metal/StagingBufferMTL.mm",
|
||||||
"src/dawn_native/metal/SwapChainMTL.h",
|
"src/dawn_native/metal/SwapChainMTL.h",
|
||||||
"src/dawn_native/metal/SwapChainMTL.mm",
|
"src/dawn_native/metal/SwapChainMTL.mm",
|
||||||
"src/dawn_native/metal/TextureMTL.h",
|
"src/dawn_native/metal/TextureMTL.h",
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "common/Assert.h"
|
#include "common/Assert.h"
|
||||||
#include "dawn_native/Device.h"
|
#include "dawn_native/Device.h"
|
||||||
|
#include "dawn_native/DynamicUploader.h"
|
||||||
#include "dawn_native/ValidationUtils_autogen.h"
|
#include "dawn_native/ValidationUtils_autogen.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -183,6 +184,26 @@ namespace dawn_native {
|
||||||
MapReadAsyncImpl(mMapSerial);
|
MapReadAsyncImpl(mMapSerial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeError BufferBase::SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) {
|
||||||
|
DynamicUploader* uploader = nullptr;
|
||||||
|
DAWN_TRY_ASSIGN(uploader, GetDevice()->GetDynamicUploader());
|
||||||
|
|
||||||
|
// TODO(bryan.bernhart@intel.com): Remove once alignment constraint is added to validation
|
||||||
|
// (dawn:73). D3D12 does not specify so we assume 4-byte alignment to be safe.
|
||||||
|
static constexpr size_t kDefaultAlignment = 4;
|
||||||
|
|
||||||
|
UploadHandle uploadHandle;
|
||||||
|
DAWN_TRY_ASSIGN(uploadHandle, uploader->Allocate(count, kDefaultAlignment));
|
||||||
|
ASSERT(uploadHandle.mappedBuffer != nullptr);
|
||||||
|
|
||||||
|
memcpy(uploadHandle.mappedBuffer, data, count);
|
||||||
|
|
||||||
|
DAWN_TRY(GetDevice()->CopyFromStagingToBuffer(
|
||||||
|
uploadHandle.stagingBuffer, uploadHandle.startOffset, this, start, count));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void BufferBase::MapWriteAsync(dawnBufferMapWriteCallback callback,
|
void BufferBase::MapWriteAsync(dawnBufferMapWriteCallback callback,
|
||||||
dawnCallbackUserdata userdata) {
|
dawnCallbackUserdata userdata) {
|
||||||
if (GetDevice()->ConsumedError(ValidateMap(dawn::BufferUsageBit::MapWrite))) {
|
if (GetDevice()->ConsumedError(ValidateMap(dawn::BufferUsageBit::MapWrite))) {
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace dawn_native {
|
||||||
uint32_t dataLength);
|
uint32_t dataLength);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) = 0;
|
virtual MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data);
|
||||||
virtual void MapReadAsyncImpl(uint32_t serial) = 0;
|
virtual void MapReadAsyncImpl(uint32_t serial) = 0;
|
||||||
virtual void MapWriteAsyncImpl(uint32_t serial) = 0;
|
virtual void MapWriteAsyncImpl(uint32_t serial) = 0;
|
||||||
virtual void UnmapImpl() = 0;
|
virtual void UnmapImpl() = 0;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "dawn_native/CommandBuffer.h"
|
#include "dawn_native/CommandBuffer.h"
|
||||||
#include "dawn_native/CommandEncoder.h"
|
#include "dawn_native/CommandEncoder.h"
|
||||||
#include "dawn_native/ComputePipeline.h"
|
#include "dawn_native/ComputePipeline.h"
|
||||||
|
#include "dawn_native/DynamicUploader.h"
|
||||||
#include "dawn_native/ErrorData.h"
|
#include "dawn_native/ErrorData.h"
|
||||||
#include "dawn_native/Fence.h"
|
#include "dawn_native/Fence.h"
|
||||||
#include "dawn_native/FenceSignalTracker.h"
|
#include "dawn_native/FenceSignalTracker.h"
|
||||||
|
@ -54,9 +55,12 @@ namespace dawn_native {
|
||||||
DeviceBase::DeviceBase(AdapterBase* adapter) : mAdapter(adapter) {
|
DeviceBase::DeviceBase(AdapterBase* adapter) : mAdapter(adapter) {
|
||||||
mCaches = std::make_unique<DeviceBase::Caches>();
|
mCaches = std::make_unique<DeviceBase::Caches>();
|
||||||
mFenceSignalTracker = std::make_unique<FenceSignalTracker>(this);
|
mFenceSignalTracker = std::make_unique<FenceSignalTracker>(this);
|
||||||
|
mDynamicUploader = std::make_unique<DynamicUploader>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceBase::~DeviceBase() {
|
DeviceBase::~DeviceBase() {
|
||||||
|
// Devices must explicitly free the uploader
|
||||||
|
ASSERT(mDynamicUploader == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::HandleError(const char* message) {
|
void DeviceBase::HandleError(const char* message) {
|
||||||
|
@ -377,4 +381,11 @@ namespace dawn_native {
|
||||||
delete error;
|
delete error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResultOrError<DynamicUploader*> DeviceBase::GetDynamicUploader() const {
|
||||||
|
if (mDynamicUploader->IsEmpty()) {
|
||||||
|
DAWN_TRY(mDynamicUploader->CreateAndAppendBuffer());
|
||||||
|
}
|
||||||
|
return mDynamicUploader.get();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
|
|
@ -124,6 +124,11 @@ namespace dawn_native {
|
||||||
uint32_t destinationOffset,
|
uint32_t destinationOffset,
|
||||||
uint32_t size) = 0;
|
uint32_t size) = 0;
|
||||||
|
|
||||||
|
ResultOrError<DynamicUploader*> GetDynamicUploader() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<DynamicUploader> mDynamicUploader;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
virtual ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
||||||
const BindGroupDescriptor* descriptor) = 0;
|
const BindGroupDescriptor* descriptor) = 0;
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace dawn_native {
|
||||||
newMaxSize *= 2;
|
newMaxSize *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b-brber): Fall-back to no sub-allocations should this fail.
|
// TODO(bryan.bernhart@intel.com): Fall-back to no sub-allocations should this fail.
|
||||||
DAWN_TRY(CreateAndAppendBuffer(newMaxSize));
|
DAWN_TRY(CreateAndAppendBuffer(newMaxSize));
|
||||||
largestRingBuffer = GetLargestBuffer();
|
largestRingBuffer = GetLargestBuffer();
|
||||||
uploadHandle = largestRingBuffer->SubAllocate(alignedSize);
|
uploadHandle = largestRingBuffer->SubAllocate(alignedSize);
|
||||||
|
|
|
@ -32,11 +32,14 @@ namespace dawn_native {
|
||||||
|
|
||||||
RingBuffer* GetLargestBuffer();
|
RingBuffer* GetLargestBuffer();
|
||||||
|
|
||||||
MaybeError CreateAndAppendBuffer(size_t size);
|
MaybeError CreateAndAppendBuffer(size_t size = kBaseUploadBufferSize);
|
||||||
|
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// TODO(bryan.bernhart@intel.com): Figure out this value.
|
||||||
|
static constexpr size_t kBaseUploadBufferSize = 64000;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<RingBuffer>> mRingBuffers;
|
std::vector<std::unique_ptr<RingBuffer>> mRingBuffers;
|
||||||
DeviceBase* mDevice;
|
DeviceBase* mDevice;
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
// only two indices that keep increasing (unbounded) but can be still indexed using bit masks.
|
// only two indices that keep increasing (unbounded) but can be still indexed using bit masks.
|
||||||
// However, this 1) requires the size to always be a power-of-two and 2) remove tests that check
|
// However, this 1) requires the size to always be a power-of-two and 2) remove tests that check
|
||||||
// used bytes.
|
// used bytes.
|
||||||
// TODO(b-brber): Follow-up with ringbuffer optimization.
|
// TODO(bryan.bernhart@intel.com): Follow-up with ringbuffer optimization.
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
|
|
||||||
static constexpr size_t INVALID_OFFSET = std::numeric_limits<size_t>::max();
|
static constexpr size_t INVALID_OFFSET = std::numeric_limits<size_t>::max();
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "common/Assert.h"
|
#include "common/Assert.h"
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
#include "common/Math.h"
|
#include "common/Math.h"
|
||||||
#include "dawn_native/DynamicUploader.h"
|
|
||||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||||
#include "dawn_native/d3d12/ResourceAllocator.h"
|
#include "dawn_native/d3d12/ResourceAllocator.h"
|
||||||
|
|
||||||
|
@ -161,24 +160,6 @@ namespace dawn_native { namespace d3d12 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) {
|
|
||||||
Device* device = ToBackend(GetDevice());
|
|
||||||
|
|
||||||
DynamicUploader* uploader = nullptr;
|
|
||||||
DAWN_TRY_ASSIGN(uploader, device->GetDynamicUploader());
|
|
||||||
|
|
||||||
UploadHandle uploadHandle;
|
|
||||||
DAWN_TRY_ASSIGN(uploadHandle, uploader->Allocate(count, kDefaultAlignment));
|
|
||||||
ASSERT(uploadHandle.mappedBuffer != nullptr);
|
|
||||||
|
|
||||||
memcpy(uploadHandle.mappedBuffer, data, count);
|
|
||||||
|
|
||||||
DAWN_TRY(device->CopyFromStagingToBuffer(uploadHandle.stagingBuffer,
|
|
||||||
uploadHandle.startOffset, this, start, count));
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
||||||
mWrittenMappedRange = {};
|
mWrittenMappedRange = {};
|
||||||
D3D12_RANGE readRange = {0, GetSize()};
|
D3D12_RANGE readRange = {0, GetSize()};
|
||||||
|
|
|
@ -39,15 +39,10 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Dawn API
|
// Dawn API
|
||||||
MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) override;
|
|
||||||
void MapReadAsyncImpl(uint32_t serial) override;
|
void MapReadAsyncImpl(uint32_t serial) override;
|
||||||
void MapWriteAsyncImpl(uint32_t serial) override;
|
void MapWriteAsyncImpl(uint32_t serial) override;
|
||||||
void UnmapImpl() override;
|
void UnmapImpl() override;
|
||||||
|
|
||||||
// TODO(b-brber): Remove once alignment constraint is added to validation (dawn:73).
|
|
||||||
static constexpr size_t kDefaultAlignment =
|
|
||||||
4; // D3D does not specify so we assume 4-byte alignment to be safe.
|
|
||||||
|
|
||||||
ComPtr<ID3D12Resource> mResource;
|
ComPtr<ID3D12Resource> mResource;
|
||||||
bool mFixedResourceState = false;
|
bool mFixedResourceState = false;
|
||||||
dawn::BufferUsageBit mLastUsage = dawn::BufferUsageBit::None;
|
dawn::BufferUsageBit mLastUsage = dawn::BufferUsageBit::None;
|
||||||
|
|
|
@ -63,7 +63,6 @@ namespace dawn_native { namespace d3d12 {
|
||||||
mDescriptorHeapAllocator = std::make_unique<DescriptorHeapAllocator>(this);
|
mDescriptorHeapAllocator = std::make_unique<DescriptorHeapAllocator>(this);
|
||||||
mMapRequestTracker = std::make_unique<MapRequestTracker>(this);
|
mMapRequestTracker = std::make_unique<MapRequestTracker>(this);
|
||||||
mResourceAllocator = std::make_unique<ResourceAllocator>(this);
|
mResourceAllocator = std::make_unique<ResourceAllocator>(this);
|
||||||
mDynamicUploader = std::make_unique<DynamicUploader>(this);
|
|
||||||
|
|
||||||
NextSerial();
|
NextSerial();
|
||||||
}
|
}
|
||||||
|
@ -73,6 +72,14 @@ namespace dawn_native { namespace d3d12 {
|
||||||
WaitForSerial(mLastSubmittedSerial); // Wait for all in-flight commands to finish executing
|
WaitForSerial(mLastSubmittedSerial); // Wait for all in-flight commands to finish executing
|
||||||
TickImpl(); // Call tick one last time so resources are cleaned up
|
TickImpl(); // Call tick one last time so resources are cleaned up
|
||||||
|
|
||||||
|
// Free services explicitly so that they can free D3D12 resources before destruction of the
|
||||||
|
// device.
|
||||||
|
mDynamicUploader = nullptr;
|
||||||
|
|
||||||
|
// Releasing the uploader enqueues buffers to be released.
|
||||||
|
// Call Tick() again to clear them before releasing the allocator.
|
||||||
|
mResourceAllocator->Tick(mCompletedSerial);
|
||||||
|
|
||||||
ASSERT(mUsedComObjectRefs.Empty());
|
ASSERT(mUsedComObjectRefs.Empty());
|
||||||
ASSERT(mPendingCommands.commandList == nullptr);
|
ASSERT(mPendingCommands.commandList == nullptr);
|
||||||
}
|
}
|
||||||
|
@ -143,12 +150,16 @@ namespace dawn_native { namespace d3d12 {
|
||||||
void Device::TickImpl() {
|
void Device::TickImpl() {
|
||||||
// Perform cleanup operations to free unused objects
|
// Perform cleanup operations to free unused objects
|
||||||
mCompletedSerial = mFence->GetCompletedValue();
|
mCompletedSerial = mFence->GetCompletedValue();
|
||||||
|
|
||||||
|
// Uploader should tick before the resource allocator
|
||||||
|
// as it enqueues resources to be released.
|
||||||
|
mDynamicUploader->Tick(mCompletedSerial);
|
||||||
|
|
||||||
mResourceAllocator->Tick(mCompletedSerial);
|
mResourceAllocator->Tick(mCompletedSerial);
|
||||||
mCommandAllocatorManager->Tick(mCompletedSerial);
|
mCommandAllocatorManager->Tick(mCompletedSerial);
|
||||||
mDescriptorHeapAllocator->Tick(mCompletedSerial);
|
mDescriptorHeapAllocator->Tick(mCompletedSerial);
|
||||||
mMapRequestTracker->Tick(mCompletedSerial);
|
mMapRequestTracker->Tick(mCompletedSerial);
|
||||||
mUsedComObjectRefs.ClearUpTo(mCompletedSerial);
|
mUsedComObjectRefs.ClearUpTo(mCompletedSerial);
|
||||||
mDynamicUploader->Tick(mCompletedSerial);
|
|
||||||
ExecuteCommandLists({});
|
ExecuteCommandLists({});
|
||||||
NextSerial();
|
NextSerial();
|
||||||
}
|
}
|
||||||
|
@ -265,12 +276,4 @@ namespace dawn_native { namespace d3d12 {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<DynamicUploader*> Device::GetDynamicUploader() const {
|
|
||||||
// TODO(b-brber): Refactor this into device init once moved into DeviceBase.
|
|
||||||
if (mDynamicUploader->IsEmpty()) {
|
|
||||||
DAWN_TRY(mDynamicUploader->CreateAndAppendBuffer(kDefaultUploadBufferSize));
|
|
||||||
}
|
|
||||||
return mDynamicUploader.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
|
|
@ -77,8 +77,6 @@ namespace dawn_native { namespace d3d12 {
|
||||||
uint32_t destinationOffset,
|
uint32_t destinationOffset,
|
||||||
uint32_t size) override;
|
uint32_t size) override;
|
||||||
|
|
||||||
ResultOrError<DynamicUploader*> GetDynamicUploader() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
||||||
const BindGroupDescriptor* descriptor) override;
|
const BindGroupDescriptor* descriptor) override;
|
||||||
|
@ -121,11 +119,8 @@ namespace dawn_native { namespace d3d12 {
|
||||||
std::unique_ptr<DescriptorHeapAllocator> mDescriptorHeapAllocator;
|
std::unique_ptr<DescriptorHeapAllocator> mDescriptorHeapAllocator;
|
||||||
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
|
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
|
||||||
std::unique_ptr<ResourceAllocator> mResourceAllocator;
|
std::unique_ptr<ResourceAllocator> mResourceAllocator;
|
||||||
std::unique_ptr<DynamicUploader> mDynamicUploader;
|
|
||||||
|
|
||||||
dawn_native::PCIInfo mPCIInfo;
|
dawn_native::PCIInfo mPCIInfo;
|
||||||
|
|
||||||
static constexpr size_t kDefaultUploadBufferSize = 64000; // DXGI min heap size is 64kB.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
mUploadHeap = mDevice->GetResourceAllocator()->Allocate(
|
mUploadHeap = mDevice->GetResourceAllocator()->Allocate(
|
||||||
D3D12_HEAP_TYPE_UPLOAD, resourceDescriptor, D3D12_RESOURCE_STATE_GENERIC_READ);
|
D3D12_HEAP_TYPE_UPLOAD, resourceDescriptor, D3D12_RESOURCE_STATE_GENERIC_READ);
|
||||||
|
|
||||||
// TODO(b-brber): Record the GPU pointer for generic non-upload usage.
|
// TODO(bryan.bernhart@intel.com): Record the GPU pointer for generic non-upload usage.
|
||||||
|
|
||||||
if (FAILED(mUploadHeap->Map(0, nullptr, &mMappedPointer))) {
|
if (FAILED(mUploadHeap->Map(0, nullptr, &mMappedPointer))) {
|
||||||
return DAWN_CONTEXT_LOST_ERROR("Unable to map staging buffer.");
|
return DAWN_CONTEXT_LOST_ERROR("Unable to map staging buffer.");
|
||||||
|
|
|
@ -34,7 +34,6 @@ namespace dawn_native { namespace metal {
|
||||||
void OnMapCommandSerialFinished(uint32_t mapSerial, bool isWrite);
|
void OnMapCommandSerialFinished(uint32_t mapSerial, bool isWrite);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) override;
|
|
||||||
void MapReadAsyncImpl(uint32_t serial) override;
|
void MapReadAsyncImpl(uint32_t serial) override;
|
||||||
void MapWriteAsyncImpl(uint32_t serial) override;
|
void MapWriteAsyncImpl(uint32_t serial) override;
|
||||||
void UnmapImpl() override;
|
void UnmapImpl() override;
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "dawn_native/metal/BufferMTL.h"
|
#include "dawn_native/metal/BufferMTL.h"
|
||||||
|
|
||||||
#include "dawn_native/metal/DeviceMTL.h"
|
#include "dawn_native/metal/DeviceMTL.h"
|
||||||
#include "dawn_native/metal/ResourceUploader.h"
|
|
||||||
|
|
||||||
namespace dawn_native { namespace metal {
|
namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
|
@ -49,12 +48,6 @@ namespace dawn_native { namespace metal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) {
|
|
||||||
auto* uploader = ToBackend(GetDevice())->GetResourceUploader();
|
|
||||||
uploader->BufferSubData(mMtlBuffer, start, count, data);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
||||||
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapTracker();
|
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapTracker();
|
||||||
tracker->Track(this, serial, false);
|
tracker->Track(this, serial, false);
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
namespace dawn_native { namespace metal {
|
namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
class MapRequestTracker;
|
class MapRequestTracker;
|
||||||
class ResourceUploader;
|
|
||||||
|
|
||||||
class Device : public DeviceBase {
|
class Device : public DeviceBase {
|
||||||
public:
|
public:
|
||||||
|
@ -53,7 +52,6 @@ namespace dawn_native { namespace metal {
|
||||||
void SubmitPendingCommandBuffer();
|
void SubmitPendingCommandBuffer();
|
||||||
|
|
||||||
MapRequestTracker* GetMapTracker() const;
|
MapRequestTracker* GetMapTracker() const;
|
||||||
ResourceUploader* GetResourceUploader() const;
|
|
||||||
|
|
||||||
ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override;
|
ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override;
|
||||||
MaybeError CopyFromStagingToBuffer(StagingBufferBase* source,
|
MaybeError CopyFromStagingToBuffer(StagingBufferBase* source,
|
||||||
|
@ -90,7 +88,6 @@ namespace dawn_native { namespace metal {
|
||||||
id<MTLDevice> mMtlDevice = nil;
|
id<MTLDevice> mMtlDevice = nil;
|
||||||
id<MTLCommandQueue> mCommandQueue = nil;
|
id<MTLCommandQueue> mCommandQueue = nil;
|
||||||
std::unique_ptr<MapRequestTracker> mMapTracker;
|
std::unique_ptr<MapRequestTracker> mMapTracker;
|
||||||
std::unique_ptr<ResourceUploader> mResourceUploader;
|
|
||||||
|
|
||||||
Serial mCompletedSerial = 0;
|
Serial mCompletedSerial = 0;
|
||||||
Serial mLastSubmittedSerial = 0;
|
Serial mLastSubmittedSerial = 0;
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
#include "dawn_native/metal/PipelineLayoutMTL.h"
|
#include "dawn_native/metal/PipelineLayoutMTL.h"
|
||||||
#include "dawn_native/metal/QueueMTL.h"
|
#include "dawn_native/metal/QueueMTL.h"
|
||||||
#include "dawn_native/metal/RenderPipelineMTL.h"
|
#include "dawn_native/metal/RenderPipelineMTL.h"
|
||||||
#include "dawn_native/metal/ResourceUploader.h"
|
|
||||||
#include "dawn_native/metal/SamplerMTL.h"
|
#include "dawn_native/metal/SamplerMTL.h"
|
||||||
#include "dawn_native/metal/ShaderModuleMTL.h"
|
#include "dawn_native/metal/ShaderModuleMTL.h"
|
||||||
|
#include "dawn_native/metal/StagingBufferMTL.h"
|
||||||
#include "dawn_native/metal/SwapChainMTL.h"
|
#include "dawn_native/metal/SwapChainMTL.h"
|
||||||
#include "dawn_native/metal/TextureMTL.h"
|
#include "dawn_native/metal/TextureMTL.h"
|
||||||
|
|
||||||
|
@ -37,8 +37,7 @@ namespace dawn_native { namespace metal {
|
||||||
Device::Device(AdapterBase* adapter, id<MTLDevice> mtlDevice)
|
Device::Device(AdapterBase* adapter, id<MTLDevice> mtlDevice)
|
||||||
: DeviceBase(adapter),
|
: DeviceBase(adapter),
|
||||||
mMtlDevice([mtlDevice retain]),
|
mMtlDevice([mtlDevice retain]),
|
||||||
mMapTracker(new MapRequestTracker(this)),
|
mMapTracker(new MapRequestTracker(this)) {
|
||||||
mResourceUploader(new ResourceUploader(this)) {
|
|
||||||
[mMtlDevice retain];
|
[mMtlDevice retain];
|
||||||
mCommandQueue = [mMtlDevice newCommandQueue];
|
mCommandQueue = [mMtlDevice newCommandQueue];
|
||||||
}
|
}
|
||||||
|
@ -58,7 +57,7 @@ namespace dawn_native { namespace metal {
|
||||||
mPendingCommands = nil;
|
mPendingCommands = nil;
|
||||||
|
|
||||||
mMapTracker = nullptr;
|
mMapTracker = nullptr;
|
||||||
mResourceUploader = nullptr;
|
mDynamicUploader = nullptr;
|
||||||
|
|
||||||
[mCommandQueue release];
|
[mCommandQueue release];
|
||||||
mCommandQueue = nil;
|
mCommandQueue = nil;
|
||||||
|
@ -136,7 +135,7 @@ namespace dawn_native { namespace metal {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::TickImpl() {
|
void Device::TickImpl() {
|
||||||
mResourceUploader->Tick(mCompletedSerial);
|
mDynamicUploader->Tick(mCompletedSerial);
|
||||||
mMapTracker->Tick(mCompletedSerial);
|
mMapTracker->Tick(mCompletedSerial);
|
||||||
|
|
||||||
if (mPendingCommands != nil) {
|
if (mPendingCommands != nil) {
|
||||||
|
@ -185,12 +184,10 @@ namespace dawn_native { namespace metal {
|
||||||
return mMapTracker.get();
|
return mMapTracker.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceUploader* Device::GetResourceUploader() const {
|
|
||||||
return mResourceUploader.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultOrError<std::unique_ptr<StagingBufferBase>> Device::CreateStagingBuffer(size_t size) {
|
ResultOrError<std::unique_ptr<StagingBufferBase>> Device::CreateStagingBuffer(size_t size) {
|
||||||
return DAWN_UNIMPLEMENTED_ERROR("Device unable to create staging buffer.");
|
std::unique_ptr<StagingBufferBase> stagingBuffer =
|
||||||
|
std::make_unique<StagingBuffer>(size, this);
|
||||||
|
return std::move(stagingBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError Device::CopyFromStagingToBuffer(StagingBufferBase* source,
|
MaybeError Device::CopyFromStagingToBuffer(StagingBufferBase* source,
|
||||||
|
@ -198,7 +195,18 @@ namespace dawn_native { namespace metal {
|
||||||
BufferBase* destination,
|
BufferBase* destination,
|
||||||
uint32_t destinationOffset,
|
uint32_t destinationOffset,
|
||||||
uint32_t size) {
|
uint32_t size) {
|
||||||
return DAWN_UNIMPLEMENTED_ERROR("Device unable to copy from staging buffer.");
|
id<MTLBuffer> uploadBuffer = ToBackend(source)->GetBufferHandle();
|
||||||
|
id<MTLBuffer> buffer = ToBackend(destination)->GetMTLBuffer();
|
||||||
|
id<MTLCommandBuffer> commandBuffer = GetPendingCommandBuffer();
|
||||||
|
id<MTLBlitCommandEncoder> encoder = [commandBuffer blitCommandEncoder];
|
||||||
|
[encoder copyFromBuffer:uploadBuffer
|
||||||
|
sourceOffset:sourceOffset
|
||||||
|
toBuffer:buffer
|
||||||
|
destinationOffset:destinationOffset
|
||||||
|
size:size];
|
||||||
|
[encoder endEncoding];
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
}} // namespace dawn_native::metal
|
}} // namespace dawn_native::metal
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace dawn_native { namespace metal {
|
||||||
class RenderPipeline;
|
class RenderPipeline;
|
||||||
class Sampler;
|
class Sampler;
|
||||||
class ShaderModule;
|
class ShaderModule;
|
||||||
|
class StagingBuffer;
|
||||||
class SwapChain;
|
class SwapChain;
|
||||||
class Texture;
|
class Texture;
|
||||||
class TextureView;
|
class TextureView;
|
||||||
|
@ -59,6 +60,7 @@ namespace dawn_native { namespace metal {
|
||||||
using RenderPipelineType = RenderPipeline;
|
using RenderPipelineType = RenderPipeline;
|
||||||
using SamplerType = Sampler;
|
using SamplerType = Sampler;
|
||||||
using ShaderModuleType = ShaderModule;
|
using ShaderModuleType = ShaderModule;
|
||||||
|
using StagingBufferType = StagingBuffer;
|
||||||
using SwapChainType = SwapChain;
|
using SwapChainType = SwapChain;
|
||||||
using TextureType = Texture;
|
using TextureType = Texture;
|
||||||
using TextureViewType = TextureView;
|
using TextureViewType = TextureView;
|
||||||
|
|
|
@ -1,57 +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.
|
|
||||||
|
|
||||||
#include "dawn_native/metal/ResourceUploader.h"
|
|
||||||
|
|
||||||
#include "dawn_native/metal/DeviceMTL.h"
|
|
||||||
|
|
||||||
namespace dawn_native { namespace metal {
|
|
||||||
|
|
||||||
ResourceUploader::ResourceUploader(Device* device) : mDevice(device) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceUploader::~ResourceUploader() {
|
|
||||||
ASSERT(mInflightUploadBuffers.Empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceUploader::BufferSubData(id<MTLBuffer> buffer,
|
|
||||||
uint32_t start,
|
|
||||||
uint32_t size,
|
|
||||||
const void* data) {
|
|
||||||
// TODO(cwallez@chromium.org) use a ringbuffer instead of creating a small buffer for each
|
|
||||||
// update
|
|
||||||
id<MTLBuffer> uploadBuffer =
|
|
||||||
[mDevice->GetMTLDevice() newBufferWithLength:size options:MTLResourceStorageModeShared];
|
|
||||||
memcpy([uploadBuffer contents], data, size);
|
|
||||||
|
|
||||||
id<MTLCommandBuffer> commandBuffer = mDevice->GetPendingCommandBuffer();
|
|
||||||
id<MTLBlitCommandEncoder> encoder = [commandBuffer blitCommandEncoder];
|
|
||||||
[encoder copyFromBuffer:uploadBuffer
|
|
||||||
sourceOffset:0
|
|
||||||
toBuffer:buffer
|
|
||||||
destinationOffset:start
|
|
||||||
size:size];
|
|
||||||
[encoder endEncoding];
|
|
||||||
|
|
||||||
mInflightUploadBuffers.Enqueue(uploadBuffer, mDevice->GetPendingCommandSerial());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceUploader::Tick(Serial finishedSerial) {
|
|
||||||
for (id<MTLBuffer> buffer : mInflightUploadBuffers.IterateUpTo(finishedSerial)) {
|
|
||||||
[buffer release];
|
|
||||||
}
|
|
||||||
mInflightUploadBuffers.ClearUpTo(finishedSerial);
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace dawn_native::metal
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2017 The Dawn Authors
|
// Copyright 2018 The Dawn Authors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -12,11 +12,10 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef DAWNNATIVE_METAL_RESOURCEUPLOADER_H_
|
#ifndef DAWNNATIVE_STAGINGBUFFERMETAL_H_
|
||||||
#define DAWNNATIVE_METAL_RESOURCEUPLOADER_H_
|
#define DAWNNATIVE_STAGINGBUFFERMETAL_H_
|
||||||
|
|
||||||
#include "common/Serial.h"
|
#include "dawn_native/StagingBuffer.h"
|
||||||
#include "common/SerialQueue.h"
|
|
||||||
|
|
||||||
#import <Metal/Metal.h>
|
#import <Metal/Metal.h>
|
||||||
|
|
||||||
|
@ -24,19 +23,19 @@ namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
class Device;
|
class Device;
|
||||||
|
|
||||||
class ResourceUploader {
|
class StagingBuffer : public StagingBufferBase {
|
||||||
public:
|
public:
|
||||||
ResourceUploader(Device* device);
|
StagingBuffer(size_t size, Device* device);
|
||||||
~ResourceUploader();
|
~StagingBuffer();
|
||||||
|
|
||||||
void BufferSubData(id<MTLBuffer> buffer, uint32_t start, uint32_t size, const void* data);
|
id<MTLBuffer> GetBufferHandle() const;
|
||||||
void Tick(Serial finishedSerial);
|
|
||||||
|
MaybeError Initialize() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Device* mDevice;
|
Device* mDevice;
|
||||||
SerialQueue<id<MTLBuffer>> mInflightUploadBuffers;
|
id<MTLBuffer> mBuffer = nil;
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace dawn_native::metal
|
}} // namespace dawn_native::metal
|
||||||
|
|
||||||
#endif // DAWNNATIVE_METAL_RESOURCEUPLOADER_H_
|
#endif // DAWNNATIVE_STAGINGBUFFERMETAL_H_
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright 2018 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/metal/StagingBufferMTL.h"
|
||||||
|
#include "dawn_native/metal/DeviceMTL.h"
|
||||||
|
|
||||||
|
namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
|
StagingBuffer::StagingBuffer(size_t size, Device* device)
|
||||||
|
: StagingBufferBase(size), mDevice(device) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeError StagingBuffer::Initialize() {
|
||||||
|
const size_t bufferSize = GetSize();
|
||||||
|
mBuffer = [mDevice->GetMTLDevice() newBufferWithLength:bufferSize
|
||||||
|
options:MTLResourceStorageModeShared];
|
||||||
|
mMappedPointer = [mBuffer contents];
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
StagingBuffer::~StagingBuffer() {
|
||||||
|
[mBuffer release];
|
||||||
|
mBuffer = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
id<MTLBuffer> StagingBuffer::GetBufferHandle() const {
|
||||||
|
return mBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}} // namespace dawn_native::metal
|
|
@ -58,10 +58,10 @@ namespace dawn_native { namespace null {
|
||||||
// Device
|
// Device
|
||||||
|
|
||||||
Device::Device(Adapter* adapter) : DeviceBase(adapter) {
|
Device::Device(Adapter* adapter) : DeviceBase(adapter) {
|
||||||
mDynamicUploader = std::make_unique<DynamicUploader>(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::~Device() {
|
Device::~Device() {
|
||||||
|
mDynamicUploader = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
||||||
|
|
|
@ -136,7 +136,6 @@ namespace dawn_native { namespace null {
|
||||||
Serial mCompletedSerial = 0;
|
Serial mCompletedSerial = 0;
|
||||||
Serial mLastSubmittedSerial = 0;
|
Serial mLastSubmittedSerial = 0;
|
||||||
std::vector<std::unique_ptr<PendingOperation>> mPendingOperations;
|
std::vector<std::unique_ptr<PendingOperation>> mPendingOperations;
|
||||||
std::unique_ptr<DynamicUploader> mDynamicUploader;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Buffer : public BufferBase {
|
class Buffer : public BufferBase {
|
||||||
|
|
|
@ -44,6 +44,9 @@ namespace dawn_native { namespace opengl {
|
||||||
// on a serial that doesn't have a corresponding fence enqueued. Force all
|
// on a serial that doesn't have a corresponding fence enqueued. Force all
|
||||||
// operations to look as if they were completed (because they were).
|
// operations to look as if they were completed (because they were).
|
||||||
mCompletedSerial = mLastSubmittedSerial + 1;
|
mCompletedSerial = mLastSubmittedSerial + 1;
|
||||||
|
|
||||||
|
mDynamicUploader = nullptr;
|
||||||
|
|
||||||
Tick();
|
Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
#include "dawn_native/vulkan/BufferVk.h"
|
#include "dawn_native/vulkan/BufferVk.h"
|
||||||
|
|
||||||
#include "dawn_native/DynamicUploader.h"
|
|
||||||
#include "dawn_native/vulkan/DeviceVk.h"
|
#include "dawn_native/vulkan/DeviceVk.h"
|
||||||
#include "dawn_native/vulkan/FencedDeleter.h"
|
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||||
|
|
||||||
|
@ -196,24 +195,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
mLastUsage = usage;
|
mLastUsage = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) {
|
|
||||||
Device* device = ToBackend(GetDevice());
|
|
||||||
|
|
||||||
DynamicUploader* uploader = nullptr;
|
|
||||||
DAWN_TRY_ASSIGN(uploader, device->GetDynamicUploader());
|
|
||||||
|
|
||||||
UploadHandle uploadHandle;
|
|
||||||
DAWN_TRY_ASSIGN(uploadHandle, uploader->Allocate(count, kDefaultAlignment));
|
|
||||||
ASSERT(uploadHandle.mappedBuffer != nullptr);
|
|
||||||
|
|
||||||
memcpy(uploadHandle.mappedBuffer, data, count);
|
|
||||||
|
|
||||||
DAWN_TRY(device->CopyFromStagingToBuffer(uploadHandle.stagingBuffer,
|
|
||||||
uploadHandle.startOffset, this, start, count));
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
void Buffer::MapReadAsyncImpl(uint32_t serial) {
|
||||||
Device* device = ToBackend(GetDevice());
|
Device* device = ToBackend(GetDevice());
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,10 @@ namespace dawn_native { namespace vulkan {
|
||||||
void TransitionUsageNow(VkCommandBuffer commands, dawn::BufferUsageBit usage);
|
void TransitionUsageNow(VkCommandBuffer commands, dawn::BufferUsageBit usage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MaybeError SetSubDataImpl(uint32_t start, uint32_t count, const uint8_t* data) override;
|
|
||||||
void MapReadAsyncImpl(uint32_t serial) override;
|
void MapReadAsyncImpl(uint32_t serial) override;
|
||||||
void MapWriteAsyncImpl(uint32_t serial) override;
|
void MapWriteAsyncImpl(uint32_t serial) override;
|
||||||
void UnmapImpl() override;
|
void UnmapImpl() override;
|
||||||
|
|
||||||
// TODO(b-brber): Remove once alignment constraint is added to validation (dawn:73).
|
|
||||||
static constexpr size_t kDefaultAlignment = 4; // TODO(b-brber): Figure out this value.
|
|
||||||
|
|
||||||
VkBuffer mHandle = VK_NULL_HANDLE;
|
VkBuffer mHandle = VK_NULL_HANDLE;
|
||||||
DeviceMemoryAllocation mMemoryAllocation;
|
DeviceMemoryAllocation mMemoryAllocation;
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
mDeleter = std::make_unique<FencedDeleter>(this);
|
mDeleter = std::make_unique<FencedDeleter>(this);
|
||||||
mMapRequestTracker = std::make_unique<MapRequestTracker>(this);
|
mMapRequestTracker = std::make_unique<MapRequestTracker>(this);
|
||||||
mMemoryAllocator = std::make_unique<MemoryAllocator>(this);
|
mMemoryAllocator = std::make_unique<MemoryAllocator>(this);
|
||||||
mDynamicUploader = std::make_unique<DynamicUploader>(this);
|
|
||||||
|
|
||||||
mRenderPassCache = std::make_unique<RenderPassCache>(this);
|
mRenderPassCache = std::make_unique<RenderPassCache>(this);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -117,8 +115,8 @@ namespace dawn_native { namespace vulkan {
|
||||||
// Free services explicitly so that they can free Vulkan objects before vkDestroyDevice
|
// Free services explicitly so that they can free Vulkan objects before vkDestroyDevice
|
||||||
mDynamicUploader = nullptr;
|
mDynamicUploader = nullptr;
|
||||||
|
|
||||||
// Releasing the uploader enqueues buffers to be deleted.
|
// Releasing the uploader enqueues buffers to be released.
|
||||||
// Call Tick() again to allow the deleter to clear them prior to being released.
|
// Call Tick() again to clear them before releasing the deleter.
|
||||||
mDeleter->Tick(mCompletedSerial);
|
mDeleter->Tick(mCompletedSerial);
|
||||||
|
|
||||||
mDeleter = nullptr;
|
mDeleter = nullptr;
|
||||||
|
@ -209,7 +207,11 @@ namespace dawn_native { namespace vulkan {
|
||||||
RecycleCompletedCommands();
|
RecycleCompletedCommands();
|
||||||
|
|
||||||
mMapRequestTracker->Tick(mCompletedSerial);
|
mMapRequestTracker->Tick(mCompletedSerial);
|
||||||
|
|
||||||
|
// Uploader should tick before the resource allocator
|
||||||
|
// as it enqueues resources to be released.
|
||||||
mDynamicUploader->Tick(mCompletedSerial);
|
mDynamicUploader->Tick(mCompletedSerial);
|
||||||
|
|
||||||
mMemoryAllocator->Tick(mCompletedSerial);
|
mMemoryAllocator->Tick(mCompletedSerial);
|
||||||
|
|
||||||
mDeleter->Tick(mCompletedSerial);
|
mDeleter->Tick(mCompletedSerial);
|
||||||
|
@ -529,13 +531,4 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<DynamicUploader*> Device::GetDynamicUploader() const {
|
|
||||||
// TODO(b-brber): Refactor this into device init once moved into DeviceBase.
|
|
||||||
if (mDynamicUploader->IsEmpty()) {
|
|
||||||
DAWN_TRY(mDynamicUploader->CreateAndAppendBuffer(kDefaultUploadBufferSize));
|
|
||||||
}
|
|
||||||
return mDynamicUploader.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace dawn_native::vulkan
|
}} // namespace dawn_native::vulkan
|
||||||
|
|
|
@ -79,9 +79,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
BufferBase* destination,
|
BufferBase* destination,
|
||||||
uint32_t destinationOffset,
|
uint32_t destinationOffset,
|
||||||
uint32_t size) override;
|
uint32_t size) override;
|
||||||
|
|
||||||
ResultOrError<DynamicUploader*> GetDynamicUploader() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
||||||
const BindGroupDescriptor* descriptor) override;
|
const BindGroupDescriptor* descriptor) override;
|
||||||
|
@ -117,7 +114,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
uint32_t mQueueFamily = 0;
|
uint32_t mQueueFamily = 0;
|
||||||
VkQueue mQueue = VK_NULL_HANDLE;
|
VkQueue mQueue = VK_NULL_HANDLE;
|
||||||
|
|
||||||
std::unique_ptr<DynamicUploader> mDynamicUploader;
|
|
||||||
std::unique_ptr<FencedDeleter> mDeleter;
|
std::unique_ptr<FencedDeleter> mDeleter;
|
||||||
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
|
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
|
||||||
std::unique_ptr<MemoryAllocator> mMemoryAllocator;
|
std::unique_ptr<MemoryAllocator> mMemoryAllocator;
|
||||||
|
@ -148,9 +144,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
std::vector<CommandPoolAndBuffer> mUnusedCommands;
|
std::vector<CommandPoolAndBuffer> mUnusedCommands;
|
||||||
CommandPoolAndBuffer mPendingCommands;
|
CommandPoolAndBuffer mPendingCommands;
|
||||||
std::vector<VkSemaphore> mWaitSemaphores;
|
std::vector<VkSemaphore> mWaitSemaphores;
|
||||||
|
|
||||||
static constexpr size_t kDefaultUploadBufferSize =
|
|
||||||
64000; // TODO(b-brber): Figure out this value.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace dawn_native::vulkan
|
}} // namespace dawn_native::vulkan
|
||||||
|
|
|
@ -180,10 +180,6 @@ TEST_P(BufferSetSubDataTests, SmallDataAtOffset) {
|
||||||
|
|
||||||
// Stress test for many calls to SetSubData
|
// Stress test for many calls to SetSubData
|
||||||
TEST_P(BufferSetSubDataTests, ManySetSubData) {
|
TEST_P(BufferSetSubDataTests, ManySetSubData) {
|
||||||
// TODO(cwallez@chromium.org): Use ringbuffers for SetSubData on explicit APIs.
|
|
||||||
// otherwise this creates too many resources and can take freeze the driver(?)
|
|
||||||
DAWN_SKIP_TEST_IF(IsMetal());
|
|
||||||
|
|
||||||
// Note: Increasing the size of the buffer will likely cause timeout issues.
|
// Note: Increasing the size of the buffer will likely cause timeout issues.
|
||||||
// In D3D12, timeout detection occurs when the GPU scheduler tries but cannot preempt the task
|
// In D3D12, timeout detection occurs when the GPU scheduler tries but cannot preempt the task
|
||||||
// executing these commands in-flight. If this takes longer than ~2s, a device reset occurs and
|
// executing these commands in-flight. If this takes longer than ~2s, a device reset occurs and
|
||||||
|
|
|
@ -396,7 +396,7 @@ TEST_P(CopyTests_T2B, Texture2DArrayRegion) {
|
||||||
|
|
||||||
// Test that copying texture 2D array mips with 256-byte aligned sizes works
|
// Test that copying texture 2D array mips with 256-byte aligned sizes works
|
||||||
TEST_P(CopyTests_T2B, Texture2DArrayMip) {
|
TEST_P(CopyTests_T2B, Texture2DArrayMip) {
|
||||||
// TODO(b-brber): Figure out why this test fails on Intel Linux.
|
// TODO(bryan.bernhart@intel.com): Figure out why this test fails on Intel Linux.
|
||||||
// See https://bugs.chromium.org/p/dawn/issues/detail?id=101
|
// See https://bugs.chromium.org/p/dawn/issues/detail?id=101
|
||||||
DAWN_SKIP_TEST_IF(IsLinux() && IsVulkan() && IsIntel());
|
DAWN_SKIP_TEST_IF(IsLinux() && IsVulkan() && IsIntel());
|
||||||
constexpr uint32_t kWidth = 256;
|
constexpr uint32_t kWidth = 256;
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace {
|
||||||
class RingBufferTests : public testing::Test {
|
class RingBufferTests : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
// TODO(b-brber): Create this device through the adapter.
|
// TODO(bryan.bernhart@intel.com): Create this device through the adapter.
|
||||||
mDevice = std::make_unique<null::Device>(/*adapter*/ nullptr);
|
mDevice = std::make_unique<null::Device>(/*adapter*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ TEST_F(RingBufferTests, RingBufferSubAlloc) {
|
||||||
|
|
||||||
// In this example, Tick(8) could not reclaim the wasted bytes. The wasted bytes
|
// In this example, Tick(8) could not reclaim the wasted bytes. The wasted bytes
|
||||||
// were add to F9's sub-allocation.
|
// were add to F9's sub-allocation.
|
||||||
// TODO(b-brber): Decide if Tick(8) should free these wasted bytes.
|
// TODO(bryan.bernhart@intel.com): Decide if Tick(8) should free these wasted bytes.
|
||||||
|
|
||||||
ASSERT_EQ(offset, 0u);
|
ASSERT_EQ(offset, 0u);
|
||||||
ASSERT_EQ(buffer->GetUsedSize(), frameSizeInBytes * maxNumOfFrames);
|
ASSERT_EQ(buffer->GetUsedSize(), frameSizeInBytes * maxNumOfFrames);
|
||||||
|
|
Loading…
Reference in New Issue