dawn-cmake/src/backend/d3d12/ResourceUploader.cpp

74 lines
3.3 KiB
C++

// Copyright 2017 The NXT 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 "backend/d3d12/ResourceUploader.h"
#include "backend/d3d12/D3D12Backend.h"
#include "backend/d3d12/ResourceAllocator.h"
namespace backend { namespace d3d12 {
ResourceUploader::ResourceUploader(Device* device) : mDevice(device) {
}
void ResourceUploader::BufferSubData(ComPtr<ID3D12Resource> resource,
uint32_t start,
uint32_t count,
const void* data) {
// TODO(enga@google.com): Use a handle to a subset of a large ring buffer. On Release,
// decrease reference count on the ring buffer and free when 0. Alternatively, the
// SerialQueue could be used to track which last point of the ringbuffer is in use, and
// start reusing chunks of it that aren't in flight.
UploadHandle uploadHandle = GetUploadBuffer(count);
memcpy(uploadHandle.mappedBuffer, data, count);
mDevice->GetPendingCommandList()->CopyBufferRegion(resource.Get(), start,
uploadHandle.resource.Get(), 0, count);
Release(uploadHandle);
}
ResourceUploader::UploadHandle ResourceUploader::GetUploadBuffer(uint32_t requiredSize) {
// TODO(enga@google.com): This will find or create a mapped buffer of sufficient size and
// return a handle to a mapped range
D3D12_RESOURCE_DESC resourceDescriptor;
resourceDescriptor.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
resourceDescriptor.Alignment = 0;
resourceDescriptor.Width = requiredSize;
resourceDescriptor.Height = 1;
resourceDescriptor.DepthOrArraySize = 1;
resourceDescriptor.MipLevels = 1;
resourceDescriptor.Format = DXGI_FORMAT_UNKNOWN;
resourceDescriptor.SampleDesc.Count = 1;
resourceDescriptor.SampleDesc.Quality = 0;
resourceDescriptor.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resourceDescriptor.Flags = D3D12_RESOURCE_FLAG_NONE;
UploadHandle uploadHandle;
uploadHandle.resource = mDevice->GetResourceAllocator()->Allocate(
D3D12_HEAP_TYPE_UPLOAD, resourceDescriptor, D3D12_RESOURCE_STATE_GENERIC_READ);
D3D12_RANGE readRange;
readRange.Begin = 0;
readRange.End = 0;
uploadHandle.resource->Map(0, &readRange,
reinterpret_cast<void**>(&uploadHandle.mappedBuffer));
return uploadHandle;
}
void ResourceUploader::Release(UploadHandle uploadHandle) {
uploadHandle.resource->Unmap(0, nullptr);
mDevice->GetResourceAllocator()->Release(uploadHandle.resource);
}
}} // namespace backend::d3d12