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> onCreateCompressedTexture(SkISize dimensions, 155 const GrBackendFormat&, 156 skgpu::Budgeted, 157 skgpu::Mipmapped, 158 GrProtected, 159 OH_NativeBuffer* nativeBuffer, 160 size_t bufferSize) override; 161 162 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, 163 GrWrapOwnership, 164 GrWrapCacheable, 165 GrIOType) override; 166 sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&, 167 GrWrapOwnership, 168 GrWrapCacheable) override; 169 170 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, 171 int sampleCnt, 172 GrWrapOwnership, 173 GrWrapCacheable) override; 174 175 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override; 176 177 sk_sp<GrGpuBuffer> onCreateBuffer(size_t sizeInBytes, 178 GrGpuBufferType, 179 GrAccessPattern) override; 180 181 bool onReadPixels(GrSurface*, 182 SkIRect, 183 GrColorType surfaceColorType, 184 GrColorType dstColorType, 185 void*, 186 size_t rowBytes) override; 187 188 bool onWritePixels(GrSurface*, 189 SkIRect, 190 GrColorType surfaceColorType, 191 GrColorType srcColorType, 192 const GrMipLevel[], 193 int mipLevelCount, 194 bool prepForTexSampling) override; 195 196 bool onTransferFromBufferToBuffer(sk_sp<GrGpuBuffer> src, 197 size_t srcOffset, 198 sk_sp<GrGpuBuffer> dst, 199 size_t dstOffset, 200 size_t size) override; 201 202 bool onTransferPixelsTo(GrTexture*, 203 SkIRect, 204 GrColorType surfaceColorType, 205 GrColorType bufferColorType, 206 sk_sp<GrGpuBuffer>, 207 size_t offset, 208 size_t rowBytes) override; 209 210 bool onTransferPixelsFrom(GrSurface*, 211 SkIRect, 212 GrColorType surfaceColorType, 213 GrColorType bufferColorType, 214 sk_sp<GrGpuBuffer>, 215 size_t offset) override; 216 217 bool onCopySurface(GrSurface* dst, const SkIRect& dstRect, 218 GrSurface* src, const SkIRect& srcRect, 219 GrSamplerState::Filter) override; 220 221 bool onRegenerateMipMapLevels(GrTexture*) override; 222 223 void onResolveRenderTarget(GrRenderTarget* target, const SkIRect&) override; 224 addFinishedCallback(skgpu::AutoCallback callback,std::optional<GrTimerQuery> timerQuery)225 void addFinishedCallback(skgpu::AutoCallback callback, 226 std::optional<GrTimerQuery> timerQuery) override { 227 SkASSERT(!timerQuery); 228 this->addFinishedCallback(skgpu::RefCntedCallback::Make(std::move(callback))); 229 } 230 231 void addFinishedCallback(sk_sp<skgpu::RefCntedCallback> finishedCallback); 232 233 GrOpsRenderPass* onGetOpsRenderPass( 234 GrRenderTarget*, 235 bool useMSAASurface, 236 GrAttachment*, 237 GrSurfaceOrigin, 238 const SkIRect&, 239 const GrOpsRenderPass::LoadAndStoreInfo&, 240 const GrOpsRenderPass::StencilLoadAndStoreInfo&, 241 const skia_private::TArray<GrSurfaceProxy*, true>& sampledProxies, 242 GrXferBarrierFlags renderPassXferBarriers) override; 243 244 void prepareSurfacesForBackendAccessAndStateUpdates( 245 SkSpan<GrSurfaceProxy*> proxies, 246 SkSurfaces::BackendSurfaceAccess access, 247 const skgpu::MutableTextureState* newState) override; 248 249 bool onSubmitToGpu(const GrSubmitInfo& info) override; 250 251 GrBackendTexture onCreateBackendTexture(SkISize dimensions, 252 const GrBackendFormat&, 253 GrRenderable, 254 skgpu::Mipmapped, 255 GrProtected, 256 std::string_view label) override; 257 258 bool onClearBackendTexture(const GrBackendTexture&, 259 sk_sp<skgpu::RefCntedCallback> finishedCallback, 260 std::array<float, 4> color) override; 261 262 GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, 263 const GrBackendFormat&, 264 skgpu::Mipmapped, 265 GrProtected) override; 266 267 bool onUpdateCompressedBackendTexture(const GrBackendTexture&, 268 sk_sp<skgpu::RefCntedCallback> finishedCallback, 269 const void* data, 270 size_t size) override; 271 272 bool submitDirectCommandList(SyncQueue sync); 273 274 void checkForFinishedCommandLists(); 275 void waitForQueueCompletion(); 276 277 void copySurfaceAsCopyTexture(GrSurface* dst, GrSurface* src, GrD3DTextureResource* dstResource, 278 GrD3DTextureResource* srcResource, const SkIRect& srcRect, 279 const SkIPoint& dstPoint); 280 281 void copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 282 const SkIPoint& dstPoint); 283 void resolveTexture(GrSurface* dst, int32_t dstX, int32_t dstY, 284 GrD3DRenderTarget* src, const SkIRect& srcRect); 285 286 sk_sp<GrD3DTexture> createD3DTexture(SkISize, 287 DXGI_FORMAT, 288 GrRenderable, 289 int renderTargetSampleCnt, 290 skgpu::Budgeted, 291 GrProtected, 292 int mipLevelCount, 293 GrMipmapStatus, 294 std::string_view label); 295 296 bool uploadToTexture(GrD3DTexture* tex, 297 SkIRect rect, 298 GrColorType colorType, 299 const GrMipLevel texels[], 300 int mipLevelCount); 301 302 void readOrTransferPixels(GrD3DTextureResource* texResource, 303 SkIRect rect, 304 sk_sp<GrGpuBuffer> transferBuffer, 305 const D3D12_PLACED_SUBRESOURCE_FOOTPRINT& placedFootprint); 306 307 bool createTextureResourceForBackendSurface(DXGI_FORMAT dxgiFormat, 308 SkISize dimensions, 309 GrTexturable texturable, 310 GrRenderable renderable, 311 skgpu::Mipmapped mipmapped, 312 int sampleCnt, 313 GrD3DTextureResourceInfo* info, 314 GrProtected isProtected); 315 316 gr_cp<ID3D12Device> fDevice; 317 gr_cp<ID3D12CommandQueue> fQueue; 318 319 sk_sp<GrD3DMemoryAllocator> fMemoryAllocator; 320 321 GrD3DResourceProvider fResourceProvider; 322 GrStagingBufferManager fStagingBufferManager; 323 GrRingBuffer fConstantsRingBuffer; 324 325 gr_cp<ID3D12Fence> fFence; 326 uint64_t fCurrentFenceValue = 0; 327 328 std::unique_ptr<GrD3DDirectCommandList> fCurrentDirectCommandList; 329 // One-off special-case descriptors created directly for the mipmap compute shader 330 // and hence aren't tracked by the normal path. 331 skia_private::STArray<32, GrD3DDescriptorHeap::CPUHandle> fMipmapCPUDescriptors; 332 333 struct OutstandingCommandList { OutstandingCommandListOutstandingCommandList334 OutstandingCommandList(std::unique_ptr<GrD3DDirectCommandList> commandList, 335 uint64_t fenceValue) 336 : fCommandList(std::move(commandList)), fFenceValue(fenceValue) { 337 } 338 std::unique_ptr<GrD3DDirectCommandList> fCommandList; 339 uint64_t fFenceValue; 340 }; 341 342 SkDeque fOutstandingCommandLists; 343 344 std::unique_ptr<GrD3DOpsRenderPass> fCachedOpsRenderPass; 345 346 #if defined(GPU_TEST_UTILS) 347 IDXGraphicsAnalysis* fGraphicsAnalysis; 348 #endif 349 350 using INHERITED = GrGpu; 351 }; 352 353 #endif 354