1 /* 2 * Copyright 2017 Google Inc. 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 GrMtlGpu_DEFINED 9 #define GrMtlGpu_DEFINED 10 11 #include "include/gpu/ganesh/mtl/GrMtlBackendContext.h" 12 #include "include/private/base/SkDeque.h" 13 #include "src/gpu/ganesh/mtl/GrMtlTypesPriv.h" 14 15 #include "src/gpu/ganesh/GrGpu.h" 16 #include "src/gpu/ganesh/GrRenderTarget.h" 17 #include "src/gpu/ganesh/GrRingBuffer.h" 18 #include "src/gpu/ganesh/GrSemaphore.h" 19 #include "src/gpu/ganesh/GrStagingBufferManager.h" 20 #include "src/gpu/ganesh/GrTexture.h" 21 22 #include "src/gpu/ganesh/mtl/GrMtlAttachment.h" 23 #include "src/gpu/ganesh/mtl/GrMtlCaps.h" 24 #include "src/gpu/ganesh/mtl/GrMtlCommandBuffer.h" 25 #include "src/gpu/ganesh/mtl/GrMtlResourceProvider.h" 26 #include "src/gpu/ganesh/mtl/GrMtlUtil.h" 27 28 #import <Metal/Metal.h> 29 30 class GrMtlOpsRenderPass; 31 class GrMtlTexture; 32 class GrSemaphore; 33 class GrMtlCommandBuffer; 34 35 class GrMtlGpu : public GrGpu { 36 public: 37 static std::unique_ptr<GrGpu> Make(const GrMtlBackendContext&, 38 const GrContextOptions&, 39 GrDirectContext*); 40 ~GrMtlGpu() override; 41 42 void disconnect(DisconnectType) override; 43 44 GrThreadSafePipelineBuilder* pipelineBuilder() override; 45 sk_sp<GrThreadSafePipelineBuilder> refPipelineBuilder() override; 46 mtlCaps()47 const GrMtlCaps& mtlCaps() const { return *fMtlCaps; } 48 device()49 id<MTLDevice> device() const { return fDevice; } 50 resourceProvider()51 GrMtlResourceProvider& resourceProvider() { return fResourceProvider; } 52 stagingBufferManager()53 GrStagingBufferManager* stagingBufferManager() override { return &fStagingBufferManager; } 54 55 GrMtlCommandBuffer* commandBuffer(); 56 57 enum SyncQueue { 58 kForce_SyncQueue, 59 kSkip_SyncQueue 60 }; 61 62 void deleteBackendTexture(const GrBackendTexture&) override; 63 64 bool compile(const GrProgramDesc&, const GrProgramInfo&) override; 65 66 bool precompileShader(const SkData& key, const SkData& data) 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 resetShaderCacheForTesting()77 void resetShaderCacheForTesting() const override { 78 fResourceProvider.resetShaderCacheForTesting(); 79 } 80 #endif 81 82 void copySurfaceAsResolve(GrSurface* dst, GrSurface* src); 83 84 void copySurfaceAsBlit(GrSurface* dst, GrSurface* src, 85 GrMtlAttachment* dstAttachment, GrMtlAttachment* srcAttachment, 86 const SkIRect& srcRect, const SkIPoint& dstPoint); 87 88 bool onCopySurface(GrSurface* dst, const SkIRect& dstRect, 89 GrSurface* src, const SkIRect& srcRect, 90 GrSamplerState::Filter) override; 91 92 void submit(GrOpsRenderPass* renderPass) override; 93 94 [[nodiscard]] std::unique_ptr<GrSemaphore> makeSemaphore(bool isOwned) override; 95 std::unique_ptr<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&, 96 GrSemaphoreWrapType, 97 GrWrapOwnership) override; 98 void insertSemaphore(GrSemaphore* semaphore) override; 99 void waitSemaphore(GrSemaphore* semaphore) override; checkFinishedCallbacks()100 void checkFinishedCallbacks() override { this->checkForFinishedCommandBuffers(); } 101 void finishOutstandingGpuWork() override; 102 std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override; 103 104 GrMtlRenderCommandEncoder* loadMSAAFromResolve(GrAttachment* dst, 105 GrMtlAttachment* src, 106 const SkIRect& srcRect, 107 MTLRenderPassStencilAttachmentDescriptor*); 108 109 // When the Metal backend actually uses indirect command buffers, this function will actually do 110 // what it says. For now, every command is encoded directly into the primary command buffer, so 111 // this function is pretty useless, except for indicating that a render target has been drawn 112 // to. submitIndirectCommandBuffer(GrSurface * surface,GrSurfaceOrigin origin,const SkIRect * bounds)113 void submitIndirectCommandBuffer(GrSurface* surface, GrSurfaceOrigin origin, 114 const SkIRect* bounds) { 115 this->didWriteToSurface(surface, origin, bounds); 116 } 117 uniformsRingBuffer()118 GrRingBuffer* uniformsRingBuffer() override { return &fUniformsRingBuffer; } 119 120 private: 121 GrMtlGpu(GrDirectContext*, const GrContextOptions&, id<MTLDevice>, id<MTLCommandQueue>); 122 123 void destroyResources(); 124 xferBarrier(GrRenderTarget *,GrXferBarrierType)125 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {} 126 127 void takeOwnershipOfBuffer(sk_sp<GrGpuBuffer>) override; 128 129 GrBackendTexture onCreateBackendTexture(SkISize dimensions, 130 const GrBackendFormat&, 131 GrRenderable, 132 skgpu::Mipmapped, 133 GrProtected, 134 std::string_view label) override; 135 136 bool onClearBackendTexture(const GrBackendTexture&, 137 sk_sp<skgpu::RefCntedCallback> finishedCallback, 138 std::array<float, 4> color) override; 139 140 GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, 141 const GrBackendFormat&, 142 skgpu::Mipmapped, 143 GrProtected) override; 144 145 bool onUpdateCompressedBackendTexture(const GrBackendTexture&, 146 sk_sp<skgpu::RefCntedCallback> finishedCallback, 147 const void* data, 148 size_t size) override; 149 150 sk_sp<GrTexture> onCreateTexture(SkISize, 151 const GrBackendFormat&, 152 GrRenderable, 153 int renderTargetSampleCnt, 154 skgpu::Budgeted, 155 GrProtected, 156 int mipLevelCount, 157 uint32_t levelClearMask, 158 std::string_view label) override; 159 sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions, 160 const GrBackendFormat&, 161 skgpu::Budgeted, 162 skgpu::Mipmapped, 163 GrProtected, 164 const void* data, 165 size_t dataSize) override; 166 167 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, 168 GrWrapOwnership, 169 GrWrapCacheable, 170 GrIOType) override; 171 172 sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&, 173 GrWrapOwnership, 174 GrWrapCacheable) override; 175 176 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, 177 int sampleCnt, 178 GrWrapOwnership, 179 GrWrapCacheable) override; 180 181 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override; 182 183 sk_sp<GrGpuBuffer> onCreateBuffer(size_t, GrGpuBufferType, GrAccessPattern) override; 184 185 bool onReadPixels(GrSurface* surface, 186 SkIRect, 187 GrColorType surfaceColorType, 188 GrColorType bufferColorType, 189 void*, 190 size_t rowBytes) override; 191 192 bool onTransferFromBufferToBuffer(sk_sp<GrGpuBuffer> src, 193 size_t srcOffset, 194 sk_sp<GrGpuBuffer> dst, 195 size_t dstOffset, 196 size_t size) override; 197 198 bool onWritePixels(GrSurface*, 199 SkIRect, 200 GrColorType surfaceColorType, 201 GrColorType bufferColorType, 202 const GrMipLevel[], 203 int mipLevelCount, 204 bool prepForTexSampling) override; 205 206 bool onTransferPixelsTo(GrTexture*, 207 SkIRect, 208 GrColorType textureColorType, 209 GrColorType bufferColorType, 210 sk_sp<GrGpuBuffer>, 211 size_t offset, 212 size_t rowBytes) override; 213 214 bool onTransferPixelsFrom(GrSurface*, 215 SkIRect, 216 GrColorType surfaceColorType, 217 GrColorType bufferColorType, 218 sk_sp<GrGpuBuffer>, 219 size_t offset) override; 220 221 bool onRegenerateMipMapLevels(GrTexture*) override; 222 223 void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) override; 224 225 void resolve(GrMtlAttachment* resolveAttachment, GrMtlAttachment* msaaAttachment); 226 addFinishedCallback(skgpu::AutoCallback callback,std::optional<GrTimerQuery> timerQuery)227 void addFinishedCallback(skgpu::AutoCallback callback, 228 std::optional<GrTimerQuery> timerQuery) override { 229 SkASSERT(!timerQuery); 230 this->addFinishedCallback(skgpu::RefCntedCallback::Make(std::move(callback))); 231 } 232 233 void addFinishedCallback(sk_sp<skgpu::RefCntedCallback> finishedCallback); 234 235 GrOpsRenderPass* onGetOpsRenderPass( 236 GrRenderTarget*, 237 bool useMSAASurface, 238 GrAttachment*, 239 GrSurfaceOrigin, 240 const SkIRect&, 241 const GrOpsRenderPass::LoadAndStoreInfo&, 242 const GrOpsRenderPass::StencilLoadAndStoreInfo&, 243 const skia_private::TArray<GrSurfaceProxy*, true>& sampledProxies, 244 GrXferBarrierFlags renderPassXferBarriers) override; 245 246 bool onSubmitToGpu(const GrSubmitInfo& info) override; 247 248 // Commits the current command buffer to the queue and then creates a new command buffer. If 249 // sync is set to kForce_SyncQueue, the function will wait for all work in the committed 250 // command buffer to finish before returning. 251 bool submitCommandBuffer(SyncQueue sync); 252 253 void checkForFinishedCommandBuffers(); 254 255 // Function that uploads data onto textures with private storage mode (GPU access only). 256 bool uploadToTexture(GrMtlTexture* tex, 257 SkIRect rect, 258 GrColorType dataColorType, 259 const GrMipLevel texels[], 260 int mipLevels); 261 262 // Function that fills texture levels with transparent black based on levelMask. 263 bool clearTexture(GrMtlTexture*, size_t bbp, uint32_t levelMask); 264 265 bool readOrTransferPixels(GrSurface* surface, 266 SkIRect rect, 267 GrColorType dstColorType, 268 id<MTLBuffer> transferBuffer, 269 size_t offset, 270 size_t imageBytes, 271 size_t rowBytes); 272 273 sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& /*colorFormat*/, 274 SkISize dimensions, int numStencilSamples) override; 275 getPreferredStencilFormat(const GrBackendFormat &)276 GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) override { 277 return GrBackendFormats::MakeMtl(this->mtlCaps().preferredStencilFormat()); 278 } 279 280 sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions, 281 const GrBackendFormat& format, 282 int numSamples, 283 GrProtected isProtected, 284 GrMemoryless isMemoryless) override; 285 286 bool createMtlTextureForBackendSurface(MTLPixelFormat, 287 SkISize dimensions, 288 int sampleCnt, 289 GrTexturable, 290 GrRenderable, 291 skgpu::Mipmapped, 292 GrMtlTextureInfo*); 293 294 #if defined(GPU_TEST_UTILS) 295 void testingOnly_startCapture() override; 296 void testingOnly_stopCapture() override; 297 #endif 298 299 #ifdef SK_ENABLE_DUMP_GPU 300 void onDumpJSON(SkJSONWriter*) const override; 301 #endif 302 303 sk_sp<GrMtlCaps> fMtlCaps; 304 305 id<MTLDevice> fDevice; 306 id<MTLCommandQueue> fQueue; 307 308 sk_sp<GrMtlCommandBuffer> fCurrentCmdBuffer; 309 310 using OutstandingCommandBuffer = sk_sp<GrMtlCommandBuffer>; 311 SkDeque fOutstandingCommandBuffers; 312 313 GrMtlResourceProvider fResourceProvider; 314 GrStagingBufferManager fStagingBufferManager; 315 GrRingBuffer fUniformsRingBuffer; 316 317 bool fDisconnected; 318 319 using INHERITED = GrGpu; 320 }; 321 322 #endif 323