blob: 64e9c3f44ecafc0154dd0e20cfbc8324db64066e [file] [log] [blame]
// 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_D3D12_STAGINGDESCRIPTORALLOCATOR_H_
#define DAWNNATIVE_D3D12_STAGINGDESCRIPTORALLOCATOR_H_
#include "dawn_native/Error.h"
#include "dawn_native/d3d12/CPUDescriptorHeapAllocationD3D12.h"
#include <vector>
// |StagingDescriptorAllocator| allocates a fixed-size block of descriptors from a CPU
// descriptor heap pool.
// Internally, it manages a list of heaps using a fixed-size block allocator. The fixed-size
// block allocator is backed by a list of free blocks (free-list). The heap is in one of two
// states: AVAILABLE or not. To allocate, the next free block is removed from the free-list
// and the corresponding heap offset is returned. The AVAILABLE heap always has room for
// at-least one free block. If no AVAILABLE heap exists, a new heap is created and inserted
// back into the pool to be immediately used. To deallocate, the block corresponding to the
// offset is inserted back into the free-list.
namespace dawn::native::d3d12 {
class Device;
class StagingDescriptorAllocator {
public:
StagingDescriptorAllocator() = default;
StagingDescriptorAllocator(Device* device,
uint32_t descriptorCount,
uint32_t heapSize,
D3D12_DESCRIPTOR_HEAP_TYPE heapType);
~StagingDescriptorAllocator();
ResultOrError<CPUDescriptorHeapAllocation> AllocateCPUDescriptors();
// Will call Deallocate when the serial is passed.
ResultOrError<CPUDescriptorHeapAllocation> AllocateTransientCPUDescriptors();
void Deallocate(CPUDescriptorHeapAllocation* allocation);
uint32_t GetSizeIncrement() const;
void Tick(ExecutionSerial completedSerial);
private:
using Index = uint16_t;
struct NonShaderVisibleBuffer {
ComPtr<ID3D12DescriptorHeap> heap;
std::vector<Index> freeBlockIndices;
};
MaybeError AllocateCPUHeap();
Index GetFreeBlockIndicesSize() const;
std::vector<uint32_t> mAvailableHeaps; // Indices into the pool.
std::vector<NonShaderVisibleBuffer> mPool;
Device* mDevice;
uint32_t mSizeIncrement; // Size of the descriptor (in bytes).
uint32_t mBlockSize; // Size of the block of descriptors (in bytes).
uint32_t mHeapSize; // Size of the heap (in number of descriptors).
D3D12_DESCRIPTOR_HEAP_TYPE mHeapType;
SerialQueue<ExecutionSerial, CPUDescriptorHeapAllocation> mAllocationsToDelete;
};
} // namespace dawn::native::d3d12
#endif // DAWNNATIVE_D3D12_STAGINGDESCRIPTORALLOCATOR_H_