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