blob: 997d0f6722ab7f806f7728faf8939a7c5bf2bb50 [file] [log] [blame]
Stephen Whitebb6bed12019-08-02 09:57:55 -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
8#include "src/gpu/dawn/GrDawnProgramBuilder.h"
9
Brian Salomon201cdbb2019-08-14 17:00:30 -040010#include "src/gpu/GrRenderTarget.h"
Stephen Whitef813ef72019-08-09 12:28:37 -040011#include "src/gpu/GrShaderUtils.h"
12#include "src/gpu/GrStencilSettings.h"
Stephen Whitebb6bed12019-08-02 09:57:55 -040013#include "src/gpu/dawn/GrDawnGpu.h"
Stephen White170d9902019-08-15 16:48:24 -040014#include "src/gpu/dawn/GrDawnTexture.h"
Stephen Whitebb6bed12019-08-02 09:57:55 -040015#include "src/sksl/SkSLCompiler.h"
16
Stephen Whitebb6bed12019-08-02 09:57:55 -040017static SkSL::String sksl_to_spirv(const GrDawnGpu* gpu, const char* shaderString,
Stephen White20c626a2019-10-15 13:35:37 -040018 SkSL::Program::Kind kind, bool flipY,
19 SkSL::Program::Inputs* inputs) {
Stephen Whitebb6bed12019-08-02 09:57:55 -040020 SkSL::Program::Settings settings;
Stephen White170d9902019-08-15 16:48:24 -040021 settings.fCaps = gpu->caps()->shaderCaps();
Stephen White20c626a2019-10-15 13:35:37 -040022 settings.fFlipY = flipY;
Stephen Whitebb6bed12019-08-02 09:57:55 -040023 std::unique_ptr<SkSL::Program> program = gpu->shaderCompiler()->convertProgram(
24 kind,
25 shaderString,
26 settings);
27 if (!program) {
28 SkDebugf("SkSL error:\n%s\n", gpu->shaderCompiler()->errorText().c_str());
29 SkASSERT(false);
30 return "";
31 }
32 *inputs = program->fInputs;
33 SkSL::String code;
34 if (!gpu->shaderCompiler()->toSPIRV(*program, &code)) {
35 return "";
36 }
37 return code;
38}
39
Stephen White3cc8d4f2019-10-30 09:56:23 -040040static wgpu::BlendFactor to_dawn_blend_factor(GrBlendCoeff coeff) {
Stephen Whitebb6bed12019-08-02 09:57:55 -040041 switch (coeff) {
42 case kZero_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040043 return wgpu::BlendFactor::Zero;
Stephen Whitebb6bed12019-08-02 09:57:55 -040044 case kOne_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040045 return wgpu::BlendFactor::One;
Stephen Whitebb6bed12019-08-02 09:57:55 -040046 case kSC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040047 return wgpu::BlendFactor::SrcColor;
Stephen Whitebb6bed12019-08-02 09:57:55 -040048 case kISC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040049 return wgpu::BlendFactor::OneMinusSrcColor;
Stephen Whitebb6bed12019-08-02 09:57:55 -040050 case kDC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040051 return wgpu::BlendFactor::DstColor;
Stephen Whitebb6bed12019-08-02 09:57:55 -040052 case kIDC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040053 return wgpu::BlendFactor::OneMinusDstColor;
Stephen Whitebb6bed12019-08-02 09:57:55 -040054 case kSA_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040055 return wgpu::BlendFactor::SrcAlpha;
Stephen Whitebb6bed12019-08-02 09:57:55 -040056 case kISA_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040057 return wgpu::BlendFactor::OneMinusSrcAlpha;
Stephen Whitebb6bed12019-08-02 09:57:55 -040058 case kDA_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040059 return wgpu::BlendFactor::DstAlpha;
Stephen Whitebb6bed12019-08-02 09:57:55 -040060 case kIDA_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040061 return wgpu::BlendFactor::OneMinusDstAlpha;
Stephen Whitebb6bed12019-08-02 09:57:55 -040062 case kConstC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040063 return wgpu::BlendFactor::BlendColor;
Stephen Whitebb6bed12019-08-02 09:57:55 -040064 case kIConstC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040065 return wgpu::BlendFactor::OneMinusBlendColor;
Stephen Whitebb6bed12019-08-02 09:57:55 -040066 case kConstA_GrBlendCoeff:
67 case kIConstA_GrBlendCoeff:
68 case kS2C_GrBlendCoeff:
69 case kIS2C_GrBlendCoeff:
70 case kS2A_GrBlendCoeff:
71 case kIS2A_GrBlendCoeff:
72 default:
73 SkASSERT(!"unsupported blend coefficient");
Stephen White3cc8d4f2019-10-30 09:56:23 -040074 return wgpu::BlendFactor::One;
Stephen Whitebb6bed12019-08-02 09:57:55 -040075 }
76}
77
Stephen White3cc8d4f2019-10-30 09:56:23 -040078static wgpu::BlendFactor to_dawn_blend_factor_for_alpha(GrBlendCoeff coeff) {
Stephen Whitef813ef72019-08-09 12:28:37 -040079 switch (coeff) {
80 // Force all srcColor used in alpha slot to alpha version.
81 case kSC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040082 return wgpu::BlendFactor::SrcAlpha;
Stephen Whitef813ef72019-08-09 12:28:37 -040083 case kISC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040084 return wgpu::BlendFactor::OneMinusSrcAlpha;
Stephen Whitef813ef72019-08-09 12:28:37 -040085 case kDC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040086 return wgpu::BlendFactor::DstAlpha;
Stephen Whitef813ef72019-08-09 12:28:37 -040087 case kIDC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040088 return wgpu::BlendFactor::OneMinusDstAlpha;
Stephen Whitef813ef72019-08-09 12:28:37 -040089 default:
90 return to_dawn_blend_factor(coeff);
91 }
92}
93
Stephen White3cc8d4f2019-10-30 09:56:23 -040094static wgpu::BlendOperation to_dawn_blend_operation(GrBlendEquation equation) {
Stephen Whitebb6bed12019-08-02 09:57:55 -040095 switch (equation) {
96 case kAdd_GrBlendEquation:
Stephen White3cc8d4f2019-10-30 09:56:23 -040097 return wgpu::BlendOperation::Add;
Stephen Whitebb6bed12019-08-02 09:57:55 -040098 case kSubtract_GrBlendEquation:
Stephen White3cc8d4f2019-10-30 09:56:23 -040099 return wgpu::BlendOperation::Subtract;
Stephen Whitef813ef72019-08-09 12:28:37 -0400100 case kReverseSubtract_GrBlendEquation:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400101 return wgpu::BlendOperation::ReverseSubtract;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400102 default:
103 SkASSERT(!"unsupported blend equation");
Stephen White3cc8d4f2019-10-30 09:56:23 -0400104 return wgpu::BlendOperation::Add;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400105 }
106}
107
Stephen White3cc8d4f2019-10-30 09:56:23 -0400108static wgpu::CompareFunction to_dawn_compare_function(GrStencilTest test) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400109 switch (test) {
110 case GrStencilTest::kAlways:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400111 return wgpu::CompareFunction::Always;
Stephen Whitef813ef72019-08-09 12:28:37 -0400112 case GrStencilTest::kNever:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400113 return wgpu::CompareFunction::Never;
Stephen Whitef813ef72019-08-09 12:28:37 -0400114 case GrStencilTest::kGreater:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400115 return wgpu::CompareFunction::Greater;
Stephen Whitef813ef72019-08-09 12:28:37 -0400116 case GrStencilTest::kGEqual:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400117 return wgpu::CompareFunction::GreaterEqual;
Stephen Whitef813ef72019-08-09 12:28:37 -0400118 case GrStencilTest::kLess:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400119 return wgpu::CompareFunction::Less;
Stephen Whitef813ef72019-08-09 12:28:37 -0400120 case GrStencilTest::kLEqual:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400121 return wgpu::CompareFunction::LessEqual;
Stephen Whitef813ef72019-08-09 12:28:37 -0400122 case GrStencilTest::kEqual:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400123 return wgpu::CompareFunction::Equal;
Stephen Whitef813ef72019-08-09 12:28:37 -0400124 case GrStencilTest::kNotEqual:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400125 return wgpu::CompareFunction::NotEqual;
Stephen Whitef813ef72019-08-09 12:28:37 -0400126 default:
127 SkASSERT(!"unsupported stencil test");
Stephen White3cc8d4f2019-10-30 09:56:23 -0400128 return wgpu::CompareFunction::Always;
Stephen Whitef813ef72019-08-09 12:28:37 -0400129 }
130}
131
Stephen White3cc8d4f2019-10-30 09:56:23 -0400132static wgpu::StencilOperation to_dawn_stencil_operation(GrStencilOp op) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400133 switch (op) {
134 case GrStencilOp::kKeep:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400135 return wgpu::StencilOperation::Keep;
Stephen Whitef813ef72019-08-09 12:28:37 -0400136 case GrStencilOp::kZero:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400137 return wgpu::StencilOperation::Zero;
Stephen Whitef813ef72019-08-09 12:28:37 -0400138 case GrStencilOp::kReplace:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400139 return wgpu::StencilOperation::Replace;
Stephen Whitef813ef72019-08-09 12:28:37 -0400140 case GrStencilOp::kInvert:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400141 return wgpu::StencilOperation::Invert;
Stephen Whitef813ef72019-08-09 12:28:37 -0400142 case GrStencilOp::kIncClamp:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400143 return wgpu::StencilOperation::IncrementClamp;
Stephen Whitef813ef72019-08-09 12:28:37 -0400144 case GrStencilOp::kDecClamp:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400145 return wgpu::StencilOperation::DecrementClamp;
Stephen Whitef813ef72019-08-09 12:28:37 -0400146 case GrStencilOp::kIncWrap:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400147 return wgpu::StencilOperation::IncrementWrap;
Stephen Whitef813ef72019-08-09 12:28:37 -0400148 case GrStencilOp::kDecWrap:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400149 return wgpu::StencilOperation::DecrementWrap;
Stephen Whitef813ef72019-08-09 12:28:37 -0400150 default:
151 SkASSERT(!"unsupported stencil function");
Stephen White3cc8d4f2019-10-30 09:56:23 -0400152 return wgpu::StencilOperation::Keep;
Stephen Whitef813ef72019-08-09 12:28:37 -0400153 }
154}
155
Stephen White3cc8d4f2019-10-30 09:56:23 -0400156static wgpu::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primitiveType) {
Stephen Whitee2641312019-08-29 15:10:50 -0400157 switch (primitiveType) {
158 case GrPrimitiveType::kTriangles:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400159 return wgpu::PrimitiveTopology::TriangleList;
Stephen Whitee2641312019-08-29 15:10:50 -0400160 case GrPrimitiveType::kTriangleStrip:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400161 return wgpu::PrimitiveTopology::TriangleStrip;
Stephen Whitee2641312019-08-29 15:10:50 -0400162 case GrPrimitiveType::kPoints:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400163 return wgpu::PrimitiveTopology::PointList;
Stephen Whitee2641312019-08-29 15:10:50 -0400164 case GrPrimitiveType::kLines:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400165 return wgpu::PrimitiveTopology::LineList;
Stephen Whitee2641312019-08-29 15:10:50 -0400166 case GrPrimitiveType::kLineStrip:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400167 return wgpu::PrimitiveTopology::LineStrip;
Robert Phillips571177f2019-10-04 14:41:49 -0400168 case GrPrimitiveType::kPath:
Stephen Whitee2641312019-08-29 15:10:50 -0400169 default:
170 SkASSERT(!"unsupported primitive topology");
Stephen White3cc8d4f2019-10-30 09:56:23 -0400171 return wgpu::PrimitiveTopology::TriangleList;
Stephen Whitee2641312019-08-29 15:10:50 -0400172 }
173}
174
Stephen White3cc8d4f2019-10-30 09:56:23 -0400175static wgpu::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
Stephen Whitee2641312019-08-29 15:10:50 -0400176 switch (type) {
177 case kFloat_GrVertexAttribType:
178 case kHalf_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400179 return wgpu::VertexFormat::Float;
Stephen Whitee2641312019-08-29 15:10:50 -0400180 case kFloat2_GrVertexAttribType:
181 case kHalf2_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400182 return wgpu::VertexFormat::Float2;
Stephen Whitee2641312019-08-29 15:10:50 -0400183 case kFloat3_GrVertexAttribType:
184 case kHalf3_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400185 return wgpu::VertexFormat::Float3;
Stephen Whitee2641312019-08-29 15:10:50 -0400186 case kFloat4_GrVertexAttribType:
187 case kHalf4_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400188 return wgpu::VertexFormat::Float4;
Stephen Whitee2641312019-08-29 15:10:50 -0400189 case kUShort2_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400190 return wgpu::VertexFormat::UShort2;
Stephen Whitee2641312019-08-29 15:10:50 -0400191 case kInt_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400192 return wgpu::VertexFormat::Int;
Stephen Whitee2641312019-08-29 15:10:50 -0400193 case kUByte4_norm_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400194 return wgpu::VertexFormat::UChar4Norm;
Stephen Whitee2641312019-08-29 15:10:50 -0400195 default:
196 SkASSERT(!"unsupported vertex format");
Stephen White3cc8d4f2019-10-30 09:56:23 -0400197 return wgpu::VertexFormat::Float4;
Stephen Whitee2641312019-08-29 15:10:50 -0400198 }
199}
200
Stephen White3cc8d4f2019-10-30 09:56:23 -0400201static wgpu::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400202 const GrPipeline& pipeline,
Stephen White3cc8d4f2019-10-30 09:56:23 -0400203 wgpu::TextureFormat colorFormat) {
Stephen Whitebb6bed12019-08-02 09:57:55 -0400204 GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
205 GrBlendEquation equation = blendInfo.fEquation;
206 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
207 GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
208
Stephen White3cc8d4f2019-10-30 09:56:23 -0400209 wgpu::BlendFactor srcFactor = to_dawn_blend_factor(srcCoeff);
210 wgpu::BlendFactor dstFactor = to_dawn_blend_factor(dstCoeff);
211 wgpu::BlendFactor srcFactorAlpha = to_dawn_blend_factor_for_alpha(srcCoeff);
212 wgpu::BlendFactor dstFactorAlpha = to_dawn_blend_factor_for_alpha(dstCoeff);
213 wgpu::BlendOperation operation = to_dawn_blend_operation(equation);
214 auto mask = blendInfo.fWriteColor ? wgpu::ColorWriteMask::All : wgpu::ColorWriteMask::None;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400215
Stephen White3cc8d4f2019-10-30 09:56:23 -0400216 wgpu::BlendDescriptor colorDesc = {operation, srcFactor, dstFactor};
217 wgpu::BlendDescriptor alphaDesc = {operation, srcFactorAlpha, dstFactorAlpha};
Stephen Whitebb6bed12019-08-02 09:57:55 -0400218
Stephen White3cc8d4f2019-10-30 09:56:23 -0400219 wgpu::ColorStateDescriptor descriptor;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400220 descriptor.format = colorFormat;
221 descriptor.alphaBlend = alphaDesc;
222 descriptor.colorBlend = colorDesc;
223 descriptor.nextInChain = nullptr;
224 descriptor.writeMask = mask;
225
226 return descriptor;
227}
228
Stephen White3cc8d4f2019-10-30 09:56:23 -0400229static wgpu::StencilStateFaceDescriptor to_stencil_state_face(const GrStencilSettings::Face& face) {
230 wgpu::StencilStateFaceDescriptor desc;
Stephen Whitef813ef72019-08-09 12:28:37 -0400231 desc.compare = to_dawn_compare_function(face.fTest);
232 desc.failOp = desc.depthFailOp = to_dawn_stencil_operation(face.fFailOp);
233 desc.passOp = to_dawn_stencil_operation(face.fPassOp);
234 return desc;
235}
236
Stephen White3cc8d4f2019-10-30 09:56:23 -0400237static wgpu::DepthStencilStateDescriptor create_depth_stencil_state(
Stephen Whitef813ef72019-08-09 12:28:37 -0400238 const GrStencilSettings& stencilSettings,
Stephen White3cc8d4f2019-10-30 09:56:23 -0400239 wgpu::TextureFormat depthStencilFormat,
Stephen Whitef813ef72019-08-09 12:28:37 -0400240 GrSurfaceOrigin origin) {
Stephen White3cc8d4f2019-10-30 09:56:23 -0400241 wgpu::DepthStencilStateDescriptor state;
Stephen Whitef813ef72019-08-09 12:28:37 -0400242 state.format = depthStencilFormat;
Stephen Whitee2641312019-08-29 15:10:50 -0400243 if (!stencilSettings.isDisabled()) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400244 if (stencilSettings.isTwoSided()) {
Stephen Whitef4b3d6b2019-10-18 07:54:25 -0400245 auto front = stencilSettings.front(origin);
246 auto back = stencilSettings.front(origin);
247 state.stencilFront = to_stencil_state_face(front);
248 state.stencilBack = to_stencil_state_face(back);
249 state.stencilReadMask = front.fTestMask;
250 state.stencilWriteMask = front.fWriteMask;
Stephen Whitef813ef72019-08-09 12:28:37 -0400251 } else {
Stephen Whitef4b3d6b2019-10-18 07:54:25 -0400252 auto frontAndBack = stencilSettings.frontAndBack();
253 state.stencilBack = state.stencilFront = to_stencil_state_face(frontAndBack);
254 state.stencilReadMask = frontAndBack.fTestMask;
255 state.stencilWriteMask = frontAndBack.fWriteMask;
Stephen Whitef813ef72019-08-09 12:28:37 -0400256 }
257 }
258 return state;
259}
260
Stephen White3cc8d4f2019-10-30 09:56:23 -0400261static wgpu::BindGroupBinding make_bind_group_binding(uint32_t binding, const wgpu::Buffer& buffer,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400262 uint32_t offset, uint32_t size, const
Stephen White3cc8d4f2019-10-30 09:56:23 -0400263 wgpu::Sampler& sampler,
264 const wgpu::TextureView& textureView) {
265 wgpu::BindGroupBinding result;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400266 result.binding = binding;
267 result.buffer = buffer;
268 result.offset = offset;
269 result.size = size;
270 result.sampler = sampler;
271 result.textureView = textureView;
272 return result;
273}
274
Stephen White3cc8d4f2019-10-30 09:56:23 -0400275static wgpu::BindGroupBinding make_bind_group_binding(uint32_t binding, const wgpu::Buffer& buffer,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400276 uint32_t offset, uint32_t size) {
277 return make_bind_group_binding(binding, buffer, offset, size, nullptr, nullptr);
278}
279
Stephen White3cc8d4f2019-10-30 09:56:23 -0400280static wgpu::BindGroupBinding make_bind_group_binding(uint32_t binding,
281 const wgpu::Sampler& sampler) {
Stephen White170d9902019-08-15 16:48:24 -0400282 return make_bind_group_binding(binding, nullptr, 0, 0, sampler, nullptr);
283}
284
Stephen White3cc8d4f2019-10-30 09:56:23 -0400285static wgpu::BindGroupBinding make_bind_group_binding(uint32_t binding,
286 const wgpu::TextureView& textureView) {
Stephen White170d9902019-08-15 16:48:24 -0400287 return make_bind_group_binding(binding, nullptr, 0, 0, nullptr, textureView);
288}
289
Stephen Whitebb6bed12019-08-02 09:57:55 -0400290sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
291 GrRenderTarget* renderTarget,
Stephen White729c78d2019-10-14 12:42:59 -0400292 const GrProgramInfo& programInfo,
Stephen Whitee2641312019-08-29 15:10:50 -0400293 GrPrimitiveType primitiveType,
Stephen White3cc8d4f2019-10-30 09:56:23 -0400294 wgpu::TextureFormat colorFormat,
Stephen Whitef813ef72019-08-09 12:28:37 -0400295 bool hasDepthStencil,
Stephen White3cc8d4f2019-10-30 09:56:23 -0400296 wgpu::TextureFormat depthStencilFormat,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400297 GrProgramDesc* desc) {
Stephen White729c78d2019-10-14 12:42:59 -0400298 GrDawnProgramBuilder builder(gpu, renderTarget, programInfo, desc);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400299 if (!builder.emitAndInstallProcs()) {
300 return nullptr;
301 }
302
303 builder.fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
304 builder.fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
305 builder.fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
306 builder.fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
307
308 builder.finalizeShaders();
309
310 SkSL::Program::Inputs vertInputs, fragInputs;
311 GrDawnUniformHandler::UniformInfoArray& uniforms = builder.fUniformHandler.fUniforms;
Stephen Whitedd78efd2019-10-23 15:00:20 -0400312 uint32_t uniformBufferSize = builder.fUniformHandler.fCurrentUBOOffset;
313 sk_sp<GrDawnProgram> result(new GrDawnProgram(uniforms, uniformBufferSize));
Stephen White20c626a2019-10-15 13:35:37 -0400314 bool flipY = programInfo.origin() != kTopLeft_GrSurfaceOrigin;
315 auto vsModule = builder.createShaderModule(builder.fVS, SkSL::Program::kVertex_Kind, flipY,
Stephen Whitee2641312019-08-29 15:10:50 -0400316 &vertInputs);
Stephen White20c626a2019-10-15 13:35:37 -0400317 auto fsModule = builder.createShaderModule(builder.fFS, SkSL::Program::kFragment_Kind, flipY,
Stephen Whitee2641312019-08-29 15:10:50 -0400318 &fragInputs);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400319 result->fGeometryProcessor = std::move(builder.fGeometryProcessor);
320 result->fXferProcessor = std::move(builder.fXferProcessor);
321 result->fFragmentProcessors = std::move(builder.fFragmentProcessors);
322 result->fFragmentProcessorCnt = builder.fFragmentProcessorCnt;
Stephen White3cc8d4f2019-10-30 09:56:23 -0400323 std::vector<wgpu::BindGroupLayoutBinding> layoutBindings;
Stephen Whitedd78efd2019-10-23 15:00:20 -0400324 if (0 != uniformBufferSize) {
325 layoutBindings.push_back({ GrDawnUniformHandler::kUniformBinding,
Stephen White3cc8d4f2019-10-30 09:56:23 -0400326 wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
327 wgpu::BindingType::UniformBuffer});
Stephen White170d9902019-08-15 16:48:24 -0400328 }
329 uint32_t binding = GrDawnUniformHandler::kSamplerBindingBase;
330 for (int i = 0; i < builder.fUniformHandler.fSamplers.count(); ++i) {
Stephen White3cc8d4f2019-10-30 09:56:23 -0400331 layoutBindings.push_back({ binding++, wgpu::ShaderStage::Fragment,
332 wgpu::BindingType::Sampler});
333 layoutBindings.push_back({ binding++, wgpu::ShaderStage::Fragment,
334 wgpu::BindingType::SampledTexture});
Stephen White170d9902019-08-15 16:48:24 -0400335 }
Stephen White3cc8d4f2019-10-30 09:56:23 -0400336 wgpu::BindGroupLayoutDescriptor bindGroupLayoutDesc;
Stephen White170d9902019-08-15 16:48:24 -0400337 bindGroupLayoutDesc.bindingCount = layoutBindings.size();
338 bindGroupLayoutDesc.bindings = layoutBindings.data();
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400339 result->fBindGroupLayout = gpu->device().CreateBindGroupLayout(&bindGroupLayoutDesc);
Stephen White3cc8d4f2019-10-30 09:56:23 -0400340 wgpu::PipelineLayoutDescriptor pipelineLayoutDesc;
Stephen White170d9902019-08-15 16:48:24 -0400341 pipelineLayoutDesc.bindGroupLayoutCount = 1;
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400342 pipelineLayoutDesc.bindGroupLayouts = &result->fBindGroupLayout;
Stephen Whitee2641312019-08-29 15:10:50 -0400343 auto pipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400344 result->fBuiltinUniformHandles = builder.fUniformHandles;
Stephen White729c78d2019-10-14 12:42:59 -0400345 const GrPipeline& pipeline = programInfo.pipeline();
Stephen Whitee2641312019-08-29 15:10:50 -0400346 auto colorState = create_color_state(gpu, pipeline, colorFormat);
Stephen White3cc8d4f2019-10-30 09:56:23 -0400347 wgpu::DepthStencilStateDescriptor depthStencilState;
Stephen Whitef813ef72019-08-09 12:28:37 -0400348 GrStencilSettings stencil;
349 if (pipeline.isStencilEnabled()) {
350 int numStencilBits = renderTarget->renderTargetPriv().numStencilBits();
351 stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(), numStencilBits);
352 }
Stephen White729c78d2019-10-14 12:42:59 -0400353 depthStencilState = create_depth_stencil_state(stencil, depthStencilFormat,
354 programInfo.origin());
Stephen Whitee2641312019-08-29 15:10:50 -0400355
Stephen White3cc8d4f2019-10-30 09:56:23 -0400356 std::vector<wgpu::VertexBufferDescriptor> inputs;
Stephen Whitee2641312019-08-29 15:10:50 -0400357
Stephen White3cc8d4f2019-10-30 09:56:23 -0400358 std::vector<wgpu::VertexAttributeDescriptor> vertexAttributes;
Stephen White729c78d2019-10-14 12:42:59 -0400359 const GrPrimitiveProcessor& primProc = programInfo.primProc();
Stephen Whitee2641312019-08-29 15:10:50 -0400360 if (primProc.numVertexAttributes() > 0) {
361 size_t offset = 0;
362 int i = 0;
363 for (const auto& attrib : primProc.vertexAttributes()) {
Stephen White3cc8d4f2019-10-30 09:56:23 -0400364 wgpu::VertexAttributeDescriptor attribute;
Stephen Whitee2641312019-08-29 15:10:50 -0400365 attribute.shaderLocation = i;
366 attribute.offset = offset;
367 attribute.format = to_dawn_vertex_format(attrib.cpuType());
368 vertexAttributes.push_back(attribute);
369 offset += attrib.sizeAlign4();
370 i++;
371 }
Stephen White3cc8d4f2019-10-30 09:56:23 -0400372 wgpu::VertexBufferDescriptor input;
Stephen Whitee2641312019-08-29 15:10:50 -0400373 input.stride = offset;
Stephen White3cc8d4f2019-10-30 09:56:23 -0400374 input.stepMode = wgpu::InputStepMode::Vertex;
Stephen Whitee2641312019-08-29 15:10:50 -0400375 input.attributeCount = vertexAttributes.size();
376 input.attributes = &vertexAttributes.front();
377 inputs.push_back(input);
378 }
Stephen White3cc8d4f2019-10-30 09:56:23 -0400379 std::vector<wgpu::VertexAttributeDescriptor> instanceAttributes;
Stephen Whitee2641312019-08-29 15:10:50 -0400380 if (primProc.numInstanceAttributes() > 0) {
381 size_t offset = 0;
382 int i = 0;
383 for (const auto& attrib : primProc.instanceAttributes()) {
Stephen White3cc8d4f2019-10-30 09:56:23 -0400384 wgpu::VertexAttributeDescriptor attribute;
Stephen Whitee2641312019-08-29 15:10:50 -0400385 attribute.shaderLocation = i;
386 attribute.offset = offset;
387 attribute.format = to_dawn_vertex_format(attrib.cpuType());
388 instanceAttributes.push_back(attribute);
389 offset += attrib.sizeAlign4();
390 i++;
391 }
Stephen White3cc8d4f2019-10-30 09:56:23 -0400392 wgpu::VertexBufferDescriptor input;
Stephen Whitee2641312019-08-29 15:10:50 -0400393 input.stride = offset;
Stephen White3cc8d4f2019-10-30 09:56:23 -0400394 input.stepMode = wgpu::InputStepMode::Instance;
Stephen Whitee2641312019-08-29 15:10:50 -0400395 input.attributeCount = instanceAttributes.size();
396 input.attributes = &instanceAttributes.front();
397 inputs.push_back(input);
398 }
Stephen White3cc8d4f2019-10-30 09:56:23 -0400399 wgpu::VertexInputDescriptor vertexInput;
400 vertexInput.indexFormat = wgpu::IndexFormat::Uint16;
Stephen Whitee2641312019-08-29 15:10:50 -0400401 vertexInput.bufferCount = inputs.size();
402 vertexInput.buffers = &inputs.front();
403
Stephen White3cc8d4f2019-10-30 09:56:23 -0400404 wgpu::ProgrammableStageDescriptor vsDesc;
Stephen Whitee2641312019-08-29 15:10:50 -0400405 vsDesc.module = vsModule;
406 vsDesc.entryPoint = "main";
407
Stephen White3cc8d4f2019-10-30 09:56:23 -0400408 wgpu::ProgrammableStageDescriptor fsDesc;
Stephen Whitee2641312019-08-29 15:10:50 -0400409 fsDesc.module = fsModule;
410 fsDesc.entryPoint = "main";
411
Stephen White3cc8d4f2019-10-30 09:56:23 -0400412 wgpu::RenderPipelineDescriptor rpDesc;
Stephen Whitee2641312019-08-29 15:10:50 -0400413 rpDesc.layout = pipelineLayout;
Stephen White20c626a2019-10-15 13:35:37 -0400414 rpDesc.vertexStage = vsDesc;
Stephen Whitee2641312019-08-29 15:10:50 -0400415 rpDesc.fragmentStage = &fsDesc;
416 rpDesc.vertexInput = &vertexInput;
417 rpDesc.primitiveTopology = to_dawn_primitive_topology(primitiveType);
418 if (hasDepthStencil) {
419 rpDesc.depthStencilState = &depthStencilState;
420 }
421 rpDesc.colorStateCount = 1;
Stephen White20c626a2019-10-15 13:35:37 -0400422 rpDesc.colorStates = &colorState;
Stephen Whitee2641312019-08-29 15:10:50 -0400423 result->fRenderPipeline = gpu->device().CreateRenderPipeline(&rpDesc);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400424 return result;
425}
426
427GrDawnProgramBuilder::GrDawnProgramBuilder(GrDawnGpu* gpu,
428 GrRenderTarget* renderTarget,
Stephen White729c78d2019-10-14 12:42:59 -0400429 const GrProgramInfo& programInfo,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400430 GrProgramDesc* desc)
Stephen White729c78d2019-10-14 12:42:59 -0400431 : INHERITED(renderTarget, programInfo, desc)
Stephen Whitebb6bed12019-08-02 09:57:55 -0400432 , fGpu(gpu)
433 , fVaryingHandler(this)
434 , fUniformHandler(this) {
435}
436
Stephen White3cc8d4f2019-10-30 09:56:23 -0400437wgpu::ShaderModule GrDawnProgramBuilder::createShaderModule(const GrGLSLShaderBuilder& builder,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400438 SkSL::Program::Kind kind,
Stephen White20c626a2019-10-15 13:35:37 -0400439 bool flipY,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400440 SkSL::Program::Inputs* inputs) {
Stephen White3cc8d4f2019-10-30 09:56:23 -0400441 wgpu::Device device = fGpu->device();
Stephen Whitebb6bed12019-08-02 09:57:55 -0400442 SkString source(builder.fCompilerString.c_str());
443
444#if 0
445 SkSL::String sksl = GrShaderUtils::PrettyPrint(builder.fCompilerString);
446 printf("converting program:\n%s\n", sksl.c_str());
447#endif
448
Stephen White20c626a2019-10-15 13:35:37 -0400449 SkSL::String spirvSource = sksl_to_spirv(fGpu, source.c_str(), kind, flipY, inputs);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400450
Stephen White3cc8d4f2019-10-30 09:56:23 -0400451 wgpu::ShaderModuleDescriptor desc;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400452 desc.codeSize = spirvSource.size() / 4;
453 desc.code = reinterpret_cast<const uint32_t*>(spirvSource.c_str());
454
455 return device.CreateShaderModule(&desc);
456};
457
458const GrCaps* GrDawnProgramBuilder::caps() const {
459 return fGpu->caps();
460}
461
462void GrDawnProgram::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
463 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
464 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
465 fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
466 fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
467 }
468
469 // set RT adjustment
Brian Salomon9f2b86c2019-10-22 10:37:46 -0400470 SkISize dimensions = rt->dimensions();
Stephen Whitebb6bed12019-08-02 09:57:55 -0400471 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
472 if (fRenderTargetState.fRenderTargetOrigin != origin ||
Brian Salomon9f2b86c2019-10-22 10:37:46 -0400473 fRenderTargetState.fRenderTargetSize != dimensions) {
474 fRenderTargetState.fRenderTargetSize = dimensions;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400475 fRenderTargetState.fRenderTargetOrigin = origin;
476
477 float rtAdjustmentVec[4];
478 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
479 fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
480 }
481}
482
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400483static void setTexture(GrDawnGpu* gpu, const GrSamplerState& state, GrTexture* texture,
Stephen White3cc8d4f2019-10-30 09:56:23 -0400484 std::vector<wgpu::BindGroupBinding> *bindings, int* binding) {
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400485 // FIXME: could probably cache samplers in GrDawnProgram
Stephen White3cc8d4f2019-10-30 09:56:23 -0400486 wgpu::Sampler sampler = gpu->getOrCreateSampler(state);
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400487 bindings->push_back(make_bind_group_binding((*binding)++, sampler));
488 GrDawnTexture* tex = static_cast<GrDawnTexture*>(texture);
Stephen White3cc8d4f2019-10-30 09:56:23 -0400489 wgpu::TextureView textureView = tex->textureView();
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400490 bindings->push_back(make_bind_group_binding((*binding)++, textureView));
491}
492
Stephen White3cc8d4f2019-10-30 09:56:23 -0400493wgpu::BindGroup GrDawnProgram::setData(GrDawnGpu* gpu, const GrRenderTarget* renderTarget,
Stephen White729c78d2019-10-14 12:42:59 -0400494 const GrProgramInfo& programInfo) {
Stephen White3cc8d4f2019-10-30 09:56:23 -0400495 std::vector<wgpu::BindGroupBinding> bindings;
Stephen Whitedd78efd2019-10-23 15:00:20 -0400496 GrDawnRingBuffer::Slice slice;
497 uint32_t uniformBufferSize = fDataManager.uniformBufferSize();
498 if (0 != uniformBufferSize) {
499 slice = gpu->allocateUniformRingBufferSlice(uniformBufferSize);
500 bindings.push_back(make_bind_group_binding(GrDawnUniformHandler::kUniformBinding,
501 slice.fBuffer, slice.fOffset,
502 uniformBufferSize));
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400503 }
Stephen White729c78d2019-10-14 12:42:59 -0400504 this->setRenderTargetState(renderTarget, programInfo.origin());
505 const GrPipeline& pipeline = programInfo.pipeline();
506 const GrPrimitiveProcessor& primProc = programInfo.primProc();
Stephen Whitebb6bed12019-08-02 09:57:55 -0400507 fGeometryProcessor->setData(fDataManager, primProc,
508 GrFragmentProcessor::CoordTransformIter(pipeline));
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400509 int binding = GrDawnUniformHandler::kSamplerBindingBase;
Stephen White729c78d2019-10-14 12:42:59 -0400510 auto primProcTextures = programInfo.hasFixedPrimProcTextures() ?
511 programInfo.fixedPrimProcTextures() : nullptr;
512
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400513 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
514 auto& sampler = primProc.textureSampler(i);
515 setTexture(gpu, sampler.samplerState(), primProcTextures[i]->peekTexture(), &bindings,
516 &binding);
517 }
Stephen Whitebb6bed12019-08-02 09:57:55 -0400518 GrFragmentProcessor::Iter iter(pipeline);
519 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
520 const GrFragmentProcessor* fp = iter.next();
521 GrGLSLFragmentProcessor* glslFP = glslIter.next();
522 while (fp && glslFP) {
523 glslFP->setData(fDataManager, *fp);
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400524 for (int i = 0; i < fp->numTextureSamplers(); ++i) {
525 auto& s = fp->textureSampler(i);
526 setTexture(gpu, s.samplerState(), s.peekTexture(), &bindings, &binding);
527 }
Stephen Whitebb6bed12019-08-02 09:57:55 -0400528 fp = iter.next();
529 glslFP = glslIter.next();
530 }
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400531 SkIPoint offset;
532 GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
533 fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
534 if (GrTextureProxy* proxy = pipeline.dstTextureProxy()) {
535 GrFragmentProcessor::TextureSampler sampler(sk_ref_sp(proxy));
536 setTexture(gpu, sampler.samplerState(), sampler.peekTexture(), &bindings, &binding);
537 }
Stephen Whitedd78efd2019-10-23 15:00:20 -0400538 fDataManager.uploadUniformBuffers(gpu, slice);
Stephen White3cc8d4f2019-10-30 09:56:23 -0400539 wgpu::BindGroupDescriptor descriptor;
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400540 descriptor.layout = fBindGroupLayout;
541 descriptor.bindingCount = bindings.size();
542 descriptor.bindings = bindings.data();
543 return gpu->device().CreateBindGroup(&descriptor);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400544}