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