chromium/third_party/glslang/src/glslang/MachineIndependent/ShaderLang.cpp

//
// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
// Copyright (C) 2013-2016 LunarG, Inc.
// Copyright (C) 2015-2020 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.
//

//
// Implement the top-level of interface to the compiler/linker,
// as defined in ShaderLang.h
// This is the platform independent interface between an OGL driver
// and the shading language compiler/linker.
//
#include <cstring>
#include <iostream>
#include <sstream>
#include <memory>
#include <mutex>
#include "SymbolTable.h"
#include "ParseHelper.h"
#include "Scan.h"
#include "ScanContext.h"

#ifdef ENABLE_HLSL
#include "../HLSL/hlslParseHelper.h"
#include "../HLSL/hlslParseables.h"
#include "../HLSL/hlslScanContext.h"
#endif

#include "../Include/ShHandle.h"

#include "preprocessor/PpContext.h"

#define SH_EXPORTING
#include "../Public/ShaderLang.h"
#include "reflection.h"
#include "iomapper.h"
#include "Initialize.h"

// TODO: this really shouldn't be here, it is only because of the trial addition
// of printing pre-processed tokens, which requires knowing the string literal
// token to print ", but none of that seems appropriate for this file.
#include "preprocessor/PpTokens.h"

// Build-time generated includes
#include "glslang/build_info.h"

namespace { // anonymous namespace for file-local functions and symbols

// Total number of successful initializers of glslang: a refcount
// Shared global; access should be protected by a global mutex/critical section.
int NumberOfClients =;

// global initialization lock
#ifndef DISABLE_THREAD_SUPPORT
std::mutex init_lock;
#endif


usingnamespaceglslang;

// Create a language specific version of parseables.
TBuiltInParseables* CreateBuiltInParseables(TInfoSink& infoSink, EShSource source)
{}

// Create a language specific version of a parse context.
TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate& intermediate,
                                      int version, EProfile profile, EShSource source,
                                      EShLanguage language, TInfoSink& infoSink,
                                      SpvVersion spvVersion, bool forwardCompatible, EShMessages messages,
                                      bool parsingBuiltIns, std::string sourceEntryPointName = "")
{}

// Local mapping functions for making arrays of symbol tables....

const int VersionCount =;  // index range in MapVersionToIndex

int MapVersionToIndex(int version)
{}

const int SpvVersionCount =;  // index range in MapSpvVersionToIndex

int MapSpvVersionToIndex(const SpvVersion& spvVersion)
{}

const int ProfileCount =;   // index range in MapProfileToIndex

int MapProfileToIndex(EProfile profile)
{}

const int SourceCount =;

int MapSourceToIndex(EShSource source)
{}

// only one of these needed for non-ES; ES needs 2 for different precision defaults of built-ins
enum EPrecisionClass {};

// A process-global symbol table per version per profile for built-ins common
// to multiple stages (languages), and a process-global symbol table per version
// per profile per stage for built-ins unique to each stage.  They will be sparsely
// populated, so they will only be generated as needed.
//
// Each has a different set of built-ins, and we want to preserve that from
// compile to compile.
//
TSymbolTable* CommonSymbolTable[VersionCount][SpvVersionCount][ProfileCount][SourceCount][EPcCount] =;
TSymbolTable* SharedSymbolTables[VersionCount][SpvVersionCount][ProfileCount][SourceCount][EShLangCount] =;

TPoolAllocator* PerProcessGPA =;

//
// Parse and add to the given symbol table the content of the given shader string.
//
bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
                           EShSource source, TInfoSink& infoSink, TSymbolTable& symbolTable)
{}

int CommonIndex(EProfile profile, EShLanguage language)
{}

//
// To initialize per-stage shared tables, with the common table already complete.
//
void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int version, EProfile profile, const SpvVersion& spvVersion,
                                EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable,
                                TSymbolTable** symbolTables)
{}

//
// Initialize the full set of shareable symbol tables;
// The common (cross-stage) and those shareable per-stage.
//
bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable,  TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
{}

bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable& symbolTable, int version,
                               EProfile profile, const SpvVersion& spvVersion, EShLanguage language, EShSource source)
{}

//
// To do this on the fly, we want to leave the current state of our thread's
// pool allocator intact, so:
//  - Switch to a new pool for parsing the built-ins
//  - Do the parsing, which builds the symbol table, using the new pool
//  - Switch to the process-global pool to save a copy of the resulting symbol table
//  - Free up the new pool used to parse the built-ins
//  - Switch back to the original thread's pool
//
// This only gets done the first time any thread needs a particular symbol table
// (lazy evaluation).
//
void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
{}

// Function to Print all builtins
void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable)
{}

// Return true if the shader was correctly specified for version/profile/stage.
bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion,
                          EShSource source, int& version, EProfile& profile, const SpvVersion& spvVersion)
{}

// There are multiple paths in for setting environment stuff.
// TEnvironment takes precedence, for what it sets, so sort all this out.
// Ideally, the internal code could be made to use TEnvironment, but for
// now, translate it to the historically used parameters.
void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages, EShSource& source,
                          EShLanguage& stage, SpvVersion& spvVersion)
{}

// Most processes are recorded when set in the intermediate representation,
// These are the few that are not.
void RecordProcesses(TIntermediate& intermediate, EShMessages messages, const std::string& sourceEntryPointName)
{}

// This is the common setup and cleanup code for PreprocessDeferred and
// CompileDeferred.
// It takes any callable with a signature of
//  bool (TParseContextBase& parseContext, TPpContext& ppContext,
//                  TInputScanner& input, bool versionWillBeError,
//                  TSymbolTable& , TIntermediate& ,
//                  EShOptimizationLevel , EShMessages );
// Which returns false if a failure was detected and true otherwise.
//
template<typename ProcessingContext>
bool ProcessDeferred(
    TCompiler* compiler,
    const char* const shaderStrings[],
    const int numStrings,
    const int* inputLengths,
    const char* const stringNames[],
    const char* customPreamble,
    const EShOptimizationLevel optLevel,
    const TBuiltInResource* resources,
    int defaultVersion,  // use 100 for ES environment, 110 for desktop; this is the GLSL version, not SPIR-V or Vulkan
    EProfile defaultProfile,
    // set version/profile to defaultVersion/defaultProfile regardless of the #version
    // directive in the source code
    bool forceDefaultVersionAndProfile,
    int overrideVersion, // overrides version specified by #version or default version
    bool forwardCompatible,     // give errors for use of deprecated features
    EShMessages messages,       // warnings/errors/AST; things to print out
    TIntermediate& intermediate, // returned tree, etc.
    ProcessingContext& processingContext,
    bool requireNonempty,
    TShader::Includer& includer,
    const std::string sourceEntryPointName = "",
    const TEnvironment* environment = nullptr,  // optional way of fully setting all versions, overriding the above
    bool compileOnly = false)
{}

// Responsible for keeping track of the most recent source string and line in
// the preprocessor and outputting newlines appropriately if the source string
// or line changes.
class SourceLineSynchronizer {};

// DoPreprocessing is a valid ProcessingContext template argument,
// which only performs the preprocessing step of compilation.
// It places the result in the "string" argument to its constructor.
//
// This is not an officially supported or fully working path.
struct DoPreprocessing {};

// DoFullParse is a valid ProcessingConext template argument for fully
// parsing the shader.  It populates the "intermediate" with the AST.
struct DoFullParse{};

// Take a single compilation unit, and run the preprocessor on it.
// Return: True if there were no issues found in preprocessing,
//         False if during preprocessing any unknown version, pragmas or
//         extensions were found.
//
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
// is not an officially supported or fully working path.
bool PreprocessDeferred(
    TCompiler* compiler,
    const char* const shaderStrings[],
    const int numStrings,
    const int* inputLengths,
    const char* const stringNames[],
    const char* preamble,
    const EShOptimizationLevel optLevel,
    const TBuiltInResource* resources,
    int defaultVersion,         // use 100 for ES environment, 110 for desktop
    EProfile defaultProfile,
    bool forceDefaultVersionAndProfile,
    int overrideVersion,        // use 0 if not overriding GLSL version
    bool forwardCompatible,     // give errors for use of deprecated features
    EShMessages messages,       // warnings/errors/AST; things to print out
    TShader::Includer& includer,
    TIntermediate& intermediate, // returned tree, etc.
    std::string* outputString,
    TEnvironment* environment = nullptr)
{}

//
// do a partial compile on the given strings for a single compilation unit
// for a potential deferred link into a single stage (and deferred full compile of that
// stage through machine-dependent compilation).
//
// all preprocessing, parsing, semantic checks, etc. for a single compilation unit
// are done here.
//
// return:  the tree and other information is filled into the intermediate argument,
//          and true is returned by the function for success.
//
bool CompileDeferred(
    TCompiler* compiler,
    const char* const shaderStrings[],
    const int numStrings,
    const int* inputLengths,
    const char* const stringNames[],
    const char* preamble,
    const EShOptimizationLevel optLevel,
    const TBuiltInResource* resources,
    int defaultVersion,         // use 100 for ES environment, 110 for desktop
    EProfile defaultProfile,
    bool forceDefaultVersionAndProfile,
    int overrideVersion,        // use 0 if not overriding GLSL version
    bool forwardCompatible,     // give errors for use of deprecated features
    EShMessages messages,       // warnings/errors/AST; things to print out
    TIntermediate& intermediate,// returned tree, etc.
    TShader::Includer& includer,
    const std::string sourceEntryPointName = "",
    TEnvironment* environment = nullptr,
    bool compileOnly = false)
{}

} // end anonymous namespace for local functions

//
// ShInitialize() should be called exactly once per process, not per thread.
//
int ShInitialize()
{}

//
// Driver calls these to create and destroy compiler/linker
// objects.
//

ShHandle ShConstructCompiler(const EShLanguage language, int /*debugOptions unused*/)
{}

ShHandle ShConstructLinker(const EShExecutable executable, int /*debugOptions unused*/)
{}

ShHandle ShConstructUniformMap()
{}

void ShDestruct(ShHandle handle)
{}

//
// Cleanup symbol tables
//
int ShFinalize()
{}

//
// Do a full compile on the given strings for a single compilation unit
// forming a complete stage.  The result of the machine dependent compilation
// is left in the provided compile object.
//
// Return:  The return value is really boolean, indicating
// success (1) or failure (0).
//
int ShCompile(
    const ShHandle handle,
    const char* const shaderStrings[],
    const int numStrings,
    const int* inputLengths,
    const EShOptimizationLevel optLevel,
    const TBuiltInResource* resources,
    int /*debugOptions*/,
    int defaultVersion,        // use 100 for ES environment, 110 for desktop
    bool forwardCompatible,    // give errors for use of deprecated features
    EShMessages messages,       // warnings/errors/AST; things to print out,
    const char *shaderFileName // the filename
    )
{}

//
// Link the given compile objects.
//
// Return:  The return value of is really boolean, indicating
// success or failure.
//
int ShLinkExt(
    const ShHandle linkHandle,
    const ShHandle compHandles[],
    const int numHandles)
{}

//
// ShSetEncrpytionMethod is a place-holder for specifying
// how source code is encrypted.
//
void ShSetEncryptionMethod(ShHandle handle)
{}

//
// Return any compiler/linker/uniformmap log of messages for the application.
//
const char* ShGetInfoLog(const ShHandle handle)
{}

//
// Return the resulting binary code from the link process.  Structure
// is machine dependent.
//
const void* ShGetExecutable(const ShHandle handle)
{}

//
// Let the linker know where the application said it's attributes are bound.
// The linker does not use these values, they are remapped by the ICD or
// hardware.  It just needs them to know what's aliased.
//
// Return:  The return value of is really boolean, indicating
// success or failure.
//
int ShSetVirtualAttributeBindings(const ShHandle handle, const ShBindingTable* table)
{}

//
// Let the linker know where the predefined attributes have to live.
//
int ShSetFixedAttributeBindings(const ShHandle handle, const ShBindingTable* table)
{}

//
// Some attribute locations are off-limits to the linker...
//
int ShExcludeAttributes(const ShHandle handle, int *attributes, int count)
{}

//
// Return the index for OpenGL to use for knowing where a uniform lives.
//
// Return:  The return value of is really boolean, indicating
// success or failure.
//
int ShGetUniformLocation(const ShHandle handle, const char* name)
{}

////////////////////////////////////////////////////////////////////////////////////////////
//
// Deferred-Lowering C++ Interface
// -----------------------------------
//
// Below is a new alternate C++ interface that might potentially replace the above
// opaque handle-based interface.
//
// See more detailed comment in ShaderLang.h
//

namespace glslang {

Version GetVersion()
{}

#define QUOTE(s)
#define STR(n)

const char* GetEsslVersionString()
{}

const char* GetGlslVersionString()
{}

int GetKhronosToolId()
{}

bool InitializeProcess()
{}

void FinalizeProcess()
{}

class TDeferredCompiler : public TCompiler {};

TShader::TShader(EShLanguage s)
    :{}

TShader::~TShader()
{}

void TShader::setStrings(const char* const* s, int n)
{}

void TShader::setStringsWithLengths(const char* const* s, const int* l, int n)
{}

void TShader::setStringsWithLengthsAndNames(
    const char* const* s, const int* l, const char* const* names, int n)
{}

void TShader::setEntryPoint(const char* entryPoint)
{}

void TShader::setSourceEntryPoint(const char* name)
{}

// Log initial settings and transforms.
// See comment for class TProcesses.
void TShader::addProcesses(const std::vector<std::string>& p)
{}

void  TShader::setUniqueId(unsigned long long id)
{}

void TShader::setOverrideVersion(int version)
{}

void TShader::setDebugInfo(bool debugInfo)              {}
void TShader::setInvertY(bool invert)                   {}
void TShader::setDxPositionW(bool invert)               {}
void TShader::setEnhancedMsgs()                         {}
void TShader::setNanMinMaxClamp(bool useNonNan)         {}

// Set binding base for given resource type
void TShader::setShiftBinding(TResourceType res, unsigned int base) {}

// Set binding base for given resource type for a given binding set.
void TShader::setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set) {}

// Set binding base for sampler types
void TShader::setShiftSamplerBinding(unsigned int base) {}
// Set binding base for texture types (SRV)
void TShader::setShiftTextureBinding(unsigned int base) {}
// Set binding base for image types
void TShader::setShiftImageBinding(unsigned int base)   {}
// Set binding base for uniform buffer objects (CBV)
void TShader::setShiftUboBinding(unsigned int base)     {}
// Synonym for setShiftUboBinding, to match HLSL language.
void TShader::setShiftCbufferBinding(unsigned int base) {}
// Set binding base for UAV (unordered access view)
void TShader::setShiftUavBinding(unsigned int base)     {}
// Set binding base for SSBOs
void TShader::setShiftSsboBinding(unsigned int base)    {}
// Enables binding automapping using TIoMapper
void TShader::setAutoMapBindings(bool map)              {}
// Enables position.Y output negation in vertex shader

// Fragile: currently within one stage: simple auto-assignment of location
void TShader::setAutoMapLocations(bool map)             {}
void TShader::addUniformLocationOverride(const char* name, int loc)
{}
void TShader::setUniformLocationBase(int base)
{}
void TShader::setNoStorageFormat(bool useUnknownFormat) {}
void TShader::setResourceSetBinding(const std::vector<std::string>& base)   {}
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) {}

void TShader::addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing) {}

void TShader::setGlobalUniformBlockName(const char* name) {}
void TShader::setGlobalUniformSet(unsigned int set) {}
void TShader::setGlobalUniformBinding(unsigned int binding) {}

void TShader::setAtomicCounterBlockName(const char* name) {}
void TShader::setAtomicCounterBlockSet(unsigned int set) {}

void TShader::addSourceText(const char* text, size_t len) {}
void TShader::setSourceFile(const char* file) {}

#ifdef ENABLE_HLSL
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
void TShader::setHlslIoMapping(bool hlslIoMap)          {}
void TShader::setFlattenUniformArrays(bool flatten)     {}
#endif

//
// Turn the shader strings into a parse tree in the TIntermediate.
//
// Returns true for success.
//
bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
                    bool forwardCompatible, EShMessages messages, Includer& includer)
{}

// Fill in a string with the result of preprocessing ShaderStrings
// Returns true if all extensions, pragmas and version strings were valid.
//
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
// is not an officially supported or fully working path.
bool TShader::preprocess(const TBuiltInResource* builtInResources,
                         int defaultVersion, EProfile defaultProfile,
                         bool forceDefaultVersionAndProfile,
                         bool forwardCompatible, EShMessages message,
                         std::string* output_string,
                         Includer& includer)
{}

const char* TShader::getInfoLog()
{}

const char* TShader::getInfoDebugLog()
{}

TProgram::TProgram() :{}

TProgram::~TProgram()
{}

//
// Merge the compilation units within each stage into a single TIntermediate.
// All starting compilation units need to be the result of calling TShader::parse().
//
// Return true for success.
//
bool TProgram::link(EShMessages messages)
{}

//
// Merge the compilation units within the given stage into a single TIntermediate.
//
// Return true for success.
//
bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
{}

//
// Check that there are no errors in linker objects accross stages
//
// Return true if no errors.
//
bool TProgram::crossStageCheck(EShMessages) {}

const char* TProgram::getInfoLog()
{}

const char* TProgram::getInfoDebugLog()
{}

//
// Reflection implementation.
//

unsigned int TObjectReflection::layoutLocation() const {}

bool TProgram::buildReflection(int opts)
{}

unsigned TProgram::getLocalSize(int dim) const                        {}
int TProgram::getReflectionIndex(const char* name) const              {}
int TProgram::getReflectionPipeIOIndex(const char* name, const bool inOrOut) const
                                                                      {}

int TProgram::getNumUniformVariables() const                          {}
const TObjectReflection& TProgram::getUniform(int index) const        {}
int TProgram::getNumUniformBlocks() const                             {}
const TObjectReflection& TProgram::getUniformBlock(int index) const   {}
int TProgram::getNumPipeInputs() const                                {}
const TObjectReflection& TProgram::getPipeInput(int index) const      {}
int TProgram::getNumPipeOutputs() const                               {}
const TObjectReflection& TProgram::getPipeOutput(int index) const     {}
int TProgram::getNumBufferVariables() const                           {}
const TObjectReflection& TProgram::getBufferVariable(int index) const {}
int TProgram::getNumBufferBlocks() const                              {}
const TObjectReflection& TProgram::getBufferBlock(int index) const    {}
int TProgram::getNumAtomicCounters() const                            {}
const TObjectReflection& TProgram::getAtomicCounter(int index) const  {}
void TProgram::dumpReflection() {}

//
// I/O mapping implementation.
//
bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper)
{}

} // end namespace glslang