mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-03 05:01:27 +00:00
BUG=dawn:233 Change-Id: Ia42d7e99df910f245b7c78be16b7916c0730e8a9 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11960 Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
136 lines
5.7 KiB
C++
136 lines
5.7 KiB
C++
// 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/d3d12/DescriptorHeapAllocator.h"
|
|
|
|
#include "common/Assert.h"
|
|
#include "dawn_native/d3d12/DeviceD3D12.h"
|
|
|
|
namespace dawn_native { namespace d3d12 {
|
|
|
|
DescriptorHeapHandle::DescriptorHeapHandle()
|
|
: mDescriptorHeap(nullptr), mSizeIncrement(0), mOffset(0) {
|
|
}
|
|
|
|
DescriptorHeapHandle::DescriptorHeapHandle(ComPtr<ID3D12DescriptorHeap> descriptorHeap,
|
|
uint32_t sizeIncrement,
|
|
uint32_t offset)
|
|
: mDescriptorHeap(descriptorHeap), mSizeIncrement(sizeIncrement), mOffset(offset) {
|
|
}
|
|
|
|
ID3D12DescriptorHeap* DescriptorHeapHandle::Get() const {
|
|
return mDescriptorHeap.Get();
|
|
}
|
|
|
|
D3D12_CPU_DESCRIPTOR_HANDLE DescriptorHeapHandle::GetCPUHandle(uint32_t index) const {
|
|
ASSERT(mDescriptorHeap);
|
|
auto handle = mDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
|
|
handle.ptr += mSizeIncrement * (index + mOffset);
|
|
return handle;
|
|
}
|
|
|
|
D3D12_GPU_DESCRIPTOR_HANDLE DescriptorHeapHandle::GetGPUHandle(uint32_t index) const {
|
|
ASSERT(mDescriptorHeap);
|
|
auto handle = mDescriptorHeap->GetGPUDescriptorHandleForHeapStart();
|
|
handle.ptr += mSizeIncrement * (index + mOffset);
|
|
return handle;
|
|
}
|
|
|
|
DescriptorHeapAllocator::DescriptorHeapAllocator(Device* device)
|
|
: mDevice(device),
|
|
mSizeIncrements{
|
|
device->GetD3D12Device()->GetDescriptorHandleIncrementSize(
|
|
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV),
|
|
device->GetD3D12Device()->GetDescriptorHandleIncrementSize(
|
|
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER),
|
|
device->GetD3D12Device()->GetDescriptorHandleIncrementSize(
|
|
D3D12_DESCRIPTOR_HEAP_TYPE_RTV),
|
|
device->GetD3D12Device()->GetDescriptorHandleIncrementSize(
|
|
D3D12_DESCRIPTOR_HEAP_TYPE_DSV),
|
|
} {
|
|
}
|
|
|
|
ResultOrError<DescriptorHeapHandle> DescriptorHeapAllocator::Allocate(
|
|
D3D12_DESCRIPTOR_HEAP_TYPE type,
|
|
uint32_t count,
|
|
uint32_t allocationSize,
|
|
DescriptorHeapInfo* heapInfo,
|
|
D3D12_DESCRIPTOR_HEAP_FLAGS flags) {
|
|
const Serial pendingSerial = mDevice->GetPendingCommandSerial();
|
|
size_t startOffset = (heapInfo->heap == nullptr)
|
|
? RingBufferAllocator::kInvalidOffset
|
|
: heapInfo->allocator.Allocate(count, pendingSerial);
|
|
if (startOffset != RingBufferAllocator::kInvalidOffset) {
|
|
return DescriptorHeapHandle{heapInfo->heap, mSizeIncrements[type],
|
|
static_cast<uint32_t>(startOffset)};
|
|
}
|
|
|
|
// If the pool has no more space, replace the pool with a new one of the specified size
|
|
|
|
D3D12_DESCRIPTOR_HEAP_DESC heapDescriptor;
|
|
heapDescriptor.Type = type;
|
|
heapDescriptor.NumDescriptors = allocationSize;
|
|
heapDescriptor.Flags = flags;
|
|
heapDescriptor.NodeMask = 0;
|
|
ComPtr<ID3D12DescriptorHeap> heap;
|
|
if (FAILED(mDevice->GetD3D12Device()->CreateDescriptorHeap(&heapDescriptor,
|
|
IID_PPV_ARGS(&heap)))) {
|
|
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate heap");
|
|
}
|
|
|
|
mDevice->ReferenceUntilUnused(heap);
|
|
|
|
*heapInfo = {heap, RingBufferAllocator(allocationSize)};
|
|
|
|
startOffset = heapInfo->allocator.Allocate(count, pendingSerial);
|
|
|
|
ASSERT(startOffset != RingBufferAllocator::kInvalidOffset);
|
|
|
|
return DescriptorHeapHandle(heap, mSizeIncrements[type], startOffset);
|
|
}
|
|
|
|
ResultOrError<DescriptorHeapHandle> DescriptorHeapAllocator::AllocateCPUHeap(
|
|
D3D12_DESCRIPTOR_HEAP_TYPE type,
|
|
uint32_t count) {
|
|
return Allocate(type, count, count, &mCpuDescriptorHeapInfos[type],
|
|
D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
|
|
}
|
|
|
|
ResultOrError<DescriptorHeapHandle> DescriptorHeapAllocator::AllocateGPUHeap(
|
|
D3D12_DESCRIPTOR_HEAP_TYPE type,
|
|
uint32_t count) {
|
|
ASSERT(type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ||
|
|
type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
|
|
unsigned int heapSize = (type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV
|
|
? D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1
|
|
: D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE);
|
|
return Allocate(type, count, heapSize, &mGpuDescriptorHeapInfos[type],
|
|
D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE);
|
|
}
|
|
|
|
void DescriptorHeapAllocator::Deallocate(uint64_t lastCompletedSerial) {
|
|
for (uint32_t i = 0; i < mCpuDescriptorHeapInfos.size(); i++) {
|
|
if (mCpuDescriptorHeapInfos[i].heap != nullptr) {
|
|
mCpuDescriptorHeapInfos[i].allocator.Deallocate(lastCompletedSerial);
|
|
}
|
|
}
|
|
|
|
for (uint32_t i = 0; i < mGpuDescriptorHeapInfos.size(); i++) {
|
|
if (mGpuDescriptorHeapInfos[i].heap != nullptr) {
|
|
mGpuDescriptorHeapInfos[i].allocator.Deallocate(lastCompletedSerial);
|
|
}
|
|
}
|
|
}
|
|
}} // namespace dawn_native::d3d12
|