• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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);
setPreamble(const char * s)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.
setEnvInput(EShSource lang,EShLanguage envStage,EShClient client,int version)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     }
setEnvClient(EShClient client,EShTargetClientVersion version)440     void setEnvClient(EShClient client, EShTargetClientVersion version)
441     {
442         environment.client.client = client;
443         environment.client.version = version;
444     }
setEnvTarget(EShTargetLanguage lang,EShTargetLanguageVersion version)445     void setEnvTarget(EShTargetLanguage lang, EShTargetLanguageVersion version)
446     {
447         environment.target.language = lang;
448         environment.target.version = version;
449     }
setEnvTargetHlslFunctionality1()450     void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; }
getEnvTargetHlslFunctionality1()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 {
IncludeResultIncludeResult473             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.
includeSystem(const char *,const char *,size_t)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.
includeLocal(const char *,const char *,size_t)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;
~Includer()527         virtual ~Includer() {}
528     };
529 
530     // Fail all Includer searches
531     class ForbidIncluder : public Includer {
532     public:
releaseInclude(IncludeResult *)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 
parse(const TBuiltInResource * res,int defaultVersion,EProfile defaultProfile,bool forceDefaultVersionAndProfile,bool forwardCompatible,EShMessages messages)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.
parse(const TBuiltInResource * builtInResources,int defaultVersion,bool forwardCompatible,EShMessages messages)547     bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
548     {
549         return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
550     }
551 
parse(const TBuiltInResource * builtInResources,int defaultVersion,bool forwardCompatible,EShMessages messages,Includer & includer)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();
getStage()567     EShLanguage getStage() const { return stage; }
getIntermediate()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:
~TIoMapResolver()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();
addShader(TShader * shader)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 
getIntermediate(EShLanguage stage)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