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