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 GrD3DResourceProvider_DEFINED
9 #define GrD3DResourceProvider_DEFINED
10 
11 #include "include/gpu/d3d/GrD3DTypes.h"
12 #include "include/private/SkTArray.h"
13 #include "include/private/SkTHash.h"
14 #include "src/core/SkLRUCache.h"
15 #include "src/gpu/GrProgramDesc.h"
16 #include "src/gpu/GrRingBuffer.h"
17 #include "src/gpu/d3d/GrD3DCommandSignature.h"
18 #include "src/gpu/d3d/GrD3DCpuDescriptorManager.h"
19 #include "src/gpu/d3d/GrD3DDescriptorTableManager.h"
20 #include "src/gpu/d3d/GrD3DPipeline.h"
21 #include "src/gpu/d3d/GrD3DRootSignature.h"
22 #include "src/gpu/d3d/GrD3DUtil.h"
23 
24 #include <memory>
25 
26 class GrD3DCommandSignature;
27 class GrD3DDirectCommandList;
28 class GrD3DGpu;
29 class GrD3DPipelineState;
30 class GrD3DRenderTarget;
31 class GrSamplerState;
32 
33 class GrD3DResourceProvider {
34 public:
35     GrD3DResourceProvider(GrD3DGpu*);
36 
37     void destroyResources();
38 
39     std::unique_ptr<GrD3DDirectCommandList> findOrCreateDirectCommandList();
40 
41     void recycleDirectCommandList(std::unique_ptr<GrD3DDirectCommandList>);
42 
43     sk_sp<GrD3DRootSignature> findOrCreateRootSignature(int numTextureSamplers,
44                                                         int numUAVs = 0);
45 
46     sk_sp<GrD3DCommandSignature> findOrCreateCommandSignature(GrD3DCommandSignature::ForIndexed,
47                                                               unsigned int slot);
48 
49     GrD3DDescriptorHeap::CPUHandle createRenderTargetView(ID3D12Resource* textureResource);
50     void recycleRenderTargetView(const GrD3DDescriptorHeap::CPUHandle&);
51 
52     GrD3DDescriptorHeap::CPUHandle createDepthStencilView(ID3D12Resource* textureResource);
53     void recycleDepthStencilView(const GrD3DDescriptorHeap::CPUHandle&);
54 
55     GrD3DDescriptorHeap::CPUHandle createConstantBufferView(ID3D12Resource* bufferResource,
56                                                             size_t offset,
57                                                             size_t size);
58     GrD3DDescriptorHeap::CPUHandle createShaderResourceView(ID3D12Resource* resource,
59                                                             unsigned int mostDetailedMip = 0,
60                                                             unsigned int mipLevels = -1);
61     GrD3DDescriptorHeap::CPUHandle createUnorderedAccessView(ID3D12Resource* resource,
62                                                              unsigned int mipSlice);
63     void recycleShaderView(const GrD3DDescriptorHeap::CPUHandle&);
64 
65     D3D12_CPU_DESCRIPTOR_HANDLE findOrCreateCompatibleSampler(const GrSamplerState& params);
66 
67     sk_sp<GrD3DDescriptorTable> findOrCreateShaderViewTable(
68             const std::vector<D3D12_CPU_DESCRIPTOR_HANDLE>& shaderViews);
69     sk_sp<GrD3DDescriptorTable> findOrCreateSamplerTable(
70             const std::vector<D3D12_CPU_DESCRIPTOR_HANDLE>& samplers);
descriptorTableMgr()71     GrD3DDescriptorTableManager* descriptorTableMgr() {
72         return &fDescriptorTableManager;
73     }
74 
75     GrD3DPipelineState* findOrCreateCompatiblePipelineState(GrD3DRenderTarget*,
76                                                             const GrProgramInfo&);
77 
78     sk_sp<GrD3DPipeline> findOrCreateMipmapPipeline();
79 
80     D3D12_GPU_VIRTUAL_ADDRESS uploadConstantData(void* data, size_t size);
81     void prepForSubmit();
82 
markPipelineStateUniformsDirty()83     void markPipelineStateUniformsDirty() { fPipelineStateCache->markPipelineStateUniformsDirty(); }
84 
85 #if GR_TEST_UTILS
resetShaderCacheForTesting()86     void resetShaderCacheForTesting() const { fPipelineStateCache->release(); }
87 #endif
88 
89 private:
90 #ifdef SK_DEBUG
91 #define GR_PIPELINE_STATE_CACHE_STATS
92 #endif
93 
94     class PipelineStateCache : public ::SkNoncopyable {
95     public:
96         PipelineStateCache(GrD3DGpu* gpu);
97         ~PipelineStateCache();
98 
99         void release();
100         GrD3DPipelineState* refPipelineState(GrD3DRenderTarget*, const GrProgramInfo&);
101 
102         void markPipelineStateUniformsDirty();
103 
104     private:
105         struct Entry;
106 
107         struct DescHash {
operatorDescHash108             uint32_t operator()(const GrProgramDesc& desc) const {
109                 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
110             }
111         };
112 
113         SkLRUCache<const GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
114 
115         GrD3DGpu* fGpu;
116 
117 #ifdef GR_PIPELINE_STATE_CACHE_STATS
118         int fTotalRequests;
119         int fCacheMisses;
120 #endif
121     };
122 
123     class DescriptorTableCache : public ::SkNoncopyable {
124     public:
DescriptorTableCache(GrD3DGpu * gpu)125         DescriptorTableCache(GrD3DGpu* gpu) : fGpu(gpu), fMap(64) {
126             // Initialize the array we pass into CopyDescriptors for ranges.
127             // At the moment any descriptor we pass into CopyDescriptors is only itself,
128             // not the beginning of a range, so each range size is always 1.
129             for (int i = 0; i < kRangeSizesCount; ++i) {
130                 fRangeSizes[i] = 1;
131             }
132         }
133         ~DescriptorTableCache() = default;
134 
135         void release();
136         typedef std::function<sk_sp<GrD3DDescriptorTable>(GrD3DGpu*, unsigned int)> CreateFunc;
137         sk_sp<GrD3DDescriptorTable> findOrCreateDescTable(
138                 const std::vector<D3D12_CPU_DESCRIPTOR_HANDLE>&, CreateFunc);
139 
140     private:
141         GrD3DGpu* fGpu;
142 
143         typedef std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> DescTableKey;
144         typedef sk_sp<GrD3DDescriptorTable> DescTableValue;
145         struct DescTableHash {
operatorDescTableHash146             uint32_t operator()(DescTableKey key) const {
147                 return SkOpts::hash_fn(key.data(),
148                                        key.size()*sizeof(D3D12_CPU_DESCRIPTOR_HANDLE), 0);
149             }
150         };
151         SkLRUCache<DescTableKey, DescTableValue, DescTableHash> fMap;
152         static constexpr int kRangeSizesCount = 8;
153         unsigned int fRangeSizes[kRangeSizesCount];
154     };
155 
156     GrD3DGpu* fGpu;
157 
158     SkSTArray<4, std::unique_ptr<GrD3DDirectCommandList>> fAvailableDirectCommandLists;
159     SkSTArray<4, sk_sp<GrD3DRootSignature>> fRootSignatures;
160     SkSTArray<2, sk_sp<GrD3DCommandSignature>> fCommandSignatures;
161 
162     GrD3DCpuDescriptorManager fCpuDescriptorManager;
163     GrD3DDescriptorTableManager fDescriptorTableManager;
164 
165     std::unique_ptr<PipelineStateCache> fPipelineStateCache;
166     sk_sp<GrD3DPipeline> fMipmapPipeline;
167 
168     SkTHashMap<uint32_t, D3D12_CPU_DESCRIPTOR_HANDLE> fSamplers;
169 
170     DescriptorTableCache fShaderResourceDescriptorTableCache;
171     DescriptorTableCache fSamplerDescriptorTableCache;
172 };
173 
174 #endif
175