1 // Copyright 2020 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef DAWNNATIVE_D3D12_STAGINGDESCRIPTORALLOCATOR_H_ 16 #define DAWNNATIVE_D3D12_STAGINGDESCRIPTORALLOCATOR_H_ 17 18 #include "dawn_native/Error.h" 19 20 #include "dawn_native/d3d12/CPUDescriptorHeapAllocationD3D12.h" 21 22 #include <vector> 23 24 // |StagingDescriptorAllocator| allocates a fixed-size block of descriptors from a CPU 25 // descriptor heap pool. 26 // Internally, it manages a list of heaps using a fixed-size block allocator. The fixed-size 27 // block allocator is backed by a list of free blocks (free-list). The heap is in one of two 28 // states: AVAILABLE or not. To allocate, the next free block is removed from the free-list 29 // and the corresponding heap offset is returned. The AVAILABLE heap always has room for 30 // at-least one free block. If no AVAILABLE heap exists, a new heap is created and inserted 31 // back into the pool to be immediately used. To deallocate, the block corresponding to the 32 // offset is inserted back into the free-list. 33 namespace dawn_native { namespace d3d12 { 34 35 class Device; 36 37 class StagingDescriptorAllocator { 38 public: 39 StagingDescriptorAllocator() = default; 40 StagingDescriptorAllocator(Device* device, 41 uint32_t descriptorCount, 42 uint32_t heapSize, 43 D3D12_DESCRIPTOR_HEAP_TYPE heapType); 44 ~StagingDescriptorAllocator(); 45 46 ResultOrError<CPUDescriptorHeapAllocation> AllocateCPUDescriptors(); 47 48 // Will call Deallocate when the serial is passed. 49 ResultOrError<CPUDescriptorHeapAllocation> AllocateTransientCPUDescriptors(); 50 51 void Deallocate(CPUDescriptorHeapAllocation* allocation); 52 53 uint32_t GetSizeIncrement() const; 54 55 void Tick(ExecutionSerial completedSerial); 56 57 private: 58 using Index = uint16_t; 59 60 struct NonShaderVisibleBuffer { 61 ComPtr<ID3D12DescriptorHeap> heap; 62 std::vector<Index> freeBlockIndices; 63 }; 64 65 MaybeError AllocateCPUHeap(); 66 67 Index GetFreeBlockIndicesSize() const; 68 69 std::vector<uint32_t> mAvailableHeaps; // Indices into the pool. 70 std::vector<NonShaderVisibleBuffer> mPool; 71 72 Device* mDevice; 73 74 uint32_t mSizeIncrement; // Size of the descriptor (in bytes). 75 uint32_t mBlockSize; // Size of the block of descriptors (in bytes). 76 uint32_t mHeapSize; // Size of the heap (in number of descriptors). 77 78 D3D12_DESCRIPTOR_HEAP_TYPE mHeapType; 79 80 SerialQueue<ExecutionSerial, CPUDescriptorHeapAllocation> mAllocationsToDelete; 81 }; 82 83 }} // namespace dawn_native::d3d12 84 85 #endif // DAWNNATIVE_D3D12_STAGINGDESCRIPTORALLOCATOR_H_ 86