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 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef GrGLSLProgramBuilder_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define GrGLSLProgramBuilder_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Swizzle.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrFragmentProcessor.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGeometryProcessor.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPipeline.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProgramInfo.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSamplerState.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrShaderVar.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrXferProcessor.h" 23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h" 24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h" 25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLVertexGeoBuilder.h" 26*c8dee2aaSAndroid Build Coastguard Worker 27*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 28*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 29*c8dee2aaSAndroid Build Coastguard Worker #include <string> 30*c8dee2aaSAndroid Build Coastguard Worker #include <vector> 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker class GrBackendFormat; 33*c8dee2aaSAndroid Build Coastguard Worker class GrGLSLVaryingHandler; 34*c8dee2aaSAndroid Build Coastguard Worker class GrProgramDesc; 35*c8dee2aaSAndroid Build Coastguard Worker class SkString; 36*c8dee2aaSAndroid Build Coastguard Worker enum GrSurfaceOrigin : int; 37*c8dee2aaSAndroid Build Coastguard Worker struct GrShaderCaps; 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker class GrGLSLProgramBuilder { 40*c8dee2aaSAndroid Build Coastguard Worker public: 41*c8dee2aaSAndroid Build Coastguard Worker using UniformHandle = GrGLSLUniformHandler::UniformHandle; 42*c8dee2aaSAndroid Build Coastguard Worker using SamplerHandle = GrGLSLUniformHandler::SamplerHandle; 43*c8dee2aaSAndroid Build Coastguard Worker 44*c8dee2aaSAndroid Build Coastguard Worker virtual ~GrGLSLProgramBuilder(); 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard Worker virtual const GrCaps* caps() const = 0; shaderCaps()47*c8dee2aaSAndroid Build Coastguard Worker const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); } 48*c8dee2aaSAndroid Build Coastguard Worker origin()49*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceOrigin origin() const { return fProgramInfo.origin(); } pipeline()50*c8dee2aaSAndroid Build Coastguard Worker const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); } geometryProcessor()51*c8dee2aaSAndroid Build Coastguard Worker const GrGeometryProcessor& geometryProcessor() const { return fProgramInfo.geomProc(); } snapVerticesToPixelCenters()52*c8dee2aaSAndroid Build Coastguard Worker bool snapVerticesToPixelCenters() const { 53*c8dee2aaSAndroid Build Coastguard Worker return fProgramInfo.pipeline().snapVerticesToPixelCenters(); 54*c8dee2aaSAndroid Build Coastguard Worker } hasPointSize()55*c8dee2aaSAndroid Build Coastguard Worker bool hasPointSize() const { return fProgramInfo.primitiveType() == GrPrimitiveType::kPoints; } 56*c8dee2aaSAndroid Build Coastguard Worker desc()57*c8dee2aaSAndroid Build Coastguard Worker const GrProgramDesc& desc() const { return fDesc; } 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard Worker void appendUniformDecls(GrShaderFlags visibility, SkString*) const; 60*c8dee2aaSAndroid Build Coastguard Worker samplerVariable(SamplerHandle handle)61*c8dee2aaSAndroid Build Coastguard Worker const char* samplerVariable(SamplerHandle handle) const { 62*c8dee2aaSAndroid Build Coastguard Worker return this->uniformHandler()->samplerVariable(handle); 63*c8dee2aaSAndroid Build Coastguard Worker } 64*c8dee2aaSAndroid Build Coastguard Worker samplerSwizzle(SamplerHandle handle)65*c8dee2aaSAndroid Build Coastguard Worker skgpu::Swizzle samplerSwizzle(SamplerHandle handle) const { 66*c8dee2aaSAndroid Build Coastguard Worker return this->uniformHandler()->samplerSwizzle(handle); 67*c8dee2aaSAndroid Build Coastguard Worker } 68*c8dee2aaSAndroid Build Coastguard Worker inputSamplerVariable(SamplerHandle handle)69*c8dee2aaSAndroid Build Coastguard Worker const char* inputSamplerVariable(SamplerHandle handle) const { 70*c8dee2aaSAndroid Build Coastguard Worker return this->uniformHandler()->inputSamplerVariable(handle); 71*c8dee2aaSAndroid Build Coastguard Worker } 72*c8dee2aaSAndroid Build Coastguard Worker inputSamplerSwizzle(SamplerHandle handle)73*c8dee2aaSAndroid Build Coastguard Worker skgpu::Swizzle inputSamplerSwizzle(SamplerHandle handle) const { 74*c8dee2aaSAndroid Build Coastguard Worker return this->uniformHandler()->inputSamplerSwizzle(handle); 75*c8dee2aaSAndroid Build Coastguard Worker } 76*c8dee2aaSAndroid Build Coastguard Worker 77*c8dee2aaSAndroid Build Coastguard Worker // Used to add a uniform for render target flip (used for dFdy, sk_Clockwise, and sk_FragCoord) 78*c8dee2aaSAndroid Build Coastguard Worker // without mangling the name of the uniform inside of a stage. 79*c8dee2aaSAndroid Build Coastguard Worker void addRTFlipUniform(const char* name); 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Worker // Generates a name for a variable. The generated string will be name prefixed by the prefix 82*c8dee2aaSAndroid Build Coastguard Worker // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless 83*c8dee2aaSAndroid Build Coastguard Worker // explicitly asked not to. `nameVariable` can also be used to generate names for functions or 84*c8dee2aaSAndroid Build Coastguard Worker // other types of symbols where unique names are important. 85*c8dee2aaSAndroid Build Coastguard Worker SkString nameVariable(char prefix, const char* name, bool mangle = true); 86*c8dee2aaSAndroid Build Coastguard Worker 87*c8dee2aaSAndroid Build Coastguard Worker /** 88*c8dee2aaSAndroid Build Coastguard Worker * Emits samplers for TextureEffect fragment processors as needed. `fp` can be a TextureEffect, 89*c8dee2aaSAndroid Build Coastguard Worker * or a tree containing zero or more TextureEffects. 90*c8dee2aaSAndroid Build Coastguard Worker */ 91*c8dee2aaSAndroid Build Coastguard Worker bool emitTextureSamplersForFPs(const GrFragmentProcessor& fp, 92*c8dee2aaSAndroid Build Coastguard Worker GrFragmentProcessor::ProgramImpl& impl, 93*c8dee2aaSAndroid Build Coastguard Worker int* samplerIndex); 94*c8dee2aaSAndroid Build Coastguard Worker 95*c8dee2aaSAndroid Build Coastguard Worker /** 96*c8dee2aaSAndroid Build Coastguard Worker * advanceStage is called by program creator between each processor's emit code. It increments 97*c8dee2aaSAndroid Build Coastguard Worker * the stage index for variable name mangling, and also ensures verification variables in the 98*c8dee2aaSAndroid Build Coastguard Worker * fragment shader are cleared. 99*c8dee2aaSAndroid Build Coastguard Worker */ advanceStage()100*c8dee2aaSAndroid Build Coastguard Worker void advanceStage() { 101*c8dee2aaSAndroid Build Coastguard Worker fStageIndex++; 102*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(fFS.debugOnly_resetPerStageVerification();) 103*c8dee2aaSAndroid Build Coastguard Worker fFS.nextStage(); 104*c8dee2aaSAndroid Build Coastguard Worker } 105*c8dee2aaSAndroid Build Coastguard Worker 106*c8dee2aaSAndroid Build Coastguard Worker /** Adds the SkSL function that implements an FP assuming its children are already written. */ 107*c8dee2aaSAndroid Build Coastguard Worker void writeFPFunction(const GrFragmentProcessor& fp, GrFragmentProcessor::ProgramImpl& impl); 108*c8dee2aaSAndroid Build Coastguard Worker 109*c8dee2aaSAndroid Build Coastguard Worker /** 110*c8dee2aaSAndroid Build Coastguard Worker * Returns a function-call invocation of `fp` in string form, passing the appropriate 111*c8dee2aaSAndroid Build Coastguard Worker * combination of `inputColor`, `destColor` and `fLocalCoordsVar` for the FP. 112*c8dee2aaSAndroid Build Coastguard Worker */ 113*c8dee2aaSAndroid Build Coastguard Worker std::string invokeFP(const GrFragmentProcessor& fp, 114*c8dee2aaSAndroid Build Coastguard Worker const GrFragmentProcessor::ProgramImpl& impl, 115*c8dee2aaSAndroid Build Coastguard Worker const char* inputColor, 116*c8dee2aaSAndroid Build Coastguard Worker const char* destColor, 117*c8dee2aaSAndroid Build Coastguard Worker const char* coords) const; 118*c8dee2aaSAndroid Build Coastguard Worker /** 119*c8dee2aaSAndroid Build Coastguard Worker * If the FP's coords are unused or all uses have been lifted to interpolated varyings then 120*c8dee2aaSAndroid Build Coastguard Worker * don't put coords in the FP's function signature or call sites. 121*c8dee2aaSAndroid Build Coastguard Worker */ 122*c8dee2aaSAndroid Build Coastguard Worker bool fragmentProcessorHasCoordsParam(const GrFragmentProcessor*) const; 123*c8dee2aaSAndroid Build Coastguard Worker 124*c8dee2aaSAndroid Build Coastguard Worker virtual GrGLSLUniformHandler* uniformHandler() = 0; 125*c8dee2aaSAndroid Build Coastguard Worker virtual const GrGLSLUniformHandler* uniformHandler() const = 0; 126*c8dee2aaSAndroid Build Coastguard Worker virtual GrGLSLVaryingHandler* varyingHandler() = 0; 127*c8dee2aaSAndroid Build Coastguard Worker 128*c8dee2aaSAndroid Build Coastguard Worker // Used for backend customization of the secondary color variable from the fragment processor. 129*c8dee2aaSAndroid Build Coastguard Worker // Only used if the output is explicitly declared in the shaders. finalizeFragmentSecondaryColor(GrShaderVar & outputColor)130*c8dee2aaSAndroid Build Coastguard Worker virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {} 131*c8dee2aaSAndroid Build Coastguard Worker 132*c8dee2aaSAndroid Build Coastguard Worker // number of each input/output type in a single allocation block, used by many builders 133*c8dee2aaSAndroid Build Coastguard Worker static const int kVarsPerBlock; 134*c8dee2aaSAndroid Build Coastguard Worker 135*c8dee2aaSAndroid Build Coastguard Worker GrGLSLVertexBuilder fVS; 136*c8dee2aaSAndroid Build Coastguard Worker GrGLSLFragmentShaderBuilder fFS; 137*c8dee2aaSAndroid Build Coastguard Worker 138*c8dee2aaSAndroid Build Coastguard Worker const GrProgramDesc& fDesc; 139*c8dee2aaSAndroid Build Coastguard Worker const GrProgramInfo& fProgramInfo; 140*c8dee2aaSAndroid Build Coastguard Worker 141*c8dee2aaSAndroid Build Coastguard Worker GrGLSLBuiltinUniformHandles fUniformHandles; 142*c8dee2aaSAndroid Build Coastguard Worker 143*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrGeometryProcessor::ProgramImpl> fGPImpl; 144*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrXferProcessor::ProgramImpl> fXPImpl; 145*c8dee2aaSAndroid Build Coastguard Worker std::vector<std::unique_ptr<GrFragmentProcessor::ProgramImpl>> fFPImpls; 146*c8dee2aaSAndroid Build Coastguard Worker 147*c8dee2aaSAndroid Build Coastguard Worker SamplerHandle fDstTextureSamplerHandle; 148*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceOrigin fDstTextureOrigin; 149*c8dee2aaSAndroid Build Coastguard Worker 150*c8dee2aaSAndroid Build Coastguard Worker protected: 151*c8dee2aaSAndroid Build Coastguard Worker explicit GrGLSLProgramBuilder(const GrProgramDesc&, const GrProgramInfo&); 152*c8dee2aaSAndroid Build Coastguard Worker 153*c8dee2aaSAndroid Build Coastguard Worker void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName); 154*c8dee2aaSAndroid Build Coastguard Worker 155*c8dee2aaSAndroid Build Coastguard Worker bool emitAndInstallProcs(); 156*c8dee2aaSAndroid Build Coastguard Worker 157*c8dee2aaSAndroid Build Coastguard Worker void finalizeShaders(); 158*c8dee2aaSAndroid Build Coastguard Worker fragColorIsInOut()159*c8dee2aaSAndroid Build Coastguard Worker bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); } 160*c8dee2aaSAndroid Build Coastguard Worker 161*c8dee2aaSAndroid Build Coastguard Worker private: 162*c8dee2aaSAndroid Build Coastguard Worker SkString getMangleSuffix() const; 163*c8dee2aaSAndroid Build Coastguard Worker 164*c8dee2aaSAndroid Build Coastguard Worker // Generates a possibly mangled name for a stage variable and writes it to the fragment shader. 165*c8dee2aaSAndroid Build Coastguard Worker void nameExpression(SkString*, const char* baseName); 166*c8dee2aaSAndroid Build Coastguard Worker 167*c8dee2aaSAndroid Build Coastguard Worker bool emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage); 168*c8dee2aaSAndroid Build Coastguard Worker bool emitAndInstallDstTexture(); 169*c8dee2aaSAndroid Build Coastguard Worker /** Adds the root FPs */ 170*c8dee2aaSAndroid Build Coastguard Worker bool emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut); 171*c8dee2aaSAndroid Build Coastguard Worker /** Adds a single root FP tree. */ 172*c8dee2aaSAndroid Build Coastguard Worker SkString emitRootFragProc(const GrFragmentProcessor& fp, 173*c8dee2aaSAndroid Build Coastguard Worker GrFragmentProcessor::ProgramImpl& impl, 174*c8dee2aaSAndroid Build Coastguard Worker const SkString& input, 175*c8dee2aaSAndroid Build Coastguard Worker SkString output); 176*c8dee2aaSAndroid Build Coastguard Worker /** Recursive step to write out children FPs' functions before parent's. */ 177*c8dee2aaSAndroid Build Coastguard Worker void writeChildFPFunctions(const GrFragmentProcessor& fp, 178*c8dee2aaSAndroid Build Coastguard Worker GrFragmentProcessor::ProgramImpl& impl); 179*c8dee2aaSAndroid Build Coastguard Worker bool emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn); 180*c8dee2aaSAndroid Build Coastguard Worker SamplerHandle emitSampler(const GrBackendFormat&, GrSamplerState, const skgpu::Swizzle&, 181*c8dee2aaSAndroid Build Coastguard Worker const char* name); 182*c8dee2aaSAndroid Build Coastguard Worker SamplerHandle emitInputSampler(const skgpu::Swizzle& swizzle, const char* name); 183*c8dee2aaSAndroid Build Coastguard Worker bool checkSamplerCounts(); 184*c8dee2aaSAndroid Build Coastguard Worker 185*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG 186*c8dee2aaSAndroid Build Coastguard Worker void verify(const GrGeometryProcessor&); 187*c8dee2aaSAndroid Build Coastguard Worker void verify(const GrFragmentProcessor&); 188*c8dee2aaSAndroid Build Coastguard Worker void verify(const GrXferProcessor&); 189*c8dee2aaSAndroid Build Coastguard Worker #endif 190*c8dee2aaSAndroid Build Coastguard Worker 191*c8dee2aaSAndroid Build Coastguard Worker // This is used to check that we don't excede the allowable number of resources in a shader. 192*c8dee2aaSAndroid Build Coastguard Worker int fNumFragmentSamplers; 193*c8dee2aaSAndroid Build Coastguard Worker 194*c8dee2aaSAndroid Build Coastguard Worker GrGeometryProcessor::ProgramImpl::FPCoordsMap fFPCoordsMap; 195*c8dee2aaSAndroid Build Coastguard Worker GrShaderVar fLocalCoordsVar; 196*c8dee2aaSAndroid Build Coastguard Worker 197*c8dee2aaSAndroid Build Coastguard Worker /** 198*c8dee2aaSAndroid Build Coastguard Worker * Each root processor has an stage index. The GP is stage 0. The first root FP is stage 1, 199*c8dee2aaSAndroid Build Coastguard Worker * the second root FP is stage 2, etc. The XP's stage index is last and its value depends on 200*c8dee2aaSAndroid Build Coastguard Worker * how many root FPs there are. Names are mangled by appending _S<stage-index>. 201*c8dee2aaSAndroid Build Coastguard Worker */ 202*c8dee2aaSAndroid Build Coastguard Worker int fStageIndex = -1; 203*c8dee2aaSAndroid Build Coastguard Worker 204*c8dee2aaSAndroid Build Coastguard Worker /** 205*c8dee2aaSAndroid Build Coastguard Worker * When emitting FP stages we track the children FPs as "substages" and do additional name 206*c8dee2aaSAndroid Build Coastguard Worker * mangling based on where in the FP hierarchy we are. The first FP is stage index 1. It's first 207*c8dee2aaSAndroid Build Coastguard Worker * child would be substage 0 of stage 1. If that FP also has three children then its third child 208*c8dee2aaSAndroid Build Coastguard Worker * would be substage 2 of stubstage 0 of stage 1 and would be mangled as "_S1_c0_c2". 209*c8dee2aaSAndroid Build Coastguard Worker */ 210*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<int> fSubstageIndices; 211*c8dee2aaSAndroid Build Coastguard Worker }; 212*c8dee2aaSAndroid Build Coastguard Worker 213*c8dee2aaSAndroid Build Coastguard Worker #endif 214