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 #else
49     #define C_DECL
50 #endif
51 
52 #ifdef GLSLANG_IS_SHARED_LIBRARY
53     #ifdef _WIN32
54         #ifdef GLSLANG_EXPORTING
55             #define GLSLANG_EXPORT __declspec(dllexport)
56         #else
57             #define GLSLANG_EXPORT __declspec(dllimport)
58         #endif
59     #elif __GNUC__ >= 4
60         #define GLSLANG_EXPORT __attribute__((visibility("default")))
61     #endif
62 #endif // GLSLANG_IS_SHARED_LIBRARY
63 
64 #ifndef GLSLANG_EXPORT
65 #define GLSLANG_EXPORT
66 #endif
67 
68 //
69 // This is the platform independent interface between an OGL driver
70 // and the shading language compiler/linker.
71 //
72 
73 #ifdef __cplusplus
74     extern "C" {
75 #endif
76 
77 //
78 // Call before doing any other compiler/linker operations.
79 //
80 // (Call once per process, not once per thread.)
81 //
82 GLSLANG_EXPORT int ShInitialize();
83 
84 //
85 // Call this at process shutdown to clean up memory.
86 //
87 GLSLANG_EXPORT int ShFinalize();
88 
89 //
90 // Types of languages the compiler can consume.
91 //
92 typedef enum {
93     EShLangVertex,
94     EShLangTessControl,
95     EShLangTessEvaluation,
96     EShLangGeometry,
97     EShLangFragment,
98     EShLangCompute,
99     EShLangRayGen,
100     EShLangRayGenNV = EShLangRayGen,
101     EShLangIntersect,
102     EShLangIntersectNV = EShLangIntersect,
103     EShLangAnyHit,
104     EShLangAnyHitNV = EShLangAnyHit,
105     EShLangClosestHit,
106     EShLangClosestHitNV = EShLangClosestHit,
107     EShLangMiss,
108     EShLangMissNV = EShLangMiss,
109     EShLangCallable,
110     EShLangCallableNV = EShLangCallable,
111     EShLangTaskNV,
112     EShLangMeshNV,
113     LAST_ELEMENT_MARKER(EShLangCount),
114 } EShLanguage;         // would be better as stage, but this is ancient now
115 
116 typedef enum : unsigned {
117     EShLangVertexMask         = (1 << EShLangVertex),
118     EShLangTessControlMask    = (1 << EShLangTessControl),
119     EShLangTessEvaluationMask = (1 << EShLangTessEvaluation),
120     EShLangGeometryMask       = (1 << EShLangGeometry),
121     EShLangFragmentMask       = (1 << EShLangFragment),
122     EShLangComputeMask        = (1 << EShLangCompute),
123     EShLangRayGenMask         = (1 << EShLangRayGen),
124     EShLangRayGenNVMask       = EShLangRayGenMask,
125     EShLangIntersectMask      = (1 << EShLangIntersect),
126     EShLangIntersectNVMask    = EShLangIntersectMask,
127     EShLangAnyHitMask         = (1 << EShLangAnyHit),
128     EShLangAnyHitNVMask       = EShLangAnyHitMask,
129     EShLangClosestHitMask     = (1 << EShLangClosestHit),
130     EShLangClosestHitNVMask   = EShLangClosestHitMask,
131     EShLangMissMask           = (1 << EShLangMiss),
132     EShLangMissNVMask         = EShLangMissMask,
133     EShLangCallableMask       = (1 << EShLangCallable),
134     EShLangCallableNVMask     = EShLangCallableMask,
135     EShLangTaskNVMask         = (1 << EShLangTaskNV),
136     EShLangMeshNVMask         = (1 << EShLangMeshNV),
137     LAST_ELEMENT_MARKER(EShLanguageMaskCount),
138 } EShLanguageMask;
139 
140 namespace glslang {
141 
142 class TType;
143 
144 typedef enum {
145     EShSourceNone,
146     EShSourceGlsl,               // GLSL, includes ESSL (OpenGL ES GLSL)
147     EShSourceHlsl,               // HLSL
148     LAST_ELEMENT_MARKER(EShSourceCount),
149 } EShSource;                     // if EShLanguage were EShStage, this could be EShLanguage instead
150 
151 typedef enum {
152     EShClientNone,               // use when there is no client, e.g. for validation
153     EShClientVulkan,
154     EShClientOpenGL,
155     LAST_ELEMENT_MARKER(EShClientCount),
156 } EShClient;
157 
158 typedef enum {
159     EShTargetNone,
160     EShTargetSpv,                 // SPIR-V (preferred spelling)
161     EshTargetSpv = EShTargetSpv,  // legacy spelling
162     LAST_ELEMENT_MARKER(EShTargetCount),
163 } EShTargetLanguage;
164 
165 typedef enum {
166     EShTargetVulkan_1_0 = (1 << 22),                  // Vulkan 1.0
167     EShTargetVulkan_1_1 = (1 << 22) | (1 << 12),      // Vulkan 1.1
168     EShTargetVulkan_1_2 = (1 << 22) | (2 << 12),      // Vulkan 1.2
169     EShTargetOpenGL_450 = 450,                        // OpenGL
170     LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 4),
171 } EShTargetClientVersion;
172 
173 typedef EShTargetClientVersion EshTargetClientVersion;
174 
175 typedef enum {
176     EShTargetSpv_1_0 = (1 << 16),                     // SPIR-V 1.0
177     EShTargetSpv_1_1 = (1 << 16) | (1 << 8),          // SPIR-V 1.1
178     EShTargetSpv_1_2 = (1 << 16) | (2 << 8),          // SPIR-V 1.2
179     EShTargetSpv_1_3 = (1 << 16) | (3 << 8),          // SPIR-V 1.3
180     EShTargetSpv_1_4 = (1 << 16) | (4 << 8),          // SPIR-V 1.4
181     EShTargetSpv_1_5 = (1 << 16) | (5 << 8),          // SPIR-V 1.5
182     LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 6),
183 } EShTargetLanguageVersion;
184 
185 struct TInputLanguage {
186     EShSource languageFamily; // redundant information with other input, this one overrides when not EShSourceNone
187     EShLanguage stage;        // redundant information with other input, this one overrides when not EShSourceNone
188     EShClient dialect;
189     int dialectVersion;       // version of client's language definition, not the client (when not EShClientNone)
190 };
191 
192 struct TClient {
193     EShClient client;
194     EShTargetClientVersion version;   // version of client itself (not the client's input dialect)
195 };
196 
197 struct TTarget {
198     EShTargetLanguage language;
199     EShTargetLanguageVersion version; // version to target, if SPIR-V, defined by "word 1" of the SPIR-V header
200     bool hlslFunctionality1;          // can target hlsl_functionality1 extension(s)
201 };
202 
203 // All source/client/target versions and settings.
204 // Can override previous methods of setting, when items are set here.
205 // Expected to grow, as more are added, rather than growing parameter lists.
206 struct TEnvironment {
207     TInputLanguage input;     // definition of the input language
208     TClient client;           // what client is the overall compilation being done for?
209     TTarget target;           // what to generate
210 };
211 
212 GLSLANG_EXPORT const char* StageName(EShLanguage);
213 
214 } // end namespace glslang
215 
216 //
217 // Types of output the linker will create.
218 //
219 typedef enum {
220     EShExVertexFragment,
221     EShExFragment
222 } EShExecutable;
223 
224 //
225 // Optimization level for the compiler.
226 //
227 typedef enum {
228     EShOptNoGeneration,
229     EShOptNone,
230     EShOptSimple,       // Optimizations that can be done quickly
231     EShOptFull,         // Optimizations that will take more time
232     LAST_ELEMENT_MARKER(EshOptLevelCount),
233 } EShOptimizationLevel;
234 
235 //
236 // Texture and Sampler transformation mode.
237 //
238 typedef enum {
239     EShTexSampTransKeep,   // keep textures and samplers as is (default)
240     EShTexSampTransUpgradeTextureRemoveSampler,  // change texture w/o embeded sampler into sampled texture and throw away all samplers
241     LAST_ELEMENT_MARKER(EShTexSampTransCount),
242 } EShTextureSamplerTransformMode;
243 
244 //
245 // Message choices for what errors and warnings are given.
246 //
247 enum EShMessages : unsigned {
248     EShMsgDefault          = 0,         // default is to give all required errors and extra warnings
249     EShMsgRelaxedErrors    = (1 << 0),  // be liberal in accepting input
250     EShMsgSuppressWarnings = (1 << 1),  // suppress all warnings, except those required by the specification
251     EShMsgAST              = (1 << 2),  // print the AST intermediate representation
252     EShMsgSpvRules         = (1 << 3),  // issue messages for SPIR-V generation
253     EShMsgVulkanRules      = (1 << 4),  // issue messages for Vulkan-requirements of GLSL for SPIR-V
254     EShMsgOnlyPreprocessor = (1 << 5),  // only print out errors produced by the preprocessor
255     EShMsgReadHlsl         = (1 << 6),  // use HLSL parsing rules and semantics
256     EShMsgCascadingErrors  = (1 << 7),  // get cascading errors; risks error-recovery issues, instead of an early exit
257     EShMsgKeepUncalled     = (1 << 8),  // for testing, don't eliminate uncalled functions
258     EShMsgHlslOffsets      = (1 << 9),  // allow block offsets to follow HLSL rules instead of GLSL rules
259     EShMsgDebugInfo        = (1 << 10), // save debug information
260     EShMsgHlslEnable16BitTypes  = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
261     EShMsgHlslLegalization  = (1 << 12), // enable HLSL Legalization messages
262     EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics)
263     EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
264     LAST_ELEMENT_MARKER(EShMsgCount),
265 };
266 
267 //
268 // Options for building reflection
269 //
270 typedef enum {
271     EShReflectionDefault            = 0,        // default is original behaviour before options were added
272     EShReflectionStrictArraySuffix  = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes
273     EShReflectionBasicArraySuffix   = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection
274     EShReflectionIntermediateIO     = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader
275     EShReflectionSeparateBuffers    = (1 << 3), // buffer variables and buffer blocks are reflected separately
276     EShReflectionAllBlockVariables  = (1 << 4), // reflect all variables in blocks, even if they are inactive
277     EShReflectionUnwrapIOBlocks     = (1 << 5), // unwrap input/output blocks the same as with uniform blocks
278     EShReflectionAllIOVariables     = (1 << 6), // reflect all input/output variables, even if they are inactive
279     EShReflectionSharedStd140SSBO   = (1 << 7), // Apply std140/shared rules for ubo to ssbo
280     EShReflectionSharedStd140UBO    = (1 << 8), // Apply std140/shared rules for ubo to ssbo
281     LAST_ELEMENT_MARKER(EShReflectionCount),
282 } EShReflectionOptions;
283 
284 //
285 // Build a table for bindings.  This can be used for locating
286 // attributes, uniforms, globals, etc., as needed.
287 //
288 typedef struct {
289     const char* name;
290     int binding;
291 } ShBinding;
292 
293 typedef struct {
294     int numBindings;
295     ShBinding* bindings;  // array of bindings
296 } ShBindingTable;
297 
298 //
299 // ShHandle held by but opaque to the driver.  It is allocated,
300 // managed, and de-allocated by the compiler/linker. It's contents
301 // are defined by and used by the compiler and linker.  For example,
302 // symbol table information and object code passed from the compiler
303 // to the linker can be stored where ShHandle points.
304 //
305 // If handle creation fails, 0 will be returned.
306 //
307 typedef void* ShHandle;
308 
309 //
310 // Driver calls these to create and destroy compiler/linker
311 // objects.
312 //
313 GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions);  // one per shader
314 GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions);  // one per shader pair
315 GLSLANG_EXPORT ShHandle ShConstructUniformMap();                 // one per uniform namespace (currently entire program object)
316 GLSLANG_EXPORT void ShDestruct(ShHandle);
317 
318 //
319 // The return value of ShCompile is boolean, non-zero indicating
320 // success.
321 //
322 // The info-log should be written by ShCompile into
323 // ShHandle, so it can answer future queries.
324 //
325 GLSLANG_EXPORT int ShCompile(
326     const ShHandle,
327     const char* const shaderStrings[],
328     const int numStrings,
329     const int* lengths,
330     const EShOptimizationLevel,
331     const TBuiltInResource *resources,
332     int debugOptions,
333     int defaultVersion = 110,            // use 100 for ES environment, overridden by #version in shader
334     bool forwardCompatible = false,      // give errors for use of deprecated features
335     EShMessages messages = EShMsgDefault // warnings and errors
336     );
337 
338 GLSLANG_EXPORT int ShLinkExt(
339     const ShHandle,               // linker object
340     const ShHandle h[],           // compiler objects to link together
341     const int numHandles);
342 
343 //
344 // ShSetEncrpytionMethod is a place-holder for specifying
345 // how source code is encrypted.
346 //
347 GLSLANG_EXPORT void ShSetEncryptionMethod(ShHandle);
348 
349 //
350 // All the following return 0 if the information is not
351 // available in the object passed down, or the object is bad.
352 //
353 GLSLANG_EXPORT const char* ShGetInfoLog(const ShHandle);
354 GLSLANG_EXPORT const void* ShGetExecutable(const ShHandle);
355 GLSLANG_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*);   // to detect user aliasing
356 GLSLANG_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*);     // to force any physical mappings
357 //
358 // Tell the linker to never assign a vertex attribute to this list of physical attributes
359 //
360 GLSLANG_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count);
361 
362 //
363 // Returns the location ID of the named uniform.
364 // Returns -1 if error.
365 //
366 GLSLANG_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
367 
368 #ifdef __cplusplus
369     }  // end extern "C"
370 #endif
371 
372 ////////////////////////////////////////////////////////////////////////////////////////////
373 //
374 // Deferred-Lowering C++ Interface
375 // -----------------------------------
376 //
377 // Below is a new alternate C++ interface, which deprecates the above
378 // opaque handle-based interface.
379 //
380 // The below is further designed to handle multiple compilation units per stage, where
381 // the intermediate results, including the parse tree, are preserved until link time,
382 // rather than the above interface which is designed to have each compilation unit
383 // lowered at compile time.  In the above model, linking occurs on the lowered results,
384 // whereas in this model intra-stage linking can occur at the parse tree
385 // (treeRoot in TIntermediate) level, and then a full stage can be lowered.
386 //
387 
388 #include <list>
389 #include <string>
390 #include <utility>
391 
392 class TCompiler;
393 class TInfoSink;
394 
395 namespace glslang {
396 
397 struct Version {
398     int major;
399     int minor;
400     int patch;
401     const char* flavor;
402 };
403 
404 GLSLANG_EXPORT Version GetVersion();
405 GLSLANG_EXPORT const char* GetEsslVersionString();
406 GLSLANG_EXPORT const char* GetGlslVersionString();
407 GLSLANG_EXPORT int GetKhronosToolId();
408 
409 class TIntermediate;
410 class TProgram;
411 class TPoolAllocator;
412 
413 // Call this exactly once per process before using anything else
414 GLSLANG_EXPORT bool InitializeProcess();
415 
416 // Call once per process to tear down everything
417 GLSLANG_EXPORT void FinalizeProcess();
418 
419 // Resource type for IO resolver
420 enum TResourceType {
421     EResSampler,
422     EResTexture,
423     EResImage,
424     EResUbo,
425     EResSsbo,
426     EResUav,
427     EResCount
428 };
429 
430 
431 // Make one TShader per shader that you will link into a program. Then
432 //  - provide the shader through setStrings() or setStringsWithLengths()
433 //  - optionally call setEnv*(), see below for more detail
434 //  - optionally use setPreamble() to set a special shader string that will be
435 //    processed before all others but won't affect the validity of #version
436 //  - optionally call addProcesses() for each setting/transform,
437 //    see comment for class TProcesses
438 //  - call parse(): source language and target environment must be selected
439 //    either by correct setting of EShMessages sent to parse(), or by
440 //    explicitly calling setEnv*()
441 //  - query the info logs
442 //
443 // N.B.: Does not yet support having the same TShader instance being linked into
444 // multiple programs.
445 //
446 // N.B.: Destruct a linked program *before* destructing the shaders linked into it.
447 //
448 class TShader {
449 public:
450     GLSLANG_EXPORT explicit TShader(EShLanguage);
451     GLSLANG_EXPORT virtual ~TShader();
452     GLSLANG_EXPORT void setStrings(const char* const* s, int n);
453     GLSLANG_EXPORT void setStringsWithLengths(
454         const char* const* s, const int* l, int n);
455     GLSLANG_EXPORT void setStringsWithLengthsAndNames(
456         const char* const* s, const int* l, const char* const* names, int n);
setPreamble(const char * s)457     void setPreamble(const char* s) { preamble = s; }
458     GLSLANG_EXPORT void setEntryPoint(const char* entryPoint);
459     GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
460     GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
461 
462     // IO resolver binding data: see comments in ShaderLang.cpp
463     GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);
464     GLSLANG_EXPORT void setShiftSamplerBinding(unsigned int base);  // DEPRECATED: use setShiftBinding
465     GLSLANG_EXPORT void setShiftTextureBinding(unsigned int base);  // DEPRECATED: use setShiftBinding
466     GLSLANG_EXPORT void setShiftImageBinding(unsigned int base);    // DEPRECATED: use setShiftBinding
467     GLSLANG_EXPORT void setShiftUboBinding(unsigned int base);      // DEPRECATED: use setShiftBinding
468     GLSLANG_EXPORT void setShiftUavBinding(unsigned int base);      // DEPRECATED: use setShiftBinding
469     GLSLANG_EXPORT void setShiftCbufferBinding(unsigned int base);  // synonym for setShiftUboBinding
470     GLSLANG_EXPORT void setShiftSsboBinding(unsigned int base);     // DEPRECATED: use setShiftBinding
471     GLSLANG_EXPORT void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
472     GLSLANG_EXPORT void setResourceSetBinding(const std::vector<std::string>& base);
473     GLSLANG_EXPORT void setAutoMapBindings(bool map);
474     GLSLANG_EXPORT void setAutoMapLocations(bool map);
475     GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc);
476     GLSLANG_EXPORT void setUniformLocationBase(int base);
477     GLSLANG_EXPORT void setInvertY(bool invert);
478 #ifdef ENABLE_HLSL
479     GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
480     GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);
481 #endif
482     GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat);
483     GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp);
484     GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
485 
486     // For setting up the environment (cleared to nothingness in the constructor).
487     // These must be called so that parsing is done for the right source language and
488     // target environment, either indirectly through TranslateEnvironment() based on
489     // EShMessages et. al., or directly by the user.
490     //
491     // setEnvInput:    The input source language and stage. If generating code for a
492     //                 specific client, the input client semantics to use and the
493     //                 version of the that client's input semantics to use, otherwise
494     //                 use EShClientNone and version of 0, e.g. for validation mode.
495     //                 Note 'version' does not describe the target environment,
496     //                 just the version of the source dialect to compile under.
497     //
498     //                 See the definitions of TEnvironment, EShSource, EShLanguage,
499     //                 and EShClient for choices and more detail.
500     //
501     // setEnvClient:   The client that will be hosting the execution, and it's version.
502     //                 Note 'version' is not the version of the languages involved, but
503     //                 the version of the client environment.
504     //                 Use EShClientNone and version of 0 if there is no client, e.g.
505     //                 for validation mode.
506     //
507     //                 See EShTargetClientVersion for choices.
508     //
509     // setEnvTarget:   The language to translate to when generating code, and that
510     //                 language's version.
511     //                 Use EShTargetNone and version of 0 if there is no client, e.g.
512     //                 for validation mode.
513     //
setEnvInput(EShSource lang,EShLanguage envStage,EShClient client,int version)514     void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version)
515     {
516         environment.input.languageFamily = lang;
517         environment.input.stage = envStage;
518         environment.input.dialect = client;
519         environment.input.dialectVersion = version;
520     }
setEnvClient(EShClient client,EShTargetClientVersion version)521     void setEnvClient(EShClient client, EShTargetClientVersion version)
522     {
523         environment.client.client = client;
524         environment.client.version = version;
525     }
setEnvTarget(EShTargetLanguage lang,EShTargetLanguageVersion version)526     void setEnvTarget(EShTargetLanguage lang, EShTargetLanguageVersion version)
527     {
528         environment.target.language = lang;
529         environment.target.version = version;
530     }
531 
getStrings(const char * const * & s,int & n)532     void getStrings(const char* const* &s, int& n) { s = strings; n = numStrings; }
533 
534 #ifdef ENABLE_HLSL
setEnvTargetHlslFunctionality1()535     void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; }
getEnvTargetHlslFunctionality1()536     bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; }
537 #else
getEnvTargetHlslFunctionality1()538     bool getEnvTargetHlslFunctionality1() const { return false; }
539 #endif
540 
541     // Interface to #include handlers.
542     //
543     // To support #include, a client of Glslang does the following:
544     // 1. Call setStringsWithNames to set the source strings and associated
545     //    names.  For example, the names could be the names of the files
546     //    containing the shader sources.
547     // 2. Call parse with an Includer.
548     //
549     // When the Glslang parser encounters an #include directive, it calls
550     // the Includer's include method with the requested include name
551     // together with the current string name.  The returned IncludeResult
552     // contains the fully resolved name of the included source, together
553     // with the source text that should replace the #include directive
554     // in the source stream.  After parsing that source, Glslang will
555     // release the IncludeResult object.
556     class Includer {
557     public:
558         // An IncludeResult contains the resolved name and content of a source
559         // inclusion.
560         struct IncludeResult {
IncludeResultIncludeResult561             IncludeResult(const std::string& headerName, const char* const headerData, const size_t headerLength, void* userData) :
562                 headerName(headerName), headerData(headerData), headerLength(headerLength), userData(userData) { }
563             // For a successful inclusion, the fully resolved name of the requested
564             // include.  For example, in a file system-based includer, full resolution
565             // should convert a relative path name into an absolute path name.
566             // For a failed inclusion, this is an empty string.
567             const std::string headerName;
568             // The content and byte length of the requested inclusion.  The
569             // Includer producing this IncludeResult retains ownership of the
570             // storage.
571             // For a failed inclusion, the header
572             // field points to a string containing error details.
573             const char* const headerData;
574             const size_t headerLength;
575             // Include resolver's context.
576             void* userData;
577         protected:
578             IncludeResult& operator=(const IncludeResult&);
579             IncludeResult();
580         };
581 
582         // For both include methods below:
583         //
584         // Resolves an inclusion request by name, current source name,
585         // and include depth.
586         // On success, returns an IncludeResult containing the resolved name
587         // and content of the include.
588         // On failure, returns a nullptr, or an IncludeResult
589         // with an empty string for the headerName and error details in the
590         // header field.
591         // The Includer retains ownership of the contents
592         // of the returned IncludeResult value, and those contents must
593         // remain valid until the releaseInclude method is called on that
594         // IncludeResult object.
595         //
596         // Note "local" vs. "system" is not an "either/or": "local" is an
597         // extra thing to do over "system". Both might get called, as per
598         // the C++ specification.
599 
600         // For the "system" or <>-style includes; search the "system" paths.
includeSystem(const char *,const char *,size_t)601         virtual IncludeResult* includeSystem(const char* /*headerName*/,
602                                              const char* /*includerName*/,
603                                              size_t /*inclusionDepth*/) { return nullptr; }
604 
605         // For the "local"-only aspect of a "" include. Should not search in the
606         // "system" paths, because on returning a failure, the parser will
607         // call includeSystem() to look in the "system" locations.
includeLocal(const char *,const char *,size_t)608         virtual IncludeResult* includeLocal(const char* /*headerName*/,
609                                             const char* /*includerName*/,
610                                             size_t /*inclusionDepth*/) { return nullptr; }
611 
612         // Signals that the parser will no longer use the contents of the
613         // specified IncludeResult.
614         virtual void releaseInclude(IncludeResult*) = 0;
~Includer()615         virtual ~Includer() {}
616     };
617 
618     // Fail all Includer searches
619     class ForbidIncluder : public Includer {
620     public:
releaseInclude(IncludeResult *)621         virtual void releaseInclude(IncludeResult*) override { }
622     };
623 
624     GLSLANG_EXPORT bool parse(
625         const TBuiltInResource*, int defaultVersion, EProfile defaultProfile,
626         bool forceDefaultVersionAndProfile, bool forwardCompatible,
627         EShMessages, Includer&);
628 
parse(const TBuiltInResource * res,int defaultVersion,EProfile defaultProfile,bool forceDefaultVersionAndProfile,bool forwardCompatible,EShMessages messages)629     bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
630                bool forwardCompatible, EShMessages messages)
631     {
632         TShader::ForbidIncluder includer;
633         return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
634     }
635 
636     // Equivalent to parse() without a default profile and without forcing defaults.
parse(const TBuiltInResource * builtInResources,int defaultVersion,bool forwardCompatible,EShMessages messages)637     bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
638     {
639         return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
640     }
641 
parse(const TBuiltInResource * builtInResources,int defaultVersion,bool forwardCompatible,EShMessages messages,Includer & includer)642     bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages,
643                Includer& includer)
644     {
645         return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer);
646     }
647 
648     // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
649     // is not an officially supported or fully working path.
650     GLSLANG_EXPORT bool preprocess(
651         const TBuiltInResource* builtInResources, int defaultVersion,
652         EProfile defaultProfile, bool forceDefaultVersionAndProfile,
653         bool forwardCompatible, EShMessages message, std::string* outputString,
654         Includer& includer);
655 
656     GLSLANG_EXPORT const char* getInfoLog();
657     GLSLANG_EXPORT const char* getInfoDebugLog();
getStage()658     EShLanguage getStage() const { return stage; }
getIntermediate()659     TIntermediate* getIntermediate() const { return intermediate; }
660 
661 protected:
662     TPoolAllocator* pool;
663     EShLanguage stage;
664     TCompiler* compiler;
665     TIntermediate* intermediate;
666     TInfoSink* infoSink;
667     // strings and lengths follow the standard for glShaderSource:
668     //     strings is an array of numStrings pointers to string data.
669     //     lengths can be null, but if not it is an array of numStrings
670     //         integers containing the length of the associated strings.
671     //         if lengths is null or lengths[n] < 0  the associated strings[n] is
672     //         assumed to be null-terminated.
673     // stringNames is the optional names for all the strings. If stringNames
674     // is null, then none of the strings has name. If a certain element in
675     // stringNames is null, then the corresponding string does not have name.
676     const char* const* strings;      // explicit code to compile, see previous comment
677     const int* lengths;
678     const char* const* stringNames;
679     int numStrings;                  // size of the above arrays
680     const char* preamble;            // string of implicit code to compile before the explicitly provided code
681 
682     // a function in the source string can be renamed FROM this TO the name given in setEntryPoint.
683     std::string sourceEntryPointName;
684 
685     TEnvironment environment;
686 
687     friend class TProgram;
688 
689 private:
690     TShader& operator=(TShader&);
691 };
692 
693 #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
694 
695 //
696 // A reflection database and its interface, consistent with the OpenGL API reflection queries.
697 //
698 
699 // Data needed for just a single object at the granularity exchanged by the reflection API
700 class TObjectReflection {
701 public:
702     GLSLANG_EXPORT TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
703 
getType()704     GLSLANG_EXPORT const TType* getType() const { return type; }
705     GLSLANG_EXPORT int getBinding() const;
706     GLSLANG_EXPORT void dump() const;
badReflection()707     static TObjectReflection badReflection() { return TObjectReflection(); }
708 
709     std::string name;
710     int offset;
711     int glDefineType;
712     int size;                   // data size in bytes for a block, array size for a (non-block) object that's an array
713     int index;
714     int counterIndex;
715     int numMembers;
716     int arrayStride;            // stride of an array variable
717     int topLevelArraySize;      // size of the top-level variable in a storage buffer member
718     int topLevelArrayStride;    // stride of the top-level variable in a storage buffer member
719     EShLanguageMask stages;
720 
721 protected:
TObjectReflection()722     TObjectReflection()
723         : offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), numMembers(-1), arrayStride(0),
724           topLevelArrayStride(0), stages(EShLanguageMask(0)), type(nullptr)
725     {
726     }
727 
728     const TType* type;
729 };
730 
731 class  TReflection;
732 class  TIoMapper;
733 struct TVarEntryInfo;
734 
735 // Allows to customize the binding layout after linking.
736 // All used uniform variables will invoke at least validateBinding.
737 // If validateBinding returned true then the other resolveBinding,
738 // resolveSet, and resolveLocation are invoked to resolve the binding
739 // and descriptor set index respectively.
740 //
741 // Invocations happen in a particular order:
742 // 1) all shader inputs
743 // 2) all shader outputs
744 // 3) all uniforms with binding and set already defined
745 // 4) all uniforms with binding but no set defined
746 // 5) all uniforms with set but no binding defined
747 // 6) all uniforms with no binding and no set defined
748 //
749 // mapIO will use this resolver in two phases. The first
750 // phase is a notification phase, calling the corresponging
751 // notifiy callbacks, this phase ends with a call to endNotifications.
752 // Phase two starts directly after the call to endNotifications
753 // and calls all other callbacks to validate and to get the
754 // bindings, sets, locations, component and color indices.
755 //
756 // NOTE: that still limit checks are applied to bindings and sets
757 // and may result in an error.
758 class TIoMapResolver
759 {
760 public:
~TIoMapResolver()761     virtual ~TIoMapResolver() {}
762 
763     // Should return true if the resulting/current binding would be okay.
764     // Basic idea is to do aliasing binding checks with this.
765     virtual bool validateBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
766     // Should return a value >= 0 if the current binding should be overridden.
767     // Return -1 if the current binding (including no binding) should be kept.
768     virtual int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
769     // Should return a value >= 0 if the current set should be overridden.
770     // Return -1 if the current set (including no set) should be kept.
771     virtual int resolveSet(EShLanguage stage, TVarEntryInfo& ent) = 0;
772     // Should return a value >= 0 if the current location should be overridden.
773     // Return -1 if the current location (including no location) should be kept.
774     virtual int resolveUniformLocation(EShLanguage stage, TVarEntryInfo& ent) = 0;
775     // Should return true if the resulting/current setup would be okay.
776     // Basic idea is to do aliasing checks and reject invalid semantic names.
777     virtual bool validateInOut(EShLanguage stage, TVarEntryInfo& ent) = 0;
778     // Should return a value >= 0 if the current location should be overridden.
779     // Return -1 if the current location (including no location) should be kept.
780     virtual int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) = 0;
781     // Should return a value >= 0 if the current component index should be overridden.
782     // Return -1 if the current component index (including no index) should be kept.
783     virtual int resolveInOutComponent(EShLanguage stage, TVarEntryInfo& ent) = 0;
784     // Should return a value >= 0 if the current color index should be overridden.
785     // Return -1 if the current color index (including no index) should be kept.
786     virtual int resolveInOutIndex(EShLanguage stage, TVarEntryInfo& ent) = 0;
787     // Notification of a uniform variable
788     virtual void notifyBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
789     // Notification of a in or out variable
790     virtual void notifyInOut(EShLanguage stage, TVarEntryInfo& ent) = 0;
791     // Called by mapIO when it starts its notify pass for the given stage
792     virtual void beginNotifications(EShLanguage stage) = 0;
793     // Called by mapIO when it has finished the notify pass
794     virtual void endNotifications(EShLanguage stage) = 0;
795     // Called by mipIO when it starts its resolve pass for the given stage
796     virtual void beginResolve(EShLanguage stage) = 0;
797     // Called by mapIO when it has finished the resolve pass
798     virtual void endResolve(EShLanguage stage) = 0;
799     // Called by mapIO when it starts its symbol collect for teh given stage
800     virtual void beginCollect(EShLanguage stage) = 0;
801     // Called by mapIO when it has finished the symbol collect
802     virtual void endCollect(EShLanguage stage) = 0;
803     // Called by TSlotCollector to resolve storage locations or bindings
804     virtual void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0;
805     // Called by TSlotCollector to resolve resource locations or bindings
806     virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0;
807     // Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline
808     virtual void addStage(EShLanguage stage) = 0;
809 };
810 
811 #endif // !GLSLANG_WEB && !GLSLANG_ANGLE
812 
813 // Make one TProgram per set of shaders that will get linked together.  Add all
814 // the shaders that are to be linked together.  After calling shader.parse()
815 // for all shaders, call link().
816 //
817 // N.B.: Destruct a linked program *before* destructing the shaders linked into it.
818 //
819 class TProgram {
820 public:
821     GLSLANG_EXPORT TProgram();
822     GLSLANG_EXPORT virtual ~TProgram();
addShader(TShader * shader)823     void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
getShaders(EShLanguage stage)824     std::list<TShader*>& getShaders(EShLanguage stage) { return stages[stage]; }
825     // Link Validation interface
826     GLSLANG_EXPORT bool link(EShMessages);
827     GLSLANG_EXPORT const char* getInfoLog();
828     GLSLANG_EXPORT const char* getInfoDebugLog();
829 
getIntermediate(EShLanguage stage)830     TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
831 
832 #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
833 
834     // Reflection Interface
835 
836     // call first, to do liveness analysis, index mapping, etc.; returns false on failure
837     GLSLANG_EXPORT bool buildReflection(int opts = EShReflectionDefault);
838     GLSLANG_EXPORT unsigned getLocalSize(int dim) const;                  // return dim'th local size
839     GLSLANG_EXPORT int getReflectionIndex(const char *name) const;
840     GLSLANG_EXPORT int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const;
841     GLSLANG_EXPORT int getNumUniformVariables() const;
842     GLSLANG_EXPORT const TObjectReflection& getUniform(int index) const;
843     GLSLANG_EXPORT int getNumUniformBlocks() const;
844     GLSLANG_EXPORT const TObjectReflection& getUniformBlock(int index) const;
845     GLSLANG_EXPORT int getNumPipeInputs() const;
846     GLSLANG_EXPORT const TObjectReflection& getPipeInput(int index) const;
847     GLSLANG_EXPORT int getNumPipeOutputs() const;
848     GLSLANG_EXPORT const TObjectReflection& getPipeOutput(int index) const;
849     GLSLANG_EXPORT int getNumBufferVariables() const;
850     GLSLANG_EXPORT const TObjectReflection& getBufferVariable(int index) const;
851     GLSLANG_EXPORT int getNumBufferBlocks() const;
852     GLSLANG_EXPORT const TObjectReflection& getBufferBlock(int index) const;
853     GLSLANG_EXPORT int getNumAtomicCounters() const;
854     GLSLANG_EXPORT const TObjectReflection& getAtomicCounter(int index) const;
855 
856     // Legacy Reflection Interface - expressed in terms of above interface
857 
858     // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS)
getNumLiveUniformVariables()859     int getNumLiveUniformVariables() const             { return getNumUniformVariables(); }
860 
861     // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS)
getNumLiveUniformBlocks()862     int getNumLiveUniformBlocks() const                { return getNumUniformBlocks(); }
863 
864     // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
getNumLiveAttributes()865     int getNumLiveAttributes() const                   { return getNumPipeInputs(); }
866 
867     // can be used for glGetUniformIndices()
getUniformIndex(const char * name)868     int getUniformIndex(const char *name) const        { return getReflectionIndex(name); }
869 
getPipeIOIndex(const char * name,const bool inOrOut)870     int getPipeIOIndex(const char *name, const bool inOrOut) const
871                                                        { return getReflectionPipeIOIndex(name, inOrOut); }
872 
873     // can be used for "name" part of glGetActiveUniform()
getUniformName(int index)874     const char *getUniformName(int index) const        { return getUniform(index).name.c_str(); }
875 
876     // returns the binding number
getUniformBinding(int index)877     int getUniformBinding(int index) const             { return getUniform(index).getBinding(); }
878 
879     // returns Shaders Stages where a Uniform is present
getUniformStages(int index)880     EShLanguageMask getUniformStages(int index) const  { return getUniform(index).stages; }
881 
882     // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX)
getUniformBlockIndex(int index)883     int getUniformBlockIndex(int index) const          { return getUniform(index).index; }
884 
885     // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE)
getUniformType(int index)886     int getUniformType(int index) const                { return getUniform(index).glDefineType; }
887 
888     // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET)
getUniformBufferOffset(int index)889     int getUniformBufferOffset(int index) const        { return getUniform(index).offset; }
890 
891     // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
getUniformArraySize(int index)892     int getUniformArraySize(int index) const           { return getUniform(index).size; }
893 
894     // returns a TType*
getUniformTType(int index)895     const TType *getUniformTType(int index) const      { return getUniform(index).getType(); }
896 
897     // can be used for glGetActiveUniformBlockName()
getUniformBlockName(int index)898     const char *getUniformBlockName(int index) const   { return getUniformBlock(index).name.c_str(); }
899 
900     // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE)
getUniformBlockSize(int index)901     int getUniformBlockSize(int index) const           { return getUniformBlock(index).size; }
902 
903     // returns the block binding number
getUniformBlockBinding(int index)904     int getUniformBlockBinding(int index) const        { return getUniformBlock(index).getBinding(); }
905 
906     // returns block index of associated counter.
getUniformBlockCounterIndex(int index)907     int getUniformBlockCounterIndex(int index) const   { return getUniformBlock(index).counterIndex; }
908 
909     // returns a TType*
getUniformBlockTType(int index)910     const TType *getUniformBlockTType(int index) const { return getUniformBlock(index).getType(); }
911 
912     // can be used for glGetActiveAttrib()
getAttributeName(int index)913     const char *getAttributeName(int index) const      { return getPipeInput(index).name.c_str(); }
914 
915     // can be used for glGetActiveAttrib()
getAttributeType(int index)916     int getAttributeType(int index) const              { return getPipeInput(index).glDefineType; }
917 
918     // returns a TType*
getAttributeTType(int index)919     const TType *getAttributeTType(int index) const    { return getPipeInput(index).getType(); }
920 
921     GLSLANG_EXPORT void dumpReflection();
922     // I/O mapping: apply base offsets and map live unbound variables
923     // If resolver is not provided it uses the previous approach
924     // and respects auto assignment and offsets.
925     GLSLANG_EXPORT bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr);
926 #endif // !GLSLANG_WEB && !GLSLANG_ANGLE
927 
928 protected:
929     GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages);
930 
931     TPoolAllocator* pool;
932     std::list<TShader*> stages[EShLangCount];
933     TIntermediate* intermediate[EShLangCount];
934     bool newedIntermediate[EShLangCount];      // track which intermediate were "new" versus reusing a singleton unit in a stage
935     TInfoSink* infoSink;
936 #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
937     TReflection* reflection;
938 #endif
939     bool linked;
940 
941 private:
942     TProgram(TProgram&);
943     TProgram& operator=(TProgram&);
944 };
945 
946 } // end namespace glslang
947 
948 #endif // _COMPILER_INTERFACE_INCLUDED_
949