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