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