blob: 7e2f7cc515d0d756ae8da31e3157b73564ba331d [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,
18 SkSL::Program::Kind kind, SkSL::Program::Inputs* inputs) {
19 SkSL::Program::Settings settings;
Stephen White170d9902019-08-15 16:48:24 -040020 settings.fCaps = gpu->caps()->shaderCaps();
Stephen Whitebb6bed12019-08-02 09:57:55 -040021 std::unique_ptr<SkSL::Program> program = gpu->shaderCompiler()->convertProgram(
22 kind,
23 shaderString,
24 settings);
25 if (!program) {
26 SkDebugf("SkSL error:\n%s\n", gpu->shaderCompiler()->errorText().c_str());
27 SkASSERT(false);
28 return "";
29 }
30 *inputs = program->fInputs;
31 SkSL::String code;
32 if (!gpu->shaderCompiler()->toSPIRV(*program, &code)) {
33 return "";
34 }
35 return code;
36}
37
38static dawn::BlendFactor to_dawn_blend_factor(GrBlendCoeff coeff) {
39 switch (coeff) {
40 case kZero_GrBlendCoeff:
41 return dawn::BlendFactor::Zero;
42 case kOne_GrBlendCoeff:
43 return dawn::BlendFactor::One;
44 case kSC_GrBlendCoeff:
45 return dawn::BlendFactor::SrcColor;
46 case kISC_GrBlendCoeff:
47 return dawn::BlendFactor::OneMinusSrcColor;
48 case kDC_GrBlendCoeff:
49 return dawn::BlendFactor::DstColor;
50 case kIDC_GrBlendCoeff:
51 return dawn::BlendFactor::OneMinusDstColor;
52 case kSA_GrBlendCoeff:
53 return dawn::BlendFactor::SrcAlpha;
54 case kISA_GrBlendCoeff:
55 return dawn::BlendFactor::OneMinusSrcAlpha;
56 case kDA_GrBlendCoeff:
57 return dawn::BlendFactor::DstAlpha;
58 case kIDA_GrBlendCoeff:
59 return dawn::BlendFactor::OneMinusDstAlpha;
60 case kConstC_GrBlendCoeff:
61 return dawn::BlendFactor::BlendColor;
62 case kIConstC_GrBlendCoeff:
63 return dawn::BlendFactor::OneMinusBlendColor;
64 case kConstA_GrBlendCoeff:
65 case kIConstA_GrBlendCoeff:
66 case kS2C_GrBlendCoeff:
67 case kIS2C_GrBlendCoeff:
68 case kS2A_GrBlendCoeff:
69 case kIS2A_GrBlendCoeff:
70 default:
71 SkASSERT(!"unsupported blend coefficient");
72 return dawn::BlendFactor::One;
73 }
74}
75
Stephen Whitef813ef72019-08-09 12:28:37 -040076static dawn::BlendFactor to_dawn_blend_factor_for_alpha(GrBlendCoeff coeff) {
77 switch (coeff) {
78 // Force all srcColor used in alpha slot to alpha version.
79 case kSC_GrBlendCoeff:
80 return dawn::BlendFactor::SrcAlpha;
81 case kISC_GrBlendCoeff:
82 return dawn::BlendFactor::OneMinusSrcAlpha;
83 case kDC_GrBlendCoeff:
84 return dawn::BlendFactor::DstAlpha;
85 case kIDC_GrBlendCoeff:
86 return dawn::BlendFactor::OneMinusDstAlpha;
87 default:
88 return to_dawn_blend_factor(coeff);
89 }
90}
91
Stephen Whitebb6bed12019-08-02 09:57:55 -040092static dawn::BlendOperation to_dawn_blend_operation(GrBlendEquation equation) {
93 switch (equation) {
94 case kAdd_GrBlendEquation:
95 return dawn::BlendOperation::Add;
96 case kSubtract_GrBlendEquation:
97 return dawn::BlendOperation::Subtract;
Stephen Whitef813ef72019-08-09 12:28:37 -040098 case kReverseSubtract_GrBlendEquation:
99 return dawn::BlendOperation::ReverseSubtract;
Stephen Whitebb6bed12019-08-02 09:57:55 -0400100 default:
101 SkASSERT(!"unsupported blend equation");
102 return dawn::BlendOperation::Add;
103 }
104}
105
Stephen Whitef813ef72019-08-09 12:28:37 -0400106static dawn::CompareFunction to_dawn_compare_function(GrStencilTest test) {
107 switch (test) {
108 case GrStencilTest::kAlways:
109 return dawn::CompareFunction::Always;
110 case GrStencilTest::kNever:
111 return dawn::CompareFunction::Never;
112 case GrStencilTest::kGreater:
113 return dawn::CompareFunction::Greater;
114 case GrStencilTest::kGEqual:
115 return dawn::CompareFunction::GreaterEqual;
116 case GrStencilTest::kLess:
117 return dawn::CompareFunction::Less;
118 case GrStencilTest::kLEqual:
119 return dawn::CompareFunction::LessEqual;
120 case GrStencilTest::kEqual:
121 return dawn::CompareFunction::Equal;
122 case GrStencilTest::kNotEqual:
123 return dawn::CompareFunction::NotEqual;
124 default:
125 SkASSERT(!"unsupported stencil test");
126 return dawn::CompareFunction::Always;
127 }
128}
129
130static dawn::StencilOperation to_dawn_stencil_operation(GrStencilOp op) {
131 switch (op) {
132 case GrStencilOp::kKeep:
133 return dawn::StencilOperation::Keep;
134 case GrStencilOp::kZero:
135 return dawn::StencilOperation::Zero;
136 case GrStencilOp::kReplace:
137 return dawn::StencilOperation::Replace;
138 case GrStencilOp::kInvert:
139 return dawn::StencilOperation::Invert;
140 case GrStencilOp::kIncClamp:
141 return dawn::StencilOperation::IncrementClamp;
142 case GrStencilOp::kDecClamp:
143 return dawn::StencilOperation::DecrementClamp;
144 case GrStencilOp::kIncWrap:
145 return dawn::StencilOperation::IncrementWrap;
146 case GrStencilOp::kDecWrap:
147 return dawn::StencilOperation::DecrementWrap;
148 default:
149 SkASSERT(!"unsupported stencil function");
150 return dawn::StencilOperation::Keep;
151 }
152}
153
Stephen Whitee2641312019-08-29 15:10:50 -0400154static dawn::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primitiveType) {
155 switch (primitiveType) {
156 case GrPrimitiveType::kTriangles:
157 return dawn::PrimitiveTopology::TriangleList;
158 case GrPrimitiveType::kTriangleStrip:
159 return dawn::PrimitiveTopology::TriangleStrip;
160 case GrPrimitiveType::kPoints:
161 return dawn::PrimitiveTopology::PointList;
162 case GrPrimitiveType::kLines:
163 return dawn::PrimitiveTopology::LineList;
164 case GrPrimitiveType::kLineStrip:
165 return dawn::PrimitiveTopology::LineStrip;
166 case GrPrimitiveType::kLinesAdjacency:
167 default:
168 SkASSERT(!"unsupported primitive topology");
169 return dawn::PrimitiveTopology::TriangleList;
170 }
171}
172
173static dawn::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
174 switch (type) {
175 case kFloat_GrVertexAttribType:
176 case kHalf_GrVertexAttribType:
177 return dawn::VertexFormat::Float;
178 case kFloat2_GrVertexAttribType:
179 case kHalf2_GrVertexAttribType:
180 return dawn::VertexFormat::Float2;
181 case kFloat3_GrVertexAttribType:
182 case kHalf3_GrVertexAttribType:
183 return dawn::VertexFormat::Float3;
184 case kFloat4_GrVertexAttribType:
185 case kHalf4_GrVertexAttribType:
186 return dawn::VertexFormat::Float4;
187 case kUShort2_GrVertexAttribType:
188 return dawn::VertexFormat::UShort2;
189 case kInt_GrVertexAttribType:
190 return dawn::VertexFormat::Int;
191 case kUByte4_norm_GrVertexAttribType:
192 return dawn::VertexFormat::UChar4Norm;
193 default:
194 SkASSERT(!"unsupported vertex format");
195 return dawn::VertexFormat::Float4;
196 }
197}
198
Stephen Whitebb6bed12019-08-02 09:57:55 -0400199static dawn::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
200 const GrPipeline& pipeline,
201 dawn::TextureFormat colorFormat) {
202 GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
203 GrBlendEquation equation = blendInfo.fEquation;
204 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
205 GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
206
207 dawn::BlendFactor srcFactor = to_dawn_blend_factor(srcCoeff);
208 dawn::BlendFactor dstFactor = to_dawn_blend_factor(dstCoeff);
Stephen Whitef813ef72019-08-09 12:28:37 -0400209 dawn::BlendFactor srcFactorAlpha = to_dawn_blend_factor_for_alpha(srcCoeff);
210 dawn::BlendFactor dstFactorAlpha = to_dawn_blend_factor_for_alpha(dstCoeff);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400211 dawn::BlendOperation operation = to_dawn_blend_operation(equation);
212 auto mask = blendInfo.fWriteColor ? dawn::ColorWriteMask::All : dawn::ColorWriteMask::None;
213
214 dawn::BlendDescriptor colorDesc = {operation, srcFactor, dstFactor};
Stephen Whitef813ef72019-08-09 12:28:37 -0400215 dawn::BlendDescriptor alphaDesc = {operation, srcFactorAlpha, dstFactorAlpha};
Stephen Whitebb6bed12019-08-02 09:57:55 -0400216
217 dawn::ColorStateDescriptor descriptor;
218 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 Whitef813ef72019-08-09 12:28:37 -0400227static dawn::StencilStateFaceDescriptor to_stencil_state_face(const GrStencilSettings::Face& face) {
228 dawn::StencilStateFaceDescriptor desc;
229 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
235static dawn::DepthStencilStateDescriptor create_depth_stencil_state(
236 const GrStencilSettings& stencilSettings,
237 dawn::TextureFormat depthStencilFormat,
238 GrSurfaceOrigin origin) {
239 dawn::DepthStencilStateDescriptor state;
240 state.format = depthStencilFormat;
Stephen Whitee2641312019-08-29 15:10:50 -0400241 if (!stencilSettings.isDisabled()) {
Stephen Whitef813ef72019-08-09 12:28:37 -0400242 const GrStencilSettings::Face& front = stencilSettings.front(origin);
243 state.stencilReadMask = front.fTestMask;
244 state.stencilWriteMask = front.fWriteMask;
245 state.stencilFront = to_stencil_state_face(stencilSettings.front(origin));
246 if (stencilSettings.isTwoSided()) {
247 state.stencilBack = to_stencil_state_face(stencilSettings.back(origin));
248 } else {
249 state.stencilBack = state.stencilFront;
250 }
251 }
252 return state;
253}
254
Stephen Whitebb6bed12019-08-02 09:57:55 -0400255static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding, const dawn::Buffer& buffer,
256 uint32_t offset, uint32_t size, const
257 dawn::Sampler& sampler,
258 const dawn::TextureView& textureView) {
259 dawn::BindGroupBinding result;
260 result.binding = binding;
261 result.buffer = buffer;
262 result.offset = offset;
263 result.size = size;
264 result.sampler = sampler;
265 result.textureView = textureView;
266 return result;
267}
268
269static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding, const dawn::Buffer& buffer,
270 uint32_t offset, uint32_t size) {
271 return make_bind_group_binding(binding, buffer, offset, size, nullptr, nullptr);
272}
273
Stephen White170d9902019-08-15 16:48:24 -0400274static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding,
275 const dawn::Sampler& sampler) {
276 return make_bind_group_binding(binding, nullptr, 0, 0, sampler, nullptr);
277}
278
279static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding,
280 const dawn::TextureView& textureView) {
281 return make_bind_group_binding(binding, nullptr, 0, 0, nullptr, textureView);
282}
283
Stephen Whitebb6bed12019-08-02 09:57:55 -0400284sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
285 GrRenderTarget* renderTarget,
286 GrSurfaceOrigin origin,
287 const GrPipeline& pipeline,
288 const GrPrimitiveProcessor& primProc,
289 const GrTextureProxy* const primProcProxies[],
Stephen Whitee2641312019-08-29 15:10:50 -0400290 GrPrimitiveType primitiveType,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400291 dawn::TextureFormat colorFormat,
Stephen Whitef813ef72019-08-09 12:28:37 -0400292 bool hasDepthStencil,
293 dawn::TextureFormat depthStencilFormat,
Stephen Whitebb6bed12019-08-02 09:57:55 -0400294 GrProgramDesc* desc) {
295 GrDawnProgramBuilder builder(gpu, renderTarget, origin, primProc, primProcProxies, pipeline,
296 desc);
297 if (!builder.emitAndInstallProcs()) {
298 return nullptr;
299 }
300
301 builder.fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
302 builder.fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
303 builder.fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
304 builder.fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
305
306 builder.finalizeShaders();
307
308 SkSL::Program::Inputs vertInputs, fragInputs;
309 GrDawnUniformHandler::UniformInfoArray& uniforms = builder.fUniformHandler.fUniforms;
310 uint32_t geometryUniformSize = builder.fUniformHandler.fCurrentGeometryUBOOffset;
311 uint32_t fragmentUniformSize = builder.fUniformHandler.fCurrentFragmentUBOOffset;
312 sk_sp<GrDawnProgram> result(
313 new GrDawnProgram(uniforms, geometryUniformSize, fragmentUniformSize));
Stephen Whitee2641312019-08-29 15:10:50 -0400314 auto vsModule = builder.createShaderModule(builder.fVS, SkSL::Program::kVertex_Kind,
315 &vertInputs);
316 auto fsModule = builder.createShaderModule(builder.fFS, SkSL::Program::kFragment_Kind,
317 &fragInputs);
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;
322 std::vector<dawn::BindGroupLayoutBinding> layoutBindings;
Stephen White170d9902019-08-15 16:48:24 -0400323 if (0 != geometryUniformSize) {
324 layoutBindings.push_back({ GrDawnUniformHandler::kGeometryBinding,
325 dawn::ShaderStageBit::Vertex,
326 dawn::BindingType::UniformBuffer});
327 }
328 if (0 != fragmentUniformSize) {
329 layoutBindings.push_back({ GrDawnUniformHandler::kFragBinding,
330 dawn::ShaderStageBit::Fragment,
331 dawn::BindingType::UniformBuffer});
332 }
333 uint32_t binding = GrDawnUniformHandler::kSamplerBindingBase;
334 for (int i = 0; i < builder.fUniformHandler.fSamplers.count(); ++i) {
335 layoutBindings.push_back({ binding++, dawn::ShaderStageBit::Fragment,
336 dawn::BindingType::Sampler});
337 layoutBindings.push_back({ binding++, dawn::ShaderStageBit::Fragment,
338 dawn::BindingType::SampledTexture});
339 }
340 dawn::BindGroupLayoutDescriptor bindGroupLayoutDesc;
341 bindGroupLayoutDesc.bindingCount = layoutBindings.size();
342 bindGroupLayoutDesc.bindings = layoutBindings.data();
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400343 result->fBindGroupLayout = gpu->device().CreateBindGroupLayout(&bindGroupLayoutDesc);
Stephen White170d9902019-08-15 16:48:24 -0400344 dawn::PipelineLayoutDescriptor pipelineLayoutDesc;
345 pipelineLayoutDesc.bindGroupLayoutCount = 1;
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400346 pipelineLayoutDesc.bindGroupLayouts = &result->fBindGroupLayout;
Stephen Whitee2641312019-08-29 15:10:50 -0400347 auto pipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400348 result->fBuiltinUniformHandles = builder.fUniformHandles;
Stephen Whitee2641312019-08-29 15:10:50 -0400349 auto colorState = create_color_state(gpu, pipeline, colorFormat);
350 dawn::DepthStencilStateDescriptor depthStencilState;
Stephen Whitef813ef72019-08-09 12:28:37 -0400351 GrStencilSettings stencil;
352 if (pipeline.isStencilEnabled()) {
353 int numStencilBits = renderTarget->renderTargetPriv().numStencilBits();
354 stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(), numStencilBits);
355 }
Stephen Whitee2641312019-08-29 15:10:50 -0400356 depthStencilState = create_depth_stencil_state(stencil, depthStencilFormat, origin);
357
358 std::vector<dawn::VertexBufferDescriptor> inputs;
359
360 std::vector<dawn::VertexAttributeDescriptor> vertexAttributes;
361 if (primProc.numVertexAttributes() > 0) {
362 size_t offset = 0;
363 int i = 0;
364 for (const auto& attrib : primProc.vertexAttributes()) {
365 dawn::VertexAttributeDescriptor attribute;
366 attribute.shaderLocation = i;
367 attribute.offset = offset;
368 attribute.format = to_dawn_vertex_format(attrib.cpuType());
369 vertexAttributes.push_back(attribute);
370 offset += attrib.sizeAlign4();
371 i++;
372 }
373 dawn::VertexBufferDescriptor input;
374 input.stride = offset;
375 input.stepMode = dawn::InputStepMode::Vertex;
376 input.attributeCount = vertexAttributes.size();
377 input.attributes = &vertexAttributes.front();
378 inputs.push_back(input);
379 }
380 std::vector<dawn::VertexAttributeDescriptor> instanceAttributes;
381 if (primProc.numInstanceAttributes() > 0) {
382 size_t offset = 0;
383 int i = 0;
384 for (const auto& attrib : primProc.instanceAttributes()) {
385 dawn::VertexAttributeDescriptor attribute;
386 attribute.shaderLocation = i;
387 attribute.offset = offset;
388 attribute.format = to_dawn_vertex_format(attrib.cpuType());
389 instanceAttributes.push_back(attribute);
390 offset += attrib.sizeAlign4();
391 i++;
392 }
393 dawn::VertexBufferDescriptor input;
394 input.stride = offset;
395 input.stepMode = dawn::InputStepMode::Instance;
396 input.attributeCount = instanceAttributes.size();
397 input.attributes = &instanceAttributes.front();
398 inputs.push_back(input);
399 }
400 dawn::VertexInputDescriptor vertexInput;
401 vertexInput.indexFormat = dawn::IndexFormat::Uint16;
402 vertexInput.bufferCount = inputs.size();
403 vertexInput.buffers = &inputs.front();
404
405 dawn::PipelineStageDescriptor vsDesc;
406 vsDesc.module = vsModule;
407 vsDesc.entryPoint = "main";
408
409 dawn::PipelineStageDescriptor fsDesc;
410 fsDesc.module = fsModule;
411 fsDesc.entryPoint = "main";
412
413 dawn::RenderPipelineDescriptor rpDesc;
414 rpDesc.layout = pipelineLayout;
415 rpDesc.vertexStage = &vsDesc;
416 rpDesc.fragmentStage = &fsDesc;
417 rpDesc.vertexInput = &vertexInput;
418 rpDesc.primitiveTopology = to_dawn_primitive_topology(primitiveType);
419 if (hasDepthStencil) {
420 rpDesc.depthStencilState = &depthStencilState;
421 }
422 rpDesc.colorStateCount = 1;
423 dawn::ColorStateDescriptor* colorStatesPtr[] = { &colorState };
424 rpDesc.colorStates = colorStatesPtr;
425 result->fRenderPipeline = gpu->device().CreateRenderPipeline(&rpDesc);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400426 return result;
427}
428
429GrDawnProgramBuilder::GrDawnProgramBuilder(GrDawnGpu* gpu,
430 GrRenderTarget* renderTarget,
431 GrSurfaceOrigin origin,
432 const GrPrimitiveProcessor& primProc,
433 const GrTextureProxy* const primProcProxies[],
434 const GrPipeline& pipeline,
435 GrProgramDesc* desc)
436 : INHERITED(renderTarget, origin, primProc, primProcProxies, pipeline, desc)
437 , fGpu(gpu)
438 , fVaryingHandler(this)
439 , fUniformHandler(this) {
440}
441
442dawn::ShaderModule GrDawnProgramBuilder::createShaderModule(const GrGLSLShaderBuilder& builder,
443 SkSL::Program::Kind kind,
444 SkSL::Program::Inputs* inputs) {
445 dawn::Device device = fGpu->device();
446 SkString source(builder.fCompilerString.c_str());
447
448#if 0
449 SkSL::String sksl = GrShaderUtils::PrettyPrint(builder.fCompilerString);
450 printf("converting program:\n%s\n", sksl.c_str());
451#endif
452
453 SkSL::String spirvSource = sksl_to_spirv(fGpu, source.c_str(), kind, inputs);
454
455 dawn::ShaderModuleDescriptor desc;
456 desc.codeSize = spirvSource.size() / 4;
457 desc.code = reinterpret_cast<const uint32_t*>(spirvSource.c_str());
458
459 return device.CreateShaderModule(&desc);
460};
461
462const GrCaps* GrDawnProgramBuilder::caps() const {
463 return fGpu->caps();
464}
465
466void GrDawnProgram::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
467 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
468 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
469 fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
470 fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
471 }
472
473 // set RT adjustment
474 SkISize size;
475 size.set(rt->width(), rt->height());
476 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
477 if (fRenderTargetState.fRenderTargetOrigin != origin ||
478 fRenderTargetState.fRenderTargetSize != size) {
479 fRenderTargetState.fRenderTargetSize = size;
480 fRenderTargetState.fRenderTargetOrigin = origin;
481
482 float rtAdjustmentVec[4];
483 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
484 fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
485 }
486}
487
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400488static void setTexture(GrDawnGpu* gpu, const GrSamplerState& state, GrTexture* texture,
489 std::vector<dawn::BindGroupBinding> *bindings, int* binding) {
490 // FIXME: could probably cache samplers in GrDawnProgram
Stephen Whitec0c05042019-09-10 16:15:23 -0400491 dawn::Sampler sampler = gpu->getOrCreateSampler(state);
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400492 bindings->push_back(make_bind_group_binding((*binding)++, sampler));
493 GrDawnTexture* tex = static_cast<GrDawnTexture*>(texture);
494 dawn::TextureView textureView = tex->textureView();
495 bindings->push_back(make_bind_group_binding((*binding)++, textureView));
496}
497
498dawn::BindGroup GrDawnProgram::setData(GrDawnGpu* gpu, const GrRenderTarget* renderTarget,
499 GrSurfaceOrigin origin,
500 const GrPrimitiveProcessor& primProc,
501 const GrPipeline& pipeline,
502 const GrTextureProxy* const primProcTextures[]) {
503 std::vector<dawn::BindGroupBinding> bindings;
504 GrDawnRingBuffer::Slice geom, frag;
505 uint32_t geometryUniformSize = fDataManager.geometryUniformSize();
506 uint32_t fragmentUniformSize = fDataManager.fragmentUniformSize();
507 if (0 != geometryUniformSize) {
508 geom = gpu->allocateUniformRingBufferSlice(geometryUniformSize);
509 bindings.push_back(make_bind_group_binding(GrDawnUniformHandler::kGeometryBinding,
510 geom.fBuffer, geom.fOffset,
511 geometryUniformSize));
512 }
513 if (0 != fragmentUniformSize) {
514 frag = gpu->allocateUniformRingBufferSlice(fragmentUniformSize);
515 bindings.push_back(make_bind_group_binding(GrDawnUniformHandler::kFragBinding,
516 frag.fBuffer, frag.fOffset,
517 fragmentUniformSize));
518 }
Stephen Whitebb6bed12019-08-02 09:57:55 -0400519 this->setRenderTargetState(renderTarget, origin);
520 fGeometryProcessor->setData(fDataManager, primProc,
521 GrFragmentProcessor::CoordTransformIter(pipeline));
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400522 int binding = GrDawnUniformHandler::kSamplerBindingBase;
523 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
524 auto& sampler = primProc.textureSampler(i);
525 setTexture(gpu, sampler.samplerState(), primProcTextures[i]->peekTexture(), &bindings,
526 &binding);
527 }
Stephen Whitebb6bed12019-08-02 09:57:55 -0400528 GrFragmentProcessor::Iter iter(pipeline);
529 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
530 const GrFragmentProcessor* fp = iter.next();
531 GrGLSLFragmentProcessor* glslFP = glslIter.next();
532 while (fp && glslFP) {
533 glslFP->setData(fDataManager, *fp);
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400534 for (int i = 0; i < fp->numTextureSamplers(); ++i) {
535 auto& s = fp->textureSampler(i);
536 setTexture(gpu, s.samplerState(), s.peekTexture(), &bindings, &binding);
537 }
Stephen Whitebb6bed12019-08-02 09:57:55 -0400538 fp = iter.next();
539 glslFP = glslIter.next();
540 }
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400541 SkIPoint offset;
542 GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
543 fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
544 if (GrTextureProxy* proxy = pipeline.dstTextureProxy()) {
545 GrFragmentProcessor::TextureSampler sampler(sk_ref_sp(proxy));
546 setTexture(gpu, sampler.samplerState(), sampler.peekTexture(), &bindings, &binding);
547 }
Stephen White7fba36b2019-09-10 13:05:22 -0400548 fDataManager.uploadUniformBuffers(gpu, geom, frag);
Stephen Whiteb7eaedc2019-08-21 09:48:05 -0400549 dawn::BindGroupDescriptor descriptor;
550 descriptor.layout = fBindGroupLayout;
551 descriptor.bindingCount = bindings.size();
552 descriptor.bindings = bindings.data();
553 return gpu->device().CreateBindGroup(&descriptor);
Stephen Whitebb6bed12019-08-02 09:57:55 -0400554}