blob: 35f505ed3b26e1fda4d13670f17459dbc8a64d7a [file] [log] [blame]
Greg Daniele5ddff52017-07-05 16:49:36 -04001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/gpu/GrRenderTarget.h"
12#include "include/gpu/GrTexture.h"
13#include "src/gpu/GrGpu.h"
14#include "src/gpu/GrSemaphore.h"
Greg Daniele5ddff52017-07-05 16:49:36 -040015
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/gpu/mtl/GrMtlCaps.h"
17#include "src/gpu/mtl/GrMtlCopyManager.h"
18#include "src/gpu/mtl/GrMtlResourceProvider.h"
19#include "src/gpu/mtl/GrMtlStencilAttachment.h"
Greg Danielcebcb842017-07-31 10:45:52 -040020
Greg Daniele5ddff52017-07-05 16:49:36 -040021#import <Metal/Metal.h>
22
Ethan Nicholas01063512018-10-08 16:58:25 -040023class GrMtlGpuRTCommandBuffer;
Timothy Liangff19c8f2018-07-11 13:27:21 -040024class GrMtlTexture;
Greg Daniele5ddff52017-07-05 16:49:36 -040025class GrSemaphore;
Greg Danielb76a72a2017-07-13 15:07:54 -040026struct GrMtlBackendContext;
Jim Van Verth75c3ae42019-04-22 17:07:53 -040027class GrMtlCommandBuffer;
Greg Daniele5ddff52017-07-05 16:49:36 -040028
Timothy Liange30739a2018-07-31 10:51:17 -040029namespace SkSL {
30 class Compiler;
31}
32
Jim Van Verth61610be2019-03-07 15:33:49 -050033// Helper macros for autorelease pools
34#define SK_BEGIN_AUTORELEASE_BLOCK @autoreleasepool {
35#define SK_END_AUTORELEASE_BLOCK }
36
Greg Daniele5ddff52017-07-05 16:49:36 -040037class GrMtlGpu : public GrGpu {
38public:
Brian Salomon384fab42017-12-07 12:33:05 -050039 static sk_sp<GrGpu> Make(GrContext* context, const GrContextOptions& options,
40 id<MTLDevice> device, id<MTLCommandQueue> queue);
Jim Van Verth75c3ae42019-04-22 17:07:53 -040041 ~GrMtlGpu() override;
Greg Daniele5ddff52017-07-05 16:49:36 -040042
Jim Van Verth75c3ae42019-04-22 17:07:53 -040043 void disconnect(DisconnectType) override;
Greg Daniel4a081e22017-08-04 09:34:44 -040044
Greg Danielcebcb842017-07-31 10:45:52 -040045 const GrMtlCaps& mtlCaps() const { return *fMtlCaps.get(); }
Greg Daniele5ddff52017-07-05 16:49:36 -040046
Greg Daniel4a081e22017-08-04 09:34:44 -040047 id<MTLDevice> device() const { return fDevice; }
48
Timothy Liange30739a2018-07-31 10:51:17 -040049 GrMtlResourceProvider& resourceProvider() { return fResourceProvider; }
50
Jim Van Verth75c3ae42019-04-22 17:07:53 -040051 GrMtlCommandBuffer* commandBuffer();
Jim Van Verth568eb8d2019-04-04 14:30:42 -040052
Timothy Liangef21d7e2018-07-02 17:03:30 -040053 enum SyncQueue {
54 kForce_SyncQueue,
55 kSkip_SyncQueue
56 };
57
Timothy Liang49528b62018-08-02 14:18:37 -040058 // Commits the current command buffer to the queue and then creates a new command buffer. If
59 // sync is set to kForce_SyncQueue, the function will wait for all work in the committed
60 // command buffer to finish before creating a new buffer and returning.
61 void submitCommandBuffer(SyncQueue sync);
62
Robert Phillips9dbcdcc2019-05-13 10:40:06 -040063 GrBackendTexture createTestingOnlyBackendTexture(int w, int h,
64 const GrBackendFormat& format,
65 GrMipMapped mipMapped,
66 GrRenderable renderable,
67 const void* pixels = nullptr,
68 size_t rowBytes = 0) override;
Timothy Liang760dbc42018-07-17 13:28:20 -040069
Michael Ludwig8ad0cbd2019-05-15 19:32:01 +000070 void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override;
71
Robert Phillipsf0ced622019-05-16 09:06:25 -040072#if GR_TEST_UTILS
73 bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
Michael Ludwig8ad0cbd2019-05-15 19:32:01 +000074
Robert Phillipsf0ced622019-05-16 09:06:25 -040075 GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override;
Timothy Liang760dbc42018-07-17 13:28:20 -040076 void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
77
78 void testingOnly_flushGpuAndSync() override;
79#endif
80
Timothy Liange35055f2018-07-20 16:53:00 -040081 bool copySurfaceAsBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin,
82 GrSurface* src, GrSurfaceOrigin srcOrigin,
83 const SkIRect& srcRect, const SkIPoint& dstPoint);
84
Timothy Liang70c787a2018-08-01 09:56:25 -040085 // This function is needed when we want to copy between two surfaces with different origins and
86 // the destination surface is not a render target. We will first draw to a temporary render
87 // target to adjust for the different origins and then blit from there to the destination.
88 bool copySurfaceAsDrawThenBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin,
89 GrSurface* src, GrSurfaceOrigin srcOrigin,
90 const SkIRect& srcRect, const SkIPoint& dstPoint);
91
Robert Phillipsb0e93a22017-08-29 08:26:54 -040092 bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
93 GrSurface* src, GrSurfaceOrigin srcOrigin,
Greg Daniele5ddff52017-07-05 16:49:36 -040094 const SkIRect& srcRect,
Greg Daniel55fa6472018-03-16 16:13:10 -040095 const SkIPoint& dstPoint,
Timothy Liange35055f2018-07-20 16:53:00 -040096 bool canDiscardOutsideDstRect) override;
Greg Daniele5ddff52017-07-05 16:49:36 -040097
Robert Phillips5b5d84c2018-08-09 15:12:18 -040098 GrGpuRTCommandBuffer* getCommandBuffer(
Ethan Nicholas56d19a52018-10-15 11:26:20 -040099 GrRenderTarget*, GrSurfaceOrigin, const SkRect& bounds,
Greg Daniel6682ff22017-08-24 17:10:47 -0400100 const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
Timothy Liange70604e2018-07-19 09:49:46 -0400101 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override;
Greg Daniel6682ff22017-08-24 17:10:47 -0400102
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400103 GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400104
Timothy Liange30739a2018-07-31 10:51:17 -0400105 SkSL::Compiler* shaderCompiler() const { return fCompiler.get(); }
106
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400107 void submit(GrGpuCommandBuffer* buffer) override;
108
Greg Daniele5ddff52017-07-05 16:49:36 -0400109 GrFence SK_WARN_UNUSED_RESULT insertFence() override { return 0; }
110 bool waitFence(GrFence, uint64_t) override { return true; }
111 void deleteFence(GrFence) const override {}
112
113 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override {
114 return nullptr;
115 }
Greg Daniel48661b82018-01-22 16:11:35 -0500116 sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
117 GrResourceProvider::SemaphoreWrapType wrapType,
118 GrWrapOwnership ownership) override { return nullptr; }
Greg Daniel858e12c2018-12-06 11:11:37 -0500119 void insertSemaphore(sk_sp<GrSemaphore> semaphore) override {}
Greg Daniel48661b82018-01-22 16:11:35 -0500120 void waitSemaphore(sk_sp<GrSemaphore> semaphore) override {}
Brian Salomonb0d8b762019-05-06 16:58:22 -0400121 // We currently call finish procs immediately in onFinishFlush().
122 void checkFinishProcs() override {}
Greg Daniele5ddff52017-07-05 16:49:36 -0400123 sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override { return nullptr; }
124
Timothy Liang5422f9a2018-08-10 10:57:55 -0400125 // When the Metal backend actually uses indirect command buffers, this function will actually do
126 // what it says. For now, every command is encoded directly into the primary command buffer, so
127 // this function is pretty useless, except for indicating that a render target has been drawn
128 // to.
129 void submitIndirectCommandBuffer(GrSurface* surface, GrSurfaceOrigin origin,
130 const SkIRect* bounds) {
131 this->didWriteToSurface(surface, origin, bounds);
132 }
133
Greg Daniele5ddff52017-07-05 16:49:36 -0400134private:
Greg Danielb76a72a2017-07-13 15:07:54 -0400135 GrMtlGpu(GrContext* context, const GrContextOptions& options,
Greg Danielcebcb842017-07-31 10:45:52 -0400136 id<MTLDevice> device, id<MTLCommandQueue> queue, MTLFeatureSet featureSet);
Greg Daniele5ddff52017-07-05 16:49:36 -0400137
Jim Van Verth75c3ae42019-04-22 17:07:53 -0400138 void destroyResources();
139
Greg Daniele5ddff52017-07-05 16:49:36 -0400140 void onResetContext(uint32_t resetBits) override {}
141
Chris Dalton8c4cafd2019-04-15 19:14:36 -0600142 void querySampleLocations(GrRenderTarget*, SkTArray<SkPoint>*) override {
Chris Daltond7291ba2019-03-07 14:17:03 -0700143 SkASSERT(!this->caps()->sampleLocationsSupport());
144 SK_ABORT("Sample locations not yet implemented for Metal.");
145 }
146
Greg Daniele5ddff52017-07-05 16:49:36 -0400147 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
148
149 sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
Brian Salomon58389b92018-03-07 13:01:25 -0500150 const GrMipLevel texels[], int mipLevelCount) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400151
Brian Salomonfa2ebea2019-01-24 15:58:58 -0500152 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrWrapCacheable,
153 GrIOType) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400154
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500155 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt,
156 GrWrapOwnership, GrWrapCacheable) override;
Brian Salomond17f6582017-07-19 18:28:58 -0400157
Timothy Liange886e802018-07-02 16:03:28 -0400158 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400159
160 sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&,
Timothy Liange886e802018-07-02 16:03:28 -0400161 int sampleCnt) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400162
Brian Salomondbf70722019-02-07 11:31:24 -0500163 sk_sp<GrGpuBuffer> onCreateBuffer(size_t, GrGpuBufferType, GrAccessPattern,
164 const void*) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400165
Brian Salomona6948702018-06-01 15:33:20 -0400166 bool onReadPixels(GrSurface* surface, int left, int top, int width, int height, GrColorType,
Timothy Liangef21d7e2018-07-02 17:03:30 -0400167 void* buffer, size_t rowBytes) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400168
Brian Salomona9b04b92018-06-01 15:04:28 -0400169 bool onWritePixels(GrSurface*, int left, int top, int width, int height, GrColorType,
Timothy Lianga8046af2018-07-19 09:58:00 -0400170 const GrMipLevel[], int mipLevelCount) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400171
Brian Salomone05ba5a2019-04-08 11:59:07 -0400172 bool onTransferPixelsTo(GrTexture*,
173 int left, int top, int width, int height,
174 GrColorType, GrGpuBuffer*,
175 size_t offset, size_t rowBytes) override {
Jim Van Verth686046b2019-03-18 15:39:22 -0400176 // TODO: not sure this is worth the work since nobody uses it
Greg Daniele5ddff52017-07-05 16:49:36 -0400177 return false;
178 }
Brian Salomon26de56e2019-04-10 12:14:26 -0400179 bool onTransferPixelsFrom(GrSurface*, int left, int top, int width, int height, GrColorType,
180 GrGpuBuffer*, size_t offset) override {
Brian Salomone05ba5a2019-04-08 11:59:07 -0400181 // TODO: Will need to implement this to support async read backs.
Brian Salomon26de56e2019-04-10 12:14:26 -0400182 return false;
Brian Salomone05ba5a2019-04-08 11:59:07 -0400183 }
Greg Daniele5ddff52017-07-05 16:49:36 -0400184
Jim Van Verth686046b2019-03-18 15:39:22 -0400185 bool onRegenerateMipMapLevels(GrTexture*) override;
Brian Salomon930f9392018-06-20 16:25:26 -0400186
Brian Salomon1fabd512018-02-09 09:54:25 -0500187 void onResolveRenderTarget(GrRenderTarget* target) override { return; }
Greg Daniele5ddff52017-07-05 16:49:36 -0400188
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400189 void onFinishFlush(GrSurfaceProxy*[], int n, SkSurface::BackendSurfaceAccess access,
Greg Daniel797efca2019-05-09 14:04:20 -0400190 const GrFlushInfo& info, const GrPrepareForExternalIORequests&) override {
Greg Daniele6bfb7d2019-04-17 15:26:11 -0400191 if (info.fFlags & kSyncCpu_GrFlushFlag) {
Greg Danielbae71212019-03-01 15:24:35 -0500192 this->submitCommandBuffer(kForce_SyncQueue);
Greg Daniele6bfb7d2019-04-17 15:26:11 -0400193 if (info.fFinishedProc) {
194 info.fFinishedProc(info.fFinishedContext);
Greg Daniela3aa75a2019-04-12 14:24:55 -0400195 }
Greg Danielbae71212019-03-01 15:24:35 -0500196 } else {
197 this->submitCommandBuffer(kSkip_SyncQueue);
Greg Daniela3aa75a2019-04-12 14:24:55 -0400198 // TODO: support finishedProc to actually be called when the GPU is done with the work
199 // and not immediately.
Greg Daniele6bfb7d2019-04-17 15:26:11 -0400200 if (info.fFinishedProc) {
201 info.fFinishedProc(info.fFinishedContext);
Greg Daniela3aa75a2019-04-12 14:24:55 -0400202 }
Greg Danielbae71212019-03-01 15:24:35 -0500203 }
Timothy Liang5422f9a2018-08-10 10:57:55 -0400204 }
Greg Daniel51316782017-08-02 15:10:09 +0000205
Timothy Liangff19c8f2018-07-11 13:27:21 -0400206 // Function that uploads data onto textures with private storage mode (GPU access only).
207 bool uploadToTexture(GrMtlTexture* tex, int left, int top, int width, int height,
208 GrColorType dataColorType, const GrMipLevel texels[], int mipLevels);
Jim Van Verth686046b2019-03-18 15:39:22 -0400209 // Function that fills texture with transparent black
210 bool clearTexture(GrMtlTexture*, GrColorType);
Timothy Liangff19c8f2018-07-11 13:27:21 -0400211
Greg Daniele5ddff52017-07-05 16:49:36 -0400212 GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*,
213 int width,
Ethan Nicholas01063512018-10-08 16:58:25 -0400214 int height) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400215
Robert Phillips9dbcdcc2019-05-13 10:40:06 -0400216 bool createTestingOnlyMtlTextureInfo(GrPixelConfig, MTLPixelFormat,
217 int w, int h, bool texturable,
Timothy Liang760dbc42018-07-17 13:28:20 -0400218 bool renderable, GrMipMapped mipMapped,
Robert Phillips646f6372018-09-25 09:31:10 -0400219 const void* srcData, size_t rowBytes,
220 GrMtlTextureInfo* info);
Greg Daniel26b50a42018-03-08 09:49:58 -0500221
Greg Danielcebcb842017-07-31 10:45:52 -0400222 sk_sp<GrMtlCaps> fMtlCaps;
223
Greg Danielb76a72a2017-07-13 15:07:54 -0400224 id<MTLDevice> fDevice;
225 id<MTLCommandQueue> fQueue;
226
Jim Van Verth75c3ae42019-04-22 17:07:53 -0400227 GrMtlCommandBuffer* fCmdBuffer;
Greg Daniele5ddff52017-07-05 16:49:36 -0400228
Timothy Liange30739a2018-07-31 10:51:17 -0400229 std::unique_ptr<SkSL::Compiler> fCompiler;
Jim Van Verth75c53262019-04-26 12:23:51 -0400230
231 GrMtlCopyManager fCopyManager;
Timothy Liange30739a2018-07-31 10:51:17 -0400232 GrMtlResourceProvider fResourceProvider;
233
Jim Van Verth75c3ae42019-04-22 17:07:53 -0400234 bool fDisconnected;
235
Greg Daniele5ddff52017-07-05 16:49:36 -0400236 typedef GrGpu INHERITED;
237};
238
239#endif
240