• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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 #include "src/gpu/dawn/GrDawnGpuCommandBuffer.h"
9 
10 #include "src/gpu/GrFixedClip.h"
11 #include "src/gpu/GrMesh.h"
12 #include "src/gpu/GrOpFlushState.h"
13 #include "src/gpu/GrPipeline.h"
14 #include "src/gpu/GrRenderTargetPriv.h"
15 #include "src/gpu/GrTexturePriv.h"
16 #include "src/gpu/dawn/GrDawnBuffer.h"
17 #include "src/gpu/dawn/GrDawnGpu.h"
18 #include "src/gpu/dawn/GrDawnProgramBuilder.h"
19 #include "src/gpu/dawn/GrDawnRenderTarget.h"
20 #include "src/gpu/dawn/GrDawnStencilAttachment.h"
21 #include "src/gpu/dawn/GrDawnTexture.h"
22 #include "src/gpu/dawn/GrDawnUtil.h"
23 #include "src/sksl/SkSLCompiler.h"
24 
GrDawnGpuTextureCommandBuffer(GrDawnGpu * gpu,GrTexture * texture,GrSurfaceOrigin origin)25 GrDawnGpuTextureCommandBuffer::GrDawnGpuTextureCommandBuffer(GrDawnGpu* gpu,
26                                                              GrTexture* texture,
27                                                              GrSurfaceOrigin origin)
28     : INHERITED(texture, origin)
29     , fGpu(gpu) {
30     fEncoder = fGpu->device().CreateCommandEncoder();
31 }
32 
copy(GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)33 void GrDawnGpuTextureCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
34                                          const SkIPoint& dstPoint) {
35     if (!src->asTexture()) {
36         return;
37     }
38     uint32_t width = srcRect.width(), height = srcRect.height();
39     size_t rowBytes = srcRect.width() * GrBytesPerPixel(src->config());
40     rowBytes = GrDawnRoundRowBytes(rowBytes);
41     size_t sizeInBytes = height * rowBytes;
42 
43     dawn::BufferDescriptor desc;
44     desc.usage = dawn::BufferUsageBit::CopySrc | dawn::BufferUsageBit::CopyDst;
45     desc.size = sizeInBytes;
46 
47     dawn::Buffer buffer = fGpu->device().CreateBuffer(&desc);
48 
49     dawn::TextureCopyView srcTextureView, dstTextureView;
50     srcTextureView.texture = static_cast<GrDawnTexture*>(src->asTexture())->texture();
51     srcTextureView.origin = {(uint32_t) srcRect.x(), (uint32_t) srcRect.y(), 0};
52     dstTextureView.texture = static_cast<GrDawnTexture*>(fTexture)->texture();
53     dstTextureView.origin = {(uint32_t) dstPoint.x(), (uint32_t) dstPoint.y(), 0};
54 
55     dawn::BufferCopyView bufferView;
56     bufferView.buffer = buffer;
57     bufferView.offset = 0;
58     bufferView.rowPitch = rowBytes;
59     bufferView.imageHeight = height;
60 
61     dawn::Extent3D copySize = {width, height, 1};
62     fEncoder.CopyTextureToBuffer(&srcTextureView, &bufferView, &copySize);
63     fEncoder.CopyBufferToTexture(&bufferView, &dstTextureView, &copySize);
64 }
65 
transferFrom(const SkIRect & srcRect,GrColorType surfaceColorType,GrColorType bufferColorType,GrGpuBuffer * transferBuffer,size_t offset)66 void GrDawnGpuTextureCommandBuffer::transferFrom(const SkIRect& srcRect,
67                                                  GrColorType surfaceColorType,
68                                                  GrColorType bufferColorType,
69                                                  GrGpuBuffer* transferBuffer,
70                                                  size_t offset) {
71     fGpu->transferPixelsFrom(fTexture, srcRect.fLeft, srcRect.fTop, srcRect.width(),
72                              srcRect.height(), surfaceColorType, bufferColorType, transferBuffer,
73                              offset);
74 }
75 
submit()76 void GrDawnGpuTextureCommandBuffer::submit() {
77     dawn::CommandBuffer commandBuffer = fEncoder.Finish();
78     if (commandBuffer) {
79         fGpu->queue().Submit(1, &commandBuffer);
80     }
81 }
82 
~GrDawnGpuTextureCommandBuffer()83 GrDawnGpuTextureCommandBuffer::~GrDawnGpuTextureCommandBuffer() {}
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 
to_dawn_load_op(GrLoadOp loadOp)87 static dawn::LoadOp to_dawn_load_op(GrLoadOp loadOp) {
88     switch (loadOp) {
89         case GrLoadOp::kLoad:
90             return dawn::LoadOp::Load;
91         case GrLoadOp::kDiscard:
92             // Use LoadOp::Load to emulate DontCare.
93             // Dawn doesn't have DontCare, for security reasons.
94             // Load should be equivalent to DontCare for desktop; Clear would
95             // probably be better for tilers. If Dawn does add DontCare
96             // as an extension, use it here.
97             return dawn::LoadOp::Load;
98         case GrLoadOp::kClear:
99             return dawn::LoadOp::Clear;
100         default:
101             SK_ABORT("Invalid LoadOp");
102     }
103 }
104 
GrDawnGpuRTCommandBuffer(GrDawnGpu * gpu,GrRenderTarget * rt,GrSurfaceOrigin origin,const LoadAndStoreInfo & colorInfo,const StencilLoadAndStoreInfo & stencilInfo)105 GrDawnGpuRTCommandBuffer::GrDawnGpuRTCommandBuffer(GrDawnGpu* gpu,
106                                                    GrRenderTarget* rt, GrSurfaceOrigin origin,
107                                                    const LoadAndStoreInfo& colorInfo,
108                                                    const StencilLoadAndStoreInfo& stencilInfo)
109         : INHERITED(rt, origin)
110         , fGpu(gpu)
111         , fColorInfo(colorInfo) {
112     fEncoder = fGpu->device().CreateCommandEncoder();
113     dawn::LoadOp colorOp = to_dawn_load_op(colorInfo.fLoadOp);
114     dawn::LoadOp stencilOp = to_dawn_load_op(stencilInfo.fLoadOp);
115     fPassEncoder = beginRenderPass(colorOp, stencilOp);
116 }
117 
beginRenderPass(dawn::LoadOp colorOp,dawn::LoadOp stencilOp)118 dawn::RenderPassEncoder GrDawnGpuRTCommandBuffer::beginRenderPass(dawn::LoadOp colorOp,
119                                                                   dawn::LoadOp stencilOp) {
120     dawn::Texture texture = static_cast<GrDawnRenderTarget*>(fRenderTarget)->texture();
121     auto stencilAttachment = static_cast<GrDawnStencilAttachment*>(
122         fRenderTarget->renderTargetPriv().getStencilAttachment());
123     dawn::TextureView colorView = texture.CreateDefaultView();
124     const float *c = fColorInfo.fClearColor.vec();
125 
126     dawn::RenderPassColorAttachmentDescriptor colorAttachment;
127     colorAttachment.attachment = colorView;
128     colorAttachment.resolveTarget = nullptr;
129     colorAttachment.clearColor = { c[0], c[1], c[2], c[3] };
130     colorAttachment.loadOp = colorOp;
131     colorAttachment.storeOp = dawn::StoreOp::Store;
132     dawn::RenderPassColorAttachmentDescriptor* colorAttachments = { &colorAttachment };
133     dawn::RenderPassDescriptor renderPassDescriptor;
134     renderPassDescriptor.colorAttachmentCount = 1;
135     renderPassDescriptor.colorAttachments = &colorAttachments;
136     if (stencilAttachment) {
137         dawn::RenderPassDepthStencilAttachmentDescriptor depthStencilAttachment;
138         depthStencilAttachment.attachment = stencilAttachment->view();
139         depthStencilAttachment.depthLoadOp = stencilOp;
140         depthStencilAttachment.stencilLoadOp = stencilOp;
141         depthStencilAttachment.clearDepth = 1.0f;
142         depthStencilAttachment.clearStencil = 0;
143         depthStencilAttachment.depthStoreOp = dawn::StoreOp::Store;
144         depthStencilAttachment.stencilStoreOp = dawn::StoreOp::Store;
145         renderPassDescriptor.depthStencilAttachment = &depthStencilAttachment;
146     } else {
147         renderPassDescriptor.depthStencilAttachment = nullptr;
148     }
149     return fEncoder.BeginRenderPass(&renderPassDescriptor);
150 }
151 
~GrDawnGpuRTCommandBuffer()152 GrDawnGpuRTCommandBuffer::~GrDawnGpuRTCommandBuffer() {
153 }
154 
gpu()155 GrGpu* GrDawnGpuRTCommandBuffer::gpu() { return fGpu; }
156 
end()157 void GrDawnGpuRTCommandBuffer::end() {
158     fPassEncoder.EndPass();
159 }
160 
submit()161 void GrDawnGpuRTCommandBuffer::submit() {
162     dawn::CommandBuffer commandBuffer = fEncoder.Finish();
163     if (commandBuffer) {
164         fGpu->queue().Submit(1, &commandBuffer);
165     }
166 }
167 
insertEventMarker(const char * msg)168 void GrDawnGpuRTCommandBuffer::insertEventMarker(const char* msg) {
169     SkASSERT(!"unimplemented");
170 }
171 
transferFrom(const SkIRect & srcRect,GrColorType surfaceColorType,GrColorType bufferColorType,GrGpuBuffer * transferBuffer,size_t offset)172 void GrDawnGpuRTCommandBuffer::transferFrom(const SkIRect& srcRect, GrColorType surfaceColorType,
173                                             GrColorType bufferColorType,
174                                             GrGpuBuffer* transferBuffer, size_t offset) {
175     fGpu->transferPixelsFrom(fRenderTarget, srcRect.fLeft, srcRect.fTop, srcRect.width(),
176                              srcRect.height(), surfaceColorType, bufferColorType, transferBuffer,
177                              offset);
178 }
179 
onClearStencilClip(const GrFixedClip & clip,bool insideStencilMask)180 void GrDawnGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
181     fPassEncoder.EndPass();
182     fPassEncoder = beginRenderPass(dawn::LoadOp::Load, dawn::LoadOp::Clear);
183 }
184 
onClear(const GrFixedClip & clip,const SkPMColor4f & color)185 void GrDawnGpuRTCommandBuffer::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
186     fPassEncoder.EndPass();
187     fPassEncoder = beginRenderPass(dawn::LoadOp::Clear, dawn::LoadOp::Load);
188 }
189 
190 ////////////////////////////////////////////////////////////////////////////////
191 
inlineUpload(GrOpFlushState * state,GrDeferredTextureUploadFn & upload)192 void GrDawnGpuRTCommandBuffer::inlineUpload(GrOpFlushState* state,
193                                             GrDeferredTextureUploadFn& upload) {
194     SkASSERT(!"unimplemented");
195 }
196 
copy(GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)197 void GrDawnGpuRTCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
198                                     const SkIPoint& dstPoint) {
199     auto s = static_cast<GrDawnTexture*>(src->asTexture());
200     auto d = static_cast<GrDawnTexture*>(fRenderTarget->asTexture());
201 
202     if (!s || !d) {
203         return;
204     }
205 
206     dawn::Texture srcTex = s->texture();
207     dawn::Texture dstTex = d->texture();
208 
209     uint32_t x = srcRect.x();
210     uint32_t y = srcRect.y();
211     uint32_t width = srcRect.width();
212     uint32_t height = srcRect.height();
213     int rowPitch = GrDawnRoundRowBytes(width * GrBytesPerPixel(src->config()));
214     int sizeInBytes = rowPitch * height;
215 
216     dawn::BufferDescriptor desc;
217     desc.usage = dawn::BufferUsageBit::CopySrc | dawn::BufferUsageBit::CopyDst;
218     desc.size = sizeInBytes;
219 
220     dawn::Buffer buffer = fGpu->device().CreateBuffer(&desc);
221 
222     uint32_t dstX = dstPoint.x();
223     uint32_t dstY = dstPoint.y();
224     fPassEncoder.EndPass();
225 
226     dawn::TextureCopyView srcTextureCopyView;
227     srcTextureCopyView.texture = srcTex;
228     srcTextureCopyView.origin = {x, y, 0};
229 
230     dawn::TextureCopyView dstTextureCopyView;
231     dstTextureCopyView.texture = dstTex;
232     dstTextureCopyView.origin = {dstX, dstY, 0};
233 
234     dawn::BufferCopyView bufferCopyView;
235     bufferCopyView.buffer = buffer;
236     bufferCopyView.offset = 0;
237     bufferCopyView.rowPitch = rowPitch;
238     bufferCopyView.imageHeight = height;
239 
240     dawn::Extent3D copySize = {width, height, 1};
241     fEncoder.CopyTextureToBuffer(&srcTextureCopyView, &bufferCopyView, &copySize);
242     fEncoder.CopyBufferToTexture(&bufferCopyView, &dstTextureCopyView, &copySize);
243     fPassEncoder = beginRenderPass(dawn::LoadOp::Load, dawn::LoadOp::Load);
244 }
245 
246 ////////////////////////////////////////////////////////////////////////////////
247 
to_dawn_vertex_format(GrVertexAttribType type)248 static dawn::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
249     switch (type) {
250     case kFloat_GrVertexAttribType:
251     case kHalf_GrVertexAttribType:
252         return dawn::VertexFormat::Float;
253     case kFloat2_GrVertexAttribType:
254     case kHalf2_GrVertexAttribType:
255         return dawn::VertexFormat::Float2;
256     case kFloat3_GrVertexAttribType:
257     case kHalf3_GrVertexAttribType:
258         return dawn::VertexFormat::Float3;
259     case kFloat4_GrVertexAttribType:
260     case kHalf4_GrVertexAttribType:
261         return dawn::VertexFormat::Float4;
262     case kUShort2_GrVertexAttribType:
263         return dawn::VertexFormat::UShort2;
264     case kInt_GrVertexAttribType:
265         return dawn::VertexFormat::Int;
266     case kUByte4_norm_GrVertexAttribType:
267         return dawn::VertexFormat::UChar4Norm;
268     default:
269         SkASSERT(!"unsupported vertex format");
270         return dawn::VertexFormat::Float4;
271     }
272 }
273 
to_dawn_primitive_topology(GrPrimitiveType primitiveType)274 static dawn::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primitiveType) {
275     switch (primitiveType) {
276         case GrPrimitiveType::kTriangles:
277             return dawn::PrimitiveTopology::TriangleList;
278         case GrPrimitiveType::kTriangleStrip:
279             return dawn::PrimitiveTopology::TriangleStrip;
280         case GrPrimitiveType::kPoints:
281             return dawn::PrimitiveTopology::PointList;
282         case GrPrimitiveType::kLines:
283             return dawn::PrimitiveTopology::LineList;
284         case GrPrimitiveType::kLineStrip:
285             return dawn::PrimitiveTopology::LineStrip;
286         case GrPrimitiveType::kLinesAdjacency:
287         default:
288             SkASSERT(!"unsupported primitive topology");
289             return dawn::PrimitiveTopology::TriangleList;
290     }
291 }
292 
setScissorState(const GrPipeline & pipeline,const GrPipeline::FixedDynamicState * fixedDynamicState,const GrPipeline::DynamicStateArrays * dynamicStateArrays)293 void GrDawnGpuRTCommandBuffer::setScissorState(
294         const GrPipeline& pipeline,
295         const GrPipeline::FixedDynamicState* fixedDynamicState,
296         const GrPipeline::DynamicStateArrays* dynamicStateArrays) {
297     SkIRect rect;
298     if (pipeline.isScissorEnabled()) {
299         constexpr SkIRect kBogusScissor{0, 0, 1, 1};
300         rect = fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor;
301         if (kBottomLeft_GrSurfaceOrigin == fOrigin) {
302             rect.setXYWH(rect.x(), fRenderTarget->height() - rect.bottom(),
303                          rect.width(), rect.height());
304         }
305     } else {
306         rect = SkIRect::MakeWH(fRenderTarget->width(), fRenderTarget->height());
307     }
308     fPassEncoder.SetScissorRect(rect.x(), rect.y(), rect.width(), rect.height());
309 }
310 
applyState(const GrPipeline & pipeline,const GrPrimitiveProcessor & primProc,const GrTextureProxy * const primProcProxies[],const GrPipeline::FixedDynamicState * fixedDynamicState,const GrPipeline::DynamicStateArrays * dynamicStateArrays,const GrPrimitiveType primitiveType,bool hasPoints)311 void GrDawnGpuRTCommandBuffer::applyState(const GrPipeline& pipeline,
312                                           const GrPrimitiveProcessor& primProc,
313                                           const GrTextureProxy* const primProcProxies[],
314                                           const GrPipeline::FixedDynamicState* fixedDynamicState,
315                                           const GrPipeline::DynamicStateArrays* dynamicStateArrays,
316                                           const GrPrimitiveType primitiveType,
317                                           bool hasPoints) {
318     GrProgramDesc desc;
319     GrProgramDesc::Build(&desc, fRenderTarget, primProc, hasPoints, pipeline, fGpu);
320     dawn::TextureFormat colorFormat;
321     SkAssertResult(GrPixelConfigToDawnFormat(fRenderTarget->config(), &colorFormat));
322     dawn::TextureFormat stencilFormat = dawn::TextureFormat::Depth24PlusStencil8;
323     bool hasDepthStencil = fRenderTarget->renderTargetPriv().getStencilAttachment() != nullptr;
324     sk_sp<GrDawnProgram> program = GrDawnProgramBuilder::Build(fGpu, fRenderTarget, fOrigin,
325                                                                pipeline, primProc, primProcProxies,
326                                                                colorFormat, hasDepthStencil,
327                                                                stencilFormat, &desc);
328     SkASSERT(program);
329     program->setData(primProc, fRenderTarget, fOrigin, pipeline);
330 
331     std::vector<dawn::VertexBufferDescriptor> inputs;
332     std::vector<dawn::VertexAttributeDescriptor> vertexAttributes;
333     if (primProc.numVertexAttributes() > 0) {
334         size_t offset = 0;
335         int i = 0;
336         for (const auto& attrib : primProc.vertexAttributes()) {
337             dawn::VertexAttributeDescriptor attribute;
338             attribute.shaderLocation = i;
339             attribute.offset = offset;
340             attribute.format = to_dawn_vertex_format(attrib.cpuType());
341             vertexAttributes.push_back(attribute);
342             offset += attrib.sizeAlign4();
343             i++;
344         }
345         dawn::VertexBufferDescriptor input;
346         input.stride = offset;
347         input.stepMode = dawn::InputStepMode::Vertex;
348         input.attributes = &vertexAttributes.front();
349         input.attributeCount = vertexAttributes.size();
350         inputs.push_back(input);
351     }
352     std::vector<dawn::VertexAttributeDescriptor> instanceAttributes;
353     if (primProc.numInstanceAttributes() > 0) {
354         size_t offset = 0;
355         int i = 0;
356         for (const auto& attrib : primProc.instanceAttributes()) {
357             dawn::VertexAttributeDescriptor attribute;
358             attribute.shaderLocation = i;
359             attribute.offset = offset;
360             attribute.format = to_dawn_vertex_format(attrib.cpuType());
361             instanceAttributes.push_back(attribute);
362             offset += attrib.sizeAlign4();
363             i++;
364         }
365         dawn::VertexBufferDescriptor input;
366         input.stride = offset;
367         input.stepMode = dawn::InputStepMode::Instance;
368         input.attributes = &instanceAttributes.front();
369         input.attributeCount = instanceAttributes.size();
370         inputs.push_back(input);
371     }
372     dawn::VertexInputDescriptor vertexInput;
373     vertexInput.bufferCount = inputs.size();
374     vertexInput.buffers = &inputs.front();
375     vertexInput.indexFormat = dawn::IndexFormat::Uint16;
376 
377     dawn::PipelineStageDescriptor vsDesc;
378     vsDesc.module = program->fVSModule;
379     vsDesc.entryPoint = "main";
380 
381     dawn::PipelineStageDescriptor fsDesc;
382     fsDesc.module = program->fFSModule;
383     fsDesc.entryPoint = "main";
384 
385     dawn::RasterizationStateDescriptor rastDesc;
386 
387     rastDesc.frontFace = dawn::FrontFace::CW;
388     rastDesc.cullMode = dawn::CullMode::None;
389     rastDesc.depthBias = 0;
390     rastDesc.depthBiasSlopeScale = 0.0f;
391     rastDesc.depthBiasClamp = 0.0f;
392 
393     dawn::RenderPipelineDescriptor rpDesc;
394     rpDesc.layout = program->fPipelineLayout;
395     rpDesc.vertexStage = &vsDesc;
396     rpDesc.fragmentStage = &fsDesc;
397     rpDesc.vertexInput = &vertexInput;
398     rpDesc.rasterizationState = &rastDesc;
399     rpDesc.primitiveTopology = to_dawn_primitive_topology(primitiveType);
400     rpDesc.sampleCount = 1;
401     rpDesc.depthStencilState = hasDepthStencil ? &program->fDepthStencilState : nullptr;
402     rpDesc.colorStateCount = 1;
403     dawn::ColorStateDescriptor* colorStates[] = { &program->fColorState };
404     rpDesc.colorStates = colorStates;
405     dawn::RenderPipeline renderPipeline = fGpu->device().CreateRenderPipeline(&rpDesc);
406     fPassEncoder.SetPipeline(renderPipeline);
407     fPassEncoder.SetBindGroup(0, program->fBindGroup, 0, nullptr);
408     if (pipeline.isStencilEnabled()) {
409         fPassEncoder.SetStencilReference(pipeline.getUserStencil()->fFront.fRef);
410     }
411     GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
412     const float* c = blendInfo.fBlendConstant.vec();
413     dawn::Color color{c[0], c[1], c[2], c[3]};
414     fPassEncoder.SetBlendColor(&color);
415     this->setScissorState(pipeline, fixedDynamicState, dynamicStateArrays);
416 }
417 
onDraw(const GrPrimitiveProcessor & primProc,const GrPipeline & pipeline,const GrPipeline::FixedDynamicState * fixedDynamicState,const GrPipeline::DynamicStateArrays * dynamicStateArrays,const GrMesh meshes[],int meshCount,const SkRect & bounds)418 void GrDawnGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
419                                       const GrPipeline& pipeline,
420                                       const GrPipeline::FixedDynamicState* fixedDynamicState,
421                                       const GrPipeline::DynamicStateArrays* dynamicStateArrays,
422                                       const GrMesh meshes[],
423                                       int meshCount,
424                                       const SkRect& bounds) {
425     if (!meshCount) {
426         return;
427     }
428     bool hasPoints = false;
429     for (int i = 0; i < meshCount; ++i) {
430         if (meshes[i].primitiveType() == GrPrimitiveType::kPoints) {
431             hasPoints = true;
432         }
433     }
434     const GrTextureProxy* const* primProcProxies = nullptr;
435     if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
436         primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
437     } else if (fixedDynamicState) {
438         primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
439     }
440     for (int i = 0; i < meshCount; ++i) {
441         applyState(pipeline, primProc, primProcProxies, fixedDynamicState, dynamicStateArrays,
442                    meshes[0].primitiveType(), hasPoints);
443         meshes[i].sendToGpu(this);
444     }
445 }
446 
sendInstancedMeshToGpu(GrPrimitiveType,const GrBuffer * vertexBuffer,int vertexCount,int baseVertex,const GrBuffer * instanceBuffer,int instanceCount,int baseInstance)447 void GrDawnGpuRTCommandBuffer::sendInstancedMeshToGpu(GrPrimitiveType,
448                                                       const GrBuffer* vertexBuffer,
449                                                       int vertexCount,
450                                                       int baseVertex,
451                                                       const GrBuffer* instanceBuffer,
452                                                       int instanceCount,
453                                                       int baseInstance) {
454     static const uint64_t vertexBufferOffsets[1] = {0};
455     dawn::Buffer vb = static_cast<const GrDawnBuffer*>(vertexBuffer)->get();
456     fPassEncoder.SetVertexBuffers(0, 1, &vb, vertexBufferOffsets);
457     fPassEncoder.Draw(vertexCount, 1, baseVertex, baseInstance);
458     fGpu->stats()->incNumDraws();
459 }
460 
sendIndexedInstancedMeshToGpu(GrPrimitiveType,const GrBuffer * indexBuffer,int indexCount,int baseIndex,const GrBuffer * vertexBuffer,int baseVertex,const GrBuffer * instanceBuffer,int instanceCount,int baseInstance,GrPrimitiveRestart restart)461 void GrDawnGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(GrPrimitiveType,
462                                                              const GrBuffer* indexBuffer,
463                                                              int indexCount,
464                                                              int baseIndex,
465                                                              const GrBuffer* vertexBuffer,
466                                                              int baseVertex,
467                                                              const GrBuffer* instanceBuffer,
468                                                              int instanceCount,
469                                                              int baseInstance,
470                                                              GrPrimitiveRestart restart) {
471     uint64_t vertexBufferOffsets[1];
472     vertexBufferOffsets[0] = 0;
473     dawn::Buffer vb = static_cast<const GrDawnBuffer*>(vertexBuffer)->get();
474     dawn::Buffer ib = static_cast<const GrDawnBuffer*>(indexBuffer)->get();
475     fPassEncoder.SetIndexBuffer(ib, 0);
476     fPassEncoder.SetVertexBuffers(0, 1, &vb, vertexBufferOffsets);
477     fPassEncoder.DrawIndexed(indexCount, 1, baseIndex, baseVertex, baseInstance);
478     fGpu->stats()->incNumDraws();
479 }
480