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 GrD3DGpu_DEFINED
9 #define GrD3DGpu_DEFINED
10 
11 #include "include/private/SkDeque.h"
12 #include "src/gpu/GrGpu.h"
13 #include "src/gpu/GrRenderTarget.h"
14 #include "src/gpu/GrSemaphore.h"
15 #include "src/gpu/GrStagingBufferManager.h"
16 #include "src/gpu/d3d/GrD3DCaps.h"
17 #include "src/gpu/d3d/GrD3DCommandList.h"
18 #include "src/gpu/d3d/GrD3DResourceProvider.h"
19 
20 struct GrD3DBackendContext;
21 class GrD3DOpsRenderPass;
22 struct GrD3DOptions;
23 class GrPipeline;
24 #if GR_TEST_UTILS
25 struct IDXGraphicsAnalysis;
26 #endif
27 
28 class GrD3DGpu : public GrGpu {
29 public:
30     static sk_sp<GrGpu> Make(const GrD3DBackendContext& backendContext, const GrContextOptions&,
31                              GrDirectContext*);
32 
33     ~GrD3DGpu() override;
34 
d3dCaps() const35     const GrD3DCaps& d3dCaps() const { return static_cast<const GrD3DCaps&>(*this->caps()); }
36 
resourceProvider()37     GrD3DResourceProvider& resourceProvider() { return fResourceProvider; }
38 
39     GrThreadSafePipelineBuilder* pipelineBuilder() override;
40     sk_sp<GrThreadSafePipelineBuilder> refPipelineBuilder() override;
41 
device() const42     ID3D12Device* device() const { return fDevice.get(); }
queue() const43     ID3D12CommandQueue* queue() const { return fQueue.get(); }
44 
memoryAllocator() const45     GrD3DMemoryAllocator* memoryAllocator() const { return fMemoryAllocator.get(); }
46 
currentCommandList() const47     GrD3DDirectCommandList* currentCommandList() const { return fCurrentDirectCommandList.get(); }
48 
49     GrStagingBufferManager* stagingBufferManager() override { return &fStagingBufferManager; }
50     void takeOwnershipOfBuffer(sk_sp<GrGpuBuffer>) override;
51 
52     GrRingBuffer* uniformsRingBuffer() override { return &fConstantsRingBuffer; }
53 
protectedContext() const54     bool protectedContext() const { return false; }
55 
56     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
57 
58     void deleteBackendTexture(const GrBackendTexture&) override;
59 
60     bool compile(const GrProgramDesc&, const GrProgramInfo&) override;
61 
62 #if GR_TEST_UTILS
63     bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
64 
65     GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions,
66                                                                GrColorType,
67                                                                int sampleCnt,
68                                                                GrProtected) override;
69     void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
70 
71     void testingOnly_startCapture() override;
72     void testingOnly_endCapture() override;
73 
74     void resetShaderCacheForTesting() const override {
75         fResourceProvider.resetShaderCacheForTesting();
76     }
77 #endif
78 
79     sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
80                                               SkISize dimensions, int numStencilSamples) override;
81 
82     GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) override {
83         return GrBackendFormat::MakeDxgi(this->d3dCaps().preferredStencilFormat());
84     }
85 
86     sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions,
87                                            const GrBackendFormat& format,
88                                            int numSamples,
89                                            GrProtected isProtected,
90                                            GrMemoryless isMemoryless) override {
91         return nullptr;
92     }
93 
94     void addResourceBarriers(sk_sp<GrManagedResource> resource,
95                              int numBarriers,
96                              D3D12_RESOURCE_TRANSITION_BARRIER* barriers) const;
97 
98     void addBufferResourceBarriers(GrD3DBuffer* buffer,
99                                    int numBarriers,
100                                    D3D12_RESOURCE_TRANSITION_BARRIER* barriers) const;
101 
102     GrFence SK_WARN_UNUSED_RESULT insertFence() override;
103     bool waitFence(GrFence) override;
104     void deleteFence(GrFence) const override {}
105 
106     std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
107     std::unique_ptr<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&,
108                                                       GrSemaphoreWrapType,
109                                                       GrWrapOwnership) override;
110     void insertSemaphore(GrSemaphore* semaphore) override;
111     void waitSemaphore(GrSemaphore* semaphore) override;
112     std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override {
113         return nullptr;
114     }
115 
116     void submit(GrOpsRenderPass* renderPass) override;
117     void endRenderPass(GrRenderTarget* target, GrSurfaceOrigin origin,
118                        const SkIRect& bounds);
119 
120     void checkFinishProcs() override { this->checkForFinishedCommandLists(); }
121     void finishOutstandingGpuWork() override;
122 
123 private:
124     enum class SyncQueue {
125         kForce,
126         kSkip
127     };
128 
129     GrD3DGpu(GrDirectContext*, const GrContextOptions&, const GrD3DBackendContext&,
130              sk_sp<GrD3DMemoryAllocator>);
131 
132     void destroyResources();
133 
134     sk_sp<GrTexture> onCreateTexture(SkISize,
135                                      const GrBackendFormat&,
136                                      GrRenderable,
137                                      int renderTargetSampleCnt,
138                                      SkBudgeted,
139                                      GrProtected,
140                                      int mipLevelCount,
141                                      uint32_t levelClearMask) override;
142 
143     sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
144                                                const GrBackendFormat&,
145                                                SkBudgeted,
146                                                GrMipmapped,
147                                                GrProtected,
148                                                const void* data, size_t dataSize) override;
149 
150     sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
151                                                const GrBackendFormat&,
152                                                SkBudgeted,
153                                                GrMipmapped,
154                                                GrProtected,
155                                                OH_NativeBuffer* nativeBuffer,
156                                                size_t bufferSize) override;
157 
158     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
159                                           GrWrapOwnership,
160                                           GrWrapCacheable,
161                                           GrIOType) override;
162     sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&,
163                                                     GrWrapOwnership,
164                                                     GrWrapCacheable) override;
165 
166     sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
167                                                     int sampleCnt,
168                                                     GrWrapOwnership,
169                                                     GrWrapCacheable) override;
170 
171     sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
172 
173     sk_sp<GrGpuBuffer> onCreateBuffer(size_t sizeInBytes, GrGpuBufferType, GrAccessPattern,
174                                       const void*) override;
175 
176     bool onReadPixels(GrSurface*,
177                       SkIRect,
178                       GrColorType surfaceColorType,
179                       GrColorType dstColorType,
180                       void*,
181                       size_t rowBytes) override;
182 
183     bool onWritePixels(GrSurface*,
184                        SkIRect,
185                        GrColorType surfaceColorType,
186                        GrColorType srcColorType,
187                        const GrMipLevel[],
188                        int mipLevelCount,
189                        bool prepForTexSampling) override;
190 
191     bool onTransferPixelsTo(GrTexture*,
192                             SkIRect,
193                             GrColorType surfaceColorType,
194                             GrColorType bufferColorType,
195                             sk_sp<GrGpuBuffer>,
196                             size_t offset,
197                             size_t rowBytes) override;
198 
199     bool onTransferPixelsFrom(GrSurface*,
200                               SkIRect,
201                               GrColorType surfaceColorType,
202                               GrColorType bufferColorType,
203                               sk_sp<GrGpuBuffer>,
204                               size_t offset) override;
205 
206     bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
207                        const SkIPoint& dstPoint) override;
208 
209     bool onRegenerateMipMapLevels(GrTexture*) override;
210 
211     void onResolveRenderTarget(GrRenderTarget* target, const SkIRect&) override;
212 
213     void addFinishedProc(GrGpuFinishedProc finishedProc,
214                          GrGpuFinishedContext finishedContext) override;
215     void addFinishedCallback(sk_sp<GrRefCntedCallback> finishedCallback);
216 
217     GrOpsRenderPass* onGetOpsRenderPass(GrRenderTarget*,
218                                         bool useMSAASurface,
219                                         GrAttachment*,
220                                         GrSurfaceOrigin,
221                                         const SkIRect&,
222                                         const GrOpsRenderPass::LoadAndStoreInfo&,
223                                         const GrOpsRenderPass::StencilLoadAndStoreInfo&,
224                                         const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
225                                         GrXferBarrierFlags renderPassXferBarriers) override;
226 
227     void prepareSurfacesForBackendAccessAndStateUpdates(
228             SkSpan<GrSurfaceProxy*> proxies,
229             SkSurface::BackendSurfaceAccess access,
230             const GrBackendSurfaceMutableState* newState) override;
231 
232     bool onSubmitToGpu(bool syncCpu) override;
233 
234     GrBackendTexture onCreateBackendTexture(SkISize dimensions,
235                                             const GrBackendFormat&,
236                                             GrRenderable,
237                                             GrMipmapped,
238                                             GrProtected) override;
239 
240     bool onClearBackendTexture(const GrBackendTexture&,
241                                sk_sp<GrRefCntedCallback> finishedCallback,
242                                std::array<float, 4> color) override;
243 
244     GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions,
245                                                       const GrBackendFormat&,
246                                                       GrMipmapped,
247                                                       GrProtected) override;
248 
249     bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
250                                           sk_sp<GrRefCntedCallback> finishedCallback,
251                                           const void* data,
252                                           size_t size) override;
253 
254     bool submitDirectCommandList(SyncQueue sync);
255 
256     void checkForFinishedCommandLists();
257     void waitForQueueCompletion();
258 
259     void copySurfaceAsCopyTexture(GrSurface* dst, GrSurface* src, GrD3DTextureResource* dstResource,
260                                   GrD3DTextureResource* srcResource, const SkIRect& srcRect,
261                                   const SkIPoint& dstPoint);
262 
263     void copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
264                               const SkIPoint& dstPoint);
265     void resolveTexture(GrSurface* dst, int32_t dstX, int32_t dstY,
266                         GrD3DRenderTarget* src, const SkIRect& srcRect);
267 
268     sk_sp<GrD3DTexture> createD3DTexture(SkISize,
269                                          DXGI_FORMAT,
270                                          GrRenderable,
271                                          int renderTargetSampleCnt,
272                                          SkBudgeted,
273                                          GrProtected,
274                                          int mipLevelCount,
275                                          GrMipmapStatus);
276 
277     bool uploadToTexture(GrD3DTexture* tex,
278                          SkIRect rect,
279                          GrColorType colorType,
280                          const GrMipLevel texels[],
281                          int mipLevelCount);
282 
283     void readOrTransferPixels(GrD3DTextureResource* texResource,
284                               SkIRect rect,
285                               sk_sp<GrGpuBuffer> transferBuffer,
286                               const D3D12_PLACED_SUBRESOURCE_FOOTPRINT& placedFootprint);
287 
288     bool createTextureResourceForBackendSurface(DXGI_FORMAT dxgiFormat,
289                                                 SkISize dimensions,
290                                                 GrTexturable texturable,
291                                                 GrRenderable renderable,
292                                                 GrMipmapped mipMapped,
293                                                 int sampleCnt,
294                                                 GrD3DTextureResourceInfo* info,
295                                                 GrProtected isProtected);
296 
297     gr_cp<ID3D12Device> fDevice;
298     gr_cp<ID3D12CommandQueue> fQueue;
299 
300     sk_sp<GrD3DMemoryAllocator> fMemoryAllocator;
301 
302     GrD3DResourceProvider fResourceProvider;
303     GrStagingBufferManager fStagingBufferManager;
304     GrRingBuffer fConstantsRingBuffer;
305 
306     gr_cp<ID3D12Fence> fFence;
307     uint64_t fCurrentFenceValue = 0;
308 
309     std::unique_ptr<GrD3DDirectCommandList> fCurrentDirectCommandList;
310     // One-off special-case descriptors created directly for the mipmap compute shader
311     // and hence aren't tracked by the normal path.
312     SkSTArray<32, GrD3DDescriptorHeap::CPUHandle> fMipmapCPUDescriptors;
313 
314     struct OutstandingCommandList {
OutstandingCommandListGrD3DGpu::OutstandingCommandList315         OutstandingCommandList(std::unique_ptr<GrD3DDirectCommandList> commandList,
316                                uint64_t fenceValue)
317             : fCommandList(std::move(commandList)), fFenceValue(fenceValue) {
318         }
319         std::unique_ptr<GrD3DDirectCommandList> fCommandList;
320         uint64_t fFenceValue;
321     };
322 
323     SkDeque fOutstandingCommandLists;
324 
325     std::unique_ptr<GrD3DOpsRenderPass> fCachedOpsRenderPass;
326 
327 #if GR_TEST_UTILS
328     IDXGraphicsAnalysis* fGraphicsAnalysis;
329 #endif
330 
331     using INHERITED = GrGpu;
332 };
333 
334 #endif
335