blob: 106740fa0a47c6667f69582a8c94c42a55532cd9 [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 White40c47e12019-11-01 13:13:03 -040018 SkSL::Program::Kind kind, bool flipY, uint32_t rtHeightOffset,
Stephen White20c626a2019-10-15 13:35:37 -040019 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 White40c47e12019-11-01 13:13:03 -040023 settings.fRTHeightOffset = rtHeightOffset;
Stephen Whitebb6bed12019-08-02 09:57:55 -040024 std::unique_ptr<SkSL::Program> program = gpu->shaderCompiler()->convertProgram(
25 kind,
26 shaderString,
27 settings);
28 if (!program) {
29 SkDebugf("SkSL error:\n%s\n", gpu->shaderCompiler()->errorText().c_str());
30 SkASSERT(false);
31 return "";
32 }
33 *inputs = program->fInputs;
34 SkSL::String code;
35 if (!gpu->shaderCompiler()->toSPIRV(*program, &code)) {
36 return "";
37 }
38 return code;
39}
40
Stephen White3cc8d4f2019-10-30 09:56:23 -040041static wgpu::BlendFactor to_dawn_blend_factor(GrBlendCoeff coeff) {
Stephen Whitebb6bed12019-08-02 09:57:55 -040042 switch (coeff) {
Greg Daniel6e2af5c2020-03-30 15:07:05 -040043 case kZero_GrBlendCoeff:
44 return wgpu::BlendFactor::Zero;
45 case kOne_GrBlendCoeff:
46 return wgpu::BlendFactor::One;
47 case kSC_GrBlendCoeff:
48 return wgpu::BlendFactor::SrcColor;
49 case kISC_GrBlendCoeff:
50 return wgpu::BlendFactor::OneMinusSrcColor;
51 case kDC_GrBlendCoeff:
52 return wgpu::BlendFactor::DstColor;
53 case kIDC_GrBlendCoeff:
54 return wgpu::BlendFactor::OneMinusDstColor;
55 case kSA_GrBlendCoeff:
56 return wgpu::BlendFactor::SrcAlpha;
57 case kISA_GrBlendCoeff:
58 return wgpu::BlendFactor::OneMinusSrcAlpha;
59 case kDA_GrBlendCoeff:
60 return wgpu::BlendFactor::DstAlpha;
61 case kIDA_GrBlendCoeff:
62 return wgpu::BlendFactor::OneMinusDstAlpha;
63 case kConstC_GrBlendCoeff:
64 return wgpu::BlendFactor::BlendColor;
65 case kIConstC_GrBlendCoeff:
66 return wgpu::BlendFactor::OneMinusBlendColor;
67 case kS2C_GrBlendCoeff:
68 case kIS2C_GrBlendCoeff:
69 case kS2A_GrBlendCoeff:
70 case kIS2A_GrBlendCoeff:
71 default:
72 SkASSERT(!"unsupported blend coefficient");
73 return wgpu::BlendFactor::One;
74 }
Stephen Whitebb6bed12019-08-02 09:57:55 -040075}
76
Stephen White3cc8d4f2019-10-30 09:56:23 -040077static wgpu::BlendFactor to_dawn_blend_factor_for_alpha(GrBlendCoeff coeff) {
Stephen Whitef813ef72019-08-09 12:28:37 -040078 switch (coeff) {
79 // Force all srcColor used in alpha slot to alpha version.
80 case kSC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040081 return wgpu::BlendFactor::SrcAlpha;
Stephen Whitef813ef72019-08-09 12:28:37 -040082 case kISC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040083 return wgpu::BlendFactor::OneMinusSrcAlpha;
Stephen Whitef813ef72019-08-09 12:28:37 -040084 case kDC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040085 return wgpu::BlendFactor::DstAlpha;
Stephen Whitef813ef72019-08-09 12:28:37 -040086 case kIDC_GrBlendCoeff:
Stephen White3cc8d4f2019-10-30 09:56:23 -040087 return wgpu::BlendFactor::OneMinusDstAlpha;
Stephen Whitef813ef72019-08-09 12:28:37 -040088 default:
89 return to_dawn_blend_factor(coeff);
90 }
91}
92
Stephen White3cc8d4f2019-10-30 09:56:23 -040093static wgpu::BlendOperation to_dawn_blend_operation(GrBlendEquation equation) {
Stephen Whitebb6bed12019-08-02 09:57:55 -040094 switch (equation) {
95 case kAdd_GrBlendEquation:
Stephen White3cc8d4f2019-10-30 09:56:23 -040096 return wgpu::BlendOperation::Add;
Stephen Whitebb6bed12019-08-02 09:57:55 -040097 case kSubtract_GrBlendEquation:
Stephen White3cc8d4f2019-10-30 09:56:23 -040098 return wgpu::BlendOperation::Subtract;
Stephen Whitef813ef72019-08-09 12:28:37 -040099 case kReverseSubtract_GrBlendEquation:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400100 return wgpu::BlendOperation::ReverseSubtract;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400101 default:
102 SkASSERT(!"unsupported blend equation");
Stephen White3cc8d4f2019-10-30 09:56:23 -0400103 return wgpu::BlendOperation::Add;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400104 }
105}
106
Stephen White3cc8d4f2019-10-30 09:56:23 -0400107static wgpu::CompareFunction to_dawn_compare_function(GrStencilTest test) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400108 switch (test) {
109 case GrStencilTest::kAlways:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400110 return wgpu::CompareFunction::Always;
Stephen Whitef813ef72019-08-09 12:28:37 -0400111 case GrStencilTest::kNever:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400112 return wgpu::CompareFunction::Never;
Stephen Whitef813ef72019-08-09 12:28:37 -0400113 case GrStencilTest::kGreater:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400114 return wgpu::CompareFunction::Greater;
Stephen Whitef813ef72019-08-09 12:28:37 -0400115 case GrStencilTest::kGEqual:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400116 return wgpu::CompareFunction::GreaterEqual;
Stephen Whitef813ef72019-08-09 12:28:37 -0400117 case GrStencilTest::kLess:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400118 return wgpu::CompareFunction::Less;
Stephen Whitef813ef72019-08-09 12:28:37 -0400119 case GrStencilTest::kLEqual:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400120 return wgpu::CompareFunction::LessEqual;
Stephen Whitef813ef72019-08-09 12:28:37 -0400121 case GrStencilTest::kEqual:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400122 return wgpu::CompareFunction::Equal;
Stephen Whitef813ef72019-08-09 12:28:37 -0400123 case GrStencilTest::kNotEqual:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400124 return wgpu::CompareFunction::NotEqual;
Stephen Whitef813ef72019-08-09 12:28:37 -0400125 default:
126 SkASSERT(!"unsupported stencil test");
Stephen White3cc8d4f2019-10-30 09:56:23 -0400127 return wgpu::CompareFunction::Always;
Stephen Whitef813ef72019-08-09 12:28:37 -0400128 }
129}
130
Stephen White3cc8d4f2019-10-30 09:56:23 -0400131static wgpu::StencilOperation to_dawn_stencil_operation(GrStencilOp op) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400132 switch (op) {
133 case GrStencilOp::kKeep:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400134 return wgpu::StencilOperation::Keep;
Stephen Whitef813ef72019-08-09 12:28:37 -0400135 case GrStencilOp::kZero:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400136 return wgpu::StencilOperation::Zero;
Stephen Whitef813ef72019-08-09 12:28:37 -0400137 case GrStencilOp::kReplace:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400138 return wgpu::StencilOperation::Replace;
Stephen Whitef813ef72019-08-09 12:28:37 -0400139 case GrStencilOp::kInvert:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400140 return wgpu::StencilOperation::Invert;
Stephen Whitef813ef72019-08-09 12:28:37 -0400141 case GrStencilOp::kIncClamp:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400142 return wgpu::StencilOperation::IncrementClamp;
Stephen Whitef813ef72019-08-09 12:28:37 -0400143 case GrStencilOp::kDecClamp:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400144 return wgpu::StencilOperation::DecrementClamp;
Stephen Whitef813ef72019-08-09 12:28:37 -0400145 case GrStencilOp::kIncWrap:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400146 return wgpu::StencilOperation::IncrementWrap;
Stephen Whitef813ef72019-08-09 12:28:37 -0400147 case GrStencilOp::kDecWrap:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400148 return wgpu::StencilOperation::DecrementWrap;
Stephen Whitef813ef72019-08-09 12:28:37 -0400149 default:
150 SkASSERT(!"unsupported stencil function");
Stephen White3cc8d4f2019-10-30 09:56:23 -0400151 return wgpu::StencilOperation::Keep;
Stephen Whitef813ef72019-08-09 12:28:37 -0400152 }
153}
154
Stephen White3cc8d4f2019-10-30 09:56:23 -0400155static wgpu::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primitiveType) {
Stephen Whitee2641312019-08-29 15:10:50 -0400156 switch (primitiveType) {
157 case GrPrimitiveType::kTriangles:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400158 return wgpu::PrimitiveTopology::TriangleList;
Stephen Whitee2641312019-08-29 15:10:50 -0400159 case GrPrimitiveType::kTriangleStrip:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400160 return wgpu::PrimitiveTopology::TriangleStrip;
Stephen Whitee2641312019-08-29 15:10:50 -0400161 case GrPrimitiveType::kPoints:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400162 return wgpu::PrimitiveTopology::PointList;
Stephen Whitee2641312019-08-29 15:10:50 -0400163 case GrPrimitiveType::kLines:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400164 return wgpu::PrimitiveTopology::LineList;
Stephen Whitee2641312019-08-29 15:10:50 -0400165 case GrPrimitiveType::kLineStrip:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400166 return wgpu::PrimitiveTopology::LineStrip;
Robert Phillips571177f2019-10-04 14:41:49 -0400167 case GrPrimitiveType::kPath:
Stephen Whitee2641312019-08-29 15:10:50 -0400168 default:
169 SkASSERT(!"unsupported primitive topology");
Stephen White3cc8d4f2019-10-30 09:56:23 -0400170 return wgpu::PrimitiveTopology::TriangleList;
Stephen Whitee2641312019-08-29 15:10:50 -0400171 }
172}
173
Stephen White3cc8d4f2019-10-30 09:56:23 -0400174static wgpu::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
Stephen Whitee2641312019-08-29 15:10:50 -0400175 switch (type) {
176 case kFloat_GrVertexAttribType:
177 case kHalf_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400178 return wgpu::VertexFormat::Float;
Stephen Whitee2641312019-08-29 15:10:50 -0400179 case kFloat2_GrVertexAttribType:
180 case kHalf2_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400181 return wgpu::VertexFormat::Float2;
Stephen Whitee2641312019-08-29 15:10:50 -0400182 case kFloat3_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400183 return wgpu::VertexFormat::Float3;
Stephen Whitee2641312019-08-29 15:10:50 -0400184 case kFloat4_GrVertexAttribType:
185 case kHalf4_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400186 return wgpu::VertexFormat::Float4;
Stephen Whitee2641312019-08-29 15:10:50 -0400187 case kUShort2_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400188 return wgpu::VertexFormat::UShort2;
Stephen Whitee2641312019-08-29 15:10:50 -0400189 case kInt_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400190 return wgpu::VertexFormat::Int;
Stephen Whitee2641312019-08-29 15:10:50 -0400191 case kUByte4_norm_GrVertexAttribType:
Stephen White3cc8d4f2019-10-30 09:56:23 -0400192 return wgpu::VertexFormat::UChar4Norm;
Stephen Whitee2641312019-08-29 15:10:50 -0400193 default:
194 SkASSERT(!"unsupported vertex format");
Stephen White3cc8d4f2019-10-30 09:56:23 -0400195 return wgpu::VertexFormat::Float4;
Stephen Whitee2641312019-08-29 15:10:50 -0400196 }
197}
198
Stephen White3cc8d4f2019-10-30 09:56:23 -0400199static wgpu::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400200 const GrPipeline& pipeline,
Stephen White3cc8d4f2019-10-30 09:56:23 -0400201 wgpu::TextureFormat colorFormat) {
Stephen Whitebb6bed12019-08-02 09:57:55 -0400202 GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
203 GrBlendEquation equation = blendInfo.fEquation;
204 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
205 GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
206
Stephen White3cc8d4f2019-10-30 09:56:23 -0400207 wgpu::BlendFactor srcFactor = to_dawn_blend_factor(srcCoeff);
208 wgpu::BlendFactor dstFactor = to_dawn_blend_factor(dstCoeff);
209 wgpu::BlendFactor srcFactorAlpha = to_dawn_blend_factor_for_alpha(srcCoeff);
210 wgpu::BlendFactor dstFactorAlpha = to_dawn_blend_factor_for_alpha(dstCoeff);
211 wgpu::BlendOperation operation = to_dawn_blend_operation(equation);
212 auto mask = blendInfo.fWriteColor ? wgpu::ColorWriteMask::All : wgpu::ColorWriteMask::None;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400213
Stephen White3cc8d4f2019-10-30 09:56:23 -0400214 wgpu::BlendDescriptor colorDesc = {operation, srcFactor, dstFactor};
215 wgpu::BlendDescriptor alphaDesc = {operation, srcFactorAlpha, dstFactorAlpha};
Stephen Whitebb6bed12019-08-02 09:57:55 -0400216
Stephen White3cc8d4f2019-10-30 09:56:23 -0400217 wgpu::ColorStateDescriptor descriptor;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400218 descriptor.format = colorFormat;
219 descriptor.alphaBlend = alphaDesc;
220 descriptor.colorBlend = colorDesc;
221 descriptor.nextInChain = nullptr;
222 descriptor.writeMask = mask;
223
224 return descriptor;
225}
226
Stephen White3cc8d4f2019-10-30 09:56:23 -0400227static wgpu::StencilStateFaceDescriptor to_stencil_state_face(const GrStencilSettings::Face& face) {
228 wgpu::StencilStateFaceDescriptor desc;
Stephen Whitef813ef72019-08-09 12:28:37 -0400229 desc.compare = to_dawn_compare_function(face.fTest);
230 desc.failOp = desc.depthFailOp = to_dawn_stencil_operation(face.fFailOp);
231 desc.passOp = to_dawn_stencil_operation(face.fPassOp);
232 return desc;
233}
234
Stephen White3cc8d4f2019-10-30 09:56:23 -0400235static wgpu::DepthStencilStateDescriptor create_depth_stencil_state(
Robert Phillipsa87c5292019-11-12 10:12:42 -0500236 const GrProgramInfo& programInfo,
237 wgpu::TextureFormat depthStencilFormat) {
238 GrStencilSettings stencilSettings = programInfo.nonGLStencilSettings();
239 GrSurfaceOrigin origin = programInfo.origin();
240
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()) {
Sean Gilhuly6c536a52019-11-11 11:13:03 -0500245 auto front = stencilSettings.postOriginCCWFace(origin);
Stephen White3a62ed42019-11-11 16:56:02 -0500246 auto back = stencilSettings.postOriginCWFace(origin);
Stephen Whitef4b3d6b2019-10-18 07:54:25 -0400247 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 {
Sean Gilhuly6c536a52019-11-11 11:13:03 -0500252 auto frontAndBack = stencilSettings.singleSidedFace();
Stephen Whitef4b3d6b2019-10-18 07:54:25 -0400253 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 White3cc8d4f2019-10-30 09:56:23 -0400293 wgpu::TextureFormat colorFormat,
Stephen Whitef813ef72019-08-09 12:28:37 -0400294 bool hasDepthStencil,
Stephen White3cc8d4f2019-10-30 09:56:23 -0400295 wgpu::TextureFormat depthStencilFormat,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400296 GrProgramDesc* desc) {
Stephen White729c78d2019-10-14 12:42:59 -0400297 GrDawnProgramBuilder builder(gpu, renderTarget, programInfo, desc);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400298 if (!builder.emitAndInstallProcs()) {
299 return nullptr;
300 }
301
302 builder.fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
303 builder.fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
304 builder.fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
305 builder.fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
306
307 builder.finalizeShaders();
308
309 SkSL::Program::Inputs vertInputs, fragInputs;
Stephen White20c626a2019-10-15 13:35:37 -0400310 bool flipY = programInfo.origin() != kTopLeft_GrSurfaceOrigin;
311 auto vsModule = builder.createShaderModule(builder.fVS, SkSL::Program::kVertex_Kind, flipY,
Stephen Whitee2641312019-08-29 15:10:50 -0400312 &vertInputs);
Stephen White20c626a2019-10-15 13:35:37 -0400313 auto fsModule = builder.createShaderModule(builder.fFS, SkSL::Program::kFragment_Kind, flipY,
Stephen Whitee2641312019-08-29 15:10:50 -0400314 &fragInputs);
Stephen White40c47e12019-11-01 13:13:03 -0400315 GrDawnUniformHandler::UniformInfoArray& uniforms = builder.fUniformHandler.fUniforms;
316 uint32_t uniformBufferSize = builder.fUniformHandler.fCurrentUBOOffset;
317 sk_sp<GrDawnProgram> result(new GrDawnProgram(uniforms, uniformBufferSize));
Stephen Whitebb6bed12019-08-02 09:57:55 -0400318 result->fGeometryProcessor = std::move(builder.fGeometryProcessor);
319 result->fXferProcessor = std::move(builder.fXferProcessor);
320 result->fFragmentProcessors = std::move(builder.fFragmentProcessors);
321 result->fFragmentProcessorCnt = builder.fFragmentProcessorCnt;
Stephen White7cb52cb2019-11-12 10:40:27 -0500322 std::vector<wgpu::BindGroupLayoutBinding> uniformLayoutBindings;
Stephen Whitedd78efd2019-10-23 15:00:20 -0400323 if (0 != uniformBufferSize) {
Stephen White7cb52cb2019-11-12 10:40:27 -0500324 uniformLayoutBindings.push_back({ GrDawnUniformHandler::kUniformBinding,
325 wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
326 wgpu::BindingType::UniformBuffer});
Stephen White170d9902019-08-15 16:48:24 -0400327 }
Stephen White7cb52cb2019-11-12 10:40:27 -0500328 wgpu::BindGroupLayoutDescriptor uniformBindGroupLayoutDesc;
329 uniformBindGroupLayoutDesc.bindingCount = uniformLayoutBindings.size();
330 uniformBindGroupLayoutDesc.bindings = uniformLayoutBindings.data();
331 result->fBindGroupLayouts[0] =
332 gpu->device().CreateBindGroupLayout(&uniformBindGroupLayoutDesc);
333 uint32_t binding = 0;
334 std::vector<wgpu::BindGroupLayoutBinding> textureLayoutBindings;
Stephen White170d9902019-08-15 16:48:24 -0400335 for (int i = 0; i < builder.fUniformHandler.fSamplers.count(); ++i) {
Stephen White7cb52cb2019-11-12 10:40:27 -0500336 textureLayoutBindings.push_back({ binding++, wgpu::ShaderStage::Fragment,
337 wgpu::BindingType::Sampler});
338 textureLayoutBindings.push_back({ binding++, wgpu::ShaderStage::Fragment,
339 wgpu::BindingType::SampledTexture});
Stephen White170d9902019-08-15 16:48:24 -0400340 }
Stephen White7cb52cb2019-11-12 10:40:27 -0500341 wgpu::BindGroupLayoutDescriptor textureBindGroupLayoutDesc;
342 textureBindGroupLayoutDesc.bindingCount = textureLayoutBindings.size();
343 textureBindGroupLayoutDesc.bindings = textureLayoutBindings.data();
344 result->fBindGroupLayouts[1] =
345 gpu->device().CreateBindGroupLayout(&textureBindGroupLayoutDesc);
Stephen White3cc8d4f2019-10-30 09:56:23 -0400346 wgpu::PipelineLayoutDescriptor pipelineLayoutDesc;
Stephen White7cb52cb2019-11-12 10:40:27 -0500347 pipelineLayoutDesc.bindGroupLayoutCount = 2;
348 pipelineLayoutDesc.bindGroupLayouts = &result->fBindGroupLayouts[0];
Stephen Whitee2641312019-08-29 15:10:50 -0400349 auto pipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400350 result->fBuiltinUniformHandles = builder.fUniformHandles;
Stephen White729c78d2019-10-14 12:42:59 -0400351 const GrPipeline& pipeline = programInfo.pipeline();
Stephen Whitee2641312019-08-29 15:10:50 -0400352 auto colorState = create_color_state(gpu, pipeline, colorFormat);
Stephen White3cc8d4f2019-10-30 09:56:23 -0400353 wgpu::DepthStencilStateDescriptor depthStencilState;
Robert Phillipsa87c5292019-11-12 10:12:42 -0500354
355#ifdef SK_DEBUG
Stephen Whitef813ef72019-08-09 12:28:37 -0400356 if (pipeline.isStencilEnabled()) {
Robert Phillipsa87c5292019-11-12 10:12:42 -0500357 SkASSERT(renderTarget->renderTargetPriv().numStencilBits() == 8);
Stephen Whitef813ef72019-08-09 12:28:37 -0400358 }
Robert Phillipsa87c5292019-11-12 10:12:42 -0500359#endif
360 depthStencilState = create_depth_stencil_state(programInfo, depthStencilFormat);
Stephen Whitee2641312019-08-29 15:10:50 -0400361
Sean Gilhuly6c536a52019-11-11 11:13:03 -0500362 std::vector<wgpu::VertexBufferLayoutDescriptor> inputs;
Stephen Whitee2641312019-08-29 15:10:50 -0400363
Stephen White3cc8d4f2019-10-30 09:56:23 -0400364 std::vector<wgpu::VertexAttributeDescriptor> vertexAttributes;
Stephen White729c78d2019-10-14 12:42:59 -0400365 const GrPrimitiveProcessor& primProc = programInfo.primProc();
Stephen Whitee2641312019-08-29 15:10:50 -0400366 if (primProc.numVertexAttributes() > 0) {
367 size_t offset = 0;
368 int i = 0;
369 for (const auto& attrib : primProc.vertexAttributes()) {
Stephen White3cc8d4f2019-10-30 09:56:23 -0400370 wgpu::VertexAttributeDescriptor attribute;
Stephen Whitee2641312019-08-29 15:10:50 -0400371 attribute.shaderLocation = i;
372 attribute.offset = offset;
373 attribute.format = to_dawn_vertex_format(attrib.cpuType());
374 vertexAttributes.push_back(attribute);
375 offset += attrib.sizeAlign4();
376 i++;
377 }
Sean Gilhuly6c536a52019-11-11 11:13:03 -0500378 wgpu::VertexBufferLayoutDescriptor input;
379 input.arrayStride = offset;
Stephen White3cc8d4f2019-10-30 09:56:23 -0400380 input.stepMode = wgpu::InputStepMode::Vertex;
Stephen Whitee2641312019-08-29 15:10:50 -0400381 input.attributeCount = vertexAttributes.size();
382 input.attributes = &vertexAttributes.front();
383 inputs.push_back(input);
384 }
Stephen White3cc8d4f2019-10-30 09:56:23 -0400385 std::vector<wgpu::VertexAttributeDescriptor> instanceAttributes;
Stephen Whitee2641312019-08-29 15:10:50 -0400386 if (primProc.numInstanceAttributes() > 0) {
387 size_t offset = 0;
388 int i = 0;
389 for (const auto& attrib : primProc.instanceAttributes()) {
Stephen White3cc8d4f2019-10-30 09:56:23 -0400390 wgpu::VertexAttributeDescriptor attribute;
Stephen Whitee2641312019-08-29 15:10:50 -0400391 attribute.shaderLocation = i;
392 attribute.offset = offset;
393 attribute.format = to_dawn_vertex_format(attrib.cpuType());
394 instanceAttributes.push_back(attribute);
395 offset += attrib.sizeAlign4();
396 i++;
397 }
Sean Gilhuly6c536a52019-11-11 11:13:03 -0500398 wgpu::VertexBufferLayoutDescriptor input;
399 input.arrayStride = offset;
Stephen White3cc8d4f2019-10-30 09:56:23 -0400400 input.stepMode = wgpu::InputStepMode::Instance;
Stephen Whitee2641312019-08-29 15:10:50 -0400401 input.attributeCount = instanceAttributes.size();
402 input.attributes = &instanceAttributes.front();
403 inputs.push_back(input);
404 }
Sean Gilhuly6c536a52019-11-11 11:13:03 -0500405 wgpu::VertexStateDescriptor vertexState;
406 vertexState.indexFormat = wgpu::IndexFormat::Uint16;
407 vertexState.vertexBufferCount = inputs.size();
408 vertexState.vertexBuffers = &inputs.front();
Stephen Whitee2641312019-08-29 15:10:50 -0400409
Stephen White3cc8d4f2019-10-30 09:56:23 -0400410 wgpu::ProgrammableStageDescriptor vsDesc;
Stephen Whitee2641312019-08-29 15:10:50 -0400411 vsDesc.module = vsModule;
412 vsDesc.entryPoint = "main";
413
Stephen White3cc8d4f2019-10-30 09:56:23 -0400414 wgpu::ProgrammableStageDescriptor fsDesc;
Stephen Whitee2641312019-08-29 15:10:50 -0400415 fsDesc.module = fsModule;
416 fsDesc.entryPoint = "main";
417
Stephen White3cc8d4f2019-10-30 09:56:23 -0400418 wgpu::RenderPipelineDescriptor rpDesc;
Stephen Whitee2641312019-08-29 15:10:50 -0400419 rpDesc.layout = pipelineLayout;
Stephen White20c626a2019-10-15 13:35:37 -0400420 rpDesc.vertexStage = vsDesc;
Stephen Whitee2641312019-08-29 15:10:50 -0400421 rpDesc.fragmentStage = &fsDesc;
Sean Gilhuly6c536a52019-11-11 11:13:03 -0500422 rpDesc.vertexState = &vertexState;
Robert Phillipsfcaae482019-11-07 10:17:03 -0500423 rpDesc.primitiveTopology = to_dawn_primitive_topology(programInfo.primitiveType());
Stephen Whitee2641312019-08-29 15:10:50 -0400424 if (hasDepthStencil) {
425 rpDesc.depthStencilState = &depthStencilState;
426 }
427 rpDesc.colorStateCount = 1;
Stephen White20c626a2019-10-15 13:35:37 -0400428 rpDesc.colorStates = &colorState;
Stephen Whitee2641312019-08-29 15:10:50 -0400429 result->fRenderPipeline = gpu->device().CreateRenderPipeline(&rpDesc);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400430 return result;
431}
432
433GrDawnProgramBuilder::GrDawnProgramBuilder(GrDawnGpu* gpu,
434 GrRenderTarget* renderTarget,
Stephen White729c78d2019-10-14 12:42:59 -0400435 const GrProgramInfo& programInfo,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400436 GrProgramDesc* desc)
Stephen White511af2e2020-02-07 11:04:58 -0500437 : INHERITED(renderTarget, *desc, programInfo)
Stephen Whitebb6bed12019-08-02 09:57:55 -0400438 , fGpu(gpu)
439 , fVaryingHandler(this)
440 , fUniformHandler(this) {
441}
442
Stephen White3cc8d4f2019-10-30 09:56:23 -0400443wgpu::ShaderModule GrDawnProgramBuilder::createShaderModule(const GrGLSLShaderBuilder& builder,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400444 SkSL::Program::Kind kind,
Stephen White20c626a2019-10-15 13:35:37 -0400445 bool flipY,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400446 SkSL::Program::Inputs* inputs) {
Stephen White3cc8d4f2019-10-30 09:56:23 -0400447 wgpu::Device device = fGpu->device();
Stephen Whitebb6bed12019-08-02 09:57:55 -0400448 SkString source(builder.fCompilerString.c_str());
449
450#if 0
451 SkSL::String sksl = GrShaderUtils::PrettyPrint(builder.fCompilerString);
452 printf("converting program:\n%s\n", sksl.c_str());
453#endif
454
Stephen White40c47e12019-11-01 13:13:03 -0400455 SkSL::String spirvSource = sksl_to_spirv(fGpu, source.c_str(), kind, flipY,
456 fUniformHandler.getRTHeightOffset(), inputs);
457 if (inputs->fRTHeight) {
458 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
459 }
Stephen Whitebb6bed12019-08-02 09:57:55 -0400460
Stephen White3cc8d4f2019-10-30 09:56:23 -0400461 wgpu::ShaderModuleDescriptor desc;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400462 desc.codeSize = spirvSource.size() / 4;
463 desc.code = reinterpret_cast<const uint32_t*>(spirvSource.c_str());
464
465 return device.CreateShaderModule(&desc);
466};
467
468const GrCaps* GrDawnProgramBuilder::caps() const {
469 return fGpu->caps();
470}
471
472void GrDawnProgram::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
473 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
474 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
475 fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
476 fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
477 }
478
479 // set RT adjustment
Brian Salomon9f2b86c2019-10-22 10:37:46 -0400480 SkISize dimensions = rt->dimensions();
Stephen Whitebb6bed12019-08-02 09:57:55 -0400481 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
482 if (fRenderTargetState.fRenderTargetOrigin != origin ||
Brian Salomon9f2b86c2019-10-22 10:37:46 -0400483 fRenderTargetState.fRenderTargetSize != dimensions) {
484 fRenderTargetState.fRenderTargetSize = dimensions;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400485 fRenderTargetState.fRenderTargetOrigin = origin;
486
487 float rtAdjustmentVec[4];
488 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
489 fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
490 }
491}
492
Brian Salomonccb61422020-01-09 10:46:36 -0500493static void set_texture(GrDawnGpu* gpu, GrSamplerState state, GrTexture* texture,
494 std::vector<wgpu::BindGroupBinding>* bindings, int* binding) {
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400495 // FIXME: could probably cache samplers in GrDawnProgram
Stephen White3cc8d4f2019-10-30 09:56:23 -0400496 wgpu::Sampler sampler = gpu->getOrCreateSampler(state);
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400497 bindings->push_back(make_bind_group_binding((*binding)++, sampler));
498 GrDawnTexture* tex = static_cast<GrDawnTexture*>(texture);
Stephen White3cc8d4f2019-10-30 09:56:23 -0400499 wgpu::TextureView textureView = tex->textureView();
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400500 bindings->push_back(make_bind_group_binding((*binding)++, textureView));
501}
502
Stephen White7cb52cb2019-11-12 10:40:27 -0500503wgpu::BindGroup GrDawnProgram::setUniformData(GrDawnGpu* gpu, const GrRenderTarget* renderTarget,
504 const GrProgramInfo& programInfo) {
Stephen White3cc8d4f2019-10-30 09:56:23 -0400505 std::vector<wgpu::BindGroupBinding> bindings;
Stephen Whitedd78efd2019-10-23 15:00:20 -0400506 GrDawnRingBuffer::Slice slice;
507 uint32_t uniformBufferSize = fDataManager.uniformBufferSize();
508 if (0 != uniformBufferSize) {
509 slice = gpu->allocateUniformRingBufferSlice(uniformBufferSize);
510 bindings.push_back(make_bind_group_binding(GrDawnUniformHandler::kUniformBinding,
511 slice.fBuffer, slice.fOffset,
512 uniformBufferSize));
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400513 }
Stephen White729c78d2019-10-14 12:42:59 -0400514 this->setRenderTargetState(renderTarget, programInfo.origin());
515 const GrPipeline& pipeline = programInfo.pipeline();
516 const GrPrimitiveProcessor& primProc = programInfo.primProc();
Brian Salomonc241b582019-11-27 08:57:17 -0500517 GrFragmentProcessor::PipelineCoordTransformRange transformRange(pipeline);
518 fGeometryProcessor->setData(fDataManager, primProc, transformRange);
Brian Salomon7eabfe82019-12-02 14:20:20 -0500519 GrFragmentProcessor::CIter fpIter(pipeline);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400520 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
Brian Salomonc241b582019-11-27 08:57:17 -0500521 for (; fpIter && glslIter; ++fpIter, ++glslIter) {
522 glslIter->setData(fDataManager, *fpIter);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400523 }
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400524 SkIPoint offset;
525 GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
526 fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
Stephen White8eda4992020-03-17 11:44:48 -0400527 if (0 != uniformBufferSize) {
528 fDataManager.uploadUniformBuffers(slice.fData);
529 }
Stephen White3cc8d4f2019-10-30 09:56:23 -0400530 wgpu::BindGroupDescriptor descriptor;
Stephen White7cb52cb2019-11-12 10:40:27 -0500531 descriptor.layout = fBindGroupLayouts[0];
532 descriptor.bindingCount = bindings.size();
533 descriptor.bindings = bindings.data();
534 return gpu->device().CreateBindGroup(&descriptor);
535}
536
537wgpu::BindGroup GrDawnProgram::setTextures(GrDawnGpu* gpu,
Stephen White6e8ceee2020-02-25 16:25:43 -0500538 const GrPrimitiveProcessor& primProc,
539 const GrPipeline& pipeline,
Michael Ludwigfcdd0612019-11-25 08:34:31 -0500540 const GrSurfaceProxy* const primProcTextures[]) {
Stephen White7cb52cb2019-11-12 10:40:27 -0500541 std::vector<wgpu::BindGroupBinding> bindings;
542 int binding = 0;
Stephen White7cb52cb2019-11-12 10:40:27 -0500543 if (primProcTextures) {
544 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
Michael Ludwigfcdd0612019-11-25 08:34:31 -0500545 SkASSERT(primProcTextures[i]->asTextureProxy());
Stephen White7cb52cb2019-11-12 10:40:27 -0500546 auto& sampler = primProc.textureSampler(i);
547 set_texture(gpu, sampler.samplerState(), primProcTextures[i]->peekTexture(), &bindings,
548 &binding);
549 }
550 }
Stephen Whitea521c962019-12-04 09:57:48 -0500551 GrFragmentProcessor::CIter fpIter(pipeline);
Stephen White7cb52cb2019-11-12 10:40:27 -0500552 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
Brian Salomonc241b582019-11-27 08:57:17 -0500553 for (; fpIter && glslIter; ++fpIter, ++glslIter) {
554 for (int i = 0; i < fpIter->numTextureSamplers(); ++i) {
555 auto& s = fpIter->textureSampler(i);
Stephen White7cb52cb2019-11-12 10:40:27 -0500556 set_texture(gpu, s.samplerState(), s.peekTexture(), &bindings, &binding);
557 }
Stephen White7cb52cb2019-11-12 10:40:27 -0500558 }
559 SkIPoint offset;
560 if (GrTexture* dstTexture = pipeline.peekDstTexture(&offset)) {
Brian Salomonccb61422020-01-09 10:46:36 -0500561 set_texture(gpu, GrSamplerState::Filter::kNearest, dstTexture, &bindings, &binding);
Stephen White7cb52cb2019-11-12 10:40:27 -0500562 }
563 wgpu::BindGroupDescriptor descriptor;
564 descriptor.layout = fBindGroupLayouts[1];
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400565 descriptor.bindingCount = bindings.size();
566 descriptor.bindings = bindings.data();
567 return gpu->device().CreateBindGroup(&descriptor);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400568}