1 /*
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
10 #include "src/gpu/GrRenderTarget.h"
11 #include "src/gpu/GrShaderUtils.h"
12 #include "src/gpu/GrStencilSettings.h"
13 #include "src/gpu/dawn/GrDawnGpu.h"
14 #include "src/gpu/dawn/GrDawnTexture.h"
15
to_dawn_blend_factor(GrBlendCoeff coeff)16 static wgpu::BlendFactor to_dawn_blend_factor(GrBlendCoeff coeff) {
17 switch (coeff) {
18 case kZero_GrBlendCoeff:
19 return wgpu::BlendFactor::Zero;
20 case kOne_GrBlendCoeff:
21 return wgpu::BlendFactor::One;
22 case kSC_GrBlendCoeff:
23 return wgpu::BlendFactor::SrcColor;
24 case kISC_GrBlendCoeff:
25 return wgpu::BlendFactor::OneMinusSrcColor;
26 case kDC_GrBlendCoeff:
27 return wgpu::BlendFactor::DstColor;
28 case kIDC_GrBlendCoeff:
29 return wgpu::BlendFactor::OneMinusDstColor;
30 case kSA_GrBlendCoeff:
31 return wgpu::BlendFactor::SrcAlpha;
32 case kISA_GrBlendCoeff:
33 return wgpu::BlendFactor::OneMinusSrcAlpha;
34 case kDA_GrBlendCoeff:
35 return wgpu::BlendFactor::DstAlpha;
36 case kIDA_GrBlendCoeff:
37 return wgpu::BlendFactor::OneMinusDstAlpha;
38 case kConstC_GrBlendCoeff:
39 return wgpu::BlendFactor::BlendColor;
40 case kIConstC_GrBlendCoeff:
41 return wgpu::BlendFactor::OneMinusBlendColor;
42 case kS2C_GrBlendCoeff:
43 case kIS2C_GrBlendCoeff:
44 case kS2A_GrBlendCoeff:
45 case kIS2A_GrBlendCoeff:
46 default:
47 SkASSERT(!"unsupported blend coefficient");
48 return wgpu::BlendFactor::One;
49 }
50 }
51
to_dawn_blend_factor_for_alpha(GrBlendCoeff coeff)52 static wgpu::BlendFactor to_dawn_blend_factor_for_alpha(GrBlendCoeff coeff) {
53 switch (coeff) {
54 // Force all srcColor used in alpha slot to alpha version.
55 case kSC_GrBlendCoeff:
56 return wgpu::BlendFactor::SrcAlpha;
57 case kISC_GrBlendCoeff:
58 return wgpu::BlendFactor::OneMinusSrcAlpha;
59 case kDC_GrBlendCoeff:
60 return wgpu::BlendFactor::DstAlpha;
61 case kIDC_GrBlendCoeff:
62 return wgpu::BlendFactor::OneMinusDstAlpha;
63 default:
64 return to_dawn_blend_factor(coeff);
65 }
66 }
67
to_dawn_blend_operation(GrBlendEquation equation)68 static wgpu::BlendOperation to_dawn_blend_operation(GrBlendEquation equation) {
69 switch (equation) {
70 case kAdd_GrBlendEquation:
71 return wgpu::BlendOperation::Add;
72 case kSubtract_GrBlendEquation:
73 return wgpu::BlendOperation::Subtract;
74 case kReverseSubtract_GrBlendEquation:
75 return wgpu::BlendOperation::ReverseSubtract;
76 default:
77 SkASSERT(!"unsupported blend equation");
78 return wgpu::BlendOperation::Add;
79 }
80 }
81
to_dawn_compare_function(GrStencilTest test)82 static wgpu::CompareFunction to_dawn_compare_function(GrStencilTest test) {
83 switch (test) {
84 case GrStencilTest::kAlways:
85 return wgpu::CompareFunction::Always;
86 case GrStencilTest::kNever:
87 return wgpu::CompareFunction::Never;
88 case GrStencilTest::kGreater:
89 return wgpu::CompareFunction::Greater;
90 case GrStencilTest::kGEqual:
91 return wgpu::CompareFunction::GreaterEqual;
92 case GrStencilTest::kLess:
93 return wgpu::CompareFunction::Less;
94 case GrStencilTest::kLEqual:
95 return wgpu::CompareFunction::LessEqual;
96 case GrStencilTest::kEqual:
97 return wgpu::CompareFunction::Equal;
98 case GrStencilTest::kNotEqual:
99 return wgpu::CompareFunction::NotEqual;
100 default:
101 SkASSERT(!"unsupported stencil test");
102 return wgpu::CompareFunction::Always;
103 }
104 }
105
to_dawn_stencil_operation(GrStencilOp op)106 static wgpu::StencilOperation to_dawn_stencil_operation(GrStencilOp op) {
107 switch (op) {
108 case GrStencilOp::kKeep:
109 return wgpu::StencilOperation::Keep;
110 case GrStencilOp::kZero:
111 return wgpu::StencilOperation::Zero;
112 case GrStencilOp::kReplace:
113 return wgpu::StencilOperation::Replace;
114 case GrStencilOp::kInvert:
115 return wgpu::StencilOperation::Invert;
116 case GrStencilOp::kIncClamp:
117 return wgpu::StencilOperation::IncrementClamp;
118 case GrStencilOp::kDecClamp:
119 return wgpu::StencilOperation::DecrementClamp;
120 case GrStencilOp::kIncWrap:
121 return wgpu::StencilOperation::IncrementWrap;
122 case GrStencilOp::kDecWrap:
123 return wgpu::StencilOperation::DecrementWrap;
124 default:
125 SkASSERT(!"unsupported stencil function");
126 return wgpu::StencilOperation::Keep;
127 }
128 }
129
to_dawn_primitive_topology(GrPrimitiveType primitiveType)130 static wgpu::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primitiveType) {
131 switch (primitiveType) {
132 case GrPrimitiveType::kTriangles:
133 return wgpu::PrimitiveTopology::TriangleList;
134 case GrPrimitiveType::kTriangleStrip:
135 return wgpu::PrimitiveTopology::TriangleStrip;
136 case GrPrimitiveType::kPoints:
137 return wgpu::PrimitiveTopology::PointList;
138 case GrPrimitiveType::kLines:
139 return wgpu::PrimitiveTopology::LineList;
140 case GrPrimitiveType::kLineStrip:
141 return wgpu::PrimitiveTopology::LineStrip;
142 case GrPrimitiveType::kPath:
143 default:
144 SkASSERT(!"unsupported primitive topology");
145 return wgpu::PrimitiveTopology::TriangleList;
146 }
147 }
148
to_dawn_vertex_format(GrVertexAttribType type)149 static wgpu::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
150 switch (type) {
151 case kFloat_GrVertexAttribType:
152 case kHalf_GrVertexAttribType:
153 return wgpu::VertexFormat::Float;
154 case kFloat2_GrVertexAttribType:
155 case kHalf2_GrVertexAttribType:
156 return wgpu::VertexFormat::Float2;
157 case kFloat3_GrVertexAttribType:
158 return wgpu::VertexFormat::Float3;
159 case kFloat4_GrVertexAttribType:
160 case kHalf4_GrVertexAttribType:
161 return wgpu::VertexFormat::Float4;
162 case kUShort2_GrVertexAttribType:
163 return wgpu::VertexFormat::UShort2;
164 case kInt_GrVertexAttribType:
165 return wgpu::VertexFormat::Int;
166 case kUByte4_norm_GrVertexAttribType:
167 return wgpu::VertexFormat::UChar4Norm;
168 default:
169 SkASSERT(!"unsupported vertex format");
170 return wgpu::VertexFormat::Float4;
171 }
172 }
173
create_color_state(const GrDawnGpu * gpu,const GrPipeline & pipeline,wgpu::TextureFormat colorFormat)174 static wgpu::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
175 const GrPipeline& pipeline,
176 wgpu::TextureFormat colorFormat) {
177 GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
178 GrBlendEquation equation = blendInfo.fEquation;
179 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
180 GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
181
182 wgpu::BlendFactor srcFactor = to_dawn_blend_factor(srcCoeff);
183 wgpu::BlendFactor dstFactor = to_dawn_blend_factor(dstCoeff);
184 wgpu::BlendFactor srcFactorAlpha = to_dawn_blend_factor_for_alpha(srcCoeff);
185 wgpu::BlendFactor dstFactorAlpha = to_dawn_blend_factor_for_alpha(dstCoeff);
186 wgpu::BlendOperation operation = to_dawn_blend_operation(equation);
187 auto mask = blendInfo.fWriteColor ? wgpu::ColorWriteMask::All : wgpu::ColorWriteMask::None;
188
189 wgpu::BlendDescriptor colorDesc = {operation, srcFactor, dstFactor};
190 wgpu::BlendDescriptor alphaDesc = {operation, srcFactorAlpha, dstFactorAlpha};
191
192 wgpu::ColorStateDescriptor descriptor;
193 descriptor.format = colorFormat;
194 descriptor.alphaBlend = alphaDesc;
195 descriptor.colorBlend = colorDesc;
196 descriptor.nextInChain = nullptr;
197 descriptor.writeMask = mask;
198
199 return descriptor;
200 }
201
to_stencil_state_face(const GrStencilSettings::Face & face)202 static wgpu::StencilStateFaceDescriptor to_stencil_state_face(const GrStencilSettings::Face& face) {
203 wgpu::StencilStateFaceDescriptor desc;
204 desc.compare = to_dawn_compare_function(face.fTest);
205 desc.failOp = desc.depthFailOp = to_dawn_stencil_operation(face.fFailOp);
206 desc.passOp = to_dawn_stencil_operation(face.fPassOp);
207 return desc;
208 }
209
create_depth_stencil_state(const GrProgramInfo & programInfo,wgpu::TextureFormat depthStencilFormat)210 static wgpu::DepthStencilStateDescriptor create_depth_stencil_state(
211 const GrProgramInfo& programInfo,
212 wgpu::TextureFormat depthStencilFormat) {
213 GrStencilSettings stencilSettings = programInfo.nonGLStencilSettings();
214 GrSurfaceOrigin origin = programInfo.origin();
215
216 wgpu::DepthStencilStateDescriptor state;
217 state.format = depthStencilFormat;
218 if (!stencilSettings.isDisabled()) {
219 if (stencilSettings.isTwoSided()) {
220 auto front = stencilSettings.postOriginCCWFace(origin);
221 auto back = stencilSettings.postOriginCWFace(origin);
222 state.stencilFront = to_stencil_state_face(front);
223 state.stencilBack = to_stencil_state_face(back);
224 state.stencilReadMask = front.fTestMask;
225 state.stencilWriteMask = front.fWriteMask;
226 } else {
227 auto frontAndBack = stencilSettings.singleSidedFace();
228 state.stencilBack = state.stencilFront = to_stencil_state_face(frontAndBack);
229 state.stencilReadMask = frontAndBack.fTestMask;
230 state.stencilWriteMask = frontAndBack.fWriteMask;
231 }
232 }
233 return state;
234 }
235
make_bind_group_entry(uint32_t binding,const wgpu::Sampler & sampler,const wgpu::TextureView & textureView)236 static wgpu::BindGroupEntry make_bind_group_entry(uint32_t binding,
237 const wgpu::Sampler& sampler,
238 const wgpu::TextureView& textureView) {
239 wgpu::BindGroupEntry result;
240 result.binding = binding;
241 result.buffer = nullptr;
242 result.offset = 0;
243 result.size = 0;
244 result.sampler = sampler;
245 result.textureView = textureView;
246 return result;
247 }
248
make_bind_group_entry(uint32_t binding,const wgpu::Sampler & sampler)249 static wgpu::BindGroupEntry make_bind_group_entry(uint32_t binding,
250 const wgpu::Sampler& sampler) {
251 return make_bind_group_entry(binding, sampler, nullptr);
252 }
253
make_bind_group_entry(uint32_t binding,const wgpu::TextureView & textureView)254 static wgpu::BindGroupEntry make_bind_group_entry(uint32_t binding,
255 const wgpu::TextureView& textureView) {
256 return make_bind_group_entry(binding, nullptr, textureView);
257 }
258
Build(GrDawnGpu * gpu,GrRenderTarget * renderTarget,const GrProgramInfo & programInfo,wgpu::TextureFormat colorFormat,bool hasDepthStencil,wgpu::TextureFormat depthStencilFormat,GrProgramDesc * desc)259 sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
260 GrRenderTarget* renderTarget,
261 const GrProgramInfo& programInfo,
262 wgpu::TextureFormat colorFormat,
263 bool hasDepthStencil,
264 wgpu::TextureFormat depthStencilFormat,
265 GrProgramDesc* desc) {
266 GrDawnProgramBuilder builder(gpu, renderTarget, programInfo, desc);
267 if (!builder.emitAndInstallProcs()) {
268 return nullptr;
269 }
270
271 builder.fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
272 builder.fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
273 builder.fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
274 builder.fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
275
276 builder.finalizeShaders();
277
278 SkSL::Program::Inputs vertInputs, fragInputs;
279 bool flipY = programInfo.origin() != kTopLeft_GrSurfaceOrigin;
280 auto vsModule = builder.createShaderModule(builder.fVS, SkSL::Program::kVertex_Kind, flipY,
281 &vertInputs);
282 auto fsModule = builder.createShaderModule(builder.fFS, SkSL::Program::kFragment_Kind, flipY,
283 &fragInputs);
284 GrSPIRVUniformHandler::UniformInfoArray& uniforms = builder.fUniformHandler.fUniforms;
285 uint32_t uniformBufferSize = builder.fUniformHandler.fCurrentUBOOffset;
286 sk_sp<GrDawnProgram> result(new GrDawnProgram(uniforms, uniformBufferSize));
287 result->fGeometryProcessor = std::move(builder.fGeometryProcessor);
288 result->fXferProcessor = std::move(builder.fXferProcessor);
289 result->fFragmentProcessors = std::move(builder.fFragmentProcessors);
290 std::vector<wgpu::BindGroupLayoutEntry> uniformLayoutEntries;
291 if (0 != uniformBufferSize) {
292 uniformLayoutEntries.push_back({ GrSPIRVUniformHandler::kUniformBinding,
293 wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
294 wgpu::BindingType::UniformBuffer });
295 }
296 wgpu::BindGroupLayoutDescriptor uniformBindGroupLayoutDesc;
297 uniformBindGroupLayoutDesc.entryCount = uniformLayoutEntries.size();
298 uniformBindGroupLayoutDesc.entries = uniformLayoutEntries.data();
299 result->fBindGroupLayouts.push_back(
300 gpu->device().CreateBindGroupLayout(&uniformBindGroupLayoutDesc));
301 uint32_t binding = 0;
302 std::vector<wgpu::BindGroupLayoutEntry> textureLayoutEntries;
303 int textureCount = builder.fUniformHandler.fSamplers.count();
304 if (textureCount > 0) {
305 for (int i = 0; i < textureCount; ++i) {
306 textureLayoutEntries.push_back({ binding++, wgpu::ShaderStage::Fragment,
307 wgpu::BindingType::Sampler });
308 textureLayoutEntries.push_back({ binding++, wgpu::ShaderStage::Fragment,
309 wgpu::BindingType::SampledTexture });
310 }
311 wgpu::BindGroupLayoutDescriptor textureBindGroupLayoutDesc;
312 textureBindGroupLayoutDesc.entryCount = textureLayoutEntries.size();
313 textureBindGroupLayoutDesc.entries = textureLayoutEntries.data();
314 result->fBindGroupLayouts.push_back(
315 gpu->device().CreateBindGroupLayout(&textureBindGroupLayoutDesc));
316 }
317 wgpu::PipelineLayoutDescriptor pipelineLayoutDesc;
318 pipelineLayoutDesc.bindGroupLayoutCount = result->fBindGroupLayouts.size();
319 pipelineLayoutDesc.bindGroupLayouts = result->fBindGroupLayouts.data();
320 auto pipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
321 result->fBuiltinUniformHandles = builder.fUniformHandles;
322 const GrPipeline& pipeline = programInfo.pipeline();
323 auto colorState = create_color_state(gpu, pipeline, colorFormat);
324 wgpu::DepthStencilStateDescriptor depthStencilState;
325
326 #ifdef SK_DEBUG
327 if (programInfo.isStencilEnabled()) {
328 SkASSERT(renderTarget->numStencilBits() == 8);
329 }
330 #endif
331 depthStencilState = create_depth_stencil_state(programInfo, depthStencilFormat);
332
333 std::vector<wgpu::VertexBufferLayoutDescriptor> inputs;
334
335 std::vector<wgpu::VertexAttributeDescriptor> vertexAttributes;
336 const GrPrimitiveProcessor& primProc = programInfo.primProc();
337 int i = 0;
338 if (primProc.numVertexAttributes() > 0) {
339 size_t offset = 0;
340 for (const auto& attrib : primProc.vertexAttributes()) {
341 wgpu::VertexAttributeDescriptor attribute;
342 attribute.shaderLocation = i;
343 attribute.offset = offset;
344 attribute.format = to_dawn_vertex_format(attrib.cpuType());
345 vertexAttributes.push_back(attribute);
346 offset += attrib.sizeAlign4();
347 i++;
348 }
349 wgpu::VertexBufferLayoutDescriptor input;
350 input.arrayStride = offset;
351 input.stepMode = wgpu::InputStepMode::Vertex;
352 input.attributeCount = vertexAttributes.size();
353 input.attributes = &vertexAttributes.front();
354 inputs.push_back(input);
355 }
356 std::vector<wgpu::VertexAttributeDescriptor> instanceAttributes;
357 if (primProc.numInstanceAttributes() > 0) {
358 size_t offset = 0;
359 for (const auto& attrib : primProc.instanceAttributes()) {
360 wgpu::VertexAttributeDescriptor attribute;
361 attribute.shaderLocation = i;
362 attribute.offset = offset;
363 attribute.format = to_dawn_vertex_format(attrib.cpuType());
364 instanceAttributes.push_back(attribute);
365 offset += attrib.sizeAlign4();
366 i++;
367 }
368 wgpu::VertexBufferLayoutDescriptor input;
369 input.arrayStride = offset;
370 input.stepMode = wgpu::InputStepMode::Instance;
371 input.attributeCount = instanceAttributes.size();
372 input.attributes = &instanceAttributes.front();
373 inputs.push_back(input);
374 }
375 wgpu::VertexStateDescriptor vertexState;
376 if (programInfo.primitiveType() == GrPrimitiveType::kTriangleStrip ||
377 programInfo.primitiveType() == GrPrimitiveType::kLineStrip) {
378 vertexState.indexFormat = wgpu::IndexFormat::Uint16;
379 }
380 vertexState.vertexBufferCount = inputs.size();
381 vertexState.vertexBuffers = &inputs.front();
382
383 wgpu::ProgrammableStageDescriptor vsDesc;
384 vsDesc.module = vsModule;
385 vsDesc.entryPoint = "main";
386
387 wgpu::ProgrammableStageDescriptor fsDesc;
388 fsDesc.module = fsModule;
389 fsDesc.entryPoint = "main";
390
391 wgpu::RenderPipelineDescriptor rpDesc;
392 rpDesc.layout = pipelineLayout;
393 rpDesc.vertexStage = vsDesc;
394 rpDesc.fragmentStage = &fsDesc;
395 rpDesc.vertexState = &vertexState;
396 rpDesc.primitiveTopology = to_dawn_primitive_topology(programInfo.primitiveType());
397 if (hasDepthStencil) {
398 rpDesc.depthStencilState = &depthStencilState;
399 }
400 rpDesc.colorStateCount = 1;
401 rpDesc.colorStates = &colorState;
402 result->fRenderPipeline = gpu->device().CreateRenderPipeline(&rpDesc);
403 return result;
404 }
405
GrDawnProgramBuilder(GrDawnGpu * gpu,GrRenderTarget * renderTarget,const GrProgramInfo & programInfo,GrProgramDesc * desc)406 GrDawnProgramBuilder::GrDawnProgramBuilder(GrDawnGpu* gpu,
407 GrRenderTarget* renderTarget,
408 const GrProgramInfo& programInfo,
409 GrProgramDesc* desc)
410 : INHERITED(renderTarget, *desc, programInfo)
411 , fGpu(gpu)
412 , fVaryingHandler(this)
413 , fUniformHandler(this) {
414 }
415
createShaderModule(const GrGLSLShaderBuilder & builder,SkSL::Program::Kind kind,bool flipY,SkSL::Program::Inputs * inputs)416 wgpu::ShaderModule GrDawnProgramBuilder::createShaderModule(const GrGLSLShaderBuilder& builder,
417 SkSL::Program::Kind kind,
418 bool flipY,
419 SkSL::Program::Inputs* inputs) {
420 wgpu::Device device = fGpu->device();
421 SkString source(builder.fCompilerString.c_str());
422
423 #if 0
424 SkSL::String sksl = GrShaderUtils::PrettyPrint(builder.fCompilerString);
425 printf("converting program:\n%s\n", sksl.c_str());
426 #endif
427
428 SkSL::String spirvSource = fGpu->SkSLToSPIRV(source.c_str(), kind, flipY,
429 fUniformHandler.getRTHeightOffset(), inputs);
430 if (inputs->fRTHeight) {
431 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
432 }
433
434 return fGpu->createShaderModule(spirvSource);
435 };
436
caps() const437 const GrCaps* GrDawnProgramBuilder::caps() const {
438 return fGpu->caps();
439 }
440
setRenderTargetState(const GrRenderTarget * rt,GrSurfaceOrigin origin)441 void GrDawnProgram::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
442 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
443 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
444 fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
445 fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
446 }
447
448 // set RT adjustment
449 SkISize dimensions = rt->dimensions();
450 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
451 if (fRenderTargetState.fRenderTargetOrigin != origin ||
452 fRenderTargetState.fRenderTargetSize != dimensions) {
453 fRenderTargetState.fRenderTargetSize = dimensions;
454 fRenderTargetState.fRenderTargetOrigin = origin;
455
456 float rtAdjustmentVec[4];
457 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
458 fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
459 }
460 }
461
set_texture(GrDawnGpu * gpu,GrSamplerState state,GrTexture * texture,std::vector<wgpu::BindGroupEntry> * bindings,int * binding)462 static void set_texture(GrDawnGpu* gpu, GrSamplerState state, GrTexture* texture,
463 std::vector<wgpu::BindGroupEntry>* bindings, int* binding) {
464 // FIXME: could probably cache samplers in GrDawnProgram
465 wgpu::Sampler sampler = gpu->getOrCreateSampler(state);
466 bindings->push_back(make_bind_group_entry((*binding)++, sampler));
467 GrDawnTexture* tex = static_cast<GrDawnTexture*>(texture);
468 wgpu::TextureViewDescriptor viewDesc;
469 // Note that a mipLevelCount of zero here means to expose all available levels.
470 viewDesc.mipLevelCount = GrSamplerState::MipmapMode::kNone == state.mipmapMode() ? 1 : 0;
471 wgpu::TextureView textureView = tex->texture().CreateView(&viewDesc);
472 bindings->push_back(make_bind_group_entry((*binding)++, textureView));
473 }
474
setUniformData(GrDawnGpu * gpu,const GrRenderTarget * renderTarget,const GrProgramInfo & programInfo)475 wgpu::BindGroup GrDawnProgram::setUniformData(GrDawnGpu* gpu, const GrRenderTarget* renderTarget,
476 const GrProgramInfo& programInfo) {
477 if (0 == fDataManager.uniformBufferSize()) {
478 return nullptr;
479 }
480 this->setRenderTargetState(renderTarget, programInfo.origin());
481 const GrPipeline& pipeline = programInfo.pipeline();
482 const GrPrimitiveProcessor& primProc = programInfo.primProc();
483 fGeometryProcessor->setData(fDataManager, primProc);
484
485 for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
486 auto& pipelineFP = programInfo.pipeline().getFragmentProcessor(i);
487 auto& baseGLSLFP = *fFragmentProcessors[i];
488 for (auto [fp, glslFP] : GrGLSLFragmentProcessor::ParallelRange(pipelineFP, baseGLSLFP)) {
489 glslFP.setData(fDataManager, fp);
490 }
491 }
492
493 SkIPoint offset;
494 GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
495 fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
496 return fDataManager.uploadUniformBuffers(gpu, fBindGroupLayouts[0]);
497 }
498
setTextures(GrDawnGpu * gpu,const GrPrimitiveProcessor & primProc,const GrPipeline & pipeline,const GrSurfaceProxy * const primProcTextures[])499 wgpu::BindGroup GrDawnProgram::setTextures(GrDawnGpu* gpu,
500 const GrPrimitiveProcessor& primProc,
501 const GrPipeline& pipeline,
502 const GrSurfaceProxy* const primProcTextures[]) {
503 if (fBindGroupLayouts.size() < 2) {
504 return nullptr;
505 }
506 std::vector<wgpu::BindGroupEntry> bindings;
507 int binding = 0;
508 if (primProcTextures) {
509 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
510 SkASSERT(primProcTextures[i]->asTextureProxy());
511 auto& sampler = primProc.textureSampler(i);
512 set_texture(gpu, sampler.samplerState(), primProcTextures[i]->peekTexture(), &bindings,
513 &binding);
514 }
515 }
516
517 pipeline.visitTextureEffects([&](const GrTextureEffect& te) {
518 set_texture(gpu, te.samplerState(), te.texture(), &bindings, &binding);
519 });
520
521 SkIPoint offset;
522 if (GrTexture* dstTexture = pipeline.peekDstTexture(&offset)) {
523 set_texture(gpu, GrSamplerState::Filter::kNearest, dstTexture, &bindings, &binding);
524 }
525 wgpu::BindGroupDescriptor descriptor;
526 descriptor.layout = fBindGroupLayouts[1];
527 descriptor.entryCount = bindings.size();
528 descriptor.entries = bindings.data();
529 return gpu->device().CreateBindGroup(&descriptor);
530 }
531