blob: 607f70414a6e82e6d10117046f4b2325fcc26594 [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
11#include "GrGpu.h"
12#include "GrRenderTarget.h"
13#include "GrSemaphore.h"
14#include "GrTexture.h"
15
Greg Danielcebcb842017-07-31 10:45:52 -040016#include "GrMtlCaps.h"
Timothy Liange30739a2018-07-31 10:51:17 -040017#include "GrMtlCopyManager.h"
18#include "GrMtlResourceProvider.h"
Ethan Nicholas01063512018-10-08 16:58:25 -040019#include "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;
Greg Daniele5ddff52017-07-05 16:49:36 -040027
Timothy Liange30739a2018-07-31 10:51:17 -040028namespace SkSL {
29 class Compiler;
30}
31
Greg Daniele5ddff52017-07-05 16:49:36 -040032class GrMtlGpu : public GrGpu {
33public:
Brian Salomon384fab42017-12-07 12:33:05 -050034 static sk_sp<GrGpu> Make(GrContext* context, const GrContextOptions& options,
35 id<MTLDevice> device, id<MTLCommandQueue> queue);
Greg Daniele5ddff52017-07-05 16:49:36 -040036
Timothy Liange30739a2018-07-31 10:51:17 -040037 ~GrMtlGpu() override = default;
Greg Daniel4a081e22017-08-04 09:34:44 -040038
Greg Danielcebcb842017-07-31 10:45:52 -040039 const GrMtlCaps& mtlCaps() const { return *fMtlCaps.get(); }
Greg Daniele5ddff52017-07-05 16:49:36 -040040
Greg Daniel4a081e22017-08-04 09:34:44 -040041 id<MTLDevice> device() const { return fDevice; }
42
Timothy Liangef21d7e2018-07-02 17:03:30 -040043 id<MTLCommandBuffer> commandBuffer() const { return fCmdBuffer; }
44
Timothy Liange30739a2018-07-31 10:51:17 -040045 GrMtlResourceProvider& resourceProvider() { return fResourceProvider; }
46
Timothy Liangef21d7e2018-07-02 17:03:30 -040047 enum SyncQueue {
48 kForce_SyncQueue,
49 kSkip_SyncQueue
50 };
51
Timothy Liang49528b62018-08-02 14:18:37 -040052 // 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
Timothy Liang760dbc42018-07-17 13:28:20 -040057#ifdef GR_TEST_UTILS
58 GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h,
Robert Phillips646f6372018-09-25 09:31:10 -040059 GrColorType colorType, bool isRT,
60 GrMipMapped, size_t rowBytes = 0) override;
Timothy Liang760dbc42018-07-17 13:28:20 -040061
62 bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
63
64 void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override;
65
Brian Osman2d010b62018-08-09 10:55:09 -040066 GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override;
Timothy Liang760dbc42018-07-17 13:28:20 -040067
68 void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
69
70 void testingOnly_flushGpuAndSync() override;
71#endif
72
Timothy Liange35055f2018-07-20 16:53:00 -040073 bool copySurfaceAsBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin,
74 GrSurface* src, GrSurfaceOrigin srcOrigin,
75 const SkIRect& srcRect, const SkIPoint& dstPoint);
76
Timothy Liang70c787a2018-08-01 09:56:25 -040077 // 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
Robert Phillipsb0e93a22017-08-29 08:26:54 -040084 bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
85 GrSurface* src, GrSurfaceOrigin srcOrigin,
Greg Daniele5ddff52017-07-05 16:49:36 -040086 const SkIRect& srcRect,
Greg Daniel55fa6472018-03-16 16:13:10 -040087 const SkIPoint& dstPoint,
Timothy Liange35055f2018-07-20 16:53:00 -040088 bool canDiscardOutsideDstRect) override;
Greg Daniele5ddff52017-07-05 16:49:36 -040089
Robert Phillips5b5d84c2018-08-09 15:12:18 -040090 GrGpuRTCommandBuffer* getCommandBuffer(
Ethan Nicholas56d19a52018-10-15 11:26:20 -040091 GrRenderTarget*, GrSurfaceOrigin, const SkRect& bounds,
Greg Daniel6682ff22017-08-24 17:10:47 -040092 const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
Timothy Liange70604e2018-07-19 09:49:46 -040093 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override;
Greg Daniel6682ff22017-08-24 17:10:47 -040094
Robert Phillips5b5d84c2018-08-09 15:12:18 -040095 GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
Greg Daniele5ddff52017-07-05 16:49:36 -040096
Timothy Liange30739a2018-07-31 10:51:17 -040097 SkSL::Compiler* shaderCompiler() const { return fCompiler.get(); }
98
Robert Phillips5b5d84c2018-08-09 15:12:18 -040099 void submit(GrGpuCommandBuffer* buffer) override;
100
Greg Daniele5ddff52017-07-05 16:49:36 -0400101 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 }
Greg Daniel48661b82018-01-22 16:11:35 -0500108 sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
109 GrResourceProvider::SemaphoreWrapType wrapType,
110 GrWrapOwnership ownership) override { return nullptr; }
111 void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override {}
112 void waitSemaphore(sk_sp<GrSemaphore> semaphore) override {}
Greg Daniele5ddff52017-07-05 16:49:36 -0400113 sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override { return nullptr; }
114
Timothy Liang5422f9a2018-08-10 10:57:55 -0400115 // 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
Greg Daniele5ddff52017-07-05 16:49:36 -0400124private:
Greg Danielb76a72a2017-07-13 15:07:54 -0400125 GrMtlGpu(GrContext* context, const GrContextOptions& options,
Greg Danielcebcb842017-07-31 10:45:52 -0400126 id<MTLDevice> device, id<MTLCommandQueue> queue, MTLFeatureSet featureSet);
Greg Daniele5ddff52017-07-05 16:49:36 -0400127
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,
Brian Salomon58389b92018-03-07 13:01:25 -0500133 const GrMipLevel texels[], int mipLevelCount) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400134
Brian Salomon796693a2018-12-05 14:36:35 -0500135 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrIOType,
Greg Daniel2268ad22018-11-15 09:27:38 -0500136 bool purgeImmediately) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400137
Brian Salomond17f6582017-07-19 18:28:58 -0400138 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
Brian Salomond17f6582017-07-19 18:28:58 -0400139 int sampleCnt,
Timothy Liange886e802018-07-02 16:03:28 -0400140 GrWrapOwnership) override;
Brian Salomond17f6582017-07-19 18:28:58 -0400141
Timothy Liange886e802018-07-02 16:03:28 -0400142 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400143
144 sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&,
Timothy Liange886e802018-07-02 16:03:28 -0400145 int sampleCnt) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400146
Timothy Liang49528b62018-08-02 14:18:37 -0400147 GrBuffer* onCreateBuffer(size_t, GrBufferType, GrAccessPattern, const void*) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400148
Brian Salomona6948702018-06-01 15:33:20 -0400149 bool onReadPixels(GrSurface* surface, int left, int top, int width, int height, GrColorType,
Timothy Liangef21d7e2018-07-02 17:03:30 -0400150 void* buffer, size_t rowBytes) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400151
Brian Salomona9b04b92018-06-01 15:04:28 -0400152 bool onWritePixels(GrSurface*, int left, int top, int width, int height, GrColorType,
Timothy Lianga8046af2018-07-19 09:58:00 -0400153 const GrMipLevel[], int mipLevelCount) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400154
Brian Salomonc320b152018-02-20 14:05:36 -0500155 bool onTransferPixels(GrTexture*,
Greg Daniele5ddff52017-07-05 16:49:36 -0400156 int left, int top, int width, int height,
Brian Salomonc320b152018-02-20 14:05:36 -0500157 GrColorType, GrBuffer*,
Greg Daniele5ddff52017-07-05 16:49:36 -0400158 size_t offset, size_t rowBytes) override {
159 return false;
160 }
161
Brian Salomon930f9392018-06-20 16:25:26 -0400162 bool onRegenerateMipMapLevels(GrTexture*) override { return false; }
163
Brian Salomon1fabd512018-02-09 09:54:25 -0500164 void onResolveRenderTarget(GrRenderTarget* target) override { return; }
Greg Daniele5ddff52017-07-05 16:49:36 -0400165
Timothy Liang5422f9a2018-08-10 10:57:55 -0400166 void onFinishFlush(bool insertedSemaphores) override {
167 this->submitCommandBuffer(kSkip_SyncQueue);
168 }
Greg Daniel51316782017-08-02 15:10:09 +0000169
Timothy Liangff19c8f2018-07-11 13:27:21 -0400170 // Function that uploads data onto textures with private storage mode (GPU access only).
171 bool uploadToTexture(GrMtlTexture* tex, int left, int top, int width, int height,
172 GrColorType dataColorType, const GrMipLevel texels[], int mipLevels);
173
Greg Daniele5ddff52017-07-05 16:49:36 -0400174 GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*,
175 int width,
Ethan Nicholas01063512018-10-08 16:58:25 -0400176 int height) override;
Greg Daniele5ddff52017-07-05 16:49:36 -0400177
Brian Salomonf865b052018-03-09 09:01:53 -0500178#if GR_TEST_UTILS
Robert Phillips646f6372018-09-25 09:31:10 -0400179 bool createTestingOnlyMtlTextureInfo(GrColorType colorType, int w, int h, bool texturable,
Timothy Liang760dbc42018-07-17 13:28:20 -0400180 bool renderable, GrMipMapped mipMapped,
Robert Phillips646f6372018-09-25 09:31:10 -0400181 const void* srcData, size_t rowBytes,
182 GrMtlTextureInfo* info);
Brian Salomonf865b052018-03-09 09:01:53 -0500183#endif
Greg Daniel26b50a42018-03-08 09:49:58 -0500184
Greg Danielcebcb842017-07-31 10:45:52 -0400185 sk_sp<GrMtlCaps> fMtlCaps;
186
Greg Danielb76a72a2017-07-13 15:07:54 -0400187 id<MTLDevice> fDevice;
188 id<MTLCommandQueue> fQueue;
189
Timothy Liangef21d7e2018-07-02 17:03:30 -0400190 id<MTLCommandBuffer> fCmdBuffer;
Greg Daniele5ddff52017-07-05 16:49:36 -0400191
Timothy Liange30739a2018-07-31 10:51:17 -0400192 std::unique_ptr<SkSL::Compiler> fCompiler;
193 GrMtlCopyManager fCopyManager;
194 GrMtlResourceProvider fResourceProvider;
195
Greg Daniele5ddff52017-07-05 16:49:36 -0400196 typedef GrGpu INHERITED;
197};
198
199#endif
200