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