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