blob: 47dda8d548325a5bcd6c9fea7edd6e07b437665a [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 Whited67c71f2019-08-06 11:15:41 -040020#include "src/gpu/dawn/GrDawnUtil.h"
21#include "src/sksl/SkSLCompiler.h"
Stephen White985741a2019-07-18 11:43:45 -040022
23void GrDawnGpuTextureCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
24 const SkIPoint& dstPoint) {
Stephen Whitec0a837f2019-07-30 11:38:22 -040025 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -040026}
27
28void GrDawnGpuTextureCommandBuffer::insertEventMarker(const char* msg) {
Stephen Whitec0a837f2019-07-30 11:38:22 -040029 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -040030}
31
32void GrDawnGpuTextureCommandBuffer::submit() {
33 for (int i = 0; i < fCopies.count(); ++i) {
34 CopyInfo& copyInfo = fCopies[i];
35 fGpu->copySurface(fTexture, copyInfo.fSrc, copyInfo.fSrcRect, copyInfo.fDstPoint);
36 }
37}
38
39GrDawnGpuTextureCommandBuffer::~GrDawnGpuTextureCommandBuffer() {}
40
41////////////////////////////////////////////////////////////////////////////////
42
43dawn::LoadOp to_dawn_load_op(GrLoadOp loadOp) {
44 switch (loadOp) {
45 case GrLoadOp::kLoad:
46 return dawn::LoadOp::Load;
47 case GrLoadOp::kClear:
48 return dawn::LoadOp::Clear;
49 case GrLoadOp::kDiscard:
50 default:
51 SK_ABORT("Invalid LoadOp");
Stephen White985741a2019-07-18 11:43:45 -040052 }
53}
54
55GrDawnGpuRTCommandBuffer::GrDawnGpuRTCommandBuffer(GrDawnGpu* gpu,
56 GrRenderTarget* rt, GrSurfaceOrigin origin,
57 const LoadAndStoreInfo& colorInfo,
58 const StencilLoadAndStoreInfo& stencilInfo)
59 : INHERITED(rt, origin)
Stephen Whited67c71f2019-08-06 11:15:41 -040060 , fGpu(gpu)
61 , fColorInfo(colorInfo) {
62 fEncoder = fGpu->device().CreateCommandEncoder();
63 fPassEncoder = beginRenderPass();
Stephen White985741a2019-07-18 11:43:45 -040064}
65
Stephen Whited67c71f2019-08-06 11:15:41 -040066dawn::RenderPassEncoder GrDawnGpuRTCommandBuffer::beginRenderPass() {
67 dawn::Texture texture = static_cast<GrDawnRenderTarget*>(fRenderTarget)->texture();
68 dawn::TextureView colorView = texture.CreateDefaultView();
69 const float *c = fColorInfo.fClearColor.vec();
70 dawn::LoadOp colorOp = to_dawn_load_op(fColorInfo.fLoadOp);
Stephen White985741a2019-07-18 11:43:45 -040071
Stephen Whited67c71f2019-08-06 11:15:41 -040072 dawn::RenderPassColorAttachmentDescriptor colorAttachment;
73 colorAttachment.attachment = colorView;
74 colorAttachment.resolveTarget = nullptr;
75 colorAttachment.clearColor = { c[0], c[1], c[2], c[3] };
76 colorAttachment.loadOp = colorOp;
77 colorAttachment.storeOp = dawn::StoreOp::Store;
78 dawn::RenderPassColorAttachmentDescriptor* colorAttachments = { &colorAttachment };
79 dawn::RenderPassDescriptor renderPassDescriptor;
80 renderPassDescriptor.colorAttachmentCount = 1;
81 renderPassDescriptor.colorAttachments = &colorAttachments;
82 renderPassDescriptor.depthStencilAttachment = nullptr;
83 return fEncoder.BeginRenderPass(&renderPassDescriptor);
84}
Stephen White985741a2019-07-18 11:43:45 -040085
86GrDawnGpuRTCommandBuffer::~GrDawnGpuRTCommandBuffer() {
87}
88
89GrGpu* GrDawnGpuRTCommandBuffer::gpu() { return fGpu; }
90
91void GrDawnGpuRTCommandBuffer::end() {
Stephen Whited67c71f2019-08-06 11:15:41 -040092 fPassEncoder.EndPass();
Stephen White985741a2019-07-18 11:43:45 -040093}
94
95void GrDawnGpuRTCommandBuffer::submit() {
Stephen Whited67c71f2019-08-06 11:15:41 -040096 dawn::CommandBuffer commandBuffer = fEncoder.Finish();
97 if (commandBuffer) {
98 fGpu->queue().Submit(1, &commandBuffer);
Stephen White985741a2019-07-18 11:43:45 -040099 }
100}
101
102void GrDawnGpuRTCommandBuffer::insertEventMarker(const char* msg) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400103 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400104}
105
Stephen Whited7325182019-08-02 17:22:59 -0400106void GrDawnGpuRTCommandBuffer::transferFrom(const SkIRect& srcRect, GrColorType surfaceColorType,
107 GrColorType bufferColorType,
Stephen White985741a2019-07-18 11:43:45 -0400108 GrGpuBuffer* transferBuffer, size_t offset) {
109 fGpu->transferPixelsFrom(fRenderTarget, srcRect.fLeft, srcRect.fTop, srcRect.width(),
Stephen Whited7325182019-08-02 17:22:59 -0400110 srcRect.height(), surfaceColorType, bufferColorType, transferBuffer,
111 offset);
Stephen White985741a2019-07-18 11:43:45 -0400112}
113
114void GrDawnGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400115 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400116}
117
118void GrDawnGpuRTCommandBuffer::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400119 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400120}
121
122////////////////////////////////////////////////////////////////////////////////
123
124void GrDawnGpuRTCommandBuffer::inlineUpload(GrOpFlushState* state,
125 GrDeferredTextureUploadFn& upload) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400126 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400127}
128
129void GrDawnGpuRTCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
130 const SkIPoint& dstPoint) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400131 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400132}
133
134////////////////////////////////////////////////////////////////////////////////
135
Stephen Whited67c71f2019-08-06 11:15:41 -0400136static dawn::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
137 switch (type) {
138 case kFloat_GrVertexAttribType:
139 case kHalf_GrVertexAttribType:
140 return dawn::VertexFormat::Float;
141 case kFloat2_GrVertexAttribType:
142 case kHalf2_GrVertexAttribType:
143 return dawn::VertexFormat::Float2;
144 case kFloat3_GrVertexAttribType:
145 case kHalf3_GrVertexAttribType:
146 return dawn::VertexFormat::Float3;
147 case kFloat4_GrVertexAttribType:
148 case kHalf4_GrVertexAttribType:
149 return dawn::VertexFormat::Float4;
150 case kUShort2_GrVertexAttribType:
151 return dawn::VertexFormat::UShort2;
152 case kUByte4_norm_GrVertexAttribType:
153 return dawn::VertexFormat::UChar4Norm;
154 default:
155 SkASSERT(!"unsupported vertex format");
156 return dawn::VertexFormat::Float4;
157 }
158}
159
160void GrDawnGpuRTCommandBuffer::beginDraw(const GrPipeline& pipeline,
161 const GrPrimitiveProcessor& primProc,
162 const GrTextureProxy* const primProcProxies[],
163 bool hasPoints) {
164 GrProgramDesc desc;
165 GrProgramDesc::Build(&desc, fRenderTarget, primProc, hasPoints, pipeline, fGpu);
166 dawn::TextureFormat colorFormat;
167 SkAssertResult(GrPixelConfigToDawnFormat(fRenderTarget->config(), &colorFormat));
168 sk_sp<GrDawnProgram> program = GrDawnProgramBuilder::Build(fGpu, fRenderTarget, fOrigin,
169 pipeline, primProc, primProcProxies,
170 colorFormat, &desc);
171 SkASSERT(program);
172 program->setData(primProc, fRenderTarget, fOrigin, pipeline);
173
174 std::vector<dawn::VertexBufferDescriptor> inputs;
175 std::vector<dawn::VertexAttributeDescriptor> vertexAttributes;
176 if (primProc.numVertexAttributes() > 0) {
177 size_t offset = 0;
178 int i = 0;
179 for (const auto& attrib : primProc.vertexAttributes()) {
180 dawn::VertexAttributeDescriptor attribute;
181 attribute.shaderLocation = i;
182 attribute.offset = offset;
183 attribute.format = to_dawn_vertex_format(attrib.cpuType());
184 vertexAttributes.push_back(attribute);
185 offset += attrib.sizeAlign4();
186 i++;
187 }
188 dawn::VertexBufferDescriptor input;
189 input.stride = offset;
190 input.stepMode = dawn::InputStepMode::Vertex;
191 input.attributes = &vertexAttributes.front();
192 input.attributeCount = vertexAttributes.size();
193 inputs.push_back(input);
194 }
195 std::vector<dawn::VertexAttributeDescriptor> instanceAttributes;
196 if (primProc.numInstanceAttributes() > 0) {
197 size_t offset = 0;
198 int i = 0;
199 for (const auto& attrib : primProc.instanceAttributes()) {
200 dawn::VertexAttributeDescriptor attribute;
201 attribute.shaderLocation = i;
202 attribute.offset = offset;
203 attribute.format = to_dawn_vertex_format(attrib.cpuType());
204 instanceAttributes.push_back(attribute);
205 offset += attrib.sizeAlign4();
206 i++;
207 }
208 dawn::VertexBufferDescriptor input;
209 input.stride = offset;
210 input.stepMode = dawn::InputStepMode::Instance;
211 input.attributes = &instanceAttributes.front();
212 input.attributeCount = instanceAttributes.size();
213 inputs.push_back(input);
214 }
215 dawn::VertexInputDescriptor vertexInput;
216 vertexInput.bufferCount = inputs.size();
217 vertexInput.buffers = &inputs.front();
218 vertexInput.indexFormat = dawn::IndexFormat::Uint16;
219
220 dawn::PipelineStageDescriptor vsDesc;
221 vsDesc.module = program->fVSModule;
222 vsDesc.entryPoint = "main";
223
224 dawn::PipelineStageDescriptor fsDesc;
225 fsDesc.module = program->fFSModule;
226 fsDesc.entryPoint = "main";
227
228 dawn::StencilStateFaceDescriptor stencilFace;
229 stencilFace.compare = dawn::CompareFunction::Always;
230 stencilFace.failOp = dawn::StencilOperation::Keep;
231 stencilFace.depthFailOp = dawn::StencilOperation::Keep;
232 stencilFace.passOp = dawn::StencilOperation::Replace;
233
234 dawn::RasterizationStateDescriptor rastDesc;
235
236 rastDesc.frontFace = dawn::FrontFace::CW;
237 rastDesc.cullMode = dawn::CullMode::None;
238 rastDesc.depthBias = 0;
239 rastDesc.depthBiasSlopeScale = 0.0f;
240 rastDesc.depthBiasClamp = 0.0f;
241
242 dawn::RenderPipelineDescriptor rpDesc;
243 rpDesc.layout = program->fPipelineLayout;
244 rpDesc.vertexStage = &vsDesc;
245 rpDesc.fragmentStage = &fsDesc;
246 rpDesc.vertexInput = &vertexInput;
247 rpDesc.rasterizationState = &rastDesc;
248 rpDesc.primitiveTopology = dawn::PrimitiveTopology::TriangleList;
249 rpDesc.sampleCount = 1;
250 rpDesc.depthStencilState = nullptr;
251 rpDesc.colorStateCount = 1;
252 dawn::ColorStateDescriptor* colorStates[] = { &program->fColorState };
253 rpDesc.colorStates = colorStates;
254 dawn::RenderPipeline renderPipeline = fGpu->device().CreateRenderPipeline(&rpDesc);
255 fPassEncoder.SetPipeline(renderPipeline);
256 fPassEncoder.SetBindGroup(0, program->fUniformBindGroup, 0, nullptr);
257}
258
259void GrDawnGpuRTCommandBuffer::endDraw() {
Stephen White985741a2019-07-18 11:43:45 -0400260}
261
262void GrDawnGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
263 const GrPipeline& pipeline,
264 const GrPipeline::FixedDynamicState* fixedDynamicState,
265 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
266 const GrMesh meshes[],
267 int meshCount,
268 const SkRect& bounds) {
269 if (!meshCount) {
270 return;
271 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400272 bool hasPoints = false;
Stephen White985741a2019-07-18 11:43:45 -0400273 for (int i = 0; i < meshCount; ++i) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400274 if (meshes[i].primitiveType() == GrPrimitiveType::kPoints) {
275 hasPoints = true;
276 }
Stephen White985741a2019-07-18 11:43:45 -0400277 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400278 const GrTextureProxy* const* primProcProxies = nullptr;
279 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
280 primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
281 } else if (fixedDynamicState) {
282 primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
283 }
284
285 beginDraw(pipeline, primProc, primProcProxies, hasPoints);
286 for (int i = 0; i < meshCount; ++i) {
287 meshes[i].sendToGpu(this);
288 }
289 endDraw();
Stephen White985741a2019-07-18 11:43:45 -0400290}
291
292void GrDawnGpuRTCommandBuffer::sendInstancedMeshToGpu(GrPrimitiveType,
293 const GrBuffer* vertexBuffer,
294 int vertexCount,
295 int baseVertex,
296 const GrBuffer* instanceBuffer,
297 int instanceCount,
298 int baseInstance) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400299 static const uint64_t vertexBufferOffsets[1] = {0};
300 dawn::Buffer vb = static_cast<const GrDawnBuffer*>(vertexBuffer)->get();
301 fPassEncoder.SetVertexBuffers(0, 1, &vb, vertexBufferOffsets);
302 fPassEncoder.Draw(vertexCount, 1, baseVertex, baseInstance);
Stephen White985741a2019-07-18 11:43:45 -0400303 fGpu->stats()->incNumDraws();
304}
305
306void GrDawnGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(GrPrimitiveType,
307 const GrBuffer* indexBuffer,
308 int indexCount,
309 int baseIndex,
310 const GrBuffer* vertexBuffer,
311 int baseVertex,
312 const GrBuffer* instanceBuffer,
313 int instanceCount,
314 int baseInstance,
315 GrPrimitiveRestart restart) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400316 uint64_t vertexBufferOffsets[1];
317 vertexBufferOffsets[0] = 0;
318 dawn::Buffer vb = static_cast<const GrDawnBuffer*>(vertexBuffer)->get();
319 dawn::Buffer ib = static_cast<const GrDawnBuffer*>(indexBuffer)->get();
320 fPassEncoder.SetIndexBuffer(ib, 0);
321 fPassEncoder.SetVertexBuffers(0, 1, &vb, vertexBufferOffsets);
322 fPassEncoder.DrawIndexed(indexCount, 1, baseIndex, baseVertex, baseInstance);
Stephen White985741a2019-07-18 11:43:45 -0400323 fGpu->stats()->incNumDraws();
324}