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