summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/glslang/glslang/Public/ShaderLang.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/glslang/glslang/Public/ShaderLang.h')
-rw-r--r--src/3rdparty/glslang/glslang/Public/ShaderLang.h846
1 files changed, 846 insertions, 0 deletions
diff --git a/src/3rdparty/glslang/glslang/Public/ShaderLang.h b/src/3rdparty/glslang/glslang/Public/ShaderLang.h
new file mode 100644
index 0000000..0c25569
--- /dev/null
+++ b/src/3rdparty/glslang/glslang/Public/ShaderLang.h
@@ -0,0 +1,846 @@
+//
+// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+// Copyright (C) 2013-2016 LunarG, Inc.
+// Copyright (C) 2015-2018 Google, Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+#ifndef _COMPILER_INTERFACE_INCLUDED_
+#define _COMPILER_INTERFACE_INCLUDED_
+
+#include "../Include/ResourceLimits.h"
+#include "../MachineIndependent/Versions.h"
+
+#include <cstring>
+#include <vector>
+
+#ifdef _WIN32
+#define C_DECL __cdecl
+//#ifdef SH_EXPORTING
+// #define SH_IMPORT_EXPORT __declspec(dllexport)
+//#else
+// #define SH_IMPORT_EXPORT __declspec(dllimport)
+//#endif
+#define SH_IMPORT_EXPORT
+#else
+#define SH_IMPORT_EXPORT
+#define C_DECL
+#endif
+
+//
+// This is the platform independent interface between an OGL driver
+// and the shading language compiler/linker.
+//
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+// This should always increase, as some paths to do not consume
+// a more major number.
+// It should increment by one when new functionality is added.
+#define GLSLANG_MINOR_VERSION 11
+
+//
+// Call before doing any other compiler/linker operations.
+//
+// (Call once per process, not once per thread.)
+//
+SH_IMPORT_EXPORT int ShInitialize();
+
+//
+// Call this at process shutdown to clean up memory.
+//
+SH_IMPORT_EXPORT int ShFinalize();
+
+//
+// Types of languages the compiler can consume.
+//
+typedef enum {
+ EShLangVertex,
+ EShLangTessControl,
+ EShLangTessEvaluation,
+ EShLangGeometry,
+ EShLangFragment,
+ EShLangCompute,
+ EShLangRayGenNV,
+ EShLangIntersectNV,
+ EShLangAnyHitNV,
+ EShLangClosestHitNV,
+ EShLangMissNV,
+ EShLangCallableNV,
+ EShLangTaskNV,
+ EShLangMeshNV,
+ EShLangCount,
+} EShLanguage; // would be better as stage, but this is ancient now
+
+typedef enum {
+ EShLangVertexMask = (1 << EShLangVertex),
+ EShLangTessControlMask = (1 << EShLangTessControl),
+ EShLangTessEvaluationMask = (1 << EShLangTessEvaluation),
+ EShLangGeometryMask = (1 << EShLangGeometry),
+ EShLangFragmentMask = (1 << EShLangFragment),
+ EShLangComputeMask = (1 << EShLangCompute),
+ EShLangRayGenNVMask = (1 << EShLangRayGenNV),
+ EShLangIntersectNVMask = (1 << EShLangIntersectNV),
+ EShLangAnyHitNVMask = (1 << EShLangAnyHitNV),
+ EShLangClosestHitNVMask = (1 << EShLangClosestHitNV),
+ EShLangMissNVMask = (1 << EShLangMissNV),
+ EShLangCallableNVMask = (1 << EShLangCallableNV),
+ EShLangTaskNVMask = (1 << EShLangTaskNV),
+ EShLangMeshNVMask = (1 << EShLangMeshNV),
+} EShLanguageMask;
+
+namespace glslang {
+
+class TType;
+
+typedef enum {
+ EShSourceNone,
+ EShSourceGlsl,
+ EShSourceHlsl,
+} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead
+
+typedef enum {
+ EShClientNone,
+ EShClientVulkan,
+ EShClientOpenGL,
+} EShClient;
+
+typedef enum {
+ EShTargetNone,
+ EShTargetSpv, // preferred spelling
+ EshTargetSpv = EShTargetSpv, // legacy spelling
+} EShTargetLanguage;
+
+typedef enum {
+ EShTargetVulkan_1_0 = (1 << 22),
+ EShTargetVulkan_1_1 = (1 << 22) | (1 << 12),
+ EShTargetOpenGL_450 = 450,
+} EShTargetClientVersion;
+
+typedef EShTargetClientVersion EshTargetClientVersion;
+
+typedef enum {
+ EShTargetSpv_1_0 = (1 << 16),
+ EShTargetSpv_1_1 = (1 << 16) | (1 << 8),
+ EShTargetSpv_1_2 = (1 << 16) | (2 << 8),
+ EShTargetSpv_1_3 = (1 << 16) | (3 << 8),
+ EShTargetSpv_1_4 = (1 << 16) | (4 << 8),
+} EShTargetLanguageVersion;
+
+struct TInputLanguage {
+ EShSource languageFamily; // redundant information with other input, this one overrides when not EShSourceNone
+ EShLanguage stage; // redundant information with other input, this one overrides when not EShSourceNone
+ EShClient dialect;
+ int dialectVersion; // version of client's language definition, not the client (when not EShClientNone)
+};
+
+struct TClient {
+ EShClient client;
+ EShTargetClientVersion version; // version of client itself (not the client's input dialect)
+};
+
+struct TTarget {
+ EShTargetLanguage language;
+ EShTargetLanguageVersion version; // version to target, if SPIR-V, defined by "word 1" of the SPIR-V header
+ bool hlslFunctionality1; // can target hlsl_functionality1 extension(s)
+};
+
+// All source/client/target versions and settings.
+// Can override previous methods of setting, when items are set here.
+// Expected to grow, as more are added, rather than growing parameter lists.
+struct TEnvironment {
+ TInputLanguage input; // definition of the input language
+ TClient client; // what client is the overall compilation being done for?
+ TTarget target; // what to generate
+};
+
+const char* StageName(EShLanguage);
+
+} // end namespace glslang
+
+//
+// Types of output the linker will create.
+//
+typedef enum {
+ EShExVertexFragment,
+ EShExFragment
+} EShExecutable;
+
+//
+// Optimization level for the compiler.
+//
+typedef enum {
+ EShOptNoGeneration,
+ EShOptNone,
+ EShOptSimple, // Optimizations that can be done quickly
+ EShOptFull, // Optimizations that will take more time
+} EShOptimizationLevel;
+
+//
+// Texture and Sampler transformation mode.
+//
+typedef enum {
+ EShTexSampTransKeep, // keep textures and samplers as is (default)
+ EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers
+} EShTextureSamplerTransformMode;
+
+//
+// Message choices for what errors and warnings are given.
+//
+enum EShMessages {
+ EShMsgDefault = 0, // default is to give all required errors and extra warnings
+ EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input
+ EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification
+ EShMsgAST = (1 << 2), // print the AST intermediate representation
+ EShMsgSpvRules = (1 << 3), // issue messages for SPIR-V generation
+ EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V
+ EShMsgOnlyPreprocessor = (1 << 5), // only print out errors produced by the preprocessor
+ EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics
+ EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit
+ EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions
+ EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules
+ EShMsgDebugInfo = (1 << 10), // save debug information
+ EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
+ EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
+ EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers)
+};
+
+//
+// Options for building reflection
+//
+typedef enum {
+ EShReflectionDefault = 0, // default is original behaviour before options were added
+ EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes
+ EShReflectionBasicArraySuffix = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection
+ EShReflectionIntermediateIO = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader
+ EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately
+ EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive
+ EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks
+} EShReflectionOptions;
+
+//
+// Build a table for bindings. This can be used for locating
+// attributes, uniforms, globals, etc., as needed.
+//
+typedef struct {
+ const char* name;
+ int binding;
+} ShBinding;
+
+typedef struct {
+ int numBindings;
+ ShBinding* bindings; // array of bindings
+} ShBindingTable;
+
+//
+// ShHandle held by but opaque to the driver. It is allocated,
+// managed, and de-allocated by the compiler/linker. It's contents
+// are defined by and used by the compiler and linker. For example,
+// symbol table information and object code passed from the compiler
+// to the linker can be stored where ShHandle points.
+//
+// If handle creation fails, 0 will be returned.
+//
+typedef void* ShHandle;
+
+//
+// Driver calls these to create and destroy compiler/linker
+// objects.
+//
+SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader
+SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair
+SH_IMPORT_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object)
+SH_IMPORT_EXPORT void ShDestruct(ShHandle);
+
+//
+// The return value of ShCompile is boolean, non-zero indicating
+// success.
+//
+// The info-log should be written by ShCompile into
+// ShHandle, so it can answer future queries.
+//
+SH_IMPORT_EXPORT int ShCompile(
+ const ShHandle,
+ const char* const shaderStrings[],
+ const int numStrings,
+ const int* lengths,
+ const EShOptimizationLevel,
+ const TBuiltInResource *resources,
+ int debugOptions,
+ int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader
+ bool forwardCompatible = false, // give errors for use of deprecated features
+ EShMessages messages = EShMsgDefault // warnings and errors
+ );
+
+SH_IMPORT_EXPORT int ShLinkExt(
+ const ShHandle, // linker object
+ const ShHandle h[], // compiler objects to link together
+ const int numHandles);
+
+//
+// ShSetEncrpytionMethod is a place-holder for specifying
+// how source code is encrypted.
+//
+SH_IMPORT_EXPORT void ShSetEncryptionMethod(ShHandle);
+
+//
+// All the following return 0 if the information is not
+// available in the object passed down, or the object is bad.
+//
+SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle);
+SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle);
+SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing
+SH_IMPORT_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings
+//
+// Tell the linker to never assign a vertex attribute to this list of physical attributes
+//
+SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count);
+
+//
+// Returns the location ID of the named uniform.
+// Returns -1 if error.
+//
+SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
+
+#ifdef __cplusplus
+ } // end extern "C"
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Deferred-Lowering C++ Interface
+// -----------------------------------
+//
+// Below is a new alternate C++ interface, which deprecates the above
+// opaque handle-based interface.
+//
+// The below is further designed to handle multiple compilation units per stage, where
+// the intermediate results, including the parse tree, are preserved until link time,
+// rather than the above interface which is designed to have each compilation unit
+// lowered at compile time. In the above model, linking occurs on the lowered results,
+// whereas in this model intra-stage linking can occur at the parse tree
+// (treeRoot in TIntermediate) level, and then a full stage can be lowered.
+//
+
+#include <list>
+#include <string>
+#include <utility>
+
+class TCompiler;
+class TInfoSink;
+
+namespace glslang {
+
+const char* GetEsslVersionString();
+const char* GetGlslVersionString();
+int GetKhronosToolId();
+
+class TIntermediate;
+class TProgram;
+class TPoolAllocator;
+
+// Call this exactly once per process before using anything else
+bool InitializeProcess();
+
+// Call once per process to tear down everything
+void FinalizeProcess();
+
+// Resource type for IO resolver
+enum TResourceType {
+ EResSampler,
+ EResTexture,
+ EResImage,
+ EResUbo,
+ EResSsbo,
+ EResUav,
+ EResCount
+};
+
+// Make one TShader per shader that you will link into a program. Then
+// - provide the shader through setStrings() or setStringsWithLengths()
+// - optionally call setEnv*(), see below for more detail
+// - optionally use setPreamble() to set a special shader string that will be
+// processed before all others but won't affect the validity of #version
+// - call parse(): source language and target environment must be selected
+// either by correct setting of EShMessages sent to parse(), or by
+// explicitly calling setEnv*()
+// - query the info logs
+//
+// N.B.: Does not yet support having the same TShader instance being linked into
+// multiple programs.
+//
+// N.B.: Destruct a linked program *before* destructing the shaders linked into it.
+//
+class TShader {
+public:
+ explicit TShader(EShLanguage);
+ virtual ~TShader();
+ void setStrings(const char* const* s, int n);
+ void setStringsWithLengths(const char* const* s, const int* l, int n);
+ void setStringsWithLengthsAndNames(
+ const char* const* s, const int* l, const char* const* names, int n);
+ void setPreamble(const char* s) { preamble = s; }
+ void setEntryPoint(const char* entryPoint);
+ void setSourceEntryPoint(const char* sourceEntryPointName);
+ void addProcesses(const std::vector<std::string>&);
+
+ // IO resolver binding data: see comments in ShaderLang.cpp
+ void setShiftBinding(TResourceType res, unsigned int base);
+ void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
+ void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
+ void setResourceSetBinding(const std::vector<std::string>& base);
+ void setAutoMapBindings(bool map);
+ void setAutoMapLocations(bool map);
+ void addUniformLocationOverride(const char* name, int loc);
+ void setUniformLocationBase(int base);
+ void setInvertY(bool invert);
+ void setHlslIoMapping(bool hlslIoMap);
+ void setFlattenUniformArrays(bool flatten);
+ void setNoStorageFormat(bool useUnknownFormat);
+ void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
+
+ // For setting up the environment (cleared to nothingness in the constructor).
+ // These must be called so that parsing is done for the right source language and
+ // target environment, either indirectly through TranslateEnvironment() based on
+ // EShMessages et. al., or directly by the user.
+ void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version)
+ {
+ environment.input.languageFamily = lang;
+ environment.input.stage = envStage;
+ environment.input.dialect = client;
+ environment.input.dialectVersion = version;
+ }
+ void setEnvClient(EShClient client, EShTargetClientVersion version)
+ {
+ environment.client.client = client;
+ environment.client.version = version;
+ }
+ void setEnvTarget(EShTargetLanguage lang, EShTargetLanguageVersion version)
+ {
+ environment.target.language = lang;
+ environment.target.version = version;
+ }
+ void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; }
+ bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; }
+
+ // Interface to #include handlers.
+ //
+ // To support #include, a client of Glslang does the following:
+ // 1. Call setStringsWithNames to set the source strings and associated
+ // names. For example, the names could be the names of the files
+ // containing the shader sources.
+ // 2. Call parse with an Includer.
+ //
+ // When the Glslang parser encounters an #include directive, it calls
+ // the Includer's include method with the requested include name
+ // together with the current string name. The returned IncludeResult
+ // contains the fully resolved name of the included source, together
+ // with the source text that should replace the #include directive
+ // in the source stream. After parsing that source, Glslang will
+ // release the IncludeResult object.
+ class Includer {
+ public:
+ // An IncludeResult contains the resolved name and content of a source
+ // inclusion.
+ struct IncludeResult {
+ IncludeResult(const std::string& headerName, const char* const headerData, const size_t headerLength, void* userData) :
+ headerName(headerName), headerData(headerData), headerLength(headerLength), userData(userData) { }
+ // For a successful inclusion, the fully resolved name of the requested
+ // include. For example, in a file system-based includer, full resolution
+ // should convert a relative path name into an absolute path name.
+ // For a failed inclusion, this is an empty string.
+ const std::string headerName;
+ // The content and byte length of the requested inclusion. The
+ // Includer producing this IncludeResult retains ownership of the
+ // storage.
+ // For a failed inclusion, the header
+ // field points to a string containing error details.
+ const char* const headerData;
+ const size_t headerLength;
+ // Include resolver's context.
+ void* userData;
+ protected:
+ IncludeResult& operator=(const IncludeResult&);
+ IncludeResult();
+ };
+
+ // For both include methods below:
+ //
+ // Resolves an inclusion request by name, current source name,
+ // and include depth.
+ // On success, returns an IncludeResult containing the resolved name
+ // and content of the include.
+ // On failure, returns a nullptr, or an IncludeResult
+ // with an empty string for the headerName and error details in the
+ // header field.
+ // The Includer retains ownership of the contents
+ // of the returned IncludeResult value, and those contents must
+ // remain valid until the releaseInclude method is called on that
+ // IncludeResult object.
+ //
+ // Note "local" vs. "system" is not an "either/or": "local" is an
+ // extra thing to do over "system". Both might get called, as per
+ // the C++ specification.
+
+ // For the "system" or <>-style includes; search the "system" paths.
+ virtual IncludeResult* includeSystem(const char* /*headerName*/,
+ const char* /*includerName*/,
+ size_t /*inclusionDepth*/) { return nullptr; }
+
+ // For the "local"-only aspect of a "" include. Should not search in the
+ // "system" paths, because on returning a failure, the parser will
+ // call includeSystem() to look in the "system" locations.
+ virtual IncludeResult* includeLocal(const char* /*headerName*/,
+ const char* /*includerName*/,
+ size_t /*inclusionDepth*/) { return nullptr; }
+
+ // Signals that the parser will no longer use the contents of the
+ // specified IncludeResult.
+ virtual void releaseInclude(IncludeResult*) = 0;
+ virtual ~Includer() {}
+ };
+
+ // Fail all Includer searches
+ class ForbidIncluder : public Includer {
+ public:
+ virtual void releaseInclude(IncludeResult*) override { }
+ };
+
+ bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
+ bool forwardCompatible, EShMessages, Includer&);
+
+ bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
+ bool forwardCompatible, EShMessages messages)
+ {
+ TShader::ForbidIncluder includer;
+ return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
+ }
+
+ // Equivalent to parse() without a default profile and without forcing defaults.
+ bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
+ {
+ return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
+ }
+
+ bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages,
+ Includer& includer)
+ {
+ return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer);
+ }
+
+ // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
+ // is not an officially supported or fully working path.
+ bool preprocess(const TBuiltInResource* builtInResources,
+ int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
+ bool forwardCompatible, EShMessages message, std::string* outputString,
+ Includer& includer);
+
+ const char* getInfoLog();
+ const char* getInfoDebugLog();
+ EShLanguage getStage() const { return stage; }
+ TIntermediate* getIntermediate() const { return intermediate; }
+
+protected:
+ TPoolAllocator* pool;
+ EShLanguage stage;
+ TCompiler* compiler;
+ TIntermediate* intermediate;
+ TInfoSink* infoSink;
+ // strings and lengths follow the standard for glShaderSource:
+ // strings is an array of numStrings pointers to string data.
+ // lengths can be null, but if not it is an array of numStrings
+ // integers containing the length of the associated strings.
+ // if lengths is null or lengths[n] < 0 the associated strings[n] is
+ // assumed to be null-terminated.
+ // stringNames is the optional names for all the strings. If stringNames
+ // is null, then none of the strings has name. If a certain element in
+ // stringNames is null, then the corresponding string does not have name.
+ const char* const* strings;
+ const int* lengths;
+ const char* const* stringNames;
+ const char* preamble;
+ int numStrings;
+
+ // a function in the source string can be renamed FROM this TO the name given in setEntryPoint.
+ std::string sourceEntryPointName;
+
+ TEnvironment environment;
+
+ friend class TProgram;
+
+private:
+ TShader& operator=(TShader&);
+};
+
+//
+// A reflection database and its interface, consistent with the OpenGL API reflection queries.
+//
+
+// Data needed for just a single object at the granularity exchanged by the reflection API
+class TObjectReflection {
+public:
+ TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
+
+ const TType* getType() const { return type; }
+ int getBinding() const;
+ void dump() const;
+ static TObjectReflection badReflection() { return TObjectReflection(); }
+
+ std::string name;
+ int offset;
+ int glDefineType;
+ int size; // data size in bytes for a block, array size for a (non-block) object that's an array
+ int index;
+ int counterIndex;
+ int numMembers;
+ int arrayStride; // stride of an array variable
+ int topLevelArrayStride; // stride of the top-level variable in a storage buffer member
+ EShLanguageMask stages;
+
+protected:
+ TObjectReflection()
+ : offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), numMembers(-1), arrayStride(0),
+ topLevelArrayStride(0), stages(EShLanguageMask(0)), type(nullptr)
+ {
+ }
+
+ const TType* type;
+};
+
+class TReflection;
+class TIoMapper;
+
+// Allows to customize the binding layout after linking.
+// All used uniform variables will invoke at least validateBinding.
+// If validateBinding returned true then the other resolveBinding,
+// resolveSet, and resolveLocation are invoked to resolve the binding
+// and descriptor set index respectively.
+//
+// Invocations happen in a particular order:
+// 1) all shader inputs
+// 2) all shader outputs
+// 3) all uniforms with binding and set already defined
+// 4) all uniforms with binding but no set defined
+// 5) all uniforms with set but no binding defined
+// 6) all uniforms with no binding and no set defined
+//
+// mapIO will use this resolver in two phases. The first
+// phase is a notification phase, calling the corresponging
+// notifiy callbacks, this phase ends with a call to endNotifications.
+// Phase two starts directly after the call to endNotifications
+// and calls all other callbacks to validate and to get the
+// bindings, sets, locations, component and color indices.
+//
+// NOTE: that still limit checks are applied to bindings and sets
+// and may result in an error.
+class TIoMapResolver
+{
+public:
+ virtual ~TIoMapResolver() {}
+
+ // Should return true if the resulting/current binding would be okay.
+ // Basic idea is to do aliasing binding checks with this.
+ virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+ // Should return a value >= 0 if the current binding should be overridden.
+ // Return -1 if the current binding (including no binding) should be kept.
+ virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+ // Should return a value >= 0 if the current set should be overridden.
+ // Return -1 if the current set (including no set) should be kept.
+ virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+ // Should return a value >= 0 if the current location should be overridden.
+ // Return -1 if the current location (including no location) should be kept.
+ virtual int resolveUniformLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+ // Should return true if the resulting/current setup would be okay.
+ // Basic idea is to do aliasing checks and reject invalid semantic names.
+ virtual bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+ // Should return a value >= 0 if the current location should be overridden.
+ // Return -1 if the current location (including no location) should be kept.
+ virtual int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+ // Should return a value >= 0 if the current component index should be overridden.
+ // Return -1 if the current component index (including no index) should be kept.
+ virtual int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+ // Should return a value >= 0 if the current color index should be overridden.
+ // Return -1 if the current color index (including no index) should be kept.
+ virtual int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+ // Notification of a uniform variable
+ virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+ // Notification of a in or out variable
+ virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+ // Called by mapIO when it has finished the notify pass
+ virtual void endNotifications(EShLanguage stage) = 0;
+ // Called by mapIO when it starts its notify pass for the given stage
+ virtual void beginNotifications(EShLanguage stage) = 0;
+ // Called by mipIO when it starts its resolve pass for the given stage
+ virtual void beginResolve(EShLanguage stage) = 0;
+ // Called by mapIO when it has finished the resolve pass
+ virtual void endResolve(EShLanguage stage) = 0;
+};
+
+// Make one TProgram per set of shaders that will get linked together. Add all
+// the shaders that are to be linked together. After calling shader.parse()
+// for all shaders, call link().
+//
+// N.B.: Destruct a linked program *before* destructing the shaders linked into it.
+//
+class TProgram {
+public:
+ TProgram();
+ virtual ~TProgram();
+ void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
+
+ // Link Validation interface
+ bool link(EShMessages);
+ const char* getInfoLog();
+ const char* getInfoDebugLog();
+
+ TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
+
+ // Reflection Interface
+
+ // call first, to do liveness analysis, index mapping, etc.; returns false on failure
+ bool buildReflection(int opts = EShReflectionDefault);
+
+ unsigned getLocalSize(int dim) const; // return dim'th local size
+ int getReflectionIndex(const char *name) const;
+
+ int getNumUniformVariables() const;
+ const TObjectReflection& getUniform(int index) const;
+ int getNumUniformBlocks() const;
+ const TObjectReflection& getUniformBlock(int index) const;
+ int getNumPipeInputs() const;
+ const TObjectReflection& getPipeInput(int index) const;
+ int getNumPipeOutputs() const;
+ const TObjectReflection& getPipeOutput(int index) const;
+ int getNumBufferVariables() const;
+ const TObjectReflection& getBufferVariable(int index) const;
+ int getNumBufferBlocks() const;
+ const TObjectReflection& getBufferBlock(int index) const;
+ int getNumAtomicCounters() const;
+ const TObjectReflection& getAtomicCounter(int index) const;
+
+ // Legacy Reflection Interface - expressed in terms of above interface
+
+ // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS)
+ int getNumLiveUniformVariables() const { return getNumUniformVariables(); }
+
+ // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS)
+ int getNumLiveUniformBlocks() const { return getNumUniformBlocks(); }
+
+ // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
+ int getNumLiveAttributes() const { return getNumPipeInputs(); }
+
+ // can be used for glGetUniformIndices()
+ int getUniformIndex(const char *name) const { return getReflectionIndex(name); }
+
+ // can be used for "name" part of glGetActiveUniform()
+ const char *getUniformName(int index) const { return getUniform(index).name.c_str(); }
+
+ // returns the binding number
+ int getUniformBinding(int index) const { return getUniform(index).getBinding(); }
+
+ // returns Shaders Stages where a Uniform is present
+ EShLanguageMask getUniformStages(int index) const { return getUniform(index).stages; }
+
+ // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX)
+ int getUniformBlockIndex(int index) const { return getUniform(index).index; }
+
+ // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE)
+ int getUniformType(int index) const { return getUniform(index).glDefineType; }
+
+ // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET)
+ int getUniformBufferOffset(int index) const { return getUniform(index).offset; }
+
+ // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
+ int getUniformArraySize(int index) const { return getUniform(index).size; }
+
+ // returns a TType*
+ const TType *getUniformTType(int index) const { return getUniform(index).getType(); }
+
+ // can be used for glGetActiveUniformBlockName()
+ const char *getUniformBlockName(int index) const { return getUniformBlock(index).name.c_str(); }
+
+ // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE)
+ int getUniformBlockSize(int index) const { return getUniformBlock(index).size; }
+
+ // returns the block binding number
+ int getUniformBlockBinding(int index) const { return getUniformBlock(index).getBinding(); }
+
+ // returns block index of associated counter.
+ int getUniformBlockCounterIndex(int index) const { return getUniformBlock(index).counterIndex; }
+
+ // returns a TType*
+ const TType *getUniformBlockTType(int index) const { return getUniformBlock(index).getType(); }
+
+ // can be used for glGetActiveAttrib()
+ const char *getAttributeName(int index) const { return getPipeInput(index).name.c_str(); }
+
+ // can be used for glGetActiveAttrib()
+ int getAttributeType(int index) const { return getPipeInput(index).glDefineType; }
+
+ // returns a TType*
+ const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); }
+
+ void dumpReflection();
+
+ // I/O mapping: apply base offsets and map live unbound variables
+ // If resolver is not provided it uses the previous approach
+ // and respects auto assignment and offsets.
+ bool mapIO(TIoMapResolver* resolver = NULL);
+
+protected:
+ bool linkStage(EShLanguage, EShMessages);
+
+ TPoolAllocator* pool;
+ std::list<TShader*> stages[EShLangCount];
+ TIntermediate* intermediate[EShLangCount];
+ bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage
+ TInfoSink* infoSink;
+ TReflection* reflection;
+ TIoMapper* ioMapper;
+ bool linked;
+
+private:
+ TProgram(TProgram&);
+ TProgram& operator=(TProgram&);
+};
+
+} // end namespace glslang
+
+#endif // _COMPILER_INTERFACE_INCLUDED_