blob: e8abcf1b871ec8e0563af063b6ef5950e0b55bc3 [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 Whited729e2d2019-08-28 12:37:47 -0400101 fGpu->appendCommandBuffer(fEncoder.Finish());
Stephen White985741a2019-07-18 11:43:45 -0400102}
103
Stephen Whiteef2dc902019-08-26 15:19:42 -0400104void GrDawnOpsRenderPass::insertEventMarker(const char* msg) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400105 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400106}
107
Stephen Whiteef2dc902019-08-26 15:19:42 -0400108void GrDawnOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400109 fPassEncoder.EndPass();
110 fPassEncoder = beginRenderPass(dawn::LoadOp::Load, dawn::LoadOp::Clear);
Stephen White985741a2019-07-18 11:43:45 -0400111}
112
Stephen Whiteef2dc902019-08-26 15:19:42 -0400113void GrDawnOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400114 fPassEncoder.EndPass();
115 fPassEncoder = beginRenderPass(dawn::LoadOp::Clear, dawn::LoadOp::Load);
Stephen White985741a2019-07-18 11:43:45 -0400116}
117
118////////////////////////////////////////////////////////////////////////////////
119
Stephen Whiteef2dc902019-08-26 15:19:42 -0400120void GrDawnOpsRenderPass::inlineUpload(GrOpFlushState* state,
121 GrDeferredTextureUploadFn& upload) {
Stephen Whitec0a837f2019-07-30 11:38:22 -0400122 SkASSERT(!"unimplemented");
Stephen White985741a2019-07-18 11:43:45 -0400123}
124
Stephen White985741a2019-07-18 11:43:45 -0400125////////////////////////////////////////////////////////////////////////////////
126
Stephen Whiteef2dc902019-08-26 15:19:42 -0400127void GrDawnOpsRenderPass::setScissorState(
Stephen White170d9902019-08-15 16:48:24 -0400128 const GrPipeline& pipeline,
129 const GrPipeline::FixedDynamicState* fixedDynamicState,
130 const GrPipeline::DynamicStateArrays* dynamicStateArrays) {
131 SkIRect rect;
132 if (pipeline.isScissorEnabled()) {
133 constexpr SkIRect kBogusScissor{0, 0, 1, 1};
134 rect = fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor;
135 if (kBottomLeft_GrSurfaceOrigin == fOrigin) {
136 rect.setXYWH(rect.x(), fRenderTarget->height() - rect.bottom(),
137 rect.width(), rect.height());
138 }
139 } else {
140 rect = SkIRect::MakeWH(fRenderTarget->width(), fRenderTarget->height());
141 }
142 fPassEncoder.SetScissorRect(rect.x(), rect.y(), rect.width(), rect.height());
143}
144
Stephen Whiteef2dc902019-08-26 15:19:42 -0400145void GrDawnOpsRenderPass::applyState(const GrPipeline& pipeline,
Stephen Whitef813ef72019-08-09 12:28:37 -0400146 const GrPrimitiveProcessor& primProc,
147 const GrTextureProxy* const primProcProxies[],
148 const GrPipeline::FixedDynamicState* fixedDynamicState,
149 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
150 const GrPrimitiveType primitiveType,
151 bool hasPoints) {
Stephen Whitee2641312019-08-29 15:10:50 -0400152 sk_sp<GrDawnProgram> program = fGpu->getOrCreateRenderPipeline(fRenderTarget,
153 fOrigin,
154 pipeline,
155 primProc,
156 primProcProxies,
157 hasPoints,
158 primitiveType);
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400159 auto bindGroup = program->setData(fGpu, fRenderTarget, fOrigin, primProc, pipeline,
160 primProcProxies);
Stephen Whitee2641312019-08-29 15:10:50 -0400161 fPassEncoder.SetPipeline(program->fRenderPipeline);
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400162 fPassEncoder.SetBindGroup(0, bindGroup, 0, nullptr);
Stephen Whitef813ef72019-08-09 12:28:37 -0400163 if (pipeline.isStencilEnabled()) {
164 fPassEncoder.SetStencilReference(pipeline.getUserStencil()->fFront.fRef);
165 }
Stephen White170d9902019-08-15 16:48:24 -0400166 GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
167 const float* c = blendInfo.fBlendConstant.vec();
168 dawn::Color color{c[0], c[1], c[2], c[3]};
169 fPassEncoder.SetBlendColor(&color);
170 this->setScissorState(pipeline, fixedDynamicState, dynamicStateArrays);
Stephen White985741a2019-07-18 11:43:45 -0400171}
172
Stephen Whiteef2dc902019-08-26 15:19:42 -0400173void GrDawnOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
174 const GrPipeline& pipeline,
175 const GrPipeline::FixedDynamicState* fixedDynamicState,
176 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
177 const GrMesh meshes[],
178 int meshCount,
179 const SkRect& bounds) {
Stephen White985741a2019-07-18 11:43:45 -0400180 if (!meshCount) {
181 return;
182 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400183 bool hasPoints = false;
Stephen White985741a2019-07-18 11:43:45 -0400184 for (int i = 0; i < meshCount; ++i) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400185 if (meshes[i].primitiveType() == GrPrimitiveType::kPoints) {
186 hasPoints = true;
187 }
Stephen White985741a2019-07-18 11:43:45 -0400188 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400189 const GrTextureProxy* const* primProcProxies = nullptr;
190 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
191 primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
192 } else if (fixedDynamicState) {
193 primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
194 }
Stephen Whited67c71f2019-08-06 11:15:41 -0400195 for (int i = 0; i < meshCount; ++i) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400196 applyState(pipeline, primProc, primProcProxies, fixedDynamicState, dynamicStateArrays,
197 meshes[0].primitiveType(), hasPoints);
Stephen Whited67c71f2019-08-06 11:15:41 -0400198 meshes[i].sendToGpu(this);
199 }
Stephen White985741a2019-07-18 11:43:45 -0400200}
201
Stephen Whiteef2dc902019-08-26 15:19:42 -0400202void GrDawnOpsRenderPass::sendInstancedMeshToGpu(GrPrimitiveType,
203 const GrBuffer* vertexBuffer,
204 int vertexCount,
205 int baseVertex,
206 const GrBuffer* instanceBuffer,
207 int instanceCount,
208 int baseInstance) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400209 static const uint64_t vertexBufferOffsets[1] = {0};
210 dawn::Buffer vb = static_cast<const GrDawnBuffer*>(vertexBuffer)->get();
211 fPassEncoder.SetVertexBuffers(0, 1, &vb, vertexBufferOffsets);
212 fPassEncoder.Draw(vertexCount, 1, baseVertex, baseInstance);
Stephen White985741a2019-07-18 11:43:45 -0400213 fGpu->stats()->incNumDraws();
214}
215
Stephen Whiteef2dc902019-08-26 15:19:42 -0400216void GrDawnOpsRenderPass::sendIndexedInstancedMeshToGpu(GrPrimitiveType,
217 const GrBuffer* indexBuffer,
218 int indexCount,
219 int baseIndex,
220 const GrBuffer* vertexBuffer,
221 int baseVertex,
222 const GrBuffer* instanceBuffer,
223 int instanceCount,
224 int baseInstance,
225 GrPrimitiveRestart restart) {
Stephen Whited67c71f2019-08-06 11:15:41 -0400226 uint64_t vertexBufferOffsets[1];
227 vertexBufferOffsets[0] = 0;
228 dawn::Buffer vb = static_cast<const GrDawnBuffer*>(vertexBuffer)->get();
229 dawn::Buffer ib = static_cast<const GrDawnBuffer*>(indexBuffer)->get();
230 fPassEncoder.SetIndexBuffer(ib, 0);
231 fPassEncoder.SetVertexBuffers(0, 1, &vb, vertexBufferOffsets);
232 fPassEncoder.DrawIndexed(indexCount, 1, baseIndex, baseVertex, baseInstance);
Stephen White985741a2019-07-18 11:43:45 -0400233 fGpu->stats()->incNumDraws();
234}