Home | History | Annotate | Download | only in glsl
      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