• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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/ganesh/GrShaderCaps.h"
9 #include "src/gpu/ganesh/glsl/GrGLSLProgramBuilder.h"
10 #include "src/gpu/ganesh/glsl/GrGLSLVarying.h"
11 
addPassThroughAttribute(const GrShaderVar & vsVar,const char * output,Interpolation interpolation)12 void GrGLSLVaryingHandler::addPassThroughAttribute(const GrShaderVar& vsVar,
13                                                    const char* output,
14                                                    Interpolation interpolation) {
15     SkASSERT(vsVar.getType() != SkSLType::kVoid);
16     GrGLSLVarying v(vsVar.getType());
17     this->addVarying(vsVar.c_str(), &v, interpolation);
18     fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), vsVar.c_str());
19     fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn());
20 }
21 
use_flat_interpolation(GrGLSLVaryingHandler::Interpolation interpolation,const GrShaderCaps & shaderCaps)22 static bool use_flat_interpolation(GrGLSLVaryingHandler::Interpolation interpolation,
23                                    const GrShaderCaps& shaderCaps) {
24     switch (interpolation) {
25         using Interpolation = GrGLSLVaryingHandler::Interpolation;
26         case Interpolation::kInterpolated:
27             return false;
28         case Interpolation::kCanBeFlat:
29             SkASSERT(!shaderCaps.fPreferFlatInterpolation || shaderCaps.fFlatInterpolationSupport);
30             return shaderCaps.fPreferFlatInterpolation;
31         case Interpolation::kMustBeFlat:
32             SkASSERT(shaderCaps.fFlatInterpolationSupport);
33             return true;
34     }
35     SK_ABORT("Invalid interpolation");
36 }
37 
addVarying(const char * name,GrGLSLVarying * varying,Interpolation interpolation)38 void GrGLSLVaryingHandler::addVarying(const char* name, GrGLSLVarying* varying,
39                                       Interpolation interpolation) {
40     SkASSERT(SkSLTypeIsFloatType(varying->type()) || Interpolation::kMustBeFlat == interpolation);
41     VaryingInfo& v = fVaryings.push_back();
42 
43     SkASSERT(varying);
44     SkASSERT(SkSLType::kVoid != varying->fType);
45     v.fType = varying->fType;
46     v.fIsFlat = use_flat_interpolation(interpolation, *fProgramBuilder->shaderCaps());
47     v.fVsOut = fProgramBuilder->nameVariable('v', name);
48     v.fVisibility = kNone_GrShaderFlags;
49     if (varying->isInVertexShader()) {
50         varying->fVsOut = v.fVsOut.c_str();
51         v.fVisibility |= kVertex_GrShaderFlag;
52     }
53     if (varying->isInFragmentShader()) {
54         varying->fFsIn = v.fVsOut.c_str();
55         v.fVisibility |= kFragment_GrShaderFlag;
56     }
57 }
58 
emitAttributes(const GrGeometryProcessor & gp)59 void GrGLSLVaryingHandler::emitAttributes(const GrGeometryProcessor& gp) {
60     for (auto attr : gp.vertexAttributes()) {
61         this->addAttribute(attr.asShaderVar());
62     }
63     for (auto attr : gp.instanceAttributes()) {
64         this->addAttribute(attr.asShaderVar());
65     }
66 }
67 
addAttribute(const GrShaderVar & var)68 void GrGLSLVaryingHandler::addAttribute(const GrShaderVar& var) {
69     SkASSERT(GrShaderVar::TypeModifier::In == var.getTypeModifier());
70     for (const GrShaderVar& attr : fVertexInputs.items()) {
71         // if attribute already added, don't add it again
72         if (attr.getName().equals(var.getName())) {
73             return;
74         }
75     }
76     fVertexInputs.push_back(var);
77 }
78 
setNoPerspective()79 void GrGLSLVaryingHandler::setNoPerspective() {
80     const GrShaderCaps& caps = *fProgramBuilder->shaderCaps();
81     if (!caps.fNoPerspectiveInterpolationSupport) {
82         return;
83     }
84     if (const char* extension = caps.noperspectiveInterpolationExtensionString()) {
85         int bit = 1 << GrGLSLShaderBuilder::kNoPerspectiveInterpolation_GLSLPrivateFeature;
86         fProgramBuilder->fVS.addFeature(bit, extension);
87         fProgramBuilder->fFS.addFeature(bit, extension);
88     }
89     fDefaultInterpolationModifier = "noperspective";
90 }
91 
finalize()92 void GrGLSLVaryingHandler::finalize() {
93     for (const VaryingInfo& v : fVaryings.items()) {
94         const char* modifier = v.fIsFlat ? "flat" : fDefaultInterpolationModifier;
95         if (v.fVisibility & kVertex_GrShaderFlag) {
96             fVertexOutputs.emplace_back(v.fVsOut, v.fType, GrShaderVar::TypeModifier::Out,
97                                         GrShaderVar::kNonArray, SkString(), SkString(modifier));
98         }
99         if (v.fVisibility & kFragment_GrShaderFlag) {
100             const char* fsIn = v.fVsOut.c_str();
101             fFragInputs.emplace_back(SkString(fsIn), v.fType, GrShaderVar::TypeModifier::In,
102                                      GrShaderVar::kNonArray, SkString(), SkString(modifier));
103         }
104     }
105     this->onFinalize();
106 }
107 
appendDecls(const VarArray & vars,SkString * out) const108 void GrGLSLVaryingHandler::appendDecls(const VarArray& vars, SkString* out) const {
109     for (const GrShaderVar& varying : vars.items()) {
110         varying.appendDecl(fProgramBuilder->shaderCaps(), out);
111         out->append(";");
112     }
113 }
114 
getVertexDecls(SkString * inputDecls,SkString * outputDecls) const115 void GrGLSLVaryingHandler::getVertexDecls(SkString* inputDecls, SkString* outputDecls) const {
116     this->appendDecls(fVertexInputs, inputDecls);
117     this->appendDecls(fVertexOutputs, outputDecls);
118 }
119 
getFragDecls(SkString * inputDecls,SkString * outputDecls) const120 void GrGLSLVaryingHandler::getFragDecls(SkString* inputDecls, SkString* outputDecls) const {
121     // We should not have any outputs in the fragment shader when using version 1.10
122     SkASSERT(SkSL::GLSLGeneration::k110 != fProgramBuilder->shaderCaps()->fGLSLGeneration ||
123              fFragOutputs.empty());
124     this->appendDecls(fFragInputs, inputDecls);
125     this->appendDecls(fFragOutputs, outputDecls);
126 }
127