blob: 8f478adfd123d47d3ab41e29092cadc8e71d6bb0 [file] [log] [blame]
egdaniel066df7c2016-06-08 14:02:27 -07001/*
2* Copyright 2016 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
Greg Daniel2d41d0d2019-08-26 11:08:51 -04008#ifndef GrOpsRenderPass_DEFINED
9#define GrOpsRenderPass_DEFINED
egdaniel066df7c2016-06-08 14:02:27 -070010
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkDrawable.h"
12#include "src/gpu/GrPipeline.h"
13#include "src/gpu/ops/GrDrawOp.h"
egdaniel066df7c2016-06-08 14:02:27 -070014
Brian Salomon742e31d2016-12-07 17:06:19 -050015class GrOpFlushState;
egdaniel9cb63402016-06-23 08:37:05 -070016class GrGpu;
egdaniel9cb63402016-06-23 08:37:05 -070017class GrPipeline;
18class GrPrimitiveProcessor;
Robert Phillips901aff02019-10-08 12:32:56 -040019class GrProgramInfo;
egdaniel066df7c2016-06-08 14:02:27 -070020class GrRenderTarget;
Michael Ludwig1e632792020-05-21 12:45:31 -040021class GrScissorState;
Greg Daniel64cc9aa2018-10-19 13:54:56 -040022class GrSemaphore;
egdaniel9cb63402016-06-23 08:37:05 -070023struct SkIRect;
Greg Daniel36a77ee2016-10-18 10:33:25 -040024struct SkRect;
egdaniel066df7c2016-06-08 14:02:27 -070025
Greg Daniel2d41d0d2019-08-26 11:08:51 -040026/**
27 * The GrOpsRenderPass is a series of commands (draws, clears, and discards), which all target the
28 * same render target. It is possible that these commands execute immediately (GL), or get buffered
29 * up for later execution (Vulkan). GrOps execute into a GrOpsRenderPass.
30 */
31class GrOpsRenderPass {
Greg Daniel500d58b2017-08-24 15:59:33 -040032public:
Greg Daniel2d41d0d2019-08-26 11:08:51 -040033 virtual ~GrOpsRenderPass() {}
Greg Daniel500d58b2017-08-24 15:59:33 -040034
egdaniel9cb63402016-06-23 08:37:05 -070035 struct LoadAndStoreInfo {
Brian Osman9a9baae2018-11-05 15:06:26 -050036 GrLoadOp fLoadOp;
37 GrStoreOp fStoreOp;
38 SkPMColor4f fClearColor;
egdaniel066df7c2016-06-08 14:02:27 -070039 };
40
Robert Phillips95214472017-08-08 18:00:03 -040041 // Load-time clears of the stencil buffer are always to 0 so we don't store
42 // an 'fStencilClearValue'
43 struct StencilLoadAndStoreInfo {
Robert Phillips6b47c7d2017-08-29 07:24:09 -040044 GrLoadOp fLoadOp;
45 GrStoreOp fStoreOp;
Robert Phillips95214472017-08-08 18:00:03 -040046 };
47
Chris Dalton2c3e1692020-03-20 12:32:55 -060048 void begin();
Greg Daniel2d41d0d2019-08-26 11:08:51 -040049 // Signals the end of recording to the GrOpsRenderPass and that it can now be submitted.
Chris Dalton2c3e1692020-03-20 12:32:55 -060050 void end();
egdaniel066df7c2016-06-08 14:02:27 -070051
Chris Daltonaa0e45c2020-03-16 10:05:11 -060052 // Updates the internal pipeline state for drawing with the provided GrProgramInfo. Enters an
53 // internal "bad" state if the pipeline could not be set.
54 void bindPipeline(const GrProgramInfo&, const SkRect& drawBounds);
Chris Dalton4386ad12020-02-19 16:42:06 -070055
Chris Dalton2e7ed262020-02-21 15:17:59 -070056 // The scissor rect is always dynamic state and therefore not stored on GrPipeline. If scissor
57 // test is enabled on the current pipeline, then the client must call setScissorRect() before
58 // drawing. The scissor rect may also be updated between draws without having to bind a new
59 // pipeline.
60 void setScissorRect(const SkIRect&);
61
Chris Daltondb20afc2020-03-05 12:13:53 -070062 // Binds textures for the primitive processor and any FP on the GrPipeline. Texture bindings are
63 // dynamic state and therefore not set during bindPipeline(). If the current program uses
64 // textures, then the client must call bindTextures() before drawing. The primitive processor
65 // textures may also be updated between draws by calling bindTextures() again with a different
66 // array for primProcTextures. (On subsequent calls, if the backend is capable of updating the
67 // primitive processor textures independently, then it will automatically skip re-binding
68 // FP textures from GrPipeline.)
Chris Daltonded43702020-03-02 11:45:27 -070069 //
70 // If the current program does not use textures, this is a no-op.
Chris Daltondb20afc2020-03-05 12:13:53 -070071 void bindTextures(const GrPrimitiveProcessor&, const GrSurfaceProxy* const primProcTextures[],
72 const GrPipeline&);
Chris Dalton2e7ed262020-02-21 15:17:59 -070073
Greg Daniel426274b2020-07-20 11:37:38 -040074 void bindBuffers(sk_sp<const GrBuffer> indexBuffer, sk_sp<const GrBuffer> instanceBuffer,
75 sk_sp<const GrBuffer> vertexBuffer, GrPrimitiveRestart = GrPrimitiveRestart::kNo);
Chris Daltonded43702020-03-02 11:45:27 -070076
Chris Dalton03fdf6a2020-04-07 12:31:59 -060077 // The next several draw*() methods issue draws using the current pipeline state. Before
78 // drawing, the caller must configure the pipeline and dynamic state:
Chris Daltonded43702020-03-02 11:45:27 -070079 //
80 // - Call bindPipeline()
81 // - If the scissor test is enabled, call setScissorRect()
82 // - If the current program uses textures, call bindTextures()
83 // - Call bindBuffers() (even if all buffers are null)
84 void draw(int vertexCount, int baseVertex);
85 void drawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue,
Chris Dalton33db9fc2020-02-25 18:52:12 -070086 int baseVertex);
Chris Dalton03fdf6a2020-04-07 12:31:59 -060087
88 // Requires caps.drawInstancedSupport().
Chris Daltonded43702020-03-02 11:45:27 -070089 void drawInstanced(int instanceCount, int baseInstance, int vertexCount, int baseVertex);
Chris Dalton03fdf6a2020-04-07 12:31:59 -060090
91 // Requires caps.drawInstancedSupport().
Chris Daltonded43702020-03-02 11:45:27 -070092 void drawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance,
93 int baseVertex);
Chris Dalton2e7ed262020-02-21 15:17:59 -070094
Chris Dalton03fdf6a2020-04-07 12:31:59 -060095 // Executes multiple draws from an array of GrDrawIndirectCommand in the provided buffer.
96 //
97 // Requires caps.drawInstancedSupport().
98 //
99 // If caps.nativeDrawIndirectSupport() is unavailable, then 'drawIndirectBuffer' must be a
100 // GrCpuBuffer in order to polyfill. Performance may suffer in this scenario.
101 void drawIndirect(const GrBuffer* drawIndirectBuffer, size_t bufferOffset, int drawCount);
102
103 // Executes multiple draws from an array of GrDrawIndexedIndirectCommand in the provided buffer.
104 //
105 // Requires caps.drawInstancedSupport().
106 //
107 // If caps.nativeDrawIndirectSupport() is unavailable, then 'drawIndirectBuffer' must be a
108 // GrCpuBuffer in order to polyfill. Performance may suffer in this scenario.
109 void drawIndexedIndirect(const GrBuffer* drawIndirectBuffer, size_t bufferOffset,
110 int drawCount);
111
Chris Daltonbb768422020-03-12 12:13:29 -0600112 // This is a helper method for drawing a repeating pattern of vertices. The bound index buffer
113 // is understood to contain 'maxPatternRepetitionsInIndexBuffer' repetitions of the pattern.
114 // If more repetitions are required, then we loop.
115 void drawIndexPattern(int patternIndexCount, int patternRepeatCount,
116 int maxPatternRepetitionsInIndexBuffer, int patternVertexCount,
117 int baseVertex);
118
Greg Daniel77b53f62016-10-18 11:48:51 -0400119 // Performs an upload of vertex data in the middle of a set of a set of draws
Brian Salomon943ed792017-10-30 09:37:55 -0400120 virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0;
Greg Daniel77b53f62016-10-18 11:48:51 -0400121
egdaniel9cb63402016-06-23 08:37:05 -0700122 /**
Michael Ludwig1e632792020-05-21 12:45:31 -0400123 * Clear the owned render target. Clears the full target if 'scissor' is disabled, otherwise it
124 * is restricted to 'scissor'. Must check caps.performPartialClearsAsDraws() before using an
125 * enabled scissor test; must check caps.performColorClearsAsDraws() before using this at all.
Greg Daniel77b53f62016-10-18 11:48:51 -0400126 */
Michael Ludwig1e632792020-05-21 12:45:31 -0400127 void clear(const GrScissorState& scissor, const SkPMColor4f&);
egdaniel9cb63402016-06-23 08:37:05 -0700128
Michael Ludwig1e632792020-05-21 12:45:31 -0400129 /**
130 * Same as clear() but modifies the stencil; check caps.performStencilClearsAsDraws() and
131 * caps.performPartialClearsAsDraws().
132 */
133 void clearStencilClip(const GrScissorState& scissor, bool insideStencilMask);
Greg Daniel36a77ee2016-10-18 10:33:25 -0400134
egdaniel9cb63402016-06-23 08:37:05 -0700135 /**
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400136 * Executes the SkDrawable object for the underlying backend.
137 */
Chris Dalton4386ad12020-02-19 16:42:06 -0700138 void executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>);
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400139
Robert Phillips19e51dc2017-08-09 09:30:51 -0400140protected:
Greg Daniel2d41d0d2019-08-26 11:08:51 -0400141 GrOpsRenderPass() : fOrigin(kTopLeft_GrSurfaceOrigin), fRenderTarget(nullptr) {}
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400142
Greg Daniel2d41d0d2019-08-26 11:08:51 -0400143 GrOpsRenderPass(GrRenderTarget* rt, GrSurfaceOrigin origin)
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400144 : fOrigin(origin)
Greg Daniel500d58b2017-08-24 15:59:33 -0400145 , fRenderTarget(rt) {
146 }
147
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400148 void set(GrRenderTarget* rt, GrSurfaceOrigin origin) {
149 SkASSERT(!fRenderTarget);
150
151 fRenderTarget = rt;
152 fOrigin = origin;
153 }
154
155 GrSurfaceOrigin fOrigin;
Robert Phillips19e51dc2017-08-09 09:30:51 -0400156 GrRenderTarget* fRenderTarget;
Robert Phillips65a88fa2017-08-08 08:36:22 -0400157
Chris Dalton2c3e1692020-03-20 12:32:55 -0600158 // Backends may defer binding of certain buffers if their draw API requires a buffer, or if
159 // their bind methods don't support base values.
160 sk_sp<const GrBuffer> fActiveIndexBuffer;
161 sk_sp<const GrBuffer> fActiveVertexBuffer;
162 sk_sp<const GrBuffer> fActiveInstanceBuffer;
163
egdaniel9cb63402016-06-23 08:37:05 -0700164private:
165 virtual GrGpu* gpu() = 0;
Greg Daniel65a09272016-10-12 09:47:22 -0400166
Chris Daltonb60c8a22020-03-31 17:24:22 -0600167 void resetActiveBuffers() {
168 fActiveIndexBuffer.reset();
169 fActiveInstanceBuffer.reset();
170 fActiveVertexBuffer.reset();
171 }
172
Chris Dalton33db9fc2020-02-25 18:52:12 -0700173 bool prepareToDraw();
174
Chris Dalton4386ad12020-02-19 16:42:06 -0700175 // overridden by backend-specific derived class to perform the rendering command.
Chris Dalton2c3e1692020-03-20 12:32:55 -0600176 virtual void onBegin() {}
177 virtual void onEnd() {}
Chris Dalton4386ad12020-02-19 16:42:06 -0700178 virtual bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) = 0;
Chris Dalton2e7ed262020-02-21 15:17:59 -0700179 virtual void onSetScissorRect(const SkIRect&) = 0;
Chris Daltondb20afc2020-03-05 12:13:53 -0700180 virtual bool onBindTextures(const GrPrimitiveProcessor&,
181 const GrSurfaceProxy* const primProcTextures[],
182 const GrPipeline&) = 0;
Greg Daniel426274b2020-07-20 11:37:38 -0400183 virtual void onBindBuffers(sk_sp<const GrBuffer> indexBuffer, sk_sp<const GrBuffer> instanceBuffer,
184 sk_sp<const GrBuffer> vertexBuffer, GrPrimitiveRestart) = 0;
Chris Daltonded43702020-03-02 11:45:27 -0700185 virtual void onDraw(int vertexCount, int baseVertex) = 0;
186 virtual void onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
187 uint16_t maxIndexValue, int baseVertex) = 0;
188 virtual void onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
Chris Dalton33db9fc2020-02-25 18:52:12 -0700189 int baseVertex) = 0;
Chris Daltonded43702020-03-02 11:45:27 -0700190 virtual void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount,
191 int baseInstance, int baseVertex) = 0;
Chris Dalton03fdf6a2020-04-07 12:31:59 -0600192 virtual void onDrawIndirect(const GrBuffer*, size_t offset, int drawCount) {
193 SK_ABORT("Not implemented."); // Only called if caps.nativeDrawIndirectSupport().
194 }
195 virtual void onDrawIndexedIndirect(const GrBuffer*, size_t offset, int drawCount) {
196 SK_ABORT("Not implemented."); // Only called if caps.nativeDrawIndirectSupport().
197 }
Michael Ludwig1e632792020-05-21 12:45:31 -0400198 virtual void onClear(const GrScissorState&, const SkPMColor4f&) = 0;
199 virtual void onClearStencilClip(const GrScissorState&, bool insideStencilMask) = 0;
Chris Dalton4386ad12020-02-19 16:42:06 -0700200 virtual void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) {}
201
202 enum class DrawPipelineStatus {
203 kOk = 0,
204 kNotConfigured,
205 kFailedToBind
206 };
207
208 DrawPipelineStatus fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
Chris Dalton2e7ed262020-02-21 15:17:59 -0700209 GrXferBarrierType fXferBarrierType;
210
211#ifdef SK_DEBUG
212 enum class DynamicStateStatus {
213 kDisabled,
214 kUninitialized,
215 kConfigured
216 };
217
Chris Dalton2c3e1692020-03-20 12:32:55 -0600218 DynamicStateStatus fScissorStatus;
219 DynamicStateStatus fTextureBindingStatus;
220 bool fHasIndexBuffer;
221 DynamicStateStatus fInstanceBufferStatus;
222 DynamicStateStatus fVertexBufferStatus;
Chris Dalton2e7ed262020-02-21 15:17:59 -0700223#endif
Greg Daniel500d58b2017-08-24 15:59:33 -0400224
Greg Daniel2d41d0d2019-08-26 11:08:51 -0400225 typedef GrOpsRenderPass INHERITED;
egdaniel066df7c2016-06-08 14:02:27 -0700226};
227
228#endif