• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "src/sksl/SkSLCompiler.h"
16 
sksl_to_spirv(const GrDawnGpu * gpu,const char * shaderString,SkSL::Program::Kind kind,SkSL::Program::Inputs * inputs)17 static 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;
20     settings.fCaps = gpu->caps()->shaderCaps();
21     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 
to_dawn_blend_factor(GrBlendCoeff coeff)38 static 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 
to_dawn_blend_factor_for_alpha(GrBlendCoeff coeff)76 static 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 
to_dawn_blend_operation(GrBlendEquation equation)92 static 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;
98     case kReverseSubtract_GrBlendEquation:
99         return dawn::BlendOperation::ReverseSubtract;
100     default:
101         SkASSERT(!"unsupported blend equation");
102         return dawn::BlendOperation::Add;
103     }
104 }
105 
to_dawn_compare_function(GrStencilTest test)106 static 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 
to_dawn_stencil_operation(GrStencilOp op)130 static 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 
to_dawn_filter_mode(GrSamplerState::Filter filter)154 static dawn::FilterMode to_dawn_filter_mode(GrSamplerState::Filter filter) {
155     switch (filter) {
156         case GrSamplerState::Filter::kNearest:
157             return dawn::FilterMode::Nearest;
158         case GrSamplerState::Filter::kBilerp:
159         case GrSamplerState::Filter::kMipMap:
160             return dawn::FilterMode::Linear;
161         default:
162             SkASSERT(!"unsupported filter mode");
163             return dawn::FilterMode::Nearest;
164     }
165 }
166 
to_dawn_address_mode(GrSamplerState::WrapMode wrapMode)167 static dawn::AddressMode to_dawn_address_mode(GrSamplerState::WrapMode wrapMode) {
168     switch (wrapMode) {
169         case GrSamplerState::WrapMode::kClamp:
170             return dawn::AddressMode::ClampToEdge;
171         case GrSamplerState::WrapMode::kClampToBorder:
172             // TODO: unsupported
173             return dawn::AddressMode::ClampToEdge;
174         case GrSamplerState::WrapMode::kRepeat:
175             return dawn::AddressMode::Repeat;
176         case GrSamplerState::WrapMode::kMirrorRepeat:
177             return dawn::AddressMode::MirrorRepeat;
178     }
179     SkASSERT(!"unsupported address mode");
180     return dawn::AddressMode::ClampToEdge;
181 }
182 
create_color_state(const GrDawnGpu * gpu,const GrPipeline & pipeline,dawn::TextureFormat colorFormat)183 static dawn::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
184                                                      const GrPipeline& pipeline,
185                                                      dawn::TextureFormat colorFormat) {
186     GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
187     GrBlendEquation equation = blendInfo.fEquation;
188     GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
189     GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
190 
191     dawn::BlendFactor srcFactor = to_dawn_blend_factor(srcCoeff);
192     dawn::BlendFactor dstFactor = to_dawn_blend_factor(dstCoeff);
193     dawn::BlendFactor srcFactorAlpha = to_dawn_blend_factor_for_alpha(srcCoeff);
194     dawn::BlendFactor dstFactorAlpha = to_dawn_blend_factor_for_alpha(dstCoeff);
195     dawn::BlendOperation operation = to_dawn_blend_operation(equation);
196     auto mask = blendInfo.fWriteColor ? dawn::ColorWriteMask::All : dawn::ColorWriteMask::None;
197 
198     dawn::BlendDescriptor colorDesc = {operation, srcFactor, dstFactor};
199     dawn::BlendDescriptor alphaDesc = {operation, srcFactorAlpha, dstFactorAlpha};
200 
201     dawn::ColorStateDescriptor descriptor;
202     descriptor.format = colorFormat;
203     descriptor.alphaBlend = alphaDesc;
204     descriptor.colorBlend = colorDesc;
205     descriptor.nextInChain = nullptr;
206     descriptor.writeMask = mask;
207 
208     return descriptor;
209 }
210 
to_stencil_state_face(const GrStencilSettings::Face & face)211 static dawn::StencilStateFaceDescriptor to_stencil_state_face(const GrStencilSettings::Face& face) {
212      dawn::StencilStateFaceDescriptor desc;
213      desc.compare = to_dawn_compare_function(face.fTest);
214      desc.failOp = desc.depthFailOp = to_dawn_stencil_operation(face.fFailOp);
215      desc.passOp = to_dawn_stencil_operation(face.fPassOp);
216      return desc;
217 }
218 
create_depth_stencil_state(const GrStencilSettings & stencilSettings,dawn::TextureFormat depthStencilFormat,GrSurfaceOrigin origin)219 static dawn::DepthStencilStateDescriptor create_depth_stencil_state(
220         const GrStencilSettings& stencilSettings,
221         dawn::TextureFormat depthStencilFormat,
222         GrSurfaceOrigin origin) {
223     dawn::DepthStencilStateDescriptor state;
224     state.format = depthStencilFormat;
225     state.depthWriteEnabled = false;
226     state.depthCompare = dawn::CompareFunction::Always;
227     if (stencilSettings.isDisabled()) {
228         dawn::StencilStateFaceDescriptor stencilFace;
229         stencilFace.compare = dawn::CompareFunction::Always;
230         stencilFace.failOp = dawn::StencilOperation::Keep;
231         stencilFace.depthFailOp = dawn::StencilOperation::Keep;
232         stencilFace.passOp = dawn::StencilOperation::Keep;
233         state.stencilReadMask = state.stencilWriteMask = 0x0;
234         state.stencilBack = state.stencilFront = stencilFace;
235     } else {
236         const GrStencilSettings::Face& front = stencilSettings.front(origin);
237         state.stencilReadMask = front.fTestMask;
238         state.stencilWriteMask = front.fWriteMask;
239         state.stencilFront = to_stencil_state_face(stencilSettings.front(origin));
240         if (stencilSettings.isTwoSided()) {
241             state.stencilBack = to_stencil_state_face(stencilSettings.back(origin));
242         } else {
243             state.stencilBack = state.stencilFront;
244         }
245     }
246     return state;
247 }
248 
create_sampler(const GrDawnGpu * gpu,const GrSamplerState & samplerState)249 static dawn::Sampler create_sampler(const GrDawnGpu* gpu, const GrSamplerState& samplerState) {
250     dawn::SamplerDescriptor desc;
251     desc.addressModeU = to_dawn_address_mode(samplerState.wrapModeX());
252     desc.addressModeV = to_dawn_address_mode(samplerState.wrapModeY());
253     desc.addressModeW = dawn::AddressMode::ClampToEdge;
254     desc.magFilter = desc.minFilter = to_dawn_filter_mode(samplerState.filter());
255     desc.mipmapFilter = dawn::FilterMode::Linear;
256     desc.lodMinClamp = 0.0f;
257     desc.lodMaxClamp = 1000.0f;
258     desc.compare = dawn::CompareFunction::Never;
259     return gpu->device().CreateSampler(&desc);
260 }
261 
make_bind_group_binding(uint32_t binding,const dawn::Buffer & buffer,uint32_t offset,uint32_t size,const dawn::Sampler & sampler,const dawn::TextureView & textureView)262 static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding, const dawn::Buffer& buffer,
263                                                       uint32_t offset, uint32_t size, const
264                                                       dawn::Sampler& sampler,
265                                                       const dawn::TextureView& textureView) {
266     dawn::BindGroupBinding result;
267     result.binding = binding;
268     result.buffer = buffer;
269     result.offset = offset;
270     result.size = size;
271     result.sampler = sampler;
272     result.textureView = textureView;
273     return result;
274 }
275 
make_bind_group_binding(uint32_t binding,const dawn::Buffer & buffer,uint32_t offset,uint32_t size)276 static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding, const dawn::Buffer& buffer,
277                                                       uint32_t offset, uint32_t size) {
278     return make_bind_group_binding(binding, buffer, offset, size, nullptr, nullptr);
279 }
280 
make_bind_group_binding(uint32_t binding,const dawn::Sampler & sampler)281 static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding,
282                                                       const dawn::Sampler& sampler) {
283     return make_bind_group_binding(binding, nullptr, 0, 0, sampler, nullptr);
284 }
285 
make_bind_group_binding(uint32_t binding,const dawn::TextureView & textureView)286 static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding,
287                                                       const dawn::TextureView& textureView) {
288     return make_bind_group_binding(binding, nullptr, 0, 0, nullptr, textureView);
289 }
290 
Build(GrDawnGpu * gpu,GrRenderTarget * renderTarget,GrSurfaceOrigin origin,const GrPipeline & pipeline,const GrPrimitiveProcessor & primProc,const GrTextureProxy * const primProcProxies[],dawn::TextureFormat colorFormat,bool hasDepthStencil,dawn::TextureFormat depthStencilFormat,GrProgramDesc * desc)291 sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
292                                                  GrRenderTarget* renderTarget,
293                                                  GrSurfaceOrigin origin,
294                                                  const GrPipeline& pipeline,
295                                                  const GrPrimitiveProcessor& primProc,
296                                                  const GrTextureProxy* const primProcProxies[],
297                                                  dawn::TextureFormat colorFormat,
298                                                  bool hasDepthStencil,
299                                                  dawn::TextureFormat depthStencilFormat,
300                                                  GrProgramDesc* desc) {
301     GrDawnProgramBuilder builder(gpu, renderTarget, origin, primProc, primProcProxies, pipeline,
302                                  desc);
303     if (!builder.emitAndInstallProcs()) {
304         return nullptr;
305     }
306 
307     builder.fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
308     builder.fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
309     builder.fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
310     builder.fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
311 
312     builder.finalizeShaders();
313 
314     SkSL::Program::Inputs vertInputs, fragInputs;
315     GrDawnUniformHandler::UniformInfoArray& uniforms = builder.fUniformHandler.fUniforms;
316     uint32_t geometryUniformSize = builder.fUniformHandler.fCurrentGeometryUBOOffset;
317     uint32_t fragmentUniformSize = builder.fUniformHandler.fCurrentFragmentUBOOffset;
318     sk_sp<GrDawnProgram> result(
319         new GrDawnProgram(uniforms, geometryUniformSize, fragmentUniformSize));
320     result->fVSModule = builder.createShaderModule(builder.fVS, SkSL::Program::kVertex_Kind,
321                                                    &vertInputs);
322     result->fFSModule = builder.createShaderModule(builder.fFS, SkSL::Program::kFragment_Kind,
323                                                    &fragInputs);
324     result->fGeometryProcessor = std::move(builder.fGeometryProcessor);
325     result->fXferProcessor = std::move(builder.fXferProcessor);
326     result->fFragmentProcessors = std::move(builder.fFragmentProcessors);
327     result->fFragmentProcessorCnt = builder.fFragmentProcessorCnt;
328     std::vector<dawn::BindGroupLayoutBinding> layoutBindings;
329     std::vector<dawn::BindGroupBinding> bindings;
330     if (0 != geometryUniformSize) {
331         layoutBindings.push_back({ GrDawnUniformHandler::kGeometryBinding,
332                                    dawn::ShaderStageBit::Vertex,
333                                    dawn::BindingType::UniformBuffer});
334     }
335     if (0 != fragmentUniformSize) {
336         layoutBindings.push_back({ GrDawnUniformHandler::kFragBinding,
337                                    dawn::ShaderStageBit::Fragment,
338                                    dawn::BindingType::UniformBuffer});
339     }
340     uint32_t binding = GrDawnUniformHandler::kSamplerBindingBase;
341     for (int i = 0; i < builder.fUniformHandler.fSamplers.count(); ++i) {
342         layoutBindings.push_back({ binding++, dawn::ShaderStageBit::Fragment,
343                                    dawn::BindingType::Sampler});
344         layoutBindings.push_back({ binding++, dawn::ShaderStageBit::Fragment,
345                                    dawn::BindingType::SampledTexture});
346     }
347     dawn::BindGroupLayoutDescriptor bindGroupLayoutDesc;
348     bindGroupLayoutDesc.bindingCount = layoutBindings.size();
349     bindGroupLayoutDesc.bindings = layoutBindings.data();
350     auto bindGroupLayout = gpu->device().CreateBindGroupLayout(&bindGroupLayoutDesc);
351     dawn::PipelineLayoutDescriptor pipelineLayoutDesc;
352     pipelineLayoutDesc.bindGroupLayoutCount = 1;
353     pipelineLayoutDesc.bindGroupLayouts = &bindGroupLayout;
354     result->fPipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
355     if (0 != geometryUniformSize) {
356         dawn::BufferDescriptor desc;
357         desc.usage = dawn::BufferUsageBit::Uniform | dawn::BufferUsageBit::CopyDst;
358         desc.size = geometryUniformSize;
359         result->fGeometryUniformBuffer = gpu->device().CreateBuffer(&desc);
360         bindings.push_back(make_bind_group_binding(GrDawnUniformHandler::kGeometryBinding,
361                                                    result->fGeometryUniformBuffer,
362                                                    0, geometryUniformSize));
363     }
364     if (0 != fragmentUniformSize) {
365         dawn::BufferDescriptor desc;
366         desc.usage = dawn::BufferUsageBit::Uniform | dawn::BufferUsageBit::CopyDst;
367         desc.size = fragmentUniformSize;
368         result->fFragmentUniformBuffer = gpu->device().CreateBuffer(&desc);
369         bindings.push_back(make_bind_group_binding(GrDawnUniformHandler::kFragBinding,
370                                                    result->fFragmentUniformBuffer,
371                                                    0, fragmentUniformSize));
372     }
373     binding = GrDawnUniformHandler::kSamplerBindingBase;
374     for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
375         dawn::Sampler sampler = create_sampler(gpu, primProc.textureSampler(i).samplerState());
376         bindings.push_back(make_bind_group_binding(binding++, sampler));
377         GrDawnTexture* tex = static_cast<GrDawnTexture*>(primProcProxies[i]->peekTexture());
378         dawn::TextureView textureView = tex->textureView();
379         bindings.push_back(make_bind_group_binding(binding++, textureView));
380     }
381     GrFragmentProcessor::Iter iter(pipeline);
382     const GrFragmentProcessor* fp = iter.next();
383     while (fp) {
384         for (int i = 0; i < fp->numTextureSamplers(); ++i) {
385             dawn::Sampler sampler = create_sampler(gpu, fp->textureSampler(i).samplerState());
386             bindings.push_back(make_bind_group_binding(binding++, sampler));
387             GrDawnTexture* tex = static_cast<GrDawnTexture*>(fp->textureSampler(i).peekTexture());
388             dawn::TextureView textureView = tex->textureView();
389             bindings.push_back(make_bind_group_binding(binding++, textureView));
390         }
391         fp = iter.next();
392     }
393     dawn::BindGroupDescriptor bindGroupDescriptor;
394     bindGroupDescriptor.layout = bindGroupLayout;
395     bindGroupDescriptor.bindingCount = bindings.size();
396     bindGroupDescriptor.bindings = bindings.data();
397     result->fBindGroup = gpu->device().CreateBindGroup(&bindGroupDescriptor);
398     result->fBuiltinUniformHandles = builder.fUniformHandles;
399     result->fColorState = create_color_state(gpu, pipeline, colorFormat);
400     GrStencilSettings stencil;
401     if (pipeline.isStencilEnabled()) {
402         int numStencilBits = renderTarget->renderTargetPriv().numStencilBits();
403         stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(), numStencilBits);
404     }
405     result->fDepthStencilState = create_depth_stencil_state(stencil, depthStencilFormat, origin);
406     return result;
407 }
408 
GrDawnProgramBuilder(GrDawnGpu * gpu,GrRenderTarget * renderTarget,GrSurfaceOrigin origin,const GrPrimitiveProcessor & primProc,const GrTextureProxy * const primProcProxies[],const GrPipeline & pipeline,GrProgramDesc * desc)409 GrDawnProgramBuilder::GrDawnProgramBuilder(GrDawnGpu* gpu,
410                                            GrRenderTarget* renderTarget,
411                                            GrSurfaceOrigin origin,
412                                            const GrPrimitiveProcessor& primProc,
413                                            const GrTextureProxy* const primProcProxies[],
414                                            const GrPipeline& pipeline,
415                                            GrProgramDesc* desc)
416     : INHERITED(renderTarget, origin, primProc, primProcProxies, pipeline, desc)
417     , fGpu(gpu)
418     , fVaryingHandler(this)
419     , fUniformHandler(this) {
420 }
421 
createShaderModule(const GrGLSLShaderBuilder & builder,SkSL::Program::Kind kind,SkSL::Program::Inputs * inputs)422 dawn::ShaderModule GrDawnProgramBuilder::createShaderModule(const GrGLSLShaderBuilder& builder,
423                                                             SkSL::Program::Kind kind,
424                                                             SkSL::Program::Inputs* inputs) {
425     dawn::Device device = fGpu->device();
426     SkString source(builder.fCompilerString.c_str());
427 
428 #if 0
429     SkSL::String sksl = GrShaderUtils::PrettyPrint(builder.fCompilerString);
430     printf("converting program:\n%s\n", sksl.c_str());
431 #endif
432 
433     SkSL::String spirvSource = sksl_to_spirv(fGpu, source.c_str(), kind, inputs);
434 
435     dawn::ShaderModuleDescriptor desc;
436     desc.codeSize = spirvSource.size() / 4;
437     desc.code = reinterpret_cast<const uint32_t*>(spirvSource.c_str());
438 
439     return device.CreateShaderModule(&desc);
440 };
441 
caps() const442 const GrCaps* GrDawnProgramBuilder::caps() const {
443     return fGpu->caps();
444 }
445 
setRenderTargetState(const GrRenderTarget * rt,GrSurfaceOrigin origin)446 void GrDawnProgram::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
447     // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
448     if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
449         fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
450         fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
451     }
452 
453     // set RT adjustment
454     SkISize size;
455     size.set(rt->width(), rt->height());
456     SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
457     if (fRenderTargetState.fRenderTargetOrigin != origin ||
458         fRenderTargetState.fRenderTargetSize != size) {
459         fRenderTargetState.fRenderTargetSize = size;
460         fRenderTargetState.fRenderTargetOrigin = origin;
461 
462         float rtAdjustmentVec[4];
463         fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
464         fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
465     }
466 }
467 
setData(const GrPrimitiveProcessor & primProc,const GrRenderTarget * renderTarget,GrSurfaceOrigin origin,const GrPipeline & pipeline)468 void GrDawnProgram::setData(const GrPrimitiveProcessor& primProc,
469                             const GrRenderTarget* renderTarget,
470                             GrSurfaceOrigin origin,
471                             const GrPipeline& pipeline) {
472     this->setRenderTargetState(renderTarget, origin);
473     fGeometryProcessor->setData(fDataManager, primProc,
474                                 GrFragmentProcessor::CoordTransformIter(pipeline));
475     GrFragmentProcessor::Iter iter(pipeline);
476     GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
477     const GrFragmentProcessor* fp = iter.next();
478     GrGLSLFragmentProcessor* glslFP = glslIter.next();
479     while (fp && glslFP) {
480         glslFP->setData(fDataManager, *fp);
481         fp = iter.next();
482         glslFP = glslIter.next();
483     }
484     fDataManager.uploadUniformBuffers(fGeometryUniformBuffer,
485                                       fFragmentUniformBuffer);
486 }
487