Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2020 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 | |
Robert Phillips | 769b488 | 2021-09-07 16:48:46 -0400 | [diff] [blame] | 8 | #include "src/gpu/ops/DrawAtlasPathOp.h" |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 9 | |
Brian Salomon | 4895946 | 2021-08-11 13:01:06 -0400 | [diff] [blame] | 10 | #include "src/gpu/GrGeometryProcessor.h" |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 11 | #include "src/gpu/GrOpFlushState.h" |
| 12 | #include "src/gpu/GrOpsRenderPass.h" |
| 13 | #include "src/gpu/GrProgramInfo.h" |
Robert Phillips | 1a82a4e | 2021-07-01 10:27:44 -0400 | [diff] [blame] | 14 | #include "src/gpu/GrResourceProvider.h" |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 15 | #include "src/gpu/GrVertexWriter.h" |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 16 | #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 17 | #include "src/gpu/glsl/GrGLSLVarying.h" |
| 18 | #include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h" |
| 19 | |
| 20 | namespace { |
| 21 | |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 22 | class DrawAtlasPathShader : public GrGeometryProcessor { |
| 23 | public: |
Brian Salomon | bab2d11 | 2021-08-11 09:59:56 -0400 | [diff] [blame] | 24 | DrawAtlasPathShader(bool usesLocalCoords, |
Robert Phillips | ef80d7b | 2021-09-14 16:10:56 -0400 | [diff] [blame] | 25 | const skgpu::v1::AtlasInstancedHelper* atlasHelper, |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 26 | const GrShaderCaps& shaderCaps) |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 27 | : GrGeometryProcessor(kDrawAtlasPathShader_ClassID) |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 28 | , fUsesLocalCoords(usesLocalCoords) |
| 29 | , fAtlasHelper(atlasHelper) |
Brian Salomon | bab2d11 | 2021-08-11 09:59:56 -0400 | [diff] [blame] | 30 | , fAtlasAccess(GrSamplerState::Filter::kNearest, |
| 31 | fAtlasHelper->proxy()->backendFormat(), |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 32 | fAtlasHelper->atlasSwizzle()) { |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 33 | if (!shaderCaps.vertexIDSupport()) { |
Brian Salomon | bab2d11 | 2021-08-11 09:59:56 -0400 | [diff] [blame] | 34 | constexpr static Attribute kUnitCoordAttrib( |
| 35 | "unitCoord", kFloat2_GrVertexAttribType, kFloat2_GrSLType); |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 36 | this->setVertexAttributes(&kUnitCoordAttrib, 1); |
| 37 | } |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 38 | fAttribs.emplace_back("fillBounds", kFloat4_GrVertexAttribType, kFloat4_GrSLType); |
| 39 | if (fUsesLocalCoords) { |
| 40 | fAttribs.emplace_back("affineMatrix", kFloat4_GrVertexAttribType, kFloat4_GrSLType); |
| 41 | fAttribs.emplace_back("translate", kFloat2_GrVertexAttribType, kFloat2_GrSLType); |
| 42 | } |
| 43 | SkASSERT(fAttribs.count() == this->colorAttribIdx()); |
| 44 | fAttribs.emplace_back("color", kFloat4_GrVertexAttribType, kHalf4_GrSLType); |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 45 | fAtlasHelper->appendInstanceAttribs(&fAttribs); |
| 46 | SkASSERT(fAttribs.count() <= kMaxInstanceAttribs); |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 47 | this->setInstanceAttributes(fAttribs.data(), fAttribs.count()); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 48 | this->setTextureSamplerCnt(1); |
| 49 | } |
| 50 | |
| 51 | private: |
Brian Salomon | bab2d11 | 2021-08-11 09:59:56 -0400 | [diff] [blame] | 52 | class Impl; |
| 53 | |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 54 | int colorAttribIdx() const { return fUsesLocalCoords ? 3 : 1; } |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 55 | const char* name() const override { return "DrawAtlasPathShader"; } |
Brian Salomon | 13b2873 | 2021-08-06 15:33:58 -0400 | [diff] [blame] | 56 | void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override { |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 57 | b->addBits(1, fUsesLocalCoords, "localCoords"); |
| 58 | fAtlasHelper->getKeyBits(b); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 59 | } |
| 60 | const TextureSampler& onTextureSampler(int) const override { return fAtlasAccess; } |
Brian Salomon | f95940b | 2021-08-09 15:56:24 -0400 | [diff] [blame] | 61 | std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override; |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 62 | |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 63 | const bool fUsesLocalCoords; |
Robert Phillips | ef80d7b | 2021-09-14 16:10:56 -0400 | [diff] [blame] | 64 | const skgpu::v1::AtlasInstancedHelper* const fAtlasHelper; |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 65 | TextureSampler fAtlasAccess; |
| 66 | constexpr static int kMaxInstanceAttribs = 6; |
| 67 | SkSTArray<kMaxInstanceAttribs, GrGeometryProcessor::Attribute> fAttribs; |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 68 | }; |
| 69 | |
Brian Salomon | f95940b | 2021-08-09 15:56:24 -0400 | [diff] [blame] | 70 | class DrawAtlasPathShader::Impl : public ProgramImpl { |
Brian Salomon | bab2d11 | 2021-08-11 09:59:56 -0400 | [diff] [blame] | 71 | public: |
| 72 | void setData(const GrGLSLProgramDataManager& pdman, |
| 73 | const GrShaderCaps&, |
| 74 | const GrGeometryProcessor& geomProc) override { |
| 75 | auto* atlasHelper = geomProc.cast<DrawAtlasPathShader>().fAtlasHelper; |
| 76 | atlasHelper->setUniformData(pdman, fAtlasAdjustUniform); |
| 77 | } |
| 78 | |
| 79 | private: |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 80 | void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { |
Robert Phillips | 787fd9d | 2021-03-22 14:48:09 -0400 | [diff] [blame] | 81 | const auto& shader = args.fGeomProc.cast<DrawAtlasPathShader>(); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 82 | args.fVaryingHandler->emitAttributes(shader); |
| 83 | |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 84 | if (args.fShaderCaps->vertexIDSupport()) { |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 85 | // If we don't have sk_VertexID support then "unitCoord" already came in as a vertex |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 86 | // attrib. |
| 87 | args.fVertBuilder->codeAppendf(R"( |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 88 | float2 unitCoord = float2(sk_VertexID & 1, sk_VertexID >> 1);)"); |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 89 | } |
| 90 | |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 91 | args.fVertBuilder->codeAppendf(R"( |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 92 | float2 devCoord = mix(fillBounds.xy, fillBounds.zw, unitCoord);)"); |
| 93 | gpArgs->fPositionVar.set(kFloat2_GrSLType, "devCoord"); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 94 | |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 95 | if (shader.fUsesLocalCoords) { |
| 96 | args.fVertBuilder->codeAppendf(R"( |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 97 | float2x2 M = float2x2(affineMatrix); |
| 98 | float2 localCoord = inverse(M) * (devCoord - translate);)"); |
| 99 | gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localCoord"); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 100 | } |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 101 | |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 102 | args.fFragBuilder->codeAppendf("half4 %s = half4(1);", args.fOutputCoverage); |
| 103 | shader.fAtlasHelper->injectShaderCode(args, gpArgs->fPositionVar, &fAtlasAdjustUniform); |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 104 | |
| 105 | args.fFragBuilder->codeAppendf("half4 %s;", args.fOutputColor); |
| 106 | args.fVaryingHandler->addPassThroughAttribute( |
Brian Salomon | 4895946 | 2021-08-11 13:01:06 -0400 | [diff] [blame] | 107 | shader.fAttribs[shader.colorAttribIdx()].asShaderVar(), |
| 108 | args.fOutputColor, |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 109 | GrGLSLVaryingHandler::Interpolation::kCanBeFlat); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 110 | } |
| 111 | |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 112 | GrGLSLUniformHandler::UniformHandle fAtlasAdjustUniform; |
| 113 | }; |
| 114 | |
Brian Salomon | f95940b | 2021-08-09 15:56:24 -0400 | [diff] [blame] | 115 | std::unique_ptr<GrGeometryProcessor::ProgramImpl> DrawAtlasPathShader::makeProgramImpl( |
| 116 | const GrShaderCaps&) const { |
| 117 | return std::make_unique<Impl>(); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 118 | } |
| 119 | |
Robert Phillips | 769b488 | 2021-09-07 16:48:46 -0400 | [diff] [blame] | 120 | } // anonymous namespace |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 121 | |
Robert Phillips | 769b488 | 2021-09-07 16:48:46 -0400 | [diff] [blame] | 122 | namespace skgpu::v1 { |
| 123 | |
| 124 | GrProcessorSet::Analysis DrawAtlasPathOp::finalize(const GrCaps& caps, const GrAppliedClip* clip, |
| 125 | GrClampType clampType) { |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 126 | const GrProcessorSet::Analysis& analysis = fProcessors.finalize( |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 127 | fHeadInstance->fColor, GrProcessorAnalysisCoverage::kSingleChannel, clip, |
| 128 | &GrUserStencilSettings::kUnused, caps, clampType, &fHeadInstance->fColor); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 129 | fUsesLocalCoords = analysis.usesLocalCoords(); |
| 130 | return analysis; |
| 131 | } |
| 132 | |
Robert Phillips | 769b488 | 2021-09-07 16:48:46 -0400 | [diff] [blame] | 133 | GrOp::CombineResult DrawAtlasPathOp::onCombineIfPossible(GrOp* op, SkArenaAlloc*, const GrCaps&) { |
| 134 | auto that = op->cast<DrawAtlasPathOp>(); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 135 | |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 136 | if (!fAtlasHelper.isCompatible(that->fAtlasHelper) || |
| 137 | fProcessors != that->fProcessors) { |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 138 | return CombineResult::kCannotCombine; |
| 139 | } |
| 140 | |
| 141 | SkASSERT(fUsesLocalCoords == that->fUsesLocalCoords); |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 142 | *fTailInstance = that->fHeadInstance; |
| 143 | fTailInstance = that->fTailInstance; |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 144 | fInstanceCount += that->fInstanceCount; |
| 145 | return CombineResult::kMerged; |
| 146 | } |
| 147 | |
Robert Phillips | 769b488 | 2021-09-07 16:48:46 -0400 | [diff] [blame] | 148 | void DrawAtlasPathOp::prepareProgram(const GrCaps& caps, SkArenaAlloc* arena, |
| 149 | const GrSurfaceProxyView& writeView, bool usesMSAASurface, |
| 150 | GrAppliedClip&& appliedClip, |
| 151 | const GrDstProxyView& dstProxyView, |
| 152 | GrXferBarrierFlags renderPassXferBarriers, |
| 153 | GrLoadOp colorLoadOp) { |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 154 | SkASSERT(!fProgram); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 155 | GrPipeline::InitArgs initArgs; |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 156 | initArgs.fCaps = ∩︀ |
| 157 | initArgs.fDstProxyView = dstProxyView; |
| 158 | initArgs.fWriteSwizzle = writeView.swizzle(); |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 159 | auto pipeline = arena->make<GrPipeline>(initArgs, std::move(fProcessors), |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 160 | std::move(appliedClip)); |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 161 | auto shader = arena->make<DrawAtlasPathShader>(fUsesLocalCoords, &fAtlasHelper, |
| 162 | *caps.shaderCaps()); |
Chris Dalton | 2a26c50 | 2021-08-26 10:05:11 -0600 | [diff] [blame] | 163 | fProgram = arena->make<GrProgramInfo>(caps, writeView, usesMSAASurface, pipeline, |
| 164 | &GrUserStencilSettings::kUnused, shader, |
| 165 | GrPrimitiveType::kTriangleStrip, 0, |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 166 | renderPassXferBarriers, colorLoadOp); |
| 167 | } |
Chris Dalton | 012f849 | 2020-03-05 11:49:15 -0700 | [diff] [blame] | 168 | |
Robert Phillips | 769b488 | 2021-09-07 16:48:46 -0400 | [diff] [blame] | 169 | void DrawAtlasPathOp::onPrePrepare(GrRecordingContext* rContext, |
| 170 | const GrSurfaceProxyView& writeView, |
| 171 | GrAppliedClip* appliedClip, const GrDstProxyView& dstProxyView, |
| 172 | GrXferBarrierFlags renderPassXferBarriers, |
| 173 | GrLoadOp colorLoadOp) { |
Chris Dalton | 2a26c50 | 2021-08-26 10:05:11 -0600 | [diff] [blame] | 174 | // DMSAA is not supported on DDL. |
| 175 | bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1; |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 176 | this->prepareProgram(*rContext->priv().caps(), rContext->priv().recordTimeAllocator(), |
Chris Dalton | 2a26c50 | 2021-08-26 10:05:11 -0600 | [diff] [blame] | 177 | writeView, usesMSAASurface, std::move(*appliedClip), dstProxyView, |
| 178 | renderPassXferBarriers, colorLoadOp); |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 179 | SkASSERT(fProgram); |
| 180 | rContext->priv().recordProgramInfo(fProgram); |
| 181 | } |
| 182 | |
| 183 | GR_DECLARE_STATIC_UNIQUE_KEY(gUnitQuadBufferKey); |
| 184 | |
Robert Phillips | 769b488 | 2021-09-07 16:48:46 -0400 | [diff] [blame] | 185 | void DrawAtlasPathOp::onPrepare(GrOpFlushState* flushState) { |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 186 | if (!fProgram) { |
| 187 | this->prepareProgram(flushState->caps(), flushState->allocator(), flushState->writeView(), |
Chris Dalton | cc29a39 | 2021-07-12 15:16:29 -0600 | [diff] [blame] | 188 | flushState->usesMSAASurface(), flushState->detachAppliedClip(), |
| 189 | flushState->dstProxyView(), flushState->renderPassBarriers(), |
| 190 | flushState->colorLoadOp()); |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 191 | SkASSERT(fProgram); |
| 192 | } |
| 193 | |
| 194 | if (GrVertexWriter instanceWriter = flushState->makeVertexSpace( |
| 195 | fProgram->geomProc().instanceStride(), fInstanceCount, &fInstanceBuffer, |
| 196 | &fBaseInstance)) { |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 197 | for (const Instance* i = fHeadInstance; i; i = i->fNext) { |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 198 | instanceWriter.write( |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 199 | SkRect::Make(i->fFillBounds), |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 200 | GrVertexWriter::If(fUsesLocalCoords, |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 201 | i->fLocalToDeviceIfUsingLocalCoords), |
| 202 | i->fColor); |
| 203 | fAtlasHelper.writeInstanceData(&instanceWriter, &i->fAtlasInstance); |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 204 | } |
| 205 | } |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 206 | |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 207 | if (!flushState->caps().shaderCaps()->vertexIDSupport()) { |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 208 | constexpr static SkPoint kUnitQuad[4] = {{0,0}, {0,1}, {1,0}, {1,1}}; |
| 209 | |
| 210 | GR_DEFINE_STATIC_UNIQUE_KEY(gUnitQuadBufferKey); |
| 211 | |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 212 | fVertexBufferIfNoIDSupport = flushState->resourceProvider()->findOrMakeStaticBuffer( |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 213 | GrGpuBufferType::kVertex, sizeof(kUnitQuad), kUnitQuad, gUnitQuadBufferKey); |
| 214 | } |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 215 | } |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 216 | |
Robert Phillips | 769b488 | 2021-09-07 16:48:46 -0400 | [diff] [blame] | 217 | void DrawAtlasPathOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 218 | flushState->bindPipelineAndScissorClip(*fProgram, this->bounds()); |
Chris Dalton | b1fd64e | 2021-07-08 15:38:51 -0600 | [diff] [blame] | 219 | flushState->bindTextures(fProgram->geomProc(), *fAtlasHelper.proxy(), fProgram->pipeline()); |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 220 | flushState->bindBuffers(nullptr, std::move(fInstanceBuffer), fVertexBufferIfNoIDSupport); |
| 221 | flushState->drawInstanced(fInstanceCount, fBaseInstance, 4, 0); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 222 | } |
Robert Phillips | 769b488 | 2021-09-07 16:48:46 -0400 | [diff] [blame] | 223 | |
| 224 | } // namespace skgpu::v1 |