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