Home | History | Annotate | Download | only in glsl
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef GrGLSLProgramBuilder_DEFINED
      9 #define GrGLSLProgramBuilder_DEFINED
     10 
     11 #include "GrCaps.h"
     12 #include "GrGeometryProcessor.h"
     13 #include "GrProgramDesc.h"
     14 #include "glsl/GrGLSLFragmentProcessor.h"
     15 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     16 #include "glsl/GrGLSLGeometryShaderBuilder.h"
     17 #include "glsl/GrGLSLPrimitiveProcessor.h"
     18 #include "glsl/GrGLSLProgramDataManager.h"
     19 #include "glsl/GrGLSLUniformHandler.h"
     20 #include "glsl/GrGLSLVertexShaderBuilder.h"
     21 #include "glsl/GrGLSLXferProcessor.h"
     22 
     23 class GrShaderVar;
     24 class GrGLSLVaryingHandler;
     25 class SkString;
     26 class GrShaderCaps;
     27 
     28 typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs;
     29 
     30 class GrGLSLProgramBuilder {
     31 public:
     32     using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
     33     using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
     34     using TexelBufferHandle  = GrGLSLUniformHandler::TexelBufferHandle;
     35     using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
     36 
     37     virtual ~GrGLSLProgramBuilder() {}
     38 
     39     virtual const GrCaps* caps() const = 0;
     40     const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
     41 
     42     const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
     43     const GrPipeline& pipeline() const { return fPipeline; }
     44     GrProgramDesc* desc() { return fDesc; }
     45     const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); }
     46 
     47     void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
     48 
     49     const GrShaderVar& samplerVariable(SamplerHandle handle) const {
     50         return this->uniformHandler()->samplerVariable(handle);
     51     }
     52 
     53     GrSwizzle samplerSwizzle(SamplerHandle handle) const {
     54         return this->uniformHandler()->samplerSwizzle(handle);
     55     }
     56 
     57     const GrShaderVar& texelBufferVariable(TexelBufferHandle handle) const {
     58         return this->uniformHandler()->texelBufferVariable(handle);
     59     }
     60 
     61     const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const {
     62         return this->uniformHandler()->imageStorageVariable(handle);
     63     }
     64 
     65     // Handles for program uniforms (other than per-effect uniforms)
     66     struct BuiltinUniformHandles {
     67         UniformHandle       fRTAdjustmentUni;
     68 
     69         // We use the render target height to provide a y-down frag coord when specifying
     70         // origin_upper_left is not supported.
     71         UniformHandle       fRTHeightUni;
     72     };
     73 
     74     // Used to add a uniform for the RenderTarget height (used for frag position) without mangling
     75     // the name of the uniform inside of a stage.
     76     void addRTHeightUniform(const char* name);
     77 
     78     // Generates a name for a variable. The generated string will be name prefixed by the prefix
     79     // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
     80     // explicitly asked not to.
     81     void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
     82 
     83     virtual GrGLSLUniformHandler* uniformHandler() = 0;
     84     virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
     85     virtual GrGLSLVaryingHandler* varyingHandler() = 0;
     86 
     87     // Used for backend customization of the output color and secondary color variables from the
     88     // fragment processor. Only used if the outputs are explicitly declared in the shaders
     89     virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {}
     90     virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {}
     91 
     92     // number of each input/output type in a single allocation block, used by many builders
     93     static const int kVarsPerBlock;
     94 
     95     GrGLSLVertexBuilder         fVS;
     96     GrGLSLGeometryBuilder       fGS;
     97     GrGLSLFragmentShaderBuilder fFS;
     98 
     99     int fStageIndex;
    100 
    101     const GrPipeline&           fPipeline;
    102     const GrPrimitiveProcessor& fPrimProc;
    103     GrProgramDesc*              fDesc;
    104 
    105     BuiltinUniformHandles fUniformHandles;
    106 
    107     GrGLSLPrimitiveProcessor* fGeometryProcessor;
    108     GrGLSLXferProcessor* fXferProcessor;
    109     GrGLSLFragProcs fFragmentProcessors;
    110 
    111 protected:
    112     explicit GrGLSLProgramBuilder(const GrPipeline&,
    113                                   const GrPrimitiveProcessor&,
    114                                   GrProgramDesc*);
    115 
    116     void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
    117 
    118     bool emitAndInstallProcs();
    119 
    120     void cleanupFragmentProcessors();
    121 
    122     void finalizeShaders();
    123 
    124 private:
    125     // reset is called by program creator between each processor's emit code.  It increments the
    126     // stage offset for variable name mangling, and also ensures verfication variables in the
    127     // fragment shader are cleared.
    128     void reset() {
    129         this->addStage();
    130         SkDEBUGCODE(fFS.resetVerification();)
    131     }
    132     void addStage() { fStageIndex++; }
    133 
    134     class AutoStageAdvance {
    135     public:
    136         AutoStageAdvance(GrGLSLProgramBuilder* pb)
    137             : fPB(pb) {
    138             fPB->reset();
    139             // Each output to the fragment processor gets its own code section
    140             fPB->fFS.nextStage();
    141         }
    142         ~AutoStageAdvance() {}
    143     private:
    144         GrGLSLProgramBuilder* fPB;
    145     };
    146 
    147     // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
    148     void nameExpression(SkString*, const char* baseName);
    149 
    150     void emitAndInstallPrimProc(const GrPrimitiveProcessor&,
    151                                 SkString* outputColor,
    152                                 SkString* outputCoverage);
    153     void emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut);
    154     SkString emitAndInstallFragProc(const GrFragmentProcessor&,
    155                                     int index,
    156                                     int transformedCoordVarsIdx,
    157                                     const SkString& input,
    158                                     SkString output);
    159     void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
    160     void emitSamplersAndImageStorages(const GrResourceIOProcessor& processor,
    161                                       SkTArray<SamplerHandle>* outTexSamplerHandles,
    162                                       SkTArray<TexelBufferHandle>* outTexelBufferHandles,
    163                                       SkTArray<ImageStorageHandle>* outImageStorageHandles);
    164     SamplerHandle emitSampler(GrSLType samplerType, GrPixelConfig, const char* name,
    165                               GrShaderFlags visibility);
    166     TexelBufferHandle emitTexelBuffer(GrPixelConfig, const char* name, GrShaderFlags visibility);
    167     ImageStorageHandle emitImageStorage(const GrResourceIOProcessor::ImageStorageAccess&,
    168                                         const char* name);
    169     void emitFSOutputSwizzle(bool hasSecondaryOutput);
    170     void updateSamplerCounts(GrShaderFlags visibility);
    171     bool checkSamplerCounts();
    172     bool checkImageStorageCounts();
    173 
    174 #ifdef SK_DEBUG
    175     void verify(const GrPrimitiveProcessor&);
    176     void verify(const GrXferProcessor&);
    177     void verify(const GrFragmentProcessor&);
    178 #endif
    179 
    180     // These are used to check that we don't excede the allowable number of resources in a shader.
    181     // The sampler counts include both normal texure samplers as well as texel buffers.
    182     int                         fNumVertexSamplers;
    183     int                         fNumGeometrySamplers;
    184     int                         fNumFragmentSamplers;
    185     int                         fNumVertexImageStorages;
    186     int                         fNumGeometryImageStorages;
    187     int                         fNumFragmentImageStorages;
    188     SkSTArray<4, GrShaderVar>   fTransformedCoordVars;
    189 };
    190 
    191 #endif
    192