1/*
2 * Copyright 2020 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrD3DGpuDescriptorTableManager_DEFINED
9#define GrD3DGpuDescriptorTableManager_DEFINED
10
11#include "src/gpu/d3d/GrD3DDescriptorHeap.h"
12#include <vector>
13
14class GrD3DCommandList;
15class GrD3DDirectCommandList;
16class GrD3DGpu;
17
18class GrD3DDescriptorTable : public SkRefCnt {
19public:
20    GrD3DDescriptorTable(D3D12_CPU_DESCRIPTOR_HANDLE baseCPU, D3D12_GPU_DESCRIPTOR_HANDLE baseGPU,
21                         ID3D12DescriptorHeap* heap, D3D12_DESCRIPTOR_HEAP_TYPE type)
22        : fDescriptorTableCpuStart(baseCPU)
23        , fDescriptorTableGpuStart(baseGPU)
24        , fHeap(heap)
25        , fType(type) {}
26
27    const D3D12_CPU_DESCRIPTOR_HANDLE* baseCpuDescriptorPtr() {
28        return &fDescriptorTableCpuStart;
29    }
30
31    const D3D12_GPU_DESCRIPTOR_HANDLE baseGpuDescriptor() {
32        return fDescriptorTableGpuStart;
33    }
34
35    ID3D12DescriptorHeap* heap() const { return fHeap; }
36    D3D12_DESCRIPTOR_HEAP_TYPE type() const { return fType; }
37
38private:
39    D3D12_CPU_DESCRIPTOR_HANDLE fDescriptorTableCpuStart;
40    D3D12_GPU_DESCRIPTOR_HANDLE fDescriptorTableGpuStart;
41    ID3D12DescriptorHeap* fHeap;
42    D3D12_DESCRIPTOR_HEAP_TYPE fType;
43};
44
45class GrD3DDescriptorTableManager {
46public:
47    GrD3DDescriptorTableManager(GrD3DGpu*);
48
49    sk_sp<GrD3DDescriptorTable> createShaderViewTable(GrD3DGpu*, unsigned int count);
50    sk_sp<GrD3DDescriptorTable> createSamplerTable(GrD3DGpu*, unsigned int count);
51
52    void prepForSubmit(GrD3DGpu* gpu);
53
54private:
55    class Heap : public GrRecycledResource {
56    public:
57        static sk_sp<Heap> Make(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE type,
58                                unsigned int numDescriptors);
59
60        sk_sp<GrD3DDescriptorTable> allocateTable(unsigned int count);
61        bool canAllocate(unsigned int count) const {
62            return (fDescriptorCount - fNextAvailable) >= count;
63        }
64        ID3D12DescriptorHeap* d3dDescriptorHeap() const { return fHeap->descriptorHeap(); }
65        D3D12_DESCRIPTOR_HEAP_TYPE type() const { return fType; }
66        unsigned int descriptorCount() { return fDescriptorCount; }
67        bool used() { return fNextAvailable > 0; }
68
69        void reset() {
70            fNextAvailable = 0;
71        }
72
73    private:
74        Heap(GrD3DGpu* gpu, std::unique_ptr<GrD3DDescriptorHeap>& heap,
75             D3D12_DESCRIPTOR_HEAP_TYPE type, unsigned int descriptorCount)
76            : INHERITED()
77            , fGpu(gpu)
78            , fHeap(std::move(heap))
79            , fType(type)
80            , fDescriptorCount(descriptorCount)
81            , fNextAvailable(0) {
82        }
83
84        void freeGPUData() const override {}
85        void onRecycle() const override;
86
87#ifdef SK_TRACE_MANAGED_RESOURCES
88        void dumpInfo() const override {
89            SkDebugf("GrD3DDescriptorTable::Heap: %p (%d refs)\n", fHeap.get(), this->getRefCnt());
90        }
91#endif
92
93        GrD3DGpu* fGpu;
94        std::unique_ptr<GrD3DDescriptorHeap> fHeap;
95        D3D12_DESCRIPTOR_HEAP_TYPE fType;
96        unsigned int fDescriptorCount;
97        unsigned int fNextAvailable;
98
99        using INHERITED = GrRecycledResource;
100    };
101
102    class HeapPool {
103    public:
104        HeapPool(GrD3DGpu*, D3D12_DESCRIPTOR_HEAP_TYPE);
105
106        sk_sp<GrD3DDescriptorTable> allocateTable(GrD3DGpu*, unsigned int count);
107        void recycle(sk_sp<Heap>);
108        sk_sp<Heap>& currentDescriptorHeap();
109        void prepForSubmit(GrD3DGpu* gpu);
110
111    private:
112        inline static constexpr int kInitialHeapDescriptorCount = 256;
113
114        std::vector<sk_sp<Heap>> fDescriptorHeaps;
115        D3D12_DESCRIPTOR_HEAP_TYPE fHeapType;
116        unsigned int fCurrentHeapDescriptorCount;
117    };
118
119    void recycle(Heap*);
120
121    HeapPool fShaderViewDescriptorPool;
122    HeapPool fSamplerDescriptorPool;
123};
124
125#endif
126