blob: dc1710898681bc41a6f5054fd6142e322e0fea2d [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
Stephen Whiteef2dc902019-08-26 15:19:42 -04008#include "src/gpu/dawn/GrDawnOpsRenderPass.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 Whitee3b13892019-08-14 15:48:02 -040021#include "src/gpu/dawn/GrDawnTexture.h"
Stephen Whited67c71f2019-08-06 11:15:41 -040022#include "src/gpu/dawn/GrDawnUtil.h"
23#include "src/sksl/SkSLCompiler.h"
Stephen White985741a2019-07-18 11:43:45 -040024
Stephen White985741a2019-07-18 11:43:45 -040025////////////////////////////////////////////////////////////////////////////////
26
Stephen White170d9902019-08-15 16:48:24 -040027static dawn::LoadOp to_dawn_load_op(GrLoadOp loadOp) {
Stephen White985741a2019-07-18 11:43:45 -040028 switch (loadOp) {
29 case GrLoadOp::kLoad:
30 return dawn::LoadOp::Load;
Stephen White170d9902019-08-15 16:48:24 -040031 case GrLoadOp::kDiscard:
32 // Use LoadOp::Load to emulate DontCare.
33 // Dawn doesn't have DontCare, for security reasons.
34 // Load should be equivalent to DontCare for desktop; Clear would
35 // probably be better for tilers. If Dawn does add DontCare
36 // as an extension, use it here.
37 return dawn::LoadOp::Load;
Stephen White985741a2019-07-18 11:43:45 -040038 case GrLoadOp::kClear:
39 return dawn::LoadOp::Clear;
Stephen White985741a2019-07-18 11:43:45 -040040 default:
41 SK_ABORT("Invalid LoadOp");
Stephen White985741a2019-07-18 11:43:45 -040042 }
43}
44
Stephen Whiteef2dc902019-08-26 15:19:42 -040045GrDawnOpsRenderPass::GrDawnOpsRenderPass(GrDawnGpu* gpu, GrRenderTarget* rt, GrSurfaceOrigin origin,
46 const LoadAndStoreInfo& colorInfo,
47 const StencilLoadAndStoreInfo& stencilInfo)
Stephen White985741a2019-07-18 11:43:45 -040048 : INHERITED(rt, origin)
Stephen Whited67c71f2019-08-06 11:15:41 -040049 , fGpu(gpu)
50 , fColorInfo(colorInfo) {
51 fEncoder = fGpu->device().CreateCommandEncoder();
Stephen Whitef813ef72019-08-09 12:28:37 -040052 dawn::LoadOp colorOp = to_dawn_load_op(colorInfo.fLoadOp);
53 dawn::LoadOp stencilOp = to_dawn_load_op(stencilInfo.fLoadOp);
54 fPassEncoder = beginRenderPass(colorOp, stencilOp);
Stephen White985741a2019-07-18 11:43:45 -040055}
56
Stephen Whiteef2dc902019-08-26 15:19:42 -040057dawn::RenderPassEncoder GrDawnOpsRenderPass::beginRenderPass(dawn::LoadOp colorOp,
58 dawn::LoadOp stencilOp) {
Stephen Whited67c71f2019-08-06 11:15:41 -040059 dawn::Texture texture = static_cast<GrDawnRenderTarget*>(fRenderTarget)->texture();
Stephen Whitef813ef72019-08-09 12:28:37 -040060 auto stencilAttachment = static_cast<GrDawnStencilAttachment*>(
61 fRenderTarget->renderTargetPriv().getStencilAttachment());
Stephen Whited67c71f2019-08-06 11:15:41 -040062 dawn::TextureView colorView = texture.CreateDefaultView();
63 const float *c = fColorInfo.fClearColor.vec();
Stephen White985741a2019-07-18 11:43:45 -040064
Stephen Whited67c71f2019-08-06 11:15:41 -040065 dawn::RenderPassColorAttachmentDescriptor colorAttachment;
66 colorAttachment.attachment = colorView;
67 colorAttachment.resolveTarget = nullptr;
68 colorAttachment.clearColor = { c[0], c[1], c[2], c[3] };
69 colorAttachment.loadOp = colorOp;
70 colorAttachment.storeOp = dawn::StoreOp::Store;
71 dawn::RenderPassColorAttachmentDescriptor* colorAttachments = { &colorAttachment };
72 dawn::RenderPassDescriptor renderPassDescriptor;
73 renderPassDescriptor.colorAttachmentCount = 1;
74 renderPassDescriptor.colorAttachments = &colorAttachments;
Stephen Whitef813ef72019-08-09 12:28:37 -040075 if (stencilAttachment) {
76 dawn::RenderPassDepthStencilAttachmentDescriptor depthStencilAttachment;
77 depthStencilAttachment.attachment = stencilAttachment->view();
78 depthStencilAttachment.depthLoadOp = stencilOp;
79 depthStencilAttachment.stencilLoadOp = stencilOp;
80 depthStencilAttachment.clearDepth = 1.0f;
81 depthStencilAttachment.clearStencil = 0;
82 depthStencilAttachment.depthStoreOp = dawn::StoreOp::Store;
83 depthStencilAttachment.stencilStoreOp = dawn::StoreOp::Store;
84 renderPassDescriptor.depthStencilAttachment = &depthStencilAttachment;
85 } else {
86 renderPassDescriptor.depthStencilAttachment = nullptr;
87 }
Stephen Whited67c71f2019-08-06 11:15:41 -040088 return fEncoder.BeginRenderPass(&renderPassDescriptor);
89}
Stephen White985741a2019-07-18 11:43:45 -040090
Stephen Whiteef2dc902019-08-26 15:19:42 -040091GrDawnOpsRenderPass::~GrDawnOpsRenderPass() {
Stephen White985741a2019-07-18 11:43:45 -040092}
93
Stephen Whiteef2dc902019-08-26 15:19:42 -040094GrGpu* GrDawnOpsRenderPass::gpu() { return fGpu; }
Stephen White985741a2019-07-18 11:43:45 -040095
Stephen Whiteef2dc902019-08-26 15:19:42 -040096void GrDawnOpsRenderPass::end() {
Stephen Whited67c71f2019-08-06 11:15:41 -040097 fPassEncoder.EndPass();
Stephen White985741a2019-07-18 11:43:45 -040098}
99
Stephen Whiteef2dc902019-08-26 15:19:42 -0400100void GrDawnOpsRenderPass::submit() {
Stephen Whited67c71f2019-08-06 11:15:41 -0400101 dawn::CommandBuffer commandBuffer = fEncoder.Finish();
102 if (commandBuffer) {
103 fGpu->queue().Submit(1, &commandBuffer);
Stephen White985741a2019-07-18 11:43:45 -0400104 }
105}
106
Stephen Whiteef2dc902019-08-26 15:19:42 -0400107void GrDawnOpsRenderPass::insertEventMarker(const char* msg) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400108 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400109}
110
Stephen Whiteef2dc902019-08-26 15:19:42 -0400111void GrDawnOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400112 fPassEncoder.EndPass();
113 fPassEncoder = beginRenderPass(dawn::LoadOp::Load, dawn::LoadOp::Clear);
Stephen White985741a2019-07-18 11:43:45 -0400114}
115
Stephen Whiteef2dc902019-08-26 15:19:42 -0400116void GrDawnOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400117 fPassEncoder.EndPass();
118 fPassEncoder = beginRenderPass(dawn::LoadOp::Clear, dawn::LoadOp::Load);
Stephen White985741a2019-07-18 11:43:45 -0400119}
120
121////////////////////////////////////////////////////////////////////////////////
122
Stephen Whiteef2dc902019-08-26 15:19:42 -0400123void GrDawnOpsRenderPass::inlineUpload(GrOpFlushState* state,
124 GrDeferredTextureUploadFn& upload) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400125 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400126}
127
Stephen White985741a2019-07-18 11:43:45 -0400128////////////////////////////////////////////////////////////////////////////////
129
Stephen Whited67c71f2019-08-06 11:15:41 -0400130static dawn::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
131 switch (type) {
132 case kFloat_GrVertexAttribType:
133 case kHalf_GrVertexAttribType:
134 return dawn::VertexFormat::Float;
135 case kFloat2_GrVertexAttribType:
136 case kHalf2_GrVertexAttribType:
137 return dawn::VertexFormat::Float2;
138 case kFloat3_GrVertexAttribType:
139 case kHalf3_GrVertexAttribType:
140 return dawn::VertexFormat::Float3;
141 case kFloat4_GrVertexAttribType:
142 case kHalf4_GrVertexAttribType:
143 return dawn::VertexFormat::Float4;
144 case kUShort2_GrVertexAttribType:
145 return dawn::VertexFormat::UShort2;
Stephen White170d9902019-08-15 16:48:24 -0400146 case kInt_GrVertexAttribType:
147 return dawn::VertexFormat::Int;
Stephen Whited67c71f2019-08-06 11:15:41 -0400148 case kUByte4_norm_GrVertexAttribType:
149 return dawn::VertexFormat::UChar4Norm;
150 default:
151 SkASSERT(!"unsupported vertex format");
152 return dawn::VertexFormat::Float4;
153 }
154}
155
Stephen Whitef813ef72019-08-09 12:28:37 -0400156static dawn::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primitiveType) {
157 switch (primitiveType) {
158 case GrPrimitiveType::kTriangles:
159 return dawn::PrimitiveTopology::TriangleList;
160 case GrPrimitiveType::kTriangleStrip:
161 return dawn::PrimitiveTopology::TriangleStrip;
162 case GrPrimitiveType::kPoints:
163 return dawn::PrimitiveTopology::PointList;
164 case GrPrimitiveType::kLines:
165 return dawn::PrimitiveTopology::LineList;
166 case GrPrimitiveType::kLineStrip:
167 return dawn::PrimitiveTopology::LineStrip;
168 case GrPrimitiveType::kLinesAdjacency:
169 default:
170 SkASSERT(!"unsupported primitive topology");
171 return dawn::PrimitiveTopology::TriangleList;
172 }
173}
174
Stephen Whiteef2dc902019-08-26 15:19:42 -0400175void GrDawnOpsRenderPass::setScissorState(
Stephen White170d9902019-08-15 16:48:24 -0400176 const GrPipeline& pipeline,
177 const GrPipeline::FixedDynamicState* fixedDynamicState,
178 const GrPipeline::DynamicStateArrays* dynamicStateArrays) {
179 SkIRect rect;
180 if (pipeline.isScissorEnabled()) {
181 constexpr SkIRect kBogusScissor{0, 0, 1, 1};
182 rect = fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor;
183 if (kBottomLeft_GrSurfaceOrigin == fOrigin) {
184 rect.setXYWH(rect.x(), fRenderTarget->height() - rect.bottom(),
185 rect.width(), rect.height());
186 }
187 } else {
188 rect = SkIRect::MakeWH(fRenderTarget->width(), fRenderTarget->height());
189 }
190 fPassEncoder.SetScissorRect(rect.x(), rect.y(), rect.width(), rect.height());
191}
192
Stephen Whiteef2dc902019-08-26 15:19:42 -0400193void GrDawnOpsRenderPass::applyState(const GrPipeline& pipeline,
Stephen Whitef813ef72019-08-09 12:28:37 -0400194 const GrPrimitiveProcessor& primProc,
195 const GrTextureProxy* const primProcProxies[],
196 const GrPipeline::FixedDynamicState* fixedDynamicState,
197 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
198 const GrPrimitiveType primitiveType,
199 bool hasPoints) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400200 GrProgramDesc desc;
201 GrProgramDesc::Build(&desc, fRenderTarget, primProc, hasPoints, pipeline, fGpu);
202 dawn::TextureFormat colorFormat;
203 SkAssertResult(GrPixelConfigToDawnFormat(fRenderTarget->config(), &colorFormat));
Stephen Whitef813ef72019-08-09 12:28:37 -0400204 dawn::TextureFormat stencilFormat = dawn::TextureFormat::Depth24PlusStencil8;
205 bool hasDepthStencil = fRenderTarget->renderTargetPriv().getStencilAttachment() != nullptr;
Stephen Whited67c71f2019-08-06 11:15:41 -0400206 sk_sp<GrDawnProgram> program = GrDawnProgramBuilder::Build(fGpu, fRenderTarget, fOrigin,
207 pipeline, primProc, primProcProxies,
Stephen Whitef813ef72019-08-09 12:28:37 -0400208 colorFormat, hasDepthStencil,
209 stencilFormat, &desc);
Stephen Whited67c71f2019-08-06 11:15:41 -0400210 SkASSERT(program);
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400211 auto bindGroup = program->setData(fGpu, fRenderTarget, fOrigin, primProc, pipeline,
212 primProcProxies);
Stephen Whited67c71f2019-08-06 11:15:41 -0400213
214 std::vector<dawn::VertexBufferDescriptor> inputs;
215 std::vector<dawn::VertexAttributeDescriptor> vertexAttributes;
216 if (primProc.numVertexAttributes() > 0) {
217 size_t offset = 0;
218 int i = 0;
219 for (const auto& attrib : primProc.vertexAttributes()) {
220 dawn::VertexAttributeDescriptor attribute;
221 attribute.shaderLocation = i;
222 attribute.offset = offset;
223 attribute.format = to_dawn_vertex_format(attrib.cpuType());
224 vertexAttributes.push_back(attribute);
225 offset += attrib.sizeAlign4();
226 i++;
227 }
228 dawn::VertexBufferDescriptor input;
229 input.stride = offset;
230 input.stepMode = dawn::InputStepMode::Vertex;
231 input.attributes = &vertexAttributes.front();
232 input.attributeCount = vertexAttributes.size();
233 inputs.push_back(input);
234 }
235 std::vector<dawn::VertexAttributeDescriptor> instanceAttributes;
236 if (primProc.numInstanceAttributes() > 0) {
237 size_t offset = 0;
238 int i = 0;
239 for (const auto& attrib : primProc.instanceAttributes()) {
240 dawn::VertexAttributeDescriptor attribute;
241 attribute.shaderLocation = i;
242 attribute.offset = offset;
243 attribute.format = to_dawn_vertex_format(attrib.cpuType());
244 instanceAttributes.push_back(attribute);
245 offset += attrib.sizeAlign4();
246 i++;
247 }
248 dawn::VertexBufferDescriptor input;
249 input.stride = offset;
250 input.stepMode = dawn::InputStepMode::Instance;
251 input.attributes = &instanceAttributes.front();
252 input.attributeCount = instanceAttributes.size();
253 inputs.push_back(input);
254 }
255 dawn::VertexInputDescriptor vertexInput;
256 vertexInput.bufferCount = inputs.size();
257 vertexInput.buffers = &inputs.front();
258 vertexInput.indexFormat = dawn::IndexFormat::Uint16;
259
260 dawn::PipelineStageDescriptor vsDesc;
261 vsDesc.module = program->fVSModule;
262 vsDesc.entryPoint = "main";
263
264 dawn::PipelineStageDescriptor fsDesc;
265 fsDesc.module = program->fFSModule;
266 fsDesc.entryPoint = "main";
267
Stephen Whited67c71f2019-08-06 11:15:41 -0400268 dawn::RasterizationStateDescriptor rastDesc;
269
270 rastDesc.frontFace = dawn::FrontFace::CW;
271 rastDesc.cullMode = dawn::CullMode::None;
272 rastDesc.depthBias = 0;
273 rastDesc.depthBiasSlopeScale = 0.0f;
274 rastDesc.depthBiasClamp = 0.0f;
275
276 dawn::RenderPipelineDescriptor rpDesc;
277 rpDesc.layout = program->fPipelineLayout;
278 rpDesc.vertexStage = &vsDesc;
279 rpDesc.fragmentStage = &fsDesc;
280 rpDesc.vertexInput = &vertexInput;
281 rpDesc.rasterizationState = &rastDesc;
Stephen Whitef813ef72019-08-09 12:28:37 -0400282 rpDesc.primitiveTopology = to_dawn_primitive_topology(primitiveType);
Stephen Whited67c71f2019-08-06 11:15:41 -0400283 rpDesc.sampleCount = 1;
Stephen Whitef813ef72019-08-09 12:28:37 -0400284 rpDesc.depthStencilState = hasDepthStencil ? &program->fDepthStencilState : nullptr;
Stephen Whited67c71f2019-08-06 11:15:41 -0400285 rpDesc.colorStateCount = 1;
286 dawn::ColorStateDescriptor* colorStates[] = { &program->fColorState };
287 rpDesc.colorStates = colorStates;
288 dawn::RenderPipeline renderPipeline = fGpu->device().CreateRenderPipeline(&rpDesc);
289 fPassEncoder.SetPipeline(renderPipeline);
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400290 fPassEncoder.SetBindGroup(0, bindGroup, 0, nullptr);
Stephen Whitef813ef72019-08-09 12:28:37 -0400291 if (pipeline.isStencilEnabled()) {
292 fPassEncoder.SetStencilReference(pipeline.getUserStencil()->fFront.fRef);
293 }
Stephen White170d9902019-08-15 16:48:24 -0400294 GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
295 const float* c = blendInfo.fBlendConstant.vec();
296 dawn::Color color{c[0], c[1], c[2], c[3]};
297 fPassEncoder.SetBlendColor(&color);
298 this->setScissorState(pipeline, fixedDynamicState, dynamicStateArrays);
Stephen White985741a2019-07-18 11:43:45 -0400299}
300
Stephen Whiteef2dc902019-08-26 15:19:42 -0400301void GrDawnOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
302 const GrPipeline& pipeline,
303 const GrPipeline::FixedDynamicState* fixedDynamicState,
304 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
305 const GrMesh meshes[],
306 int meshCount,
307 const SkRect& bounds) {
Stephen White985741a2019-07-18 11:43:45 -0400308 if (!meshCount) {
309 return;
310 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400311 bool hasPoints = false;
Stephen White985741a2019-07-18 11:43:45 -0400312 for (int i = 0; i < meshCount; ++i) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400313 if (meshes[i].primitiveType() == GrPrimitiveType::kPoints) {
314 hasPoints = true;
315 }
Stephen White985741a2019-07-18 11:43:45 -0400316 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400317 const GrTextureProxy* const* primProcProxies = nullptr;
318 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
319 primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
320 } else if (fixedDynamicState) {
321 primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
322 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400323 for (int i = 0; i < meshCount; ++i) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400324 applyState(pipeline, primProc, primProcProxies, fixedDynamicState, dynamicStateArrays,
325 meshes[0].primitiveType(), hasPoints);
Stephen Whited67c71f2019-08-06 11:15:41 -0400326 meshes[i].sendToGpu(this);
327 }
Stephen White985741a2019-07-18 11:43:45 -0400328}
329
Stephen Whiteef2dc902019-08-26 15:19:42 -0400330void GrDawnOpsRenderPass::sendInstancedMeshToGpu(GrPrimitiveType,
331 const GrBuffer* vertexBuffer,
332 int vertexCount,
333 int baseVertex,
334 const GrBuffer* instanceBuffer,
335 int instanceCount,
336 int baseInstance) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400337 static const uint64_t vertexBufferOffsets[1] = {0};
338 dawn::Buffer vb = static_cast<const GrDawnBuffer*>(vertexBuffer)->get();
339 fPassEncoder.SetVertexBuffers(0, 1, &vb, vertexBufferOffsets);
340 fPassEncoder.Draw(vertexCount, 1, baseVertex, baseInstance);
Stephen White985741a2019-07-18 11:43:45 -0400341 fGpu->stats()->incNumDraws();
342}
343
Stephen Whiteef2dc902019-08-26 15:19:42 -0400344void GrDawnOpsRenderPass::sendIndexedInstancedMeshToGpu(GrPrimitiveType,
345 const GrBuffer* indexBuffer,
346 int indexCount,
347 int baseIndex,
348 const GrBuffer* vertexBuffer,
349 int baseVertex,
350 const GrBuffer* instanceBuffer,
351 int instanceCount,
352 int baseInstance,
353 GrPrimitiveRestart restart) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400354 uint64_t vertexBufferOffsets[1];
355 vertexBufferOffsets[0] = 0;
356 dawn::Buffer vb = static_cast<const GrDawnBuffer*>(vertexBuffer)->get();
357 dawn::Buffer ib = static_cast<const GrDawnBuffer*>(indexBuffer)->get();
358 fPassEncoder.SetIndexBuffer(ib, 0);
359 fPassEncoder.SetVertexBuffers(0, 1, &vb, vertexBufferOffsets);
360 fPassEncoder.DrawIndexed(indexCount, 1, baseIndex, baseVertex, baseInstance);
Stephen White985741a2019-07-18 11:43:45 -0400361 fGpu->stats()->incNumDraws();
362}