blob: 1f1a6640a848a25f026c59882ccd1c5e44698486 [file] [log] [blame]
Stephen White985741a2019-07-18 11:43:45 -04001/*
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
Mike Klein52337de2019-07-25 09:00:52 -05008#include "src/gpu/dawn/GrDawnGpuCommandBuffer.h"
Stephen White985741a2019-07-18 11:43:45 -04009
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"
Stephen Whited67c71f2019-08-06 11:15:41 -040016#include "src/gpu/dawn/GrDawnBuffer.h"
Stephen White985741a2019-07-18 11:43:45 -040017#include "src/gpu/dawn/GrDawnGpu.h"
Stephen Whited67c71f2019-08-06 11:15:41 -040018#include "src/gpu/dawn/GrDawnProgramBuilder.h"
Stephen White985741a2019-07-18 11:43:45 -040019#include "src/gpu/dawn/GrDawnRenderTarget.h"
Stephen Whitef813ef72019-08-09 12:28:37 -040020#include "src/gpu/dawn/GrDawnStencilAttachment.h"
Stephen Whited67c71f2019-08-06 11:15:41 -040021#include "src/gpu/dawn/GrDawnUtil.h"
22#include "src/sksl/SkSLCompiler.h"
Stephen White985741a2019-07-18 11:43:45 -040023
24void GrDawnGpuTextureCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
25 const SkIPoint& dstPoint) {
Stephen Whitec0a837f2019-07-30 11:38:22 -040026 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -040027}
28
29void GrDawnGpuTextureCommandBuffer::insertEventMarker(const char* msg) {
Stephen Whitec0a837f2019-07-30 11:38:22 -040030 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -040031}
32
33void GrDawnGpuTextureCommandBuffer::submit() {
34 for (int i = 0; i < fCopies.count(); ++i) {
35 CopyInfo& copyInfo = fCopies[i];
36 fGpu->copySurface(fTexture, copyInfo.fSrc, copyInfo.fSrcRect, copyInfo.fDstPoint);
37 }
38}
39
40GrDawnGpuTextureCommandBuffer::~GrDawnGpuTextureCommandBuffer() {}
41
42////////////////////////////////////////////////////////////////////////////////
43
44dawn::LoadOp to_dawn_load_op(GrLoadOp loadOp) {
45 switch (loadOp) {
46 case GrLoadOp::kLoad:
47 return dawn::LoadOp::Load;
48 case GrLoadOp::kClear:
49 return dawn::LoadOp::Clear;
50 case GrLoadOp::kDiscard:
51 default:
52 SK_ABORT("Invalid LoadOp");
Stephen White985741a2019-07-18 11:43:45 -040053 }
54}
55
56GrDawnGpuRTCommandBuffer::GrDawnGpuRTCommandBuffer(GrDawnGpu* gpu,
57 GrRenderTarget* rt, GrSurfaceOrigin origin,
58 const LoadAndStoreInfo& colorInfo,
59 const StencilLoadAndStoreInfo& stencilInfo)
60 : INHERITED(rt, origin)
Stephen Whited67c71f2019-08-06 11:15:41 -040061 , fGpu(gpu)
62 , fColorInfo(colorInfo) {
63 fEncoder = fGpu->device().CreateCommandEncoder();
Stephen Whitef813ef72019-08-09 12:28:37 -040064 dawn::LoadOp colorOp = to_dawn_load_op(colorInfo.fLoadOp);
65 dawn::LoadOp stencilOp = to_dawn_load_op(stencilInfo.fLoadOp);
66 fPassEncoder = beginRenderPass(colorOp, stencilOp);
Stephen White985741a2019-07-18 11:43:45 -040067}
68
Stephen Whitef813ef72019-08-09 12:28:37 -040069dawn::RenderPassEncoder GrDawnGpuRTCommandBuffer::beginRenderPass(dawn::LoadOp colorOp,
70 dawn::LoadOp stencilOp) {
Stephen Whited67c71f2019-08-06 11:15:41 -040071 dawn::Texture texture = static_cast<GrDawnRenderTarget*>(fRenderTarget)->texture();
Stephen Whitef813ef72019-08-09 12:28:37 -040072 auto stencilAttachment = static_cast<GrDawnStencilAttachment*>(
73 fRenderTarget->renderTargetPriv().getStencilAttachment());
Stephen Whited67c71f2019-08-06 11:15:41 -040074 dawn::TextureView colorView = texture.CreateDefaultView();
75 const float *c = fColorInfo.fClearColor.vec();
Stephen White985741a2019-07-18 11:43:45 -040076
Stephen Whited67c71f2019-08-06 11:15:41 -040077 dawn::RenderPassColorAttachmentDescriptor colorAttachment;
78 colorAttachment.attachment = colorView;
79 colorAttachment.resolveTarget = nullptr;
80 colorAttachment.clearColor = { c[0], c[1], c[2], c[3] };
81 colorAttachment.loadOp = colorOp;
82 colorAttachment.storeOp = dawn::StoreOp::Store;
83 dawn::RenderPassColorAttachmentDescriptor* colorAttachments = { &colorAttachment };
84 dawn::RenderPassDescriptor renderPassDescriptor;
85 renderPassDescriptor.colorAttachmentCount = 1;
86 renderPassDescriptor.colorAttachments = &colorAttachments;
Stephen Whitef813ef72019-08-09 12:28:37 -040087 if (stencilAttachment) {
88 dawn::RenderPassDepthStencilAttachmentDescriptor depthStencilAttachment;
89 depthStencilAttachment.attachment = stencilAttachment->view();
90 depthStencilAttachment.depthLoadOp = stencilOp;
91 depthStencilAttachment.stencilLoadOp = stencilOp;
92 depthStencilAttachment.clearDepth = 1.0f;
93 depthStencilAttachment.clearStencil = 0;
94 depthStencilAttachment.depthStoreOp = dawn::StoreOp::Store;
95 depthStencilAttachment.stencilStoreOp = dawn::StoreOp::Store;
96 renderPassDescriptor.depthStencilAttachment = &depthStencilAttachment;
97 } else {
98 renderPassDescriptor.depthStencilAttachment = nullptr;
99 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400100 return fEncoder.BeginRenderPass(&renderPassDescriptor);
101}
Stephen White985741a2019-07-18 11:43:45 -0400102
103GrDawnGpuRTCommandBuffer::~GrDawnGpuRTCommandBuffer() {
104}
105
106GrGpu* GrDawnGpuRTCommandBuffer::gpu() { return fGpu; }
107
108void GrDawnGpuRTCommandBuffer::end() {
Stephen Whited67c71f2019-08-06 11:15:41 -0400109 fPassEncoder.EndPass();
Stephen White985741a2019-07-18 11:43:45 -0400110}
111
112void GrDawnGpuRTCommandBuffer::submit() {
Stephen Whited67c71f2019-08-06 11:15:41 -0400113 dawn::CommandBuffer commandBuffer = fEncoder.Finish();
114 if (commandBuffer) {
115 fGpu->queue().Submit(1, &commandBuffer);
Stephen White985741a2019-07-18 11:43:45 -0400116 }
117}
118
119void GrDawnGpuRTCommandBuffer::insertEventMarker(const char* msg) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400120 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400121}
122
Stephen Whited7325182019-08-02 17:22:59 -0400123void GrDawnGpuRTCommandBuffer::transferFrom(const SkIRect& srcRect, GrColorType surfaceColorType,
124 GrColorType bufferColorType,
Stephen White985741a2019-07-18 11:43:45 -0400125 GrGpuBuffer* transferBuffer, size_t offset) {
126 fGpu->transferPixelsFrom(fRenderTarget, srcRect.fLeft, srcRect.fTop, srcRect.width(),
Stephen Whited7325182019-08-02 17:22:59 -0400127 srcRect.height(), surfaceColorType, bufferColorType, transferBuffer,
128 offset);
Stephen White985741a2019-07-18 11:43:45 -0400129}
130
131void GrDawnGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400132 fPassEncoder.EndPass();
133 fPassEncoder = beginRenderPass(dawn::LoadOp::Load, dawn::LoadOp::Clear);
Stephen White985741a2019-07-18 11:43:45 -0400134}
135
136void GrDawnGpuRTCommandBuffer::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400137 fPassEncoder.EndPass();
138 fPassEncoder = beginRenderPass(dawn::LoadOp::Clear, dawn::LoadOp::Load);
Stephen White985741a2019-07-18 11:43:45 -0400139}
140
141////////////////////////////////////////////////////////////////////////////////
142
143void GrDawnGpuRTCommandBuffer::inlineUpload(GrOpFlushState* state,
144 GrDeferredTextureUploadFn& upload) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400145 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400146}
147
148void GrDawnGpuRTCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
149 const SkIPoint& dstPoint) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400150 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400151}
152
153////////////////////////////////////////////////////////////////////////////////
154
Stephen Whited67c71f2019-08-06 11:15:41 -0400155static dawn::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
156 switch (type) {
157 case kFloat_GrVertexAttribType:
158 case kHalf_GrVertexAttribType:
159 return dawn::VertexFormat::Float;
160 case kFloat2_GrVertexAttribType:
161 case kHalf2_GrVertexAttribType:
162 return dawn::VertexFormat::Float2;
163 case kFloat3_GrVertexAttribType:
164 case kHalf3_GrVertexAttribType:
165 return dawn::VertexFormat::Float3;
166 case kFloat4_GrVertexAttribType:
167 case kHalf4_GrVertexAttribType:
168 return dawn::VertexFormat::Float4;
169 case kUShort2_GrVertexAttribType:
170 return dawn::VertexFormat::UShort2;
171 case kUByte4_norm_GrVertexAttribType:
172 return dawn::VertexFormat::UChar4Norm;
173 default:
174 SkASSERT(!"unsupported vertex format");
175 return dawn::VertexFormat::Float4;
176 }
177}
178
Stephen Whitef813ef72019-08-09 12:28:37 -0400179static dawn::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primitiveType) {
180 switch (primitiveType) {
181 case GrPrimitiveType::kTriangles:
182 return dawn::PrimitiveTopology::TriangleList;
183 case GrPrimitiveType::kTriangleStrip:
184 return dawn::PrimitiveTopology::TriangleStrip;
185 case GrPrimitiveType::kPoints:
186 return dawn::PrimitiveTopology::PointList;
187 case GrPrimitiveType::kLines:
188 return dawn::PrimitiveTopology::LineList;
189 case GrPrimitiveType::kLineStrip:
190 return dawn::PrimitiveTopology::LineStrip;
191 case GrPrimitiveType::kLinesAdjacency:
192 default:
193 SkASSERT(!"unsupported primitive topology");
194 return dawn::PrimitiveTopology::TriangleList;
195 }
196}
197
198void GrDawnGpuRTCommandBuffer::applyState(const GrPipeline& pipeline,
199 const GrPrimitiveProcessor& primProc,
200 const GrTextureProxy* const primProcProxies[],
201 const GrPipeline::FixedDynamicState* fixedDynamicState,
202 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
203 const GrPrimitiveType primitiveType,
204 bool hasPoints) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400205 GrProgramDesc desc;
206 GrProgramDesc::Build(&desc, fRenderTarget, primProc, hasPoints, pipeline, fGpu);
207 dawn::TextureFormat colorFormat;
208 SkAssertResult(GrPixelConfigToDawnFormat(fRenderTarget->config(), &colorFormat));
Stephen Whitef813ef72019-08-09 12:28:37 -0400209 dawn::TextureFormat stencilFormat = dawn::TextureFormat::Depth24PlusStencil8;
210 bool hasDepthStencil = fRenderTarget->renderTargetPriv().getStencilAttachment() != nullptr;
Stephen Whited67c71f2019-08-06 11:15:41 -0400211 sk_sp<GrDawnProgram> program = GrDawnProgramBuilder::Build(fGpu, fRenderTarget, fOrigin,
212 pipeline, primProc, primProcProxies,
Stephen Whitef813ef72019-08-09 12:28:37 -0400213 colorFormat, hasDepthStencil,
214 stencilFormat, &desc);
Stephen Whited67c71f2019-08-06 11:15:41 -0400215 SkASSERT(program);
216 program->setData(primProc, fRenderTarget, fOrigin, pipeline);
217
218 std::vector<dawn::VertexBufferDescriptor> inputs;
219 std::vector<dawn::VertexAttributeDescriptor> vertexAttributes;
220 if (primProc.numVertexAttributes() > 0) {
221 size_t offset = 0;
222 int i = 0;
223 for (const auto& attrib : primProc.vertexAttributes()) {
224 dawn::VertexAttributeDescriptor attribute;
225 attribute.shaderLocation = i;
226 attribute.offset = offset;
227 attribute.format = to_dawn_vertex_format(attrib.cpuType());
228 vertexAttributes.push_back(attribute);
229 offset += attrib.sizeAlign4();
230 i++;
231 }
232 dawn::VertexBufferDescriptor input;
233 input.stride = offset;
234 input.stepMode = dawn::InputStepMode::Vertex;
235 input.attributes = &vertexAttributes.front();
236 input.attributeCount = vertexAttributes.size();
237 inputs.push_back(input);
238 }
239 std::vector<dawn::VertexAttributeDescriptor> instanceAttributes;
240 if (primProc.numInstanceAttributes() > 0) {
241 size_t offset = 0;
242 int i = 0;
243 for (const auto& attrib : primProc.instanceAttributes()) {
244 dawn::VertexAttributeDescriptor attribute;
245 attribute.shaderLocation = i;
246 attribute.offset = offset;
247 attribute.format = to_dawn_vertex_format(attrib.cpuType());
248 instanceAttributes.push_back(attribute);
249 offset += attrib.sizeAlign4();
250 i++;
251 }
252 dawn::VertexBufferDescriptor input;
253 input.stride = offset;
254 input.stepMode = dawn::InputStepMode::Instance;
255 input.attributes = &instanceAttributes.front();
256 input.attributeCount = instanceAttributes.size();
257 inputs.push_back(input);
258 }
259 dawn::VertexInputDescriptor vertexInput;
260 vertexInput.bufferCount = inputs.size();
261 vertexInput.buffers = &inputs.front();
262 vertexInput.indexFormat = dawn::IndexFormat::Uint16;
263
264 dawn::PipelineStageDescriptor vsDesc;
265 vsDesc.module = program->fVSModule;
266 vsDesc.entryPoint = "main";
267
268 dawn::PipelineStageDescriptor fsDesc;
269 fsDesc.module = program->fFSModule;
270 fsDesc.entryPoint = "main";
271
Stephen Whited67c71f2019-08-06 11:15:41 -0400272 dawn::RasterizationStateDescriptor rastDesc;
273
274 rastDesc.frontFace = dawn::FrontFace::CW;
275 rastDesc.cullMode = dawn::CullMode::None;
276 rastDesc.depthBias = 0;
277 rastDesc.depthBiasSlopeScale = 0.0f;
278 rastDesc.depthBiasClamp = 0.0f;
279
280 dawn::RenderPipelineDescriptor rpDesc;
281 rpDesc.layout = program->fPipelineLayout;
282 rpDesc.vertexStage = &vsDesc;
283 rpDesc.fragmentStage = &fsDesc;
284 rpDesc.vertexInput = &vertexInput;
285 rpDesc.rasterizationState = &rastDesc;
Stephen Whitef813ef72019-08-09 12:28:37 -0400286 rpDesc.primitiveTopology = to_dawn_primitive_topology(primitiveType);
Stephen Whited67c71f2019-08-06 11:15:41 -0400287 rpDesc.sampleCount = 1;
Stephen Whitef813ef72019-08-09 12:28:37 -0400288 rpDesc.depthStencilState = hasDepthStencil ? &program->fDepthStencilState : nullptr;
Stephen Whited67c71f2019-08-06 11:15:41 -0400289 rpDesc.colorStateCount = 1;
290 dawn::ColorStateDescriptor* colorStates[] = { &program->fColorState };
291 rpDesc.colorStates = colorStates;
292 dawn::RenderPipeline renderPipeline = fGpu->device().CreateRenderPipeline(&rpDesc);
293 fPassEncoder.SetPipeline(renderPipeline);
294 fPassEncoder.SetBindGroup(0, program->fUniformBindGroup, 0, nullptr);
Stephen Whitef813ef72019-08-09 12:28:37 -0400295 if (pipeline.isStencilEnabled()) {
296 fPassEncoder.SetStencilReference(pipeline.getUserStencil()->fFront.fRef);
297 }
Stephen White985741a2019-07-18 11:43:45 -0400298}
299
300void GrDawnGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
301 const GrPipeline& pipeline,
302 const GrPipeline::FixedDynamicState* fixedDynamicState,
303 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
304 const GrMesh meshes[],
305 int meshCount,
306 const SkRect& bounds) {
307 if (!meshCount) {
308 return;
309 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400310 bool hasPoints = false;
Stephen White985741a2019-07-18 11:43:45 -0400311 for (int i = 0; i < meshCount; ++i) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400312 if (meshes[i].primitiveType() == GrPrimitiveType::kPoints) {
313 hasPoints = true;
314 }
Stephen White985741a2019-07-18 11:43:45 -0400315 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400316 const GrTextureProxy* const* primProcProxies = nullptr;
317 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
318 primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
319 } else if (fixedDynamicState) {
320 primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
321 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400322 for (int i = 0; i < meshCount; ++i) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400323 applyState(pipeline, primProc, primProcProxies, fixedDynamicState, dynamicStateArrays,
324 meshes[0].primitiveType(), hasPoints);
Stephen Whited67c71f2019-08-06 11:15:41 -0400325 meshes[i].sendToGpu(this);
326 }
Stephen White985741a2019-07-18 11:43:45 -0400327}
328
329void GrDawnGpuRTCommandBuffer::sendInstancedMeshToGpu(GrPrimitiveType,
330 const GrBuffer* vertexBuffer,
331 int vertexCount,
332 int baseVertex,
333 const GrBuffer* instanceBuffer,
334 int instanceCount,
335 int baseInstance) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400336 static const uint64_t vertexBufferOffsets[1] = {0};
337 dawn::Buffer vb = static_cast<const GrDawnBuffer*>(vertexBuffer)->get();
338 fPassEncoder.SetVertexBuffers(0, 1, &vb, vertexBufferOffsets);
339 fPassEncoder.Draw(vertexCount, 1, baseVertex, baseInstance);
Stephen White985741a2019-07-18 11:43:45 -0400340 fGpu->stats()->incNumDraws();
341}
342
343void GrDawnGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(GrPrimitiveType,
344 const GrBuffer* indexBuffer,
345 int indexCount,
346 int baseIndex,
347 const GrBuffer* vertexBuffer,
348 int baseVertex,
349 const GrBuffer* instanceBuffer,
350 int instanceCount,
351 int baseInstance,
352 GrPrimitiveRestart restart) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400353 uint64_t vertexBufferOffsets[1];
354 vertexBufferOffsets[0] = 0;
355 dawn::Buffer vb = static_cast<const GrDawnBuffer*>(vertexBuffer)->get();
356 dawn::Buffer ib = static_cast<const GrDawnBuffer*>(indexBuffer)->get();
357 fPassEncoder.SetIndexBuffer(ib, 0);
358 fPassEncoder.SetVertexBuffers(0, 1, &vb, vertexBufferOffsets);
359 fPassEncoder.DrawIndexed(indexCount, 1, baseIndex, baseVertex, baseInstance);
Stephen White985741a2019-07-18 11:43:45 -0400360 fGpu->stats()->incNumDraws();
361}