10eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel/*
20eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel * Copyright 2015 Google Inc.
30eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel *
40eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel * Use of this source code is governed by a BSD-style license that can be
50eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel * found in the LICENSE file.
60eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel */
70eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
80eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel#include "glsl/GrGLSLVarying.h"
90eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
100eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel#include "glsl/GrGLSLProgramBuilder.h"
110eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
120eafe79f42e3c675f3c504aed4a41abf511df2b7egdanielvoid GrGLSLVaryingHandler::addPassThroughAttribute(const GrGeometryProcessor::Attribute* input,
13c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                                   const char* output, GrSLPrecision precision) {
140eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    GrSLType type = GrVertexAttribTypeToSLType(input->fType);
150eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    GrGLSLVertToFrag v(type);
16c08f196648463d44eb85e17c5815dbf8f709a42acdalton    this->addVarying(input->fName, &v, precision);
17c08f196648463d44eb85e17c5815dbf8f709a42acdalton    this->writePassThroughAttribute(input, output, v);
18c08f196648463d44eb85e17c5815dbf8f709a42acdalton}
19c08f196648463d44eb85e17c5815dbf8f709a42acdalton
20c08f196648463d44eb85e17c5815dbf8f709a42acdaltonvoid GrGLSLVaryingHandler::addFlatPassThroughAttribute(const GrGeometryProcessor::Attribute* input,
21c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                                       const char* output,
22c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                                       GrSLPrecision precision) {
23c08f196648463d44eb85e17c5815dbf8f709a42acdalton    GrSLType type = GrVertexAttribTypeToSLType(input->fType);
24c08f196648463d44eb85e17c5815dbf8f709a42acdalton    GrGLSLVertToFrag v(type);
25c08f196648463d44eb85e17c5815dbf8f709a42acdalton    this->addFlatVarying(input->fName, &v, precision);
26c08f196648463d44eb85e17c5815dbf8f709a42acdalton    this->writePassThroughAttribute(input, output, v);
27c08f196648463d44eb85e17c5815dbf8f709a42acdalton}
28c08f196648463d44eb85e17c5815dbf8f709a42acdalton
29c08f196648463d44eb85e17c5815dbf8f709a42acdaltonvoid GrGLSLVaryingHandler::writePassThroughAttribute(const GrGeometryProcessor::Attribute* input,
30c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                                     const char* output, const GrGLSLVarying& v) {
310eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName);
320eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
330eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    if (fProgramBuilder->primitiveProcessor().willUseGeoShader()) {
340eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel        fProgramBuilder->fGS.codeAppendf("%s = %s[0];", v.gsOut(), v.gsIn());
350eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    }
360eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
370eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn());
380eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel}
390eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
40c08f196648463d44eb85e17c5815dbf8f709a42acdaltonvoid GrGLSLVaryingHandler::internalAddVarying(const char* name,
41c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                              GrGLSLVarying* varying,
42c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                              GrSLPrecision precision,
43c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                              bool flat) {
44c08f196648463d44eb85e17c5815dbf8f709a42acdalton    bool willUseGeoShader = fProgramBuilder->primitiveProcessor().willUseGeoShader();
45c08f196648463d44eb85e17c5815dbf8f709a42acdalton    VaryingInfo& v = fVaryings.push_back();
46c08f196648463d44eb85e17c5815dbf8f709a42acdalton
470eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    SkASSERT(varying);
48c08f196648463d44eb85e17c5815dbf8f709a42acdalton    v.fType = varying->fType;
49c08f196648463d44eb85e17c5815dbf8f709a42acdalton    v.fPrecision = precision;
50c08f196648463d44eb85e17c5815dbf8f709a42acdalton    v.fIsFlat = flat;
51c08f196648463d44eb85e17c5815dbf8f709a42acdalton    fProgramBuilder->nameVariable(&v.fVsOut, 'v', name);
52c08f196648463d44eb85e17c5815dbf8f709a42acdalton    v.fVisibility = kNone_GrShaderFlags;
530eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    if (varying->vsVarying()) {
54c08f196648463d44eb85e17c5815dbf8f709a42acdalton        varying->fVsOut = v.fVsOut.c_str();
55c08f196648463d44eb85e17c5815dbf8f709a42acdalton        v.fVisibility |= kVertex_GrShaderFlag;
560eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    }
57c08f196648463d44eb85e17c5815dbf8f709a42acdalton    if (willUseGeoShader) {
58c08f196648463d44eb85e17c5815dbf8f709a42acdalton        fProgramBuilder->nameVariable(&v.fGsOut, 'g', name);
59c08f196648463d44eb85e17c5815dbf8f709a42acdalton        varying->fGsIn = v.fVsOut.c_str();
60c08f196648463d44eb85e17c5815dbf8f709a42acdalton        varying->fGsOut = v.fGsOut.c_str();
61c08f196648463d44eb85e17c5815dbf8f709a42acdalton        v.fVisibility |= kGeometry_GrShaderFlag;
620eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    }
630eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    if (varying->fsVarying()) {
64c08f196648463d44eb85e17c5815dbf8f709a42acdalton        varying->fFsIn = (willUseGeoShader ? v.fGsOut : v.fVsOut).c_str();
65c08f196648463d44eb85e17c5815dbf8f709a42acdalton        v.fVisibility |= kFragment_GrShaderFlag;
660eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    }
670eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel}
680eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
690eafe79f42e3c675f3c504aed4a41abf511df2b7egdanielvoid GrGLSLVaryingHandler::emitAttributes(const GrGeometryProcessor& gp) {
700eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    int vaCount = gp.numAttribs();
710eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    for (int i = 0; i < vaCount; i++) {
720eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel        const GrGeometryProcessor::Attribute& attr = gp.getAttrib(i);
730eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel        this->addAttribute(GrShaderVar(attr.fName,
740eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel                                       GrVertexAttribTypeToSLType(attr.fType),
750eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel                                       GrShaderVar::kAttribute_TypeModifier,
760eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel                                       GrShaderVar::kNonArray,
770eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel                                       attr.fPrecision));
780eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    }
790eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel}
800eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
810eafe79f42e3c675f3c504aed4a41abf511df2b7egdanielvoid GrGLSLVaryingHandler::addAttribute(const GrShaderVar& var) {
820eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    SkASSERT(GrShaderVar::kAttribute_TypeModifier == var.getTypeModifier());
830eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    for (int j = 0; j < fVertexInputs.count(); ++j) {
840eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel        const GrGLSLShaderVar& attr = fVertexInputs[j];
850eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel        // if attribute already added, don't add it again
860eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel        if (attr.getName().equals(var.getName())) {
870eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel            return;
880eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel        }
890eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    }
900eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    fVertexInputs.push_back(var);
91b80ec8b79c0a60a5a300870de838aa31bbc18cddegdaniel}
92b80ec8b79c0a60a5a300870de838aa31bbc18cddegdaniel
93c08f196648463d44eb85e17c5815dbf8f709a42acdaltonvoid GrGLSLVaryingHandler::setNoPerspective() {
94c08f196648463d44eb85e17c5815dbf8f709a42acdalton    const GrGLSLCaps& caps = *fProgramBuilder->glslCaps();
95c08f196648463d44eb85e17c5815dbf8f709a42acdalton    if (!caps.noperspectiveInterpolationSupport()) {
96c08f196648463d44eb85e17c5815dbf8f709a42acdalton        return;
97c08f196648463d44eb85e17c5815dbf8f709a42acdalton    }
98c08f196648463d44eb85e17c5815dbf8f709a42acdalton    if (const char* extension = caps.noperspectiveInterpolationExtensionString()) {
998528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton        int bit = 1 << GrGLSLFragmentBuilder::kNoPerspectiveInterpolation_GLSLPrivateFeature;
100c08f196648463d44eb85e17c5815dbf8f709a42acdalton        fProgramBuilder->fVS.addFeature(bit, extension);
101c08f196648463d44eb85e17c5815dbf8f709a42acdalton        if (fProgramBuilder->primitiveProcessor().willUseGeoShader()) {
102c08f196648463d44eb85e17c5815dbf8f709a42acdalton            fProgramBuilder->fGS.addFeature(bit, extension);
103c08f196648463d44eb85e17c5815dbf8f709a42acdalton        }
104c08f196648463d44eb85e17c5815dbf8f709a42acdalton        fProgramBuilder->fFS.addFeature(bit, extension);
105c08f196648463d44eb85e17c5815dbf8f709a42acdalton    }
106c08f196648463d44eb85e17c5815dbf8f709a42acdalton    fDefaultInterpolationModifier = "noperspective";
107c08f196648463d44eb85e17c5815dbf8f709a42acdalton}
108c08f196648463d44eb85e17c5815dbf8f709a42acdalton
109b80ec8b79c0a60a5a300870de838aa31bbc18cddegdanielvoid GrGLSLVaryingHandler::finalize() {
110c08f196648463d44eb85e17c5815dbf8f709a42acdalton    for (int i = 0; i < fVaryings.count(); ++i) {
111c08f196648463d44eb85e17c5815dbf8f709a42acdalton        const VaryingInfo& v = this->fVaryings[i];
112c08f196648463d44eb85e17c5815dbf8f709a42acdalton        const char* modifier = v.fIsFlat ? "flat" : fDefaultInterpolationModifier;
113c08f196648463d44eb85e17c5815dbf8f709a42acdalton        if (v.fVisibility & kVertex_GrShaderFlag) {
114c08f196648463d44eb85e17c5815dbf8f709a42acdalton            fVertexOutputs.push_back().set(v.fType, GrShaderVar::kVaryingOut_TypeModifier, v.fVsOut,
115c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                           v.fPrecision, nullptr, modifier);
116c08f196648463d44eb85e17c5815dbf8f709a42acdalton            if (v.fVisibility & kGeometry_GrShaderFlag) {
117c08f196648463d44eb85e17c5815dbf8f709a42acdalton                fGeomInputs.push_back().set(v.fType, GrShaderVar::kVaryingIn_TypeModifier, v.fVsOut,
118c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                            GrShaderVar::kUnsizedArray, v.fPrecision, nullptr,
119c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                            modifier);
120c08f196648463d44eb85e17c5815dbf8f709a42acdalton            }
121c08f196648463d44eb85e17c5815dbf8f709a42acdalton        }
122c08f196648463d44eb85e17c5815dbf8f709a42acdalton        if (v.fVisibility & kFragment_GrShaderFlag) {
123c08f196648463d44eb85e17c5815dbf8f709a42acdalton            const char* fsIn = v.fVsOut.c_str();
124c08f196648463d44eb85e17c5815dbf8f709a42acdalton            if (v.fVisibility & kGeometry_GrShaderFlag) {
125c08f196648463d44eb85e17c5815dbf8f709a42acdalton                fGeomOutputs.push_back().set(v.fType, GrGLSLShaderVar::kVaryingOut_TypeModifier,
126c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                             v.fGsOut, v.fPrecision, nullptr, modifier);
127c08f196648463d44eb85e17c5815dbf8f709a42acdalton                fsIn = v.fGsOut.c_str();
128c08f196648463d44eb85e17c5815dbf8f709a42acdalton            }
129c08f196648463d44eb85e17c5815dbf8f709a42acdalton            fFragInputs.push_back().set(v.fType, GrShaderVar::kVaryingIn_TypeModifier, fsIn,
130c08f196648463d44eb85e17c5815dbf8f709a42acdalton                                        v.fPrecision, nullptr, modifier);
131c08f196648463d44eb85e17c5815dbf8f709a42acdalton        }
132c08f196648463d44eb85e17c5815dbf8f709a42acdalton    }
133b80ec8b79c0a60a5a300870de838aa31bbc18cddegdaniel    this->onFinalize();
1340eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel}
1350eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
1360eafe79f42e3c675f3c504aed4a41abf511df2b7egdanielvoid GrGLSLVaryingHandler::appendDecls(const VarArray& vars, SkString* out) const {
1370eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    for (int i = 0; i < vars.count(); ++i) {
1380eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel        vars[i].appendDecl(fProgramBuilder->glslCaps(), out);
1390eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel        out->append(";");
1400eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    }
1410eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel}
1420eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
1430eafe79f42e3c675f3c504aed4a41abf511df2b7egdanielvoid GrGLSLVaryingHandler::getVertexDecls(SkString* inputDecls, SkString* outputDecls) const {
1440eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    this->appendDecls(fVertexInputs, inputDecls);
1450eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    this->appendDecls(fVertexOutputs, outputDecls);
1460eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel}
1470eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
1480eafe79f42e3c675f3c504aed4a41abf511df2b7egdanielvoid GrGLSLVaryingHandler::getGeomDecls(SkString* inputDecls, SkString* outputDecls) const {
1490eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    this->appendDecls(fGeomInputs, inputDecls);
1500eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    this->appendDecls(fGeomOutputs, outputDecls);
1510eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel}
1520eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
1530eafe79f42e3c675f3c504aed4a41abf511df2b7egdanielvoid GrGLSLVaryingHandler::getFragDecls(SkString* inputDecls, SkString* outputDecls) const {
1540eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    // We should not have any outputs in the fragment shader when using version 1.10
1550eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    SkASSERT(k110_GrGLSLGeneration != fProgramBuilder->glslCaps()->generation() ||
1560eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel             fFragOutputs.empty());
1570eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    this->appendDecls(fFragInputs, inputDecls);
1580eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel    this->appendDecls(fFragOutputs, outputDecls);
1590eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel}
1600eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel
161