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 "GrGpu.h" 12 #include "GrRenderTarget.h" 13 #include "GrSemaphore.h" 14 #include "GrTexture.h" 15 16 #include "GrMtlCaps.h" 17 #include "GrMtlCopyManager.h" 18 #include "GrMtlResourceProvider.h" 19 #include "GrMtlStencilAttachment.h" 20 21 #import <Metal/Metal.h> 22 23 class GrMtlGpuRTCommandBuffer; 24 class GrMtlTexture; 25 class GrSemaphore; 26 struct GrMtlBackendContext; 27 28 namespace SkSL { 29 class Compiler; 30 } 31 32 class GrMtlGpu : public GrGpu { 33 public: 34 static sk_sp<GrGpu> Make(GrContext* context, const GrContextOptions& options, 35 id<MTLDevice> device, id<MTLCommandQueue> queue); 36 37 ~GrMtlGpu() override = default; 38 39 const GrMtlCaps& mtlCaps() const { return *fMtlCaps.get(); } 40 41 id<MTLDevice> device() const { return fDevice; } 42 43 id<MTLCommandBuffer> commandBuffer() const { return fCmdBuffer; } 44 45 GrMtlResourceProvider& resourceProvider() { return fResourceProvider; } 46 47 enum SyncQueue { 48 kForce_SyncQueue, 49 kSkip_SyncQueue 50 }; 51 52 // Commits the current command buffer to the queue and then creates a new command buffer. If 53 // sync is set to kForce_SyncQueue, the function will wait for all work in the committed 54 // command buffer to finish before creating a new buffer and returning. 55 void submitCommandBuffer(SyncQueue sync); 56 57 #ifdef GR_TEST_UTILS 58 GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h, 59 GrColorType colorType, bool isRT, 60 GrMipMapped, size_t rowBytes = 0) override; 61 62 bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; 63 64 void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override; 65 66 GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override; 67 68 void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; 69 70 void testingOnly_flushGpuAndSync() override; 71 #endif 72 73 bool copySurfaceAsBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin, 74 GrSurface* src, GrSurfaceOrigin srcOrigin, 75 const SkIRect& srcRect, const SkIPoint& dstPoint); 76 77 // This function is needed when we want to copy between two surfaces with different origins and 78 // the destination surface is not a render target. We will first draw to a temporary render 79 // target to adjust for the different origins and then blit from there to the destination. 80 bool copySurfaceAsDrawThenBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin, 81 GrSurface* src, GrSurfaceOrigin srcOrigin, 82 const SkIRect& srcRect, const SkIPoint& dstPoint); 83 84 bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, 85 GrSurface* src, GrSurfaceOrigin srcOrigin, 86 const SkIRect& srcRect, 87 const SkIPoint& dstPoint, 88 bool canDiscardOutsideDstRect) override; 89 90 GrGpuRTCommandBuffer* getCommandBuffer( 91 GrRenderTarget*, GrSurfaceOrigin, const SkRect& bounds, 92 const GrGpuRTCommandBuffer::LoadAndStoreInfo&, 93 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override; 94 95 GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override; 96 97 SkSL::Compiler* shaderCompiler() const { return fCompiler.get(); } 98 99 void submit(GrGpuCommandBuffer* buffer) override; 100 101 GrFence SK_WARN_UNUSED_RESULT insertFence() override { return 0; } 102 bool waitFence(GrFence, uint64_t) override { return true; } 103 void deleteFence(GrFence) const override {} 104 105 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override { 106 return nullptr; 107 } 108 sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore, 109 GrResourceProvider::SemaphoreWrapType wrapType, 110 GrWrapOwnership ownership) override { return nullptr; } 111 void insertSemaphore(sk_sp<GrSemaphore> semaphore) override {} 112 void waitSemaphore(sk_sp<GrSemaphore> semaphore) override {} 113 sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override { return nullptr; } 114 115 // When the Metal backend actually uses indirect command buffers, this function will actually do 116 // what it says. For now, every command is encoded directly into the primary command buffer, so 117 // this function is pretty useless, except for indicating that a render target has been drawn 118 // to. 119 void submitIndirectCommandBuffer(GrSurface* surface, GrSurfaceOrigin origin, 120 const SkIRect* bounds) { 121 this->didWriteToSurface(surface, origin, bounds); 122 } 123 124 private: 125 GrMtlGpu(GrContext* context, const GrContextOptions& options, 126 id<MTLDevice> device, id<MTLCommandQueue> queue, MTLFeatureSet featureSet); 127 128 void onResetContext(uint32_t resetBits) override {} 129 130 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {} 131 132 sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, 133 const GrMipLevel texels[], int mipLevelCount) override; 134 135 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrWrapCacheable, 136 GrIOType) override; 137 138 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt, 139 GrWrapOwnership, GrWrapCacheable) override; 140 141 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override; 142 143 sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&, 144 int sampleCnt) override; 145 146 sk_sp<GrBuffer> onCreateBuffer(size_t, GrBufferType, GrAccessPattern, const void*) override; 147 148 bool onReadPixels(GrSurface* surface, int left, int top, int width, int height, GrColorType, 149 void* buffer, size_t rowBytes) override; 150 151 bool onWritePixels(GrSurface*, int left, int top, int width, int height, GrColorType, 152 const GrMipLevel[], int mipLevelCount) override; 153 154 bool onTransferPixels(GrTexture*, 155 int left, int top, int width, int height, 156 GrColorType, GrBuffer*, 157 size_t offset, size_t rowBytes) override { 158 return false; 159 } 160 161 bool onRegenerateMipMapLevels(GrTexture*) override { return false; } 162 163 void onResolveRenderTarget(GrRenderTarget* target) override { return; } 164 165 void onFinishFlush(bool insertedSemaphores) override { 166 this->submitCommandBuffer(kSkip_SyncQueue); 167 } 168 169 // Function that uploads data onto textures with private storage mode (GPU access only). 170 bool uploadToTexture(GrMtlTexture* tex, int left, int top, int width, int height, 171 GrColorType dataColorType, const GrMipLevel texels[], int mipLevels); 172 173 GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*, 174 int width, 175 int height) override; 176 177 #if GR_TEST_UTILS 178 bool createTestingOnlyMtlTextureInfo(GrColorType colorType, int w, int h, bool texturable, 179 bool renderable, GrMipMapped mipMapped, 180 const void* srcData, size_t rowBytes, 181 GrMtlTextureInfo* info); 182 #endif 183 184 sk_sp<GrMtlCaps> fMtlCaps; 185 186 id<MTLDevice> fDevice; 187 id<MTLCommandQueue> fQueue; 188 189 id<MTLCommandBuffer> fCmdBuffer; 190 191 std::unique_ptr<SkSL::Compiler> fCompiler; 192 GrMtlCopyManager fCopyManager; 193 GrMtlResourceProvider fResourceProvider; 194 195 typedef GrGpu INHERITED; 196 }; 197 198 #endif 199 200