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

//
// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
// Copyright (C) 2012-2013 LunarG, Inc.
// Copyright (C) 2017, 2022-2024 Arm Limited.
// Copyright (C) 2015-2020 Google, Inc.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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.
//

//
// Help manage multiple profiles, versions, extensions etc.
//
// These don't return error codes, as the presumption is parsing will
// always continue as if the tested feature were enabled, and thus there
// is no error recovery needed.
//

//
// HOW TO add a feature enabled by an extension.
//
// To add a new hypothetical "Feature F" to the front end, where an extension
// "XXX_extension_X" can be used to enable the feature, do the following.
//
// OVERVIEW: Specific features are what are error-checked for, not
//    extensions:  A specific Feature F might be enabled by an extension, or a
//    particular version in a particular profile, or a stage, or combinations, etc.
//
//    The basic mechanism is to use the following to "declare" all the things that
//    enable/disable Feature F, in a code path that implements Feature F:
//
//        requireProfile()
//        profileRequires()
//        requireStage()
//        checkDeprecated()
//        requireNotRemoved()
//        requireExtensions()
//        extensionRequires()
//
//    Typically, only the first two calls are needed.  They go into a code path that
//    implements Feature F, and will log the proper error/warning messages.  Parsing
//    will then always continue as if the tested feature was enabled.
//
//    There is typically no if-testing or conditional parsing, just insertion of the calls above.
//    However, if symbols specific to the extension are added (step 5), they will
//    only be added under tests that the minimum version and profile are present.
//
// 1) Add a symbol name for the extension string at the bottom of Versions.h:
//
//     const char* const XXX_extension_X = "XXX_extension_X";
//
// 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(),
//    the first function below and optionally a entry to extensionData for additional
//    error checks:
//
//     extensionBehavior[XXX_extension_X] = EBhDisable;
//     (Optional) exts[] = {XXX_extension_X, EShTargetSpv_1_4}
//
// 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble():
//
//           "#define XXX_extension_X 1\n"
//
//    The new-line is important, as that ends preprocess tokens.
//
// 4) Insert a profile check in the feature's path (unless all profiles support the feature,
//    for some version level).  That is, call requireProfile() to constrain the profiles, e.g.:
//
//         // ... in a path specific to Feature F...
//         requireProfile(loc,
//                        ECoreProfile | ECompatibilityProfile,
//                        "Feature F");
//
// 5) For each profile that supports the feature, insert version/extension checks:
//
//    The mostly likely scenario is that Feature F can only be used with a
//    particular profile if XXX_extension_X is present or the version is
//    high enough that the core specification already incorporated it.
//
//        // following the requireProfile() call...
//        profileRequires(loc,
//                        ECoreProfile | ECompatibilityProfile,
//                        420,             // 0 if no version incorporated the feature into the core spec.
//                        XXX_extension_X, // can be a list of extensions that all add the feature
//                        "Feature F Description");
//
//    This allows the feature if either A) one of the extensions is enabled or
//    B) the version is high enough.  If no version yet incorporates the feature
//    into core, pass in 0.
//
//    This can be called multiple times, if different profiles support the
//    feature starting at different version numbers or with different
//    extensions.
//
//    This must be called for each profile allowed by the initial call to requireProfile().
//
//    Profiles are all masks, which can be "or"-ed together.
//
//        ENoProfile
//        ECoreProfile
//        ECompatibilityProfile
//        EEsProfile
//
//    The ENoProfile profile is only for desktop, before profiles showed up in version 150;
//    All other #version with no profile default to either es or core, and so have profiles.
//
//    You can select all but a particular profile using ~.  The following basically means "desktop":
//
//        ~EEsProfile
//
// 6) If built-in symbols are added by the extension, add them in Initialize.cpp:  Their use
//    will be automatically error checked against the extensions enabled at that moment.
//    see the comment at the top of Initialize.cpp for where to put them.  Establish them at
//    the earliest release that supports the extension.  Then, tag them with the
//    set of extensions that both enable them and are necessary, given the version of the symbol
//    table. (There is a different symbol table for each version.)
//
// 7) If the extension has additional requirements like minimum SPIR-V version required, add them
//    to extensionRequires()

#include "parseVersions.h"
#include "localintermediate.h"

namespace glslang {

//
// Initialize all extensions, almost always to 'disable', as once their features
// are incorporated into a core version, their features are supported through allowing that
// core version, not through a pseudo-enablement of the extension.
//
void TParseVersions::initializeExtensionBehavior()
{}

// Get code that is not part of a shared symbol table, is specific to this shader,
// or needed by the preprocessor (which does not use a shared symbol table).
void TParseVersions::getPreamble(std::string& preamble)
{}

//
// Map from stage enum to externally readable text name.
//
const char* StageName(EShLanguage stage)
{}

//
// When to use requireStage()
//
//     If only some stages support a feature.
//
// Operation: If the current stage is not present, give an error message.
//
void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguageMask languageMask, const char* featureDesc)
{}

// If only one stage supports a feature, this can be called.  But, all supporting stages
// must be specified with one call.
void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, const char* featureDesc)
{}

//
// When to use requireProfile():
//
//     Use if only some profiles support a feature.  However, if within a profile the feature
//     is version or extension specific, follow this call with calls to profileRequires().
//
// Operation:  If the current profile is not one of the profileMask,
// give an error message.
//
void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc)
{}

//
// When to use profileRequires():
//
//     If a set of profiles have the same requirements for what version or extensions
//     are needed to support a feature.
//
//     It must be called for each profile that needs protection.  Use requireProfile() first
//     to reduce that set of profiles.
//
// Operation: Will issue warnings/errors based on the current profile, version, and extension
// behaviors.  It only checks extensions when the current profile is one of the profileMask.
//
// A minVersion of 0 means no version of the profileMask support this in core,
// the extension must be present.
//

// entry point that takes multiple extensions
void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions,
    const char* const extensions[], const char* featureDesc)
{}

// entry point for the above that takes a single extension
void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension,
    const char* featureDesc)
{}

void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc)
{}

//
// Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether
// a future compatibility context is being use.
//
void TParseVersions::checkDeprecated(const TSourceLoc& loc, int profileMask, int depVersion, const char* featureDesc)
{}

//
// Within a set of profiles, see if a feature has now been removed and if so, give an error.
// The version argument is the first version no longer having the feature.
//
void TParseVersions::requireNotRemoved(const TSourceLoc& loc, int profileMask, int removedVersion, const char* featureDesc)
{}

// Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
// Warns appropriately if the requested behavior of an extension is "warn".
bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
{}

//
// Use when there are no profile/version to check, it's just an error if one of the
// extensions is not present.
//
void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[],
    const char* featureDesc)
{}

//
// Use by preprocessor when there are no profile/version to check, it's just an error if one of the
// extensions is not present.
//
void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[],
    const char* featureDesc)
{}

TExtensionBehavior TParseVersions::getExtensionBehavior(const char* extension)
{}

// Returns true if the given extension is set to enable, require, or warn.
bool TParseVersions::extensionTurnedOn(const char* const extension)
{}
// See if any of the extensions are set to enable, require, or warn.
bool TParseVersions::extensionsTurnedOn(int numExtensions, const char* const extensions[])
{}

//
// Change the current state of an extension's behavior.
//
void TParseVersions::updateExtensionBehavior(int line, const char* extension, const char* behaviorString)
{}

void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
{}

// Check if extension is used with correct shader stage.
void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * const extension)
{}

// Check if extension has additional requirements
void TParseVersions::extensionRequires(const TSourceLoc &loc, const char * const extension, const char *behaviorString)
{}

// Call for any operation needing full GLSL integer data-type support.
void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
{}

// Call for any operation needing GLSL double data-type support.
void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
{}

// Call for any operation needing GLSL float16 data-type support.
void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn)
{}

bool TParseVersions::float16Arithmetic()
{}

bool TParseVersions::int16Arithmetic()
{}

bool TParseVersions::int8Arithmetic()
{}

void TParseVersions::requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc)
{}

void TParseVersions::requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc)
{}

void TParseVersions::requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc)
{}

void TParseVersions::float16ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{}

// Call for any operation needing GLSL float32 data-type support.
void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op, bool builtIn)
{}

// Call for any operation needing GLSL float64 data-type support.
void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op, bool builtIn)
{}

// Call for any operation needing GLSL explicit int8 data-type support.
void TParseVersions::explicitInt8Check(const TSourceLoc& loc, const char* op, bool builtIn)
{}

// Call for any operation needing GLSL float16 opaque-type support
void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{}

// Call for any operation needing GLSL explicit int16 data-type support.
void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn)
{}

void TParseVersions::int16ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{}

void TParseVersions::int8ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{}

// Call for any operation needing GLSL explicit int32 data-type support.
void TParseVersions::explicitInt32Check(const TSourceLoc& loc, const char* op, bool builtIn)
{}

// Call for any operation needing GLSL 64-bit integer data-type support.
void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool builtIn)
{}

void TParseVersions::fcoopmatCheckNV(const TSourceLoc& loc, const char* op, bool builtIn)
{}

void TParseVersions::intcoopmatCheckNV(const TSourceLoc& loc, const char* op, bool builtIn)
{}

void TParseVersions::coopmatCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{}

// Call for any operation removed because SPIR-V is in use.
void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
{}

// Call for any operation removed because Vulkan SPIR-V is being generated.
void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op)
{}

// Call for any operation that requires Vulkan.
void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op)
{}

// Call for any operation that requires SPIR-V.
void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op)
{}
void TParseVersions::requireSpv(const TSourceLoc& loc, const char *op, unsigned int version)
{}

} // end namespace glslang