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