1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/GrShaderCaps.h" 9cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLProgramBuilder.h" 10cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVarying.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_civoid GrGLSLVaryingHandler::addPassThroughAttribute(const GrShaderVar& vsVar, 13cb93a386Sopenharmony_ci const char* output, 14cb93a386Sopenharmony_ci Interpolation interpolation) { 15cb93a386Sopenharmony_ci SkASSERT(vsVar.getType() != kVoid_GrSLType); 16cb93a386Sopenharmony_ci GrGLSLVarying v(vsVar.getType()); 17cb93a386Sopenharmony_ci this->addVarying(vsVar.c_str(), &v, interpolation); 18cb93a386Sopenharmony_ci fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), vsVar.c_str()); 19cb93a386Sopenharmony_ci fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn()); 20cb93a386Sopenharmony_ci} 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_cistatic bool use_flat_interpolation(GrGLSLVaryingHandler::Interpolation interpolation, 23cb93a386Sopenharmony_ci const GrShaderCaps& shaderCaps) { 24cb93a386Sopenharmony_ci switch (interpolation) { 25cb93a386Sopenharmony_ci using Interpolation = GrGLSLVaryingHandler::Interpolation; 26cb93a386Sopenharmony_ci case Interpolation::kInterpolated: 27cb93a386Sopenharmony_ci return false; 28cb93a386Sopenharmony_ci case Interpolation::kCanBeFlat: 29cb93a386Sopenharmony_ci SkASSERT(!shaderCaps.preferFlatInterpolation() || 30cb93a386Sopenharmony_ci shaderCaps.flatInterpolationSupport()); 31cb93a386Sopenharmony_ci return shaderCaps.preferFlatInterpolation(); 32cb93a386Sopenharmony_ci case Interpolation::kMustBeFlat: 33cb93a386Sopenharmony_ci SkASSERT(shaderCaps.flatInterpolationSupport()); 34cb93a386Sopenharmony_ci return true; 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci SK_ABORT("Invalid interpolation"); 37cb93a386Sopenharmony_ci} 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_civoid GrGLSLVaryingHandler::addVarying(const char* name, GrGLSLVarying* varying, 40cb93a386Sopenharmony_ci Interpolation interpolation) { 41cb93a386Sopenharmony_ci SkASSERT(GrSLTypeIsFloatType(varying->type()) || Interpolation::kMustBeFlat == interpolation); 42cb93a386Sopenharmony_ci VaryingInfo& v = fVaryings.push_back(); 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ci SkASSERT(varying); 45cb93a386Sopenharmony_ci SkASSERT(kVoid_GrSLType != varying->fType); 46cb93a386Sopenharmony_ci v.fType = varying->fType; 47cb93a386Sopenharmony_ci v.fIsFlat = use_flat_interpolation(interpolation, *fProgramBuilder->shaderCaps()); 48cb93a386Sopenharmony_ci v.fVsOut = fProgramBuilder->nameVariable('v', name); 49cb93a386Sopenharmony_ci v.fVisibility = kNone_GrShaderFlags; 50cb93a386Sopenharmony_ci if (varying->isInVertexShader()) { 51cb93a386Sopenharmony_ci varying->fVsOut = v.fVsOut.c_str(); 52cb93a386Sopenharmony_ci v.fVisibility |= kVertex_GrShaderFlag; 53cb93a386Sopenharmony_ci } 54cb93a386Sopenharmony_ci if (varying->isInFragmentShader()) { 55cb93a386Sopenharmony_ci varying->fFsIn = v.fVsOut.c_str(); 56cb93a386Sopenharmony_ci v.fVisibility |= kFragment_GrShaderFlag; 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci} 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_civoid GrGLSLVaryingHandler::emitAttributes(const GrGeometryProcessor& gp) { 61cb93a386Sopenharmony_ci for (const auto& attr : gp.vertexAttributes()) { 62cb93a386Sopenharmony_ci this->addAttribute(attr.asShaderVar()); 63cb93a386Sopenharmony_ci } 64cb93a386Sopenharmony_ci for (const auto& attr : gp.instanceAttributes()) { 65cb93a386Sopenharmony_ci this->addAttribute(attr.asShaderVar()); 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci} 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_civoid GrGLSLVaryingHandler::addAttribute(const GrShaderVar& var) { 70cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::TypeModifier::In == var.getTypeModifier()); 71cb93a386Sopenharmony_ci for (const GrShaderVar& attr : fVertexInputs.items()) { 72cb93a386Sopenharmony_ci // if attribute already added, don't add it again 73cb93a386Sopenharmony_ci if (attr.getName().equals(var.getName())) { 74cb93a386Sopenharmony_ci return; 75cb93a386Sopenharmony_ci } 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci fVertexInputs.push_back(var); 78cb93a386Sopenharmony_ci} 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_civoid GrGLSLVaryingHandler::setNoPerspective() { 81cb93a386Sopenharmony_ci const GrShaderCaps& caps = *fProgramBuilder->shaderCaps(); 82cb93a386Sopenharmony_ci if (!caps.noperspectiveInterpolationSupport()) { 83cb93a386Sopenharmony_ci return; 84cb93a386Sopenharmony_ci } 85cb93a386Sopenharmony_ci if (const char* extension = caps.noperspectiveInterpolationExtensionString()) { 86cb93a386Sopenharmony_ci int bit = 1 << GrGLSLShaderBuilder::kNoPerspectiveInterpolation_GLSLPrivateFeature; 87cb93a386Sopenharmony_ci fProgramBuilder->fVS.addFeature(bit, extension); 88cb93a386Sopenharmony_ci fProgramBuilder->fFS.addFeature(bit, extension); 89cb93a386Sopenharmony_ci } 90cb93a386Sopenharmony_ci fDefaultInterpolationModifier = "noperspective"; 91cb93a386Sopenharmony_ci} 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_civoid GrGLSLVaryingHandler::finalize() { 94cb93a386Sopenharmony_ci for (const VaryingInfo& v : fVaryings.items()) { 95cb93a386Sopenharmony_ci const char* modifier = v.fIsFlat ? "flat" : fDefaultInterpolationModifier; 96cb93a386Sopenharmony_ci if (v.fVisibility & kVertex_GrShaderFlag) { 97cb93a386Sopenharmony_ci fVertexOutputs.emplace_back(v.fVsOut, v.fType, GrShaderVar::TypeModifier::Out, 98cb93a386Sopenharmony_ci GrShaderVar::kNonArray, SkString(), SkString(modifier)); 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci if (v.fVisibility & kFragment_GrShaderFlag) { 101cb93a386Sopenharmony_ci const char* fsIn = v.fVsOut.c_str(); 102cb93a386Sopenharmony_ci fFragInputs.emplace_back(SkString(fsIn), v.fType, GrShaderVar::TypeModifier::In, 103cb93a386Sopenharmony_ci GrShaderVar::kNonArray, SkString(), SkString(modifier)); 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci this->onFinalize(); 107cb93a386Sopenharmony_ci} 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_civoid GrGLSLVaryingHandler::appendDecls(const VarArray& vars, SkString* out) const { 110cb93a386Sopenharmony_ci for (const GrShaderVar& varying : vars.items()) { 111cb93a386Sopenharmony_ci varying.appendDecl(fProgramBuilder->shaderCaps(), out); 112cb93a386Sopenharmony_ci out->append(";"); 113cb93a386Sopenharmony_ci } 114cb93a386Sopenharmony_ci} 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_civoid GrGLSLVaryingHandler::getVertexDecls(SkString* inputDecls, SkString* outputDecls) const { 117cb93a386Sopenharmony_ci this->appendDecls(fVertexInputs, inputDecls); 118cb93a386Sopenharmony_ci this->appendDecls(fVertexOutputs, outputDecls); 119cb93a386Sopenharmony_ci} 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_civoid GrGLSLVaryingHandler::getFragDecls(SkString* inputDecls, SkString* outputDecls) const { 122cb93a386Sopenharmony_ci // We should not have any outputs in the fragment shader when using version 1.10 123cb93a386Sopenharmony_ci SkASSERT(k110_GrGLSLGeneration != fProgramBuilder->shaderCaps()->generation() || 124cb93a386Sopenharmony_ci fFragOutputs.empty()); 125cb93a386Sopenharmony_ci this->appendDecls(fFragInputs, inputDecls); 126cb93a386Sopenharmony_ci this->appendDecls(fFragOutputs, outputDecls); 127cb93a386Sopenharmony_ci} 128