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

source code of qtshadertools/src/3rdparty/glslang/glslang/Public/ShaderLang.h