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