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