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 "glsl/GrGLSLVarying.h" 9 10 #include "glsl/GrGLSLProgramBuilder.h" 11 12 void GrGLSLVaryingHandler::addPassThroughAttribute(const GrGeometryProcessor::Attribute* input, 13 const char* output, GrSLPrecision precision) { 14 GrSLType type = GrVertexAttribTypeToSLType(input->fType); 15 GrGLSLVertToFrag v(type); 16 this->addVarying(input->fName, &v, precision); 17 this->writePassThroughAttribute(input, output, v); 18 } 19 20 void GrGLSLVaryingHandler::addFlatPassThroughAttribute(const GrGeometryProcessor::Attribute* input, 21 const char* output, 22 GrSLPrecision precision) { 23 GrSLType type = GrVertexAttribTypeToSLType(input->fType); 24 GrGLSLVertToFrag v(type); 25 this->addFlatVarying(input->fName, &v, precision); 26 this->writePassThroughAttribute(input, output, v); 27 } 28 29 void GrGLSLVaryingHandler::writePassThroughAttribute(const GrGeometryProcessor::Attribute* input, 30 const char* output, const GrGLSLVarying& v) { 31 fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); 32 33 if (fProgramBuilder->primitiveProcessor().willUseGeoShader()) { 34 fProgramBuilder->fGS.codeAppendf("%s = %s[0];", v.gsOut(), v.gsIn()); 35 } 36 37 fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn()); 38 } 39 40 void GrGLSLVaryingHandler::internalAddVarying(const char* name, 41 GrGLSLVarying* varying, 42 GrSLPrecision precision, 43 bool flat) { 44 bool willUseGeoShader = fProgramBuilder->primitiveProcessor().willUseGeoShader(); 45 VaryingInfo& v = fVaryings.push_back(); 46 47 SkASSERT(varying); 48 v.fType = varying->fType; 49 v.fPrecision = precision; 50 v.fIsFlat = flat; 51 fProgramBuilder->nameVariable(&v.fVsOut, 'v', name); 52 v.fVisibility = kNone_GrShaderFlags; 53 if (varying->vsVarying()) { 54 varying->fVsOut = v.fVsOut.c_str(); 55 v.fVisibility |= kVertex_GrShaderFlag; 56 } 57 if (willUseGeoShader) { 58 fProgramBuilder->nameVariable(&v.fGsOut, 'g', name); 59 varying->fGsIn = v.fVsOut.c_str(); 60 varying->fGsOut = v.fGsOut.c_str(); 61 v.fVisibility |= kGeometry_GrShaderFlag; 62 } 63 if (varying->fsVarying()) { 64 varying->fFsIn = (willUseGeoShader ? v.fGsOut : v.fVsOut).c_str(); 65 v.fVisibility |= kFragment_GrShaderFlag; 66 } 67 } 68 69 void GrGLSLVaryingHandler::emitAttributes(const GrGeometryProcessor& gp) { 70 int vaCount = gp.numAttribs(); 71 for (int i = 0; i < vaCount; i++) { 72 const GrGeometryProcessor::Attribute& attr = gp.getAttrib(i); 73 this->addAttribute(GrShaderVar(attr.fName, 74 GrVertexAttribTypeToSLType(attr.fType), 75 GrShaderVar::kAttribute_TypeModifier, 76 GrShaderVar::kNonArray, 77 attr.fPrecision)); 78 } 79 } 80 81 void GrGLSLVaryingHandler::addAttribute(const GrShaderVar& var) { 82 SkASSERT(GrShaderVar::kAttribute_TypeModifier == var.getTypeModifier()); 83 for (int j = 0; j < fVertexInputs.count(); ++j) { 84 const GrGLSLShaderVar& attr = fVertexInputs[j]; 85 // if attribute already added, don't add it again 86 if (attr.getName().equals(var.getName())) { 87 return; 88 } 89 } 90 fVertexInputs.push_back(var); 91 } 92 93 void GrGLSLVaryingHandler::setNoPerspective() { 94 const GrGLSLCaps& caps = *fProgramBuilder->glslCaps(); 95 if (!caps.noperspectiveInterpolationSupport()) { 96 return; 97 } 98 if (const char* extension = caps.noperspectiveInterpolationExtensionString()) { 99 int bit = 1 << GrGLSLFragmentBuilder::kNoPerspectiveInterpolation_GLSLPrivateFeature; 100 fProgramBuilder->fVS.addFeature(bit, extension); 101 if (fProgramBuilder->primitiveProcessor().willUseGeoShader()) { 102 fProgramBuilder->fGS.addFeature(bit, extension); 103 } 104 fProgramBuilder->fFS.addFeature(bit, extension); 105 } 106 fDefaultInterpolationModifier = "noperspective"; 107 } 108 109 void GrGLSLVaryingHandler::finalize() { 110 for (int i = 0; i < fVaryings.count(); ++i) { 111 const VaryingInfo& v = this->fVaryings[i]; 112 const char* modifier = v.fIsFlat ? "flat" : fDefaultInterpolationModifier; 113 if (v.fVisibility & kVertex_GrShaderFlag) { 114 fVertexOutputs.push_back().set(v.fType, GrShaderVar::kVaryingOut_TypeModifier, v.fVsOut, 115 v.fPrecision, nullptr, modifier); 116 if (v.fVisibility & kGeometry_GrShaderFlag) { 117 fGeomInputs.push_back().set(v.fType, GrShaderVar::kVaryingIn_TypeModifier, v.fVsOut, 118 GrShaderVar::kUnsizedArray, v.fPrecision, nullptr, 119 modifier); 120 } 121 } 122 if (v.fVisibility & kFragment_GrShaderFlag) { 123 const char* fsIn = v.fVsOut.c_str(); 124 if (v.fVisibility & kGeometry_GrShaderFlag) { 125 fGeomOutputs.push_back().set(v.fType, GrGLSLShaderVar::kVaryingOut_TypeModifier, 126 v.fGsOut, v.fPrecision, nullptr, modifier); 127 fsIn = v.fGsOut.c_str(); 128 } 129 fFragInputs.push_back().set(v.fType, GrShaderVar::kVaryingIn_TypeModifier, fsIn, 130 v.fPrecision, nullptr, modifier); 131 } 132 } 133 this->onFinalize(); 134 } 135 136 void GrGLSLVaryingHandler::appendDecls(const VarArray& vars, SkString* out) const { 137 for (int i = 0; i < vars.count(); ++i) { 138 vars[i].appendDecl(fProgramBuilder->glslCaps(), out); 139 out->append(";"); 140 } 141 } 142 143 void GrGLSLVaryingHandler::getVertexDecls(SkString* inputDecls, SkString* outputDecls) const { 144 this->appendDecls(fVertexInputs, inputDecls); 145 this->appendDecls(fVertexOutputs, outputDecls); 146 } 147 148 void GrGLSLVaryingHandler::getGeomDecls(SkString* inputDecls, SkString* outputDecls) const { 149 this->appendDecls(fGeomInputs, inputDecls); 150 this->appendDecls(fGeomOutputs, outputDecls); 151 } 152 153 void GrGLSLVaryingHandler::getFragDecls(SkString* inputDecls, SkString* outputDecls) const { 154 // We should not have any outputs in the fragment shader when using version 1.10 155 SkASSERT(k110_GrGLSLGeneration != fProgramBuilder->glslCaps()->generation() || 156 fFragOutputs.empty()); 157 this->appendDecls(fFragInputs, inputDecls); 158 this->appendDecls(fFragOutputs, outputDecls); 159 } 160 161