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