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()35     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()42     ID3D12Device* device() const { return fDevice.get(); }
queue()43     ID3D12CommandQueue* queue() const { return fQueue.get(); }
44 
memoryAllocator()45     GrD3DMemoryAllocator* memoryAllocator() const { return fMemoryAllocator.get(); }
46 
currentCommandList()47     GrD3DDirectCommandList* currentCommandList() const { return fCurrentDirectCommandList.get(); }
48 
stagingBufferManager()49     GrStagingBufferManager* stagingBufferManager() override { return &fStagingBufferManager; }
50     void takeOwnershipOfBuffer(sk_sp<GrGpuBuffer>) override;
51 
uniformsRingBuffer()52     GrRingBuffer* uniformsRingBuffer() override { return &fConstantsRingBuffer; }
53 
protectedContext()54     bool protectedContext() const { return false; }
55 
xferBarrier(GrRenderTarget *,GrXferBarrierType)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 
resetShaderCacheForTesting()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 
getPreferredStencilFormat(const GrBackendFormat &)82     GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) override {
83         return GrBackendFormat::MakeDxgi(this->d3dCaps().preferredStencilFormat());
84     }
85 
makeMSAAAttachment(SkISize dimensions,const GrBackendFormat & format,int numSamples,GrProtected isProtected)86     sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions,
87                                            const GrBackendFormat& format,
88                                            int numSamples,
89                                            GrProtected isProtected) override {
90         return nullptr;
91     }
92 
93     void addResourceBarriers(sk_sp<GrManagedResource> resource,
94                              int numBarriers,
95                              D3D12_RESOURCE_TRANSITION_BARRIER* barriers) const;
96 
97     void addBufferResourceBarriers(GrD3DBuffer* buffer,
98                                    int numBarriers,
99                                    D3D12_RESOURCE_TRANSITION_BARRIER* barriers) const;
100 
101     GrFence SK_WARN_UNUSED_RESULT insertFence() override;
102     bool waitFence(GrFence) override;
deleteFence(GrFence)103     void deleteFence(GrFence) const override {}
104 
105     std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
106     std::unique_ptr<GrSemaphore> wrapBackendSemaphore(
107             const GrBackendSemaphore& semaphore,
108             GrResourceProvider::SemaphoreWrapType wrapType,
109             GrWrapOwnership ownership) override;
110     void insertSemaphore(GrSemaphore* semaphore) override;
111     void waitSemaphore(GrSemaphore* semaphore) override;
prepareTextureForCrossContextUsage(GrTexture *)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 
checkFinishProcs()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> onWrapBackendTexture(const GrBackendTexture&,
151                                           GrWrapOwnership,
152                                           GrWrapCacheable,
153                                           GrIOType) override;
154     sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&,
155                                                     GrWrapOwnership,
156                                                     GrWrapCacheable) override;
157 
158     sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
159                                                     int sampleCnt,
160                                                     GrWrapOwnership,
161                                                     GrWrapCacheable) override;
162 
163     sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
164 
165     sk_sp<GrGpuBuffer> onCreateBuffer(size_t sizeInBytes, GrGpuBufferType, GrAccessPattern,
166                                       const void*) override;
167 
168     bool onReadPixels(GrSurface* surface, int left, int top, int width, int height,
169                       GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
170                       size_t rowBytes) override;
171 
172     bool onWritePixels(GrSurface* surface, int left, int top, int width, int height,
173                        GrColorType surfaceColorType, GrColorType srcColorType,
174                        const GrMipLevel texels[], int mipLevelCount,
175                        bool prepForTexSampling) override;
176 
onTransferPixelsTo(GrTexture * texture,int left,int top,int width,int height,GrColorType surfaceColorType,GrColorType bufferColorType,sk_sp<GrGpuBuffer> transferBuffer,size_t offset,size_t rowBytes)177     bool onTransferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
178                             GrColorType surfaceColorType, GrColorType bufferColorType,
179                             sk_sp<GrGpuBuffer> transferBuffer, size_t offset,
180                             size_t rowBytes) override {
181         return true;
182     }
onTransferPixelsFrom(GrSurface * surface,int left,int top,int width,int height,GrColorType surfaceColorType,GrColorType bufferColorType,sk_sp<GrGpuBuffer> transferBuffer,size_t offset)183     bool onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
184                               GrColorType surfaceColorType, GrColorType bufferColorType,
185                               sk_sp<GrGpuBuffer> transferBuffer, size_t offset) override {
186         return true;
187     }
188     bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
189                        const SkIPoint& dstPoint) override;
190 
191     bool onRegenerateMipMapLevels(GrTexture*) override;
192 
193     void onResolveRenderTarget(GrRenderTarget* target, const SkIRect&) override;
194 
195     void addFinishedProc(GrGpuFinishedProc finishedProc,
196                          GrGpuFinishedContext finishedContext) override;
197     void addFinishedCallback(sk_sp<GrRefCntedCallback> finishedCallback);
198 
199     GrOpsRenderPass* onGetOpsRenderPass(GrRenderTarget*,
200                                         bool useMSAASurface,
201                                         GrAttachment*,
202                                         GrSurfaceOrigin,
203                                         const SkIRect&,
204                                         const GrOpsRenderPass::LoadAndStoreInfo&,
205                                         const GrOpsRenderPass::StencilLoadAndStoreInfo&,
206                                         const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
207                                         GrXferBarrierFlags renderPassXferBarriers) override;
208 
209     void prepareSurfacesForBackendAccessAndStateUpdates(
210             SkSpan<GrSurfaceProxy*> proxies,
211             SkSurface::BackendSurfaceAccess access,
212             const GrBackendSurfaceMutableState* newState) override;
213 
214     bool onSubmitToGpu(bool syncCpu) override;
215 
216     GrBackendTexture onCreateBackendTexture(SkISize dimensions,
217                                             const GrBackendFormat&,
218                                             GrRenderable,
219                                             GrMipmapped,
220                                             GrProtected) override;
221 
222     bool onClearBackendTexture(const GrBackendTexture&,
223                                sk_sp<GrRefCntedCallback> finishedCallback,
224                                std::array<float, 4> color) override;
225 
226     GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions,
227                                                       const GrBackendFormat&,
228                                                       GrMipmapped,
229                                                       GrProtected) override;
230 
231     bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
232                                           sk_sp<GrRefCntedCallback> finishedCallback,
233                                           const void* data,
234                                           size_t size) override;
235 
236     bool submitDirectCommandList(SyncQueue sync);
237 
238     void checkForFinishedCommandLists();
239     void waitForQueueCompletion();
240 
241     void copySurfaceAsCopyTexture(GrSurface* dst, GrSurface* src, GrD3DTextureResource* dstResource,
242                                   GrD3DTextureResource* srcResource, const SkIRect& srcRect,
243                                   const SkIPoint& dstPoint);
244 
245     void copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
246                               const SkIPoint& dstPoint);
247     void resolveTexture(GrSurface* dst, int32_t dstX, int32_t dstY,
248                         GrD3DRenderTarget* src, const SkIRect& srcRect);
249 
250     sk_sp<GrD3DTexture> createD3DTexture(SkISize,
251                                          DXGI_FORMAT,
252                                          GrRenderable,
253                                          int renderTargetSampleCnt,
254                                          SkBudgeted,
255                                          GrProtected,
256                                          int mipLevelCount,
257                                          GrMipmapStatus);
258 
259     bool uploadToTexture(GrD3DTexture* tex, int left, int top, int width, int height,
260                          GrColorType colorType, const GrMipLevel* texels, int mipLevelCount);
261 
262     bool createTextureResourceForBackendSurface(DXGI_FORMAT dxgiFormat,
263                                                 SkISize dimensions,
264                                                 GrTexturable texturable,
265                                                 GrRenderable renderable,
266                                                 GrMipmapped mipMapped,
267                                                 int sampleCnt,
268                                                 GrD3DTextureResourceInfo* info,
269                                                 GrProtected isProtected);
270 
271     gr_cp<ID3D12Device> fDevice;
272     gr_cp<ID3D12CommandQueue> fQueue;
273 
274     sk_sp<GrD3DMemoryAllocator> fMemoryAllocator;
275 
276     GrD3DResourceProvider fResourceProvider;
277     GrStagingBufferManager fStagingBufferManager;
278     GrRingBuffer fConstantsRingBuffer;
279 
280     gr_cp<ID3D12Fence> fFence;
281     uint64_t fCurrentFenceValue = 0;
282 
283     std::unique_ptr<GrD3DDirectCommandList> fCurrentDirectCommandList;
284     // One-off special-case descriptors created directly for the mipmap compute shader
285     // and hence aren't tracked by the normal path.
286     SkSTArray<32, GrD3DDescriptorHeap::CPUHandle> fMipmapCPUDescriptors;
287 
288     struct OutstandingCommandList {
OutstandingCommandListOutstandingCommandList289         OutstandingCommandList(std::unique_ptr<GrD3DDirectCommandList> commandList,
290                                uint64_t fenceValue)
291             : fCommandList(std::move(commandList)), fFenceValue(fenceValue) {
292         }
293         std::unique_ptr<GrD3DDirectCommandList> fCommandList;
294         uint64_t fFenceValue;
295     };
296 
297     SkDeque fOutstandingCommandLists;
298 
299     std::unique_ptr<GrD3DOpsRenderPass> fCachedOpsRenderPass;
300 
301 #if GR_TEST_UTILS
302     IDXGraphicsAnalysis* fGraphicsAnalysis;
303 #endif
304 
305     using INHERITED = GrGpu;
306 };
307 
308 #endif
309