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, ©Size);
63 fEncoder.CopyBufferToTexture(&bufferView, &dstTextureView, ©Size);
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, ©Size);
242 fEncoder.CopyBufferToTexture(&bufferCopyView, &dstTextureCopyView, ©Size);
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