blob: 88468afc9f2df4572c41e65066324f9ef988b586 [file] [log] [blame]
egdaniel9cb63402016-06-23 08:37:05 -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#include "src/gpu/GrOpsRenderPass.h"
egdaniel9cb63402016-06-23 08:37:05 -07009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkRect.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/gpu/GrCaps.h"
Michael Ludwig1e632792020-05-21 12:45:31 -040012#include "src/gpu/GrCpuBuffer.h"
Chris Daltona6a3d052021-02-07 20:56:36 -070013#include "src/gpu/GrDrawIndirectCommand.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/GrGpu.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/gpu/GrPrimitiveProcessor.h"
Robert Phillips901aff02019-10-08 12:32:56 -040016#include "src/gpu/GrProgramInfo.h"
Brian Salomon201cdbb2019-08-14 17:00:30 -040017#include "src/gpu/GrRenderTarget.h"
Michael Ludwig1e632792020-05-21 12:45:31 -040018#include "src/gpu/GrScissorState.h"
Chris Daltoneb694b72020-03-16 09:25:50 -060019#include "src/gpu/GrSimpleMesh.h"
Brian Salomon4cfae3b2020-07-23 10:33:24 -040020#include "src/gpu/GrTexture.h"
egdaniel9cb63402016-06-23 08:37:05 -070021
Chris Dalton2c3e1692020-03-20 12:32:55 -060022void GrOpsRenderPass::begin() {
23 fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
24#ifdef SK_DEBUG
25 fScissorStatus = DynamicStateStatus::kDisabled;
26 fTextureBindingStatus = DynamicStateStatus::kDisabled;
27 fHasIndexBuffer = false;
28 fInstanceBufferStatus = DynamicStateStatus::kDisabled;
29 fVertexBufferStatus = DynamicStateStatus::kDisabled;
30#endif
31 this->onBegin();
32}
33
34void GrOpsRenderPass::end() {
35 this->onEnd();
Chris Daltonb60c8a22020-03-31 17:24:22 -060036 this->resetActiveBuffers();
Chris Dalton2c3e1692020-03-20 12:32:55 -060037}
38
Brian Salomon07bc9a22020-12-02 13:37:16 -050039void GrOpsRenderPass::clear(const GrScissorState& scissor, std::array<float, 4> color) {
Robert Phillips4912d902018-04-27 12:09:35 -040040 SkASSERT(fRenderTarget);
Michael Ludwigc39d0c82019-01-15 10:03:43 -050041 // A clear at this level will always be a true clear, so make sure clears were not supposed to
42 // be redirected to draws instead
43 SkASSERT(!this->gpu()->caps()->performColorClearsAsDraws());
Michael Ludwig1e632792020-05-21 12:45:31 -040044 SkASSERT(!scissor.enabled() || !this->gpu()->caps()->performPartialClearsAsDraws());
Chris Dalton4386ad12020-02-19 16:42:06 -070045 fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
Michael Ludwig1e632792020-05-21 12:45:31 -040046 this->onClear(scissor, color);
egdaniel9cb63402016-06-23 08:37:05 -070047}
48
Michael Ludwig1e632792020-05-21 12:45:31 -040049void GrOpsRenderPass::clearStencilClip(const GrScissorState& scissor, bool insideStencilMask) {
Michael Ludwigc39d0c82019-01-15 10:03:43 -050050 // As above, make sure the stencil clear wasn't supposed to be a draw rect with stencil settings
51 SkASSERT(!this->gpu()->caps()->performStencilClearsAsDraws());
Michael Ludwig1e632792020-05-21 12:45:31 -040052 SkASSERT(!scissor.enabled() || !this->gpu()->caps()->performPartialClearsAsDraws());
Chris Dalton4386ad12020-02-19 16:42:06 -070053 fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
Michael Ludwig1e632792020-05-21 12:45:31 -040054 this->onClearStencilClip(scissor, insideStencilMask);
egdaniel9cb63402016-06-23 08:37:05 -070055}
56
Chris Dalton4386ad12020-02-19 16:42:06 -070057void GrOpsRenderPass::executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable) {
58 fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
59 this->onExecuteDrawable(std::move(drawable));
60}
Robert Phillips901aff02019-10-08 12:32:56 -040061
Chris Daltonaa0e45c2020-03-16 10:05:11 -060062void GrOpsRenderPass::bindPipeline(const GrProgramInfo& programInfo, const SkRect& drawBounds) {
Chris Daltonbca46e22017-05-15 11:03:26 -060063#ifdef SK_DEBUG
Chris Dalton56c09f02020-03-13 17:30:03 -060064 // Both the 'programInfo' and this renderPass have an origin. Since they come from the same
65 // place (i.e., the target renderTargetProxy) they had best agree.
66 SkASSERT(programInfo.origin() == fOrigin);
Chris Dalton4386ad12020-02-19 16:42:06 -070067 if (programInfo.primProc().hasInstanceAttributes()) {
Chris Daltona77cdee2020-04-03 14:50:43 -060068 SkASSERT(this->gpu()->caps()->drawInstancedSupport());
Chris Dalton4386ad12020-02-19 16:42:06 -070069 }
70 if (programInfo.pipeline().usesConservativeRaster()) {
71 SkASSERT(this->gpu()->caps()->conservativeRasterSupport());
Chris Dalton4386ad12020-02-19 16:42:06 -070072 }
73 if (programInfo.pipeline().isWireframe()) {
74 SkASSERT(this->gpu()->caps()->wireframeSupport());
75 }
Chris Dalton3d28b6a2020-04-13 11:12:28 -060076 if (this->gpu()->caps()->twoSidedStencilRefsAndMasksMustMatch() &&
Chris Dalton1b6a43c2020-09-25 12:21:18 -060077 programInfo.isStencilEnabled()) {
78 const GrUserStencilSettings* stencil = programInfo.userStencilSettings();
Chris Dalton3d28b6a2020-04-13 11:12:28 -060079 if (stencil->isTwoSided(programInfo.pipeline().hasStencilClip())) {
80 SkASSERT(stencil->fCCWFace.fRef == stencil->fCWFace.fRef);
81 SkASSERT(stencil->fCCWFace.fTestMask == stencil->fCWFace.fTestMask);
82 SkASSERT(stencil->fCCWFace.fWriteMask == stencil->fCWFace.fWriteMask);
83 }
84 }
Chris Dalton4386ad12020-02-19 16:42:06 -070085 if (GrPrimitiveType::kPatches == programInfo.primitiveType()) {
86 SkASSERT(this->gpu()->caps()->shaderCaps()->tessellationSupport());
87 }
Robert Phillips2d8a95e2019-10-10 12:50:22 -040088 programInfo.checkAllInstantiated();
89 programInfo.checkMSAAAndMIPSAreResolved();
Robert Phillips12c46292019-04-23 07:36:17 -040090#endif
Robert Phillipsa91e0b72017-05-01 13:12:20 -040091
Chris Daltonb60c8a22020-03-31 17:24:22 -060092 this->resetActiveBuffers();
93
Robert Phillips901aff02019-10-08 12:32:56 -040094 if (programInfo.primProc().numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
Chris Dalton4386ad12020-02-19 16:42:06 -070095 fDrawPipelineStatus = DrawPipelineStatus::kFailedToBind;
96 return;
egdaniel9cb63402016-06-23 08:37:05 -070097 }
Chris Dalton4386ad12020-02-19 16:42:06 -070098
99 if (!this->onBindPipeline(programInfo, drawBounds)) {
100 fDrawPipelineStatus = DrawPipelineStatus::kFailedToBind;
101 return;
102 }
Robert Phillips901aff02019-10-08 12:32:56 -0400103
Chris Dalton8c4cafd2019-04-15 19:14:36 -0600104#ifdef SK_DEBUG
Robert Phillips901aff02019-10-08 12:32:56 -0400105 GrProcessor::CustomFeatures processorFeatures = programInfo.requestedFeatures();
Chris Dalton8c4cafd2019-04-15 19:14:36 -0600106 if (GrProcessor::CustomFeatures::kSampleLocations & processorFeatures) {
107 // Verify we always have the same sample pattern key, regardless of graphics state.
Brian Salomonf7f54332020-07-28 09:23:35 -0400108 SkASSERT(this->gpu()->findOrAssignSamplePatternKey(fRenderTarget) ==
109 fRenderTarget->getSamplePatternKey());
Chris Dalton8c4cafd2019-04-15 19:14:36 -0600110 }
Chris Dalton2e7ed262020-02-21 15:17:59 -0700111 fScissorStatus = (programInfo.pipeline().isScissorTestEnabled()) ?
112 DynamicStateStatus::kUninitialized : DynamicStateStatus::kDisabled;
113 bool hasTextures = (programInfo.primProc().numTextureSamplers() > 0);
114 if (!hasTextures) {
Brian Salomon7e67dca2020-07-21 09:27:25 -0400115 programInfo.pipeline().visitProxies([&hasTextures](GrSurfaceProxy*, GrMipmapped) {
Chris Dalton2e7ed262020-02-21 15:17:59 -0700116 hasTextures = true;
117 });
118 }
119 fTextureBindingStatus = (hasTextures) ?
120 DynamicStateStatus::kUninitialized : DynamicStateStatus::kDisabled;
Chris Daltonded43702020-03-02 11:45:27 -0700121 fHasIndexBuffer = false;
122 fInstanceBufferStatus = (programInfo.primProc().hasInstanceAttributes()) ?
123 DynamicStateStatus::kUninitialized : DynamicStateStatus::kDisabled;
124 fVertexBufferStatus = (programInfo.primProc().hasVertexAttributes()) ?
125 DynamicStateStatus::kUninitialized : DynamicStateStatus::kDisabled;
Chris Dalton8c4cafd2019-04-15 19:14:36 -0600126#endif
Chris Dalton4386ad12020-02-19 16:42:06 -0700127
128 fDrawPipelineStatus = DrawPipelineStatus::kOk;
Greg Danield358cbe2020-09-11 09:33:54 -0400129 fXferBarrierType = programInfo.pipeline().xferBarrierType(*this->gpu()->caps());
Chris Dalton2e7ed262020-02-21 15:17:59 -0700130}
131
132void GrOpsRenderPass::setScissorRect(const SkIRect& scissor) {
133 if (DrawPipelineStatus::kOk != fDrawPipelineStatus) {
134 SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
135 return;
136 }
137 SkASSERT(DynamicStateStatus::kDisabled != fScissorStatus);
138 this->onSetScissorRect(scissor);
139 SkDEBUGCODE(fScissorStatus = DynamicStateStatus::kConfigured);
140}
141
Chris Daltondb20afc2020-03-05 12:13:53 -0700142void GrOpsRenderPass::bindTextures(const GrPrimitiveProcessor& primProc,
143 const GrSurfaceProxy* const primProcTextures[],
144 const GrPipeline& pipeline) {
Chris Dalton1b1b0d52020-03-03 12:00:59 -0700145#ifdef SK_DEBUG
146 SkASSERT((primProc.numTextureSamplers() > 0) == SkToBool(primProcTextures));
147 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
Chris Dalton3bf2f3a2020-03-17 11:48:23 -0600148 const auto& sampler = primProc.textureSampler(i);
149 const GrSurfaceProxy* proxy = primProcTextures[i];
150 SkASSERT(proxy);
151 SkASSERT(proxy->backendFormat() == sampler.backendFormat());
152 SkASSERT(proxy->backendFormat().textureType() == sampler.backendFormat().textureType());
153
154 const GrTexture* tex = proxy->peekTexture();
155 SkASSERT(tex);
Brian Salomone69b9ef2020-07-22 11:18:06 -0400156 if (sampler.samplerState().mipmapped() == GrMipmapped::kYes &&
Chris Dalton3bf2f3a2020-03-17 11:48:23 -0600157 (tex->width() != 1 || tex->height() != 1)) {
158 // There are some cases where we might be given a non-mipmapped texture with a mipmap
159 // filter. See skbug.com/7094.
Brian Salomon4cfae3b2020-07-23 10:33:24 -0400160 SkASSERT(tex->mipmapped() != GrMipmapped::kYes || !tex->mipmapsAreDirty());
Chris Dalton3bf2f3a2020-03-17 11:48:23 -0600161 }
Chris Dalton1b1b0d52020-03-03 12:00:59 -0700162 }
163#endif
164
Chris Dalton2e7ed262020-02-21 15:17:59 -0700165 if (DrawPipelineStatus::kOk != fDrawPipelineStatus) {
166 SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
167 return;
168 }
Chris Dalton1b1b0d52020-03-03 12:00:59 -0700169
Chris Dalton2e7ed262020-02-21 15:17:59 -0700170 // Don't assert on fTextureBindingStatus. onBindTextures() just turns into a no-op when there
171 // aren't any textures, and it's hard to tell from the GrPipeline whether there are any. For
172 // many clients it is easier to just always call this method.
Chris Daltondb20afc2020-03-05 12:13:53 -0700173 if (!this->onBindTextures(primProc, primProcTextures, pipeline)) {
Chris Dalton2e7ed262020-02-21 15:17:59 -0700174 fDrawPipelineStatus = DrawPipelineStatus::kFailedToBind;
175 return;
176 }
Chris Dalton1b1b0d52020-03-03 12:00:59 -0700177
Chris Dalton2e7ed262020-02-21 15:17:59 -0700178 SkDEBUGCODE(fTextureBindingStatus = DynamicStateStatus::kConfigured);
Chris Dalton4386ad12020-02-19 16:42:06 -0700179}
180
Greg Daniel426274b2020-07-20 11:37:38 -0400181void GrOpsRenderPass::bindBuffers(sk_sp<const GrBuffer> indexBuffer,
182 sk_sp<const GrBuffer> instanceBuffer,
183 sk_sp<const GrBuffer> vertexBuffer,
184 GrPrimitiveRestart primRestart) {
Chris Daltonded43702020-03-02 11:45:27 -0700185 if (DrawPipelineStatus::kOk != fDrawPipelineStatus) {
186 SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
187 return;
188 }
189
190#ifdef SK_DEBUG
191 if (indexBuffer) {
192 fHasIndexBuffer = true;
193 }
194
195 SkASSERT((DynamicStateStatus::kDisabled == fInstanceBufferStatus) != SkToBool(instanceBuffer));
196 if (instanceBuffer) {
197 fInstanceBufferStatus = DynamicStateStatus::kConfigured;
198 }
199
200 SkASSERT((DynamicStateStatus::kDisabled == fVertexBufferStatus) != SkToBool(vertexBuffer));
201 if (vertexBuffer) {
202 fVertexBufferStatus = DynamicStateStatus::kConfigured;
203 }
204
205 if (GrPrimitiveRestart::kYes == primRestart) {
206 SkASSERT(this->gpu()->caps()->usePrimitiveRestart());
207 }
208#endif
209
Greg Daniel426274b2020-07-20 11:37:38 -0400210 this->onBindBuffers(std::move(indexBuffer), std::move(instanceBuffer), std::move(vertexBuffer),
211 primRestart);
Chris Daltonded43702020-03-02 11:45:27 -0700212}
213
Chris Dalton33db9fc2020-02-25 18:52:12 -0700214bool GrOpsRenderPass::prepareToDraw() {
Chris Dalton4386ad12020-02-19 16:42:06 -0700215 if (DrawPipelineStatus::kOk != fDrawPipelineStatus) {
216 SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
217 this->gpu()->stats()->incNumFailedDraws();
Chris Dalton33db9fc2020-02-25 18:52:12 -0700218 return false;
Chris Dalton4386ad12020-02-19 16:42:06 -0700219 }
Chris Dalton2e7ed262020-02-21 15:17:59 -0700220 SkASSERT(DynamicStateStatus::kUninitialized != fScissorStatus);
221 SkASSERT(DynamicStateStatus::kUninitialized != fTextureBindingStatus);
Chris Dalton4386ad12020-02-19 16:42:06 -0700222
Chris Dalton2e7ed262020-02-21 15:17:59 -0700223 if (kNone_GrXferBarrierType != fXferBarrierType) {
224 this->gpu()->xferBarrier(fRenderTarget, fXferBarrierType);
Chris Dalton4386ad12020-02-19 16:42:06 -0700225 }
Chris Dalton33db9fc2020-02-25 18:52:12 -0700226 return true;
227}
228
Chris Daltonded43702020-03-02 11:45:27 -0700229void GrOpsRenderPass::draw(int vertexCount, int baseVertex) {
Chris Dalton33db9fc2020-02-25 18:52:12 -0700230 if (!this->prepareToDraw()) {
231 return;
232 }
Chris Daltonded43702020-03-02 11:45:27 -0700233 SkASSERT(!fHasIndexBuffer);
234 SkASSERT(DynamicStateStatus::kConfigured != fInstanceBufferStatus);
235 SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
236 this->onDraw(vertexCount, baseVertex);
Chris Dalton33db9fc2020-02-25 18:52:12 -0700237}
238
Chris Daltonded43702020-03-02 11:45:27 -0700239void GrOpsRenderPass::drawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
240 uint16_t maxIndexValue, int baseVertex) {
Chris Dalton33db9fc2020-02-25 18:52:12 -0700241 if (!this->prepareToDraw()) {
242 return;
243 }
Chris Daltonded43702020-03-02 11:45:27 -0700244 SkASSERT(fHasIndexBuffer);
245 SkASSERT(DynamicStateStatus::kConfigured != fInstanceBufferStatus);
246 SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
247 this->onDrawIndexed(indexCount, baseIndex, minIndexValue, maxIndexValue, baseVertex);
Chris Dalton33db9fc2020-02-25 18:52:12 -0700248}
249
Chris Daltonded43702020-03-02 11:45:27 -0700250void GrOpsRenderPass::drawInstanced(int instanceCount, int baseInstance, int vertexCount,
Chris Dalton33db9fc2020-02-25 18:52:12 -0700251 int baseVertex) {
Chris Daltona77cdee2020-04-03 14:50:43 -0600252 SkASSERT(this->gpu()->caps()->drawInstancedSupport());
Chris Dalton33db9fc2020-02-25 18:52:12 -0700253 if (!this->prepareToDraw()) {
254 return;
255 }
Chris Daltonded43702020-03-02 11:45:27 -0700256 SkASSERT(!fHasIndexBuffer);
257 SkASSERT(DynamicStateStatus::kUninitialized != fInstanceBufferStatus);
258 SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
259 this->onDrawInstanced(instanceCount, baseInstance, vertexCount, baseVertex);
Chris Dalton33db9fc2020-02-25 18:52:12 -0700260}
261
Chris Daltonded43702020-03-02 11:45:27 -0700262void GrOpsRenderPass::drawIndexedInstanced(int indexCount, int baseIndex, int instanceCount,
263 int baseInstance, int baseVertex) {
Chris Daltona77cdee2020-04-03 14:50:43 -0600264 SkASSERT(this->gpu()->caps()->drawInstancedSupport());
Chris Dalton33db9fc2020-02-25 18:52:12 -0700265 if (!this->prepareToDraw()) {
266 return;
267 }
Chris Daltonded43702020-03-02 11:45:27 -0700268 SkASSERT(fHasIndexBuffer);
269 SkASSERT(DynamicStateStatus::kUninitialized != fInstanceBufferStatus);
270 SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
271 this->onDrawIndexedInstanced(indexCount, baseIndex, instanceCount, baseInstance, baseVertex);
egdaniel9cb63402016-06-23 08:37:05 -0700272}
Chris Daltonbb768422020-03-12 12:13:29 -0600273
Chris Dalton03fdf6a2020-04-07 12:31:59 -0600274void GrOpsRenderPass::drawIndirect(const GrBuffer* drawIndirectBuffer, size_t bufferOffset,
275 int drawCount) {
276 SkASSERT(this->gpu()->caps()->drawInstancedSupport());
277 SkASSERT(drawIndirectBuffer->isCpuBuffer() ||
278 !static_cast<const GrGpuBuffer*>(drawIndirectBuffer)->isMapped());
279 if (!this->prepareToDraw()) {
280 return;
281 }
282 SkASSERT(!fHasIndexBuffer);
283 SkASSERT(DynamicStateStatus::kUninitialized != fInstanceBufferStatus);
284 SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
285 if (!this->gpu()->caps()->nativeDrawIndirectSupport()) {
286 // Polyfill indirect draws with looping instanced calls.
287 SkASSERT(drawIndirectBuffer->isCpuBuffer());
Chris Daltona6a3d052021-02-07 20:56:36 -0700288 auto* cpuIndirectBuffer = static_cast<const GrCpuBuffer*>(drawIndirectBuffer);
289 auto* cmds = reinterpret_cast<const GrDrawIndirectCommand*>(
Chris Dalton03fdf6a2020-04-07 12:31:59 -0600290 cpuIndirectBuffer->data() + bufferOffset);
Chris Daltona6a3d052021-02-07 20:56:36 -0700291 for (int i = 0; i < drawCount; ++i) {
292 // TODO: SkASSERT(caps.drawIndirectSignature() == standard);
293 auto [vertexCount, instanceCount, baseVertex, baseInstance] = cmds[i];
294 this->onDrawInstanced(instanceCount, baseInstance, vertexCount, baseVertex);
Chris Dalton03fdf6a2020-04-07 12:31:59 -0600295 }
296 return;
297 }
298 this->onDrawIndirect(drawIndirectBuffer, bufferOffset, drawCount);
299}
300
301void GrOpsRenderPass::drawIndexedIndirect(const GrBuffer* drawIndirectBuffer, size_t bufferOffset,
302 int drawCount) {
303 SkASSERT(this->gpu()->caps()->drawInstancedSupport());
304 SkASSERT(drawIndirectBuffer->isCpuBuffer() ||
305 !static_cast<const GrGpuBuffer*>(drawIndirectBuffer)->isMapped());
306 if (!this->prepareToDraw()) {
307 return;
308 }
309 SkASSERT(fHasIndexBuffer);
310 SkASSERT(DynamicStateStatus::kUninitialized != fInstanceBufferStatus);
311 SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
312 if (!this->gpu()->caps()->nativeDrawIndirectSupport() ||
313 this->gpu()->caps()->nativeDrawIndexedIndirectIsBroken()) {
314 // Polyfill indexedIndirect draws with looping indexedInstanced calls.
315 SkASSERT(drawIndirectBuffer->isCpuBuffer());
Chris Daltona6a3d052021-02-07 20:56:36 -0700316 auto* cpuIndirectBuffer = static_cast<const GrCpuBuffer*>(drawIndirectBuffer);
317 auto* cmds = reinterpret_cast<const GrDrawIndexedIndirectCommand*>(
Chris Dalton03fdf6a2020-04-07 12:31:59 -0600318 cpuIndirectBuffer->data() + bufferOffset);
Chris Daltona6a3d052021-02-07 20:56:36 -0700319 for (int i = 0; i < drawCount; ++i) {
320 // TODO: SkASSERT(caps.drawIndirectSignature() == standard);
321 auto [indexCount, instanceCount, baseIndex, baseVertex, baseInstance] = cmds[i];
322 this->onDrawIndexedInstanced(indexCount, baseIndex, instanceCount, baseInstance,
323 baseVertex);
Chris Dalton03fdf6a2020-04-07 12:31:59 -0600324 }
325 return;
326 }
327 this->onDrawIndexedIndirect(drawIndirectBuffer, bufferOffset, drawCount);
328}
329
Chris Daltonbb768422020-03-12 12:13:29 -0600330void GrOpsRenderPass::drawIndexPattern(int patternIndexCount, int patternRepeatCount,
331 int maxPatternRepetitionsInIndexBuffer,
332 int patternVertexCount, int baseVertex) {
333 int baseRepetition = 0;
334 while (baseRepetition < patternRepeatCount) {
335 int repeatCount = std::min(patternRepeatCount - baseRepetition,
336 maxPatternRepetitionsInIndexBuffer);
337 int drawIndexCount = repeatCount * patternIndexCount;
338 // A patterned index buffer must contain indices in the range [0..vertexCount].
339 int minIndexValue = 0;
340 int maxIndexValue = patternVertexCount * repeatCount - 1;
341 this->drawIndexed(drawIndexCount, 0, minIndexValue, maxIndexValue,
342 patternVertexCount * baseRepetition + baseVertex);
343 baseRepetition += repeatCount;
344 }
345}