2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 // Copyright (C) 2013-2016 LunarG, Inc.
4 // Copyright (C) 2015-2018 Google, Inc.
6 // All rights reserved.
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions
12 // Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
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.
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.
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.
37 #ifndef _COMPILER_INTERFACE_INCLUDED_
38 #define _COMPILER_INTERFACE_INCLUDED_
40 #include "../Include/ResourceLimits.h"
41 #include "../MachineIndependent/Versions.h"
47 #define C_DECL __cdecl
49 // #define SH_IMPORT_EXPORT __declspec(dllexport)
51 // #define SH_IMPORT_EXPORT __declspec(dllimport)
53 #define SH_IMPORT_EXPORT
55 #define SH_IMPORT_EXPORT
60 // This is the platform independent interface between an OGL driver
61 // and the shading language compiler/linker.
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
74 // Call before doing any other compiler/linker operations.
76 // (Call once per process, not once per thread.)
78 SH_IMPORT_EXPORT int ShInitialize();
81 // Call this at process shutdown to clean up memory.
83 SH_IMPORT_EXPORT int ShFinalize();
86 // Types of languages the compiler can consume.
91 EShLangTessEvaluation,
103 LAST_ELEMENT_MARKER(EShLangCount),
104 } EShLanguage; // would be better as stage, but this is ancient now
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),
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
136 EShClientNone, // use when there is no client, e.g. for validation
139 LAST_ELEMENT_MARKER(EShClientCount),
144 EShTargetSpv, // SPIR-V (preferred spelling)
145 EshTargetSpv = EShTargetSpv, // legacy spelling
146 LAST_ELEMENT_MARKER(EShTargetCount),
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;
156 typedef EShTargetClientVersion EshTargetClientVersion;
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;
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
172 int dialectVersion; // version of client's language definition, not the client (when not EShClientNone)
177 EShTargetClientVersion version; // version of client itself (not the client's input dialect)
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)
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
195 const char* StageName(EShLanguage);
197 } // end namespace glslang
200 // Types of output the linker will create.
208 // Optimization level for the compiler.
213 EShOptSimple, // Optimizations that can be done quickly
214 EShOptFull, // Optimizations that will take more time
215 LAST_ELEMENT_MARKER(EshOptLevelCount),
216 } EShOptimizationLevel;
219 // Texture and Sampler transformation mode.
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;
228 // Message choices for what errors and warnings are given.
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),
251 // Options for building reflection
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;
265 // Build a table for bindings. This can be used for locating
266 // attributes, uniforms, globals, etc., as needed.
275 ShBinding* bindings; // array of bindings
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.
285 // If handle creation fails, 0 will be returned.
287 typedef void* ShHandle;
290 // Driver calls these to create and destroy compiler/linker
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);
299 // The return value of ShCompile is boolean, non-zero indicating
302 // The info-log should be written by ShCompile into
303 // ShHandle, so it can answer future queries.
305 SH_IMPORT_EXPORT int ShCompile(
307 const char* const shaderStrings[],
308 const int numStrings,
310 const EShOptimizationLevel,
311 const TBuiltInResource *resources,
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
318 SH_IMPORT_EXPORT int ShLinkExt(
319 const ShHandle, // linker object
320 const ShHandle h[], // compiler objects to link together
321 const int numHandles);
324 // ShSetEncrpytionMethod is a place-holder for specifying
325 // how source code is encrypted.
327 SH_IMPORT_EXPORT void ShSetEncryptionMethod(ShHandle);
330 // All the following return 0 if the information is not
331 // available in the object passed down, or the object is bad.
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
338 // Tell the linker to never assign a vertex attribute to this list of physical attributes
340 SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count);
343 // Returns the location ID of the named uniform.
344 // Returns -1 if error.
346 SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
352 ////////////////////////////////////////////////////////////////////////////////////////////
354 // Deferred-Lowering C++ Interface
355 // -----------------------------------
357 // Below is a new alternate C++ interface, which deprecates the above
358 // opaque handle-based interface.
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.
377 const char* GetEsslVersionString();
378 const char* GetGlslVersionString();
379 int GetKhronosToolId();
383 class TPoolAllocator;
385 // Call this exactly once per process before using anything else
386 bool InitializeProcess();
388 // Call once per process to tear down everything
389 void FinalizeProcess();
391 // Resource type for IO resolver
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
412 // N.B.: Does not yet support having the same TShader instance being linked into
413 // multiple programs.
415 // N.B.: Destruct a linked program *before* destructing the shaders linked into it.
419 explicit TShader(EShLanguage);
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>&);
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);
447 void setHlslIoMapping(bool hlslIoMap);
448 void setFlattenUniformArrays(bool flatten);
450 void setNoStorageFormat(bool useUnknownFormat);
451 void setNanMinMaxClamp(bool nanMinMaxClamp);
452 void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
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.
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.
466 // See the definitions of TEnvironment, EShSource, EShLanguage,
467 // and EShClient for choices and more detail.
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.
475 // See EShTargetClientVersion for choices.
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.
482 void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version)
484 environment.input.languageFamily = lang;
485 environment.input.stage = envStage;
486 environment.input.dialect = client;
487 environment.input.dialectVersion = version;
489 void setEnvClient(EShClient client, EShTargetClientVersion version)
491 environment.client.client = client;
492 environment.client.version = version;
494 void setEnvTarget(EShTargetLanguage lang, EShTargetLanguageVersion version)
496 environment.target.language = lang;
497 environment.target.version = version;
500 void getStrings(const char* const* &s, int& n) { s = strings; n = numStrings; }
503 void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; }
504 bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; }
506 bool getEnvTargetHlslFunctionality1() const { return false; }
509 // Interface to #include handlers.
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.
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.
526 // An IncludeResult contains the resolved name and content of a source
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
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.
546 IncludeResult& operator=(const IncludeResult&);
550 // For both include methods below:
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
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.
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.
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; }
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; }
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() {}
586 // Fail all Includer searches
587 class ForbidIncluder : public Includer {
589 virtual void releaseInclude(IncludeResult*) override { }
592 bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
593 bool forwardCompatible, EShMessages, Includer&);
595 bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
596 bool forwardCompatible, EShMessages messages)
598 TShader::ForbidIncluder includer;
599 return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
602 // Equivalent to parse() without a default profile and without forcing defaults.
603 bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
605 return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
608 bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages,
611 return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer);
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,
621 const char* getInfoLog();
622 const char* getInfoDebugLog();
623 EShLanguage getStage() const { return stage; }
624 TIntermediate* getIntermediate() const { return intermediate; }
627 TPoolAllocator* pool;
630 TIntermediate* intermediate;
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;
643 const char* const* stringNames;
644 const char* preamble;
647 // a function in the source string can be renamed FROM this TO the name given in setEntryPoint.
648 std::string sourceEntryPointName;
650 TEnvironment environment;
652 friend class TProgram;
655 TShader& operator=(TShader&);
661 // A reflection database and its interface, consistent with the OpenGL API reflection queries.
664 // Data needed for just a single object at the granularity exchanged by the reflection API
665 class TObjectReflection {
667 TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
669 const TType* getType() const { return type; }
670 int getBinding() const;
672 static TObjectReflection badReflection() { return TObjectReflection(); }
677 int size; // data size in bytes for a block, array size for a (non-block) object that's an array
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;
687 : offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), numMembers(-1), arrayStride(0),
688 topLevelArrayStride(0), stages(EShLanguageMask(0)), type(nullptr)
697 struct TVarEntryInfo;
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.
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
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.
720 // NOTE: that still limit checks are applied to bindings and sets
721 // and may result in an error.
725 virtual ~TIoMapResolver() {}
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;
775 #endif // GLSLANG_WEB
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().
781 // N.B.: Destruct a linked program *before* destructing the shaders linked into it.
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();
794 TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
798 // Reflection Interface
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;
820 // Legacy Reflection Interface - expressed in terms of above interface
822 // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS)
823 int getNumLiveUniformVariables() const { return getNumUniformVariables(); }
825 // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS)
826 int getNumLiveUniformBlocks() const { return getNumUniformBlocks(); }
828 // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
829 int getNumLiveAttributes() const { return getNumPipeInputs(); }
831 // can be used for glGetUniformIndices()
832 int getUniformIndex(const char *name) const { return getReflectionIndex(name); }
834 int getPipeIOIndex(const char *name, const bool inOrOut) const
835 { return getReflectionPipeIOIndex(name, inOrOut); }
837 // can be used for "name" part of glGetActiveUniform()
838 const char *getUniformName(int index) const { return getUniform(index).name.c_str(); }
840 // returns the binding number
841 int getUniformBinding(int index) const { return getUniform(index).getBinding(); }
843 // returns Shaders Stages where a Uniform is present
844 EShLanguageMask getUniformStages(int index) const { return getUniform(index).stages; }
846 // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX)
847 int getUniformBlockIndex(int index) const { return getUniform(index).index; }
849 // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE)
850 int getUniformType(int index) const { return getUniform(index).glDefineType; }
852 // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET)
853 int getUniformBufferOffset(int index) const { return getUniform(index).offset; }
855 // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
856 int getUniformArraySize(int index) const { return getUniform(index).size; }
859 const TType *getUniformTType(int index) const { return getUniform(index).getType(); }
861 // can be used for glGetActiveUniformBlockName()
862 const char *getUniformBlockName(int index) const { return getUniformBlock(index).name.c_str(); }
864 // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE)
865 int getUniformBlockSize(int index) const { return getUniformBlock(index).size; }
867 // returns the block binding number
868 int getUniformBlockBinding(int index) const { return getUniformBlock(index).getBinding(); }
870 // returns block index of associated counter.
871 int getUniformBlockCounterIndex(int index) const { return getUniformBlock(index).counterIndex; }
874 const TType *getUniformBlockTType(int index) const { return getUniformBlock(index).getType(); }
876 // can be used for glGetActiveAttrib()
877 const char *getAttributeName(int index) const { return getPipeInput(index).name.c_str(); }
879 // can be used for glGetActiveAttrib()
880 int getAttributeType(int index) const { return getPipeInput(index).glDefineType; }
883 const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); }
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);
893 bool linkStage(EShLanguage, EShMessages);
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
901 TReflection* reflection;
907 TProgram& operator=(TProgram&);
910 } // end namespace glslang
912 #endif // _COMPILER_INTERFACE_INCLUDED_