Home | History | Annotate | Download | only in Public
      1 //
      2 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
      3 // Copyright (C) 2013-2016 LunarG, Inc.
      4 // Copyright (C) 2015-2018 Google, Inc.
      5 //
      6 // All rights reserved.
      7 //
      8 // Redistribution and use in source and binary forms, with or without
      9 // modification, are permitted provided that the following conditions
     10 // are met:
     11 //
     12 //    Redistributions of source code must retain the above copyright
     13 //    notice, this list of conditions and the following disclaimer.
     14 //
     15 //    Redistributions in binary form must reproduce the above
     16 //    copyright notice, this list of conditions and the following
     17 //    disclaimer in the documentation and/or other materials provided
     18 //    with the distribution.
     19 //
     20 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
     21 //    contributors may be used to endorse or promote products derived
     22 //    from this software without specific prior written permission.
     23 //
     24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     27 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     28 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     31 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     32 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     34 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35 // POSSIBILITY OF SUCH DAMAGE.
     36 //
     37 #ifndef _COMPILER_INTERFACE_INCLUDED_
     38 #define _COMPILER_INTERFACE_INCLUDED_
     39 
     40 #include "../Include/ResourceLimits.h"
     41 #include "../MachineIndependent/Versions.h"
     42 
     43 #include <cstring>
     44 #include <vector>
     45 
     46 #ifdef _WIN32
     47 #define C_DECL __cdecl
     48 //#ifdef SH_EXPORTING
     49 //    #define SH_IMPORT_EXPORT __declspec(dllexport)
     50 //#else
     51 //    #define SH_IMPORT_EXPORT __declspec(dllimport)
     52 //#endif
     53 #define SH_IMPORT_EXPORT
     54 #else
     55 #define SH_IMPORT_EXPORT
     56 #ifndef __fastcall
     57 #define __fastcall
     58 #endif
     59 #define C_DECL
     60 #endif
     61 
     62 //
     63 // This is the platform independent interface between an OGL driver
     64 // and the shading language compiler/linker.
     65 //
     66 
     67 #ifdef __cplusplus
     68     extern "C" {
     69 #endif
     70 
     71 // This should always increase, as some paths to do not consume
     72 // a more major number.
     73 // It should increment by one when new functionality is added.
     74 #define GLSLANG_MINOR_VERSION 11
     75 
     76 //
     77 // Call before doing any other compiler/linker operations.
     78 //
     79 // (Call once per process, not once per thread.)
     80 //
     81 SH_IMPORT_EXPORT int ShInitialize();
     82 
     83 //
     84 // Call this at process shutdown to clean up memory.
     85 //
     86 SH_IMPORT_EXPORT int __fastcall ShFinalize();
     87 
     88 //
     89 // Types of languages the compiler can consume.
     90 //
     91 typedef enum {
     92     EShLangVertex,
     93     EShLangTessControl,
     94     EShLangTessEvaluation,
     95     EShLangGeometry,
     96     EShLangFragment,
     97     EShLangCompute,
     98     EShLangRayGenNV,
     99     EShLangIntersectNV,
    100     EShLangAnyHitNV,
    101     EShLangClosestHitNV,
    102     EShLangMissNV,
    103     EShLangCallableNV,
    104     EShLangTaskNV,
    105     EShLangMeshNV,
    106     EShLangCount,
    107 } EShLanguage;         // would be better as stage, but this is ancient now
    108 
    109 typedef enum {
    110     EShLangVertexMask         = (1 << EShLangVertex),
    111     EShLangTessControlMask    = (1 << EShLangTessControl),
    112     EShLangTessEvaluationMask = (1 << EShLangTessEvaluation),
    113     EShLangGeometryMask       = (1 << EShLangGeometry),
    114     EShLangFragmentMask       = (1 << EShLangFragment),
    115     EShLangComputeMask        = (1 << EShLangCompute),
    116     EShLangRayGenNVMask       = (1 << EShLangRayGenNV),
    117     EShLangIntersectNVMask    = (1 << EShLangIntersectNV),
    118     EShLangAnyHitNVMask       = (1 << EShLangAnyHitNV),
    119     EShLangClosestHitNVMask   = (1 << EShLangClosestHitNV),
    120     EShLangMissNVMask         = (1 << EShLangMissNV),
    121     EShLangCallableNVMask     = (1 << EShLangCallableNV),
    122     EShLangTaskNVMask         = (1 << EShLangTaskNV),
    123     EShLangMeshNVMask         = (1 << EShLangMeshNV),
    124 } EShLanguageMask;
    125 
    126 namespace glslang {
    127 
    128 class TType;
    129 
    130 typedef enum {
    131     EShSourceNone,
    132     EShSourceGlsl,
    133     EShSourceHlsl,
    134 } EShSource;                  // if EShLanguage were EShStage, this could be EShLanguage instead
    135 
    136 typedef enum {
    137     EShClientNone,
    138     EShClientVulkan,
    139     EShClientOpenGL,
    140 } EShClient;
    141 
    142 typedef enum {
    143     EShTargetNone,
    144     EShTargetSpv,                 // preferred spelling
    145     EshTargetSpv = EShTargetSpv,  // legacy spelling
    146 } EShTargetLanguage;
    147 
    148 typedef enum {
    149     EShTargetVulkan_1_0 = (1 << 22),
    150     EShTargetVulkan_1_1 = (1 << 22) | (1 << 12),
    151     EShTargetOpenGL_450 = 450,
    152 } EShTargetClientVersion;
    153 
    154 typedef EShTargetClientVersion EshTargetClientVersion;
    155 
    156 typedef enum {
    157     EShTargetSpv_1_0 = (1 << 16),
    158     EShTargetSpv_1_1 = (1 << 16) | (1 << 8),
    159     EShTargetSpv_1_2 = (1 << 16) | (2 << 8),
    160     EShTargetSpv_1_3 = (1 << 16) | (3 << 8),
    161     EShTargetSpv_1_4 = (1 << 16) | (4 << 8),
    162 } EShTargetLanguageVersion;
    163 
    164 struct TInputLanguage {
    165     EShSource languageFamily; // redundant information with other input, this one overrides when not EShSourceNone
    166     EShLanguage stage;        // redundant information with other input, this one overrides when not EShSourceNone
    167     EShClient dialect;
    168     int dialectVersion;       // version of client's language definition, not the client (when not EShClientNone)
    169 };
    170 
    171 struct TClient {
    172     EShClient client;
    173     EShTargetClientVersion version;   // version of client itself (not the client's input dialect)
    174 };
    175 
    176 struct TTarget {
    177     EShTargetLanguage language;
    178     EShTargetLanguageVersion version; // version to target, if SPIR-V, defined by "word 1" of the SPIR-V header
    179     bool hlslFunctionality1;          // can target hlsl_functionality1 extension(s)
    180 };
    181 
    182 // All source/client/target versions and settings.
    183 // Can override previous methods of setting, when items are set here.
    184 // Expected to grow, as more are added, rather than growing parameter lists.
    185 struct TEnvironment {
    186     TInputLanguage input;     // definition of the input language
    187     TClient client;           // what client is the overall compilation being done for?
    188     TTarget target;           // what to generate
    189 };
    190 
    191 const char* StageName(EShLanguage);
    192 
    193 } // end namespace glslang
    194 
    195 //
    196 // Types of output the linker will create.
    197 //
    198 typedef enum {
    199     EShExVertexFragment,
    200     EShExFragment
    201 } EShExecutable;
    202 
    203 //
    204 // Optimization level for the compiler.
    205 //
    206 typedef enum {
    207     EShOptNoGeneration,
    208     EShOptNone,
    209     EShOptSimple,       // Optimizations that can be done quickly
    210     EShOptFull,         // Optimizations that will take more time
    211 } EShOptimizationLevel;
    212 
    213 //
    214 // Texture and Sampler transformation mode.
    215 //
    216 typedef enum {
    217     EShTexSampTransKeep,   // keep textures and samplers as is (default)
    218     EShTexSampTransUpgradeTextureRemoveSampler,  // change texture w/o embeded sampler into sampled texture and throw away all samplers
    219 } EShTextureSamplerTransformMode;
    220 
    221 //
    222 // Message choices for what errors and warnings are given.
    223 //
    224 enum EShMessages {
    225     EShMsgDefault          = 0,         // default is to give all required errors and extra warnings
    226     EShMsgRelaxedErrors    = (1 << 0),  // be liberal in accepting input
    227     EShMsgSuppressWarnings = (1 << 1),  // suppress all warnings, except those required by the specification
    228     EShMsgAST              = (1 << 2),  // print the AST intermediate representation
    229     EShMsgSpvRules         = (1 << 3),  // issue messages for SPIR-V generation
    230     EShMsgVulkanRules      = (1 << 4),  // issue messages for Vulkan-requirements of GLSL for SPIR-V
    231     EShMsgOnlyPreprocessor = (1 << 5),  // only print out errors produced by the preprocessor
    232     EShMsgReadHlsl         = (1 << 6),  // use HLSL parsing rules and semantics
    233     EShMsgCascadingErrors  = (1 << 7),  // get cascading errors; risks error-recovery issues, instead of an early exit
    234     EShMsgKeepUncalled     = (1 << 8),  // for testing, don't eliminate uncalled functions
    235     EShMsgHlslOffsets      = (1 << 9),  // allow block offsets to follow HLSL rules instead of GLSL rules
    236     EShMsgDebugInfo        = (1 << 10), // save debug information
    237     EShMsgHlslEnable16BitTypes  = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
    238     EShMsgHlslLegalization  = (1 << 12), // enable HLSL Legalization messages
    239     EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers)
    240 };
    241 
    242 //
    243 // Build a table for bindings.  This can be used for locating
    244 // attributes, uniforms, globals, etc., as needed.
    245 //
    246 typedef struct {
    247     const char* name;
    248     int binding;
    249 } ShBinding;
    250 
    251 typedef struct {
    252     int numBindings;
    253     ShBinding* bindings;  // array of bindings
    254 } ShBindingTable;
    255 
    256 //
    257 // ShHandle held by but opaque to the driver.  It is allocated,
    258 // managed, and de-allocated by the compiler/linker. It's contents
    259 // are defined by and used by the compiler and linker.  For example,
    260 // symbol table information and object code passed from the compiler
    261 // to the linker can be stored where ShHandle points.
    262 //
    263 // If handle creation fails, 0 will be returned.
    264 //
    265 typedef void* ShHandle;
    266 
    267 //
    268 // Driver calls these to create and destroy compiler/linker
    269 // objects.
    270 //
    271 SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions);  // one per shader
    272 SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions);  // one per shader pair
    273 SH_IMPORT_EXPORT ShHandle ShConstructUniformMap();                 // one per uniform namespace (currently entire program object)
    274 SH_IMPORT_EXPORT void ShDestruct(ShHandle);
    275 
    276 //
    277 // The return value of ShCompile is boolean, non-zero indicating
    278 // success.
    279 //
    280 // The info-log should be written by ShCompile into
    281 // ShHandle, so it can answer future queries.
    282 //
    283 SH_IMPORT_EXPORT int ShCompile(
    284     const ShHandle,
    285     const char* const shaderStrings[],
    286     const int numStrings,
    287     const int* lengths,
    288     const EShOptimizationLevel,
    289     const TBuiltInResource *resources,
    290     int debugOptions,
    291     int defaultVersion = 110,            // use 100 for ES environment, overridden by #version in shader
    292     bool forwardCompatible = false,      // give errors for use of deprecated features
    293     EShMessages messages = EShMsgDefault // warnings and errors
    294     );
    295 
    296 SH_IMPORT_EXPORT int ShLinkExt(
    297     const ShHandle,               // linker object
    298     const ShHandle h[],           // compiler objects to link together
    299     const int numHandles);
    300 
    301 //
    302 // ShSetEncrpytionMethod is a place-holder for specifying
    303 // how source code is encrypted.
    304 //
    305 SH_IMPORT_EXPORT void ShSetEncryptionMethod(ShHandle);
    306 
    307 //
    308 // All the following return 0 if the information is not
    309 // available in the object passed down, or the object is bad.
    310 //
    311 SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle);
    312 SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle);
    313 SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*);   // to detect user aliasing
    314 SH_IMPORT_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*);     // to force any physical mappings
    315 //
    316 // Tell the linker to never assign a vertex attribute to this list of physical attributes
    317 //
    318 SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count);
    319 
    320 //
    321 // Returns the location ID of the named uniform.
    322 // Returns -1 if error.
    323 //
    324 SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
    325 
    326 #ifdef __cplusplus
    327     }  // end extern "C"
    328 #endif
    329 
    330 ////////////////////////////////////////////////////////////////////////////////////////////
    331 //
    332 // Deferred-Lowering C++ Interface
    333 // -----------------------------------
    334 //
    335 // Below is a new alternate C++ interface, which deprecates the above
    336 // opaque handle-based interface.
    337 //
    338 // The below is further designed to handle multiple compilation units per stage, where
    339 // the intermediate results, including the parse tree, are preserved until link time,
    340 // rather than the above interface which is designed to have each compilation unit
    341 // lowered at compile time.  In the above model, linking occurs on the lowered results,
    342 // whereas in this model intra-stage linking can occur at the parse tree
    343 // (treeRoot in TIntermediate) level, and then a full stage can be lowered.
    344 //
    345 
    346 #include <list>
    347 #include <string>
    348 #include <utility>
    349 
    350 class TCompiler;
    351 class TInfoSink;
    352 
    353 namespace glslang {
    354 
    355 const char* GetEsslVersionString();
    356 const char* GetGlslVersionString();
    357 int GetKhronosToolId();
    358 
    359 class TIntermediate;
    360 class TProgram;
    361 class TPoolAllocator;
    362 
    363 // Call this exactly once per process before using anything else
    364 bool InitializeProcess();
    365 
    366 // Call once per process to tear down everything
    367 void FinalizeProcess();
    368 
    369 // Resource type for IO resolver
    370 enum TResourceType {
    371     EResSampler,
    372     EResTexture,
    373     EResImage,
    374     EResUbo,
    375     EResSsbo,
    376     EResUav,
    377     EResCount
    378 };
    379 
    380 // Make one TShader per shader that you will link into a program. Then
    381 //  - provide the shader through setStrings() or setStringsWithLengths()
    382 //  - optionally call setEnv*(), see below for more detail
    383 //  - optionally use setPreamble() to set a special shader string that will be
    384 //    processed before all others but won't affect the validity of #version
    385 //  - call parse(): source language and target environment must be selected
    386 //    either by correct setting of EShMessages sent to parse(), or by
    387 //    explicitly calling setEnv*()
    388 //  - query the info logs
    389 //
    390 // N.B.: Does not yet support having the same TShader instance being linked into
    391 // multiple programs.
    392 //
    393 // N.B.: Destruct a linked program *before* destructing the shaders linked into it.
    394 //
    395 class TShader {
    396 public:
    397     explicit TShader(EShLanguage);
    398     virtual ~TShader();
    399     void setStrings(const char* const* s, int n);
    400     void setStringsWithLengths(const char* const* s, const int* l, int n);
    401     void setStringsWithLengthsAndNames(
    402         const char* const* s, const int* l, const char* const* names, int n);
    403     void setPreamble(const char* s) { preamble = s; }
    404     void setEntryPoint(const char* entryPoint);
    405     void setSourceEntryPoint(const char* sourceEntryPointName);
    406     void addProcesses(const std::vector<std::string>&);
    407 
    408     // IO resolver binding data: see comments in ShaderLang.cpp
    409     void setShiftBinding(TResourceType res, unsigned int base);
    410     void setShiftSamplerBinding(unsigned int base);  // DEPRECATED: use setShiftBinding
    411     void setShiftTextureBinding(unsigned int base);  // DEPRECATED: use setShiftBinding
    412     void setShiftImageBinding(unsigned int base);    // DEPRECATED: use setShiftBinding
    413     void setShiftUboBinding(unsigned int base);      // DEPRECATED: use setShiftBinding
    414     void setShiftUavBinding(unsigned int base);      // DEPRECATED: use setShiftBinding
    415     void setShiftCbufferBinding(unsigned int base);  // synonym for setShiftUboBinding
    416     void setShiftSsboBinding(unsigned int base);     // DEPRECATED: use setShiftBinding
    417     void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
    418     void setResourceSetBinding(const std::vector<std::string>& base);
    419     void setAutoMapBindings(bool map);
    420     void setAutoMapLocations(bool map);
    421     void addUniformLocationOverride(const char* name, int loc);
    422     void setUniformLocationBase(int base);
    423     void setInvertY(bool invert);
    424     void setHlslIoMapping(bool hlslIoMap);
    425     void setFlattenUniformArrays(bool flatten);
    426     void setNoStorageFormat(bool useUnknownFormat);
    427     void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
    428 
    429     // For setting up the environment (cleared to nothingness in the constructor).
    430     // These must be called so that parsing is done for the right source language and
    431     // target environment, either indirectly through TranslateEnvironment() based on
    432     // EShMessages et. al., or directly by the user.
    433     void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version)
    434     {
    435         environment.input.languageFamily = lang;
    436         environment.input.stage = envStage;
    437         environment.input.dialect = client;
    438         environment.input.dialectVersion = version;
    439     }
    440     void setEnvClient(EShClient client, EShTargetClientVersion version)
    441     {
    442         environment.client.client = client;
    443         environment.client.version = version;
    444     }
    445     void setEnvTarget(EShTargetLanguage lang, EShTargetLanguageVersion version)
    446     {
    447         environment.target.language = lang;
    448         environment.target.version = version;
    449     }
    450     void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; }
    451     bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; }
    452 
    453     // Interface to #include handlers.
    454     //
    455     // To support #include, a client of Glslang does the following:
    456     // 1. Call setStringsWithNames to set the source strings and associated
    457     //    names.  For example, the names could be the names of the files
    458     //    containing the shader sources.
    459     // 2. Call parse with an Includer.
    460     //
    461     // When the Glslang parser encounters an #include directive, it calls
    462     // the Includer's include method with the requested include name
    463     // together with the current string name.  The returned IncludeResult
    464     // contains the fully resolved name of the included source, together
    465     // with the source text that should replace the #include directive
    466     // in the source stream.  After parsing that source, Glslang will
    467     // release the IncludeResult object.
    468     class Includer {
    469     public:
    470         // An IncludeResult contains the resolved name and content of a source
    471         // inclusion.
    472         struct IncludeResult {
    473             IncludeResult(const std::string& headerName, const char* const headerData, const size_t headerLength, void* userData) :
    474                 headerName(headerName), headerData(headerData), headerLength(headerLength), userData(userData) { }
    475             // For a successful inclusion, the fully resolved name of the requested
    476             // include.  For example, in a file system-based includer, full resolution
    477             // should convert a relative path name into an absolute path name.
    478             // For a failed inclusion, this is an empty string.
    479             const std::string headerName;
    480             // The content and byte length of the requested inclusion.  The
    481             // Includer producing this IncludeResult retains ownership of the
    482             // storage.
    483             // For a failed inclusion, the header
    484             // field points to a string containing error details.
    485             const char* const headerData;
    486             const size_t headerLength;
    487             // Include resolver's context.
    488             void* userData;
    489         protected:
    490             IncludeResult& operator=(const IncludeResult&);
    491             IncludeResult();
    492         };
    493 
    494         // For both include methods below:
    495         //
    496         // Resolves an inclusion request by name, current source name,
    497         // and include depth.
    498         // On success, returns an IncludeResult containing the resolved name
    499         // and content of the include.
    500         // On failure, returns a nullptr, or an IncludeResult
    501         // with an empty string for the headerName and error details in the
    502         // header field.
    503         // The Includer retains ownership of the contents
    504         // of the returned IncludeResult value, and those contents must
    505         // remain valid until the releaseInclude method is called on that
    506         // IncludeResult object.
    507         //
    508         // Note "local" vs. "system" is not an "either/or": "local" is an
    509         // extra thing to do over "system". Both might get called, as per
    510         // the C++ specification.
    511 
    512         // For the "system" or <>-style includes; search the "system" paths.
    513         virtual IncludeResult* includeSystem(const char* /*headerName*/,
    514                                              const char* /*includerName*/,
    515                                              size_t /*inclusionDepth*/) { return nullptr; }
    516 
    517         // For the "local"-only aspect of a "" include. Should not search in the
    518         // "system" paths, because on returning a failure, the parser will
    519         // call includeSystem() to look in the "system" locations.
    520         virtual IncludeResult* includeLocal(const char* /*headerName*/,
    521                                             const char* /*includerName*/,
    522                                             size_t /*inclusionDepth*/) { return nullptr; }
    523 
    524         // Signals that the parser will no longer use the contents of the
    525         // specified IncludeResult.
    526         virtual void releaseInclude(IncludeResult*) = 0;
    527         virtual ~Includer() {}
    528     };
    529 
    530     // Fail all Includer searches
    531     class ForbidIncluder : public Includer {
    532     public:
    533         virtual void releaseInclude(IncludeResult*) override { }
    534     };
    535 
    536     bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
    537                bool forwardCompatible, EShMessages, Includer&);
    538 
    539     bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
    540                bool forwardCompatible, EShMessages messages)
    541     {
    542         TShader::ForbidIncluder includer;
    543         return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
    544     }
    545 
    546     // Equivalent to parse() without a default profile and without forcing defaults.
    547     bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
    548     {
    549         return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
    550     }
    551 
    552     bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages,
    553                Includer& includer)
    554     {
    555         return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer);
    556     }
    557 
    558     // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
    559     // is not an officially supported or fully working path.
    560     bool preprocess(const TBuiltInResource* builtInResources,
    561                     int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
    562                     bool forwardCompatible, EShMessages message, std::string* outputString,
    563                     Includer& includer);
    564 
    565     const char* getInfoLog();
    566     const char* getInfoDebugLog();
    567     EShLanguage getStage() const { return stage; }
    568     TIntermediate* getIntermediate() const { return intermediate; }
    569 
    570 protected:
    571     TPoolAllocator* pool;
    572     EShLanguage stage;
    573     TCompiler* compiler;
    574     TIntermediate* intermediate;
    575     TInfoSink* infoSink;
    576     // strings and lengths follow the standard for glShaderSource:
    577     //     strings is an array of numStrings pointers to string data.
    578     //     lengths can be null, but if not it is an array of numStrings
    579     //         integers containing the length of the associated strings.
    580     //         if lengths is null or lengths[n] < 0  the associated strings[n] is
    581     //         assumed to be null-terminated.
    582     // stringNames is the optional names for all the strings. If stringNames
    583     // is null, then none of the strings has name. If a certain element in
    584     // stringNames is null, then the corresponding string does not have name.
    585     const char* const* strings;
    586     const int* lengths;
    587     const char* const* stringNames;
    588     const char* preamble;
    589     int numStrings;
    590 
    591     // a function in the source string can be renamed FROM this TO the name given in setEntryPoint.
    592     std::string sourceEntryPointName;
    593 
    594     TEnvironment environment;
    595 
    596     friend class TProgram;
    597 
    598 private:
    599     TShader& operator=(TShader&);
    600 };
    601 
    602 class TReflection;
    603 class TIoMapper;
    604 
    605 // Allows to customize the binding layout after linking.
    606 // All used uniform variables will invoke at least validateBinding.
    607 // If validateBinding returned true then the other resolveBinding,
    608 // resolveSet, and resolveLocation are invoked to resolve the binding
    609 // and descriptor set index respectively.
    610 //
    611 // Invocations happen in a particular order:
    612 // 1) all shader inputs
    613 // 2) all shader outputs
    614 // 3) all uniforms with binding and set already defined
    615 // 4) all uniforms with binding but no set defined
    616 // 5) all uniforms with set but no binding defined
    617 // 6) all uniforms with no binding and no set defined
    618 //
    619 // mapIO will use this resolver in two phases. The first
    620 // phase is a notification phase, calling the corresponging
    621 // notifiy callbacks, this phase ends with a call to endNotifications.
    622 // Phase two starts directly after the call to endNotifications
    623 // and calls all other callbacks to validate and to get the
    624 // bindings, sets, locations, component and color indices.
    625 //
    626 // NOTE: that still limit checks are applied to bindings and sets
    627 // and may result in an error.
    628 class TIoMapResolver
    629 {
    630 public:
    631   virtual ~TIoMapResolver() {}
    632 
    633   // Should return true if the resulting/current binding would be okay.
    634   // Basic idea is to do aliasing binding checks with this.
    635   virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
    636   // Should return a value >= 0 if the current binding should be overridden.
    637   // Return -1 if the current binding (including no binding) should be kept.
    638   virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
    639   // Should return a value >= 0 if the current set should be overridden.
    640   // Return -1 if the current set (including no set) should be kept.
    641   virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
    642   // Should return a value >= 0 if the current location should be overridden.
    643   // Return -1 if the current location (including no location) should be kept.
    644   virtual int resolveUniformLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
    645   // Should return true if the resulting/current setup would be okay.
    646   // Basic idea is to do aliasing checks and reject invalid semantic names.
    647   virtual bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
    648   // Should return a value >= 0 if the current location should be overridden.
    649   // Return -1 if the current location (including no location) should be kept.
    650   virtual int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
    651   // Should return a value >= 0 if the current component index should be overridden.
    652   // Return -1 if the current component index (including no index) should be kept.
    653   virtual int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
    654   // Should return a value >= 0 if the current color index should be overridden.
    655   // Return -1 if the current color index (including no index) should be kept.
    656   virtual int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
    657   // Notification of a uniform variable
    658   virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
    659   // Notification of a in or out variable
    660   virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
    661   // Called by mapIO when it has finished the notify pass
    662   virtual void endNotifications(EShLanguage stage) = 0;
    663   // Called by mapIO when it starts its notify pass for the given stage
    664   virtual void beginNotifications(EShLanguage stage) = 0;
    665   // Called by mipIO when it starts its resolve pass for the given stage
    666   virtual void beginResolve(EShLanguage stage) = 0;
    667   // Called by mapIO when it has finished the resolve pass
    668   virtual void endResolve(EShLanguage stage) = 0;
    669 };
    670 
    671 // Make one TProgram per set of shaders that will get linked together.  Add all
    672 // the shaders that are to be linked together.  After calling shader.parse()
    673 // for all shaders, call link().
    674 //
    675 // N.B.: Destruct a linked program *before* destructing the shaders linked into it.
    676 //
    677 class TProgram {
    678 public:
    679     TProgram();
    680     virtual ~TProgram();
    681     void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
    682 
    683     // Link Validation interface
    684     bool link(EShMessages);
    685     const char* getInfoLog();
    686     const char* getInfoDebugLog();
    687 
    688     TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
    689 
    690     // Reflection Interface
    691     bool buildReflection();                          // call first, to do liveness analysis, index mapping, etc.; returns false on failure
    692     int getNumLiveUniformVariables() const;                // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS)
    693     int getNumLiveUniformBlocks() const;                   // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS)
    694     const char* getUniformName(int index) const;           // can be used for "name" part of glGetActiveUniform()
    695     const char* getUniformBlockName(int blockIndex) const; // can be used for glGetActiveUniformBlockName()
    696     int getUniformBlockSize(int blockIndex) const;         // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE)
    697     int getUniformIndex(const char* name) const;           // can be used for glGetUniformIndices()
    698     int getUniformBinding(int index) const;                // returns the binding number
    699     EShLanguageMask getUniformStages(int index) const;     // returns Shaders Stages where a Uniform is present
    700     int getUniformBlockBinding(int index) const;           // returns the block binding number
    701     int getUniformBlockIndex(int index) const;             // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX)
    702     int getUniformBlockCounterIndex(int index) const;      // returns block index of associated counter.
    703     int getUniformType(int index) const;                   // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE)
    704     int getUniformBufferOffset(int index) const;           // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET)
    705     int getUniformArraySize(int index) const;              // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
    706     int getNumLiveAttributes() const;                      // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
    707     unsigned getLocalSize(int dim) const;                  // return dim'th local size
    708     const char *getAttributeName(int index) const;         // can be used for glGetActiveAttrib()
    709     int getAttributeType(int index) const;                 // can be used for glGetActiveAttrib()
    710     const TType* getUniformTType(int index) const;         // returns a TType*
    711     const TType* getUniformBlockTType(int index) const;    // returns a TType*
    712     const TType* getAttributeTType(int index) const;       // returns a TType*
    713 
    714     void dumpReflection();
    715 
    716     // I/O mapping: apply base offsets and map live unbound variables
    717     // If resolver is not provided it uses the previous approach
    718     // and respects auto assignment and offsets.
    719     bool mapIO(TIoMapResolver* resolver = NULL);
    720 
    721 protected:
    722     bool linkStage(EShLanguage, EShMessages);
    723 
    724     TPoolAllocator* pool;
    725     std::list<TShader*> stages[EShLangCount];
    726     TIntermediate* intermediate[EShLangCount];
    727     bool newedIntermediate[EShLangCount];      // track which intermediate were "new" versus reusing a singleton unit in a stage
    728     TInfoSink* infoSink;
    729     TReflection* reflection;
    730     TIoMapper* ioMapper;
    731     bool linked;
    732 
    733 private:
    734     TProgram(TProgram&);
    735     TProgram& operator=(TProgram&);
    736 };
    737 
    738 } // end namespace glslang
    739 
    740 #endif // _COMPILER_INTERFACE_INCLUDED_
    741