Vulkan: Update all components to Vulkan SDK 1.4.335.0

VulkanMemoryAllocator not updated as it's not versioned together with the SDK, and it
often requires more work.

SPIRV-Reflect: Fix reflection code and remove Godot's SC parsing patch.

Co-authored-by: Dario <dariosamo@gmail.com>
This commit is contained in:
Rémi Verschelde 2025-12-16 11:39:19 +01:00
parent 2487a297b2
commit d2ed1773fc
No known key found for this signature in database
GPG key ID: C3336907360768E1
156 changed files with 226241 additions and 110200 deletions

View file

@ -579,6 +579,11 @@ Comment: SPIRV-Cross
Copyright: 2015-2021, Arm Limited
License: Apache-2.0 or Expat
Files: thirdparty/spirv-headers/*
Comment: SPIRV-Headers
Copyright: 2015-2024, The Khronos Group Inc.
License: Expat
Files: thirdparty/spirv-reflect/*
Comment: SPIRV-Reflect
Copyright: 2017-2022, Google Inc.
@ -613,14 +618,14 @@ License: BSD-3-clause
Files: thirdparty/volk/*
Comment: volk
Copyright: 2018-2024, Arseny Kapoulkine
Copyright: 2018-2025, Arseny Kapoulkine
License: Expat
Files: thirdparty/vulkan/*
Comment: Vulkan Headers
Copyright: 2014-2024, The Khronos Group Inc.
2014-2024, Valve Corporation
2014-2024, LunarG, Inc.
Copyright: 2015-2025, The Khronos Group Inc.
2015-2025, Valve Corporation
2015-2025, LunarG, Inc.
License: Apache-2.0
Files: thirdparty/vulkan/vk_mem_alloc.h

View file

@ -19,6 +19,7 @@ thirdparty_sources = [
"spirv_reflect.cpp",
"spirv_glsl.cpp",
"spirv_cross_parsed_ir.cpp",
"spirv_cross_util.cpp",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]

View file

@ -52,7 +52,6 @@ if env["builtin_glslang"]:
"SPIRV/Logger.cpp",
"SPIRV/SpvBuilder.cpp",
"SPIRV/SpvPostProcess.cpp",
"SPIRV/SPVRemapper.cpp",
"SPIRV/SpvTools.cpp",
]

View file

@ -492,22 +492,31 @@ Error RenderingShaderContainer::reflect_spirv(const String &p_shader_name, Span<
SpvReflectSpecializationConstant *spc = spec_constants[j];
sconst.set_spv_reflect(stage, spc);
if (spc->default_value_size != 4) {
ERR_FAIL_V_MSG(FAILED, vformat("Reflection of SPIR-V shader stage '%s' failed because the specialization constant #%d's default value is not 4 bytes long (%d) and is currently not supported.", RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage], spc->constant_id, spc->default_value_size));
}
sconst.constant_id = spc->constant_id;
sconst.int_value = 0; // Clear previous value JIC.
switch (spc->constant_type) {
case SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL: {
switch (spc->type_description->op) {
case SpvOpTypeBool:
sconst.type = RDC::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
sconst.bool_value = spc->default_value.int_bool_value != 0;
} break;
case SPV_REFLECT_SPECIALIZATION_CONSTANT_INT: {
sconst.bool_value = *(uint32_t *)(spc->default_value);
break;
case SpvOpTypeInt:
sconst.type = RDC::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
sconst.int_value = spc->default_value.int_bool_value;
} break;
case SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT: {
sconst.int_value = *(uint32_t *)(spc->default_value);
break;
case SpvOpTypeFloat:
sconst.type = RDC::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT;
sconst.float_value = spc->default_value.float_value;
} break;
sconst.float_value = *(float *)(spc->default_value);
break;
default:
ERR_FAIL_V_MSG(FAILED, vformat("Reflection of SPIR-V shader stage '%s' failed because the specialization constant #%d does not use a known operation (%d).", RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage], spc->constant_id, spc->type_description->op));
break;
}
sconst.stages.set_flag(stage_flag);
for (uint32_t k = 0; k < reflection.specialization_constants.size(); k++) {

31
thirdparty/README.md vendored
View file

@ -413,7 +413,7 @@ Patches:
## glslang
- Upstream: https://github.com/KhronosGroup/glslang
- Version: vulkan-sdk-1.3.283.0 (e8dd0b6903b34f1879520b444634c75ea2deedf5, 2024)
- Version: vulkan-sdk-1.4.335.0 (b5782e52ee2f7b3e40bb9c80d15b47016e008bc9, 2025)
- License: glslang
Version should be kept in sync with the one of the used Vulkan SDK (see `vulkan`
@ -424,6 +424,8 @@ Files extracted from upstream source:
- `glslang/` folder (except the `glslang/HLSL` and `glslang/ExtensionHeaders`
subfolders), `SPIRV/` folder
* Remove C interface code: `CInterface/` folders, files matching `"*_c[_\.]*"`
* Remove `glslang/stub.cpp`
* Remove `SPIRV/spirv.hpp11` (should use copy from `thirdparty/spirv-headers`)
- Run `cmake . && make` and copy generated `include/glslang/build_info.h`
to `glslang/build_info.h`
- `LICENSE.txt`
@ -432,7 +434,6 @@ Files extracted from upstream source:
Patches:
- `0001-apple-disable-absolute-paths.patch` ([GH-92010](https://github.com/godotengine/godot/pull/92010))
- `0002-gcc15-include-fix.patch` ([GH-102022](https://github.com/godotengine/godot/pull/102022))
## graphite
@ -998,12 +999,12 @@ Patches:
## spirv-cross
- Upstream: https://github.com/KhronosGroup/SPIRV-Cross
- Version: git (d7440cbc6c50332600fdf21c45e6a5df0b07e54c, 2025)
- Version: git (fb0c1a307cca4b4a9d891837bf4c44d17fe2d324, 2025)
- License: Apache 2.0
Files extracted from upstream source:
- All `.cpp`, `.hpp` and `.h` files, minus `main.cpp`, `spirv_cross_c.*`, `spirv_hlsl.*`, `spirv_cpp.*`
- All `.cpp`, `.hpp` and `.h` files, minus `main.cpp`, `spirv.h*`, `spirv_cross_c.*`, `spirv_hlsl.*`, `spirv_cpp.*`
- `include/` folder
- `LICENSE` and `LICENSES/` folder, minus `CC-BY-4.0.txt`
@ -1014,17 +1015,19 @@ to generate Metal source from Vulkan SPIR-V.
## spirv-headers
- Upstream: https://github.com/KhronosGroup/SPIRV-Headers
- Version: vulkan-sdk-1.4.328.1 (01e0577914a75a2569c846778c2f93aa8e6feddd, 2025)
- Version: vulkan-sdk-1.4.335.0 (b824a462d4256d720bebb40e78b9eb8f78bbb305, 2025)
- License: MIT
Files extracted from upstream source:
- `include/spirv/unified1` folder with only `spirv.h` and `spirv.hpp`
- `LICENSE`
- `include/spirv/unified1/spirv.{h,hpp,hpp11}` with the same folder structure
- `LICENSE` (edited to keep only relevant license)
## spirv-reflect
- Upstream: https://github.com/KhronosGroup/SPIRV-Reflect
- Version: vulkan-sdk-1.3.283.0 (ee5b57fba6a986381f998567761bbc064428e645, 2024)
- Version: vulkan-sdk-1.4.335.0 (ef913b3ab3da1becca3cf46b15a10667c67bebe5, 2025)
- License: Apache 2.0
Version should be kept in sync with the one of the used Vulkan SDK (see `vulkan`
@ -1033,14 +1036,12 @@ section).
Files extracted from upstream source:
- `spirv_reflect.h`, `spirv_reflect.c`
- `include/` folder
- `LICENSE`
Patches:
- `0001-specialization-constants.patch` ([GH-50325](https://github.com/godotengine/godot/pull/50325))
- `0002-zero-size-for-sc-sized-arrays.patch` ([GH-94985](https://github.com/godotengine/godot/pull/94985))
- `0003-spirv-headers.patch` ([GH-111452](https://github.com/godotengine/godot/pull/111452))
- `0001-zero-size-for-sc-sized-arrays.patch` ([GH-94985](https://github.com/godotengine/godot/pull/94985))
- `0002-spirv-headers.patch` ([GH-111452](https://github.com/godotengine/godot/pull/111452))
## swappy-frame-pacing
@ -1125,7 +1126,7 @@ Patches:
## volk
- Upstream: https://github.com/zeux/volk
- Version: vulkan-sdk-1.3.283.0 (3a8068a57417940cf2bf9d837a7bb60d015ca2f1, 2024)
- Version: vulkan-sdk-1.4.335.0 (4f3bcee79618a9abe79f4c717c50379197c77512, 2025)
- License: MIT
Version should be kept in sync with the one of the used Vulkan SDK (see `vulkan`
@ -1140,7 +1141,7 @@ Files extracted from upstream source:
## vulkan
- Upstream: https://github.com/KhronosGroup/Vulkan-Headers
- Version: vulkan-sdk-1.3.283.0 (eaa319dade959cb61ed2229c8ea42e307cc8f8b3, 2024)
- Version: vulkan-sdk-1.4.335.0 (2fa203425eb4af9dfc6b03f97ef72b0b5bcb8350, 2025)
- License: Apache 2.0
Unless there is a specific reason to package a more recent version, please stick
@ -1149,6 +1150,8 @@ to tagged SDK releases. All Vulkan libraries and headers should be kept in sync
- Update Vulkan SDK components to the matching tag (see "vulkan")
- Update volk (see "volk")
- Update glslang (see "glslang")
- Update spirv-headers (see "spriv-headers")
- Update spirv-cross (see "spirv-cross")
- Update spirv-reflect (see "spirv-reflect")
Files extracted from upstream source:

View file

@ -13,9 +13,6 @@ Other parts, outside of glslang proper, include:
- update_glslang_sources.py, which is not part of the project proper and does
not need to be used.
- the SPIR-V "remapper", which is optional, but has the same license as
glslang proper
- Google tests and SPIR-V tools, and anything in the external subdirectory
are external and optional; see them for their respective licenses.

View file

@ -1,5 +1,5 @@
/*
** Copyright (c) 2022 ARM Limited
** Copyright (c) 2022, 2025 ARM Limited
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
@ -28,8 +28,10 @@
#define GLSLextARM_H
static const int GLSLextARMVersion = 100;
static const int GLSLextARMRevision = 1;
static const int GLSLextARMRevision = 2;
static const char * const E_SPV_ARM_core_builtins = "SPV_ARM_core_builtins";
static const char* const E_SPV_ARM_core_builtins = "SPV_ARM_core_builtins";
static const char* const E_SPV_ARM_cooperative_matrix_layouts = "SPV_ARM_cooperative_matrix_layouts";
static const char* const E_SPV_ARM_tensors = "SPV_ARM_tensors";
#endif // #ifndef GLSLextARM_H

View file

@ -41,5 +41,8 @@ static const char* const E_SPV_EXT_shader_atomic_float_min_max = "SPV_EXT_shader
static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64";
static const char* const E_SPV_EXT_shader_tile_image = "SPV_EXT_shader_tile_image";
static const char* const E_SPV_EXT_mesh_shader = "SPV_EXT_mesh_shader";
static const char* const E_SPV_EXT_float8 = "SPV_EXT_float8";
static const char* const E_SPV_EXT_shader_64bit_indexing = "SPV_EXT_shader_64bit_indexing";
static const char* const E_SPV_EXT_shader_invocation_reorder = "SPV_EXT_shader_invocation_reorder";
#endif // #ifndef GLSLextEXT_H

View file

@ -61,5 +61,10 @@ static const char* const E_SPV_KHR_cooperative_matrix = "SPV_KHR_coope
static const char* const E_SPV_KHR_maximal_reconvergence = "SPV_KHR_maximal_reconvergence";
static const char* const E_SPV_KHR_subgroup_rotate = "SPV_KHR_subgroup_rotate";
static const char* const E_SPV_KHR_expect_assume = "SPV_KHR_expect_assume";
static const char* const E_SPV_EXT_replicated_composites = "SPV_EXT_replicated_composites";
static const char* const E_SPV_KHR_relaxed_extended_instruction = "SPV_KHR_relaxed_extended_instruction";
static const char* const E_SPV_KHR_integer_dot_product = "SPV_KHR_integer_dot_product";
static const char* const E_SPV_NV_cooperative_vector = "SPV_NV_cooperative_vector";
static const char* const E_SPV_KHR_bfloat16 = "SPV_KHR_bfloat16";
#endif // #ifndef GLSLextKHR_H

View file

@ -27,10 +27,10 @@
#ifndef GLSLextNV_H
#define GLSLextNV_H
enum BuiltIn;
enum Decoration;
enum Op;
enum Capability;
enum class BuiltIn : unsigned;
enum class Decoration : unsigned;
enum class Op : unsigned;
enum class Capability : unsigned;
static const int GLSLextNVVersion = 100;
static const int GLSLextNVRevision = 11;
@ -90,4 +90,15 @@ const char* const E_SPV_NV_displacement_micromap = "SPV_NV_displacement_micromap
//SPV_NV_shader_atomic_fp16_vector
const char* const E_SPV_NV_shader_atomic_fp16_vector = "SPV_NV_shader_atomic_fp16_vector";
//SPV_NV_tensor_addressing
const char* const E_SPV_NV_tensor_addressing = "SPV_NV_tensor_addressing";
//SPV_NV_cooperative_matrix2
const char* const E_SPV_NV_cooperative_matrix2 = "SPV_NV_cooperative_matrix2";
//SPV_NV_cluster_acceleration_structure
const char* const E_SPV_NV_cluster_acceleration_structure = "SPV_NV_cluster_acceleration_structure";
//SPV_NV_linear_swept_spheres
const char* const E_SPV_NV_linear_swept_spheres = "SPV_NV_linear_swept_spheres";
#endif // #ifndef GLSLextNV_H

View file

@ -27,10 +27,10 @@
#ifndef GLSLextQCOM_H
#define GLSLextQCOM_H
enum BuiltIn;
enum Decoration;
enum Op;
enum Capability;
enum class BuiltIn : unsigned;
enum class Decoration : unsigned;
enum class Op : unsigned;
enum class Capability : unsigned;
static const int GLSLextQCOMVersion = 100;
static const int GLSLextQCOMRevision = 1;
@ -39,5 +39,10 @@ static const int GLSLextQCOMRevision = 1;
const char* const E_SPV_QCOM_image_processing = "SPV_QCOM_image_processing";
//SPV_QCOM_image_processing2
const char* const E_SPV_QCOM_image_processing2 = "SPV_QCOM_image_processing2";
//SPV_QCOM_cooperative_matrix_conversion
const char* const E_SPV_QCOM_cooperative_matrix_conversion = "SPV_QCOM_cooperative_matrix_conversion";
//SPV_QCOM_tile_shading
const char* const E_SPV_QCOM_tile_shading = "SPV_QCOM_tile_shading";
#endif // #ifndef GLSLextQCOM_H

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,7 @@
#include <vector>
#include "Logger.h"
#include "glslang/Include/visibility.h"
namespace glslang {
class TIntermediate;
@ -53,15 +54,16 @@ struct SpvOptions {
bool emitNonSemanticShaderDebugInfo {false};
bool emitNonSemanticShaderDebugSource{ false };
bool compileOnly{false};
bool optimizerAllowExpandedIDBound{false};
};
void GetSpirvVersion(std::string&);
int GetSpirvGeneratorVersion();
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
SpvOptions* options = nullptr);
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
bool OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
bool OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
GLSLANG_EXPORT void GetSpirvVersion(std::string&);
GLSLANG_EXPORT int GetSpirvGeneratorVersion();
GLSLANG_EXPORT void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
SpvOptions* options = nullptr);
GLSLANG_EXPORT void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
GLSLANG_EXPORT bool OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
GLSLANG_EXPORT bool OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
}

View file

@ -85,7 +85,7 @@ public:
Id mergeId = mergeInst->getIdOperand(0);
mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock();
delayed_.insert(mergeBlock);
if (mergeInst->getOpCode() == spv::OpLoopMerge) {
if (mergeInst->getOpCode() == spv::Op::OpLoopMerge) {
Id continueId = mergeInst->getIdOperand(1);
continueBlock =
block->getParent().getParent().getInstruction(continueId)->getBlock();

View file

@ -37,12 +37,13 @@
#include <string>
#include <vector>
#include "glslang/Include/visibility.h"
namespace spv {
// A class for holding all SPIR-V build status messages, including
// missing/TBD functionalities, warnings, and errors.
class SpvBuildLogger {
class GLSLANG_EXPORT SpvBuildLogger {
public:
SpvBuildLogger() {}

File diff suppressed because it is too large Load diff

View file

@ -1,284 +0,0 @@
//
// Copyright (C) 2015 LunarG, 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 SPIRVREMAPPER_H
#define SPIRVREMAPPER_H
#include <string>
#include <vector>
#include <cstdlib>
#include <exception>
namespace spv {
class spirvbin_base_t
{
public:
enum Options {
NONE = 0,
STRIP = (1<<0),
MAP_TYPES = (1<<1),
MAP_NAMES = (1<<2),
MAP_FUNCS = (1<<3),
DCE_FUNCS = (1<<4),
DCE_VARS = (1<<5),
DCE_TYPES = (1<<6),
OPT_LOADSTORE = (1<<7),
OPT_FWD_LS = (1<<8), // EXPERIMENTAL: PRODUCES INVALID SCHEMA-0 SPIRV
MAP_ALL = (MAP_TYPES | MAP_NAMES | MAP_FUNCS),
DCE_ALL = (DCE_FUNCS | DCE_VARS | DCE_TYPES),
OPT_ALL = (OPT_LOADSTORE),
ALL_BUT_STRIP = (MAP_ALL | DCE_ALL | OPT_ALL),
DO_EVERYTHING = (STRIP | ALL_BUT_STRIP)
};
};
} // namespace SPV
#include <functional>
#include <cstdint>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <set>
#include <cassert>
#include "spirv.hpp"
namespace spv {
const Id NoResult = 0;
// class to hold SPIR-V binary data for remapping, DCE, and debug stripping
class spirvbin_t : public spirvbin_base_t
{
public:
spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose), errorLatch(false)
{ }
virtual ~spirvbin_t() { }
// remap on an existing binary in memory
void remap(std::vector<std::uint32_t>& spv, const std::vector<std::string>& whiteListStrings,
std::uint32_t opts = DO_EVERYTHING);
// remap on an existing binary in memory - legacy interface without white list
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
// Type for error/log handler functions
typedef std::function<void(const std::string&)> errorfn_t;
typedef std::function<void(const std::string&)> logfn_t;
// Register error/log handling functions (can be lambda fn / functor / etc)
static void registerErrorHandler(errorfn_t handler) { errorHandler = handler; }
static void registerLogHandler(logfn_t handler) { logHandler = handler; }
protected:
// This can be overridden to provide other message behavior if needed
virtual void msg(int minVerbosity, int indent, const std::string& txt) const;
private:
// Local to global, or global to local ID map
typedef std::unordered_map<spv::Id, spv::Id> idmap_t;
typedef std::unordered_set<spv::Id> idset_t;
typedef std::unordered_map<spv::Id, int> blockmap_t;
void remap(std::uint32_t opts = DO_EVERYTHING);
// Map of names to IDs
typedef std::unordered_map<std::string, spv::Id> namemap_t;
typedef std::uint32_t spirword_t;
typedef std::pair<unsigned, unsigned> range_t;
typedef std::function<void(spv::Id&)> idfn_t;
typedef std::function<bool(spv::Op, unsigned start)> instfn_t;
// Special Values for ID map:
static const spv::Id unmapped; // unchanged from default value
static const spv::Id unused; // unused ID
static const int header_size; // SPIR header = 5 words
class id_iterator_t;
// For mapping type entries between different shaders
typedef std::vector<spirword_t> typeentry_t;
typedef std::map<spv::Id, typeentry_t> globaltypes_t;
// A set that preserves position order, and a reverse map
typedef std::set<int> posmap_t;
typedef std::unordered_map<spv::Id, int> posmap_rev_t;
// Maps and ID to the size of its base type, if known.
typedef std::unordered_map<spv::Id, unsigned> typesize_map_t;
// handle error
void error(const std::string& txt) const { errorLatch = true; errorHandler(txt); }
bool isConstOp(spv::Op opCode) const;
bool isTypeOp(spv::Op opCode) const;
bool isStripOp(spv::Op opCode) const;
bool isFlowCtrl(spv::Op opCode) const;
range_t literalRange(spv::Op opCode) const;
range_t typeRange(spv::Op opCode) const;
range_t constRange(spv::Op opCode) const;
unsigned typeSizeInWords(spv::Id id) const;
unsigned idTypeSizeInWords(spv::Id id) const;
bool isStripOp(spv::Op opCode, unsigned start) const;
spv::Id& asId(unsigned word) { return spv[word]; }
const spv::Id& asId(unsigned word) const { return spv[word]; }
spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); }
std::uint32_t asOpCodeHash(unsigned word);
spv::Decoration asDecoration(unsigned word) const { return spv::Decoration(spv[word]); }
unsigned asWordCount(unsigned word) const { return opWordCount(spv[word]); }
spv::Id asTypeConstId(unsigned word) const { return asId(word + (isTypeOp(asOpCode(word)) ? 1 : 2)); }
unsigned idPos(spv::Id id) const;
static unsigned opWordCount(spirword_t data) { return data >> spv::WordCountShift; }
static spv::Op opOpCode(spirword_t data) { return spv::Op(data & spv::OpCodeMask); }
// Header access & set methods
spirword_t magic() const { return spv[0]; } // return magic number
spirword_t bound() const { return spv[3]; } // return Id bound from header
spirword_t bound(spirword_t b) { return spv[3] = b; }
spirword_t genmagic() const { return spv[2]; } // generator magic
spirword_t genmagic(spirword_t m) { return spv[2] = m; }
spirword_t schemaNum() const { return spv[4]; } // schema number from header
// Mapping fns: get
spv::Id localId(spv::Id id) const { return idMapL[id]; }
// Mapping fns: set
inline spv::Id localId(spv::Id id, spv::Id newId);
void countIds(spv::Id id);
// Return next unused new local ID.
// NOTE: boost::dynamic_bitset would be more efficient due to find_next(),
// which std::vector<bool> doens't have.
inline spv::Id nextUnusedId(spv::Id id);
void buildLocalMaps();
std::string literalString(unsigned word) const; // Return literal as a std::string
int literalStringWords(const std::string& str) const { return (int(str.size())+4)/4; }
bool isNewIdMapped(spv::Id newId) const { return isMapped(newId); }
bool isOldIdUnmapped(spv::Id oldId) const { return localId(oldId) == unmapped; }
bool isOldIdUnused(spv::Id oldId) const { return localId(oldId) == unused; }
bool isOldIdMapped(spv::Id oldId) const { return !isOldIdUnused(oldId) && !isOldIdUnmapped(oldId); }
bool isFunction(spv::Id oldId) const { return fnPos.find(oldId) != fnPos.end(); }
// bool matchType(const globaltypes_t& globalTypes, spv::Id lt, spv::Id gt) const;
// spv::Id findType(const globaltypes_t& globalTypes, spv::Id lt) const;
std::uint32_t hashType(unsigned typeStart) const;
spirvbin_t& process(instfn_t, idfn_t, unsigned begin = 0, unsigned end = 0);
int processInstruction(unsigned word, instfn_t, idfn_t);
void validate() const;
void mapTypeConst();
void mapFnBodies();
void optLoadStore();
void dceFuncs();
void dceVars();
void dceTypes();
void mapNames();
void foldIds(); // fold IDs to smallest space
void forwardLoadStores(); // load store forwarding (EXPERIMENTAL)
void offsetIds(); // create relative offset IDs
void applyMap(); // remap per local name map
void mapRemainder(); // map any IDs we haven't touched yet
void stripDebug(); // strip all debug info
void stripDeadRefs(); // strips debug info for now-dead references after DCE
void strip(); // remove debug symbols
std::vector<spirword_t> spv; // SPIR words
std::vector<std::string> stripWhiteList;
namemap_t nameMap; // ID names from OpName
// Since we want to also do binary ops, we can't use std::vector<bool>. we could use
// boost::dynamic_bitset, but we're trying to avoid a boost dependency.
typedef std::uint64_t bits_t;
std::vector<bits_t> mapped; // which new IDs have been mapped
static const int mBits = sizeof(bits_t) * 4;
bool isMapped(spv::Id id) const { return id < maxMappedId() && ((mapped[id/mBits] & (1LL<<(id%mBits))) != 0); }
void setMapped(spv::Id id) { resizeMapped(id); mapped[id/mBits] |= (1LL<<(id%mBits)); }
void resizeMapped(spv::Id id) { if (id >= maxMappedId()) mapped.resize(id/mBits+1, 0); }
size_t maxMappedId() const { return mapped.size() * mBits; }
// Add a strip range for a given instruction starting at 'start'
// Note: avoiding brace initializers to please older versions os MSVC.
void stripInst(unsigned start) { stripRange.push_back(range_t(start, start + asWordCount(start))); }
// Function start and end. use unordered_map because we'll have
// many fewer functions than IDs.
std::unordered_map<spv::Id, range_t> fnPos;
// Which functions are called, anywhere in the module, with a call count
std::unordered_map<spv::Id, int> fnCalls;
posmap_t typeConstPos; // word positions that define types & consts (ordered)
posmap_rev_t idPosR; // reverse map from IDs to positions
typesize_map_t idTypeSizeMap; // maps each ID to its type size, if known.
std::vector<spv::Id> idMapL; // ID {M}ap from {L}ocal to {G}lobal IDs
spv::Id entryPoint; // module entry point
spv::Id largestNewId; // biggest new ID we have mapped anything to
// Sections of the binary to strip, given as [begin,end)
std::vector<range_t> stripRange;
// processing options:
std::uint32_t options;
int verbose; // verbosity level
// Error latch: this is set if the error handler is ever executed. It would be better to
// use a try/catch block and throw, but that's not desired for certain environments, so
// this is the alternative.
mutable bool errorLatch;
static errorfn_t errorHandler;
static logfn_t logHandler;
};
} // namespace SPV
#endif // SPIRVREMAPPER_H

File diff suppressed because it is too large Load diff

View file

@ -48,10 +48,14 @@
#define SpvBuilder_H
#include "Logger.h"
#include "spirv.hpp"
#define SPV_ENABLE_UTILITY_CODE
#include "spirv.hpp11"
#include "spvIR.h"
#include "spvUtil.h"
namespace spv {
#include "GLSL.ext.KHR.h"
#include "GLSL.ext.EXT.h"
#include "NonSemanticShaderDebugInfo100.h"
}
@ -63,6 +67,7 @@ namespace spv {
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <map>
namespace spv {
@ -74,8 +79,17 @@ typedef enum {
Spv_1_3 = (1 << 16) | (3 << 8),
Spv_1_4 = (1 << 16) | (4 << 8),
Spv_1_5 = (1 << 16) | (5 << 8),
Spv_1_6 = (1 << 16) | (6 << 8),
} SpvVersion;
struct StructMemberDebugInfo {
std::string name {};
int line {0};
int column {0};
// Set if the caller knows a better debug type than what is associated with the functional SPIR-V type.
spv::Id debugTypeOverride {0};
};
class Builder {
public:
Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
@ -96,7 +110,7 @@ public:
if (sItr != stringIds.end())
return sItr->second;
spv::Id strId = getUniqueId();
Instruction* fileString = new Instruction(strId, NoType, OpString);
Instruction* fileString = new Instruction(strId, NoType, Op::OpString);
const char* file_c_str = str.c_str();
fileString->addStringOperand(file_c_str);
strings.push_back(std::unique_ptr<Instruction>(fileString));
@ -108,7 +122,7 @@ public:
spv::Id getMainFileId() const { return mainFileId; }
// Initialize the main source file name
void setDebugSourceFile(const std::string& file)
void setDebugMainSourceFile(const std::string& file)
{
if (trackDebugInfo) {
dirtyLineTracker = true;
@ -124,7 +138,7 @@ public:
if (trackDebugInfo) {
dirtyLineTracker = true;
if (line != 0) {
// TODO: This is special handling of some AST nodes having (untracked) line 0.
// TODO: This is special handling of some AST nodes having (untracked) line 0.
// But they should have a valid line number.
currentLine = line;
if (filename) {
@ -192,6 +206,24 @@ public:
return id;
}
// Maps the given OpType Id to a Non-Semantic DebugType Id.
Id getDebugType(Id type) {
if (auto it = debugTypeIdLookup.find(type); it != debugTypeIdLookup.end()) {
return it->second;
}
return NoType;
}
// Maps the given OpFunction Id to a Non-Semantic DebugFunction Id.
Id getDebugFunction(Id func) {
if (auto it = debugFuncIdLookup.find(func); it != debugFuncIdLookup.end()) {
return it->second;
}
return NoResult;
}
// For creating new types (will return old type if the requested one was already made).
Id makeVoidType();
Id makeBoolType();
@ -202,28 +234,28 @@ public:
Id makeIntType(int width) { return makeIntegerType(width, true); }
Id makeUintType(int width) { return makeIntegerType(width, false); }
Id makeFloatType(int width);
Id makeStructType(const std::vector<Id>& members, const char* name, bool const compilerGenerated = true);
Id makeBFloat16Type();
Id makeFloatE5M2Type();
Id makeFloatE4M3Type();
Id makeStructType(const std::vector<Id>& members, const std::vector<spv::StructMemberDebugInfo>& memberDebugInfo,
const char* name, bool const compilerGenerated = true);
Id makeStructResultType(Id type0, Id type1);
Id makeVectorType(Id component, int size);
Id makeMatrixType(Id component, int cols, int rows);
Id makeArrayType(Id element, Id sizeId, int stride); // 0 stride means no stride decoration
Id makeRuntimeArray(Id element);
Id makeFunctionType(Id returnType, const std::vector<Id>& paramTypes);
Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);
Id makeSamplerType();
Id makeSampledImageType(Id imageType);
Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format, const char* debugNames);
Id makeSamplerType(const char* debugName);
Id makeSampledImageType(Id imageType, const char* debugName);
Id makeCooperativeMatrixTypeKHR(Id component, Id scope, Id rows, Id cols, Id use);
Id makeCooperativeMatrixTypeNV(Id component, Id scope, Id rows, Id cols);
Id makeCooperativeMatrixTypeWithSameShape(Id component, Id otherType);
Id makeCooperativeVectorTypeNV(Id componentType, Id components);
Id makeTensorTypeARM(Id elementType, Id rank);
Id makeGenericType(spv::Op opcode, std::vector<spv::IdImmediate>& operands);
// SPIR-V NonSemantic Shader DebugInfo Instructions
struct DebugTypeLoc {
std::string name {};
int line {0};
int column {0};
};
std::unordered_map<Id, DebugTypeLoc> debugTypeLocs;
Id makeDebugInfoNone();
Id makeBoolDebugType(int const size);
Id makeIntegerDebugType(int const width, bool const hasSign);
@ -232,10 +264,12 @@ public:
Id makeArrayDebugType(Id const baseType, Id const componentCount);
Id makeVectorDebugType(Id const baseType, int const componentCount);
Id makeMatrixDebugType(Id const vectorType, int const vectorCount, bool columnMajor = true);
Id makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTypeLoc);
Id makeCompositeDebugType(std::vector<Id> const& memberTypes, char const*const name,
NonSemanticShaderDebugInfo100DebugCompositeType const tag, bool const isOpaqueType = false);
Id makeMemberDebugType(Id const memberType, StructMemberDebugInfo const& debugTypeLoc);
Id makeCompositeDebugType(std::vector<Id> const& memberTypes, std::vector<StructMemberDebugInfo> const& memberDebugInfo,
char const* const name, NonSemanticShaderDebugInfo100DebugCompositeType const tag);
Id makeOpaqueDebugType(char const* const name);
Id makePointerDebugType(StorageClass storageClass, Id const baseType);
Id makeForwardPointerDebugType(StorageClass storageClass);
Id makeDebugSource(const Id fileName);
Id makeDebugCompilationUnit();
Id createDebugGlobalVariable(Id const type, char const*const name, Id const variable);
@ -245,11 +279,14 @@ public:
Id makeDebugValue(Id const debugLocalVariable, Id const value);
Id makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTypes);
Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId);
Id makeDebugLexicalBlock(uint32_t line);
Id makeDebugLexicalBlock(uint32_t line, uint32_t column);
std::string unmangleFunctionName(std::string const& name) const;
void setupDebugFunctionEntry(Function* function, const char* name, int line,
const std::vector<Id>& paramTypes,
const std::vector<char const*>& paramNames);
// Initialize non-semantic debug information for a function, including those of:
// - The function definition
// - The function parameters
void setupFunctionDebugInfo(Function* function, const char* name, const std::vector<Id>& paramTypes,
const std::vector<char const*>& paramNames);
// accelerationStructureNV type
Id makeAccelerationStructureType();
@ -257,6 +294,8 @@ public:
Id makeRayQueryType();
// hitObjectNV type
Id makeHitObjectNVType();
// hitObjectEXT type
Id makeHitObjectEXTType();
// For querying about types.
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
@ -264,9 +303,9 @@ public:
Op getOpCode(Id id) const { return module.getInstruction(id)->getOpCode(); }
Op getTypeClass(Id typeId) const { return getOpCode(typeId); }
Op getMostBasicTypeClass(Id typeId) const;
int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); }
int getNumTypeConstituents(Id typeId) const;
int getNumTypeComponents(Id typeId) const { return getNumTypeConstituents(typeId); }
unsigned int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); }
unsigned int getNumTypeConstituents(Id typeId) const;
unsigned int getNumTypeComponents(Id typeId) const { return getNumTypeConstituents(typeId); }
Id getScalarTypeId(Id typeId) const;
Id getContainedTypeId(Id typeId) const;
Id getContainedTypeId(Id typeId, int) const;
@ -275,54 +314,60 @@ public:
{ return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
Id getResultingAccessChainType() const;
Id getIdOperand(Id resultId, int idx) { return module.getInstruction(resultId)->getIdOperand(idx); }
Id getCooperativeVectorNumComponents(Id typeId) const { return module.getInstruction(typeId)->getIdOperand(1); }
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); }
bool isMatrix(Id resultId) const { return isMatrixType(getTypeId(resultId)); }
bool isCooperativeMatrix(Id resultId)const { return isCooperativeMatrixType(getTypeId(resultId)); }
bool isCooperativeVector(Id resultId)const { return isCooperativeVectorType(getTypeId(resultId)); }
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
bool isTensorView(Id resultId)const { return isTensorViewType(getTypeId(resultId)); }
bool isBoolType(Id typeId)
{ return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
{ return groupedTypes[enumCast(Op::OpTypeBool)].size() > 0 && typeId == groupedTypes[enumCast(Op::OpTypeBool)].back()->getResultId(); }
bool isIntType(Id typeId) const
{ return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
{ return getTypeClass(typeId) == Op::OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
bool isUintType(Id typeId) const
{ return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
bool isFloatType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat; }
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
{ return getTypeClass(typeId) == Op::OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
bool isFloatType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeFloat; }
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypePointer; }
bool isScalarType(Id typeId) const
{ return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt ||
getTypeClass(typeId) == OpTypeBool; }
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; }
{ return getTypeClass(typeId) == Op::OpTypeFloat || getTypeClass(typeId) == Op::OpTypeInt ||
getTypeClass(typeId) == Op::OpTypeBool; }
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeVector; }
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeMatrix; }
bool isStructType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeStruct; }
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeArray; }
bool isCooperativeMatrixType(Id typeId)const
{
return getTypeClass(typeId) == OpTypeCooperativeMatrixKHR || getTypeClass(typeId) == OpTypeCooperativeMatrixNV;
return getTypeClass(typeId) == Op::OpTypeCooperativeMatrixKHR || getTypeClass(typeId) == Op::OpTypeCooperativeMatrixNV;
}
bool isTensorViewType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeTensorViewNV; }
bool isCooperativeVectorType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeCooperativeVectorNV; }
bool isTensorTypeARM(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeTensorARM; }
bool isAggregateType(Id typeId) const
{ return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
bool isImageType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeImage; }
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeSampler; }
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeSampledImage; }
bool containsType(Id typeId, Op typeOp, unsigned int width) const;
bool containsPhysicalStorageBufferOrArray(Id typeId) const;
bool isConstantOpCode(Op opcode) const;
bool isSpecConstantOpCode(Op opcode) const;
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == Op::OpConstant; }
bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
unsigned int getConstantScalar(Id resultId) const
{ return module.getInstruction(resultId)->getImmediateOperand(0); }
StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
bool isVariableOpCode(Op opcode) const { return opcode == OpVariable; }
bool isVariableOpCode(Op opcode) const { return opcode == Op::OpVariable; }
bool isVariable(Id resultId) const { return isVariableOpCode(getOpCode(resultId)); }
bool isGlobalStorage(Id resultId) const { return getStorageClass(resultId) != StorageClassFunction; }
bool isGlobalStorage(Id resultId) const { return getStorageClass(resultId) != StorageClass::Function; }
bool isGlobalVariable(Id resultId) const { return isVariable(resultId) && isGlobalStorage(resultId); }
// See if a resultId is valid for use as an initializer.
bool isValidInitializer(Id resultId) const { return isConstant(resultId) || isGlobalVariable(resultId); }
@ -330,22 +375,22 @@ public:
int getScalarTypeWidth(Id typeId) const
{
Id scalarTypeId = getScalarTypeId(typeId);
assert(getTypeClass(scalarTypeId) == OpTypeInt || getTypeClass(scalarTypeId) == OpTypeFloat);
assert(getTypeClass(scalarTypeId) == Op::OpTypeInt || getTypeClass(scalarTypeId) == Op::OpTypeFloat);
return module.getInstruction(scalarTypeId)->getImmediateOperand(0);
}
int getTypeNumColumns(Id typeId) const
unsigned int getTypeNumColumns(Id typeId) const
{
assert(isMatrixType(typeId));
return getNumTypeConstituents(typeId);
}
int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); }
int getTypeNumRows(Id typeId) const
unsigned int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); }
unsigned int getTypeNumRows(Id typeId) const
{
assert(isMatrixType(typeId));
return getNumTypeComponents(getContainedTypeId(typeId));
}
int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }
unsigned int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }
Dim getTypeDimensionality(Id typeId) const
{
@ -367,6 +412,8 @@ public:
// For making new constants (will return old constant if the requested one was already made).
Id makeNullConstant(Id typeId);
Id makeBoolConstant(bool b, bool specConstant = false);
Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
Id makeInt8Constant(int i, bool specConstant = false)
{ return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
Id makeUint8Constant(unsigned u, bool specConstant = false)
@ -379,6 +426,14 @@ public:
{ return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
Id makeUintConstant(unsigned u, bool specConstant = false)
{ return makeIntConstant(makeUintType(32), u, specConstant); }
Id makeUintConstant(Scope u, bool specConstant = false)
{ return makeUintConstant((unsigned)u, specConstant); }
Id makeUintConstant(StorageClass u, bool specConstant = false)
{ return makeUintConstant((unsigned)u, specConstant); }
Id makeUintConstant(MemorySemanticsMask u, bool specConstant = false)
{ return makeUintConstant((unsigned)u, specConstant); }
Id makeUintConstant(SourceLanguage u, bool specConstant = false)
{ return makeUintConstant((unsigned)u, specConstant); }
Id makeInt64Constant(long long i, bool specConstant = false)
{ return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
Id makeUint64Constant(unsigned long long u, bool specConstant = false)
@ -386,6 +441,9 @@ public:
Id makeFloatConstant(float f, bool specConstant = false);
Id makeDoubleConstant(double d, bool specConstant = false);
Id makeFloat16Constant(float f16, bool specConstant = false);
Id makeBFloat16Constant(float bf16, bool specConstant = false);
Id makeFloatE5M2Constant(float fe5m2, bool specConstant = false);
Id makeFloatE4M3Constant(float fe4m3, bool specConstant = false);
Id makeFpConstant(Id type, double d, bool specConstant = false);
Id importNonSemanticShaderDebugInfoInstructions();
@ -416,8 +474,7 @@ public:
// Also reset current last DebugScope and current source line to unknown
void setBuildPoint(Block* bp) {
buildPoint = bp;
// TODO: Technically, change of build point should set line tracker dirty. But we'll have bad line info for
// branch instructions. Commenting this for now because at least this matches the old behavior.
dirtyLineTracker = true;
dirtyScopeTracker = true;
}
Block* getBuildPoint() const { return buildPoint; }
@ -426,6 +483,11 @@ public:
// Optionally, additional debug info instructions may also be prepended.
void addInstruction(std::unique_ptr<Instruction> inst);
// Append an instruction to the end of the current build point without prepending any debug instructions.
// This is useful for insertion of some debug info instructions themselves or some control flow instructions
// that are attached to its predecessor instruction.
void addInstructionNoDebugInfo(std::unique_ptr<Instruction> inst);
// Make the entry-point function. The returned pointer is only valid
// for the lifetime of this builder.
Function* makeEntryPoint(const char*);
@ -442,7 +504,7 @@ public:
void makeReturn(bool implicit, Id retVal = 0);
// Initialize state and generate instructions for new lexical scope
void enterLexicalBlock(uint32_t line);
void enterLexicalBlock(uint32_t line, uint32_t column);
// Set state and generate instructions to exit current lexical scope
void leaveLexicalBlock();
@ -461,6 +523,10 @@ public:
// such as OpEmitMeshTasksEXT
void makeStatementTerminator(spv::Op opcode, const std::vector<Id>& operands, const char* name);
// Create a global/local constant. Because OpConstant is automatically emitted by getting the constant
// ids, this function only handles debug info.
void createConstVariable(Id type, const char* name, Id constant, bool isGlobal);
// Create a global or function local or IO variable.
Id createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name = nullptr,
Id initializer = NoResult, bool const compilerGenerated = true);
@ -469,19 +535,19 @@ public:
Id createUndefined(Id type);
// Store into an Id and return the l-value
void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMask::MaskNone,
spv::Scope scope = spv::Scope::Max, unsigned int alignment = 0);
// Load from an Id and return it
Id createLoad(Id lValue, spv::Decoration precision,
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMask::MaskNone,
spv::Scope scope = spv::Scope::Max, unsigned int alignment = 0);
// Create an OpAccessChain instruction
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
// Create an OpArrayLength instruction
Id createArrayLength(Id base, unsigned int member);
Id createArrayLength(Id base, unsigned int member, unsigned int bits);
// Create an OpCooperativeMatrixLengthKHR instruction
Id createCooperativeMatrixLengthKHR(Id type);
@ -502,7 +568,7 @@ public:
void createNoResultOp(Op, const std::vector<Id>& operands);
void createNoResultOp(Op, const std::vector<IdImmediate>& operands);
void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
void createMemoryBarrier(Scope executionScope, MemorySemanticsMask memorySemantics);
Id createUnaryOp(Op, Id typeId, Id operand);
Id createBinOp(Op, Id typeId, Id operand1, Id operand2);
Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);
@ -573,6 +639,7 @@ public:
Id coarse;
bool nonprivate;
bool volatil;
bool nontemporal;
};
// Select the correct texture operation based on all inputs, and emit the correct instruction
@ -600,10 +667,15 @@ public:
// matrix constructor
Id createMatrixConstructor(Decoration precision, const std::vector<Id>& sources, Id constructee);
// coopmat conversion
Id createCooperativeMatrixConversion(Id typeId, Id source);
Id createCooperativeMatrixReduce(Op opcode, Id typeId, Id source, unsigned int mask, Id func);
Id createCooperativeMatrixPerElementOp(Id typeId, const std::vector<Id>& operands);
// Helper to use for building nested control flow with if-then-else.
class If {
public:
If(Id condition, unsigned int ctrl, Builder& builder);
If(Id condition, SelectionControlMask ctrl, Builder& builder);
~If() {}
void makeBeginElse();
@ -615,7 +687,7 @@ public:
Builder& builder;
Id condition;
unsigned int control;
SelectionControlMask control;
Function* function;
Block* headerBlock;
Block* thenBlock;
@ -635,11 +707,11 @@ public:
// Returns the right set of basic blocks to start each code segment with, so that the caller's
// recursion stack can hold the memory for it.
//
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
void makeSwitch(Id condition, SelectionControlMask control, int numSegments, const std::vector<int>& caseValues,
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB);
// Add a branch to the innermost switch's merge block.
void addSwitchBreak();
void addSwitchBreak(bool implicit);
// Move to the next code segment, passing in the return argument in makeSwitch()
void nextSwitchSegment(std::vector<Block*>& segmentBB, int segment);
@ -736,6 +808,7 @@ public:
unsigned shadercallcoherent : 1;
unsigned nonprivate : 1;
unsigned volatil : 1;
unsigned nontemporal : 1;
unsigned isImage : 1;
unsigned nonUniform : 1;
@ -748,6 +821,7 @@ public:
shadercallcoherent = 0;
nonprivate = 0;
volatil = 0;
nontemporal = 0;
isImage = 0;
nonUniform = 0;
}
@ -761,6 +835,7 @@ public:
shadercallcoherent |= other.shadercallcoherent;
nonprivate |= other.nonprivate;
volatil |= other.volatil;
nontemporal = other.nontemporal;
isImage |= other.isImage;
nonUniform |= other.nonUniform;
return *this;
@ -823,12 +898,12 @@ public:
// use accessChain and swizzle to store value
void accessChainStore(Id rvalue, Decoration nonUniform,
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMask::MaskNone,
spv::Scope scope = spv::Scope::Max, unsigned int alignment = 0);
// use accessChain and swizzle to load an r-value
Id accessChainLoad(Decoration precision, Decoration l_nonUniform, Decoration r_nonUniform, Id ResultType,
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax,
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMask::MaskNone, spv::Scope scope = spv::Scope::Max,
unsigned int alignment = 0);
// Return whether or not the access chain can be represented in SPIR-V
@ -856,12 +931,16 @@ public:
void postProcess(Instruction&);
// Hook to visit each non-32-bit sized float/int operation in a block.
void postProcessType(const Instruction&, spv::Id typeId);
// move OpSampledImage instructions to be next to their users.
void postProcessSamplers();
void dump(std::vector<unsigned int>&) const;
void createBranch(Block* block);
// Add a branch to the target block.
// If set implicit, the branch instruction shouldn't have debug source location.
void createBranch(bool implicit, Block* block);
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
void createLoopMerge(Block* mergeBlock, Block* continueBlock, LoopControlMask control,
const std::vector<unsigned int>& operands);
// Sets to generate opcode for specialization constants.
@ -871,25 +950,32 @@ public:
// Check if the builder is generating code for spec constants.
bool isInSpecConstCodeGenMode() { return generatingOpCodeForSpecConst; }
protected:
Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
void setUseReplicatedComposites(bool use) { useReplicatedComposites = use; }
private:
// Helper to get size of a scalar (in bytes)
unsigned int postProcessGetLargestScalarSize(const Instruction& type);
protected:
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value);
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2);
Id findCompositeConstant(Op typeClass, Id typeId, const std::vector<Id>& comps);
Id findCompositeConstant(Op typeClass, Op opcode, Id typeId, const std::vector<Id>& comps, size_t numMembers);
Id findStructConstant(Id typeId, const std::vector<Id>& comps);
Id collapseAccessChain();
void remapDynamicSwizzle();
void transferAccessChainSwizzle(bool dynamic);
void simplifyAccessChainSwizzle();
void createAndSetNoPredecessorBlock(const char*);
void createSelectionMerge(Block* mergeBlock, unsigned int control);
void createSelectionMerge(Block* mergeBlock, SelectionControlMask control);
void dumpSourceInstructions(std::vector<unsigned int>&) const;
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
template <class Range> void dumpInstructions(std::vector<unsigned int>& out, const Range& instructions) const;
void dumpModuleProcesses(std::vector<unsigned int>&) const;
spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
const;
struct DecorationInstructionLessThan {
bool operator()(const std::unique_ptr<Instruction>& lhs, const std::unique_ptr<Instruction>& rhs) const;
};
unsigned int spvVersion; // the version of SPIR-V to emit in the header
SourceLanguage sourceLang;
@ -936,7 +1022,10 @@ public:
Block* buildPoint;
Id uniqueId;
Function* entryPointFunction;
// This tracks the current function being built, or nullptr if not in a function.
Function const* currentFunction { nullptr };
bool generatingOpCodeForSpecConst;
bool useReplicatedComposites { false };
AccessChain accessChain;
// special blocks of instructions for output
@ -945,15 +1034,65 @@ public:
std::vector<std::unique_ptr<Instruction> > entryPoints;
std::vector<std::unique_ptr<Instruction> > executionModes;
std::vector<std::unique_ptr<Instruction> > names;
std::vector<std::unique_ptr<Instruction> > decorations;
std::set<std::unique_ptr<Instruction>, DecorationInstructionLessThan> decorations;
std::vector<std::unique_ptr<Instruction> > constantsTypesGlobals;
std::vector<std::unique_ptr<Instruction> > externals;
std::vector<std::unique_ptr<Function> > functions;
// not output, internally used for quick & dirty canonical (unique) creation
// Key for scalar constants (handles both 32-bit and 64-bit)
struct ScalarConstantKey {
unsigned int typeClass; // OpTypeInt, OpTypeFloat, OpTypeBool
unsigned int opcode; // OpConstant, OpSpecConstant, OpConstantTrue, etc.
Id typeId; // The specific type
unsigned value1; // First operand (or only operand)
unsigned value2; // Second operand (0 for single-operand constants)
bool operator==(const ScalarConstantKey& other) const {
return typeClass == other.typeClass &&
opcode == other.opcode &&
typeId == other.typeId &&
value1 == other.value1 &&
value2 == other.value2;
}
};
struct ScalarConstantKeyHash {
// 64/32 bit mix function from MurmurHash3
inline std::size_t hash_mix(std::size_t h) const {
if constexpr (sizeof(std::size_t) == 8) {
h ^= h >> 33;
h *= UINT64_C(0xff51afd7ed558ccd);
h ^= h >> 33;
h *= UINT64_C(0xc4ceb9fe1a85ec53);
h ^= h >> 33;
return h;
} else {
h ^= h >> 16;
h *= UINT32_C(0x85ebca6b);
h ^= h >> 13;
h *= UINT32_C(0xc2b2ae35);
h ^= h >> 16;
return h;
}
}
// Hash combine from boost
inline std::size_t hash_combine(std::size_t seed, std::size_t v) const {
return hash_mix(seed + 0x9e3779b9 + v);
}
std::size_t operator()(const ScalarConstantKey& k) const {
size_t hash1 = hash_combine(std::hash<unsigned>{}(k.typeClass), std::hash<unsigned>{}(k.opcode));
size_t hash2 = hash_combine(std::hash<Id>{}(k.value1), std::hash<unsigned>{}(k.value2));
size_t hash3 = hash_combine(hash1, hash2);
return hash_combine(hash3, std::hash<unsigned>{}(k.typeId));
}
};
// map type opcodes to constant inst.
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants;
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedCompositeConstants;
// map struct-id to constant instructions
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
// map type opcodes to type instructions
@ -962,6 +1101,12 @@ public:
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedDebugTypes;
// list of OpConstantNull instructions
std::vector<Instruction*> nullConstants;
// map scalar constants to result IDs
std::unordered_map<ScalarConstantKey, Id, ScalarConstantKeyHash> groupedScalarConstantResultIDs;
// Track which types have explicit layouts, to avoid reusing in storage classes without layout.
// Currently only tracks array types.
std::unordered_set<unsigned int> explicitlyLaidOut;
// stack of switches
std::stack<Block*> switchMerges;
@ -975,8 +1120,11 @@ public:
// map from include file name ids to their contents
std::map<spv::Id, const std::string*> includeFiles;
// map from core id to debug id
std::map <spv::Id, spv::Id> debugId;
// maps from OpTypeXXX id to DebugTypeXXX id
std::unordered_map<spv::Id, spv::Id> debugTypeIdLookup;
// maps from OpFunction id to DebugFunction id
std::unordered_map<spv::Id, spv::Id> debugFuncIdLookup;
// map from file name string id to DebugSource id
std::unordered_map<spv::Id, spv::Id> debugSourceId;
@ -985,6 +1133,6 @@ public:
SpvBuildLogger* logger;
}; // end Builder class
}; // end spv namespace
} // end spv namespace
#endif // SpvBuilder_H

View file

@ -43,8 +43,10 @@
#include <unordered_set>
#include <algorithm>
#include "SPIRV/spvIR.h"
#include "SpvBuilder.h"
#include "spirv.hpp"
#include "spirv.hpp11"
#include "spvUtil.h"
namespace spv {
#include "GLSL.std.450.h"
@ -64,182 +66,213 @@ namespace spv {
void Builder::postProcessType(const Instruction& inst, Id typeId)
{
// Characterize the type being questioned
Id basicTypeOp = getMostBasicTypeClass(typeId);
Op basicTypeOp = getMostBasicTypeClass(typeId);
int width = 0;
if (basicTypeOp == OpTypeFloat || basicTypeOp == OpTypeInt)
if (basicTypeOp == Op::OpTypeFloat || basicTypeOp == Op::OpTypeInt)
width = getScalarTypeWidth(typeId);
// Do opcode-specific checks
switch (inst.getOpCode()) {
case OpLoad:
case OpStore:
if (basicTypeOp == OpTypeStruct) {
if (containsType(typeId, OpTypeInt, 8))
addCapability(CapabilityInt8);
if (containsType(typeId, OpTypeInt, 16))
addCapability(CapabilityInt16);
if (containsType(typeId, OpTypeFloat, 16))
addCapability(CapabilityFloat16);
case Op::OpLoad:
case Op::OpStore:
if (basicTypeOp == Op::OpTypeStruct) {
if (containsType(typeId, Op::OpTypeInt, 8))
addCapability(Capability::Int8);
if (containsType(typeId, Op::OpTypeInt, 16))
addCapability(Capability::Int16);
if (containsType(typeId, Op::OpTypeFloat, 16))
addCapability(Capability::Float16);
} else {
StorageClass storageClass = getStorageClass(inst.getIdOperand(0));
if (width == 8) {
switch (storageClass) {
case StorageClassPhysicalStorageBufferEXT:
case StorageClassUniform:
case StorageClassStorageBuffer:
case StorageClassPushConstant:
case StorageClass::PhysicalStorageBufferEXT:
case StorageClass::Uniform:
case StorageClass::StorageBuffer:
case StorageClass::PushConstant:
break;
default:
addCapability(CapabilityInt8);
addCapability(Capability::Int8);
break;
}
} else if (width == 16) {
switch (storageClass) {
case StorageClassPhysicalStorageBufferEXT:
case StorageClassUniform:
case StorageClassStorageBuffer:
case StorageClassPushConstant:
case StorageClassInput:
case StorageClassOutput:
case StorageClass::PhysicalStorageBufferEXT:
case StorageClass::Uniform:
case StorageClass::StorageBuffer:
case StorageClass::PushConstant:
case StorageClass::Input:
case StorageClass::Output:
break;
default:
if (basicTypeOp == OpTypeInt)
addCapability(CapabilityInt16);
if (basicTypeOp == OpTypeFloat)
addCapability(CapabilityFloat16);
if (basicTypeOp == Op::OpTypeInt)
addCapability(Capability::Int16);
if (basicTypeOp == Op::OpTypeFloat)
addCapability(Capability::Float16);
break;
}
}
}
break;
case OpCopyObject:
case Op::OpCopyObject:
break;
case OpFConvert:
case OpSConvert:
case OpUConvert:
case Op::OpFConvert:
case Op::OpSConvert:
case Op::OpUConvert:
// Look for any 8/16-bit storage capabilities. If there are none, assume that
// the convert instruction requires the Float16/Int8/16 capability.
if (containsType(typeId, OpTypeFloat, 16) || containsType(typeId, OpTypeInt, 16)) {
if (containsType(typeId, Op::OpTypeFloat, 16) || containsType(typeId, Op::OpTypeInt, 16)) {
bool foundStorage = false;
for (auto it = capabilities.begin(); it != capabilities.end(); ++it) {
spv::Capability cap = *it;
if (cap == spv::CapabilityStorageInputOutput16 ||
cap == spv::CapabilityStoragePushConstant16 ||
cap == spv::CapabilityStorageUniformBufferBlock16 ||
cap == spv::CapabilityStorageUniform16) {
if (cap == spv::Capability::StorageInputOutput16 ||
cap == spv::Capability::StoragePushConstant16 ||
cap == spv::Capability::StorageUniformBufferBlock16 ||
cap == spv::Capability::StorageUniform16) {
foundStorage = true;
break;
}
}
if (!foundStorage) {
if (containsType(typeId, OpTypeFloat, 16))
addCapability(CapabilityFloat16);
if (containsType(typeId, OpTypeInt, 16))
addCapability(CapabilityInt16);
if (containsType(typeId, Op::OpTypeFloat, 16))
addCapability(Capability::Float16);
if (containsType(typeId, Op::OpTypeInt, 16))
addCapability(Capability::Int16);
}
}
if (containsType(typeId, OpTypeInt, 8)) {
if (containsType(typeId, Op::OpTypeInt, 8)) {
bool foundStorage = false;
for (auto it = capabilities.begin(); it != capabilities.end(); ++it) {
spv::Capability cap = *it;
if (cap == spv::CapabilityStoragePushConstant8 ||
cap == spv::CapabilityUniformAndStorageBuffer8BitAccess ||
cap == spv::CapabilityStorageBuffer8BitAccess) {
if (cap == spv::Capability::StoragePushConstant8 ||
cap == spv::Capability::UniformAndStorageBuffer8BitAccess ||
cap == spv::Capability::StorageBuffer8BitAccess) {
foundStorage = true;
break;
}
}
if (!foundStorage) {
addCapability(CapabilityInt8);
addCapability(Capability::Int8);
}
}
break;
case OpExtInst:
case Op::OpExtInst:
switch (inst.getImmediateOperand(1)) {
case GLSLstd450Frexp:
case GLSLstd450FrexpStruct:
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, OpTypeInt, 16))
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, Op::OpTypeInt, 16))
addExtension(spv::E_SPV_AMD_gpu_shader_int16);
break;
case GLSLstd450InterpolateAtCentroid:
case GLSLstd450InterpolateAtSample:
case GLSLstd450InterpolateAtOffset:
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, OpTypeFloat, 16))
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, Op::OpTypeFloat, 16))
addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
break;
default:
break;
}
break;
case OpAccessChain:
case OpPtrAccessChain:
case Op::OpAccessChain:
case Op::OpPtrAccessChain:
if (isPointerType(typeId))
break;
if (basicTypeOp == OpTypeInt) {
if (basicTypeOp == Op::OpTypeInt) {
if (width == 16)
addCapability(CapabilityInt16);
addCapability(Capability::Int16);
else if (width == 8)
addCapability(CapabilityInt8);
addCapability(Capability::Int8);
}
break;
default:
if (basicTypeOp == OpTypeInt) {
if (basicTypeOp == Op::OpTypeInt) {
if (width == 16)
addCapability(CapabilityInt16);
addCapability(Capability::Int16);
else if (width == 8)
addCapability(CapabilityInt8);
addCapability(Capability::Int8);
else if (width == 64)
addCapability(CapabilityInt64);
} else if (basicTypeOp == OpTypeFloat) {
addCapability(Capability::Int64);
} else if (basicTypeOp == Op::OpTypeFloat) {
if (width == 16)
addCapability(CapabilityFloat16);
addCapability(Capability::Float16);
else if (width == 64)
addCapability(CapabilityFloat64);
addCapability(Capability::Float64);
}
break;
}
}
unsigned int Builder::postProcessGetLargestScalarSize(const Instruction& type)
{
switch (type.getOpCode()) {
case Op::OpTypeBool:
return 1;
case Op::OpTypeInt:
case Op::OpTypeFloat:
return type.getImmediateOperand(0) / 8;
case Op::OpTypePointer:
return 8;
case Op::OpTypeVector:
case Op::OpTypeMatrix:
case Op::OpTypeArray:
case Op::OpTypeRuntimeArray: {
const Instruction* elem_type = module.getInstruction(type.getIdOperand(0));
return postProcessGetLargestScalarSize(*elem_type);
}
case Op::OpTypeStruct: {
unsigned int largest = 0;
for (int i = 0; i < type.getNumOperands(); ++i) {
const Instruction* elem_type = module.getInstruction(type.getIdOperand(i));
unsigned int elem_size = postProcessGetLargestScalarSize(*elem_type);
largest = std::max(largest, elem_size);
}
return largest;
}
default:
return 0;
}
}
// Called for each instruction that resides in a block.
void Builder::postProcess(Instruction& inst)
{
// Add capabilities based simply on the opcode.
switch (inst.getOpCode()) {
case OpExtInst:
case Op::OpExtInst:
switch (inst.getImmediateOperand(1)) {
case GLSLstd450InterpolateAtCentroid:
case GLSLstd450InterpolateAtSample:
case GLSLstd450InterpolateAtOffset:
addCapability(CapabilityInterpolationFunction);
addCapability(Capability::InterpolationFunction);
break;
default:
break;
}
break;
case OpDPdxFine:
case OpDPdyFine:
case OpFwidthFine:
case OpDPdxCoarse:
case OpDPdyCoarse:
case OpFwidthCoarse:
addCapability(CapabilityDerivativeControl);
case Op::OpDPdxFine:
case Op::OpDPdyFine:
case Op::OpFwidthFine:
case Op::OpDPdxCoarse:
case Op::OpDPdyCoarse:
case Op::OpFwidthCoarse:
addCapability(Capability::DerivativeControl);
break;
case OpImageQueryLod:
case OpImageQuerySize:
case OpImageQuerySizeLod:
case OpImageQuerySamples:
case OpImageQueryLevels:
addCapability(CapabilityImageQuery);
case Op::OpImageQueryLod:
case Op::OpImageQuerySize:
case Op::OpImageQuerySizeLod:
case Op::OpImageQuerySamples:
case Op::OpImageQueryLevels:
addCapability(Capability::ImageQuery);
break;
case OpGroupNonUniformPartitionNV:
case Op::OpGroupNonUniformPartitionNV:
addExtension(E_SPV_NV_shader_subgroup_partitioned);
addCapability(CapabilityGroupNonUniformPartitionedNV);
addCapability(Capability::GroupNonUniformPartitionedNV);
break;
case OpLoad:
case OpStore:
case Op::OpLoad:
case Op::OpStore:
{
// For any load/store to a PhysicalStorageBufferEXT, walk the accesschain
// index list to compute the misalignment. The pre-existing alignment value
@ -247,13 +280,13 @@ void Builder::postProcess(Instruction& inst)
// the reference type and any scalar component selection in the accesschain,
// and this function computes the rest from the SPIR-V Offset decorations.
Instruction *accessChain = module.getInstruction(inst.getIdOperand(0));
if (accessChain->getOpCode() == OpAccessChain) {
Instruction *base = module.getInstruction(accessChain->getIdOperand(0));
if (accessChain->getOpCode() == Op::OpAccessChain) {
const Instruction* base = module.getInstruction(accessChain->getIdOperand(0));
// Get the type of the base of the access chain. It must be a pointer type.
Id typeId = base->getTypeId();
Instruction *type = module.getInstruction(typeId);
assert(type->getOpCode() == OpTypePointer);
if (type->getImmediateOperand(0) != StorageClassPhysicalStorageBufferEXT) {
assert(type->getOpCode() == Op::OpTypePointer);
if (type->getImmediateOperand(0) != StorageClass::PhysicalStorageBuffer) {
break;
}
// Get the pointee type.
@ -264,31 +297,37 @@ void Builder::postProcess(Instruction& inst)
// Offset/ArrayStride/MatrixStride decorations, and bitwise OR them all
// together.
int alignment = 0;
bool first_struct_elem = false;
for (int i = 1; i < accessChain->getNumOperands(); ++i) {
Instruction *idx = module.getInstruction(accessChain->getIdOperand(i));
if (type->getOpCode() == OpTypeStruct) {
assert(idx->getOpCode() == OpConstant);
if (type->getOpCode() == Op::OpTypeStruct) {
assert(idx->getOpCode() == Op::OpConstant);
unsigned int c = idx->getImmediateOperand(0);
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
if (decoration.get()->getOpCode() == OpMemberDecorate &&
if (decoration.get()->getOpCode() == Op::OpMemberDecorate &&
decoration.get()->getIdOperand(0) == typeId &&
decoration.get()->getImmediateOperand(1) == c &&
(decoration.get()->getImmediateOperand(2) == DecorationOffset ||
decoration.get()->getImmediateOperand(2) == DecorationMatrixStride)) {
alignment |= decoration.get()->getImmediateOperand(3);
(decoration.get()->getImmediateOperand(2) == Decoration::Offset ||
decoration.get()->getImmediateOperand(2) == Decoration::MatrixStride)) {
unsigned int opernad_value = decoration.get()->getImmediateOperand(3);
alignment |= opernad_value;
if (opernad_value == 0 &&
decoration.get()->getImmediateOperand(2) == Decoration::Offset) {
first_struct_elem = true;
}
}
};
std::for_each(decorations.begin(), decorations.end(), function);
// get the next member type
typeId = type->getIdOperand(c);
type = module.getInstruction(typeId);
} else if (type->getOpCode() == OpTypeArray ||
type->getOpCode() == OpTypeRuntimeArray) {
} else if (type->getOpCode() == Op::OpTypeArray ||
type->getOpCode() == Op::OpTypeRuntimeArray) {
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
if (decoration.get()->getOpCode() == OpDecorate &&
if (decoration.get()->getOpCode() == Op::OpDecorate &&
decoration.get()->getIdOperand(0) == typeId &&
decoration.get()->getImmediateOperand(1) == DecorationArrayStride) {
decoration.get()->getImmediateOperand(1) == Decoration::ArrayStride) {
alignment |= decoration.get()->getImmediateOperand(2);
}
};
@ -302,18 +341,51 @@ void Builder::postProcess(Instruction& inst)
}
}
assert(inst.getNumOperands() >= 3);
unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1);
assert(memoryAccess & MemoryAccessAlignedMask);
const bool is_store = inst.getOpCode() == Op::OpStore;
auto const memoryAccess = (MemoryAccessMask)inst.getImmediateOperand(is_store ? 2 : 1);
assert(anySet(memoryAccess, MemoryAccessMask::Aligned));
static_cast<void>(memoryAccess);
// Compute the index of the alignment operand.
int alignmentIdx = 2;
if (inst.getOpCode() == OpStore)
if (is_store)
alignmentIdx++;
// Merge new and old (mis)alignment
alignment |= inst.getImmediateOperand(alignmentIdx);
if (!is_store) {
Instruction* inst_type = module.getInstruction(inst.getTypeId());
if (inst_type->getOpCode() == Op::OpTypePointer &&
inst_type->getImmediateOperand(0) == StorageClass::PhysicalStorageBuffer) {
// This means we are loading a pointer which means need to ensure it is at least 8-byte aligned
// See https://github.com/KhronosGroup/glslang/issues/4084
// In case the alignment is currently 4, need to ensure it is 8 before grabbing the LSB
alignment |= 8;
alignment &= 8;
}
}
// Pick the LSB
alignment = alignment & ~(alignment & (alignment-1));
// The edge case we find is when copying a struct to another struct, we never find the alignment anywhere,
// so in this case, fallback to doing a full size lookup on the type
if (alignment == 0 && first_struct_elem) {
// Quick get the struct type back
const Instruction* pointer_type = module.getInstruction(base->getTypeId());
const Instruction* struct_type = module.getInstruction(pointer_type->getIdOperand(1));
assert(struct_type->getOpCode() == Op::OpTypeStruct);
const Instruction* elem_type = module.getInstruction(struct_type->getIdOperand(0));
unsigned int largest_scalar = postProcessGetLargestScalarSize(*elem_type);
if (largest_scalar != 0) {
alignment = largest_scalar;
} else {
alignment = 16; // fallback if can't determine a godo alignment
}
}
// update the Aligned operand
assert(alignment != 0);
inst.setImmediateOperand(alignmentIdx, alignment);
}
break;
@ -387,12 +459,14 @@ void Builder::postProcessCFG()
}
// Remove unneeded decorations, for unreachable instructions
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
[&unreachableDefinitions](std::unique_ptr<Instruction>& I) -> bool {
Id decoration_id = I.get()->getIdOperand(0);
return unreachableDefinitions.count(decoration_id) != 0;
}),
decorations.end());
for (auto decorationIter = decorations.begin(); decorationIter != decorations.end();) {
Id decorationId = (*decorationIter)->getIdOperand(0);
if (unreachableDefinitions.count(decorationId) != 0) {
decorationIter = decorations.erase(decorationIter);
} else {
++decorationIter;
}
}
}
// comment in header
@ -402,17 +476,17 @@ void Builder::postProcessFeatures() {
// Look for any 8/16 bit type in physical storage buffer class, and set the
// appropriate capability. This happens in createSpvVariable for other storage
// classes, but there isn't always a variable for physical storage buffer.
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
Instruction* type = groupedTypes[OpTypePointer][t];
if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) {
if (containsType(type->getIdOperand(1), OpTypeInt, 8)) {
for (int t = 0; t < (int)groupedTypes[enumCast(Op::OpTypePointer)].size(); ++t) {
Instruction* type = groupedTypes[enumCast(Op::OpTypePointer)][t];
if (type->getImmediateOperand(0) == (unsigned)StorageClass::PhysicalStorageBufferEXT) {
if (containsType(type->getIdOperand(1), Op::OpTypeInt, 8)) {
addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
addCapability(spv::CapabilityStorageBuffer8BitAccess);
addCapability(spv::Capability::StorageBuffer8BitAccess);
}
if (containsType(type->getIdOperand(1), OpTypeInt, 16) ||
containsType(type->getIdOperand(1), OpTypeFloat, 16)) {
if (containsType(type->getIdOperand(1), Op::OpTypeInt, 16) ||
containsType(type->getIdOperand(1), Op::OpTypeFloat, 16)) {
addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
addCapability(spv::CapabilityStorageBuffer16BitAccess);
addCapability(spv::Capability::StorageBuffer16BitAccess);
}
}
}
@ -435,15 +509,15 @@ void Builder::postProcessFeatures() {
bool foundDecoration = false;
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
if (decoration.get()->getIdOperand(0) == resultId &&
decoration.get()->getOpCode() == OpDecorate &&
(decoration.get()->getImmediateOperand(1) == spv::DecorationAliasedPointerEXT ||
decoration.get()->getImmediateOperand(1) == spv::DecorationRestrictPointerEXT)) {
decoration.get()->getOpCode() == Op::OpDecorate &&
(decoration.get()->getImmediateOperand(1) == spv::Decoration::AliasedPointerEXT ||
decoration.get()->getImmediateOperand(1) == spv::Decoration::RestrictPointerEXT)) {
foundDecoration = true;
}
};
std::for_each(decorations.begin(), decorations.end(), function);
if (!foundDecoration) {
addDecoration(resultId, spv::DecorationAliasedPointerEXT);
addDecoration(resultId, spv::Decoration::AliasedPointerEXT);
}
}
}
@ -452,13 +526,13 @@ void Builder::postProcessFeatures() {
// If any Vulkan memory model-specific functionality is used, update the
// OpMemoryModel to match.
if (capabilities.find(spv::CapabilityVulkanMemoryModelKHR) != capabilities.end()) {
memoryModel = spv::MemoryModelVulkanKHR;
if (capabilities.find(spv::Capability::VulkanMemoryModelKHR) != capabilities.end()) {
memoryModel = spv::MemoryModel::VulkanKHR;
addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
}
// Add Aliased decoration if there's more than one Workgroup Block variable.
if (capabilities.find(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
if (capabilities.find(spv::Capability::WorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
assert(entryPoints.size() == 1);
auto &ep = entryPoints[0];
@ -469,20 +543,72 @@ void Builder::postProcessFeatures() {
const Id id = ep->getIdOperand(i);
const Instruction *instr = module.getInstruction(id);
if (instr->getOpCode() != spv::OpVariable)
if (instr->getOpCode() != spv::Op::OpVariable)
continue;
if (instr->getImmediateOperand(0) == spv::StorageClassWorkgroup)
if (instr->getImmediateOperand(0) == spv::StorageClass::Workgroup)
workgroup_variables.push_back(id);
}
if (workgroup_variables.size() > 1) {
for (size_t i = 0; i < workgroup_variables.size(); i++)
addDecoration(workgroup_variables[i], spv::DecorationAliased);
addDecoration(workgroup_variables[i], spv::Decoration::Aliased);
}
}
}
// SPIR-V requires that any instruction consuming the result of an OpSampledImage
// be in the same block as the OpSampledImage instruction. This pass goes finds
// uses of OpSampledImage where that is not the case and duplicates the
// OpSampledImage to be immediately before the instruction that consumes it.
// The old OpSampledImage is left in place, potentially with no users.
void Builder::postProcessSamplers()
{
// first, find all OpSampledImage instructions and store them in a map.
std::map<Id, Instruction*> sampledImageInstrs;
for (auto f: module.getFunctions()) {
for (auto b: f->getBlocks()) {
for (auto &i: b->getInstructions()) {
if (i->getOpCode() == spv::Op::OpSampledImage) {
sampledImageInstrs[i->getResultId()] = i.get();
}
}
}
}
// next find all uses of the given ids and rewrite them if needed.
for (auto f: module.getFunctions()) {
for (auto b: f->getBlocks()) {
auto &instrs = b->getInstructions();
for (size_t idx = 0; idx < instrs.size(); idx++) {
Instruction *i = instrs[idx].get();
for (int opnum = 0; opnum < i->getNumOperands(); opnum++) {
// Is this operand of the current instruction the result of an OpSampledImage?
if (i->isIdOperand(opnum) &&
sampledImageInstrs.count(i->getIdOperand(opnum)))
{
Instruction *opSampImg = sampledImageInstrs[i->getIdOperand(opnum)];
if (i->getBlock() != opSampImg->getBlock()) {
Instruction *newInstr = new Instruction(getUniqueId(),
opSampImg->getTypeId(),
spv::Op::OpSampledImage);
newInstr->addIdOperand(opSampImg->getIdOperand(0));
newInstr->addIdOperand(opSampImg->getIdOperand(1));
newInstr->setBlock(b);
// rewrite the user of the OpSampledImage to use the new instruction.
i->setIdOperand(opnum, newInstr->getResultId());
// insert the new OpSampledImage right before the current instruction.
instrs.insert(instrs.begin() + idx,
std::unique_ptr<Instruction>(newInstr));
idx++;
}
}
}
}
}
}
}
// comment in header
void Builder::postProcess(bool compileOnly)
{
@ -491,6 +617,7 @@ void Builder::postProcess(bool compileOnly)
postProcessCFG();
postProcessFeatures();
postProcessSamplers();
}
}; // end spv namespace
} // end spv namespace

View file

@ -44,6 +44,7 @@
#include "SpvTools.h"
#include "spirv-tools/optimizer.hpp"
#include "glslang/MachineIndependent/localintermediate.h"
namespace glslang {
@ -70,6 +71,8 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
return spv_target_env::SPV_ENV_VULKAN_1_2;
case glslang::EShTargetVulkan_1_3:
return spv_target_env::SPV_ENV_VULKAN_1_3;
case glslang::EShTargetVulkan_1_4:
return spv_target_env::SPV_ENV_VULKAN_1_4;
default:
break;
}
@ -81,6 +84,11 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
}
spv_target_env MapToSpirvToolsEnv(const glslang::TIntermediate& intermediate, spv::SpvBuildLogger* logger)
{
return MapToSpirvToolsEnv(intermediate.getSpv(), logger);
}
// Callback passed to spvtools::Optimizer::SetMessageConsumer
void OptimizerMesssageConsumer(spv_message_level_t level, const char *source,
const spv_position_t &position, const char *message)
@ -157,6 +165,7 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<
spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
spvValidatorOptionsSetAllowOffsetTextureOperand(options, intermediate.usingTextureOffsetNonConst());
spvValidateWithOptions(context, options, &binary, &diagnostic);
// report
@ -218,9 +227,20 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
spvtools::OptimizerOptions spvOptOptions;
if (options->optimizerAllowExpandedIDBound)
spvOptOptions.set_max_id_bound(0x3FFFFFFF);
optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
if (options->optimizerAllowExpandedIDBound) {
if (spirv.size() > 3 && spirv[3] > kDefaultMaxIdBound) {
spvtools::Optimizer optimizer2(target_env);
optimizer2.SetMessageConsumer(OptimizerMesssageConsumer);
optimizer2.RegisterPass(spvtools::CreateCompactIdsPass());
optimizer2.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
}
}
}
bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
@ -292,6 +312,6 @@ void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
}
}; // end namespace glslang
} // end namespace glslang
#endif

View file

@ -44,10 +44,12 @@
#if ENABLE_OPT
#include <vector>
#include <ostream>
#include <unordered_set>
#include "spirv-tools/libspirv.h"
#endif
#include "glslang/MachineIndependent/localintermediate.h"
#include "glslang/MachineIndependent/Versions.h"
#include "glslang/Include/visibility.h"
#include "GlslangToSpv.h"
#include "Logger.h"
@ -55,45 +57,50 @@ namespace glslang {
#if ENABLE_OPT
class TIntermediate;
// Translate glslang's view of target versioning to what SPIRV-Tools uses.
spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger);
GLSLANG_EXPORT spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger);
GLSLANG_EXPORT spv_target_env MapToSpirvToolsEnv(const glslang::TIntermediate& intermediate, spv::SpvBuildLogger* logger);
// Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment.
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
GLSLANG_EXPORT void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
// Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment.
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv,
spv_target_env requested_context);
GLSLANG_EXPORT void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv,
spv_target_env requested_context);
// Apply the SPIRV-Tools validator to generated SPIR-V.
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger*, bool prelegalization);
GLSLANG_EXPORT void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger*, bool prelegalization);
// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process.
void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger*, const SpvOptions*);
GLSLANG_EXPORT void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger*, const SpvOptions*);
// Apply the SPIRV-Tools EliminateDeadInputComponents pass to generated SPIR-V. Put result in |spirv|.
void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger*);
GLSLANG_EXPORT void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger*);
// Apply the SPIRV-Tools AnalyzeDeadOutputStores pass to generated SPIR-V. Put result in |live_locs|.
// Return true if the result is valid.
bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
std::unordered_set<uint32_t>* live_locs,
std::unordered_set<uint32_t>* live_builtins, spv::SpvBuildLogger*);
GLSLANG_EXPORT bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
std::unordered_set<uint32_t>* live_locs,
std::unordered_set<uint32_t>* live_builtins,
spv::SpvBuildLogger*);
// Apply the SPIRV-Tools EliminateDeadOutputStores and AggressiveDeadCodeElimination passes to generated SPIR-V using
// |live_locs|. Put result in |spirv|.
void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
std::unordered_set<uint32_t>* live_locs,
std::unordered_set<uint32_t>* live_builtins, spv::SpvBuildLogger*);
GLSLANG_EXPORT void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
std::unordered_set<uint32_t>* live_locs,
std::unordered_set<uint32_t>* live_builtins,
spv::SpvBuildLogger*);
// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by
// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if
// optimization is disabled.
void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
std::vector<unsigned int>& spirv, spv::SpvBuildLogger*);
GLSLANG_EXPORT void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
std::vector<unsigned int>& spirv, spv::SpvBuildLogger*);
#endif

View file

@ -36,6 +36,7 @@
// Disassembler for SPIR-V.
//
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <cassert>
@ -47,6 +48,7 @@
#include "disassemble.h"
#include "doc.h"
#include "spvUtil.h"
namespace spv {
extern "C" {
@ -59,7 +61,7 @@ namespace spv {
#include "GLSL.ext.QCOM.h"
}
}
const char* GlslStd450DebugNames[spv::GLSLstd450Count];
static const char* GlslStd450DebugNames[spv::GLSLstd450Count];
namespace spv {
@ -96,7 +98,7 @@ public:
protected:
SpirvStream(const SpirvStream&);
SpirvStream& operator=(const SpirvStream&);
Op getOpCode(int id) const { return idInstruction[id] ? (Op)(stream[idInstruction[id]] & OpCodeMask) : OpNop; }
Op getOpCode(int id) const { return idInstruction[id] ? (Op)(stream[idInstruction[id]] & OpCodeMask) : Op::OpNop; }
// Output methods
void outputIndent();
@ -186,14 +188,14 @@ void SpirvStream::processInstructions()
// Type <id>
Id typeId = 0;
if (InstructionDesc[opCode].hasType()) {
if (InstructionDesc[enumCast(opCode)].hasType()) {
typeId = stream[word++];
--numOperands;
}
// Result <id>
Id resultId = 0;
if (InstructionDesc[opCode].hasResult()) {
if (InstructionDesc[enumCast(opCode)].hasResult()) {
resultId = stream[word++];
--numOperands;
@ -338,26 +340,38 @@ int SpirvStream::disassembleString()
return decoderes.first;
}
static uint32_t popcount(uint32_t mask)
{
uint32_t count = 0;
while (mask) {
if (mask & 1) {
count++;
}
mask >>= 1;
}
return count;
}
void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands)
{
// Process the opcode
out << (OpcodeString(opCode) + 2); // leave out the "Op"
out << (OpcodeString((int)opCode) + 2); // leave out the "Op"
if (opCode == OpLoopMerge || opCode == OpSelectionMerge)
if (opCode == Op::OpLoopMerge || opCode == Op::OpSelectionMerge)
nextNestedControl = stream[word];
else if (opCode == OpBranchConditional || opCode == OpSwitch) {
else if (opCode == Op::OpBranchConditional || opCode == Op::OpSwitch) {
if (nextNestedControl) {
nestedControl.push(nextNestedControl);
nextNestedControl = 0;
}
} else if (opCode == OpExtInstImport) {
} else if (opCode == Op::OpExtInstImport) {
idDescriptor[resultId] = decodeString().second;
}
else {
if (resultId != 0 && idDescriptor[resultId].size() == 0) {
switch (opCode) {
case OpTypeInt:
case Op::OpTypeInt:
switch (stream[word]) {
case 8: idDescriptor[resultId] = "int8_t"; break;
case 16: idDescriptor[resultId] = "int16_t"; break;
@ -366,26 +380,49 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
case 64: idDescriptor[resultId] = "int64_t"; break;
}
break;
case OpTypeFloat:
case Op::OpTypeFloat:
switch (stream[word]) {
case 16: idDescriptor[resultId] = "float16_t"; break;
case 8:
case 16:
if (numOperands > 1) {
switch (stream[word+1]) {
default:
assert(0); [[fallthrough]];
case (int)spv::FPEncoding::BFloat16KHR:
idDescriptor[resultId] = "bfloat16_t";
break;
case (int)spv::FPEncoding::Float8E4M3EXT:
idDescriptor[resultId] = "floate4m3_t";
break;
case (int)spv::FPEncoding::Float8E5M2EXT:
idDescriptor[resultId] = "floate5m2_t";
break;
}
} else {
idDescriptor[resultId] = "float16_t";
}
break;
default: assert(0); [[fallthrough]];
case 32: idDescriptor[resultId] = "float"; break;
case 64: idDescriptor[resultId] = "float64_t"; break;
}
break;
case OpTypeBool:
case Op::OpTypeBool:
idDescriptor[resultId] = "bool";
break;
case OpTypeStruct:
case Op::OpTypeStruct:
idDescriptor[resultId] = "struct";
break;
case OpTypePointer:
case Op::OpTypePointer:
idDescriptor[resultId] = "ptr";
break;
case OpTypeVector:
case Op::OpTypeVector:
if (idDescriptor[stream[word]].size() > 0) {
idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 1);
if (idDescriptor[stream[word]].substr(0,2) == "bf") {
idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 2);
} else {
idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 1);
}
if (strstr(idDescriptor[stream[word]].c_str(), "8")) {
idDescriptor[resultId].append("8");
}
@ -417,10 +454,10 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
// swapped in mid-traversal.
// Handle images specially, so can put out helpful strings.
if (opCode == OpTypeImage) {
if (opCode == Op::OpTypeImage) {
out << " ";
disassembleIds(1);
out << " " << DimensionString((Dim)stream[word++]);
out << " " << DimensionString((int)(Dim)stream[word++]);
out << (stream[word++] != 0 ? " depth" : "");
out << (stream[word++] != 0 ? " array" : "");
out << (stream[word++] != 0 ? " multi-sampled" : "");
@ -429,7 +466,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
case 1: out << " sampled"; break;
case 2: out << " nonsampled"; break;
}
out << " format:" << ImageFormatString((ImageFormat)stream[word++]);
out << " format:" << ImageFormatString((int)(ImageFormat)stream[word++]);
if (numOperands == 8) {
out << " " << AccessQualifierString(stream[word++]);
@ -438,9 +475,9 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
}
// Handle all the parameterized operands
for (int op = 0; op < InstructionDesc[opCode].operands.getNum() && numOperands > 0; ++op) {
for (int op = 0; op < InstructionDesc[enumCast(opCode)].operands.getNum() && numOperands > 0; ++op) {
out << " ";
OperandClass operandClass = InstructionDesc[opCode].operands.getClass(op);
OperandClass operandClass = InstructionDesc[enumCast(opCode)].operands.getClass(op);
switch (operandClass) {
case OperandId:
case OperandScope:
@ -448,7 +485,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
disassembleIds(1);
--numOperands;
// Get names for printing "(XXX)" for readability, *after* this id
if (opCode == OpName)
if (opCode == Op::OpName)
idDescriptor[stream[word - 1]] = decodeString().second;
break;
case OperandVariableIds:
@ -461,8 +498,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
return;
case OperandOptionalLiteral:
case OperandVariableLiterals:
if ((opCode == OpDecorate && stream[word - 1] == DecorationBuiltIn) ||
(opCode == OpMemberDecorate && stream[word - 1] == DecorationBuiltIn)) {
if ((opCode == Op::OpDecorate && stream[word - 1] == Decoration::BuiltIn) ||
(opCode == Op::OpMemberDecorate && stream[word - 1] == Decoration::BuiltIn)) {
out << BuiltInString(stream[word++]);
--numOperands;
++op;
@ -498,7 +535,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
case OperandLiteralNumber:
disassembleImmediates(1);
--numOperands;
if (opCode == OpExtInst) {
if (opCode == Op::OpExtInst) {
ExtInstSet extInstSet = GLSL450Inst;
const char* name = idDescriptor[stream[word - 2]].c_str();
if (strcmp("OpenCL.std", name) == 0) {
@ -552,18 +589,41 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
numOperands -= disassembleString();
return;
case OperandMemoryAccess:
outputMask(OperandMemoryAccess, stream[word++]);
--numOperands;
// Aligned is the only memory access operand that uses an immediate
// value, and it is also the first operand that uses a value at all.
if (stream[word-1] & MemoryAccessAlignedMask) {
disassembleImmediates(1);
numOperands--;
if (numOperands)
{
outputMask(OperandMemoryAccess, stream[word++]);
--numOperands;
// Put a space after "None" if there are any remaining operands
if (numOperands && stream[word-1] == 0) {
out << " ";
}
uint32_t mask = stream[word-1];
// Aligned is the only memory access operand that uses an immediate
// value, and it is also the first operand that uses a value at all.
if (mask & (uint32_t)MemoryAccessMask::Aligned) {
disassembleImmediates(1);
numOperands--;
if (numOperands)
out << " ";
}
uint32_t bitCount = popcount(mask & (uint32_t)(MemoryAccessMask::MakePointerAvailable | MemoryAccessMask::MakePointerVisible));
disassembleIds(bitCount);
numOperands -= bitCount;
}
disassembleIds(numOperands);
return;
break;
case OperandTensorAddressingOperands:
{
outputMask(OperandTensorAddressingOperands, stream[word++]);
--numOperands;
// Put a space after "None" if there are any remaining operands
if (numOperands && stream[word-1] == 0) {
out << " ";
}
uint32_t bitCount = popcount(stream[word-1]);
disassembleIds(bitCount);
numOperands -= bitCount;
}
break;
default:
assert(operandClass >= OperandSource && operandClass < OperandOpcode);
@ -721,41 +781,41 @@ static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
strcmp(name, spv::E_SPV_NV_shader_image_footprint) == 0) {
switch (entrypoint) {
// NV builtins
case BuiltInViewportMaskNV: return "ViewportMaskNV";
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
case BuiltInBaryCoordNV: return "BaryCoordNV";
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
case BuiltInTaskCountNV: return "TaskCountNV";
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV";
case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV";
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV";
case (unsigned)BuiltIn::ViewportMaskNV: return "ViewportMaskNV";
case (unsigned)BuiltIn::SecondaryPositionNV: return "SecondaryPositionNV";
case (unsigned)BuiltIn::SecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
case (unsigned)BuiltIn::PositionPerViewNV: return "PositionPerViewNV";
case (unsigned)BuiltIn::ViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
case (unsigned)BuiltIn::BaryCoordNV: return "BaryCoordNV";
case (unsigned)BuiltIn::BaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
case (unsigned)BuiltIn::TaskCountNV: return "TaskCountNV";
case (unsigned)BuiltIn::PrimitiveCountNV: return "PrimitiveCountNV";
case (unsigned)BuiltIn::PrimitiveIndicesNV: return "PrimitiveIndicesNV";
case (unsigned)BuiltIn::ClipDistancePerViewNV: return "ClipDistancePerViewNV";
case (unsigned)BuiltIn::CullDistancePerViewNV: return "CullDistancePerViewNV";
case (unsigned)BuiltIn::LayerPerViewNV: return "LayerPerViewNV";
case (unsigned)BuiltIn::MeshViewCountNV: return "MeshViewCountNV";
case (unsigned)BuiltIn::MeshViewIndicesNV: return "MeshViewIndicesNV";
// NV Capabilities
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
case CapabilityMeshShadingNV: return "MeshShadingNV";
case CapabilityImageFootprintNV: return "ImageFootprintNV";
case CapabilitySampleMaskOverrideCoverageNV:return "SampleMaskOverrideCoverageNV";
case (unsigned)Capability::GeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
case (unsigned)Capability::ShaderViewportMaskNV: return "ShaderViewportMaskNV";
case (unsigned)Capability::ShaderStereoViewNV: return "ShaderStereoViewNV";
case (unsigned)Capability::PerViewAttributesNV: return "PerViewAttributesNV";
case (unsigned)Capability::FragmentBarycentricNV: return "FragmentBarycentricNV";
case (unsigned)Capability::MeshShadingNV: return "MeshShadingNV";
case (unsigned)Capability::ImageFootprintNV: return "ImageFootprintNV";
case (unsigned)Capability::SampleMaskOverrideCoverageNV:return "SampleMaskOverrideCoverageNV";
// NV Decorations
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
case DecorationPassthroughNV: return "PassthroughNV";
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
case DecorationPerVertexNV: return "PerVertexNV";
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
case DecorationPerViewNV: return "PerViewNV";
case DecorationPerTaskNV: return "PerTaskNV";
case (unsigned)Decoration::OverrideCoverageNV: return "OverrideCoverageNV";
case (unsigned)Decoration::PassthroughNV: return "PassthroughNV";
case (unsigned)Decoration::ViewportRelativeNV: return "ViewportRelativeNV";
case (unsigned)Decoration::SecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
case (unsigned)Decoration::PerVertexNV: return "PerVertexNV";
case (unsigned)Decoration::PerPrimitiveNV: return "PerPrimitiveNV";
case (unsigned)Decoration::PerViewNV: return "PerViewNV";
case (unsigned)Decoration::PerTaskNV: return "PerTaskNV";
default: return "Bad";
}
@ -825,4 +885,4 @@ void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
SpirvStream.processInstructions();
}
}; // end namespace spv
} // end namespace spv

View file

@ -43,10 +43,12 @@
#include <iostream>
#include <vector>
#include "glslang/Include/visibility.h"
namespace spv {
// disassemble with glslang custom disassembler
void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
GLSLANG_EXPORT void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
} // end namespace spv

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@
#pragma once
#include "spirv.hpp"
#include "spirv.hpp11"
#include <vector>
@ -157,6 +157,7 @@ enum OperandClass {
OperandKernelProfilingInfo,
OperandCapability,
OperandCooperativeMatrixOperands,
OperandTensorAddressingOperands,
OperandOpcode,

View file

@ -50,6 +50,52 @@ class Float16 {
uint16_t val;
};
class FloatE5M2 {
public:
FloatE5M2(uint8_t v) : val(v) {}
FloatE5M2() {}
static bool isNan(const FloatE5M2& val) {
return ((val.val & 0x7C) == 0x7C) && ((val.val & 0x3) != 0);
}
// Returns true if the given value is any kind of infinity.
static bool isInfinity(const FloatE5M2& val) {
return ((val.val & 0x7C) == 0x7C) && ((val.val & 0x3) == 0);
}
FloatE5M2(const FloatE5M2& other) { val = other.val; }
uint8_t get_value() const { return val; }
// Returns the maximum normal value.
static FloatE5M2 max() { return FloatE5M2(0x7B); }
// Returns the lowest normal value.
static FloatE5M2 lowest() { return FloatE5M2(0xFB); }
private:
uint8_t val;
};
class FloatE4M3 {
public:
FloatE4M3(uint8_t v) : val(v) {}
FloatE4M3() {}
static bool isNan(const FloatE4M3& val) {
return (val.val & 0x7F) == 0x7F;
}
// Returns true if the given value is any kind of infinity.
static bool isInfinity(const FloatE4M3&) {
return false;
}
FloatE4M3(const FloatE4M3& other) { val = other.val; }
uint8_t get_value() const { return val; }
// Returns the maximum normal value.
static FloatE4M3 max() { return FloatE4M3(0x7E); }
// Returns the lowest normal value.
static FloatE4M3 lowest() { return FloatE4M3(0xFE); }
private:
uint8_t val;
};
// To specialize this type, you must override uint_type to define
// an unsigned integer that can fit your floating point type.
// You must also add a isNan function that returns true if
@ -95,6 +141,30 @@ struct FloatProxyTraits<Float16> {
static Float16 lowest() { return Float16::lowest(); }
};
template <>
struct FloatProxyTraits<FloatE5M2> {
typedef uint8_t uint_type;
static bool isNan(FloatE5M2 f) { return FloatE5M2::isNan(f); }
// Returns true if the given value is any kind of infinity.
static bool isInfinity(FloatE5M2 f) { return FloatE5M2::isInfinity(f); }
// Returns the maximum normal value.
static FloatE5M2 max() { return FloatE5M2::max(); }
// Returns the lowest normal value.
static FloatE5M2 lowest() { return FloatE5M2::lowest(); }
};
template <>
struct FloatProxyTraits<FloatE4M3> {
typedef uint8_t uint_type;
static bool isNan(FloatE4M3 f) { return FloatE4M3::isNan(f); }
// Returns true if the given value is any kind of infinity.
static bool isInfinity(FloatE4M3 f) { return FloatE4M3::isInfinity(f); }
// Returns the maximum normal value.
static FloatE4M3 max() { return FloatE4M3::max(); }
// Returns the lowest normal value.
static FloatE4M3 lowest() { return FloatE4M3::lowest(); }
};
// Since copying a floating point number (especially if it is NaN)
// does not guarantee that bits are preserved, this class lets us
// store the type and use it as a float when necessary.
@ -182,6 +252,7 @@ struct HexFloatTraits {
// The bias of the exponent. (How much we need to subtract from the stored
// value to get the correct value.)
static const uint32_t exponent_bias = 0;
static bool supportsInfinity() { return true; }
};
// Traits for IEEE float.
@ -196,6 +267,7 @@ struct HexFloatTraits<FloatProxy<float>> {
static const uint_type num_exponent_bits = 8;
static const uint_type num_fraction_bits = 23;
static const uint_type exponent_bias = 127;
static bool supportsInfinity() { return true; }
};
// Traits for IEEE double.
@ -210,6 +282,7 @@ struct HexFloatTraits<FloatProxy<double>> {
static const uint_type num_exponent_bits = 11;
static const uint_type num_fraction_bits = 52;
static const uint_type exponent_bias = 1023;
static bool supportsInfinity() { return true; }
};
// Traits for IEEE half.
@ -224,6 +297,33 @@ struct HexFloatTraits<FloatProxy<Float16>> {
static const uint_type num_exponent_bits = 5;
static const uint_type num_fraction_bits = 10;
static const uint_type exponent_bias = 15;
static bool supportsInfinity() { return true; }
};
template <>
struct HexFloatTraits<FloatProxy<FloatE5M2>> {
typedef uint8_t uint_type;
typedef int8_t int_type;
typedef uint8_t underlying_type;
typedef uint8_t native_type;
static const uint_type num_used_bits = 8;
static const uint_type num_exponent_bits = 5;
static const uint_type num_fraction_bits = 2;
static const uint_type exponent_bias = 15;
static bool supportsInfinity() { return true; }
};
template <>
struct HexFloatTraits<FloatProxy<FloatE4M3>> {
typedef uint8_t uint_type;
typedef int8_t int_type;
typedef uint8_t underlying_type;
typedef uint8_t native_type;
static const uint_type num_used_bits = 8;
static const uint_type num_exponent_bits = 4;
static const uint_type num_fraction_bits = 3;
static const uint_type exponent_bias = 7;
static bool supportsInfinity() { return false; }
};
enum round_direction {
@ -243,6 +343,7 @@ class HexFloat {
typedef typename Traits::int_type int_type;
typedef typename Traits::underlying_type underlying_type;
typedef typename Traits::native_type native_type;
using Traits_T = Traits;
explicit HexFloat(T f) : value_(f) {}
@ -584,14 +685,22 @@ class HexFloat {
(getBits() & exponent_mask) == exponent_mask && significand != 0;
bool is_inf =
!is_nan &&
((exponent + carried) > static_cast<int_type>(other_T::exponent_bias) ||
(((exponent + carried) > static_cast<int_type>(other_T::exponent_bias) && other_T::Traits_T::supportsInfinity()) ||
((exponent + carried) > static_cast<int_type>(other_T::exponent_bias + 1) && !other_T::Traits_T::supportsInfinity()) ||
(significand == 0 && (getBits() & exponent_mask) == exponent_mask));
// If we are Nan or Inf we should pass that through.
if (is_inf) {
other.set_value(BitwiseCast<typename other_T::underlying_type>(
static_cast<typename other_T::uint_type>(
(negate ? other_T::sign_mask : 0) | other_T::exponent_mask)));
if (other_T::Traits_T::supportsInfinity()) {
// encode as +/-inf
other.set_value(BitwiseCast<typename other_T::underlying_type>(
static_cast<typename other_T::uint_type>(
(negate ? other_T::sign_mask : 0) | other_T::exponent_mask)));
} else {
// encode as +/-nan
other.set_value(BitwiseCast<typename other_T::underlying_type>(
static_cast<typename other_T::uint_type>(negate ? ~0 : ~other_T::sign_mask)));
}
return;
}
if (is_nan) {

View file

@ -47,7 +47,7 @@
#ifndef spvIR_H
#define spvIR_H
#include "spirv.hpp"
#include "spirv.hpp11"
#include <algorithm>
#include <cassert>
@ -67,7 +67,7 @@ class Module;
const Id NoResult = 0;
const Id NoType = 0;
const Decoration NoPrecision = DecorationMax;
const Decoration NoPrecision = Decoration::Max;
#ifdef __GNUC__
# define POTENTIALLY_UNUSED __attribute__((unused))
@ -77,15 +77,19 @@ const Decoration NoPrecision = DecorationMax;
POTENTIALLY_UNUSED
const MemorySemanticsMask MemorySemanticsAllMemory =
(MemorySemanticsMask)(MemorySemanticsUniformMemoryMask |
MemorySemanticsWorkgroupMemoryMask |
MemorySemanticsAtomicCounterMemoryMask |
MemorySemanticsImageMemoryMask);
(MemorySemanticsMask)(MemorySemanticsMask::UniformMemory |
MemorySemanticsMask::WorkgroupMemory |
MemorySemanticsMask::AtomicCounterMemory |
MemorySemanticsMask::ImageMemory);
struct IdImmediate {
bool isId; // true if word is an Id, false if word is an immediate
unsigned word;
IdImmediate(bool i, unsigned w) : isId(i), word(w) {}
IdImmediate(bool i, spv::MemoryAccessMask w) : isId(i), word((unsigned)w) {}
IdImmediate(bool i, spv::TensorAddressingOperandsMask w) : isId(i), word((unsigned)w) {}
IdImmediate(bool i, spv::ImageOperandsMask w) : isId(i), word((unsigned)w) {}
IdImmediate(bool i, spv::CooperativeMatrixOperandsMask w) : isId(i), word((unsigned)w) {}
};
//
@ -107,10 +111,79 @@ public:
operands.push_back(id);
idOperand.push_back(true);
}
// This method is potentially dangerous as it can break assumptions
// about SSA and lack of forward references.
void setIdOperand(unsigned idx, Id id) {
assert(id);
assert(idOperand[idx]);
operands[idx] = id;
}
void addImmediateOperand(unsigned int immediate) {
operands.push_back(immediate);
idOperand.push_back(false);
}
void addImmediateOperand(spv::StorageClass immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::ExecutionMode immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::ExecutionModel immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::Decoration immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::LinkageType immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::MemoryAccessMask immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::Capability immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::AddressingModel immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::MemoryModel immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::FPEncoding immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::SourceLanguage immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::Dim immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::FunctionControlMask immediate){
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::SelectionControlMask immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::LoopControlMask immediate) {
addImmediateOperand((unsigned)immediate);
}
void setImmediateOperand(unsigned idx, unsigned int immediate) {
assert(!idOperand[idx]);
operands[idx] = immediate;
@ -120,7 +193,7 @@ public:
{
unsigned int word = 0;
unsigned int shiftAmount = 0;
char c;
unsigned char c;
do {
c = *(str++);
@ -170,7 +243,7 @@ public:
wordCount += (unsigned int)operands.size();
// Write out the beginning of the instruction
out.push_back(((wordCount) << WordCountShift) | opCode);
out.push_back(((wordCount) << WordCountShift) | (unsigned)opCode);
if (typeId)
out.push_back(typeId);
if (resultId)
@ -181,6 +254,15 @@ public:
out.push_back(operands[op]);
}
const char *getNameString() const {
if (opCode == Op::OpString) {
return (const char *)&operands[0];
} else {
assert(opCode == Op::OpName);
return (const char *)&operands[1];
}
}
protected:
Instruction(const Instruction&);
Id resultId;
@ -238,7 +320,7 @@ public:
void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }
const std::vector<Block*>& getPredecessors() const { return predecessors; }
const std::vector<Block*>& getSuccessors() const { return successors; }
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
std::vector<std::unique_ptr<Instruction> >& getInstructions() {
return instructions;
}
const std::vector<std::unique_ptr<Instruction> >& getLocalVariables() const { return localVariables; }
@ -249,8 +331,8 @@ public:
if (instructions.size() < 2) return nullptr;
const Instruction* nextToLast = (instructions.cend() - 2)->get();
switch (nextToLast->getOpCode()) {
case OpSelectionMerge:
case OpLoopMerge:
case Op::OpSelectionMerge:
case Op::OpLoopMerge:
return nextToLast;
default:
return nullptr;
@ -267,7 +349,7 @@ public:
assert(instructions.size() > 0);
instructions.resize(1);
successors.clear();
addInstruction(std::unique_ptr<Instruction>(new Instruction(OpUnreachable)));
addInstruction(std::unique_ptr<Instruction>(new Instruction(Op::OpUnreachable)));
}
// Change this block into a canonical dead continue target branching to the
// given header ID. Delete instructions as necessary. A canonical dead continue
@ -281,7 +363,7 @@ public:
successors.clear();
// Add OpBranch back to the header.
assert(header != nullptr);
Instruction* branch = new Instruction(OpBranch);
Instruction* branch = new Instruction(Op::OpBranch);
branch->addIdOperand(header->getId());
addInstruction(std::unique_ptr<Instruction>(branch));
successors.push_back(header);
@ -290,14 +372,14 @@ public:
bool isTerminated() const
{
switch (instructions.back()->getOpCode()) {
case OpBranch:
case OpBranchConditional:
case OpSwitch:
case OpKill:
case OpTerminateInvocation:
case OpReturn:
case OpReturnValue:
case OpUnreachable:
case Op::OpBranch:
case Op::OpBranchConditional:
case Op::OpSwitch:
case Op::OpKill:
case Op::OpTerminateInvocation:
case Op::OpReturn:
case Op::OpReturnValue:
case Op::OpUnreachable:
return true;
default:
return false;
@ -394,14 +476,14 @@ public:
Id getFuncTypeId() const { return functionInstruction.getIdOperand(1); }
void setReturnPrecision(Decoration precision)
{
if (precision == DecorationRelaxedPrecision)
if (precision == Decoration::RelaxedPrecision)
reducedPrecisionReturn = true;
}
Decoration getReturnPrecision() const
{ return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; }
{ return reducedPrecisionReturn ? Decoration::RelaxedPrecision : NoPrecision; }
void setDebugLineInfo(Id fileName, int line, int column) {
lineInstruction = std::unique_ptr<Instruction>{new Instruction(OpLine)};
lineInstruction = std::unique_ptr<Instruction>{new Instruction(Op::OpLine)};
lineInstruction->reserveOperands(3);
lineInstruction->addIdOperand(fileName);
lineInstruction->addImmediateOperand(line);
@ -414,13 +496,13 @@ public:
void addParamPrecision(unsigned param, Decoration precision)
{
if (precision == DecorationRelaxedPrecision)
if (precision == Decoration::RelaxedPrecision)
reducedPrecisionParams.insert(param);
}
Decoration getParamPrecision(unsigned param) const
{
return reducedPrecisionParams.find(param) != reducedPrecisionParams.end() ?
DecorationRelaxedPrecision : NoPrecision;
Decoration::RelaxedPrecision : NoPrecision;
}
void dump(std::vector<unsigned int>& out) const
@ -439,7 +521,7 @@ public:
// Blocks
inReadableOrder(blocks[0], [&out](const Block* b, ReachReason, Block*) { b->dump(out); });
Instruction end(0, 0, OpFunctionEnd);
Instruction end(0, 0, Op::OpFunctionEnd);
end.dump(out);
}
@ -492,7 +574,7 @@ public:
}
StorageClass getStorageClass(Id typeId) const
{
assert(idToInstruction[typeId]->getOpCode() == spv::OpTypePointer);
assert(idToInstruction[typeId]->getOpCode() == spv::Op::OpTypePointer);
return (StorageClass)idToInstruction[typeId]->getImmediateOperand(0);
}
@ -521,13 +603,13 @@ protected:
// - all the OpFunctionParameter instructions
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, LinkageType linkage, const std::string& name, Module& parent)
: parent(parent), lineInstruction(nullptr),
functionInstruction(id, resultType, OpFunction), implicitThis(false),
functionInstruction(id, resultType, Op::OpFunction), implicitThis(false),
reducedPrecisionReturn(false),
linkType(linkage)
{
// OpFunction
functionInstruction.reserveOperands(2);
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
functionInstruction.addImmediateOperand(FunctionControlMask::MaskNone);
functionInstruction.addIdOperand(functionType);
parent.mapInstruction(&functionInstruction);
parent.addFunction(this);
@ -536,13 +618,13 @@ __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParam
Instruction* typeInst = parent.getInstruction(functionType);
int numParams = typeInst->getNumOperands() - 1;
for (int p = 0; p < numParams; ++p) {
Instruction* param = new Instruction(firstParamId + p, typeInst->getIdOperand(p + 1), OpFunctionParameter);
Instruction* param = new Instruction(firstParamId + p, typeInst->getIdOperand(p + 1), Op::OpFunctionParameter);
parent.mapInstruction(param);
parameterInstructions.push_back(param);
}
// If importing/exporting, save the function name (without the mangled parameters) for the linkage decoration
if (linkType != LinkageTypeMax) {
if (linkType != LinkageType::Max) {
exportName = name.substr(0, name.find_first_of('('));
}
}
@ -556,7 +638,7 @@ __inline void Function::addLocalVariable(std::unique_ptr<Instruction> inst)
__inline Block::Block(Id id, Function& parent) : parent(parent), unreachable(false)
{
instructions.push_back(std::unique_ptr<Instruction>(new Instruction(id, NoType, OpLabel)));
instructions.push_back(std::unique_ptr<Instruction>(new Instruction(id, NoType, Op::OpLabel)));
instructions.back()->setBlock(this);
parent.getParent().mapInstruction(instructions.back().get());
}

88
thirdparty/glslang/SPIRV/spvUtil.h vendored Normal file
View file

@ -0,0 +1,88 @@
//
// Copyright (C) 2025 Jan Kelemen
//
// 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.
//
#pragma once
#ifndef spvUtil_H
#define spvUtil_H
#include <cstdint>
#include <type_traits>
#include "spirv.hpp11"
namespace spv {
__inline uint32_t operator&(uint32_t value, spv::MemoryAccessMask mask) { return value & (unsigned)mask; }
__inline bool operator==(uint32_t word, spv::FPEncoding encoding) { return word == (unsigned)encoding; }
__inline bool operator!=(uint32_t word, spv::FPEncoding encoding) { return !(word == encoding); }
__inline bool operator==(uint32_t word, spv::Decoration decoration) { return word == (unsigned)decoration; }
__inline bool operator!=(uint32_t word, spv::Decoration decoration) { return !(word == decoration); }
__inline bool operator==(uint32_t word, spv::Op op) { return word == (unsigned)op; }
__inline bool operator!=(uint32_t word, spv::Op op) { return !(word == op); }
__inline bool operator==(uint32_t word, spv::StorageClass storage) { return word == (unsigned)storage; }
__inline bool operator!=(uint32_t word, spv::StorageClass storage) { return !(word == storage); }
__inline bool anySet(spv::MemoryAccessMask value, spv::MemoryAccessMask mask)
{
return (value & mask) != spv::MemoryAccessMask::MaskNone;
}
__inline bool anySet(spv::ImageOperandsMask value, spv::ImageOperandsMask mask)
{
return (value & mask) != spv::ImageOperandsMask::MaskNone;
}
__inline bool anySet(spv::MemorySemanticsMask value, spv::MemorySemanticsMask mask)
{
return (value & mask) != spv::MemorySemanticsMask::MaskNone;
}
__inline void addMask(uint32_t& word, spv::TensorAddressingOperandsMask mask) { word |= (unsigned)mask; }
__inline void addMask(spv::CooperativeMatrixOperandsMask& word, spv::CooperativeMatrixOperandsMask mask)
{
word = word | mask;
}
template<typename Enum, typename To = std::underlying_type_t<Enum>>
__inline To enumCast(Enum value)
{
return static_cast<To>(value);
}
}
#endif // spvUtil_H

View file

@ -49,6 +49,9 @@ enum TBasicType {
EbtFloat,
EbtDouble,
EbtFloat16,
EbtBFloat16,
EbtFloatE5M2,
EbtFloatE4M3,
EbtInt8,
EbtUint8,
EbtInt16,
@ -66,7 +69,13 @@ enum TBasicType {
EbtReference,
EbtRayQuery,
EbtHitObjectNV,
EbtHitObjectEXT,
EbtCoopmat,
EbtFunction,
EbtTensorLayoutNV,
EbtTensorViewNV,
EbtCoopvecNV,
EbtTensorARM,
// SPIR-V type defined by spirv_type
EbtSpirvType,
@ -103,6 +112,7 @@ enum TStorageQualifier {
EvqCallableData,
EvqCallableDataIn,
EvqHitObjectAttrNV,
EvqHitObjectAttrEXT,
EvqtaskPayloadSharedEXT,
@ -268,7 +278,6 @@ enum TBuiltInVariable {
EbvRayTmin,
EbvRayTmax,
EbvCullMask,
EbvHitT,
EbvHitKind,
EbvObjectToWorld,
EbvObjectToWorld3x4,
@ -276,6 +285,7 @@ enum TBuiltInVariable {
EbvWorldToObject3x4,
EbvIncomingRayFlags,
EbvCurrentRayTimeNV,
EbvClusterIDNV,
// barycentrics
EbvBaryCoordNV,
EbvBaryCoordNoPerspNV,
@ -296,6 +306,13 @@ enum TBuiltInVariable {
EbvHitKindFrontFacingMicroTriangleNV,
EbvHitKindBackFacingMicroTriangleNV,
EbvHitIsSphereNV,
EbvHitIsLSSNV,
EbvHitSpherePositionNV,
EbvHitSphereRadiusNV,
EbvHitLSSPositionsNV,
EbvHitLSSRadiiNV,
//GL_EXT_mesh_shader
EbvPrimitivePointIndicesEXT,
EbvPrimitiveLineIndicesEXT,
@ -332,6 +349,11 @@ enum TBuiltInVariable {
EbvPositionFetch,
// SPV_QCOM_tile_shading
EbvTileOffsetQCOM,
EbvTileDimensionQCOM,
EbvTileApronSizeQCOM,
EbvLast
};
@ -378,7 +400,8 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
case EvqCallableData: return "callableDataNV"; break;
case EvqCallableDataIn: return "callableDataInNV"; break;
case EvqtaskPayloadSharedEXT: return "taskPayloadSharedEXT"; break;
case EvqHitObjectAttrNV:return "hitObjectAttributeNV"; break;
case EvqHitObjectAttrNV: return "hitObjectAttributeNV"; break;
case EvqHitObjectAttrEXT:return "hitObjectAttributeEXT"; break;
default: return "unknown qualifier";
}
}
@ -495,12 +518,12 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
case EbvObjectRayDirection: return "ObjectRayDirectionNV";
case EbvRayTmin: return "ObjectRayTminNV";
case EbvRayTmax: return "ObjectRayTmaxNV";
case EbvHitT: return "HitTNV";
case EbvHitKind: return "HitKindNV";
case EbvIncomingRayFlags: return "IncomingRayFlagsNV";
case EbvObjectToWorld: return "ObjectToWorldNV";
case EbvWorldToObject: return "WorldToObjectNV";
case EbvCurrentRayTimeNV: return "CurrentRayTimeNV";
case EbvClusterIDNV: return "ClusterIDNV";
case EbvBaryCoordEXT:
case EbvBaryCoordNV: return "BaryCoordKHR";
@ -532,6 +555,13 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
case EbvHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV";
case EbvHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV";
case EbvHitIsSphereNV: return "HitIsSphereNV";
case EbvHitIsLSSNV: return "HitIsLSSNV";
case EbvHitSpherePositionNV: return "HitSpherePositionNV";
case EbvHitSphereRadiusNV: return "HitSphereRadiusNV";
case EbvHitLSSPositionsNV: return "HitSpherePositionsNV";
case EbvHitLSSRadiiNV: return "HitLSSRadiiNV";
default: return "unknown built-in variable";
}
}
@ -584,12 +614,42 @@ __inline bool isTypeFloat(TBasicType type)
case EbtFloat:
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
return true;
default:
return false;
}
}
__inline uint32_t GetNumBits(TBasicType type)
{
switch (type) {
case EbtInt8:
case EbtUint8:
case EbtFloatE5M2:
case EbtFloatE4M3:
return 8;
case EbtBFloat16:
case EbtFloat16:
case EbtInt16:
case EbtUint16:
return 16;
case EbtInt:
case EbtUint:
case EbtFloat:
return 32;
case EbtDouble:
case EbtInt64:
case EbtUint64:
return 64;
default:
assert(false);
return 0;
}
}
__inline int getTypeRank(TBasicType type)
{
int res = -1;

View file

@ -94,6 +94,11 @@ std::string to_string(const T& val) {
#pragma warning(disable : 4201) // nameless union
#endif
// Allow compilation to WASI which does not support threads yet.
#ifdef __wasi__
#define DISABLE_THREAD_SUPPORT
#endif
#include "PoolAlloc.h"
//

View file

@ -899,6 +899,17 @@ public:
unionArray = new TConstUnionVector(size, val);
}
TConstUnionArray* clone() const
{
TConstUnionArray *copy = new TConstUnionArray(size());
if (unionArray) {
for (const auto i : *unionArray) {
copy->unionArray->push_back(i);
}
}
return copy;
}
int size() const { return unionArray ? (int)unionArray->size() : 0; }
TConstUnion& operator[](size_t index) { return (*unionArray)[index]; }
const TConstUnion& operator[](size_t index) const { return (*unionArray)[index]; }

View file

@ -95,10 +95,14 @@ public:
default: append("UNKNOWN ERROR: "); break;
}
}
void location(const TSourceLoc& loc, bool absolute = false) {
void location(const TSourceLoc& loc, bool absolute = false, bool displayColumn = false) {
const int maxSize = 24;
char locText[maxSize];
snprintf(locText, maxSize, ":%d", loc.line);
if (displayColumn) {
snprintf(locText, maxSize, ":%d:%d", loc.line, loc.column);
} else {
snprintf(locText, maxSize, ":%d", loc.line);
}
if(loc.getFilename() == nullptr && shaderFileName != nullptr && absolute) {
//append(std::filesystem::absolute(shaderFileName).string());
@ -119,9 +123,11 @@ public:
append(s);
append("\n");
}
void message(TPrefixType message, const char* s, const TSourceLoc& loc) {
void message(TPrefixType message, const char* s, const TSourceLoc& loc, bool absolute = false,
bool displayColumn = false)
{
prefix(message);
location(loc);
location(loc, absolute, displayColumn);
append(s);
append("\n");
}

View file

@ -61,6 +61,8 @@
// class as the allocator (second) template argument.
//
#include "visibility.h"
#include <cstddef>
#include <cstring>
#include <vector>
@ -179,6 +181,7 @@ public:
// Call allocate() to actually acquire memory. Returns nullptr if no memory
// available, otherwise a properly aligned pointer to 'numBytes' of memory.
//
GLSLANG_EXPORT_FOR_TESTS
void* allocate(size_t numBytes);
//
@ -255,6 +258,7 @@ private:
// different times. But a simple use is to have a global pop
// with everyone using the same global allocator.
//
GLSLANG_EXPORT_FOR_TESTS
extern TPoolAllocator& GetThreadPoolAllocator();
void SetThreadPoolAllocator(TPoolAllocator* poolAllocator);
@ -288,7 +292,7 @@ public:
template<class Other>
pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
pointer allocate(size_type n) {
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
pointer allocate(size_type n, const void*) {

View file

@ -85,6 +85,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
bool image : 1; // image, combined should be false
bool combined : 1; // true means texture is combined with a sampler, false means texture with no sampler
bool sampler : 1; // true means a pure sampler, other fields should be clear()
bool tileQCOM : 1; // is tile shading attachment
unsigned int vectorSize : 3; // vector return type size.
// Some languages support structures as sample results. Storing the whole structure in the
@ -127,6 +128,15 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
bool isShadow() const { return shadow; }
bool isArrayed() const { return arrayed; }
bool isTileAttachmentQCOM() const { return tileQCOM; }
// For combined sampler, returns the underlying texture. Otherwise, returns identity.
TSampler removeCombined() const {
TSampler result = *this;
result.combined = false;
return result;
}
void clear()
{
type = EbtVoid;
@ -139,6 +149,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
sampler = false;
external = false;
yuv = false;
tileQCOM = false;
#ifdef ENABLE_HLSL
clearReturnStruct();
@ -220,7 +231,8 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
isCombined() == right.isCombined() &&
isPureSampler() == right.isPureSampler() &&
isExternal() == right.isExternal() &&
isYuv() == right.isYuv()
isYuv() == right.isYuv() &&
isTileAttachmentQCOM() == right.isTileAttachmentQCOM()
#ifdef ENABLE_HLSL
&& getVectorSize() == right.getVectorSize() &&
getStructReturnIndex() == right.getStructReturnIndex()
@ -233,9 +245,9 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
return ! operator==(right);
}
TString getString() const
std::string getString() const
{
TString s;
std::string s;
if (isPureSampler()) {
s.append("sampler");
@ -246,6 +258,9 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
case EbtInt: s.append("i"); break;
case EbtUint: s.append("u"); break;
case EbtFloat16: s.append("f16"); break;
case EbtBFloat16: s.append("bf16"); break;
case EbtFloatE5M2: s.append("fe5m2"); break;
case EbtFloatE4M3: s.append("fe4m3"); break;
case EbtInt8: s.append("i8"); break;
case EbtUint16: s.append("u8"); break;
case EbtInt16: s.append("i16"); break;
@ -259,6 +274,8 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
s.append("attachmentEXT");
else if (isSubpass())
s.append("subpass");
else if (isTileAttachmentQCOM())
s.append("attachmentQCOM");
else
s.append("image");
} else if (isCombined()) {
@ -307,21 +324,6 @@ typedef TVector<TTypeLoc> TTypeList;
typedef TVector<TString*> TIdentifierList;
//
// Following are a series of helper enums for managing layouts and qualifiers,
// used for TPublicType, TType, others.
//
enum TLayoutPacking {
ElpNone,
ElpShared, // default, but different than saying nothing
ElpStd140,
ElpStd430,
ElpPacked,
ElpScalar,
ElpCount // If expanding, see bitfield width below
};
enum TLayoutMatrix {
ElmNone,
ElmRowMajor,
@ -567,6 +569,7 @@ public:
shadercallcoherent = false;
nonprivate = false;
volatil = false;
nontemporal = false;
restrict = false;
readonly = false;
writeonly = false;
@ -604,6 +607,7 @@ public:
bool writeonly : 1;
bool coherent : 1;
bool volatil : 1;
bool nontemporal : 1;
bool devicecoherent : 1;
bool queuefamilycoherent : 1;
bool workgroupcoherent : 1;
@ -618,14 +622,15 @@ public:
bool isRestrict() const { return restrict; }
bool isCoherent() const { return coherent; }
bool isVolatile() const { return volatil; }
bool isNonTemporal() const { return nontemporal; }
bool isSample() const { return sample; }
bool isMemory() const
{
return shadercallcoherent || subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate;
return shadercallcoherent || subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || nontemporal || restrict || readonly || writeonly || nonprivate;
}
bool isMemoryQualifierImageAndSSBOOnly() const
{
return shadercallcoherent || subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly;
return shadercallcoherent || subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || nontemporal || restrict || readonly || writeonly;
}
bool bufferReferenceNeedsVulkanMemoryModel() const
{
@ -820,6 +825,9 @@ public:
bool isHitObjectAttrNV() const {
return storage == EvqHitObjectAttrNV;
}
bool isHitObjectAttrEXT() const {
return storage == EvqHitObjectAttrEXT;
}
// True if this type of IO is supposed to be arrayed with extra level for per-vertex data
bool isArrayedIo(EShLanguage language) const
@ -856,11 +864,14 @@ public:
layoutFullQuads = false;
layoutQuadDeriv = false;
layoutHitObjectShaderRecordNV = false;
layoutHitObjectShaderRecordEXT = false;
layoutBindlessSampler = false;
layoutBindlessImage = false;
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
layoutFormat = ElfNone;
layoutTileAttachmentQCOM = false;
clearInterstageLayout();
layoutSpecConstantId = layoutSpecConstantIdEnd;
@ -954,6 +965,7 @@ public:
bool layoutFullQuads;
bool layoutQuadDeriv;
bool layoutHitObjectShaderRecordNV;
bool layoutHitObjectShaderRecordEXT;
// GL_EXT_spirv_intrinsics
int spirvStorageClass;
@ -962,6 +974,8 @@ public:
bool layoutBindlessSampler;
bool layoutBindlessImage;
bool layoutTileAttachmentQCOM;
bool hasUniformLayout() const
{
return hasMatrix() ||
@ -1063,6 +1077,7 @@ public:
bool isFullQuads() const { return layoutFullQuads; }
bool isQuadDeriv() const { return layoutQuadDeriv; }
bool hasHitObjectShaderRecordNV() const { return layoutHitObjectShaderRecordNV; }
bool hasHitObjectShaderRecordEXT() const { return layoutHitObjectShaderRecordEXT; }
bool hasBufferReference() const { return layoutBufferReference; }
bool hasBufferReferenceAlign() const
{
@ -1080,6 +1095,10 @@ public:
{
return layoutBindlessImage;
}
bool isTileAttachmentQCOM() const
{
return layoutTileAttachmentQCOM;
}
// GL_EXT_spirv_intrinsics
bool hasSpirvDecorate() const { return spirvDecorate != nullptr; }
@ -1293,7 +1312,7 @@ public:
}
};
// Qualifiers that don't need to be keep per object. They have shader scope, not object scope.
// Qualifiers that don't need to be kept per object. They have shader scope, not object scope.
// So, they will not be part of TType, TQualifier, etc.
struct TShaderQualifiers {
TLayoutGeometry geometry; // geometry/tessellation shader in/out primitives
@ -1323,6 +1342,9 @@ struct TShaderQualifiers {
bool layoutDerivativeGroupLinear; // true if layout derivative_group_linearNV set
int primitives; // mesh shader "max_primitives"DerivativeGroupLinear; // true if layout derivative_group_linearNV set
bool layoutPrimitiveCulling; // true if layout primitive_culling set
bool layoutNonCoherentTileAttachmentReadQCOM; // fragment shaders -- per object
int layoutTileShadingRateQCOM[3]; // compute shader
bool layoutTileShadingRateQCOMNotDefault[3]; // compute shader
TLayoutDepth getDepth() const { return layoutDepth; }
TLayoutStencil getStencil() const { return layoutStencil; }
@ -1359,6 +1381,13 @@ struct TShaderQualifiers {
layoutDerivativeGroupQuads = false;
layoutDerivativeGroupLinear = false;
layoutPrimitiveCulling = false;
layoutNonCoherentTileAttachmentReadQCOM = false;
layoutTileShadingRateQCOM[0] = 0;
layoutTileShadingRateQCOM[1] = 0;
layoutTileShadingRateQCOM[2] = 0;
layoutTileShadingRateQCOMNotDefault[0] = false;
layoutTileShadingRateQCOMNotDefault[1] = false;
layoutTileShadingRateQCOMNotDefault[2] = false;
primitives = TQualifier::layoutNotSet;
interlockOrdering = EioNone;
}
@ -1428,6 +1457,15 @@ struct TShaderQualifiers {
interlockOrdering = src.interlockOrdering;
if (src.layoutPrimitiveCulling)
layoutPrimitiveCulling = src.layoutPrimitiveCulling;
if (src.layoutNonCoherentTileAttachmentReadQCOM)
layoutNonCoherentTileAttachmentReadQCOM = src.layoutNonCoherentTileAttachmentReadQCOM;
for (int i = 0; i < 3; ++i) {
if (src.layoutTileShadingRateQCOM[i] > 1)
layoutTileShadingRateQCOM[i] = src.layoutTileShadingRateQCOM[i];
}
for (int i = 0; i < 3; ++i) {
layoutTileShadingRateQCOMNotDefault[i] = src.layoutTileShadingRateQCOMNotDefault[i] || layoutTileShadingRateQCOMNotDefault[i];
}
}
};
@ -1475,6 +1513,9 @@ public:
uint32_t matrixRows : 4;
bool coopmatNV : 1;
bool coopmatKHR : 1;
bool coopvecNV : 1;
bool tileAttachmentQCOM: 1;
uint32_t tensorRankARM : 4;
TArraySizes* arraySizes;
const TType* userDef;
TSourceLoc loc;
@ -1485,6 +1526,12 @@ public:
bool isCoopmat() const { return coopmatNV || coopmatKHR; }
bool isCoopmatNV() const { return coopmatNV; }
bool isCoopmatKHR() const { return coopmatKHR; }
bool isCoopvecNV() const { return coopvecNV; }
bool isTensorARM() const { return tensorRankARM; }
bool hasTypeParameter() const { return isCoopmat() || isCoopvecNV() || isTensorARM(); }
bool isTensorLayoutNV() const { return basicType == EbtTensorLayoutNV; }
bool isTensorViewNV() const { return basicType == EbtTensorViewNV; }
void initType(const TSourceLoc& l)
{
@ -1498,6 +1545,9 @@ public:
typeParameters = nullptr;
coopmatNV = false;
coopmatKHR = false;
coopvecNV = false;
tileAttachmentQCOM = false;
tensorRankARM = 0;
spirvType = nullptr;
}
@ -1557,8 +1607,8 @@ public:
// for "empty" type (no args) or simple scalar/vector/matrix
explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0,
bool isVector = false) :
basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false),
tileAttachmentQCOM(false), tensorRankARM(0), arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
assert(vs >= 0);
@ -1573,8 +1623,8 @@ public:
// for explicit precision qualifier
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0,
bool isVector = false) :
basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false),
tileAttachmentQCOM(false), tensorRankARM(0), arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
assert(vs >= 0);
@ -1591,8 +1641,8 @@ public:
// for turning a TPublicType into a TType, using a shallow copy
explicit TType(const TPublicType& p) :
basicType(p.basicType),
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters),
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(p.coopvecNV),
tileAttachmentQCOM(p.tileAttachmentQCOM), tensorRankARM(p.tensorRankARM), arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters),
spirvType(p.spirvType)
{
if (basicType == EbtSampler)
@ -1640,14 +1690,22 @@ public:
assert(dimSize >= 0);
coopmatKHRuse = static_cast<uint32_t>(dimSize) & 0b111;
coopmatKHRUseValid = true;
p.typeParameters->arraySizes->removeLastSize();
}
}
if (p.isCoopvecNV() && p.typeParameters) {
basicType = p.typeParameters->basicType;
}
if (p.isTensorARM() && p.typeParameters) {
basicType = p.typeParameters->basicType;
if (p.typeParameters->arraySizes->getNumDims() > 0) {
tensorRankARM = static_cast<uint32_t>(p.typeParameters->arraySizes->getDimSize(0)) & 0b1111;
}
}
}
// for construction of sampler types
TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) :
basicType(EbtSampler), vectorSize(1u), matrixCols(0u), matrixRows(0u), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
basicType(EbtSampler), vectorSize(1u), matrixCols(0u), matrixRows(0u), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false),
tileAttachmentQCOM(false), tensorRankARM(0), arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
sampler(sampler), typeParameters(nullptr), spirvType(nullptr)
{
qualifier.clear();
@ -1689,19 +1747,23 @@ public:
// dereference from vector to scalar
vectorSize = 1;
vector1 = false;
} else if (isCoopMat()) {
} else if (isCoopMat() || isCoopVecNV()) {
coopmatNV = false;
coopmatKHR = false;
coopmatKHRuse = 0;
coopmatKHRUseValid = false;
coopvecNV = false;
typeParameters = nullptr;
} else if (isTileAttachmentQCOM()) {
tileAttachmentQCOM = false;
typeParameters = nullptr;
}
}
}
// for making structures, ...
TType(TTypeList* userDef, const TString& n) :
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false),
tileAttachmentQCOM(false), tensorRankARM(0), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
sampler.clear();
@ -1710,8 +1772,8 @@ public:
}
// For interface blocks
TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false),
tileAttachmentQCOM(false), tensorRankARM(0), qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
sampler.clear();
@ -1720,7 +1782,7 @@ public:
// for block reference (first parameter must be EbtReference)
explicit TType(TBasicType t, const TType &p, const TString& n) :
basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
tileAttachmentQCOM(false), tensorRankARM(0), arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
spirvType(nullptr)
{
assert(t == EbtReference);
@ -1758,6 +1820,9 @@ public:
coopmatKHR = copyOf.isCoopMatKHR();
coopmatKHRuse = copyOf.coopmatKHRuse;
coopmatKHRUseValid = copyOf.coopmatKHRUseValid;
coopvecNV = copyOf.isCoopVecNV();
tileAttachmentQCOM = copyOf.tileAttachmentQCOM;
tensorRankARM = copyOf.tensorRankARM;
}
// Make complete copy of the whole type graph rooted at 'copyOf'.
@ -1797,6 +1862,7 @@ public:
return *typeName;
}
virtual bool hasFieldName() const { return (fieldName != nullptr); }
virtual const TString& getFieldName() const
{
assert(fieldName);
@ -1841,7 +1907,7 @@ public:
virtual const TTypeParameters* getTypeParameters() const { return typeParameters; }
virtual TTypeParameters* getTypeParameters() { return typeParameters; }
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray() && ! isCoopVecNV(); }
virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
virtual bool isScalarOrVector() const { return !isMatrix() && !isStruct() && !isArray(); }
virtual bool isVector() const { return vectorSize > 1u || vector1; }
@ -1855,7 +1921,8 @@ public:
virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); }
virtual void setImplicitlySized(bool isImplicitSized) { arraySizes->setImplicitlySized(isImplicitSized); }
virtual bool isStruct() const { return basicType == EbtStruct || basicType == EbtBlock; }
virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; }
virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16 ||
basicType == EbtBFloat16 || basicType == EbtFloatE5M2 || basicType == EbtFloatE4M3; }
virtual bool isIntegerDomain() const
{
switch (basicType) {
@ -1876,7 +1943,9 @@ public:
}
virtual bool isOpaque() const { return basicType == EbtSampler
|| basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
|| basicType == EbtHitObjectNV; }
|| basicType == EbtHitObjectNV || basicType == EbtHitObjectEXT || isTileAttachmentQCOM()
|| isTensorARM();
}
virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
virtual bool isAttachmentEXT() const { return basicType == EbtSampler && getSampler().isAttachmentEXT(); }
@ -1892,10 +1961,18 @@ public:
bool isCoopMat() const { return coopmatNV || coopmatKHR; }
bool isCoopMatNV() const { return coopmatNV; }
bool isCoopMatKHR() const { return coopmatKHR; }
bool isCoopVecNV() const { return coopvecNV; }
bool isTileAttachmentQCOM() const { return tileAttachmentQCOM; }
bool isTensorARM() const { return tensorRankARM; }
bool hasTypeParameter() const { return isCoopMat() || isCoopVecNV() || isTensorARM(); }
int getTensorRankARM() const { return static_cast<int>(tensorRankARM); }
bool isReference() const { return getBasicType() == EbtReference; }
bool isSpirvType() const { return getBasicType() == EbtSpirvType; }
int getCoopMatKHRuse() const { return static_cast<int>(coopmatKHRuse); }
bool isTensorLayoutNV() const { return getBasicType() == EbtTensorLayoutNV; }
bool isTensorViewNV() const { return getBasicType() == EbtTensorViewNV; }
// return true if this type contains any subtype which satisfies the given predicate.
template <typename P>
bool contains(P predicate) const
@ -1950,12 +2027,20 @@ public:
virtual bool containsNonOpaque() const
{
if (isTensorARM()) {
// Tensors have a numerical basicType even though it is Opaque
return false;
}
const auto nonOpaque = [](const TType* t) {
switch (t->basicType) {
case EbtVoid:
case EbtFloat:
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
case EbtInt8:
case EbtUint8:
case EbtInt16:
@ -1988,6 +2073,14 @@ public:
{
return containsBasicType(EbtFloat16);
}
bool containsBFloat16() const
{
return containsBasicType(EbtBFloat16);
}
bool contains8BitFloat() const
{
return containsBasicType(EbtFloatE5M2) || containsBasicType(EbtFloatE4M3);
}
bool contains64BitInt() const
{
return containsBasicType(EbtInt64) || containsBasicType(EbtUint64);
@ -2004,6 +2097,10 @@ public:
{
return contains([](const TType* t) { return t->coopmatNV || t->coopmatKHR; } );
}
bool containsCoopVec() const
{
return contains([](const TType* t) { return t->coopvecNV; } );
}
bool containsReference() const
{
return containsBasicType(EbtReference);
@ -2105,6 +2202,9 @@ public:
case EbtVoid: return "void";
case EbtDouble: return "double";
case EbtFloat16: return "float16_t";
case EbtBFloat16: return "bfloat16_t";
case EbtFloatE5M2: return "floate5m2_t";
case EbtFloatE4M3: return "floate4m3_t";
case EbtInt8: return "int8_t";
case EbtUint8: return "uint8_t";
case EbtInt16: return "int16_t";
@ -2121,6 +2221,10 @@ public:
case EbtString: return "string";
case EbtSpirvType: return "spirv_type";
case EbtCoopmat: return "coopmat";
case EbtTensorLayoutNV: return "tensorLayoutNV";
case EbtTensorViewNV: return "tensorViewNV";
case EbtCoopvecNV: return "coopvecNV";
case EbtTensorARM: return "tensorARM";
default: return "unknown type";
}
}
@ -2226,7 +2330,7 @@ public:
appendStr(" layoutSecondaryViewportRelativeOffset=");
appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
}
if (qualifier.layoutShaderRecord)
appendStr(" shaderRecordNV");
if (qualifier.layoutFullQuads)
@ -2235,6 +2339,8 @@ public:
appendStr(" quad_derivatives");
if (qualifier.layoutHitObjectShaderRecordNV)
appendStr(" hitobjectshaderrecordnv");
if (qualifier.layoutHitObjectShaderRecordEXT)
appendStr(" hitobjectshaderrecordext");
if (qualifier.layoutBindlessSampler)
appendStr(" layoutBindlessSampler");
@ -2289,6 +2395,8 @@ public:
appendStr(" nonprivate");
if (qualifier.volatil)
appendStr(" volatile");
if (qualifier.nontemporal)
appendStr(" nontemporal");
if (qualifier.restrict)
appendStr(" restrict");
if (qualifier.readonly)
@ -2431,6 +2539,18 @@ public:
appendStr(" ");
appendStr("coopmat");
}
if (isTensorLayoutNV()) {
appendStr(" ");
appendStr("tensorLayoutNV");
}
if (isTensorViewNV()) {
appendStr(" ");
appendStr("tensorViewNV");
}
if (isCoopVecNV()) {
appendStr(" ");
appendStr("coopvecNV");
}
appendStr("<");
for (int i = 0; i < (int)typeParameters->arraySizes->getNumDims(); ++i) {
@ -2438,10 +2558,6 @@ public:
if (i != (int)typeParameters->arraySizes->getNumDims() - 1)
appendStr(", ");
}
if (coopmatKHRUseValid) {
appendStr(", ");
appendInt(coopmatKHRuse);
}
appendStr(">");
}
if (getPrecision && qualifier.precision != EpqNone) {
@ -2494,7 +2610,7 @@ public:
TString getBasicTypeString() const
{
if (basicType == EbtSampler)
return sampler.getString();
return TString{sampler.getString()};
else
return getBasicString();
}
@ -2516,7 +2632,9 @@ public:
{
uint32_t components = 0;
if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) {
if (isCoopVecNV()) {
components = typeParameters->arraySizes->getDimSize(0);
} else if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) {
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
components += ((*tl).type)->computeNumComponents();
} else if (matrixCols)
@ -2720,6 +2838,8 @@ public:
vector1 == right.vector1 &&
isCoopMatNV() == right.isCoopMatNV() &&
isCoopMatKHR() == right.isCoopMatKHR() &&
isCoopVecNV() == right.isCoopVecNV() &&
isTensorARM() == right.isTensorARM() &&
sameStructType(right, lpidx, rpidx) &&
sameReferenceType(right);
}
@ -2741,6 +2861,18 @@ public:
return false;
}
// See if a cooperative vector type parameter with unspecified parameters is
// an OK function parameter
bool coopVecParameterOK(const TType& right) const
{
if (isCoopVecNV() && right.isCoopVecNV()) {
return ((getBasicType() == right.getBasicType()) || (getBasicType() == EbtCoopvecNV) ||
(right.getBasicType() == EbtCoopvecNV)) &&
typeParameters == nullptr && right.typeParameters != nullptr;
}
return false;
}
bool sameCoopMatBaseType(const TType &right) const {
bool rv = false;
@ -2755,8 +2887,8 @@ public:
else
rv = false;
} else if (isCoopMatKHR() && right.isCoopMatKHR()) {
if (getBasicType() == EbtFloat || getBasicType() == EbtFloat16)
rv = right.getBasicType() == EbtFloat || right.getBasicType() == EbtFloat16 || right.getBasicType() == EbtCoopmat;
if (isFloatingDomain())
rv = right.isFloatingDomain() || right.getBasicType() == EbtCoopmat;
else if (getBasicType() == EbtUint || getBasicType() == EbtUint8 || getBasicType() == EbtUint16)
rv = right.getBasicType() == EbtUint || right.getBasicType() == EbtUint8 || right.getBasicType() == EbtUint16 || right.getBasicType() == EbtCoopmat;
else if (getBasicType() == EbtInt || getBasicType() == EbtInt8 || getBasicType() == EbtInt16)
@ -2767,24 +2899,69 @@ public:
return rv;
}
bool tensorParameterOK(const TType& right) const
{
if (isTensorLayoutNV()) {
return right.isTensorLayoutNV() && right.typeParameters == nullptr && typeParameters != nullptr;
}
if (isTensorViewNV()) {
return right.isTensorViewNV() && right.typeParameters == nullptr && typeParameters != nullptr;
}
if (isTensorARM()) {
return right.isTensorARM() && right.typeParameters == nullptr && typeParameters != nullptr;
}
return false;
}
bool sameTensorBaseTypeARM(const TType &right) const {
return (typeParameters == nullptr || right.typeParameters == nullptr ||
(tensorRankARM == right.tensorRankARM && getBasicType() == right.getBasicType()));
}
bool sameCoopVecBaseType(const TType &right) const {
bool rv = false;
if (isCoopVecNV() && right.isCoopVecNV()) {
if (getBasicType() == EbtFloat || getBasicType() == EbtFloat16)
rv = right.getBasicType() == EbtFloat || right.getBasicType() == EbtFloat16 || right.getBasicType() == EbtCoopvecNV;
else if (getBasicType() == EbtUint || getBasicType() == EbtUint8 || getBasicType() == EbtUint16)
rv = right.getBasicType() == EbtUint || right.getBasicType() == EbtUint8 || right.getBasicType() == EbtUint16 || right.getBasicType() == EbtCoopvecNV;
else if (getBasicType() == EbtInt || getBasicType() == EbtInt8 || getBasicType() == EbtInt16)
rv = right.getBasicType() == EbtInt || right.getBasicType() == EbtInt8 || right.getBasicType() == EbtInt16 || right.getBasicType() == EbtCoopvecNV;
else
rv = false;
}
return rv;
}
bool sameCoopMatUse(const TType &right) const {
return coopmatKHRuse == right.coopmatKHRuse;
}
bool sameCoopMatShapeAndUse(const TType &right) const
bool sameCoopMatShape(const TType &right) const
{
if (!isCoopMat() || !right.isCoopMat() || isCoopMatKHR() != right.isCoopMatKHR())
return false;
// Skip bit width type parameter (first array size) for coopmatNV
int firstArrayDimToCompare = isCoopMatNV() ? 1 : 0;
int lastArrayDimToCompare = typeParameters->arraySizes->getNumDims() - (isCoopMatKHR() ? 1 : 0);
for (int i = firstArrayDimToCompare; i < lastArrayDimToCompare; ++i) {
if (typeParameters->arraySizes->getDimSize(i) != right.typeParameters->arraySizes->getDimSize(i))
return false;
}
return true;
}
bool sameCoopMatShapeAndUse(const TType &right) const
{
if (!sameCoopMatShape(right))
return false;
if (coopmatKHRuse != right.coopmatKHRuse)
return false;
// Skip bit width type parameter (first array size) for coopmatNV
int firstArrayDimToCompare = isCoopMatNV() ? 1 : 0;
for (int i = firstArrayDimToCompare; i < typeParameters->arraySizes->getNumDims(); ++i) {
if (typeParameters->arraySizes->getDimSize(i) != right.typeParameters->arraySizes->getDimSize(i))
return false;
}
return true;
}
@ -2842,7 +3019,9 @@ protected:
typeParameters = new TTypeParameters;
typeParameters->arraySizes = new TArraySizes;
*typeParameters->arraySizes = *copyOf.typeParameters->arraySizes;
*typeParameters->spirvType = *copyOf.typeParameters->spirvType;
if (copyOf.typeParameters->spirvType) {
*typeParameters->spirvType = *copyOf.typeParameters->spirvType;
}
typeParameters->basicType = copyOf.basicType;
}
@ -2885,6 +3064,9 @@ protected:
bool coopmatKHR : 1;
uint32_t coopmatKHRuse : 3; // Accepts one of three values: 0, 1, 2 (gl_MatrixUseA, gl_MatrixUseB, gl_MatrixUseAccumulator)
bool coopmatKHRUseValid : 1; // True if coopmatKHRuse has been set
bool coopvecNV : 1;
bool tileAttachmentQCOM : 1;
uint32_t tensorRankARM : 4; // 0 means not a tensor; non-zero indicates the tensor rank.
TQualifier qualifier;
TArraySizes* arraySizes; // nullptr unless an array; can be shared across types

View file

@ -66,6 +66,7 @@ struct TArraySize {
return SameSpecializationConstants(node, rhs.node);
}
bool operator!=(const TArraySize& rhs) const { return !(*this == rhs); }
};
//
@ -198,6 +199,12 @@ struct TSmallArrayVector {
}
bool operator!=(const TSmallArrayVector& rhs) const { return ! operator==(rhs); }
const TArraySize& operator[](int index) const
{
assert(sizes && index < (int)sizes->size());
return (*sizes)[index];
}
protected:
TSmallArrayVector(const TSmallArrayVector&);
@ -336,6 +343,10 @@ struct TArraySizes {
return true;
}
const TArraySize& getArraySize(int index) const
{
return sizes[index];
}
void setVariablyIndexed() { variablyIndexed = true; }
bool isVariablyIndexed() const { return variablyIndexed; }

View file

@ -87,189 +87,9 @@ enum TOperator {
EOpDeclare, // Used by debugging to force declaration of variable in correct scope
// (u)int* -> bool
EOpConvInt8ToBool,
EOpConvUint8ToBool,
EOpConvInt16ToBool,
EOpConvUint16ToBool,
EOpConvIntToBool,
EOpConvUintToBool,
EOpConvInt64ToBool,
EOpConvUint64ToBool,
// float* -> bool
EOpConvFloat16ToBool,
EOpConvFloatToBool,
EOpConvDoubleToBool,
// bool -> (u)int*
EOpConvBoolToInt8,
EOpConvBoolToUint8,
EOpConvBoolToInt16,
EOpConvBoolToUint16,
EOpConvBoolToInt,
EOpConvBoolToUint,
EOpConvBoolToInt64,
EOpConvBoolToUint64,
// bool -> float*
EOpConvBoolToFloat16,
EOpConvBoolToFloat,
EOpConvBoolToDouble,
// int8_t -> (u)int*
EOpConvInt8ToInt16,
EOpConvInt8ToInt,
EOpConvInt8ToInt64,
EOpConvInt8ToUint8,
EOpConvInt8ToUint16,
EOpConvInt8ToUint,
EOpConvInt8ToUint64,
// uint8_t -> (u)int*
EOpConvUint8ToInt8,
EOpConvUint8ToInt16,
EOpConvUint8ToInt,
EOpConvUint8ToInt64,
EOpConvUint8ToUint16,
EOpConvUint8ToUint,
EOpConvUint8ToUint64,
// int8_t -> float*
EOpConvInt8ToFloat16,
EOpConvInt8ToFloat,
EOpConvInt8ToDouble,
// uint8_t -> float*
EOpConvUint8ToFloat16,
EOpConvUint8ToFloat,
EOpConvUint8ToDouble,
// int16_t -> (u)int*
EOpConvInt16ToInt8,
EOpConvInt16ToInt,
EOpConvInt16ToInt64,
EOpConvInt16ToUint8,
EOpConvInt16ToUint16,
EOpConvInt16ToUint,
EOpConvInt16ToUint64,
// uint16_t -> (u)int*
EOpConvUint16ToInt8,
EOpConvUint16ToInt16,
EOpConvUint16ToInt,
EOpConvUint16ToInt64,
EOpConvUint16ToUint8,
EOpConvUint16ToUint,
EOpConvUint16ToUint64,
// int16_t -> float*
EOpConvInt16ToFloat16,
EOpConvInt16ToFloat,
EOpConvInt16ToDouble,
// uint16_t -> float*
EOpConvUint16ToFloat16,
EOpConvUint16ToFloat,
EOpConvUint16ToDouble,
// int32_t -> (u)int*
EOpConvIntToInt8,
EOpConvIntToInt16,
EOpConvIntToInt64,
EOpConvIntToUint8,
EOpConvIntToUint16,
EOpConvIntToUint,
EOpConvIntToUint64,
// uint32_t -> (u)int*
EOpConvUintToInt8,
EOpConvUintToInt16,
EOpConvUintToInt,
EOpConvUintToInt64,
EOpConvUintToUint8,
EOpConvUintToUint16,
EOpConvUintToUint64,
// int32_t -> float*
EOpConvIntToFloat16,
EOpConvIntToFloat,
EOpConvIntToDouble,
// uint32_t -> float*
EOpConvUintToFloat16,
EOpConvUintToFloat,
EOpConvUintToDouble,
// int64_t -> (u)int*
EOpConvInt64ToInt8,
EOpConvInt64ToInt16,
EOpConvInt64ToInt,
EOpConvInt64ToUint8,
EOpConvInt64ToUint16,
EOpConvInt64ToUint,
EOpConvInt64ToUint64,
// uint64_t -> (u)int*
EOpConvUint64ToInt8,
EOpConvUint64ToInt16,
EOpConvUint64ToInt,
EOpConvUint64ToInt64,
EOpConvUint64ToUint8,
EOpConvUint64ToUint16,
EOpConvUint64ToUint,
// int64_t -> float*
EOpConvInt64ToFloat16,
EOpConvInt64ToFloat,
EOpConvInt64ToDouble,
// uint64_t -> float*
EOpConvUint64ToFloat16,
EOpConvUint64ToFloat,
EOpConvUint64ToDouble,
// float16_t -> (u)int*
EOpConvFloat16ToInt8,
EOpConvFloat16ToInt16,
EOpConvFloat16ToInt,
EOpConvFloat16ToInt64,
EOpConvFloat16ToUint8,
EOpConvFloat16ToUint16,
EOpConvFloat16ToUint,
EOpConvFloat16ToUint64,
// float16_t -> float*
EOpConvFloat16ToFloat,
EOpConvFloat16ToDouble,
// float -> (u)int*
EOpConvFloatToInt8,
EOpConvFloatToInt16,
EOpConvFloatToInt,
EOpConvFloatToInt64,
EOpConvFloatToUint8,
EOpConvFloatToUint16,
EOpConvFloatToUint,
EOpConvFloatToUint64,
// float -> float*
EOpConvFloatToFloat16,
EOpConvFloatToDouble,
// float64 _t-> (u)int*
EOpConvDoubleToInt8,
EOpConvDoubleToInt16,
EOpConvDoubleToInt,
EOpConvDoubleToInt64,
EOpConvDoubleToUint8,
EOpConvDoubleToUint16,
EOpConvDoubleToUint,
EOpConvDoubleToUint64,
// float64_t -> float*
EOpConvDoubleToFloat16,
EOpConvDoubleToFloat,
// Operator used to represent all conversions between int, float, and bool.
// The specific types are inferred from TBasicType.
EOpConvNumeric,
// uint64_t <-> pointer
EOpConvUint64ToPtr,
@ -567,6 +387,11 @@ enum TOperator {
EOpSubgroupPartitionedExclusiveXor,
EOpSubgroupGuardStop,
// Integer dot product
EOpDotPackedEXT,
EOpDotAccSatEXT,
EOpDotPackedAccSatEXT,
EOpMinInvocations,
EOpMaxInvocations,
@ -628,7 +453,35 @@ enum TOperator {
EOpCooperativeMatrixMulAdd,
EOpCooperativeMatrixLoadNV,
EOpCooperativeMatrixStoreNV,
EOpCooperativeMatrixLoadTensorNV,
EOpCooperativeMatrixStoreTensorNV,
EOpCooperativeMatrixMulAddNV,
EOpCooperativeMatrixReduceNV,
EOpCooperativeMatrixPerElementOpNV,
EOpCooperativeMatrixTransposeNV,
EOpCreateTensorLayoutNV,
EOpTensorLayoutSetBlockSizeNV,
EOpTensorLayoutSetDimensionNV,
EOpTensorLayoutSetStrideNV,
EOpTensorLayoutSliceNV,
EOpTensorLayoutSetClampValueNV,
EOpCreateTensorViewNV,
EOpTensorViewSetDimensionNV,
EOpTensorViewSetStrideNV,
EOpTensorViewSetClipNV,
EOpCooperativeVectorMatMulNV,
EOpCooperativeVectorMatMulAddNV,
EOpCooperativeVectorLoadNV,
EOpCooperativeVectorStoreNV,
EOpCooperativeVectorOuterProductAccumulateNV,
EOpCooperativeVectorReduceSumAccumulateNV,
EOpTensorReadARM,
EOpTensorWriteARM,
EOpTensorSizeARM,
EOpBeginInvocationInterlock, // Fragment only
EOpEndInvocationInterlock, // Fragment only
@ -762,13 +615,27 @@ enum TOperator {
EOpConstructF16Mat4x2,
EOpConstructF16Mat4x3,
EOpConstructF16Mat4x4,
EOpConstructBFloat16,
EOpConstructBF16Vec2,
EOpConstructBF16Vec3,
EOpConstructBF16Vec4,
EOpConstructFloatE5M2,
EOpConstructFloatE5M2Vec2,
EOpConstructFloatE5M2Vec3,
EOpConstructFloatE5M2Vec4,
EOpConstructFloatE4M3,
EOpConstructFloatE4M3Vec2,
EOpConstructFloatE4M3Vec3,
EOpConstructFloatE4M3Vec4,
EOpConstructStruct,
EOpConstructTextureSampler,
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
EOpConstructReference,
EOpConstructCooperativeMatrixNV,
EOpConstructCooperativeMatrixKHR,
EOpConstructCooperativeVectorNV,
EOpConstructAccStruct,
EOpConstructSaturated,
EOpConstructGuardEnd,
//
@ -1008,6 +875,44 @@ enum TOperator {
EOpFetchMicroTriangleVertexPositionNV,
EOpFetchMicroTriangleVertexBarycentricNV,
//
// GL_EXT_shader_invocation_reorder
//
EOpHitObjectTraceRayEXT,
EOpHitObjectTraceRayMotionEXT,
EOpHitObjectRecordMissEXT,
EOpHitObjectRecordMissMotionEXT,
EOpHitObjectRecordEmptyEXT,
EOpHitObjectExecuteShaderEXT,
EOpHitObjectIsEmptyEXT,
EOpHitObjectIsMissEXT,
EOpHitObjectIsHitEXT,
EOpHitObjectGetRayTMinEXT,
EOpHitObjectGetRayTMaxEXT,
EOpHitObjectGetRayFlagsEXT,
EOpHitObjectGetObjectRayOriginEXT,
EOpHitObjectGetObjectRayDirectionEXT,
EOpHitObjectGetWorldRayOriginEXT,
EOpHitObjectGetWorldRayDirectionEXT,
EOpHitObjectGetWorldToObjectEXT,
EOpHitObjectGetObjectToWorldEXT,
EOpHitObjectGetInstanceCustomIndexEXT,
EOpHitObjectGetInstanceIdEXT,
EOpHitObjectGetGeometryIndexEXT,
EOpHitObjectGetPrimitiveIndexEXT,
EOpHitObjectGetHitKindEXT,
EOpHitObjectGetShaderBindingTableRecordIndexEXT,
EOpHitObjectSetShaderBindingTableRecordIndexEXT,
EOpHitObjectGetShaderRecordBufferHandleEXT,
EOpHitObjectGetAttributesEXT,
EOpHitObjectGetCurrentTimeEXT,
EOpReorderThreadEXT,
EOpHitObjectReorderExecuteEXT,
EOpHitObjectTraceReorderExecuteEXT,
EOpHitObjectTraceMotionReorderExecuteEXT,
EOpHitObjectRecordFromQueryEXT,
EOpHitObjectGetIntersectionTriangleVertexPositionsEXT,
// HLSL operations
//
@ -1117,14 +1022,44 @@ enum TOperator {
EOpImageBlockMatchWindowSADQCOM,
EOpImageBlockMatchGatherSSDQCOM,
EOpImageBlockMatchGatherSADQCOM,
// Cooperative Matrix Conversion
EOpBitCastArrayQCOM,
EOpExtractSubArrayQCOM,
EOpCompositeConstructCoopMatQCOM,
EOpCompositeExtractCoopMatQCOM,
// GL_NV_cluster_acceleration_structure
EOpRayQueryGetIntersectionClusterIdNV,
EOpHitObjectGetClusterIdNV,
// GL_NV_linear_swept_spheres
EOpRayQueryGetIntersectionSpherePositionNV,
EOpRayQueryGetIntersectionSphereRadiusNV,
EOpRayQueryGetIntersectionLSSHitValueNV,
EOpRayQueryGetIntersectionLSSPositionsNV,
EOpRayQueryGetIntersectionLSSRadiiNV,
EOpRayQueryIsSphereHitNV,
EOpRayQueryIsLSSHitNV,
EOpHitObjectGetSpherePositionNV,
EOpHitObjectGetSphereRadiusNV,
EOpHitObjectGetLSSPositionsNV,
EOpHitObjectGetLSSRadiiNV,
EOpHitObjectIsSphereHitNV,
EOpHitObjectIsLSSHitNV,
};
inline bool IsOpNumericConv(const TOperator op) {
return op == EOpConvNumeric;
}
enum TLinkType {
ELinkNone,
ELinkExport,
};
class TIntermTraverser;
class TIntermVariableDecl;
class TIntermOperator;
class TIntermAggregate;
class TIntermUnary;
@ -1153,6 +1088,7 @@ public:
virtual const glslang::TSourceLoc& getLoc() const { return loc; }
virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
virtual void traverse(glslang::TIntermTraverser*) = 0;
virtual glslang::TIntermVariableDecl* getAsVariableDecl() { return nullptr; }
virtual glslang::TIntermTyped* getAsTyped() { return nullptr; }
virtual glslang::TIntermOperator* getAsOperator() { return nullptr; }
virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return nullptr; }
@ -1166,6 +1102,7 @@ public:
virtual glslang::TIntermBranch* getAsBranchNode() { return nullptr; }
virtual glslang::TIntermLoop* getAsLoopNode() { return nullptr; }
virtual const glslang::TIntermVariableDecl* getAsVariableDecl() const { return nullptr; }
virtual const glslang::TIntermTyped* getAsTyped() const { return nullptr; }
virtual const glslang::TIntermOperator* getAsOperator() const { return nullptr; }
virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return nullptr; }
@ -1196,6 +1133,37 @@ struct TIntermNodePair {
TIntermNode* node2;
};
//
// Represent declaration of a variable.
//
class TIntermVariableDecl : public TIntermNode {
public:
TIntermVariableDecl(TIntermSymbol* declSymbol, TIntermNode* initNode) : declSymbol(declSymbol), initNode(initNode)
{
}
TIntermVariableDecl(const TIntermVariableDecl&) = delete;
TIntermVariableDecl& operator=(const TIntermVariableDecl&) = delete;
void traverse(glslang::TIntermTraverser* traverser) override;
TIntermVariableDecl* getAsVariableDecl() override { return this; }
const TIntermVariableDecl* getAsVariableDecl() const override { return this; }
TIntermSymbol* getDeclSymbol() { return declSymbol; }
const TIntermSymbol* getDeclSymbol() const { return declSymbol; }
TIntermNode* getInitNode() { return initNode; }
const TIntermNode* getInitNode() const { return initNode; }
private:
// This symbol represents the declared variable at its declaration point.
// It's not traversed by default. To traverse it, the visitor needs to have includeDeclSymbol enabled.
TIntermSymbol* declSymbol = nullptr;
// The initializer
TIntermNode* initNode = nullptr;
};
//
// Intermediate class for nodes that have a type.
//
@ -1218,6 +1186,7 @@ public:
virtual int getVectorSize() const { return type.getVectorSize(); }
virtual int getMatrixCols() const { return type.getMatrixCols(); }
virtual int getMatrixRows() const { return type.getMatrixRows(); }
virtual int getTensorRankARM() const { return type.getTensorRankARM(); }
virtual bool isMatrix() const { return type.isMatrix(); }
virtual bool isArray() const { return type.isArray(); }
virtual bool isVector() const { return type.isVector(); }
@ -1239,7 +1208,7 @@ protected:
//
class TIntermLoop : public TIntermNode {
public:
TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
TIntermLoop(TIntermNode* aBody, TIntermNode* aTest, TIntermTyped* aTerminal, bool testFirst) :
body(aBody),
test(aTest),
terminal(aTerminal),
@ -1258,10 +1227,20 @@ public:
virtual const TIntermLoop* getAsLoopNode() const { return this; }
virtual void traverse(TIntermTraverser*);
TIntermNode* getBody() const { return body; }
TIntermTyped* getTest() const { return test; }
TIntermNode* getTest() const { return test; }
TIntermTyped* getTerminal() const { return terminal; }
bool testFirst() const { return first; }
// Because the test node can be a declaration in a while loop, this function unwraps it to get the actual expression.
TIntermTyped* getTestExpr() const {
if (auto decl = test->getAsVariableDecl()) {
return decl->getInitNode()->getAsTyped();
}
else {
return test->getAsTyped();
}
}
void setUnroll() { unroll = true; }
void setDontUnroll() {
dontUnroll = true;
@ -1295,7 +1274,7 @@ public:
protected:
TIntermNode* body; // code to loop over
TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
TIntermNode* test; // exit condition associated with loop, could be 0 for 'for' loops
TIntermTyped* terminal; // exists for for-loops
bool first; // true for while and for, not for do-while
bool unroll; // true if unroll requested
@ -1356,11 +1335,19 @@ public:
// if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from
// per process threadPoolAllocator, then it causes increased memory usage per compile
// it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(long long i, const TString& n, const TType& t)
: TIntermTyped(t), id(i), flattenSubset(-1), constSubtree(nullptr) { name = n; }
TIntermSymbol(long long i, const TString& n, EShLanguage s, const TType& t, const TString* mn = nullptr)
: TIntermTyped(t), id(i), flattenSubset(-1), stage(s), constSubtree(nullptr) {
name = n;
if (mn) {
mangledName = *mn;
} else {
mangledName = n;
}
}
virtual long long getId() const { return id; }
virtual void changeId(long long i) { id = i; }
virtual const TString& getName() const { return name; }
virtual const TString& getMangledName() const { return mangledName; }
virtual void traverse(TIntermTraverser*);
virtual TIntermSymbol* getAsSymbolNode() { return this; }
virtual const TIntermSymbol* getAsSymbolNode() const { return this; }
@ -1376,11 +1363,14 @@ public:
// This is meant for cases where a node has already been constructed, and
// later on, it becomes necessary to switch to a different symbol.
virtual void switchId(long long newId) { id = newId; }
EShLanguage getStage() const { return stage; }
protected:
long long id; // the unique id of the symbol this node represents
int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
TString name; // the name of the symbol this node represents
EShLanguage stage;
TString mangledName; // mangled function name, or a copy of name if not a function
TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
TIntermTyped* constSubtree;
};
@ -1694,8 +1684,12 @@ typedef TVector<TStorageQualifier> TQualifierList;
//
class TIntermAggregate : public TIntermOperator {
public:
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(nullptr) { }
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(nullptr) { }
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(nullptr) {
endLoc.init();
}
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(nullptr) {
endLoc.init();
}
~TIntermAggregate() { delete pragmaTable; }
virtual TIntermAggregate* getAsAggregate() { return this; }
virtual const TIntermAggregate* getAsAggregate() const { return this; }
@ -1719,6 +1713,9 @@ public:
void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
void setEndLoc(TSourceLoc loc) { endLoc = loc; }
TSourceLoc getEndLoc() const { return endLoc; }
void setLinkType(TLinkType l) { linkType = l; }
TLinkType getLinkType() const { return linkType; }
protected:
@ -1733,6 +1730,10 @@ protected:
TPragmaTable* pragmaTable;
TSpirvInstruction spirvInst;
TLinkType linkType = ELinkNone;
// Marking the end source location of the aggregate.
// This is currently only set for a compound statement or a function body, pointing to '}'.
TSourceLoc endLoc;
};
//
@ -1834,24 +1835,26 @@ enum TVisit
class TIntermTraverser {
public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false, bool includeDeclSymbol = false) :
preVisit(preVisit),
inVisit(inVisit),
postVisit(postVisit),
rightToLeft(rightToLeft),
includeDeclSymbol(includeDeclSymbol),
depth(0),
maxDepth(0) { }
virtual ~TIntermTraverser() { }
virtual void visitSymbol(TIntermSymbol*) { }
virtual void visitConstantUnion(TIntermConstantUnion*) { }
virtual bool visitBinary(TVisit, TIntermBinary*) { return true; }
virtual bool visitUnary(TVisit, TIntermUnary*) { return true; }
virtual bool visitSelection(TVisit, TIntermSelection*) { return true; }
virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; }
virtual bool visitLoop(TVisit, TIntermLoop*) { return true; }
virtual bool visitBranch(TVisit, TIntermBranch*) { return true; }
virtual bool visitSwitch(TVisit, TIntermSwitch*) { return true; }
virtual void visitSymbol(TIntermSymbol*) { }
virtual void visitConstantUnion(TIntermConstantUnion*) { }
virtual bool visitBinary(TVisit, TIntermBinary*) { return true; }
virtual bool visitUnary(TVisit, TIntermUnary*) { return true; }
virtual bool visitSelection(TVisit, TIntermSelection*) { return true; }
virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; }
virtual bool visitLoop(TVisit, TIntermLoop*) { return true; }
virtual bool visitBranch(TVisit, TIntermBranch*) { return true; }
virtual bool visitSwitch(TVisit, TIntermSwitch*) { return true; }
virtual bool visitVariableDecl(TVisit, TIntermVariableDecl*) { return true; }
int getMaxDepth() const { return maxDepth; }
@ -1878,6 +1881,11 @@ public:
const bool postVisit;
const bool rightToLeft;
// Whether to traverse declaration symbols in the traversal.
// By default, declaration symbols are not visited in the traversal to avoid
// visiting them in SPIR-V generation where they are not needed.
const bool includeDeclSymbol;
protected:
TIntermTraverser& operator=(TIntermTraverser&);

View file

@ -0,0 +1,58 @@
//
// Copyright (C) 2023 LunarG, 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.
//
#ifdef GLSLANG_IS_SHARED_LIBRARY
#ifdef _WIN32
#ifdef GLSLANG_EXPORTING
#define GLSLANG_EXPORT __declspec(dllexport)
#else
#define GLSLANG_EXPORT __declspec(dllimport)
#endif
#elif __GNUC__ >= 4
#define GLSLANG_EXPORT __attribute__((visibility("default")))
#endif
#endif // GLSLANG_IS_SHARED_LIBRARY
#ifndef GLSLANG_EXPORT
#define GLSLANG_EXPORT
#endif
// Symbols marked with this macro are only meant for public use by the test suite
// and do not appear in publicly installed headers. They are not considered to be
// part of the glslang library ABI.
#ifdef GLSLANG_TEST_BUILD
#define GLSLANG_EXPORT_FOR_TESTS GLSLANG_EXPORT
#else
#define GLSLANG_EXPORT_FOR_TESTS
#endif

View file

@ -151,6 +151,9 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
case EbtDouble:
case EbtFloat:
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
if (rightUnionArray[i].getDConst() != 0.0)
newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst());
else if (leftUnionArray[i].getDConst() > 0.0)
@ -490,11 +493,180 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
// Process component-wise operations
for (int i = 0; i < objectSize; i++) {
// First read the value and convert to i64/u64/f64/bool, then convert
// to the destination type (still 64b), then convert down to the
// destination size.
if (IsOpNumericConv(op)) {
enum ConvType { CONV_FLOAT, CONV_INT, CONV_UINT, CONV_BOOL };
ConvType srcType = CONV_UINT, dstType = CONV_UINT;
double valf = 0.0;
uint64_t valu = 0;
int64_t vali = 0;
bool valb = false;
switch (getType().getBasicType()) {
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
case EbtFloat:
valf = unionArray[i].getDConst();
srcType = CONV_FLOAT;
break;
case EbtInt8:
vali = unionArray[i].getI8Const();
srcType = CONV_INT;
break;
case EbtInt16:
vali = unionArray[i].getI16Const();
srcType = CONV_INT;
break;
case EbtInt:
vali = unionArray[i].getIConst();
srcType = CONV_INT;
break;
case EbtInt64:
vali = unionArray[i].getI64Const();
srcType = CONV_INT;
break;
case EbtUint8:
valu = unionArray[i].getU8Const();
srcType = CONV_UINT;
break;
case EbtUint16:
valu = unionArray[i].getU16Const();
srcType = CONV_UINT;
break;
case EbtUint:
valu = unionArray[i].getUConst();
srcType = CONV_UINT;
break;
case EbtUint64:
valu = unionArray[i].getU64Const();
srcType = CONV_UINT;
break;
case EbtBool:
valb = unionArray[i].getBConst();
srcType = CONV_BOOL;
break;
default:
assert(0);
break;
}
switch (returnType.getBasicType()) {
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
case EbtFloat:
dstType = CONV_FLOAT;
break;
case EbtInt8:
case EbtInt16:
case EbtInt:
case EbtInt64:
dstType = CONV_INT;
break;
case EbtUint8:
case EbtUint16:
case EbtUint:
case EbtUint64:
dstType = CONV_UINT;
break;
case EbtBool:
dstType = CONV_BOOL;
break;
default:
assert(0);
break;
}
if (dstType == CONV_BOOL) {
switch (srcType) {
case CONV_FLOAT:
valb = (valf != 0.0); break;
case CONV_INT:
valb = (vali != 0.0); break;
case CONV_UINT:
valb = (valu != 0.0); break;
default:
break;
}
} else if (dstType == CONV_FLOAT) {
switch (srcType) {
case CONV_BOOL:
valf = (double)valb; break;
case CONV_INT:
valf = (double)vali; break;
case CONV_UINT:
valf = (double)valu; break;
default:
break;
}
} else if (dstType == CONV_INT) {
switch (srcType) {
case CONV_BOOL:
vali = (int64_t)valb; break;
case CONV_FLOAT:
vali = (int64_t)valf; break;
case CONV_UINT:
vali = (int64_t)valu; break;
default:
break;
}
} else if (dstType == CONV_UINT) {
switch (srcType) {
case CONV_BOOL:
valu = (uint64_t)valb; break;
case CONV_FLOAT:
valu = (uint64_t)valf; break;
case CONV_INT:
valu = (uint64_t)vali; break;
default:
break;
}
}
switch (returnType.getBasicType()) {
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
case EbtFloat:
newConstArray[i].setDConst(valf); break;
case EbtInt8:
newConstArray[i].setI8Const(static_cast<int8_t>(vali)); break;
case EbtInt16:
newConstArray[i].setI16Const(static_cast<int16_t>(vali)); break;
case EbtInt:
newConstArray[i].setIConst(static_cast<int32_t>(vali)); break;
case EbtInt64:
newConstArray[i].setI64Const(vali); break;
case EbtUint8:
newConstArray[i].setU8Const(static_cast<uint8_t>(valu)); break;
case EbtUint16:
newConstArray[i].setU16Const(static_cast<uint16_t>(valu)); break;
case EbtUint:
newConstArray[i].setUConst(static_cast<uint32_t>(valu)); break;
case EbtUint64:
newConstArray[i].setU64Const(valu); break;
case EbtBool:
newConstArray[i].setBConst(valb); break;
default:
assert(0);
break;
}
continue;
}
switch (op) {
case EOpNegative:
switch (getType().getBasicType()) {
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
// Note: avoid UBSAN error regarding negating 0x80000000
case EbtInt: newConstArray[i].setIConst(
@ -507,7 +679,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EbtUint8: newConstArray[i].setU8Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU8Const()))); break;
case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break;
case EbtUint16:newConstArray[i].setU16Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU16Const()))); break;
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
case EbtInt64: {
int64_t i64val = unionArray[i].getI64Const();
newConstArray[i].setI64Const(i64val == INT64_MIN ? INT64_MIN : -i64val);
break;
}
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const()))); break;
default:
return nullptr;
@ -637,277 +813,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
break;
}
case EOpConvIntToBool:
newConstArray[i].setBConst(unionArray[i].getIConst() != 0); break;
case EOpConvUintToBool:
newConstArray[i].setBConst(unionArray[i].getUConst() != 0); break;
case EOpConvBoolToInt:
newConstArray[i].setIConst(unionArray[i].getBConst()); break;
case EOpConvBoolToUint:
newConstArray[i].setUConst(unionArray[i].getBConst()); break;
case EOpConvIntToUint:
newConstArray[i].setUConst(unionArray[i].getIConst()); break;
case EOpConvUintToInt:
newConstArray[i].setIConst(unionArray[i].getUConst()); break;
case EOpConvFloatToBool:
case EOpConvDoubleToBool:
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
case EOpConvBoolToFloat:
case EOpConvBoolToDouble:
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
case EOpConvIntToFloat:
case EOpConvIntToDouble:
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
case EOpConvUintToFloat:
case EOpConvUintToDouble:
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
case EOpConvDoubleToFloat:
case EOpConvFloatToDouble:
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
case EOpConvFloatToUint:
case EOpConvDoubleToUint:
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
case EOpConvFloatToInt:
case EOpConvDoubleToInt:
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
case EOpConvInt8ToBool:
newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break;
case EOpConvUint8ToBool:
newConstArray[i].setBConst(unionArray[i].getU8Const() != 0); break;
case EOpConvInt16ToBool:
newConstArray[i].setBConst(unionArray[i].getI16Const() != 0); break;
case EOpConvUint16ToBool:
newConstArray[i].setBConst(unionArray[i].getU16Const() != 0); break;
case EOpConvInt64ToBool:
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
case EOpConvUint64ToBool:
newConstArray[i].setBConst(unionArray[i].getU64Const() != 0); break;
case EOpConvFloat16ToBool:
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
case EOpConvBoolToInt8:
newConstArray[i].setI8Const(unionArray[i].getBConst()); break;
case EOpConvBoolToUint8:
newConstArray[i].setU8Const(unionArray[i].getBConst()); break;
case EOpConvBoolToInt16:
newConstArray[i].setI16Const(unionArray[i].getBConst()); break;
case EOpConvBoolToUint16:
newConstArray[i].setU16Const(unionArray[i].getBConst()); break;
case EOpConvBoolToInt64:
newConstArray[i].setI64Const(unionArray[i].getBConst()); break;
case EOpConvBoolToUint64:
newConstArray[i].setU64Const(unionArray[i].getBConst()); break;
case EOpConvBoolToFloat16:
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
case EOpConvInt8ToInt16:
newConstArray[i].setI16Const(unionArray[i].getI8Const()); break;
case EOpConvInt8ToInt:
newConstArray[i].setIConst(unionArray[i].getI8Const()); break;
case EOpConvInt8ToInt64:
newConstArray[i].setI64Const(unionArray[i].getI8Const()); break;
case EOpConvInt8ToUint8:
newConstArray[i].setU8Const(unionArray[i].getI8Const()); break;
case EOpConvInt8ToUint16:
newConstArray[i].setU16Const(unionArray[i].getI8Const()); break;
case EOpConvInt8ToUint:
newConstArray[i].setUConst(unionArray[i].getI8Const()); break;
case EOpConvInt8ToUint64:
newConstArray[i].setU64Const(unionArray[i].getI8Const()); break;
case EOpConvUint8ToInt8:
newConstArray[i].setI8Const(unionArray[i].getU8Const()); break;
case EOpConvUint8ToInt16:
newConstArray[i].setI16Const(unionArray[i].getU8Const()); break;
case EOpConvUint8ToInt:
newConstArray[i].setIConst(unionArray[i].getU8Const()); break;
case EOpConvUint8ToInt64:
newConstArray[i].setI64Const(unionArray[i].getU8Const()); break;
case EOpConvUint8ToUint16:
newConstArray[i].setU16Const(unionArray[i].getU8Const()); break;
case EOpConvUint8ToUint:
newConstArray[i].setUConst(unionArray[i].getU8Const()); break;
case EOpConvUint8ToUint64:
newConstArray[i].setU64Const(unionArray[i].getU8Const()); break;
case EOpConvInt8ToFloat16:
newConstArray[i].setDConst(unionArray[i].getI8Const()); break;
case EOpConvInt8ToFloat:
newConstArray[i].setDConst(unionArray[i].getI8Const()); break;
case EOpConvInt8ToDouble:
newConstArray[i].setDConst(unionArray[i].getI8Const()); break;
case EOpConvUint8ToFloat16:
newConstArray[i].setDConst(unionArray[i].getU8Const()); break;
case EOpConvUint8ToFloat:
newConstArray[i].setDConst(unionArray[i].getU8Const()); break;
case EOpConvUint8ToDouble:
newConstArray[i].setDConst(unionArray[i].getU8Const()); break;
case EOpConvInt16ToInt8:
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getI16Const())); break;
case EOpConvInt16ToInt:
newConstArray[i].setIConst(unionArray[i].getI16Const()); break;
case EOpConvInt16ToInt64:
newConstArray[i].setI64Const(unionArray[i].getI16Const()); break;
case EOpConvInt16ToUint8:
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getI16Const())); break;
case EOpConvInt16ToUint16:
newConstArray[i].setU16Const(unionArray[i].getI16Const()); break;
case EOpConvInt16ToUint:
newConstArray[i].setUConst(unionArray[i].getI16Const()); break;
case EOpConvInt16ToUint64:
newConstArray[i].setU64Const(unionArray[i].getI16Const()); break;
case EOpConvUint16ToInt8:
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getU16Const())); break;
case EOpConvUint16ToInt16:
newConstArray[i].setI16Const(unionArray[i].getU16Const()); break;
case EOpConvUint16ToInt:
newConstArray[i].setIConst(unionArray[i].getU16Const()); break;
case EOpConvUint16ToInt64:
newConstArray[i].setI64Const(unionArray[i].getU16Const()); break;
case EOpConvUint16ToUint8:
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getU16Const())); break;
case EOpConvUint16ToUint:
newConstArray[i].setUConst(unionArray[i].getU16Const()); break;
case EOpConvUint16ToUint64:
newConstArray[i].setU64Const(unionArray[i].getU16Const()); break;
case EOpConvInt16ToFloat16:
newConstArray[i].setDConst(unionArray[i].getI16Const()); break;
case EOpConvInt16ToFloat:
newConstArray[i].setDConst(unionArray[i].getI16Const()); break;
case EOpConvInt16ToDouble:
newConstArray[i].setDConst(unionArray[i].getI16Const()); break;
case EOpConvUint16ToFloat16:
newConstArray[i].setDConst(unionArray[i].getU16Const()); break;
case EOpConvUint16ToFloat:
newConstArray[i].setDConst(unionArray[i].getU16Const()); break;
case EOpConvUint16ToDouble:
newConstArray[i].setDConst(unionArray[i].getU16Const()); break;
case EOpConvIntToInt8:
newConstArray[i].setI8Const((signed char)unionArray[i].getIConst()); break;
case EOpConvIntToInt16:
newConstArray[i].setI16Const((signed short)unionArray[i].getIConst()); break;
case EOpConvIntToInt64:
newConstArray[i].setI64Const(unionArray[i].getIConst()); break;
case EOpConvIntToUint8:
newConstArray[i].setU8Const((unsigned char)unionArray[i].getIConst()); break;
case EOpConvIntToUint16:
newConstArray[i].setU16Const((unsigned char)unionArray[i].getIConst()); break;
case EOpConvIntToUint64:
newConstArray[i].setU64Const(unionArray[i].getIConst()); break;
case EOpConvUintToInt8:
newConstArray[i].setI8Const((signed char)unionArray[i].getUConst()); break;
case EOpConvUintToInt16:
newConstArray[i].setI16Const((signed short)unionArray[i].getUConst()); break;
case EOpConvUintToInt64:
newConstArray[i].setI64Const(unionArray[i].getUConst()); break;
case EOpConvUintToUint8:
newConstArray[i].setU8Const((unsigned char)unionArray[i].getUConst()); break;
case EOpConvUintToUint16:
newConstArray[i].setU16Const((unsigned short)unionArray[i].getUConst()); break;
case EOpConvUintToUint64:
newConstArray[i].setU64Const(unionArray[i].getUConst()); break;
case EOpConvIntToFloat16:
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
case EOpConvUintToFloat16:
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
case EOpConvInt64ToInt8:
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getI64Const())); break;
case EOpConvInt64ToInt16:
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getI64Const())); break;
case EOpConvInt64ToInt:
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getI64Const())); break;
case EOpConvInt64ToUint8:
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getI64Const())); break;
case EOpConvInt64ToUint16:
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getI64Const())); break;
case EOpConvInt64ToUint:
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getI64Const())); break;
case EOpConvInt64ToUint64:
newConstArray[i].setU64Const(unionArray[i].getI64Const()); break;
case EOpConvUint64ToInt8:
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getU64Const())); break;
case EOpConvUint64ToInt16:
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getU64Const())); break;
case EOpConvUint64ToInt:
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getU64Const())); break;
case EOpConvUint64ToInt64:
newConstArray[i].setI64Const(unionArray[i].getU64Const()); break;
case EOpConvUint64ToUint8:
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getU64Const())); break;
case EOpConvUint64ToUint16:
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getU64Const())); break;
case EOpConvUint64ToUint:
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getU64Const())); break;
case EOpConvInt64ToFloat16:
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getI64Const())); break;
case EOpConvInt64ToFloat:
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getI64Const())); break;
case EOpConvInt64ToDouble:
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getI64Const())); break;
case EOpConvUint64ToFloat16:
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getU64Const())); break;
case EOpConvUint64ToFloat:
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getU64Const())); break;
case EOpConvUint64ToDouble:
newConstArray[i].setDConst(static_cast<double>(unionArray[i].getU64Const())); break;
case EOpConvFloat16ToInt8:
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
case EOpConvFloat16ToInt16:
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
case EOpConvFloat16ToInt:
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
case EOpConvFloat16ToInt64:
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
case EOpConvFloat16ToUint8:
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
case EOpConvFloat16ToUint16:
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
case EOpConvFloat16ToUint:
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
case EOpConvFloat16ToUint64:
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
case EOpConvFloat16ToFloat:
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
case EOpConvFloat16ToDouble:
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
case EOpConvFloatToInt8:
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
case EOpConvFloatToInt16:
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
case EOpConvFloatToInt64:
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
case EOpConvFloatToUint8:
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
case EOpConvFloatToUint16:
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
case EOpConvFloatToUint64:
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
case EOpConvFloatToFloat16:
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
case EOpConvDoubleToInt8:
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
case EOpConvDoubleToInt16:
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
case EOpConvDoubleToInt64:
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
case EOpConvDoubleToUint8:
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
case EOpConvDoubleToUint16:
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
case EOpConvDoubleToUint64:
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
case EOpConvDoubleToFloat16:
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
case EOpConvPtrToUint64:
case EOpConvUint64ToPtr:
case EOpConstructReference:
@ -1009,6 +914,12 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
objectSize = std::max(children[0]->getAsTyped()->getType().getVectorSize(),
children[2]->getAsTyped()->getType().getVectorSize());
break;
case EOpMul:
{
TIntermConstantUnion* left = children[0]->getAsConstantUnion();
TIntermConstantUnion* right = children[1]->getAsConstantUnion();
return left->fold(EOpMul, right);
}
default:
return aggrNode;
}
@ -1048,6 +959,9 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
case EOpMin:
switch(children[0]->getAsTyped()->getBasicType()) {
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
case EbtFloat:
case EbtDouble:
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
@ -1082,6 +996,9 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
case EOpMax:
switch(children[0]->getAsTyped()->getBasicType()) {
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
case EbtFloat:
case EbtDouble:
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
@ -1116,6 +1033,9 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
case EOpClamp:
switch(children[0]->getAsTyped()->getBasicType()) {
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
case EbtFloat:
case EbtDouble:
newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),
@ -1223,6 +1143,9 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
break;
}
case EOpDot:
if (!children[0]->getAsTyped()->isFloatingDomain()) {
return aggrNode;
}
newConstArray[0].setDConst(childConstUnions[0].dot(childConstUnions[1]));
break;
case EOpCross:

File diff suppressed because it is too large Load diff

View file

@ -306,4 +306,35 @@ void TIntermSwitch::traverse(TIntermTraverser* it)
it->visitSwitch(EvPostVisit, this);
}
//
// Traverse a variable declaration.
//
void TIntermVariableDecl::traverse(TIntermTraverser *it)
{
bool visit = true;
if (it->preVisit)
visit = it->visitVariableDecl(EvPreVisit, this);
if (visit) {
it->incrementDepth(this);
if (it->rightToLeft) {
if (it->includeDeclSymbol)
declSymbol->traverse(it);
if (initNode)
initNode->traverse(it);
}
else {
if (initNode)
initNode->traverse(it);
if (it->includeDeclSymbol)
declSymbol->traverse(it);
}
it->decrementDepth();
}
if (visit && it->postVisit)
it->visitVariableDecl(EvPostVisit, this);
}
} // end namespace glslang

View file

@ -46,6 +46,7 @@
#include "propagateNoContraction.h"
#include <cfloat>
#include <limits>
#include <utility>
#include <tuple>
@ -65,10 +66,10 @@ namespace glslang {
// Returns the added node.
//
TIntermSymbol* TIntermediate::addSymbol(long long id, const TString& name, const TType& type, const TConstUnionArray& constArray,
TIntermSymbol* TIntermediate::addSymbol(long long id, const TString& name, const TString& mangledName, const TType& type, const TConstUnionArray& constArray,
TIntermTyped* constSubtree, const TSourceLoc& loc)
{
TIntermSymbol* node = new TIntermSymbol(id, name, type);
TIntermSymbol* node = new TIntermSymbol(id, name, getStage(), type, &mangledName);
node->setLoc(loc);
node->setConstArray(constArray);
node->setConstSubtree(constSubtree);
@ -80,6 +81,7 @@ TIntermSymbol* TIntermediate::addSymbol(const TIntermSymbol& intermSymbol)
{
return addSymbol(intermSymbol.getId(),
intermSymbol.getName(),
intermSymbol.getMangledName(),
intermSymbol.getType(),
intermSymbol.getConstArray(),
intermSymbol.getConstSubtree(),
@ -96,14 +98,14 @@ TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable)
TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, const TSourceLoc& loc)
{
return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), variable.getConstArray(), variable.getConstSubtree(), loc);
return addSymbol(variable.getUniqueId(), variable.getName(), variable.getMangledName(), variable.getType(), variable.getConstArray(), variable.getConstSubtree(), loc);
}
TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc)
{
TConstUnionArray unionArray; // just a null constant
return addSymbol(0, "", type, unionArray, nullptr, loc);
return addSymbol(0, "", "", type, unionArray, nullptr, loc);
}
//
@ -116,7 +118,8 @@ TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc)
{
// No operations work on blocks
if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock ||
left->getType().getBasicType() == EbtString || right->getType().getBasicType() == EbtString)
return nullptr;
// Convert "reference +/- int" and "reference - reference" to integer math
@ -163,8 +166,8 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64));
right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));
left = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, left, TType(EbtInt64));
right = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, right, TType(EbtInt64));
left = addBuiltInFunctionCall(loc, EOpConvNumeric, true, left, TType(EbtInt64));
right = addBuiltInFunctionCall(loc, EOpConvNumeric, true, right, TType(EbtInt64));
left = addBinaryMath(EOpSub, left, right, loc);
@ -397,6 +400,9 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
case EOpConstructUint64: newType = EbtUint64; break;
case EOpConstructDouble: newType = EbtDouble; break;
case EOpConstructFloat16: newType = EbtFloat16; break;
case EOpConstructBFloat16: newType = EbtBFloat16; break;
case EOpConstructFloatE4M3: newType = EbtFloatE4M3; break;
case EOpConstructFloatE5M2: newType = EbtFloatE5M2; break;
default: break; // some compilers want this
}
@ -426,7 +432,10 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
case EOpConstructBool:
case EOpConstructFloat:
case EOpConstructDouble:
case EOpConstructFloat16: {
case EOpConstructFloat16:
case EOpConstructBFloat16:
case EOpConstructFloatE5M2:
case EOpConstructFloatE4M3: {
TIntermUnary* unary_node = child->getAsUnaryNode();
if (unary_node != nullptr)
unary_node->updatePrecision();
@ -567,222 +576,18 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const
bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& newOp) const
{
switch (dst) {
case EbtDouble:
switch (src) {
case EbtUint: newOp = EOpConvUintToDouble; break;
case EbtBool: newOp = EOpConvBoolToDouble; break;
case EbtFloat: newOp = EOpConvFloatToDouble; break;
case EbtInt: newOp = EOpConvIntToDouble; break;
case EbtInt8: newOp = EOpConvInt8ToDouble; break;
case EbtUint8: newOp = EOpConvUint8ToDouble; break;
case EbtInt16: newOp = EOpConvInt16ToDouble; break;
case EbtUint16: newOp = EOpConvUint16ToDouble; break;
case EbtFloat16: newOp = EOpConvFloat16ToDouble; break;
case EbtInt64: newOp = EOpConvInt64ToDouble; break;
case EbtUint64: newOp = EOpConvUint64ToDouble; break;
default:
return false;
}
break;
case EbtFloat:
switch (src) {
case EbtInt: newOp = EOpConvIntToFloat; break;
case EbtUint: newOp = EOpConvUintToFloat; break;
case EbtBool: newOp = EOpConvBoolToFloat; break;
case EbtDouble: newOp = EOpConvDoubleToFloat; break;
case EbtInt8: newOp = EOpConvInt8ToFloat; break;
case EbtUint8: newOp = EOpConvUint8ToFloat; break;
case EbtInt16: newOp = EOpConvInt16ToFloat; break;
case EbtUint16: newOp = EOpConvUint16ToFloat; break;
case EbtFloat16: newOp = EOpConvFloat16ToFloat; break;
case EbtInt64: newOp = EOpConvInt64ToFloat; break;
case EbtUint64: newOp = EOpConvUint64ToFloat; break;
default:
return false;
}
break;
case EbtFloat16:
switch (src) {
case EbtInt8: newOp = EOpConvInt8ToFloat16; break;
case EbtUint8: newOp = EOpConvUint8ToFloat16; break;
case EbtInt16: newOp = EOpConvInt16ToFloat16; break;
case EbtUint16: newOp = EOpConvUint16ToFloat16; break;
case EbtInt: newOp = EOpConvIntToFloat16; break;
case EbtUint: newOp = EOpConvUintToFloat16; break;
case EbtBool: newOp = EOpConvBoolToFloat16; break;
case EbtFloat: newOp = EOpConvFloatToFloat16; break;
case EbtDouble: newOp = EOpConvDoubleToFloat16; break;
case EbtInt64: newOp = EOpConvInt64ToFloat16; break;
case EbtUint64: newOp = EOpConvUint64ToFloat16; break;
default:
return false;
}
break;
case EbtBool:
switch (src) {
case EbtInt: newOp = EOpConvIntToBool; break;
case EbtUint: newOp = EOpConvUintToBool; break;
case EbtFloat: newOp = EOpConvFloatToBool; break;
case EbtDouble: newOp = EOpConvDoubleToBool; break;
case EbtInt8: newOp = EOpConvInt8ToBool; break;
case EbtUint8: newOp = EOpConvUint8ToBool; break;
case EbtInt16: newOp = EOpConvInt16ToBool; break;
case EbtUint16: newOp = EOpConvUint16ToBool; break;
case EbtFloat16: newOp = EOpConvFloat16ToBool; break;
case EbtInt64: newOp = EOpConvInt64ToBool; break;
case EbtUint64: newOp = EOpConvUint64ToBool; break;
default:
return false;
}
break;
case EbtInt8:
switch (src) {
case EbtUint8: newOp = EOpConvUint8ToInt8; break;
case EbtInt16: newOp = EOpConvInt16ToInt8; break;
case EbtUint16: newOp = EOpConvUint16ToInt8; break;
case EbtInt: newOp = EOpConvIntToInt8; break;
case EbtUint: newOp = EOpConvUintToInt8; break;
case EbtInt64: newOp = EOpConvInt64ToInt8; break;
case EbtUint64: newOp = EOpConvUint64ToInt8; break;
case EbtBool: newOp = EOpConvBoolToInt8; break;
case EbtFloat: newOp = EOpConvFloatToInt8; break;
case EbtDouble: newOp = EOpConvDoubleToInt8; break;
case EbtFloat16: newOp = EOpConvFloat16ToInt8; break;
default:
return false;
}
break;
case EbtUint8:
switch (src) {
case EbtInt8: newOp = EOpConvInt8ToUint8; break;
case EbtInt16: newOp = EOpConvInt16ToUint8; break;
case EbtUint16: newOp = EOpConvUint16ToUint8; break;
case EbtInt: newOp = EOpConvIntToUint8; break;
case EbtUint: newOp = EOpConvUintToUint8; break;
case EbtInt64: newOp = EOpConvInt64ToUint8; break;
case EbtUint64: newOp = EOpConvUint64ToUint8; break;
case EbtBool: newOp = EOpConvBoolToUint8; break;
case EbtFloat: newOp = EOpConvFloatToUint8; break;
case EbtDouble: newOp = EOpConvDoubleToUint8; break;
case EbtFloat16: newOp = EOpConvFloat16ToUint8; break;
default:
return false;
}
break;
case EbtInt16:
switch (src) {
case EbtUint8: newOp = EOpConvUint8ToInt16; break;
case EbtInt8: newOp = EOpConvInt8ToInt16; break;
case EbtUint16: newOp = EOpConvUint16ToInt16; break;
case EbtInt: newOp = EOpConvIntToInt16; break;
case EbtUint: newOp = EOpConvUintToInt16; break;
case EbtInt64: newOp = EOpConvInt64ToInt16; break;
case EbtUint64: newOp = EOpConvUint64ToInt16; break;
case EbtBool: newOp = EOpConvBoolToInt16; break;
case EbtFloat: newOp = EOpConvFloatToInt16; break;
case EbtDouble: newOp = EOpConvDoubleToInt16; break;
case EbtFloat16: newOp = EOpConvFloat16ToInt16; break;
default:
return false;
}
break;
case EbtUint16:
switch (src) {
case EbtInt8: newOp = EOpConvInt8ToUint16; break;
case EbtUint8: newOp = EOpConvUint8ToUint16; break;
case EbtInt16: newOp = EOpConvInt16ToUint16; break;
case EbtInt: newOp = EOpConvIntToUint16; break;
case EbtUint: newOp = EOpConvUintToUint16; break;
case EbtInt64: newOp = EOpConvInt64ToUint16; break;
case EbtUint64: newOp = EOpConvUint64ToUint16; break;
case EbtBool: newOp = EOpConvBoolToUint16; break;
case EbtFloat: newOp = EOpConvFloatToUint16; break;
case EbtDouble: newOp = EOpConvDoubleToUint16; break;
case EbtFloat16: newOp = EOpConvFloat16ToUint16; break;
default:
return false;
}
break;
case EbtInt:
switch (src) {
case EbtUint: newOp = EOpConvUintToInt; break;
case EbtBool: newOp = EOpConvBoolToInt; break;
case EbtFloat: newOp = EOpConvFloatToInt; break;
case EbtInt8: newOp = EOpConvInt8ToInt; break;
case EbtUint8: newOp = EOpConvUint8ToInt; break;
case EbtInt16: newOp = EOpConvInt16ToInt; break;
case EbtUint16: newOp = EOpConvUint16ToInt; break;
case EbtDouble: newOp = EOpConvDoubleToInt; break;
case EbtFloat16: newOp = EOpConvFloat16ToInt; break;
case EbtInt64: newOp = EOpConvInt64ToInt; break;
case EbtUint64: newOp = EOpConvUint64ToInt; break;
default:
return false;
}
break;
case EbtUint:
switch (src) {
case EbtInt: newOp = EOpConvIntToUint; break;
case EbtBool: newOp = EOpConvBoolToUint; break;
case EbtFloat: newOp = EOpConvFloatToUint; break;
case EbtInt8: newOp = EOpConvInt8ToUint; break;
case EbtUint8: newOp = EOpConvUint8ToUint; break;
case EbtInt16: newOp = EOpConvInt16ToUint; break;
case EbtUint16: newOp = EOpConvUint16ToUint; break;
case EbtDouble: newOp = EOpConvDoubleToUint; break;
case EbtFloat16: newOp = EOpConvFloat16ToUint; break;
case EbtInt64: newOp = EOpConvInt64ToUint; break;
case EbtUint64: newOp = EOpConvUint64ToUint; break;
// For bindless texture type conversion, add a dummy convert op, just
// to generate a new TIntermTyped
// uvec2(any sampler type)
// uvec2(any image type)
case EbtSampler: newOp = EOpConvIntToUint; break;
default:
return false;
}
break;
case EbtInt64:
switch (src) {
case EbtInt8: newOp = EOpConvInt8ToInt64; break;
case EbtUint8: newOp = EOpConvUint8ToInt64; break;
case EbtInt16: newOp = EOpConvInt16ToInt64; break;
case EbtUint16: newOp = EOpConvUint16ToInt64; break;
case EbtInt: newOp = EOpConvIntToInt64; break;
case EbtUint: newOp = EOpConvUintToInt64; break;
case EbtBool: newOp = EOpConvBoolToInt64; break;
case EbtFloat: newOp = EOpConvFloatToInt64; break;
case EbtDouble: newOp = EOpConvDoubleToInt64; break;
case EbtFloat16: newOp = EOpConvFloat16ToInt64; break;
case EbtUint64: newOp = EOpConvUint64ToInt64; break;
default:
return false;
}
break;
case EbtUint64:
switch (src) {
case EbtInt8: newOp = EOpConvInt8ToUint64; break;
case EbtUint8: newOp = EOpConvUint8ToUint64; break;
case EbtInt16: newOp = EOpConvInt16ToUint64; break;
case EbtUint16: newOp = EOpConvUint16ToUint64; break;
case EbtInt: newOp = EOpConvIntToUint64; break;
case EbtUint: newOp = EOpConvUintToUint64; break;
case EbtBool: newOp = EOpConvBoolToUint64; break;
case EbtFloat: newOp = EOpConvFloatToUint64; break;
case EbtDouble: newOp = EOpConvDoubleToUint64; break;
case EbtFloat16: newOp = EOpConvFloat16ToUint64; break;
case EbtInt64: newOp = EOpConvInt64ToUint64; break;
default:
return false;
}
break;
default:
// (bfloat16_t,fp8) <-> bool not supported
if (((src == EbtBFloat16 || src == EbtFloatE5M2 || src == EbtFloatE4M3) && dst == EbtBool) ||
((dst == EbtBFloat16 || dst == EbtFloatE5M2 || dst == EbtFloatE4M3) && src == EbtBool)) {
return false;
}
return true;
if ((isTypeInt(dst) || isTypeFloat(dst) || dst == EbtBool) &&
(isTypeInt(src) || isTypeFloat(src) || src == EbtBool)) {
newOp = EOpConvNumeric;
return true;
}
return false;
}
// This is 'mechanism' here, it does any conversion told.
@ -804,11 +609,15 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped
node->getBasicType() == EbtInt || node->getBasicType() == EbtUint ||
node->getBasicType() == EbtInt64 || node->getBasicType() == EbtUint64);
bool convertToFloatTypes = (convertTo == EbtFloat16 || convertTo == EbtFloat || convertTo == EbtDouble);
bool convertToFloatTypes = (convertTo == EbtFloat16 || convertTo == EbtBFloat16 || convertTo == EbtFloat || convertTo == EbtDouble ||
convertTo == EbtFloatE5M2 || convertTo == EbtFloatE4M3);
bool convertFromFloatTypes = (node->getBasicType() == EbtFloat16 ||
node->getBasicType() == EbtBFloat16 ||
node->getBasicType() == EbtFloat ||
node->getBasicType() == EbtDouble);
node->getBasicType() == EbtDouble ||
node->getBasicType() == EbtFloatE5M2 ||
node->getBasicType() == EbtFloatE4M3);
if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) ||
((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes)) {
@ -1031,7 +840,17 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
// Reject implicit conversions to cooperative matrix types
if (node->getType().isCoopMat() &&
op != EOpConstructCooperativeMatrixNV &&
op != EOpConstructCooperativeMatrixKHR)
op != EOpConstructCooperativeMatrixKHR &&
op != glslang::EOpCompositeConstructCoopMatQCOM)
return nullptr;
if (node->getType().isTensorLayoutNV() ||
node->getType().isTensorViewNV())
return nullptr;
// Reject implicit conversions to cooperative vector types
if (node->getType().isCoopVecNV() &&
op != EOpConstructCooperativeVectorNV)
return nullptr;
// Note: callers are responsible for other aspects of shape,
@ -1047,12 +866,16 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EOpConstructUint:
case EOpConstructDouble:
case EOpConstructFloat16:
case EOpConstructBFloat16:
case EOpConstructFloatE5M2:
case EOpConstructFloatE4M3:
case EOpConstructInt8:
case EOpConstructUint8:
case EOpConstructInt16:
case EOpConstructUint16:
case EOpConstructInt64:
case EOpConstructUint64:
case EOpConstructSaturated:
break;
//
@ -1101,6 +924,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EOpConstructStruct:
case EOpConstructCooperativeMatrixNV:
case EOpConstructCooperativeMatrixKHR:
case EOpConstructCooperativeVectorNV:
if (type.isReference() || node->getType().isReference()) {
// types must match to assign a reference
@ -1152,6 +976,11 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
// changing language sementics on the fly by asking what extensions are in use
// - at the time of this writing (14-Aug-2020), no test results are changed by this.
switch (op) {
case EOpConstructBFloat16:
case EOpConstructFloatE5M2:
case EOpConstructFloatE4M3:
canPromoteConstant = true;
break;
case EOpConstructFloat16:
canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16);
@ -1454,6 +1283,9 @@ bool TIntermediate::isFPPromotion(TBasicType from, TBasicType to) const
// floating-point promotions
if (to == EbtDouble) {
switch(from) {
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
case EbtFloat16:
case EbtFloat:
return true;
@ -1546,7 +1378,7 @@ bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const
bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const
{
if (to == EbtFloat && from == EbtFloat16) {
if (to == EbtFloat && (from == EbtFloat16 || from == EbtBFloat16 || from == EbtFloatE5M2 || from == EbtFloatE4M3)) {
return true;
} else {
return false;
@ -1694,10 +1526,19 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EbtInt16:
case EbtUint16:
return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) &&
numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
(numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types) ||
numericFeatures.contains(TNumericFeatures::gpu_shader_int16));
case EbtFloat16:
return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) &&
numericFeatures.contains(TNumericFeatures::gpu_shader_half_float);
(numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types) ||
numericFeatures.contains(TNumericFeatures::gpu_shader_half_float));
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
return true;
case EbtInt8:
case EbtUint8:
return numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
default:
return false;
}
@ -1710,22 +1551,37 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
return getSource() == EShSourceHlsl;
case EbtInt16:
case EbtUint16:
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16) ||
numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
case EbtFloat16:
return numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) ||
numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types) ||
getSource() == EShSourceHlsl;
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
return true;
case EbtInt8:
case EbtUint8:
return numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
default:
return false;
}
case EbtUint:
switch (from) {
case EbtInt:
return version >= 400 || getSource() == EShSourceHlsl || IsRequestedExtension(E_GL_ARB_gpu_shader5);
return version >= 400 || getSource() == EShSourceHlsl ||
IsRequestedExtension(E_GL_ARB_gpu_shader5) ||
numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
case EbtBool:
return getSource() == EShSourceHlsl;
case EbtInt16:
case EbtUint16:
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16) ||
numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
case EbtInt8:
case EbtUint8:
return numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
default:
return false;
}
@ -1734,7 +1590,10 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EbtBool:
return getSource() == EShSourceHlsl;
case EbtInt16:
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16) ||
numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
case EbtInt8:
return numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
default:
return false;
}
@ -1746,7 +1605,11 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
return true;
case EbtInt16:
case EbtUint16:
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16) ||
numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
case EbtInt8:
case EbtUint8:
return numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
default:
return false;
}
@ -1754,8 +1617,11 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
switch (from) {
case EbtInt:
return true;
case EbtInt8:
return numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
case EbtInt16:
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16) ||
numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types);
default:
return false;
}
@ -1764,6 +1630,18 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EbtInt16:
case EbtUint16:
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
case EbtFloatE5M2:
case EbtFloatE4M3:
return true;
default:
break;
}
return false;
case EbtBFloat16:
switch (from) {
case EbtFloatE5M2:
case EbtFloatE4M3:
return true;
default:
break;
}
@ -1922,6 +1800,10 @@ std::tuple<TBasicType, TBasicType> TIntermediate::getConversionDestinationType(T
(type1 == EbtFloat16 && canImplicitlyPromote(type0, EbtFloat16, op)) ) {
res0 = EbtFloat16;
res1 = EbtFloat16;
} else if ((type0 == EbtBFloat16 && canImplicitlyPromote(type1, EbtBFloat16, op)) ||
(type1 == EbtBFloat16 && canImplicitlyPromote(type0, EbtBFloat16, op)) ) {
res0 = EbtBFloat16;
res1 = EbtBFloat16;
} else if (isTypeInt(type0) && isTypeInt(type1) &&
(canImplicitlyPromote(type0, type1, op) || canImplicitlyPromote(type1, type0, op))) {
if ((isTypeSignedInt(type0) && isTypeSignedInt(type1)) ||
@ -1977,6 +1859,9 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
if (type.isCoopMatKHR())
return EOpConstructCooperativeMatrixKHR;
if (type.isCoopVecNV())
return EOpConstructCooperativeVectorNV;
switch (type.getBasicType()) {
case EbtStruct:
op = EOpConstructStruct;
@ -2215,6 +2100,33 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
}
}
break;
case EbtBFloat16:
switch (type.getVectorSize()) {
case 1: op = EOpConstructBFloat16; break;
case 2: op = EOpConstructBF16Vec2; break;
case 3: op = EOpConstructBF16Vec3; break;
case 4: op = EOpConstructBF16Vec4; break;
default: break; // some compilers want this
}
break;
case EbtFloatE5M2:
switch (type.getVectorSize()) {
case 1: op = EOpConstructFloatE5M2; break;
case 2: op = EOpConstructFloatE5M2Vec2; break;
case 3: op = EOpConstructFloatE5M2Vec3; break;
case 4: op = EOpConstructFloatE5M2Vec4; break;
default: break; // some compilers want this
}
break;
case EbtFloatE4M3:
switch (type.getVectorSize()) {
case 1: op = EOpConstructFloatE4M3; break;
case 2: op = EOpConstructFloatE4M3Vec2; break;
case 3: op = EOpConstructFloatE4M3Vec3; break;
case 4: op = EOpConstructFloatE4M3Vec4; break;
default: break; // some compilers want this
}
break;
case EbtInt8:
switch(type.getVectorSize()) {
case 1: op = EOpConstructInt8; break;
@ -2471,7 +2383,8 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
trueBlock = std::get<0>(children);
falseBlock = std::get<1>(children);
if (trueBlock == nullptr || falseBlock == nullptr)
if (trueBlock == nullptr || falseBlock == nullptr ||
trueBlock->getBasicType() == EbtString || falseBlock->getBasicType() == EbtString)
return nullptr;
// Handle a vector condition as a mix
@ -2624,7 +2537,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc&
TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const
{
assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);
assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16 || baseType == EbtBFloat16 || baseType == EbtFloatE5M2 || baseType == EbtFloatE4M3);
if (isEsProfile() && (baseType == EbtFloat || baseType == EbtFloat16)) {
int exponent = 0;
@ -2739,7 +2652,7 @@ const TIntermTyped* TIntermediate::traverseLValueBase(const TIntermTyped* node,
//
// Create while and do-while loop nodes.
//
TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst,
TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermNode* test, TIntermTyped* terminal, bool testFirst,
const TSourceLoc& loc)
{
TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
@ -2751,7 +2664,7 @@ TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TInte
//
// Create a for-loop sequence.
//
TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test,
TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermNode* test,
TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TIntermLoop*& node)
{
node = new TIntermLoop(body, test, terminal, testFirst);
@ -2962,17 +2875,16 @@ bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const
// (However, some floating-point operations result in bool, like ">",
// so are handled later.)
if (node.getType().isFloatingDomain()) {
if (IsOpNumericConv(node.getOp()) &&
isTypeFloat(node.getType().getBasicType()) &&
isTypeFloat(node.getAsUnaryNode()->getOperand()->getAsTyped()->getType().getBasicType())) {
return true;
}
switch (node.getOp()) {
case EOpIndexDirect:
case EOpIndexIndirect:
case EOpIndexDirectStruct:
case EOpVectorSwizzle:
case EOpConvFloatToDouble:
case EOpConvDoubleToFloat:
case EOpConvFloat16ToFloat:
case EOpConvFloatToFloat16:
case EOpConvFloat16ToDouble:
case EOpConvDoubleToFloat16:
return true;
default:
return false;
@ -2987,6 +2899,15 @@ bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const
// So, for now, we can assume everything left is non-floating-point...
if (IsOpNumericConv(node.getOp())) {
TBasicType srcType = node.getAsUnaryNode()->getOperand()->getAsTyped()->getType().getBasicType();
TBasicType dstType = node.getType().getBasicType();
if ((isTypeInt(srcType) || srcType == EbtBool) &&
(isTypeInt(dstType) || dstType == EbtBool)) {
return true;
}
}
// Now check for integer/bool-based operations
switch (node.getOp()) {
@ -2996,98 +2917,6 @@ bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const
case EOpIndexDirectStruct:
case EOpVectorSwizzle:
// (u)int* -> bool
case EOpConvInt8ToBool:
case EOpConvInt16ToBool:
case EOpConvIntToBool:
case EOpConvInt64ToBool:
case EOpConvUint8ToBool:
case EOpConvUint16ToBool:
case EOpConvUintToBool:
case EOpConvUint64ToBool:
// bool -> (u)int*
case EOpConvBoolToInt8:
case EOpConvBoolToInt16:
case EOpConvBoolToInt:
case EOpConvBoolToInt64:
case EOpConvBoolToUint8:
case EOpConvBoolToUint16:
case EOpConvBoolToUint:
case EOpConvBoolToUint64:
// int8_t -> (u)int*
case EOpConvInt8ToInt16:
case EOpConvInt8ToInt:
case EOpConvInt8ToInt64:
case EOpConvInt8ToUint8:
case EOpConvInt8ToUint16:
case EOpConvInt8ToUint:
case EOpConvInt8ToUint64:
// int16_t -> (u)int*
case EOpConvInt16ToInt8:
case EOpConvInt16ToInt:
case EOpConvInt16ToInt64:
case EOpConvInt16ToUint8:
case EOpConvInt16ToUint16:
case EOpConvInt16ToUint:
case EOpConvInt16ToUint64:
// int32_t -> (u)int*
case EOpConvIntToInt8:
case EOpConvIntToInt16:
case EOpConvIntToInt64:
case EOpConvIntToUint8:
case EOpConvIntToUint16:
case EOpConvIntToUint:
case EOpConvIntToUint64:
// int64_t -> (u)int*
case EOpConvInt64ToInt8:
case EOpConvInt64ToInt16:
case EOpConvInt64ToInt:
case EOpConvInt64ToUint8:
case EOpConvInt64ToUint16:
case EOpConvInt64ToUint:
case EOpConvInt64ToUint64:
// uint8_t -> (u)int*
case EOpConvUint8ToInt8:
case EOpConvUint8ToInt16:
case EOpConvUint8ToInt:
case EOpConvUint8ToInt64:
case EOpConvUint8ToUint16:
case EOpConvUint8ToUint:
case EOpConvUint8ToUint64:
// uint16_t -> (u)int*
case EOpConvUint16ToInt8:
case EOpConvUint16ToInt16:
case EOpConvUint16ToInt:
case EOpConvUint16ToInt64:
case EOpConvUint16ToUint8:
case EOpConvUint16ToUint:
case EOpConvUint16ToUint64:
// uint32_t -> (u)int*
case EOpConvUintToInt8:
case EOpConvUintToInt16:
case EOpConvUintToInt:
case EOpConvUintToInt64:
case EOpConvUintToUint8:
case EOpConvUintToUint16:
case EOpConvUintToUint64:
// uint64_t -> (u)int*
case EOpConvUint64ToInt8:
case EOpConvUint64ToInt16:
case EOpConvUint64ToInt:
case EOpConvUint64ToInt64:
case EOpConvUint64ToUint8:
case EOpConvUint64ToUint16:
case EOpConvUint64ToUint:
// unary operations
case EOpNegative:
case EOpLogicalNot:
@ -3590,6 +3419,43 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
return false;
}
if (left->getType().isCoopVecNV() || right->getType().isCoopVecNV()) {
// Operations on two cooperative vectors must have identical types
if (left->getType().isCoopVecNV() && right->getType().isCoopVecNV() &&
left->getType() != right->getType()) {
return false;
}
switch (op) {
case EOpMul:
case EOpMulAssign:
// Use VectorTimesScalar if either operand is not a vector. Otherwise use Mul.
if (!left->getType().isCoopVecNV() || !right->getType().isCoopVecNV()) {
node.setOp(op == EOpMulAssign ? EOpVectorTimesScalarAssign : EOpVectorTimesScalar);
}
// In case of scalar*vector, take the result type from the vector.
if (right->getType().isCoopVecNV()) {
node.setType(right->getType());
}
return true;
case EOpLeftShift:
case EOpLeftShiftAssign:
case EOpRightShift:
case EOpRightShiftAssign:
case EOpAdd:
case EOpSub:
case EOpDiv:
case EOpAssign:
// These require both to be cooperative vectors
if (!left->getType().isCoopVecNV() || !right->getType().isCoopVecNV()) {
return false;
}
return true;
default:
break;
}
return false;
}
// Finish handling the case, for all ops, where both operands are scalars.
if (left->isScalar() && right->isScalar())
return true;
@ -3925,6 +3791,9 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
#define TO_ALL(Get) \
switch (promoteTo) { \
case EbtBFloat16: PROMOTE(setDConst, double, Get); break; \
case EbtFloatE5M2: PROMOTE(setDConst, double, Get); break; \
case EbtFloatE4M3: PROMOTE(setDConst, double, Get); break; \
case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
case EbtFloat: PROMOTE(setDConst, double, Get); break; \
case EbtDouble: PROMOTE(setDConst, double, Get); break; \
@ -3946,6 +3815,9 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtUint: TO_ALL(getUConst); break;
case EbtBool: TO_ALL(getBConst); break;
case EbtFloat16: TO_ALL(getDConst); break;
case EbtBFloat16: TO_ALL(getDConst); break;
case EbtFloatE5M2: TO_ALL(getDConst); break;
case EbtFloatE4M3: TO_ALL(getDConst); break;
case EbtDouble: TO_ALL(getDConst); break;
case EbtInt8: TO_ALL(getI8Const); break;
case EbtInt16: TO_ALL(getI16Const); break;
@ -4034,12 +3906,15 @@ void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TInterm
const char* TIntermediate::getResourceName(TResourceType res)
{
switch (res) {
case EResSampler: return "shift-sampler-binding";
case EResTexture: return "shift-texture-binding";
case EResImage: return "shift-image-binding";
case EResUbo: return "shift-UBO-binding";
case EResSsbo: return "shift-ssbo-binding";
case EResUav: return "shift-uav-binding";
case EResSampler: return "shift-sampler-binding";
case EResTexture: return "shift-texture-binding";
case EResImage: return "shift-image-binding";
case EResUbo: return "shift-ubo-binding";
case EResSsbo: return "shift-ssbo-binding";
case EResUav: return "shift-uav-binding";
case EResCombinedSampler: return "shift-combined-sampler-binding";
case EResAs: return "shift-as-binding";
case EResTensor: return nullptr;
default:
assert(0); // internal error: should only be called with valid resource types.
return nullptr;

View file

@ -59,8 +59,8 @@ namespace glslang {
class TLiveTraverser : public TIntermTraverser {
public:
TLiveTraverser(const TIntermediate& i, bool traverseAll = false,
bool preVisit = true, bool inVisit = false, bool postVisit = false) :
TIntermTraverser(preVisit, inVisit, postVisit),
bool preVisit = true, bool inVisit = false, bool postVisit = false, bool includeDeclSymbol = false) :
TIntermTraverser(preVisit, inVisit, postVisit, false, includeDeclSymbol),
intermediate(i), traverseAll(traverseAll)
{ }
@ -132,6 +132,47 @@ protected:
return true; // traverse the whole subtree
}
// To prune semantically dead paths in switch statements with constant expressions.
virtual bool visitSwitch(TVisit /* visit */, TIntermSwitch* node)
{
if (traverseAll)
return true; // traverse all code
TIntermConstantUnion* constant = node->getCondition()->getAsConstantUnion();
if (constant) {
TConstUnion switchValue = constant->getConstArray()[0];
int liveBranch = -1;
const auto& body = node->getBody()->getSequence();
for (unsigned int i = 0; i < body.size(); ++i) {
if (body[i]->getAsBranchNode()) {
if (body[i]->getAsBranchNode()->getFlowOp() == glslang::EOpCase) {
TConstUnion caseValue =
body[i]->getAsBranchNode()->getExpression()->getAsConstantUnion()->getConstArray()[0];
if (switchValue == caseValue.getIConst()) {
liveBranch = (int)i;
break;
}
} else if (body[i]->getAsBranchNode()->getFlowOp() == glslang::EOpDefault) {
liveBranch = (int)i;
}
}
}
if (liveBranch != -1) {
for (int i = liveBranch; i < (int)body.size(); ++i) {
if (body[i]->getAsAggregate()) {
for (auto* inst : body[i]->getAsAggregate()->getSequence()) {
if (inst->getAsBranchNode() && (inst->getAsBranchNode()->getFlowOp() == glslang::EOpBreak))
return false; // found and traversed the live case(s)
inst->traverse(this);
}
}
}
}
return false; // finished traversing all cases
} else
return true; // traverse the whole subtree
}
// Track live functions as well as uniforms, so that we don't visit dead functions
// and only visit each function once.
void addFunctionCall(TIntermAggregate* call)

View file

@ -59,7 +59,7 @@ void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReaso
safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, args);
infoSink.info.prefix(prefix);
infoSink.info.location(loc, messages & EShMsgAbsolutePath);
infoSink.info.location(loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n";
if (prefix == EPrefixError) {
@ -171,6 +171,9 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
case EbtHitObjectNV:
message = "can't modify hitObjectNV";
break;
case EbtHitObjectEXT:
message = "can't modify hitObjectEXT";
break;
default:
break;
}
@ -279,7 +282,7 @@ void TParseContextBase::trackLinkage(TSymbol& symbol)
// Ensure index is in bounds, correct if necessary.
// Give an error if not.
void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index)
void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int64_t& index)
{
const auto sizeIsSpecializationExpression = [&type]() {
return type.containsSpecializationSize() &&
@ -305,6 +308,11 @@ void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int
error(loc, "", "[", "matrix index out of range '%d'", index);
index = type.getMatrixCols() - 1;
}
} else if (type.isCoopVecNV()) {
if (index >= type.computeNumComponents()) {
error(loc, "", "[", "cooperative vector index out of range '%d'", index);
index = type.computeNumComponents() - 1;
}
}
}
@ -419,7 +427,7 @@ const TFunction* TParseContextBase::selectFunction(
// to even be a potential match, number of arguments must be >= the number of
// fixed (non-default) parameters, and <= the total (including parameter with defaults).
if (call.getParamCount() < candidate.getFixedParamCount() ||
call.getParamCount() > candidate.getParamCount())
(call.getParamCount() > candidate.getParamCount() && !candidate.isVariadic()))
continue;
// see if arguments are convertible
@ -458,7 +466,8 @@ const TFunction* TParseContextBase::selectFunction(
const auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
// is call -> can2 better than call -> can1 for any parameter
bool hasBetterParam = false;
for (int param = 0; param < call.getParamCount(); ++param) {
const int paramCount = std::min({call.getParamCount(), can1.getParamCount(), can2.getParamCount()});
for (int param = 0; param < paramCount; ++param) {
if (better(*call[param].type, *can1[param].type, *can2[param].type)) {
hasBetterParam = true;
break;
@ -469,7 +478,8 @@ const TFunction* TParseContextBase::selectFunction(
const auto equivalentParams = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
// is call -> can2 equivalent to call -> can1 for all the call parameters?
for (int param = 0; param < call.getParamCount(); ++param) {
const int paramCount = std::min({call.getParamCount(), can1.getParamCount(), can2.getParamCount()});
for (int param = 0; param < paramCount; ++param) {
if (better(*call[param].type, *can1[param].type, *can2[param].type) ||
better(*call[param].type, *can2[param].type, *can1[param].type))
return false;
@ -477,6 +487,16 @@ const TFunction* TParseContextBase::selectFunction(
return true;
};
const auto enabled = [this](const TFunction& candidate) -> bool {
bool enabled = candidate.getNumExtensions() == 0;
for (int i = 0; i < candidate.getNumExtensions(); ++i) {
TExtensionBehavior behavior = getExtensionBehavior(candidate.getExtensions()[i]);
if (behavior == EBhEnable || behavior == EBhRequire)
enabled = true;
}
return enabled;
};
const TFunction* incumbent = viableCandidates.front();
for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) {
const TFunction& candidate = *(*it);
@ -492,7 +512,7 @@ const TFunction* TParseContextBase::selectFunction(
// In the case of default parameters, it may have an identical initial set, which is
// also ambiguous
if (betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate))
if ((betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate)) && enabled(candidate))
tie = true;
}

File diff suppressed because it is too large Load diff

View file

@ -115,7 +115,7 @@ public:
virtual void setLimits(const TBuiltInResource&) = 0;
void checkIndex(const TSourceLoc&, const TType&, int& index);
void checkIndex(const TSourceLoc&, const TType&, int64_t& index);
EShLanguage getLanguage() const { return language; }
void setScanContext(TScanContext* c) { scanContext = c; }
@ -381,10 +381,11 @@ public:
void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
void constantValueCheck(TIntermTyped* node, const char* token);
void integerCheck(const TIntermTyped* node, const char* token);
void arrayIndexCheck(const TIntermTyped* node, const char* token);
void globalCheck(const TSourceLoc&, const char* token);
bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&);
bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&);
void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&, const char *sizeType, const bool allowZero = false);
void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&, const char *sizeType, const bool isTypeParameter = false);
bool arrayQualifierError(const TSourceLoc&, const TQualifier&);
bool arrayError(const TSourceLoc&, const TType&);
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
@ -397,6 +398,8 @@ public:
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
void hitObjectEXTCheck(const TSourceLoc& loc, const TType& type, const TString& identifier);
void hitObjectNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
void memberQualifierCheck(glslang::TPublicType&);
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&, bool isMemberCheck = false, const TPublicType* publicType = nullptr);
@ -406,7 +409,7 @@ public:
void setDefaultPrecision(const TSourceLoc&, TPublicType&, TPrecisionQualifier);
int computeSamplerTypeIndex(TSampler&);
TPrecisionQualifier getDefaultPrecision(TPublicType&);
void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&, bool isCoopMat);
void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&, bool hasTypeParameter);
void parameterTypeCheck(const TSourceLoc&, TStorageQualifier qualifier, const TType& type);
bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&);
@ -424,7 +427,7 @@ public:
void inductiveLoopCheck(const TSourceLoc&, TIntermNode* init, TIntermLoop* loop);
void arrayLimitCheck(const TSourceLoc&, const TString&, int size);
void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature);
void coopMatTypeParametersCheck(const TSourceLoc&, const TPublicType&);
void typeParametersCheck(const TSourceLoc&, const TPublicType&);
void inductiveLoopBodyCheck(TIntermNode*, long long loopIndexId, TSymbolTable&);
void constantIndexExpressionCheck(TIntermNode*);
@ -449,8 +452,11 @@ public:
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
void makeVariadic(TFunction *F, const TSourceLoc &loc);
TParameter getParamWithDefault(const TPublicType& ty, TString* identifier, TIntermTyped* initializer,
const TSourceLoc& loc);
void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to);
void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = nullptr, TArraySizes* arraySizes = nullptr);
TIntermNode* declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = nullptr, TArraySizes* arraySizes = nullptr);
void blockStorageRemap(const TSourceLoc&, const TString*, TQualifier&);
void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
@ -508,6 +514,8 @@ protected:
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
void finish() override;
void handleCoopMat2FunctionCall(const TSourceLoc& loc, const TFunction* fnCandidate, TIntermTyped* result, TIntermNode* arguments);
void handleVector2CoopMatConversionCall(const TSourceLoc& loc, const TFunction* fnCandidate, TIntermTyped* &result, TIntermNode* arguments);
virtual const char* getGlobalUniformBlockName() const override;
virtual void finalizeGlobalUniformBlockLayout(TVariable&) override;

View file

@ -35,14 +35,21 @@
#include "../Include/Common.h"
#include "../Include/PoolAlloc.h"
// Mostly here for target that do not support threads such as WASI.
#ifdef DISABLE_THREAD_SUPPORT
#define THREAD_LOCAL
#else
#define THREAD_LOCAL thread_local
#endif
namespace glslang {
namespace {
thread_local TPoolAllocator* threadPoolAllocator = nullptr;
THREAD_LOCAL TPoolAllocator* threadPoolAllocator = nullptr;
TPoolAllocator* GetDefaultThreadPoolAllocator()
{
thread_local TPoolAllocator defaultAllocator;
THREAD_LOCAL TPoolAllocator defaultAllocator;
return &defaultAllocator;
}
} // anonymous namespace

View file

@ -43,7 +43,7 @@ namespace glslang {
// Code to recursively delete the intermediate tree.
//
struct TRemoveTraverser : TIntermTraverser {
TRemoveTraverser() : TIntermTraverser(false, false, true, false) {}
TRemoveTraverser() : TIntermTraverser(false, false, true, false, true) {}
virtual void visitSymbol(TIntermSymbol* node)
{
@ -103,6 +103,12 @@ struct TRemoveTraverser : TIntermTraverser {
return true;
}
virtual bool visitVariableDecl(TVisit /* visit */, TIntermVariableDecl* decl)
{
delete decl;
return true;
}
};
//

File diff suppressed because it is too large Load diff

View file

@ -53,7 +53,7 @@ public:
explicit TScanContext(TParseContextBase& pc) :
parseContext(pc),
afterType(false), afterStruct(false),
field(false), afterBuffer(false) { }
field(false), afterBuffer(false), inDeclaratorList(false), afterDeclarator(false), angleBracketDepth(0), squareBracketDepth(0), parenDepth(0) { }
virtual ~TScanContext() { }
static void fillInKeywordMap();
@ -82,6 +82,11 @@ protected:
bool afterStruct; // true if we've recognized the STRUCT keyword, so can only be looking for an identifier
bool field; // true if we're on a field, right after a '.'
bool afterBuffer; // true if we've recognized the BUFFER keyword
bool inDeclaratorList; // true if we detected we're in a declarator list like "float a, b;"
bool afterDeclarator; // true if we just saw an identifier after a type (potential declarator)
int angleBracketDepth; // track nesting level of < > to detect template parameters
int squareBracketDepth; // track nesting level of [ ] to detect array expressions
int parenDepth; // track nesting level of ( ) to detect function parameters
TSourceLoc loc;
TParserToken* parserToken;
TPpToken* ppToken;

View file

@ -82,7 +82,10 @@ namespace { // anonymous namespace for file-local functions and symbols
int NumberOfClients = 0;
// global initialization lock
#ifndef DISABLE_THREAD_SUPPORT
std::mutex init_lock;
#endif
using namespace glslang;
@ -294,18 +297,21 @@ 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,
bool InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int version, EProfile profile, const SpvVersion& spvVersion,
EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable,
TSymbolTable** symbolTables)
{
(*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]);
InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source,
infoSink, *symbolTables[language]);
if (!InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source,
infoSink, *symbolTables[language]))
return false;
builtInParseables.identifyBuiltIns(version, profile, spvVersion, language, *symbolTables[language]);
if (profile == EEsProfile && version >= 300)
(*symbolTables[language]).setNoBuiltInRedeclarations();
if (version == 110)
(*symbolTables[language]).setSeparateNameSpaces();
return true;
}
//
@ -314,6 +320,7 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi
//
bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
{
bool success = true;
std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
if (builtInParseables == nullptr)
@ -322,70 +329,70 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
builtInParseables->initialize(version, profile, spvVersion);
// do the common tables
InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangVertex, source,
success &= InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangVertex, source,
infoSink, *commonTable[EPcGeneral]);
if (profile == EEsProfile)
InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangFragment, source,
success &= InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangFragment, source,
infoSink, *commonTable[EPcFragment]);
// do the per-stage tables
// always have vertex and fragment
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangVertex, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangVertex, source,
infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source,
infoSink, commonTable, symbolTables);
// check for tessellation
if ((profile != EEsProfile && version >= 150) ||
(profile == EEsProfile && version >= 310)) {
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessControl, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessControl, source,
infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessEvaluation, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessEvaluation, source,
infoSink, commonTable, symbolTables);
}
// check for geometry
if ((profile != EEsProfile && version >= 150) ||
(profile == EEsProfile && version >= 310))
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source,
infoSink, commonTable, symbolTables);
// check for compute
if ((profile != EEsProfile && version >= 420) ||
(profile == EEsProfile && version >= 310))
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
infoSink, commonTable, symbolTables);
// check for ray tracing stages
if (profile != EEsProfile && version >= 450) {
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGen, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGen, source,
infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersect, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersect, source,
infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHit, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHit, source,
infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHit, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHit, source,
infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMiss, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMiss, source,
infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallable, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallable, source,
infoSink, commonTable, symbolTables);
}
// check for mesh
if ((profile != EEsProfile && version >= 450) ||
(profile == EEsProfile && version >= 320))
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMesh, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMesh, source,
infoSink, commonTable, symbolTables);
// check for task
if ((profile != EEsProfile && version >= 450) ||
(profile == EEsProfile && version >= 320))
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTask, source,
success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTask, source,
infoSink, commonTable, symbolTables);
return true;
return success;
}
bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable& symbolTable, int version,
@ -397,7 +404,8 @@ bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& inf
return false;
builtInParseables->initialize(*resources, version, profile, spvVersion, language);
InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, language, source, infoSink, symbolTable);
if (!InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, language, source, infoSink, symbolTable))
return false;
builtInParseables->identifyBuiltIns(version, profile, spvVersion, language, symbolTable, *resources);
return true;
@ -415,20 +423,24 @@ bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& inf
// 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)
bool SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
{
TInfoSink infoSink;
bool success;
// Make sure only one thread tries to do this at a time
#ifndef DISABLE_THREAD_SUPPORT
const std::lock_guard<std::mutex> lock(init_lock);
#endif
// See if it's already been done for this version/profile combination
int versionIndex = MapVersionToIndex(version);
int spvVersionIndex = MapSpvVersionToIndex(spvVersion);
int profileIndex = MapProfileToIndex(profile);
int sourceIndex = MapSourceToIndex(source);
if (CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][EPcGeneral])
return;
if (CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][EPcGeneral]) {
return true;
}
// Switch to a new pool
TPoolAllocator& previousAllocator = GetThreadPoolAllocator();
@ -444,7 +456,10 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
stageTables[stage] = new TSymbolTable;
// Generate the local symbol tables using the new pool
InitializeSymbolTables(infoSink, commonTable, stageTables, version, profile, spvVersion, source);
if (!InitializeSymbolTables(infoSink, commonTable, stageTables, version, profile, spvVersion, source)) {
success = false;
goto cleanup;
}
// Switch to the process-global pool
SetThreadPoolAllocator(PerProcessGPA);
@ -466,7 +481,9 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->readOnly();
}
}
success = true;
cleanup:
// Clean up the local tables before deleting the pool they used.
for (int precClass = 0; precClass < EPcCount; ++precClass)
delete commonTable[precClass];
@ -475,6 +492,8 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
delete builtInPoolAllocator;
SetThreadPoolAllocator(&previousAllocator);
return success;
}
// Function to Print all builtins
@ -788,7 +807,7 @@ bool ProcessDeferred(
// set version/profile to defaultVersion/defaultProfile regardless of the #version
// directive in the source code
bool forceDefaultVersionAndProfile,
int overrideVersion, // overrides version specified by #verison or default version
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.
@ -910,7 +929,9 @@ bool ProcessDeferred(
intermediate.addSourceText(strings[numPre + s], lengths[numPre + s]);
}
}
SetupBuiltinSymbolTable(version, profile, spvVersion, source);
if (!SetupBuiltinSymbolTable(version, profile, spvVersion, source)) {
return false;
}
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
[MapSpvVersionToIndex(spvVersion)]
@ -1311,17 +1332,14 @@ bool CompileDeferred(
//
int ShInitialize()
{
#ifndef DISABLE_THREAD_SUPPORT
const std::lock_guard<std::mutex> lock(init_lock);
#endif
++NumberOfClients;
if (PerProcessGPA == nullptr)
PerProcessGPA = new TPoolAllocator();
glslang::TScanContext::fillInKeywordMap();
#ifdef ENABLE_HLSL
glslang::HlslScanContext::fillInKeywordMap();
#endif
return 1;
}
@ -1371,7 +1389,9 @@ void ShDestruct(ShHandle handle)
//
int ShFinalize()
{
#ifndef DISABLE_THREAD_SUPPORT
const std::lock_guard<std::mutex> lock(init_lock);
#endif
--NumberOfClients;
assert(NumberOfClients >= 0);
if (NumberOfClients > 0)
@ -1408,11 +1428,6 @@ int ShFinalize()
PerProcessGPA = nullptr;
}
glslang::TScanContext::deleteKeywordMap();
#ifdef ENABLE_HLSL
glslang::HlslScanContext::deleteKeywordMap();
#endif
return 1;
}
@ -1717,6 +1732,10 @@ public:
virtual bool compile(TIntermNode*, int = 0, EProfile = ENoProfile) { return true; }
};
TIoMapper* GetGlslIoMapper() {
return static_cast<TIoMapper*>(new TGlslIoMapper());
}
TShader::TShader(EShLanguage s)
: stage(s), lengths(nullptr), stringNames(nullptr), preamble(""), overrideVersion(0)
{
@ -1849,6 +1868,9 @@ void TShader::setGlobalUniformBinding(unsigned int binding) { intermediate->setG
void TShader::setAtomicCounterBlockName(const char* name) { intermediate->setAtomicCounterBlockName(name); }
void TShader::setAtomicCounterBlockSet(unsigned int set) { intermediate->setAtomicCounterBlockSet(set); }
void TShader::addSourceText(const char* text, size_t len) { intermediate->addSourceText(text, len); }
void TShader::setSourceFile(const char* file) { intermediate->setSourceFile(file); }
#ifdef ENABLE_HLSL
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
@ -1957,6 +1979,14 @@ bool TProgram::link(EShMessages messages)
error = true;
}
if (messages & EShMsgAST) {
for (int s = 0; s < EShLangCount; ++s) {
if (intermediate[s] == nullptr)
continue;
intermediate[s]->output(*infoSink, true);
}
}
return ! error;
}
@ -2022,9 +2052,6 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
}
intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0);
if (messages & EShMsgAST)
intermediate[stage]->output(*infoSink, true);
return intermediate[stage]->getNumErrors() == 0;
}
@ -2033,7 +2060,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
//
// Return true if no errors.
//
bool TProgram::crossStageCheck(EShMessages) {
bool TProgram::crossStageCheck(EShMessages messages) {
// make temporary intermediates to hold the linkage symbols for each linking interface
// while we do the checks
@ -2048,9 +2075,27 @@ bool TProgram::crossStageCheck(EShMessages) {
activeStages.push_back(intermediate[s]);
}
class TFinalLinkTraverser : public TIntermTraverser {
public:
TFinalLinkTraverser() { }
virtual ~TFinalLinkTraverser() { }
virtual void visitSymbol(TIntermSymbol* symbol)
{
// Implicitly size arrays.
// If an unsized array is left as unsized, it effectively
// becomes run-time sized.
symbol->getWritableType().adoptImplicitArraySizes(false);
}
} finalLinkTraverser;
// no extra linking if there is only one stage
if (! (activeStages.size() > 1))
if (! (activeStages.size() > 1)) {
if (activeStages.size() == 1 && activeStages[0]->getTreeRoot()) {
activeStages[0]->getTreeRoot()->traverse(&finalLinkTraverser);
}
return true;
}
// setup temporary tree to hold unfirom objects from different stages
TIntermediate* firstIntermediate = activeStages.front();
@ -2072,6 +2117,12 @@ bool TProgram::crossStageCheck(EShMessages) {
}
error |= uniforms.getNumErrors() != 0;
// update implicit array sizes across shader stages
for (unsigned int i = 0; i < activeStages.size(); ++i) {
activeStages[i]->mergeImplicitArraySizes(*infoSink, uniforms);
activeStages[i]->getTreeRoot()->traverse(&finalLinkTraverser);
}
// copy final definition of global block back into each stage
for (unsigned int i = 0; i < activeStages.size(); ++i) {
// We only want to merge into already existing global uniform blocks.
@ -2084,8 +2135,15 @@ bool TProgram::crossStageCheck(EShMessages) {
// compare cross stage symbols for each stage boundary
for (unsigned int i = 1; i < activeStages.size(); ++i) {
activeStages[i - 1]->checkStageIO(*infoSink, *activeStages[i]);
error |= (activeStages[i - 1]->getNumErrors() != 0);
activeStages[i - 1]->checkStageIO(*infoSink, *activeStages[i], messages);
error |= (activeStages[i - 1]->getNumErrors() != 0 || activeStages[i]->getNumErrors() != 0);
}
// if requested, optimize cross stage IO
if (messages & EShMsgLinkTimeOptimization) {
for (unsigned int i = 1; i < activeStages.size(); ++i) {
activeStages[i - 1]->optimizeStageIO(*infoSink, *activeStages[i]);
}
}
return !error;
@ -2105,11 +2163,15 @@ const char* TProgram::getInfoDebugLog()
// Reflection implementation.
//
unsigned int TObjectReflection::layoutLocation() const { return type->getQualifier().layoutLocation; }
bool TProgram::buildReflection(int opts)
{
if (! linked || reflection != nullptr)
return false;
SetThreadPoolAllocator(pool);
int firstStage = EShLangVertex, lastStage = EShLangFragment;
if (opts & EShReflectionIntermediateIO) {
@ -2138,6 +2200,7 @@ bool TProgram::buildReflection(int opts)
}
unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); }
unsigned TProgram::getTileShadingRateQCOM(int dim) const { return reflection->getTileShadingRateQCOM(dim); }
int TProgram::getReflectionIndex(const char* name) const { return reflection->getIndex(name); }
int TProgram::getReflectionPipeIOIndex(const char* name, const bool inOrOut) const
{ return reflection->getPipeIOIndex(name, inOrOut); }
@ -2158,6 +2221,12 @@ int TProgram::getNumAtomicCounters() const { return r
const TObjectReflection& TProgram::getAtomicCounter(int index) const { return reflection->getAtomicCounter(index); }
void TProgram::dumpReflection() { if (reflection != nullptr) reflection->dump(); }
TIoMapResolver* TProgram::getGlslIoResolver(EShLanguage stage) {
auto *intermediate = getIntermediate(stage);
if (!intermediate)
return NULL;
return static_cast<TIoMapResolver*>(new TDefaultGlslIoResolver(*intermediate));
}
//
// I/O mapping implementation.
//
@ -2165,6 +2234,9 @@ bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper)
{
if (! linked)
return false;
SetThreadPoolAllocator(pool);
TIoMapper* ioMapper = nullptr;
TIoMapper defaultIOMapper;
if (pIoMapper == nullptr)

View file

@ -55,11 +55,16 @@ namespace glslang {
//
void TType::buildMangledName(TString& mangledName) const
{
if (isMatrix())
if (isTensorARM())
mangledName += 'T';
else if (isMatrix())
mangledName += 'm';
else if (isVector())
mangledName += 'v';
if (isCoopVecNV())
mangledName += "coopvec";
switch (basicType) {
case EbtFloat: mangledName += 'f'; break;
case EbtInt: mangledName += 'i'; break;
@ -67,6 +72,9 @@ void TType::buildMangledName(TString& mangledName) const
case EbtBool: mangledName += 'b'; break;
case EbtDouble: mangledName += 'd'; break;
case EbtFloat16: mangledName += "f16"; break;
case EbtBFloat16: mangledName += "bf16"; break;
case EbtFloatE5M2: mangledName += "fe5m2"; break;
case EbtFloatE4M3: mangledName += "fe4m3"; break;
case EbtInt8: mangledName += "i8"; break;
case EbtUint8: mangledName += "u8"; break;
case EbtInt16: mangledName += "i16"; break;
@ -78,6 +86,9 @@ void TType::buildMangledName(TString& mangledName) const
case EbtRayQuery: mangledName += "rq"; break;
case EbtSpirvType: mangledName += "spv-t"; break;
case EbtHitObjectNV: mangledName += "ho"; break;
case EbtHitObjectEXT: mangledName += "ho"; break;
case EbtTensorLayoutNV: mangledName += "tl"; break;
case EbtTensorViewNV: mangledName += "tv"; break;
case EbtSampler:
switch (sampler.type) {
case EbtFloat16: mangledName += "f16"; break;
@ -161,6 +172,23 @@ void TType::buildMangledName(TString& mangledName) const
mangledName += static_cast<char>('0' + getMatrixRows());
}
if (typeParameters) {
const int maxSize = 11;
char buf[maxSize];
for (int i = 0; i < typeParameters->arraySizes->getNumDims(); ++i) {
if (typeParameters->arraySizes->getDimNode(i)) {
if (typeParameters->arraySizes->getDimNode(i)->getAsSymbolNode())
snprintf(buf, maxSize, "s%lld", typeParameters->arraySizes->getDimNode(i)->getAsSymbolNode()->getId());
else
snprintf(buf, maxSize, "s%p", typeParameters->arraySizes->getDimNode(i));
} else
snprintf(buf, maxSize, "%d", typeParameters->arraySizes->getDimSize(i));
mangledName += '<';
mangledName += buf;
mangledName += '>';
}
}
if (arraySizes) {
const int maxSize = 11;
char buf[maxSize];
@ -169,7 +197,7 @@ void TType::buildMangledName(TString& mangledName) const
if (arraySizes->getDimNode(i)->getAsSymbolNode())
snprintf(buf, maxSize, "s%lld", arraySizes->getDimNode(i)->getAsSymbolNode()->getId());
else
snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i));
snprintf(buf, maxSize, "s%p", (void*)(arraySizes->getDimNode(i)));
} else
snprintf(buf, maxSize, "%d", arraySizes->getDimSize(i));
mangledName += '[';
@ -319,6 +347,24 @@ void TSymbolTableLevel::setFunctionExtensions(const char* name, int num, const c
}
}
// Call the callback function to determine the required extensions
void TSymbolTableLevel::setFunctionExtensionsCallback(const char* name, std::function<std::vector<const char *>(const char *)> const &func)
{
tLevel::const_iterator candidate = level.lower_bound(name);
while (candidate != level.end()) {
const TString& candidateName = (*candidate).first;
TString::size_type parenAt = candidateName.find_first_of('(');
if (parenAt != candidateName.npos && candidateName.compare(0, parenAt, name) == 0) {
TSymbol* symbol = candidate->second;
auto exts = func(candidateName.c_str());
symbol->setExtensions(exts.size(), exts.data());
} else
break;
++candidate;
}
}
// Make a single function require an extension(s). i.e., this will only set the extensions for the symbol that matches 'name' exactly.
// This is different from setFunctionExtensions, which uses std::map::lower_bound to effectively set all symbols that start with 'name'.
// Should only be used for a version/profile that actually needs the extension(s).
@ -344,6 +390,7 @@ void TSymbolTableLevel::readOnly()
TSymbol::TSymbol(const TSymbol& copyOf)
{
name = NewPoolTString(copyOf.name->c_str());
mangledName = NewPoolTString(copyOf.mangledName->c_str());
uniqueId = copyOf.uniqueId;
writable = true;
}
@ -397,6 +444,7 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
defined = copyOf.defined;
prototyped = copyOf.prototyped;
implicitThis = copyOf.implicitThis;
variadic = copyOf.variadic;
illegalImplicitThis = copyOf.illegalImplicitThis;
defaultParamCount = copyOf.defaultParamCount;
spirvInst = copyOf.spirvInst;

View file

@ -69,6 +69,9 @@
#include "../Include/intermediate.h"
#include "../Include/InfoSink.h"
#include <functional>
#include <unordered_map>
namespace glslang {
//
@ -84,7 +87,8 @@ typedef TVector<const char*> TExtensionList;
class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
explicit TSymbol(const TString *n) : name(n), uniqueId(0), extensions(nullptr), writable(true) { }
explicit TSymbol(const TString *n, const TString *mn) : name(n), mangledName(mn), uniqueId(0), extensions(nullptr), writable(true) { }
explicit TSymbol(const TString *n) : TSymbol(n, n) { }
virtual TSymbol* clone() const = 0;
virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
@ -96,7 +100,7 @@ public:
newName.append(*name);
changeName(NewPoolTString(newName.c_str()));
}
virtual const TString& getMangledName() const { return getName(); }
virtual const TString& getMangledName() const { return *mangledName; }
virtual TFunction* getAsFunction() { return nullptr; }
virtual const TFunction* getAsFunction() const { return nullptr; }
virtual TVariable* getAsVariable() { return nullptr; }
@ -128,6 +132,7 @@ protected:
TSymbol& operator=(const TSymbol&);
const TString *name;
const TString *mangledName;
unsigned long long uniqueId; // For cross-scope comparing during code generation
// For tracking what extensions must be present
@ -154,7 +159,9 @@ protected:
class TVariable : public TSymbol {
public:
TVariable(const TString *name, const TType& t, bool uT = false )
: TSymbol(name),
: TVariable(name, name, t, uT) {}
TVariable(const TString *name, const TString *mangledName, const TType& t, bool uT = false )
: TSymbol(name, mangledName),
userType(uT),
constSubtree(nullptr),
memberExtensions(nullptr),
@ -228,6 +235,13 @@ struct TParameter {
name = nullptr;
type = param.type->clone();
defaultValue = param.defaultValue;
if (defaultValue) {
// The defaultValue of a builtin is created in a TPoolAllocator that no longer exists
// when parsing the user program, so make a deep copy.
if (const auto *constUnion = defaultValue->getAsConstantUnion()) {
defaultValue = new TIntermConstantUnion(*constUnion->getConstArray().clone(), constUnion->getType());
}
}
return *this;
}
TBuiltInVariable getDeclaredBuiltIn() const { return type->getQualifier().declaredBuiltIn; }
@ -241,12 +255,12 @@ public:
explicit TFunction(TOperator o) :
TSymbol(nullptr),
op(o),
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) { }
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), variadic(false), defaultParamCount(0) { }
TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
TSymbol(name),
mangledName(*name + '('),
op(tOp),
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0),
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), variadic(false), defaultParamCount(0),
linkType(ELinkNone)
{
returnType.shallowCopy(retType);
@ -264,6 +278,7 @@ public:
virtual void addParameter(TParameter& p)
{
assert(writable);
assert(!variadic && "cannot add more parameters if function is marked variadic");
parameters.push_back(p);
p.type->appendMangledName(mangledName);
@ -306,6 +321,13 @@ public:
virtual bool hasImplicitThis() const { return implicitThis; }
virtual void setIllegalImplicitThis() { assert(writable); illegalImplicitThis = true; }
virtual bool hasIllegalImplicitThis() const { return illegalImplicitThis; }
virtual void setVariadic() {
assert(writable);
assert(!variadic && "function was already marked variadic");
variadic = true;
mangledName += 'z';
}
virtual bool isVariadic() const { return variadic; }
// Return total number of parameters
virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
@ -348,6 +370,7 @@ protected:
// even if it finds member variables in the symbol table.
// This is important for a static member function that has member variables in scope,
// but is not allowed to use them, or see hidden symbols instead.
bool variadic;
int defaultParamCount;
TSpirvInstruction spirvInst; // SPIR-V instruction qualifiers
@ -483,6 +506,11 @@ public:
retargetedSymbols.push_back({from, to});
}
void collectRetargetedSymbols(std::unordered_multimap<std::string, std::string> &out) const {
for (const auto &[fromName, toName] : retargetedSymbols)
out.insert({std::string{toName}, std::string{fromName}});
}
TSymbol* find(const TString& name) const
{
tLevel::const_iterator it = level.find(name);
@ -576,6 +604,7 @@ public:
void relateToOperator(const char* name, TOperator op);
void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
void setFunctionExtensionsCallback(const char* name, std::function<std::vector<const char *>(const char *)> const &func);
void setSingleFunctionExtensions(const char* name, int num, const char* const extensions[]);
void dump(TInfoSink& infoSink, bool complete = false) const;
TSymbolTableLevel* clone() const;
@ -639,9 +668,10 @@ public:
//
protected:
static const uint32_t LevelFlagBitOffset = 56;
static const int globalLevel = 3;
static constexpr int builtinLevel = 2;
static constexpr int globalLevel = 3;
static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
static bool isBuiltInLevel(int level) { return level <= builtinLevel; } // exclude user globals
static bool isGlobalLevel(int level) { return level <= globalLevel; } // include user globals
public:
bool isEmpty() { return table.size() == 0; }
@ -806,6 +836,13 @@ public:
table[level]->retargetSymbol(from, to);
}
std::unordered_multimap<std::string, std::string> collectBuiltinAlias() {
std::unordered_multimap<std::string, std::string> allRetargets;
for (int level = 0; level <= std::min(currentLevel(), builtinLevel); ++level)
table[level]->collectRetargetedSymbols(allRetargets);
return allRetargets;
}
// Find of a symbol that returns how many layers deep of nested
// structures-with-member-functions ('this' scopes) deep the symbol was
@ -878,6 +915,12 @@ public:
table[level]->setFunctionExtensions(name, num, extensions);
}
void setFunctionExtensionsCallback(const char* name, std::function<std::vector<const char *>(const char *)> const &func)
{
for (unsigned int level = 0; level < table.size(); ++level)
table[level]->setFunctionExtensionsCallback(name, func);
}
void setSingleFunctionExtensions(const char* name, int num, const char* const extensions[])
{
for (unsigned int level = 0; level < table.size(); ++level)

View file

@ -165,7 +165,8 @@ void TParseVersions::initializeExtensionBehavior()
const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4},
{E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4},
{E_GL_EXT_mesh_shader, EShTargetSpv_1_4}
{E_GL_EXT_mesh_shader, EShTargetSpv_1_4},
{E_GL_NV_cooperative_matrix2, EShTargetSpv_1_6}
};
for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) {
@ -187,7 +188,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_3DL_array_objects] = EBhDisable;
extensionBehavior[E_GL_ARB_shading_language_420pack] = EBhDisable;
extensionBehavior[E_GL_ARB_texture_gather] = EBhDisable;
extensionBehavior[E_GL_ARB_gpu_shader5] = EBhDisablePartial;
extensionBehavior[E_GL_ARB_gpu_shader5] = EBhDisable;
extensionBehavior[E_GL_ARB_separate_shader_objects] = EBhDisable;
extensionBehavior[E_GL_ARB_compute_shader] = EBhDisable;
extensionBehavior[E_GL_ARB_tessellation_shader] = EBhDisable;
@ -224,9 +225,11 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_shading_language_packing] = EBhDisable;
extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable;
extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable;
extensionBehavior[E_GL_NV_gpu_shader5] = EBhDisable;
extensionBehavior[E_GL_ARB_draw_instanced] = EBhDisable;
extensionBehavior[E_GL_ARB_bindless_texture] = EBhDisable;
extensionBehavior[E_GL_ARB_fragment_coord_conventions] = EBhDisable;
extensionBehavior[E_GL_ARB_conservative_depth] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
@ -265,8 +268,10 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_expect_assume] = EBhDisable;
extensionBehavior[E_GL_EXT_control_flow_attributes2] = EBhDisable;
extensionBehavior[E_GL_EXT_spec_constant_composites] = EBhDisable;
extensionBehavior[E_GL_KHR_cooperative_matrix] = EBhDisable;
extensionBehavior[E_GL_NV_cooperative_vector] = EBhDisable;
// #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
@ -309,13 +314,19 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_NV_shader_invocation_reorder] = EBhDisable;
extensionBehavior[E_GL_NV_displacement_micromap] = EBhDisable;
extensionBehavior[E_GL_NV_shader_atomic_fp16_vector] = EBhDisable;
extensionBehavior[E_GL_NV_cooperative_matrix2] = EBhDisable;
extensionBehavior[E_GL_NV_cluster_acceleration_structure] = EBhDisable;
extensionBehavior[E_GL_NV_linear_swept_spheres] = EBhDisable;
// ARM
extensionBehavior[E_GL_ARM_shader_core_builtins] = EBhDisable;
extensionBehavior[E_GL_ARM_tensors] = EBhDisable;
// QCOM
extensionBehavior[E_GL_QCOM_image_processing] = EBhDisable;
extensionBehavior[E_GL_QCOM_image_processing2] = EBhDisable;
extensionBehavior[E_GL_QCOM_tile_shading] = EBhDisable;
extensionBehavior[E_GL_QCOM_cooperative_matrix_conversion] = EBhDisable;
// AEP
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable;
@ -370,6 +381,14 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_texture_shadow_lod] = EBhDisable;
extensionBehavior[E_GL_EXT_draw_instanced] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_array] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_offset_non_const] = EBhDisable;
extensionBehavior[E_GL_EXT_nontemporal_keyword] = EBhDisable;
extensionBehavior[E_GL_EXT_bfloat16] = EBhDisable;
extensionBehavior[E_GL_EXT_float_e4m3] = EBhDisable;
extensionBehavior[E_GL_EXT_float_e5m2] = EBhDisable;
extensionBehavior[E_GL_EXT_uniform_buffer_unsized_array] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_64bit_indexing] = EBhDisable;
extensionBehavior[E_GL_EXT_conservative_depth] = EBhDisable;
// OVR extensions
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
@ -393,6 +412,10 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_atomic_float2] = EBhDisable;
extensionBehavior[E_GL_EXT_integer_dot_product] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_invocation_reorder] = EBhDisable;
// Record extensions not for spv.
spvUnsupportedExt.push_back(E_GL_ARB_bindless_texture);
}
@ -414,6 +437,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_shader_texture_lod 1\n"
"#define GL_EXT_shadow_samplers 1\n"
"#define GL_EXT_fragment_shading_rate 1\n"
"#define GL_EXT_conservative_depth 1\n"
// AEP
"#define GL_ANDROID_extension_pack_es31a 1\n"
@ -448,6 +472,8 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_QCOM_image_processing 1\n"
"#define GL_QCOM_image_processing2 1\n"
"#define GL_QCOM_tile_shading 1\n"
"#define GL_QCOM_cooperative_matrix_conversion 1\n"
;
if (version >= 300) {
@ -498,8 +524,10 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_ARB_shader_storage_buffer_object 1\n"
"#define GL_ARB_texture_query_lod 1\n"
"#define GL_ARB_vertex_attrib_64bit 1\n"
"#define GL_NV_gpu_shader5 1\n"
"#define GL_ARB_draw_instanced 1\n"
"#define GL_ARB_fragment_coord_conventions 1\n"
"#define GL_ARB_conservative_depth 1\n"
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
"#define GL_EXT_shader_image_load_formatted 1\n"
@ -519,6 +547,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_fragment_shading_rate 1\n"
"#define GL_EXT_shared_memory_block 1\n"
"#define GL_EXT_shader_integer_mix 1\n"
"#define GL_EXT_spec_constant_composites 1\n"
// GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n"
@ -572,9 +601,12 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_NV_cooperative_matrix 1\n"
"#define GL_NV_integer_cooperative_matrix 1\n"
"#define GL_NV_shader_invocation_reorder 1\n"
"#define GL_NV_cooperative_matrix2 1\n"
"#define GL_QCOM_image_processing 1\n"
"#define GL_QCOM_image_processing2 1\n"
"#define GL_QCOM_tile_shading 1\n"
"#define GL_QCOM_cooperative_matrix_conversion 1\n"
"#define GL_EXT_shader_explicit_arithmetic_types 1\n"
"#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n"
@ -598,6 +630,15 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_texture_array 1\n"
"#define GL_EXT_control_flow_attributes2 1\n"
"#define GL_EXT_integer_dot_product 1\n"
"#define GL_EXT_bfloat16 1\n"
"#define GL_EXT_float_e5m2 1\n"
"#define GL_EXT_float_e4m3 1\n"
"#define GL_EXT_uniform_buffer_unsized_array 1\n"
"#define GL_EXT_shader_64bit_indexing 1\n"
"#define GL_EXT_shader_invocation_reorder 1\n"
;
if (spvVersion.spv == 0) {
@ -630,6 +671,11 @@ void TParseVersions::getPreamble(std::string& preamble)
;
}
if ((!isEsProfile() && version >= 130) ||
(isEsProfile() && version >= 300)) {
preamble += "#define GL_EXT_texture_offset_non_const 1\n";
}
if (version >= 300 /* both ES and non-ES */) {
preamble +=
"#define GL_OVR_multiview 1\n"
@ -773,7 +819,7 @@ void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int
for (int i = 0; i < numExtensions; ++i) {
switch (getExtensionBehavior(extensions[i])) {
case EBhWarn:
infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
[[fallthrough]];
case EBhRequire:
case EBhEnable:
@ -811,7 +857,8 @@ void TParseVersions::checkDeprecated(const TSourceLoc& loc, int profileMask, int
error(loc, "deprecated, may be removed in future release", featureDesc, "");
else if (! suppressWarnings())
infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " +
String(depVersion) + "; may be removed in future release").c_str(), loc);
String(depVersion) + "; may be removed in future release").c_str(),
loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
}
}
}
@ -848,11 +895,14 @@ bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExte
for (int i = 0; i < numExtensions; ++i) {
TExtensionBehavior behavior = getExtensionBehavior(extensions[i]);
if (behavior == EBhDisable && relaxedErrors()) {
infoSink.info.message(EPrefixWarning, "The following extension must be enabled to use this feature:", loc);
infoSink.info.message(EPrefixWarning, "The following extension must be enabled to use this feature:", loc,
messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
behavior = EBhWarn;
}
if (behavior == EBhWarn) {
infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
infoSink.info.message(EPrefixWarning,
("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(),
loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
warned = true;
}
}
@ -1015,6 +1065,8 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
updateExtensionBehavior(line, "GL_EXT_buffer_reference", behaviorString);
else if (strcmp(extension, "GL_NV_integer_cooperative_matrix") == 0)
updateExtensionBehavior(line, "GL_NV_cooperative_matrix", behaviorString);
else if (strcmp(extension, "GL_NV_cooperative_matrix2") == 0)
updateExtensionBehavior(line, "GL_KHR_cooperative_matrix", behaviorString);
// subgroup extended types to explicit types
else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_int8") == 0)
updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int8", behaviorString);
@ -1050,6 +1102,9 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
intermediate.updateNumericFeature(TNumericFeatures::gpu_shader_int16, on);
else if (strcmp(extension, "GL_AMD_gpu_shader_half_float") == 0)
intermediate.updateNumericFeature(TNumericFeatures::gpu_shader_half_float, on);
else if (strcmp(extension, "GL_NV_gpu_shader5") == 0) {
intermediate.updateNumericFeature(TNumericFeatures::nv_gpu_shader5_types, on);
}
}
void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
@ -1177,6 +1232,7 @@ bool TParseVersions::float16Arithmetic()
const char* const extensions[] = {
E_GL_AMD_gpu_shader_half_float,
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_float16};
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
}
@ -1186,6 +1242,7 @@ bool TParseVersions::int16Arithmetic()
const char* const extensions[] = {
E_GL_AMD_gpu_shader_int16,
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_int16};
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
}
@ -1194,6 +1251,7 @@ bool TParseVersions::int8Arithmetic()
{
const char* const extensions[] = {
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_int8};
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
}
@ -1208,6 +1266,7 @@ void TParseVersions::requireFloat16Arithmetic(const TSourceLoc& loc, const char*
const char* const extensions[] = {
E_GL_AMD_gpu_shader_half_float,
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_float16};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
}
@ -1222,6 +1281,7 @@ void TParseVersions::requireInt16Arithmetic(const TSourceLoc& loc, const char* o
const char* const extensions[] = {
E_GL_AMD_gpu_shader_int16,
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_int16};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
}
@ -1235,6 +1295,7 @@ void TParseVersions::requireInt8Arithmetic(const TSourceLoc& loc, const char* op
const char* const extensions[] = {
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_int8};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
}
@ -1246,18 +1307,50 @@ void TParseVersions::float16ScalarVectorCheck(const TSourceLoc& loc, const char*
E_GL_AMD_gpu_shader_half_float,
E_GL_EXT_shader_16bit_storage,
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_float16};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
void TParseVersions::bfloat16ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {
E_GL_EXT_bfloat16,
};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
void TParseVersions::floate5m2ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {
E_GL_EXT_float_e5m2,
};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
void TParseVersions::floate4m3ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {
E_GL_EXT_float_e4m3,
};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
// Call for any operation needing GLSL float32 data-type support.
void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
const char* const extensions[] = {E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_float32};
requireExtensions(loc, 2, extensions, op);
requireExtensions(loc, sizeof(extensions) / sizeof(extensions[0]), extensions, op);
}
}
@ -1265,11 +1358,15 @@ void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op,
void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
const char* const extensions[] = {E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_float64};
requireExtensions(loc, 2, extensions, op);
requireExtensions(loc, sizeof(extensions) / sizeof(extensions[0]), extensions, op);
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
if(extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) && extensionTurnedOn(E_GL_NV_gpu_shader5))
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 150, nullptr, op);
else
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
}
}
@ -1312,6 +1409,7 @@ void TParseVersions::int16ScalarVectorCheck(const TSourceLoc& loc, const char* o
E_GL_AMD_gpu_shader_int16,
E_GL_EXT_shader_16bit_storage,
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_int16};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
@ -1323,6 +1421,7 @@ void TParseVersions::int8ScalarVectorCheck(const TSourceLoc& loc, const char* op
const char* const extensions[] = {
E_GL_EXT_shader_8bit_storage,
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_int8};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
@ -1332,9 +1431,10 @@ void TParseVersions::int8ScalarVectorCheck(const TSourceLoc& loc, const char* op
void TParseVersions::explicitInt32Check(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (! builtIn) {
const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types,
const char* const extensions[] = {E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_int32};
requireExtensions(loc, 2, extensions, op);
requireExtensions(loc, sizeof(extensions) / sizeof(extensions[0]), extensions, op);
}
}
@ -1342,11 +1442,15 @@ void TParseVersions::explicitInt32Check(const TSourceLoc& loc, const char* op, b
void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (! builtIn) {
const char* const extensions[3] = {E_GL_ARB_gpu_shader_int64,
const char* const extensions[] = {E_GL_ARB_gpu_shader_int64,
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_int64};
requireExtensions(loc, 3, extensions, op);
requireExtensions(loc, sizeof(extensions) / sizeof(extensions[0]), extensions, op);
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
if (extensionTurnedOn(E_GL_NV_gpu_shader5))
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 150, nullptr, op);
else
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
}
}
@ -1375,6 +1479,46 @@ void TParseVersions::coopmatCheck(const TSourceLoc& loc, const char* op, bool bu
}
}
void TParseVersions::coopmatConverisonCheckQCOM(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {E_GL_KHR_cooperative_matrix};
requireExtensions(loc, sizeof(extensions) / sizeof(extensions[0]), extensions, op);
}
}
void TParseVersions::tensorLayoutViewCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {E_GL_NV_cooperative_matrix2};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
void TParseVersions::coopvecCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {E_GL_NV_cooperative_vector};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
void TParseVersions::intattachmentCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {E_GL_QCOM_tile_shading};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
void TParseVersions::tensorCheckARM(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {E_GL_ARM_tensors};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
// Call for any operation removed because SPIR-V is in use.
void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
{

View file

@ -4,6 +4,7 @@
// Copyright (C) 2017, 2022-2024 Arm Limited.
// Copyright (C) 2015-2018 Google, Inc.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
// Modifications Copyright (C) 2024 Valve Corporation.
//
// All rights reserved.
//
@ -164,6 +165,7 @@ const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_
const char* const E_GL_ARB_draw_instanced = "GL_ARB_draw_instanced";
const char* const E_GL_ARB_fragment_coord_conventions = "GL_ARB_fragment_coord_conventions";
const char* const E_GL_ARB_bindless_texture = "GL_ARB_bindless_texture";
const char* const E_GL_ARB_conservative_depth = "GL_ARB_conservative_depth";
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
@ -222,6 +224,11 @@ const char* const E_GL_EXT_texture_array = "GL_EXT_texture_ar
const char* const E_GL_EXT_maximal_reconvergence = "GL_EXT_maximal_reconvergence";
const char* const E_GL_EXT_expect_assume = "GL_EXT_expect_assume";
const char* const E_GL_EXT_control_flow_attributes2 = "GL_EXT_control_flow_attributes2";
const char* const E_GL_EXT_spec_constant_composites = "GL_EXT_spec_constant_composites";
const char* const E_GL_EXT_texture_offset_non_const = "GL_EXT_texture_offset_non_const";
const char* const E_GL_EXT_nontemporal_keyword = "GL_EXT_nontemporal_keyword";
const char* const E_GL_EXT_uniform_buffer_unsized_array = "GL_EXT_uniform_buffer_unsized_array";
const char* const E_GL_EXT_conservative_depth = "GL_EXT_conservative_depth";
// Arrays of extensions for the above viewportEXTs duplications
@ -281,9 +288,15 @@ const char* const E_GL_NV_shader_invocation_reorder = "GL_NV_shader_
const char* const E_GL_EXT_ray_tracing_position_fetch = "GL_EXT_ray_tracing_position_fetch";
const char* const E_GL_NV_displacement_micromap = "GL_NV_displacement_micromap";
const char* const E_GL_NV_shader_atomic_fp16_vector = "GL_NV_shader_atomic_fp16_vector";
const char* const E_GL_NV_cooperative_matrix2 = "GL_NV_cooperative_matrix2";
const char* const E_GL_NV_cooperative_vector = "GL_NV_cooperative_vector";
const char* const E_GL_NV_cluster_acceleration_structure = "GL_NV_cluster_acceleration_structure";
const char* const E_GL_NV_linear_swept_spheres = "GL_NV_linear_swept_spheres";
const char* const E_GL_NV_gpu_shader5 = "GL_NV_gpu_shader5";
// ARM
const char* const E_GL_ARM_shader_core_builtins = "GL_ARM_shader_core_builtins";
const char* const E_GL_ARM_tensors = "GL_ARM_tensors";
// Arrays of extensions for the above viewportEXTs duplications
@ -293,6 +306,8 @@ const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
const char* const E_GL_QCOM_image_processing = "GL_QCOM_image_processing";
const char* const E_GL_QCOM_image_processing2 = "GL_QCOM_image_processing2";
const char* const E_GL_QCOM_tile_shading = "GL_QCOM_tile_shading";
const char* const E_GL_QCOM_cooperative_matrix_conversion = "GL_QCOM_cooperative_matrix_conversion";
// AEP
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
@ -346,6 +361,16 @@ const char* const E_GL_EXT_shader_tile_image = "GL_EXT_shader_tile_image";
const char* const E_GL_EXT_texture_shadow_lod = "GL_EXT_texture_shadow_lod";
const char* const E_GL_EXT_integer_dot_product = "GL_EXT_integer_dot_product";
const char* const E_GL_EXT_bfloat16 = "GL_EXT_bfloat16";
const char* const E_GL_EXT_float_e5m2 = "GL_EXT_float_e5m2";
const char* const E_GL_EXT_float_e4m3 = "GL_EXT_float_e4m3";
const char* const E_GL_EXT_shader_64bit_indexing = "GL_EXT_shader_64bit_indexing";
const char* const E_GL_EXT_shader_invocation_reorder = "GL_EXT_shader_invocation_reorder";
// Arrays of extensions for the above AEP duplications
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
@ -357,6 +382,9 @@ const int Num_AEP_geometry_point_size = sizeof(AEP_geometry_point_size)/sizeof(A
const char* const AEP_gpu_shader5[] = { E_GL_EXT_gpu_shader5, E_GL_OES_gpu_shader5 };
const int Num_AEP_gpu_shader5 = sizeof(AEP_gpu_shader5)/sizeof(AEP_gpu_shader5[0]);
const char* const AEP_core_gpu_shader5[] = { E_GL_ARB_gpu_shader5, E_GL_NV_gpu_shader5};
const int Num_AEP_core_gpu_shader5 = sizeof(AEP_core_gpu_shader5)/sizeof(AEP_core_gpu_shader5[0]);
const char* const AEP_primitive_bounding_box[] = { E_GL_EXT_primitive_bounding_box, E_GL_OES_primitive_bounding_box };
const int Num_AEP_primitive_bounding_box = sizeof(AEP_primitive_bounding_box)/sizeof(AEP_primitive_bounding_box[0]);

View file

@ -146,7 +146,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> UTEXTURE2D UTEXTURE3D UTEXTURECUBE UTEXTURE2DARRAY
%token <lex> ATTRIBUTE VARYING
%token <lex> FLOAT16_T FLOAT32_T DOUBLE FLOAT64_T
%token <lex> FLOATE5M2_T FLOATE4M3_T BFLOAT16_T FLOAT16_T FLOAT32_T DOUBLE FLOAT64_T
%token <lex> INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T
%token <lex> I64VEC2 I64VEC3 I64VEC4
%token <lex> U64VEC2 U64VEC3 U64VEC4
@ -157,6 +157,9 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> I8VEC2 I8VEC3 I8VEC4
%token <lex> U8VEC2 U8VEC3 U8VEC4
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
%token <lex> BF16VEC2 BF16VEC3 BF16VEC4
%token <lex> FE5M2VEC2 FE5M2VEC3 FE5M2VEC4
%token <lex> FE4M3VEC2 FE4M3VEC3 FE4M3VEC4
%token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4
%token <lex> F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4
%token <lex> F64VEC2 F64VEC3 F64VEC4 F64MAT2 F64MAT3 F64MAT4
@ -178,7 +181,10 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> RAYQUERYEXT
%token <lex> FCOOPMATNV ICOOPMATNV UCOOPMATNV
%token <lex> COOPMAT
%token <lex> HITOBJECTNV HITOBJECTATTRNV
%token <lex> COOPVECNV
%token <lex> HITOBJECTNV HITOBJECTATTRNV HITOBJECTEXT HITOBJECTATTREXT
%token <lex> TENSORLAYOUTNV TENSORVIEWNV
%token <lex> TENSORARM
// combined image/sampler
%token <lex> SAMPLERCUBEARRAY SAMPLERCUBEARRAYSHADOW
@ -275,11 +281,11 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> DOUBLECONSTANT INT16CONSTANT UINT16CONSTANT FLOAT16CONSTANT INT32CONSTANT UINT32CONSTANT
%token <lex> INT64CONSTANT UINT64CONSTANT
%token <lex> SUBROUTINE DEMOTE
%token <lex> SUBROUTINE DEMOTE FUNCTION
%token <lex> PAYLOADNV PAYLOADINNV HITATTRNV CALLDATANV CALLDATAINNV
%token <lex> PAYLOADEXT PAYLOADINEXT HITATTREXT CALLDATAEXT CALLDATAINEXT
%token <lex> PATCH SAMPLE NONUNIFORM
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY NONTEMPORAL DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
%token <lex> SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXEXT PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV PERPRIMITIVEEXT TASKPAYLOADWORKGROUPEXT
%token <lex> PRECISE
@ -292,7 +298,8 @@ extern int yylex(YYSTYPE*, TParseContext&);
%type <interm.intermTypedNode> conditional_expression constant_expression
%type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression
%type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
%type <interm.intermTypedNode> function_call initializer condition conditionopt
%type <interm.intermTypedNode> function_call initializer
%type <interm.intermNode> condition conditionopt
%type <interm.intermNode> translation_unit function_definition
%type <interm.intermNode> statement simple_statement
@ -445,7 +452,7 @@ postfix_expression
integer_expression
: expression {
parseContext.integerCheck($1, "[]");
parseContext.arrayIndexCheck($1, "[]");
$$ = $1;
}
;
@ -549,7 +556,7 @@ function_identifier
TIntermMethod* method = $1->getAsMethodNode();
if (method) {
$$.function = new TFunction(&method->getMethodName(), TType(EbtInt), EOpArrayLength);
$$.function = new TFunction(&method->getMethodName(), method->getType(), EOpArrayLength);
$$.intermNode = method->getObject();
} else {
TIntermSymbol* symbol = $1->getAsSymbolNode();
@ -906,31 +913,22 @@ declaration
$$ = 0;
}
| block_structure SEMICOLON {
parseContext.declareBlock($1.loc, *$1.typeList);
$$ = 0;
$$ = parseContext.declareBlock($1.loc, *$1.typeList);
}
| block_structure IDENTIFIER SEMICOLON {
parseContext.declareBlock($1.loc, *$1.typeList, $2.string);
$$ = 0;
$$ = parseContext.declareBlock($1.loc, *$1.typeList, $2.string);
}
| block_structure IDENTIFIER array_specifier SEMICOLON {
parseContext.declareBlock($1.loc, *$1.typeList, $2.string, $3.arraySizes);
$$ = 0;
$$ = parseContext.declareBlock($1.loc, *$1.typeList, $2.string, $3.arraySizes);
}
| type_qualifier SEMICOLON {
parseContext.globalQualifierFixCheck($1.loc, $1.qualifier);
parseContext.updateStandaloneQualifierDefaults($1.loc, $1);
$$ = 0;
}
| type_qualifier IDENTIFIER SEMICOLON {
| type_qualifier identifier_list SEMICOLON {
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2.string);
$$ = 0;
}
| type_qualifier IDENTIFIER identifier_list SEMICOLON {
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
$3->push_back($2.string);
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$3);
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2);
$$ = 0;
}
;
@ -947,9 +945,9 @@ block_structure
}
identifier_list
: COMMA IDENTIFIER {
: IDENTIFIER {
$$ = new TIdentifierList;
$$->push_back($2.string);
$$->push_back($1.string);
}
| identifier_list COMMA IDENTIFIER {
$$ = $1;
@ -1034,6 +1032,10 @@ function_header_with_parameters
parseContext.vkRelaxedRemapFunctionParameter($1, $3.param);
}
}
| function_header_with_parameters COMMA DOT DOT DOT {
$$ = $1;
parseContext.makeVariadic($1, $3.loc);
}
;
function_header
@ -1094,6 +1096,11 @@ parameter_declarator
$$.loc = $2.loc;
$$.param = param;
}
| type_specifier IDENTIFIER EQUAL initializer {
TParameter param = parseContext.getParamWithDefault($1, $2.string, $4, $3.loc);
$$.loc = $2.loc;
$$.param = param;
}
;
parameter_declaration
@ -1104,7 +1111,7 @@ parameter_declaration
$$ = $2;
if ($1.qualifier.precision != EpqNone)
$$.param.type->getQualifier().precision = $1.qualifier.precision;
parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier(), $$.param.type->isCoopMat());
parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier(), $$.param.type->hasTypeParameter());
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
parseContext.parameterTypeCheck($2.loc, $1.qualifier.storage, *$$.param.type);
@ -1116,7 +1123,7 @@ parameter_declaration
parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type);
parseContext.paramCheckFixStorage($1.loc, EvqTemporary, *$$.param.type);
parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier(), $$.param.type->isCoopMat());
parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier(), $$.param.type->hasTypeParameter());
}
//
// Without name
@ -1125,7 +1132,7 @@ parameter_declaration
$$ = $2;
if ($1.qualifier.precision != EpqNone)
$$.param.type->getQualifier().precision = $1.qualifier.precision;
parseContext.precisionQualifierCheck($1.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier(), $$.param.type->isCoopMat());
parseContext.precisionQualifierCheck($1.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier(), $$.param.type->hasTypeParameter());
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
parseContext.parameterTypeCheck($2.loc, $1.qualifier.storage, *$$.param.type);
@ -1136,7 +1143,7 @@ parameter_declaration
parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type);
parseContext.paramCheckFixStorage($1.loc, EvqTemporary, *$$.param.type);
parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier(), $$.param.type->isCoopMat());
parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier(), $$.param.type->hasTypeParameter());
}
;
@ -1155,21 +1162,23 @@ init_declarator_list
}
| init_declarator_list COMMA IDENTIFIER {
$$ = $1;
parseContext.declareVariable($3.loc, *$3.string, $1.type);
TIntermNode* declNode = parseContext.declareVariable($3.loc, *$3.string, $1.type);
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, declNode, $3.loc);
}
| init_declarator_list COMMA IDENTIFIER array_specifier {
$$ = $1;
parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes);
TIntermNode* declNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes);
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, declNode, $3.loc);
}
| init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer {
$$.type = $1.type;
TIntermNode* initNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes, $6);
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, initNode, $5.loc);
TIntermNode* declNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes, $6);
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, declNode, $5.loc);
}
| init_declarator_list COMMA IDENTIFIER EQUAL initializer {
$$.type = $1.type;
TIntermNode* initNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, 0, $5);
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, initNode, $4.loc);
TIntermNode* declNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, 0, $5);
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, declNode, $4.loc);
}
;
@ -1181,23 +1190,24 @@ single_declaration
}
| fully_specified_type IDENTIFIER {
$$.type = $1;
$$.intermNode = 0;
parseContext.declareVariable($2.loc, *$2.string, $1);
TIntermNode* declNode = parseContext.declareVariable($2.loc, *$2.string, $1);
$$.intermNode = parseContext.intermediate.growAggregate(nullptr, declNode, $2.loc);
}
| fully_specified_type IDENTIFIER array_specifier {
$$.type = $1;
$$.intermNode = 0;
parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes);
TIntermNode* declNode = parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes);
$$.intermNode = parseContext.intermediate.growAggregate(nullptr, declNode, $2.loc);
}
| fully_specified_type IDENTIFIER array_specifier EQUAL initializer {
$$.type = $1;
TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes, $5);
$$.intermNode = parseContext.intermediate.growAggregate(0, initNode, $4.loc);
TIntermNode* declNode = parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes, $5);
$$.intermNode = parseContext.intermediate.growAggregate(nullptr, declNode, $2.loc);
}
| fully_specified_type IDENTIFIER EQUAL initializer {
$$.type = $1;
TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4);
$$.intermNode = parseContext.intermediate.growAggregate(0, initNode, $3.loc);
TIntermNode* declNode = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4);
$$.intermNode = parseContext.intermediate.growAggregate(nullptr, declNode, $2.loc);
}
// Grammar Note: No 'enum', or 'typedef'.
@ -1211,7 +1221,7 @@ fully_specified_type
parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type");
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
}
parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier, $$.isCoopmat());
parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier, $$.hasTypeParameter());
}
| type_qualifier type_specifier {
parseContext.globalQualifierFixCheck($1.loc, $1.qualifier, false, &$2);
@ -1228,7 +1238,7 @@ fully_specified_type
parseContext.checkNoShaderLayouts($2.loc, $1.shaderQualifiers);
$2.shaderQualifiers.merge($1.shaderQualifiers);
parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
parseContext.precisionQualifierCheck($2.loc, $2.basicType, $2.qualifier, $2.isCoopmat());
parseContext.precisionQualifierCheck($2.loc, $2.basicType, $2.qualifier, $2.hasTypeParameter());
$$ = $2;
@ -1528,14 +1538,22 @@ storage_qualifier
$$.init($1.loc);
$$.qualifier.storage = EvqHitAttr;
}
| HITOBJECTATTRNV {
| HITOBJECTATTRNV {
parseContext.globalCheck($1.loc, "hitAttributeNV");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask
| EShLangMissMask), "hitObjectAttributeNV");
parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_shader_invocation_reorder, "hitObjectAttributeNV");
$$.init($1.loc);
$$.qualifier.storage = EvqHitObjectAttrNV;
}
}
| HITOBJECTATTREXT {
parseContext.globalCheck($1.loc, "hitAttributeEXT");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask
| EShLangMissMask), "hitObjectAttributeEXT");
parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_EXT_shader_invocation_reorder, "hitObjectAttributeEXT");
$$.init($1.loc);
$$.qualifier.storage = EvqHitObjectAttrEXT;
}
| HITATTREXT {
parseContext.globalCheck($1.loc, "hitAttributeEXT");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask
@ -1656,6 +1674,10 @@ storage_qualifier
$$.init($1.loc);
$$.qualifier.writeonly = true;
}
| NONTEMPORAL {
$$.init($1.loc);
$$.qualifier.nontemporal = true;
}
| SUBROUTINE {
parseContext.spvRemoved($1.loc, "subroutine");
parseContext.globalCheck($1.loc, "subroutine");
@ -1700,7 +1722,7 @@ type_specifier
$$ = $1;
$$.qualifier.precision = parseContext.getDefaultPrecision($$);
$$.typeParameters = $2;
parseContext.coopMatTypeParametersCheck($1.loc, $$);
parseContext.typeParametersCheck($1.loc, $$);
}
| type_specifier_nonarray type_parameter_specifier_opt array_specifier {
@ -1709,7 +1731,7 @@ type_specifier
$$.qualifier.precision = parseContext.getDefaultPrecision($$);
$$.typeParameters = $2;
$$.arraySizes = $3.arraySizes;
parseContext.coopMatTypeParametersCheck($1.loc, $$);
parseContext.typeParametersCheck($1.loc, $$);
}
;
@ -1931,6 +1953,21 @@ type_specifier_nonarray
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtDouble;
}
| BFLOAT16_T {
parseContext.bfloat16ScalarVectorCheck($1.loc, "bfloat16_t", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtBFloat16;
}
| FLOATE5M2_T {
parseContext.floate5m2ScalarVectorCheck($1.loc, "floate5m2_t", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloatE5M2;
}
| FLOATE4M3_T {
parseContext.floate4m3ScalarVectorCheck($1.loc, "floate4m3_t", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloatE4M3;
}
| FLOAT16_T {
parseContext.float16ScalarVectorCheck($1.loc, "float16_t", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
@ -2010,6 +2047,60 @@ type_specifier_nonarray
$$.basicType = EbtDouble;
$$.setVector(4);
}
| BF16VEC2 {
parseContext.bfloat16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtBFloat16;
$$.setVector(2);
}
| BF16VEC3 {
parseContext.bfloat16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtBFloat16;
$$.setVector(3);
}
| BF16VEC4 {
parseContext.bfloat16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtBFloat16;
$$.setVector(4);
}
| FE5M2VEC2 {
parseContext.floate5m2ScalarVectorCheck($1.loc, "fe5m2 vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloatE5M2;
$$.setVector(2);
}
| FE5M2VEC3 {
parseContext.floate5m2ScalarVectorCheck($1.loc, "fe5m2 vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloatE5M2;
$$.setVector(3);
}
| FE5M2VEC4 {
parseContext.floate5m2ScalarVectorCheck($1.loc, "fe5m2 vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloatE5M2;
$$.setVector(4);
}
| FE4M3VEC2 {
parseContext.floate4m3ScalarVectorCheck($1.loc, "fe4m3 vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloatE4M3;
$$.setVector(2);
}
| FE4M3VEC3 {
parseContext.floate4m3ScalarVectorCheck($1.loc, "fe4m3 vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloatE4M3;
$$.setVector(3);
}
| FE4M3VEC4 {
parseContext.floate4m3ScalarVectorCheck($1.loc, "fe4m3 vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloatE4M3;
$$.setVector(4);
}
| F16VEC2 {
parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
@ -3535,14 +3626,44 @@ type_specifier_nonarray
$$.coopmatNV = false;
$$.coopmatKHR = true;
}
| TENSORLAYOUTNV {
parseContext.tensorLayoutViewCheck($1.loc, "tensorLayoutNV", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtTensorLayoutNV;
}
| TENSORVIEWNV {
parseContext.tensorLayoutViewCheck($1.loc, "tensorViewNV", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtTensorViewNV;
}
| FUNCTION {
$$.init($1.loc);
$$.basicType = EbtFunction;
}
| COOPVECNV {
parseContext.coopvecCheck($1.loc, "coopvecNV", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtCoopvecNV;
$$.coopvecNV = true;
}
| TENSORARM {
parseContext.tensorCheckARM($1.loc, "tensorARM", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.tensorRankARM = 1; // placeholder value
$$.basicType = EbtTensorARM;
}
| spirv_type_specifier {
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier");
$$ = $1;
}
| HITOBJECTNV {
| HITOBJECTNV {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtHitObjectNV;
}
}
| HITOBJECTEXT {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtHitObjectEXT;
}
| struct_specifier {
$$ = $1;
$$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
@ -3636,7 +3757,7 @@ struct_declaration
$$ = $2;
parseContext.voidErrorCheck($1.loc, (*$2)[0].type->getFieldName(), $1.basicType);
parseContext.precisionQualifierCheck($1.loc, $1.basicType, $1.qualifier, $1.isCoopmat());
parseContext.precisionQualifierCheck($1.loc, $1.basicType, $1.qualifier, $1.hasTypeParameter());
for (unsigned int i = 0; i < $$->size(); ++i) {
TType type($1);
@ -3660,7 +3781,7 @@ struct_declaration
parseContext.memberQualifierCheck($1);
parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2.basicType);
parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
parseContext.precisionQualifierCheck($2.loc, $2.basicType, $2.qualifier, $2.isCoopmat());
parseContext.precisionQualifierCheck($2.loc, $2.basicType, $2.qualifier, $2.hasTypeParameter());
for (unsigned int i = 0; i < $$->size(); ++i) {
TType type($2);
@ -3773,8 +3894,10 @@ compound_statement
--parseContext.statementNestingLevel;
}
RIGHT_BRACE {
if ($3 && $3->getAsAggregate())
if ($3 && $3->getAsAggregate()) {
$3->getAsAggregate()->setOperator(parseContext.intermediate.getDebugInfo() ? EOpScope : EOpSequence);
$3->getAsAggregate()->setEndLoc($5.loc);
}
$$ = $3;
}
;
@ -3810,8 +3933,10 @@ compound_statement_no_new_scope
$$ = 0;
}
| LEFT_BRACE statement_list RIGHT_BRACE {
if ($2 && $2->getAsAggregate())
if ($2 && $2->getAsAggregate()) {
$2->getAsAggregate()->setOperator(EOpSequence);
$2->getAsAggregate()->setEndLoc($3.loc);
}
$$ = $2;
}
;
@ -3878,11 +4003,7 @@ condition
parseContext.boolCheck($2.loc, $1);
TType type($1);
TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4);
if (initNode)
$$ = initNode->getAsTyped();
else
$$ = 0;
$$ = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4);
}
;
@ -3972,6 +4093,10 @@ iteration_statement_nonattributed
condition RIGHT_PAREN statement_no_new_scope {
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
$$ = parseContext.intermediate.addLoop($6, $4, 0, true, $1.loc);
if (parseContext.intermediate.getDebugInfo()) {
$$ = parseContext.intermediate.makeAggregate($$, $1.loc);
$$->getAsAggregate()->setOperator(EOpScope);
}
--parseContext.loopNestingLevel;
--parseContext.statementNestingLevel;
--parseContext.controlFlowNestingLevel;
@ -3989,6 +4114,10 @@ iteration_statement_nonattributed
parseContext.boolCheck($8.loc, $6);
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
if (parseContext.intermediate.getDebugInfo()) {
$$ = parseContext.intermediate.makeAggregate($$, $4.loc);
$$->getAsAggregate()->setOperator(EOpScope);
}
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
--parseContext.loopNestingLevel;
--parseContext.statementNestingLevel;
@ -4007,7 +4136,7 @@ iteration_statement_nonattributed
if (! parseContext.limits.nonInductiveForLoops)
parseContext.inductiveLoopCheck($1.loc, $4, forLoop);
$$ = parseContext.intermediate.growAggregate($$, forLoop, $1.loc);
$$->getAsAggregate()->setOperator(EOpSequence);
$$->getAsAggregate()->setOperator(parseContext.intermediate.getDebugInfo() ? EOpScope : EOpSequence);
--parseContext.loopNestingLevel;
--parseContext.statementNestingLevel;
--parseContext.controlFlowNestingLevel;

File diff suppressed because it is too large Load diff

View file

@ -114,408 +114,428 @@ extern int yydebug;
UTEXTURE2DARRAY = 315, /* UTEXTURE2DARRAY */
ATTRIBUTE = 316, /* ATTRIBUTE */
VARYING = 317, /* VARYING */
FLOAT16_T = 318, /* FLOAT16_T */
FLOAT32_T = 319, /* FLOAT32_T */
DOUBLE = 320, /* DOUBLE */
FLOAT64_T = 321, /* FLOAT64_T */
INT64_T = 322, /* INT64_T */
UINT64_T = 323, /* UINT64_T */
INT32_T = 324, /* INT32_T */
UINT32_T = 325, /* UINT32_T */
INT16_T = 326, /* INT16_T */
UINT16_T = 327, /* UINT16_T */
INT8_T = 328, /* INT8_T */
UINT8_T = 329, /* UINT8_T */
I64VEC2 = 330, /* I64VEC2 */
I64VEC3 = 331, /* I64VEC3 */
I64VEC4 = 332, /* I64VEC4 */
U64VEC2 = 333, /* U64VEC2 */
U64VEC3 = 334, /* U64VEC3 */
U64VEC4 = 335, /* U64VEC4 */
I32VEC2 = 336, /* I32VEC2 */
I32VEC3 = 337, /* I32VEC3 */
I32VEC4 = 338, /* I32VEC4 */
U32VEC2 = 339, /* U32VEC2 */
U32VEC3 = 340, /* U32VEC3 */
U32VEC4 = 341, /* U32VEC4 */
I16VEC2 = 342, /* I16VEC2 */
I16VEC3 = 343, /* I16VEC3 */
I16VEC4 = 344, /* I16VEC4 */
U16VEC2 = 345, /* U16VEC2 */
U16VEC3 = 346, /* U16VEC3 */
U16VEC4 = 347, /* U16VEC4 */
I8VEC2 = 348, /* I8VEC2 */
I8VEC3 = 349, /* I8VEC3 */
I8VEC4 = 350, /* I8VEC4 */
U8VEC2 = 351, /* U8VEC2 */
U8VEC3 = 352, /* U8VEC3 */
U8VEC4 = 353, /* U8VEC4 */
DVEC2 = 354, /* DVEC2 */
DVEC3 = 355, /* DVEC3 */
DVEC4 = 356, /* DVEC4 */
DMAT2 = 357, /* DMAT2 */
DMAT3 = 358, /* DMAT3 */
DMAT4 = 359, /* DMAT4 */
F16VEC2 = 360, /* F16VEC2 */
F16VEC3 = 361, /* F16VEC3 */
F16VEC4 = 362, /* F16VEC4 */
F16MAT2 = 363, /* F16MAT2 */
F16MAT3 = 364, /* F16MAT3 */
F16MAT4 = 365, /* F16MAT4 */
F32VEC2 = 366, /* F32VEC2 */
F32VEC3 = 367, /* F32VEC3 */
F32VEC4 = 368, /* F32VEC4 */
F32MAT2 = 369, /* F32MAT2 */
F32MAT3 = 370, /* F32MAT3 */
F32MAT4 = 371, /* F32MAT4 */
F64VEC2 = 372, /* F64VEC2 */
F64VEC3 = 373, /* F64VEC3 */
F64VEC4 = 374, /* F64VEC4 */
F64MAT2 = 375, /* F64MAT2 */
F64MAT3 = 376, /* F64MAT3 */
F64MAT4 = 377, /* F64MAT4 */
DMAT2X2 = 378, /* DMAT2X2 */
DMAT2X3 = 379, /* DMAT2X3 */
DMAT2X4 = 380, /* DMAT2X4 */
DMAT3X2 = 381, /* DMAT3X2 */
DMAT3X3 = 382, /* DMAT3X3 */
DMAT3X4 = 383, /* DMAT3X4 */
DMAT4X2 = 384, /* DMAT4X2 */
DMAT4X3 = 385, /* DMAT4X3 */
DMAT4X4 = 386, /* DMAT4X4 */
F16MAT2X2 = 387, /* F16MAT2X2 */
F16MAT2X3 = 388, /* F16MAT2X3 */
F16MAT2X4 = 389, /* F16MAT2X4 */
F16MAT3X2 = 390, /* F16MAT3X2 */
F16MAT3X3 = 391, /* F16MAT3X3 */
F16MAT3X4 = 392, /* F16MAT3X4 */
F16MAT4X2 = 393, /* F16MAT4X2 */
F16MAT4X3 = 394, /* F16MAT4X3 */
F16MAT4X4 = 395, /* F16MAT4X4 */
F32MAT2X2 = 396, /* F32MAT2X2 */
F32MAT2X3 = 397, /* F32MAT2X3 */
F32MAT2X4 = 398, /* F32MAT2X4 */
F32MAT3X2 = 399, /* F32MAT3X2 */
F32MAT3X3 = 400, /* F32MAT3X3 */
F32MAT3X4 = 401, /* F32MAT3X4 */
F32MAT4X2 = 402, /* F32MAT4X2 */
F32MAT4X3 = 403, /* F32MAT4X3 */
F32MAT4X4 = 404, /* F32MAT4X4 */
F64MAT2X2 = 405, /* F64MAT2X2 */
F64MAT2X3 = 406, /* F64MAT2X3 */
F64MAT2X4 = 407, /* F64MAT2X4 */
F64MAT3X2 = 408, /* F64MAT3X2 */
F64MAT3X3 = 409, /* F64MAT3X3 */
F64MAT3X4 = 410, /* F64MAT3X4 */
F64MAT4X2 = 411, /* F64MAT4X2 */
F64MAT4X3 = 412, /* F64MAT4X3 */
F64MAT4X4 = 413, /* F64MAT4X4 */
ATOMIC_UINT = 414, /* ATOMIC_UINT */
ACCSTRUCTNV = 415, /* ACCSTRUCTNV */
ACCSTRUCTEXT = 416, /* ACCSTRUCTEXT */
RAYQUERYEXT = 417, /* RAYQUERYEXT */
FCOOPMATNV = 418, /* FCOOPMATNV */
ICOOPMATNV = 419, /* ICOOPMATNV */
UCOOPMATNV = 420, /* UCOOPMATNV */
COOPMAT = 421, /* COOPMAT */
HITOBJECTNV = 422, /* HITOBJECTNV */
HITOBJECTATTRNV = 423, /* HITOBJECTATTRNV */
SAMPLERCUBEARRAY = 424, /* SAMPLERCUBEARRAY */
SAMPLERCUBEARRAYSHADOW = 425, /* SAMPLERCUBEARRAYSHADOW */
ISAMPLERCUBEARRAY = 426, /* ISAMPLERCUBEARRAY */
USAMPLERCUBEARRAY = 427, /* USAMPLERCUBEARRAY */
SAMPLER1D = 428, /* SAMPLER1D */
SAMPLER1DARRAY = 429, /* SAMPLER1DARRAY */
SAMPLER1DARRAYSHADOW = 430, /* SAMPLER1DARRAYSHADOW */
ISAMPLER1D = 431, /* ISAMPLER1D */
SAMPLER1DSHADOW = 432, /* SAMPLER1DSHADOW */
SAMPLER2DRECT = 433, /* SAMPLER2DRECT */
SAMPLER2DRECTSHADOW = 434, /* SAMPLER2DRECTSHADOW */
ISAMPLER2DRECT = 435, /* ISAMPLER2DRECT */
USAMPLER2DRECT = 436, /* USAMPLER2DRECT */
SAMPLERBUFFER = 437, /* SAMPLERBUFFER */
ISAMPLERBUFFER = 438, /* ISAMPLERBUFFER */
USAMPLERBUFFER = 439, /* USAMPLERBUFFER */
SAMPLER2DMS = 440, /* SAMPLER2DMS */
ISAMPLER2DMS = 441, /* ISAMPLER2DMS */
USAMPLER2DMS = 442, /* USAMPLER2DMS */
SAMPLER2DMSARRAY = 443, /* SAMPLER2DMSARRAY */
ISAMPLER2DMSARRAY = 444, /* ISAMPLER2DMSARRAY */
USAMPLER2DMSARRAY = 445, /* USAMPLER2DMSARRAY */
SAMPLEREXTERNALOES = 446, /* SAMPLEREXTERNALOES */
SAMPLEREXTERNAL2DY2YEXT = 447, /* SAMPLEREXTERNAL2DY2YEXT */
ISAMPLER1DARRAY = 448, /* ISAMPLER1DARRAY */
USAMPLER1D = 449, /* USAMPLER1D */
USAMPLER1DARRAY = 450, /* USAMPLER1DARRAY */
F16SAMPLER1D = 451, /* F16SAMPLER1D */
F16SAMPLER2D = 452, /* F16SAMPLER2D */
F16SAMPLER3D = 453, /* F16SAMPLER3D */
F16SAMPLER2DRECT = 454, /* F16SAMPLER2DRECT */
F16SAMPLERCUBE = 455, /* F16SAMPLERCUBE */
F16SAMPLER1DARRAY = 456, /* F16SAMPLER1DARRAY */
F16SAMPLER2DARRAY = 457, /* F16SAMPLER2DARRAY */
F16SAMPLERCUBEARRAY = 458, /* F16SAMPLERCUBEARRAY */
F16SAMPLERBUFFER = 459, /* F16SAMPLERBUFFER */
F16SAMPLER2DMS = 460, /* F16SAMPLER2DMS */
F16SAMPLER2DMSARRAY = 461, /* F16SAMPLER2DMSARRAY */
F16SAMPLER1DSHADOW = 462, /* F16SAMPLER1DSHADOW */
F16SAMPLER2DSHADOW = 463, /* F16SAMPLER2DSHADOW */
F16SAMPLER1DARRAYSHADOW = 464, /* F16SAMPLER1DARRAYSHADOW */
F16SAMPLER2DARRAYSHADOW = 465, /* F16SAMPLER2DARRAYSHADOW */
F16SAMPLER2DRECTSHADOW = 466, /* F16SAMPLER2DRECTSHADOW */
F16SAMPLERCUBESHADOW = 467, /* F16SAMPLERCUBESHADOW */
F16SAMPLERCUBEARRAYSHADOW = 468, /* F16SAMPLERCUBEARRAYSHADOW */
IMAGE1D = 469, /* IMAGE1D */
IIMAGE1D = 470, /* IIMAGE1D */
UIMAGE1D = 471, /* UIMAGE1D */
IMAGE2D = 472, /* IMAGE2D */
IIMAGE2D = 473, /* IIMAGE2D */
UIMAGE2D = 474, /* UIMAGE2D */
IMAGE3D = 475, /* IMAGE3D */
IIMAGE3D = 476, /* IIMAGE3D */
UIMAGE3D = 477, /* UIMAGE3D */
IMAGE2DRECT = 478, /* IMAGE2DRECT */
IIMAGE2DRECT = 479, /* IIMAGE2DRECT */
UIMAGE2DRECT = 480, /* UIMAGE2DRECT */
IMAGECUBE = 481, /* IMAGECUBE */
IIMAGECUBE = 482, /* IIMAGECUBE */
UIMAGECUBE = 483, /* UIMAGECUBE */
IMAGEBUFFER = 484, /* IMAGEBUFFER */
IIMAGEBUFFER = 485, /* IIMAGEBUFFER */
UIMAGEBUFFER = 486, /* UIMAGEBUFFER */
IMAGE1DARRAY = 487, /* IMAGE1DARRAY */
IIMAGE1DARRAY = 488, /* IIMAGE1DARRAY */
UIMAGE1DARRAY = 489, /* UIMAGE1DARRAY */
IMAGE2DARRAY = 490, /* IMAGE2DARRAY */
IIMAGE2DARRAY = 491, /* IIMAGE2DARRAY */
UIMAGE2DARRAY = 492, /* UIMAGE2DARRAY */
IMAGECUBEARRAY = 493, /* IMAGECUBEARRAY */
IIMAGECUBEARRAY = 494, /* IIMAGECUBEARRAY */
UIMAGECUBEARRAY = 495, /* UIMAGECUBEARRAY */
IMAGE2DMS = 496, /* IMAGE2DMS */
IIMAGE2DMS = 497, /* IIMAGE2DMS */
UIMAGE2DMS = 498, /* UIMAGE2DMS */
IMAGE2DMSARRAY = 499, /* IMAGE2DMSARRAY */
IIMAGE2DMSARRAY = 500, /* IIMAGE2DMSARRAY */
UIMAGE2DMSARRAY = 501, /* UIMAGE2DMSARRAY */
F16IMAGE1D = 502, /* F16IMAGE1D */
F16IMAGE2D = 503, /* F16IMAGE2D */
F16IMAGE3D = 504, /* F16IMAGE3D */
F16IMAGE2DRECT = 505, /* F16IMAGE2DRECT */
F16IMAGECUBE = 506, /* F16IMAGECUBE */
F16IMAGE1DARRAY = 507, /* F16IMAGE1DARRAY */
F16IMAGE2DARRAY = 508, /* F16IMAGE2DARRAY */
F16IMAGECUBEARRAY = 509, /* F16IMAGECUBEARRAY */
F16IMAGEBUFFER = 510, /* F16IMAGEBUFFER */
F16IMAGE2DMS = 511, /* F16IMAGE2DMS */
F16IMAGE2DMSARRAY = 512, /* F16IMAGE2DMSARRAY */
I64IMAGE1D = 513, /* I64IMAGE1D */
U64IMAGE1D = 514, /* U64IMAGE1D */
I64IMAGE2D = 515, /* I64IMAGE2D */
U64IMAGE2D = 516, /* U64IMAGE2D */
I64IMAGE3D = 517, /* I64IMAGE3D */
U64IMAGE3D = 518, /* U64IMAGE3D */
I64IMAGE2DRECT = 519, /* I64IMAGE2DRECT */
U64IMAGE2DRECT = 520, /* U64IMAGE2DRECT */
I64IMAGECUBE = 521, /* I64IMAGECUBE */
U64IMAGECUBE = 522, /* U64IMAGECUBE */
I64IMAGEBUFFER = 523, /* I64IMAGEBUFFER */
U64IMAGEBUFFER = 524, /* U64IMAGEBUFFER */
I64IMAGE1DARRAY = 525, /* I64IMAGE1DARRAY */
U64IMAGE1DARRAY = 526, /* U64IMAGE1DARRAY */
I64IMAGE2DARRAY = 527, /* I64IMAGE2DARRAY */
U64IMAGE2DARRAY = 528, /* U64IMAGE2DARRAY */
I64IMAGECUBEARRAY = 529, /* I64IMAGECUBEARRAY */
U64IMAGECUBEARRAY = 530, /* U64IMAGECUBEARRAY */
I64IMAGE2DMS = 531, /* I64IMAGE2DMS */
U64IMAGE2DMS = 532, /* U64IMAGE2DMS */
I64IMAGE2DMSARRAY = 533, /* I64IMAGE2DMSARRAY */
U64IMAGE2DMSARRAY = 534, /* U64IMAGE2DMSARRAY */
TEXTURECUBEARRAY = 535, /* TEXTURECUBEARRAY */
ITEXTURECUBEARRAY = 536, /* ITEXTURECUBEARRAY */
UTEXTURECUBEARRAY = 537, /* UTEXTURECUBEARRAY */
TEXTURE1D = 538, /* TEXTURE1D */
ITEXTURE1D = 539, /* ITEXTURE1D */
UTEXTURE1D = 540, /* UTEXTURE1D */
TEXTURE1DARRAY = 541, /* TEXTURE1DARRAY */
ITEXTURE1DARRAY = 542, /* ITEXTURE1DARRAY */
UTEXTURE1DARRAY = 543, /* UTEXTURE1DARRAY */
TEXTURE2DRECT = 544, /* TEXTURE2DRECT */
ITEXTURE2DRECT = 545, /* ITEXTURE2DRECT */
UTEXTURE2DRECT = 546, /* UTEXTURE2DRECT */
TEXTUREBUFFER = 547, /* TEXTUREBUFFER */
ITEXTUREBUFFER = 548, /* ITEXTUREBUFFER */
UTEXTUREBUFFER = 549, /* UTEXTUREBUFFER */
TEXTURE2DMS = 550, /* TEXTURE2DMS */
ITEXTURE2DMS = 551, /* ITEXTURE2DMS */
UTEXTURE2DMS = 552, /* UTEXTURE2DMS */
TEXTURE2DMSARRAY = 553, /* TEXTURE2DMSARRAY */
ITEXTURE2DMSARRAY = 554, /* ITEXTURE2DMSARRAY */
UTEXTURE2DMSARRAY = 555, /* UTEXTURE2DMSARRAY */
F16TEXTURE1D = 556, /* F16TEXTURE1D */
F16TEXTURE2D = 557, /* F16TEXTURE2D */
F16TEXTURE3D = 558, /* F16TEXTURE3D */
F16TEXTURE2DRECT = 559, /* F16TEXTURE2DRECT */
F16TEXTURECUBE = 560, /* F16TEXTURECUBE */
F16TEXTURE1DARRAY = 561, /* F16TEXTURE1DARRAY */
F16TEXTURE2DARRAY = 562, /* F16TEXTURE2DARRAY */
F16TEXTURECUBEARRAY = 563, /* F16TEXTURECUBEARRAY */
F16TEXTUREBUFFER = 564, /* F16TEXTUREBUFFER */
F16TEXTURE2DMS = 565, /* F16TEXTURE2DMS */
F16TEXTURE2DMSARRAY = 566, /* F16TEXTURE2DMSARRAY */
SUBPASSINPUT = 567, /* SUBPASSINPUT */
SUBPASSINPUTMS = 568, /* SUBPASSINPUTMS */
ISUBPASSINPUT = 569, /* ISUBPASSINPUT */
ISUBPASSINPUTMS = 570, /* ISUBPASSINPUTMS */
USUBPASSINPUT = 571, /* USUBPASSINPUT */
USUBPASSINPUTMS = 572, /* USUBPASSINPUTMS */
F16SUBPASSINPUT = 573, /* F16SUBPASSINPUT */
F16SUBPASSINPUTMS = 574, /* F16SUBPASSINPUTMS */
SPIRV_INSTRUCTION = 575, /* SPIRV_INSTRUCTION */
SPIRV_EXECUTION_MODE = 576, /* SPIRV_EXECUTION_MODE */
SPIRV_EXECUTION_MODE_ID = 577, /* SPIRV_EXECUTION_MODE_ID */
SPIRV_DECORATE = 578, /* SPIRV_DECORATE */
SPIRV_DECORATE_ID = 579, /* SPIRV_DECORATE_ID */
SPIRV_DECORATE_STRING = 580, /* SPIRV_DECORATE_STRING */
SPIRV_TYPE = 581, /* SPIRV_TYPE */
SPIRV_STORAGE_CLASS = 582, /* SPIRV_STORAGE_CLASS */
SPIRV_BY_REFERENCE = 583, /* SPIRV_BY_REFERENCE */
SPIRV_LITERAL = 584, /* SPIRV_LITERAL */
ATTACHMENTEXT = 585, /* ATTACHMENTEXT */
IATTACHMENTEXT = 586, /* IATTACHMENTEXT */
UATTACHMENTEXT = 587, /* UATTACHMENTEXT */
LEFT_OP = 588, /* LEFT_OP */
RIGHT_OP = 589, /* RIGHT_OP */
INC_OP = 590, /* INC_OP */
DEC_OP = 591, /* DEC_OP */
LE_OP = 592, /* LE_OP */
GE_OP = 593, /* GE_OP */
EQ_OP = 594, /* EQ_OP */
NE_OP = 595, /* NE_OP */
AND_OP = 596, /* AND_OP */
OR_OP = 597, /* OR_OP */
XOR_OP = 598, /* XOR_OP */
MUL_ASSIGN = 599, /* MUL_ASSIGN */
DIV_ASSIGN = 600, /* DIV_ASSIGN */
ADD_ASSIGN = 601, /* ADD_ASSIGN */
MOD_ASSIGN = 602, /* MOD_ASSIGN */
LEFT_ASSIGN = 603, /* LEFT_ASSIGN */
RIGHT_ASSIGN = 604, /* RIGHT_ASSIGN */
AND_ASSIGN = 605, /* AND_ASSIGN */
XOR_ASSIGN = 606, /* XOR_ASSIGN */
OR_ASSIGN = 607, /* OR_ASSIGN */
SUB_ASSIGN = 608, /* SUB_ASSIGN */
STRING_LITERAL = 609, /* STRING_LITERAL */
LEFT_PAREN = 610, /* LEFT_PAREN */
RIGHT_PAREN = 611, /* RIGHT_PAREN */
LEFT_BRACKET = 612, /* LEFT_BRACKET */
RIGHT_BRACKET = 613, /* RIGHT_BRACKET */
LEFT_BRACE = 614, /* LEFT_BRACE */
RIGHT_BRACE = 615, /* RIGHT_BRACE */
DOT = 616, /* DOT */
COMMA = 617, /* COMMA */
COLON = 618, /* COLON */
EQUAL = 619, /* EQUAL */
SEMICOLON = 620, /* SEMICOLON */
BANG = 621, /* BANG */
DASH = 622, /* DASH */
TILDE = 623, /* TILDE */
PLUS = 624, /* PLUS */
STAR = 625, /* STAR */
SLASH = 626, /* SLASH */
PERCENT = 627, /* PERCENT */
LEFT_ANGLE = 628, /* LEFT_ANGLE */
RIGHT_ANGLE = 629, /* RIGHT_ANGLE */
VERTICAL_BAR = 630, /* VERTICAL_BAR */
CARET = 631, /* CARET */
AMPERSAND = 632, /* AMPERSAND */
QUESTION = 633, /* QUESTION */
INVARIANT = 634, /* INVARIANT */
HIGH_PRECISION = 635, /* HIGH_PRECISION */
MEDIUM_PRECISION = 636, /* MEDIUM_PRECISION */
LOW_PRECISION = 637, /* LOW_PRECISION */
PRECISION = 638, /* PRECISION */
PACKED = 639, /* PACKED */
RESOURCE = 640, /* RESOURCE */
SUPERP = 641, /* SUPERP */
FLOATCONSTANT = 642, /* FLOATCONSTANT */
INTCONSTANT = 643, /* INTCONSTANT */
UINTCONSTANT = 644, /* UINTCONSTANT */
BOOLCONSTANT = 645, /* BOOLCONSTANT */
IDENTIFIER = 646, /* IDENTIFIER */
TYPE_NAME = 647, /* TYPE_NAME */
CENTROID = 648, /* CENTROID */
IN = 649, /* IN */
OUT = 650, /* OUT */
INOUT = 651, /* INOUT */
STRUCT = 652, /* STRUCT */
VOID = 653, /* VOID */
WHILE = 654, /* WHILE */
BREAK = 655, /* BREAK */
CONTINUE = 656, /* CONTINUE */
DO = 657, /* DO */
ELSE = 658, /* ELSE */
FOR = 659, /* FOR */
IF = 660, /* IF */
DISCARD = 661, /* DISCARD */
RETURN = 662, /* RETURN */
SWITCH = 663, /* SWITCH */
CASE = 664, /* CASE */
DEFAULT = 665, /* DEFAULT */
TERMINATE_INVOCATION = 666, /* TERMINATE_INVOCATION */
TERMINATE_RAY = 667, /* TERMINATE_RAY */
IGNORE_INTERSECTION = 668, /* IGNORE_INTERSECTION */
UNIFORM = 669, /* UNIFORM */
SHARED = 670, /* SHARED */
BUFFER = 671, /* BUFFER */
TILEIMAGEEXT = 672, /* TILEIMAGEEXT */
FLAT = 673, /* FLAT */
SMOOTH = 674, /* SMOOTH */
LAYOUT = 675, /* LAYOUT */
DOUBLECONSTANT = 676, /* DOUBLECONSTANT */
INT16CONSTANT = 677, /* INT16CONSTANT */
UINT16CONSTANT = 678, /* UINT16CONSTANT */
FLOAT16CONSTANT = 679, /* FLOAT16CONSTANT */
INT32CONSTANT = 680, /* INT32CONSTANT */
UINT32CONSTANT = 681, /* UINT32CONSTANT */
INT64CONSTANT = 682, /* INT64CONSTANT */
UINT64CONSTANT = 683, /* UINT64CONSTANT */
SUBROUTINE = 684, /* SUBROUTINE */
DEMOTE = 685, /* DEMOTE */
PAYLOADNV = 686, /* PAYLOADNV */
PAYLOADINNV = 687, /* PAYLOADINNV */
HITATTRNV = 688, /* HITATTRNV */
CALLDATANV = 689, /* CALLDATANV */
CALLDATAINNV = 690, /* CALLDATAINNV */
PAYLOADEXT = 691, /* PAYLOADEXT */
PAYLOADINEXT = 692, /* PAYLOADINEXT */
HITATTREXT = 693, /* HITATTREXT */
CALLDATAEXT = 694, /* CALLDATAEXT */
CALLDATAINEXT = 695, /* CALLDATAINEXT */
PATCH = 696, /* PATCH */
SAMPLE = 697, /* SAMPLE */
NONUNIFORM = 698, /* NONUNIFORM */
COHERENT = 699, /* COHERENT */
VOLATILE = 700, /* VOLATILE */
RESTRICT = 701, /* RESTRICT */
READONLY = 702, /* READONLY */
WRITEONLY = 703, /* WRITEONLY */
DEVICECOHERENT = 704, /* DEVICECOHERENT */
QUEUEFAMILYCOHERENT = 705, /* QUEUEFAMILYCOHERENT */
WORKGROUPCOHERENT = 706, /* WORKGROUPCOHERENT */
SUBGROUPCOHERENT = 707, /* SUBGROUPCOHERENT */
NONPRIVATE = 708, /* NONPRIVATE */
SHADERCALLCOHERENT = 709, /* SHADERCALLCOHERENT */
NOPERSPECTIVE = 710, /* NOPERSPECTIVE */
EXPLICITINTERPAMD = 711, /* EXPLICITINTERPAMD */
PERVERTEXEXT = 712, /* PERVERTEXEXT */
PERVERTEXNV = 713, /* PERVERTEXNV */
PERPRIMITIVENV = 714, /* PERPRIMITIVENV */
PERVIEWNV = 715, /* PERVIEWNV */
PERTASKNV = 716, /* PERTASKNV */
PERPRIMITIVEEXT = 717, /* PERPRIMITIVEEXT */
TASKPAYLOADWORKGROUPEXT = 718, /* TASKPAYLOADWORKGROUPEXT */
PRECISE = 719 /* PRECISE */
FLOATE5M2_T = 318, /* FLOATE5M2_T */
FLOATE4M3_T = 319, /* FLOATE4M3_T */
BFLOAT16_T = 320, /* BFLOAT16_T */
FLOAT16_T = 321, /* FLOAT16_T */
FLOAT32_T = 322, /* FLOAT32_T */
DOUBLE = 323, /* DOUBLE */
FLOAT64_T = 324, /* FLOAT64_T */
INT64_T = 325, /* INT64_T */
UINT64_T = 326, /* UINT64_T */
INT32_T = 327, /* INT32_T */
UINT32_T = 328, /* UINT32_T */
INT16_T = 329, /* INT16_T */
UINT16_T = 330, /* UINT16_T */
INT8_T = 331, /* INT8_T */
UINT8_T = 332, /* UINT8_T */
I64VEC2 = 333, /* I64VEC2 */
I64VEC3 = 334, /* I64VEC3 */
I64VEC4 = 335, /* I64VEC4 */
U64VEC2 = 336, /* U64VEC2 */
U64VEC3 = 337, /* U64VEC3 */
U64VEC4 = 338, /* U64VEC4 */
I32VEC2 = 339, /* I32VEC2 */
I32VEC3 = 340, /* I32VEC3 */
I32VEC4 = 341, /* I32VEC4 */
U32VEC2 = 342, /* U32VEC2 */
U32VEC3 = 343, /* U32VEC3 */
U32VEC4 = 344, /* U32VEC4 */
I16VEC2 = 345, /* I16VEC2 */
I16VEC3 = 346, /* I16VEC3 */
I16VEC4 = 347, /* I16VEC4 */
U16VEC2 = 348, /* U16VEC2 */
U16VEC3 = 349, /* U16VEC3 */
U16VEC4 = 350, /* U16VEC4 */
I8VEC2 = 351, /* I8VEC2 */
I8VEC3 = 352, /* I8VEC3 */
I8VEC4 = 353, /* I8VEC4 */
U8VEC2 = 354, /* U8VEC2 */
U8VEC3 = 355, /* U8VEC3 */
U8VEC4 = 356, /* U8VEC4 */
DVEC2 = 357, /* DVEC2 */
DVEC3 = 358, /* DVEC3 */
DVEC4 = 359, /* DVEC4 */
DMAT2 = 360, /* DMAT2 */
DMAT3 = 361, /* DMAT3 */
DMAT4 = 362, /* DMAT4 */
BF16VEC2 = 363, /* BF16VEC2 */
BF16VEC3 = 364, /* BF16VEC3 */
BF16VEC4 = 365, /* BF16VEC4 */
FE5M2VEC2 = 366, /* FE5M2VEC2 */
FE5M2VEC3 = 367, /* FE5M2VEC3 */
FE5M2VEC4 = 368, /* FE5M2VEC4 */
FE4M3VEC2 = 369, /* FE4M3VEC2 */
FE4M3VEC3 = 370, /* FE4M3VEC3 */
FE4M3VEC4 = 371, /* FE4M3VEC4 */
F16VEC2 = 372, /* F16VEC2 */
F16VEC3 = 373, /* F16VEC3 */
F16VEC4 = 374, /* F16VEC4 */
F16MAT2 = 375, /* F16MAT2 */
F16MAT3 = 376, /* F16MAT3 */
F16MAT4 = 377, /* F16MAT4 */
F32VEC2 = 378, /* F32VEC2 */
F32VEC3 = 379, /* F32VEC3 */
F32VEC4 = 380, /* F32VEC4 */
F32MAT2 = 381, /* F32MAT2 */
F32MAT3 = 382, /* F32MAT3 */
F32MAT4 = 383, /* F32MAT4 */
F64VEC2 = 384, /* F64VEC2 */
F64VEC3 = 385, /* F64VEC3 */
F64VEC4 = 386, /* F64VEC4 */
F64MAT2 = 387, /* F64MAT2 */
F64MAT3 = 388, /* F64MAT3 */
F64MAT4 = 389, /* F64MAT4 */
DMAT2X2 = 390, /* DMAT2X2 */
DMAT2X3 = 391, /* DMAT2X3 */
DMAT2X4 = 392, /* DMAT2X4 */
DMAT3X2 = 393, /* DMAT3X2 */
DMAT3X3 = 394, /* DMAT3X3 */
DMAT3X4 = 395, /* DMAT3X4 */
DMAT4X2 = 396, /* DMAT4X2 */
DMAT4X3 = 397, /* DMAT4X3 */
DMAT4X4 = 398, /* DMAT4X4 */
F16MAT2X2 = 399, /* F16MAT2X2 */
F16MAT2X3 = 400, /* F16MAT2X3 */
F16MAT2X4 = 401, /* F16MAT2X4 */
F16MAT3X2 = 402, /* F16MAT3X2 */
F16MAT3X3 = 403, /* F16MAT3X3 */
F16MAT3X4 = 404, /* F16MAT3X4 */
F16MAT4X2 = 405, /* F16MAT4X2 */
F16MAT4X3 = 406, /* F16MAT4X3 */
F16MAT4X4 = 407, /* F16MAT4X4 */
F32MAT2X2 = 408, /* F32MAT2X2 */
F32MAT2X3 = 409, /* F32MAT2X3 */
F32MAT2X4 = 410, /* F32MAT2X4 */
F32MAT3X2 = 411, /* F32MAT3X2 */
F32MAT3X3 = 412, /* F32MAT3X3 */
F32MAT3X4 = 413, /* F32MAT3X4 */
F32MAT4X2 = 414, /* F32MAT4X2 */
F32MAT4X3 = 415, /* F32MAT4X3 */
F32MAT4X4 = 416, /* F32MAT4X4 */
F64MAT2X2 = 417, /* F64MAT2X2 */
F64MAT2X3 = 418, /* F64MAT2X3 */
F64MAT2X4 = 419, /* F64MAT2X4 */
F64MAT3X2 = 420, /* F64MAT3X2 */
F64MAT3X3 = 421, /* F64MAT3X3 */
F64MAT3X4 = 422, /* F64MAT3X4 */
F64MAT4X2 = 423, /* F64MAT4X2 */
F64MAT4X3 = 424, /* F64MAT4X3 */
F64MAT4X4 = 425, /* F64MAT4X4 */
ATOMIC_UINT = 426, /* ATOMIC_UINT */
ACCSTRUCTNV = 427, /* ACCSTRUCTNV */
ACCSTRUCTEXT = 428, /* ACCSTRUCTEXT */
RAYQUERYEXT = 429, /* RAYQUERYEXT */
FCOOPMATNV = 430, /* FCOOPMATNV */
ICOOPMATNV = 431, /* ICOOPMATNV */
UCOOPMATNV = 432, /* UCOOPMATNV */
COOPMAT = 433, /* COOPMAT */
COOPVECNV = 434, /* COOPVECNV */
HITOBJECTNV = 435, /* HITOBJECTNV */
HITOBJECTATTRNV = 436, /* HITOBJECTATTRNV */
HITOBJECTEXT = 437, /* HITOBJECTEXT */
HITOBJECTATTREXT = 438, /* HITOBJECTATTREXT */
TENSORLAYOUTNV = 439, /* TENSORLAYOUTNV */
TENSORVIEWNV = 440, /* TENSORVIEWNV */
TENSORARM = 441, /* TENSORARM */
SAMPLERCUBEARRAY = 442, /* SAMPLERCUBEARRAY */
SAMPLERCUBEARRAYSHADOW = 443, /* SAMPLERCUBEARRAYSHADOW */
ISAMPLERCUBEARRAY = 444, /* ISAMPLERCUBEARRAY */
USAMPLERCUBEARRAY = 445, /* USAMPLERCUBEARRAY */
SAMPLER1D = 446, /* SAMPLER1D */
SAMPLER1DARRAY = 447, /* SAMPLER1DARRAY */
SAMPLER1DARRAYSHADOW = 448, /* SAMPLER1DARRAYSHADOW */
ISAMPLER1D = 449, /* ISAMPLER1D */
SAMPLER1DSHADOW = 450, /* SAMPLER1DSHADOW */
SAMPLER2DRECT = 451, /* SAMPLER2DRECT */
SAMPLER2DRECTSHADOW = 452, /* SAMPLER2DRECTSHADOW */
ISAMPLER2DRECT = 453, /* ISAMPLER2DRECT */
USAMPLER2DRECT = 454, /* USAMPLER2DRECT */
SAMPLERBUFFER = 455, /* SAMPLERBUFFER */
ISAMPLERBUFFER = 456, /* ISAMPLERBUFFER */
USAMPLERBUFFER = 457, /* USAMPLERBUFFER */
SAMPLER2DMS = 458, /* SAMPLER2DMS */
ISAMPLER2DMS = 459, /* ISAMPLER2DMS */
USAMPLER2DMS = 460, /* USAMPLER2DMS */
SAMPLER2DMSARRAY = 461, /* SAMPLER2DMSARRAY */
ISAMPLER2DMSARRAY = 462, /* ISAMPLER2DMSARRAY */
USAMPLER2DMSARRAY = 463, /* USAMPLER2DMSARRAY */
SAMPLEREXTERNALOES = 464, /* SAMPLEREXTERNALOES */
SAMPLEREXTERNAL2DY2YEXT = 465, /* SAMPLEREXTERNAL2DY2YEXT */
ISAMPLER1DARRAY = 466, /* ISAMPLER1DARRAY */
USAMPLER1D = 467, /* USAMPLER1D */
USAMPLER1DARRAY = 468, /* USAMPLER1DARRAY */
F16SAMPLER1D = 469, /* F16SAMPLER1D */
F16SAMPLER2D = 470, /* F16SAMPLER2D */
F16SAMPLER3D = 471, /* F16SAMPLER3D */
F16SAMPLER2DRECT = 472, /* F16SAMPLER2DRECT */
F16SAMPLERCUBE = 473, /* F16SAMPLERCUBE */
F16SAMPLER1DARRAY = 474, /* F16SAMPLER1DARRAY */
F16SAMPLER2DARRAY = 475, /* F16SAMPLER2DARRAY */
F16SAMPLERCUBEARRAY = 476, /* F16SAMPLERCUBEARRAY */
F16SAMPLERBUFFER = 477, /* F16SAMPLERBUFFER */
F16SAMPLER2DMS = 478, /* F16SAMPLER2DMS */
F16SAMPLER2DMSARRAY = 479, /* F16SAMPLER2DMSARRAY */
F16SAMPLER1DSHADOW = 480, /* F16SAMPLER1DSHADOW */
F16SAMPLER2DSHADOW = 481, /* F16SAMPLER2DSHADOW */
F16SAMPLER1DARRAYSHADOW = 482, /* F16SAMPLER1DARRAYSHADOW */
F16SAMPLER2DARRAYSHADOW = 483, /* F16SAMPLER2DARRAYSHADOW */
F16SAMPLER2DRECTSHADOW = 484, /* F16SAMPLER2DRECTSHADOW */
F16SAMPLERCUBESHADOW = 485, /* F16SAMPLERCUBESHADOW */
F16SAMPLERCUBEARRAYSHADOW = 486, /* F16SAMPLERCUBEARRAYSHADOW */
IMAGE1D = 487, /* IMAGE1D */
IIMAGE1D = 488, /* IIMAGE1D */
UIMAGE1D = 489, /* UIMAGE1D */
IMAGE2D = 490, /* IMAGE2D */
IIMAGE2D = 491, /* IIMAGE2D */
UIMAGE2D = 492, /* UIMAGE2D */
IMAGE3D = 493, /* IMAGE3D */
IIMAGE3D = 494, /* IIMAGE3D */
UIMAGE3D = 495, /* UIMAGE3D */
IMAGE2DRECT = 496, /* IMAGE2DRECT */
IIMAGE2DRECT = 497, /* IIMAGE2DRECT */
UIMAGE2DRECT = 498, /* UIMAGE2DRECT */
IMAGECUBE = 499, /* IMAGECUBE */
IIMAGECUBE = 500, /* IIMAGECUBE */
UIMAGECUBE = 501, /* UIMAGECUBE */
IMAGEBUFFER = 502, /* IMAGEBUFFER */
IIMAGEBUFFER = 503, /* IIMAGEBUFFER */
UIMAGEBUFFER = 504, /* UIMAGEBUFFER */
IMAGE1DARRAY = 505, /* IMAGE1DARRAY */
IIMAGE1DARRAY = 506, /* IIMAGE1DARRAY */
UIMAGE1DARRAY = 507, /* UIMAGE1DARRAY */
IMAGE2DARRAY = 508, /* IMAGE2DARRAY */
IIMAGE2DARRAY = 509, /* IIMAGE2DARRAY */
UIMAGE2DARRAY = 510, /* UIMAGE2DARRAY */
IMAGECUBEARRAY = 511, /* IMAGECUBEARRAY */
IIMAGECUBEARRAY = 512, /* IIMAGECUBEARRAY */
UIMAGECUBEARRAY = 513, /* UIMAGECUBEARRAY */
IMAGE2DMS = 514, /* IMAGE2DMS */
IIMAGE2DMS = 515, /* IIMAGE2DMS */
UIMAGE2DMS = 516, /* UIMAGE2DMS */
IMAGE2DMSARRAY = 517, /* IMAGE2DMSARRAY */
IIMAGE2DMSARRAY = 518, /* IIMAGE2DMSARRAY */
UIMAGE2DMSARRAY = 519, /* UIMAGE2DMSARRAY */
F16IMAGE1D = 520, /* F16IMAGE1D */
F16IMAGE2D = 521, /* F16IMAGE2D */
F16IMAGE3D = 522, /* F16IMAGE3D */
F16IMAGE2DRECT = 523, /* F16IMAGE2DRECT */
F16IMAGECUBE = 524, /* F16IMAGECUBE */
F16IMAGE1DARRAY = 525, /* F16IMAGE1DARRAY */
F16IMAGE2DARRAY = 526, /* F16IMAGE2DARRAY */
F16IMAGECUBEARRAY = 527, /* F16IMAGECUBEARRAY */
F16IMAGEBUFFER = 528, /* F16IMAGEBUFFER */
F16IMAGE2DMS = 529, /* F16IMAGE2DMS */
F16IMAGE2DMSARRAY = 530, /* F16IMAGE2DMSARRAY */
I64IMAGE1D = 531, /* I64IMAGE1D */
U64IMAGE1D = 532, /* U64IMAGE1D */
I64IMAGE2D = 533, /* I64IMAGE2D */
U64IMAGE2D = 534, /* U64IMAGE2D */
I64IMAGE3D = 535, /* I64IMAGE3D */
U64IMAGE3D = 536, /* U64IMAGE3D */
I64IMAGE2DRECT = 537, /* I64IMAGE2DRECT */
U64IMAGE2DRECT = 538, /* U64IMAGE2DRECT */
I64IMAGECUBE = 539, /* I64IMAGECUBE */
U64IMAGECUBE = 540, /* U64IMAGECUBE */
I64IMAGEBUFFER = 541, /* I64IMAGEBUFFER */
U64IMAGEBUFFER = 542, /* U64IMAGEBUFFER */
I64IMAGE1DARRAY = 543, /* I64IMAGE1DARRAY */
U64IMAGE1DARRAY = 544, /* U64IMAGE1DARRAY */
I64IMAGE2DARRAY = 545, /* I64IMAGE2DARRAY */
U64IMAGE2DARRAY = 546, /* U64IMAGE2DARRAY */
I64IMAGECUBEARRAY = 547, /* I64IMAGECUBEARRAY */
U64IMAGECUBEARRAY = 548, /* U64IMAGECUBEARRAY */
I64IMAGE2DMS = 549, /* I64IMAGE2DMS */
U64IMAGE2DMS = 550, /* U64IMAGE2DMS */
I64IMAGE2DMSARRAY = 551, /* I64IMAGE2DMSARRAY */
U64IMAGE2DMSARRAY = 552, /* U64IMAGE2DMSARRAY */
TEXTURECUBEARRAY = 553, /* TEXTURECUBEARRAY */
ITEXTURECUBEARRAY = 554, /* ITEXTURECUBEARRAY */
UTEXTURECUBEARRAY = 555, /* UTEXTURECUBEARRAY */
TEXTURE1D = 556, /* TEXTURE1D */
ITEXTURE1D = 557, /* ITEXTURE1D */
UTEXTURE1D = 558, /* UTEXTURE1D */
TEXTURE1DARRAY = 559, /* TEXTURE1DARRAY */
ITEXTURE1DARRAY = 560, /* ITEXTURE1DARRAY */
UTEXTURE1DARRAY = 561, /* UTEXTURE1DARRAY */
TEXTURE2DRECT = 562, /* TEXTURE2DRECT */
ITEXTURE2DRECT = 563, /* ITEXTURE2DRECT */
UTEXTURE2DRECT = 564, /* UTEXTURE2DRECT */
TEXTUREBUFFER = 565, /* TEXTUREBUFFER */
ITEXTUREBUFFER = 566, /* ITEXTUREBUFFER */
UTEXTUREBUFFER = 567, /* UTEXTUREBUFFER */
TEXTURE2DMS = 568, /* TEXTURE2DMS */
ITEXTURE2DMS = 569, /* ITEXTURE2DMS */
UTEXTURE2DMS = 570, /* UTEXTURE2DMS */
TEXTURE2DMSARRAY = 571, /* TEXTURE2DMSARRAY */
ITEXTURE2DMSARRAY = 572, /* ITEXTURE2DMSARRAY */
UTEXTURE2DMSARRAY = 573, /* UTEXTURE2DMSARRAY */
F16TEXTURE1D = 574, /* F16TEXTURE1D */
F16TEXTURE2D = 575, /* F16TEXTURE2D */
F16TEXTURE3D = 576, /* F16TEXTURE3D */
F16TEXTURE2DRECT = 577, /* F16TEXTURE2DRECT */
F16TEXTURECUBE = 578, /* F16TEXTURECUBE */
F16TEXTURE1DARRAY = 579, /* F16TEXTURE1DARRAY */
F16TEXTURE2DARRAY = 580, /* F16TEXTURE2DARRAY */
F16TEXTURECUBEARRAY = 581, /* F16TEXTURECUBEARRAY */
F16TEXTUREBUFFER = 582, /* F16TEXTUREBUFFER */
F16TEXTURE2DMS = 583, /* F16TEXTURE2DMS */
F16TEXTURE2DMSARRAY = 584, /* F16TEXTURE2DMSARRAY */
SUBPASSINPUT = 585, /* SUBPASSINPUT */
SUBPASSINPUTMS = 586, /* SUBPASSINPUTMS */
ISUBPASSINPUT = 587, /* ISUBPASSINPUT */
ISUBPASSINPUTMS = 588, /* ISUBPASSINPUTMS */
USUBPASSINPUT = 589, /* USUBPASSINPUT */
USUBPASSINPUTMS = 590, /* USUBPASSINPUTMS */
F16SUBPASSINPUT = 591, /* F16SUBPASSINPUT */
F16SUBPASSINPUTMS = 592, /* F16SUBPASSINPUTMS */
SPIRV_INSTRUCTION = 593, /* SPIRV_INSTRUCTION */
SPIRV_EXECUTION_MODE = 594, /* SPIRV_EXECUTION_MODE */
SPIRV_EXECUTION_MODE_ID = 595, /* SPIRV_EXECUTION_MODE_ID */
SPIRV_DECORATE = 596, /* SPIRV_DECORATE */
SPIRV_DECORATE_ID = 597, /* SPIRV_DECORATE_ID */
SPIRV_DECORATE_STRING = 598, /* SPIRV_DECORATE_STRING */
SPIRV_TYPE = 599, /* SPIRV_TYPE */
SPIRV_STORAGE_CLASS = 600, /* SPIRV_STORAGE_CLASS */
SPIRV_BY_REFERENCE = 601, /* SPIRV_BY_REFERENCE */
SPIRV_LITERAL = 602, /* SPIRV_LITERAL */
ATTACHMENTEXT = 603, /* ATTACHMENTEXT */
IATTACHMENTEXT = 604, /* IATTACHMENTEXT */
UATTACHMENTEXT = 605, /* UATTACHMENTEXT */
LEFT_OP = 606, /* LEFT_OP */
RIGHT_OP = 607, /* RIGHT_OP */
INC_OP = 608, /* INC_OP */
DEC_OP = 609, /* DEC_OP */
LE_OP = 610, /* LE_OP */
GE_OP = 611, /* GE_OP */
EQ_OP = 612, /* EQ_OP */
NE_OP = 613, /* NE_OP */
AND_OP = 614, /* AND_OP */
OR_OP = 615, /* OR_OP */
XOR_OP = 616, /* XOR_OP */
MUL_ASSIGN = 617, /* MUL_ASSIGN */
DIV_ASSIGN = 618, /* DIV_ASSIGN */
ADD_ASSIGN = 619, /* ADD_ASSIGN */
MOD_ASSIGN = 620, /* MOD_ASSIGN */
LEFT_ASSIGN = 621, /* LEFT_ASSIGN */
RIGHT_ASSIGN = 622, /* RIGHT_ASSIGN */
AND_ASSIGN = 623, /* AND_ASSIGN */
XOR_ASSIGN = 624, /* XOR_ASSIGN */
OR_ASSIGN = 625, /* OR_ASSIGN */
SUB_ASSIGN = 626, /* SUB_ASSIGN */
STRING_LITERAL = 627, /* STRING_LITERAL */
LEFT_PAREN = 628, /* LEFT_PAREN */
RIGHT_PAREN = 629, /* RIGHT_PAREN */
LEFT_BRACKET = 630, /* LEFT_BRACKET */
RIGHT_BRACKET = 631, /* RIGHT_BRACKET */
LEFT_BRACE = 632, /* LEFT_BRACE */
RIGHT_BRACE = 633, /* RIGHT_BRACE */
DOT = 634, /* DOT */
COMMA = 635, /* COMMA */
COLON = 636, /* COLON */
EQUAL = 637, /* EQUAL */
SEMICOLON = 638, /* SEMICOLON */
BANG = 639, /* BANG */
DASH = 640, /* DASH */
TILDE = 641, /* TILDE */
PLUS = 642, /* PLUS */
STAR = 643, /* STAR */
SLASH = 644, /* SLASH */
PERCENT = 645, /* PERCENT */
LEFT_ANGLE = 646, /* LEFT_ANGLE */
RIGHT_ANGLE = 647, /* RIGHT_ANGLE */
VERTICAL_BAR = 648, /* VERTICAL_BAR */
CARET = 649, /* CARET */
AMPERSAND = 650, /* AMPERSAND */
QUESTION = 651, /* QUESTION */
INVARIANT = 652, /* INVARIANT */
HIGH_PRECISION = 653, /* HIGH_PRECISION */
MEDIUM_PRECISION = 654, /* MEDIUM_PRECISION */
LOW_PRECISION = 655, /* LOW_PRECISION */
PRECISION = 656, /* PRECISION */
PACKED = 657, /* PACKED */
RESOURCE = 658, /* RESOURCE */
SUPERP = 659, /* SUPERP */
FLOATCONSTANT = 660, /* FLOATCONSTANT */
INTCONSTANT = 661, /* INTCONSTANT */
UINTCONSTANT = 662, /* UINTCONSTANT */
BOOLCONSTANT = 663, /* BOOLCONSTANT */
IDENTIFIER = 664, /* IDENTIFIER */
TYPE_NAME = 665, /* TYPE_NAME */
CENTROID = 666, /* CENTROID */
IN = 667, /* IN */
OUT = 668, /* OUT */
INOUT = 669, /* INOUT */
STRUCT = 670, /* STRUCT */
VOID = 671, /* VOID */
WHILE = 672, /* WHILE */
BREAK = 673, /* BREAK */
CONTINUE = 674, /* CONTINUE */
DO = 675, /* DO */
ELSE = 676, /* ELSE */
FOR = 677, /* FOR */
IF = 678, /* IF */
DISCARD = 679, /* DISCARD */
RETURN = 680, /* RETURN */
SWITCH = 681, /* SWITCH */
CASE = 682, /* CASE */
DEFAULT = 683, /* DEFAULT */
TERMINATE_INVOCATION = 684, /* TERMINATE_INVOCATION */
TERMINATE_RAY = 685, /* TERMINATE_RAY */
IGNORE_INTERSECTION = 686, /* IGNORE_INTERSECTION */
UNIFORM = 687, /* UNIFORM */
SHARED = 688, /* SHARED */
BUFFER = 689, /* BUFFER */
TILEIMAGEEXT = 690, /* TILEIMAGEEXT */
FLAT = 691, /* FLAT */
SMOOTH = 692, /* SMOOTH */
LAYOUT = 693, /* LAYOUT */
DOUBLECONSTANT = 694, /* DOUBLECONSTANT */
INT16CONSTANT = 695, /* INT16CONSTANT */
UINT16CONSTANT = 696, /* UINT16CONSTANT */
FLOAT16CONSTANT = 697, /* FLOAT16CONSTANT */
INT32CONSTANT = 698, /* INT32CONSTANT */
UINT32CONSTANT = 699, /* UINT32CONSTANT */
INT64CONSTANT = 700, /* INT64CONSTANT */
UINT64CONSTANT = 701, /* UINT64CONSTANT */
SUBROUTINE = 702, /* SUBROUTINE */
DEMOTE = 703, /* DEMOTE */
FUNCTION = 704, /* FUNCTION */
PAYLOADNV = 705, /* PAYLOADNV */
PAYLOADINNV = 706, /* PAYLOADINNV */
HITATTRNV = 707, /* HITATTRNV */
CALLDATANV = 708, /* CALLDATANV */
CALLDATAINNV = 709, /* CALLDATAINNV */
PAYLOADEXT = 710, /* PAYLOADEXT */
PAYLOADINEXT = 711, /* PAYLOADINEXT */
HITATTREXT = 712, /* HITATTREXT */
CALLDATAEXT = 713, /* CALLDATAEXT */
CALLDATAINEXT = 714, /* CALLDATAINEXT */
PATCH = 715, /* PATCH */
SAMPLE = 716, /* SAMPLE */
NONUNIFORM = 717, /* NONUNIFORM */
COHERENT = 718, /* COHERENT */
VOLATILE = 719, /* VOLATILE */
RESTRICT = 720, /* RESTRICT */
READONLY = 721, /* READONLY */
WRITEONLY = 722, /* WRITEONLY */
NONTEMPORAL = 723, /* NONTEMPORAL */
DEVICECOHERENT = 724, /* DEVICECOHERENT */
QUEUEFAMILYCOHERENT = 725, /* QUEUEFAMILYCOHERENT */
WORKGROUPCOHERENT = 726, /* WORKGROUPCOHERENT */
SUBGROUPCOHERENT = 727, /* SUBGROUPCOHERENT */
NONPRIVATE = 728, /* NONPRIVATE */
SHADERCALLCOHERENT = 729, /* SHADERCALLCOHERENT */
NOPERSPECTIVE = 730, /* NOPERSPECTIVE */
EXPLICITINTERPAMD = 731, /* EXPLICITINTERPAMD */
PERVERTEXEXT = 732, /* PERVERTEXEXT */
PERVERTEXNV = 733, /* PERVERTEXNV */
PERPRIMITIVENV = 734, /* PERPRIMITIVENV */
PERVIEWNV = 735, /* PERVIEWNV */
PERTASKNV = 736, /* PERTASKNV */
PERPRIMITIVEEXT = 737, /* PERPRIMITIVEEXT */
TASKPAYLOADWORKGROUPEXT = 738, /* TASKPAYLOADWORKGROUPEXT */
PRECISE = 739 /* PRECISE */
};
typedef enum yytokentype yytoken_kind_t;
#endif
@ -563,7 +583,7 @@ union YYSTYPE
glslang::TTypeParameters* typeParameters;
} interm;
#line 567 "MachineIndependent/glslang_tab.cpp.h"
#line 587 "MachineIndependent/glslang_tab.cpp.h"
};
typedef union YYSTYPE YYSTYPE;

View file

@ -81,6 +81,7 @@ public:
virtual bool visitLoop(TVisit, TIntermLoop* node);
virtual bool visitBranch(TVisit, TIntermBranch* node);
virtual bool visitSwitch(TVisit, TIntermSwitch* node);
virtual bool visitVariableDecl(TVisit, TIntermVariableDecl* node);
TInfoSink& infoSink;
protected:
@ -204,6 +205,13 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
OutputTreeText(out, node, depth);
if (IsOpNumericConv(node->getAsOperator()->getOp())) {
out.debug << "Convert " << TType::getBasicString(node->getOperand()->getType().getBasicType()) << " to " << TType::getBasicString(node->getType().getBasicType());
out.debug << " (" << node->getCompleteString() << ")";
out.debug << "\n";
return true;
}
switch (node->getOp()) {
case EOpNegative: out.debug << "Negate value"; break;
case EOpVectorLogicalNot:
@ -216,192 +224,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpPreDecrement: out.debug << "Pre-Decrement"; break;
case EOpCopyObject: out.debug << "copy object"; break;
// * -> bool
case EOpConvInt8ToBool: out.debug << "Convert int8_t to bool"; break;
case EOpConvUint8ToBool: out.debug << "Convert uint8_t to bool"; break;
case EOpConvInt16ToBool: out.debug << "Convert int16_t to bool"; break;
case EOpConvUint16ToBool: out.debug << "Convert uint16_t to bool";break;
case EOpConvIntToBool: out.debug << "Convert int to bool"; break;
case EOpConvUintToBool: out.debug << "Convert uint to bool"; break;
case EOpConvInt64ToBool: out.debug << "Convert int64 to bool"; break;
case EOpConvUint64ToBool: out.debug << "Convert uint64 to bool"; break;
case EOpConvFloat16ToBool: out.debug << "Convert float16_t to bool"; break;
case EOpConvFloatToBool: out.debug << "Convert float to bool"; break;
case EOpConvDoubleToBool: out.debug << "Convert double to bool"; break;
// bool -> *
case EOpConvBoolToInt8: out.debug << "Convert bool to int8_t"; break;
case EOpConvBoolToUint8: out.debug << "Convert bool to uint8_t"; break;
case EOpConvBoolToInt16: out.debug << "Convert bool to in16t_t"; break;
case EOpConvBoolToUint16: out.debug << "Convert bool to uint16_t";break;
case EOpConvBoolToInt: out.debug << "Convert bool to int" ; break;
case EOpConvBoolToUint: out.debug << "Convert bool to uint"; break;
case EOpConvBoolToInt64: out.debug << "Convert bool to int64"; break;
case EOpConvBoolToUint64: out.debug << "Convert bool to uint64";break;
case EOpConvBoolToFloat16: out.debug << "Convert bool to float16_t"; break;
case EOpConvBoolToFloat: out.debug << "Convert bool to float"; break;
case EOpConvBoolToDouble: out.debug << "Convert bool to double"; break;
// int8_t -> (u)int*
case EOpConvInt8ToInt16: out.debug << "Convert int8_t to int16_t";break;
case EOpConvInt8ToInt: out.debug << "Convert int8_t to int"; break;
case EOpConvInt8ToInt64: out.debug << "Convert int8_t to int64"; break;
case EOpConvInt8ToUint8: out.debug << "Convert int8_t to uint8_t";break;
case EOpConvInt8ToUint16: out.debug << "Convert int8_t to uint16_t";break;
case EOpConvInt8ToUint: out.debug << "Convert int8_t to uint"; break;
case EOpConvInt8ToUint64: out.debug << "Convert int8_t to uint64"; break;
// uint8_t -> (u)int*
case EOpConvUint8ToInt8: out.debug << "Convert uint8_t to int8_t";break;
case EOpConvUint8ToInt16: out.debug << "Convert uint8_t to int16_t";break;
case EOpConvUint8ToInt: out.debug << "Convert uint8_t to int"; break;
case EOpConvUint8ToInt64: out.debug << "Convert uint8_t to int64"; break;
case EOpConvUint8ToUint16: out.debug << "Convert uint8_t to uint16_t";break;
case EOpConvUint8ToUint: out.debug << "Convert uint8_t to uint"; break;
case EOpConvUint8ToUint64: out.debug << "Convert uint8_t to uint64"; break;
// int8_t -> float*
case EOpConvInt8ToFloat16: out.debug << "Convert int8_t to float16_t";break;
case EOpConvInt8ToFloat: out.debug << "Convert int8_t to float"; break;
case EOpConvInt8ToDouble: out.debug << "Convert int8_t to double"; break;
// uint8_t -> float*
case EOpConvUint8ToFloat16: out.debug << "Convert uint8_t to float16_t";break;
case EOpConvUint8ToFloat: out.debug << "Convert uint8_t to float"; break;
case EOpConvUint8ToDouble: out.debug << "Convert uint8_t to double"; break;
// int16_t -> (u)int*
case EOpConvInt16ToInt8: out.debug << "Convert int16_t to int8_t";break;
case EOpConvInt16ToInt: out.debug << "Convert int16_t to int"; break;
case EOpConvInt16ToInt64: out.debug << "Convert int16_t to int64"; break;
case EOpConvInt16ToUint8: out.debug << "Convert int16_t to uint8_t";break;
case EOpConvInt16ToUint16: out.debug << "Convert int16_t to uint16_t";break;
case EOpConvInt16ToUint: out.debug << "Convert int16_t to uint"; break;
case EOpConvInt16ToUint64: out.debug << "Convert int16_t to uint64"; break;
// int16_t -> float*
case EOpConvInt16ToFloat16: out.debug << "Convert int16_t to float16_t";break;
case EOpConvInt16ToFloat: out.debug << "Convert int16_t to float"; break;
case EOpConvInt16ToDouble: out.debug << "Convert int16_t to double"; break;
// uint16_t -> (u)int*
case EOpConvUint16ToInt8: out.debug << "Convert uint16_t to int8_t";break;
case EOpConvUint16ToInt16: out.debug << "Convert uint16_t to int16_t";break;
case EOpConvUint16ToInt: out.debug << "Convert uint16_t to int"; break;
case EOpConvUint16ToInt64: out.debug << "Convert uint16_t to int64"; break;
case EOpConvUint16ToUint8: out.debug << "Convert uint16_t to uint8_t";break;
case EOpConvUint16ToUint: out.debug << "Convert uint16_t to uint"; break;
case EOpConvUint16ToUint64: out.debug << "Convert uint16_t to uint64"; break;
// uint16_t -> float*
case EOpConvUint16ToFloat16: out.debug << "Convert uint16_t to float16_t";break;
case EOpConvUint16ToFloat: out.debug << "Convert uint16_t to float"; break;
case EOpConvUint16ToDouble: out.debug << "Convert uint16_t to double"; break;
// int32_t -> (u)int*
case EOpConvIntToInt8: out.debug << "Convert int to int8_t";break;
case EOpConvIntToInt16: out.debug << "Convert int to int16_t";break;
case EOpConvIntToInt64: out.debug << "Convert int to int64"; break;
case EOpConvIntToUint8: out.debug << "Convert int to uint8_t";break;
case EOpConvIntToUint16: out.debug << "Convert int to uint16_t";break;
case EOpConvIntToUint: out.debug << "Convert int to uint"; break;
case EOpConvIntToUint64: out.debug << "Convert int to uint64"; break;
// int32_t -> float*
case EOpConvIntToFloat16: out.debug << "Convert int to float16_t";break;
case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
case EOpConvIntToDouble: out.debug << "Convert int to double"; break;
// uint32_t -> (u)int*
case EOpConvUintToInt8: out.debug << "Convert uint to int8_t";break;
case EOpConvUintToInt16: out.debug << "Convert uint to int16_t";break;
case EOpConvUintToInt: out.debug << "Convert uint to int";break;
case EOpConvUintToInt64: out.debug << "Convert uint to int64"; break;
case EOpConvUintToUint8: out.debug << "Convert uint to uint8_t";break;
case EOpConvUintToUint16: out.debug << "Convert uint to uint16_t";break;
case EOpConvUintToUint64: out.debug << "Convert uint to uint64"; break;
// uint32_t -> float*
case EOpConvUintToFloat16: out.debug << "Convert uint to float16_t";break;
case EOpConvUintToFloat: out.debug << "Convert uint to float"; break;
case EOpConvUintToDouble: out.debug << "Convert uint to double"; break;
// int64 -> (u)int*
case EOpConvInt64ToInt8: out.debug << "Convert int64 to int8_t"; break;
case EOpConvInt64ToInt16: out.debug << "Convert int64 to int16_t"; break;
case EOpConvInt64ToInt: out.debug << "Convert int64 to int"; break;
case EOpConvInt64ToUint8: out.debug << "Convert int64 to uint8_t";break;
case EOpConvInt64ToUint16: out.debug << "Convert int64 to uint16_t";break;
case EOpConvInt64ToUint: out.debug << "Convert int64 to uint"; break;
case EOpConvInt64ToUint64: out.debug << "Convert int64 to uint64"; break;
// int64 -> float*
case EOpConvInt64ToFloat16: out.debug << "Convert int64 to float16_t";break;
case EOpConvInt64ToFloat: out.debug << "Convert int64 to float"; break;
case EOpConvInt64ToDouble: out.debug << "Convert int64 to double"; break;
// uint64 -> (u)int*
case EOpConvUint64ToInt8: out.debug << "Convert uint64 to int8_t";break;
case EOpConvUint64ToInt16: out.debug << "Convert uint64 to int16_t";break;
case EOpConvUint64ToInt: out.debug << "Convert uint64 to int"; break;
case EOpConvUint64ToInt64: out.debug << "Convert uint64 to int64"; break;
case EOpConvUint64ToUint8: out.debug << "Convert uint64 to uint8_t";break;
case EOpConvUint64ToUint16: out.debug << "Convert uint64 to uint16"; break;
case EOpConvUint64ToUint: out.debug << "Convert uint64 to uint"; break;
// uint64 -> float*
case EOpConvUint64ToFloat16: out.debug << "Convert uint64 to float16_t";break;
case EOpConvUint64ToFloat: out.debug << "Convert uint64 to float"; break;
case EOpConvUint64ToDouble: out.debug << "Convert uint64 to double"; break;
// float16_t -> int*
case EOpConvFloat16ToInt8: out.debug << "Convert float16_t to int8_t"; break;
case EOpConvFloat16ToInt16: out.debug << "Convert float16_t to int16_t"; break;
case EOpConvFloat16ToInt: out.debug << "Convert float16_t to int"; break;
case EOpConvFloat16ToInt64: out.debug << "Convert float16_t to int64"; break;
// float16_t -> uint*
case EOpConvFloat16ToUint8: out.debug << "Convert float16_t to uint8_t"; break;
case EOpConvFloat16ToUint16: out.debug << "Convert float16_t to uint16_t"; break;
case EOpConvFloat16ToUint: out.debug << "Convert float16_t to uint"; break;
case EOpConvFloat16ToUint64: out.debug << "Convert float16_t to uint64"; break;
// float16_t -> float*
case EOpConvFloat16ToFloat: out.debug << "Convert float16_t to float"; break;
case EOpConvFloat16ToDouble: out.debug << "Convert float16_t to double"; break;
// float32 -> float*
case EOpConvFloatToFloat16: out.debug << "Convert float to float16_t"; break;
case EOpConvFloatToDouble: out.debug << "Convert float to double"; break;
// float32_t -> int*
case EOpConvFloatToInt8: out.debug << "Convert float to int8_t"; break;
case EOpConvFloatToInt16: out.debug << "Convert float to int16_t"; break;
case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
case EOpConvFloatToInt64: out.debug << "Convert float to int64"; break;
// float32_t -> uint*
case EOpConvFloatToUint8: out.debug << "Convert float to uint8_t"; break;
case EOpConvFloatToUint16: out.debug << "Convert float to uint16_t"; break;
case EOpConvFloatToUint: out.debug << "Convert float to uint"; break;
case EOpConvFloatToUint64: out.debug << "Convert float to uint64"; break;
// double -> float*
case EOpConvDoubleToFloat16: out.debug << "Convert double to float16_t"; break;
case EOpConvDoubleToFloat: out.debug << "Convert double to float"; break;
// double -> int*
case EOpConvDoubleToInt8: out.debug << "Convert double to int8_t"; break;
case EOpConvDoubleToInt16: out.debug << "Convert double to int16_t"; break;
case EOpConvDoubleToInt: out.debug << "Convert double to int"; break;
case EOpConvDoubleToInt64: out.debug << "Convert double to int64"; break;
// float32_t -> uint*
case EOpConvDoubleToUint8: out.debug << "Convert double to uint8_t"; break;
case EOpConvDoubleToUint16: out.debug << "Convert double to uint16_t"; break;
case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break;
case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break;
case EOpConvUint64ToPtr: out.debug << "Convert uint64_t to pointer"; break;
case EOpConvPtrToUint64: out.debug << "Convert pointer to uint64_t"; break;
@ -673,6 +495,17 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpSpirvInst: out.debug << "spirv_instruction"; break;
case EOpCreateTensorLayoutNV: out.debug << "createTensorLayoutNV"; break;
case EOpTensorLayoutSetBlockSizeNV: out.debug << "setTensorLayoutBlockSizeNV"; break;
case EOpTensorLayoutSetDimensionNV: out.debug << "setTensorLayoutDimensionNV"; break;
case EOpTensorLayoutSetStrideNV: out.debug << "setTensorLayoutStrideNV"; break;
case EOpTensorLayoutSliceNV: out.debug << "sliceTensorLayoutNV"; break;
case EOpTensorLayoutSetClampValueNV: out.debug << "setTensorLayoutClampValueNV"; break;
case EOpCreateTensorViewNV: out.debug << "createTensorViewNV"; break;
case EOpTensorViewSetDimensionNV: out.debug << "setTensorViewDimensionsNV"; break;
case EOpTensorViewSetStrideNV: out.debug << "setTensorViewStrideNV"; break;
case EOpTensorViewSetClipNV: out.debug << "setTensorViewClipNV"; break;
default: out.debug.message(EPrefixError, "Bad unary op");
}
@ -793,6 +626,18 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break;
case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break;
case EOpConstructBMat4x4: out.debug << "Construct bmat4"; break;
case EOpConstructBFloat16: out.debug << "Construct bfloat16_t"; break;
case EOpConstructBF16Vec2: out.debug << "Construct bf16vec2"; break;
case EOpConstructBF16Vec3: out.debug << "Construct bf16vec3"; break;
case EOpConstructBF16Vec4: out.debug << "Construct bf16vec4"; break;
case EOpConstructFloatE5M2: out.debug << "Construct floate5m2_t"; break;
case EOpConstructFloatE5M2Vec2: out.debug << "Construct fe5m2vec2"; break;
case EOpConstructFloatE5M2Vec3: out.debug << "Construct fe5m2vec3"; break;
case EOpConstructFloatE5M2Vec4: out.debug << "Construct fe5m2vec4"; break;
case EOpConstructFloatE4M3: out.debug << "Construct floate4m3_t"; break;
case EOpConstructFloatE4M3Vec2: out.debug << "Construct fe4m3vec2"; break;
case EOpConstructFloatE4M3Vec3: out.debug << "Construct fe4m3vec3"; break;
case EOpConstructFloatE4M3Vec4: out.debug << "Construct fe4m3vec4"; break;
case EOpConstructFloat16: out.debug << "Construct float16_t"; break;
case EOpConstructF16Vec2: out.debug << "Construct f16vec2"; break;
case EOpConstructF16Vec3: out.debug << "Construct f16vec3"; break;
@ -811,8 +656,14 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpConstructReference: out.debug << "Construct reference"; break;
case EOpConstructCooperativeMatrixNV: out.debug << "Construct cooperative matrix NV"; break;
case EOpConstructCooperativeMatrixKHR: out.debug << "Construct cooperative matrix KHR"; break;
case EOpConstructCooperativeVectorNV: out.debug << "Construct cooperative vector NV"; break;
case EOpConstructAccStruct: out.debug << "Construct acceleration structure"; break;
case EOpBitCastArrayQCOM: out.debug << "Bitcast To Array QCOM"; break;
case EOpExtractSubArrayQCOM: out.debug << "Extract Subarray QCOM"; break;
case EOpCompositeConstructCoopMatQCOM: out.debug << "Construct Cooperative Matrix QCOM"; break;
case EOpCompositeExtractCoopMatQCOM: out.debug << "Extract Cooperative Matrix QCOM"; break;
case EOpLessThan: out.debug << "Compare Less Than"; break;
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
@ -835,6 +686,9 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpDistance: out.debug << "distance"; break;
case EOpDot: out.debug << "dot-product"; break;
case EOpDotPackedEXT: out.debug << "dot-product-packed";break;
case EOpDotAccSatEXT: out.debug << "dot-product-accumulate-saturate";break;
case EOpDotPackedAccSatEXT: out.debug << "dot-product-packed-accumulate-saturate";break;
case EOpCross: out.debug << "cross-product"; break;
case EOpFaceForward: out.debug << "face-forward"; break;
case EOpReflect: out.debug << "reflect"; break;
@ -1107,13 +961,37 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpRayQueryGetIntersectionObjectToWorld: out.debug << "rayQueryGetIntersectionObjectToWorldEXT"; break;
case EOpRayQueryGetIntersectionWorldToObject: out.debug << "rayQueryGetIntersectionWorldToObjectEXT"; break;
case EOpRayQueryGetIntersectionTriangleVertexPositionsEXT: out.debug << "rayQueryGetIntersectionTriangleVertexPositionsEXT"; break;
case EOpRayQueryGetIntersectionClusterIdNV: out.debug << "rayQueryGetIntersectionClusterIdNV"; break;
case EOpRayQueryGetIntersectionSpherePositionNV: out.debug << "rayQueryGetIntersectionSpherePositionNV"; break;
case EOpRayQueryGetIntersectionSphereRadiusNV: out.debug << "rayQueryGetIntersectionSphereRadiusNV"; break;
case EOpRayQueryGetIntersectionLSSHitValueNV: out.debug << "rayQueryGetIntersectionLSSHitValueNV"; break;
case EOpRayQueryGetIntersectionLSSPositionsNV: out.debug << "rayQueryGetIntersectionLSSPositionsNV"; break;
case EOpRayQueryGetIntersectionLSSRadiiNV: out.debug << "rayQueryGetIntersectionLSSRadiiNV"; break;
case EOpRayQueryIsSphereHitNV: out.debug << "rayQueryIsSphereHitNV"; break;
case EOpRayQueryIsLSSHitNV: out.debug << "rayQueryIsLSSHitNV"; break;
case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix KHR"; break;
case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix KHR"; break;
case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices KHR"; break;
case EOpCooperativeMatrixLoadNV: out.debug << "Load cooperative matrix NV"; break;
case EOpCooperativeMatrixStoreNV: out.debug << "Store cooperative matrix NV"; break;
case EOpCooperativeMatrixLoadTensorNV: out.debug << "Load cooperative matrix tensor NV"; break;
case EOpCooperativeMatrixStoreTensorNV: out.debug << "Store cooperative matrix tensor NV"; break;
case EOpCooperativeMatrixMulAddNV: out.debug << "MulAdd cooperative matrices NV"; break;
case EOpCooperativeMatrixReduceNV: out.debug << "Reduce cooperative matrices"; break;
case EOpCooperativeMatrixPerElementOpNV: out.debug << "cooperative matrix per element op"; break;
case EOpCooperativeMatrixTransposeNV: out.debug << "Transpose cooperative matrix"; break;
case EOpCooperativeVectorMatMulNV: out.debug << "Cooperative vector matrix multiply NV"; break;
case EOpCooperativeVectorMatMulAddNV: out.debug << "Cooperative vector matrix multiply add NV"; break;
case EOpCooperativeVectorLoadNV: out.debug << "Load cooperative vector NV"; break;
case EOpCooperativeVectorStoreNV: out.debug << "Store cooperative vector NV"; break;
case EOpCooperativeVectorOuterProductAccumulateNV: out.debug << "Cooperative vector outer product accumulate NV"; break;
case EOpCooperativeVectorReduceSumAccumulateNV: out.debug << "Cooperative vector reduce sum accumulate NV"; break;
case EOpTensorReadARM: out.debug << "Read from tensor"; break;
case EOpTensorWriteARM: out.debug << "Write to tensor"; break;
case EOpTensorSizeARM: out.debug << "Get tensor size"; break;
case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break;
case EOpDebugPrintf: out.debug << "Debug printf"; break;
@ -1148,14 +1026,32 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpHitObjectGetCurrentTimeNV: out.debug << "HitObjectGetCurrentTimeNV"; break;
case EOpHitObjectGetShaderBindingTableRecordIndexNV: out.debug << "HitObjectGetShaderBindingTableRecordIndexNV"; break;
case EOpHitObjectGetShaderRecordBufferHandleNV: out.debug << "HitObjectReadShaderRecordBufferHandleNV"; break;
case EOpHitObjectGetClusterIdNV: out.debug << "HitObjectGetClusterIdNV"; break;
case EOpReorderThreadNV: out.debug << "ReorderThreadNV"; break;
case EOpFetchMicroTriangleVertexPositionNV: out.debug << "MicroTriangleVertexPositionNV"; break;
case EOpFetchMicroTriangleVertexBarycentricNV: out.debug << "MicroTriangleVertexBarycentricNV"; break;
case EOpHitObjectGetSpherePositionNV: out.debug << "HitObjectGetSpherePositionNV"; break;
case EOpHitObjectGetSphereRadiusNV: out.debug << "HitObjectGetSphereRadiusNV"; break;
case EOpHitObjectGetLSSPositionsNV: out.debug << "HitObjectGetLSSPositionsNV"; break;
case EOpHitObjectGetLSSRadiiNV: out.debug << "HitObjectGetLSSRadiiNV"; break;
case EOpHitObjectIsSphereHitNV: out.debug << "HitObjectIsSphereHitNV"; break;
case EOpHitObjectIsLSSHitNV: out.debug << "HitObjectIsLSSHitNV"; break;
case EOpSpirvInst: out.debug << "spirv_instruction"; break;
case EOpStencilAttachmentReadEXT: out.debug << "stencilAttachmentReadEXT"; break;
case EOpDepthAttachmentReadEXT: out.debug << "depthAttachmentReadEXT"; break;
case EOpCreateTensorLayoutNV: out.debug << "createTensorLayout"; break;
case EOpTensorLayoutSetBlockSizeNV: out.debug << "setBlockSize"; break;
case EOpTensorLayoutSetDimensionNV: out.debug << "setDimension"; break;
case EOpTensorLayoutSetStrideNV: out.debug << "setStride"; break;
case EOpTensorLayoutSliceNV: out.debug << "slice"; break;
case EOpTensorLayoutSetClampValueNV: out.debug << "setClampValue"; break;
case EOpCreateTensorViewNV: out.debug << "createTensorView"; break;
case EOpTensorViewSetDimensionNV: out.debug << "setTensorViewDimensions"; break;
case EOpTensorViewSetStrideNV: out.debug << "setTensorViewStride"; break;
case EOpTensorViewSetClipNV: out.debug << "clipTensorView"; break;
default: out.debug.message(EPrefixError, "Bad aggregation op");
}
@ -1285,6 +1181,9 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
case EbtFloat:
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloatE5M2:
case EbtFloatE4M3:
OutputDouble(out, constUnion[i].getDConst(), extra);
out.debug << "\n";
break;
@ -1501,6 +1400,16 @@ bool TOutputTraverser::visitSwitch(TVisit /* visit */, TIntermSwitch* node)
return false;
}
bool TOutputTraverser::visitVariableDecl(TVisit /* visit */, TIntermVariableDecl* node)
{
TInfoSink& out = infoSink;
OutputTreeText(out, node, depth);
out.debug << "VarDecl: " << node->getDeclSymbol()->getName() << '\n';
return true;
}
//
// This function is the one to call externally to start the traversal.
// Individual functions can be initialized to 0 to skip processing of that
@ -1568,6 +1477,8 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
infoSink.debug << "using non_coherent_depth_attachment_readEXT\n";
if (nonCoherentStencilAttachmentReadEXT)
infoSink.debug << "using non_coherent_stencil_attachment_readEXT\n";
if (nonCoherentTileAttachmentReadQCOM)
infoSink.debug << "using non_coherent_attachment_readQCOM\n";
if (depthLayout != EldNone)
infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n";
if (blendEquations != 0) {
@ -1602,6 +1513,13 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
localSizeSpecId[2] << ")\n";
}
}
if (nonCoherentTileAttachmentReadQCOM)
infoSink.debug << "using non_coherent_attachment_readQCOM\n";
if (isTileShadingRateQCOMSet()) {
infoSink.debug << "shading_rateQCOM = (" << tileShadingRateQCOM[0] << ", "
<< tileShadingRateQCOM[1] << ", "
<< tileShadingRateQCOM[2] << ")\n";
}
break;
default:

View file

@ -39,6 +39,7 @@
#include "gl_types.h"
#include "iomapper.h"
#include "LiveTraverser.h"
#include "SymbolTable.h"
//
@ -60,10 +61,112 @@
namespace glslang {
struct TVarEntryInfo {
long long id;
TIntermSymbol* symbol;
bool live;
TLayoutPacking upgradedToPushConstantPacking; // ElpNone means it hasn't been upgraded
int newBinding;
int newSet;
int newLocation;
int newComponent;
int newIndex;
EShLanguage stage;
void clearNewAssignments() {
upgradedToPushConstantPacking = ElpNone;
newBinding = -1;
newSet = -1;
newLocation = -1;
newComponent = -1;
newIndex = -1;
}
struct TOrderById {
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; }
};
struct TOrderByPriority {
// ordering:
// 1) has both binding and set
// 2) has binding but no set
// 3) has no binding but set
// 4) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (lPoints == rPoints)
return l.id < r.id;
return lPoints > rPoints;
}
};
struct TOrderByPriorityAndLive {
// ordering:
// 1) do live variables first
// 2) has both binding and set
// 3) has binding but no set
// 4) has no binding but set
// 5) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (l.live != r.live)
return l.live > r.live;
if (lPoints != rPoints)
return lPoints > rPoints;
return l.id < r.id;
}
};
};
// override function "operator=", if a vector<const _Kty, _Ty> being sort,
// when use vc++, the sort function will call :
// pair& operator=(const pair<_Other1, _Other2>& _Right)
// {
// first = _Right.first;
// second = _Right.second;
// return (*this);
// }
// that will make a const type handing on left.
// override this function can avoid a compiler error.
// In the future, if the vc++ compiler can handle such a situation,
// this part of the code will be removed.
struct TVarLivePair : std::pair<const TString, TVarEntryInfo> {
TVarLivePair(const std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {}
TVarLivePair& operator=(const TVarLivePair& _Right) {
const_cast<TString&>(first) = _Right.first;
second = _Right.second;
return (*this);
}
TVarLivePair(const TVarLivePair& src) : pair(src) { }
};
typedef std::vector<TVarLivePair> TVarLiveVector;
class TVarGatherTraverser : public TLiveTraverser {
public:
TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList)
: TLiveTraverser(i, traverseDeadCode, true, true, false)
: TLiveTraverser(i, traverseDeadCode, true, true, false, false)
, inputList(inList)
, outputList(outList)
, uniformList(uniformList)
@ -106,7 +209,7 @@ class TVarSetTraverser : public TLiveTraverser
{
public:
TVarSetTraverser(const TIntermediate& i, const TVarLiveMap& inList, const TVarLiveMap& outList, const TVarLiveMap& uniformList)
: TLiveTraverser(i, true, true, true, false)
: TLiveTraverser(i, true, true, true, false, true)
, inputList(inList)
, outputList(outList)
, uniformList(uniformList)
@ -143,8 +246,11 @@ public:
base->getWritableType().getQualifier().layoutComponent = at->second.newComponent;
if (at->second.newIndex != -1)
base->getWritableType().getQualifier().layoutIndex = at->second.newIndex;
if (at->second.upgradedToPushConstant)
if (at->second.upgradedToPushConstantPacking != ElpNone) {
base->getWritableType().getQualifier().layoutPushConstant = true;
base->getWritableType().getQualifier().setBlockStorage(EbsPushConstant);
base->getWritableType().getQualifier().layoutPacking = at->second.upgradedToPushConstantPacking;
}
}
private:
@ -176,7 +282,7 @@ struct TNotifyInOutAdaptor
{
EShLanguage stage;
TIoMapResolver& resolver;
inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r)
inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r)
: stage(s)
, resolver(r)
{
@ -913,6 +1019,7 @@ uint32_t TDefaultIoResolverBase::computeTypeLocationSize(const TType& type, EShL
//TDefaultGlslIoResolver
TResourceType TDefaultGlslIoResolver::getResourceType(const glslang::TType& type) {
assert(isValidGlslType(type));
if (isImageType(type)) {
return EResImage;
}
@ -928,6 +1035,15 @@ TResourceType TDefaultGlslIoResolver::getResourceType(const glslang::TType& type
if (isUboType(type)) {
return EResUbo;
}
if (isCombinedSamplerType(type)) {
return EResCombinedSampler;
}
if (isAsType(type)) {
return EResAs;
}
if (isTensorType(type)) {
return EResTensor;
}
return EResCount;
}
@ -1277,6 +1393,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; }
TResourceType getResourceType(const glslang::TType& type) override {
assert(isValidGlslType(type));
if (isImageType(type)) {
return EResImage;
}
@ -1292,6 +1409,15 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
if (isUboType(type)) {
return EResUbo;
}
if (isCombinedSamplerType(type)) {
return EResCombinedSampler;
}
if (isAsType(type)) {
return EResAs;
}
if (isTensorType(type)) {
return EResTensor;
}
return EResCount;
}
@ -1377,6 +1503,11 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase {
if (isUboType(type)) {
return EResUbo;
}
// no support for combined samplers in HLSL
if (isAsType(type)) {
return EResAs;
}
// no support for tensors in HLSL
return EResCount;
}
@ -1497,6 +1628,36 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
return !hadError;
}
TGlslIoMapper::TGlslIoMapper() {
memset(inVarMaps, 0, sizeof(TVarLiveMap*) * EShLangCount);
memset(outVarMaps, 0, sizeof(TVarLiveMap*) * EShLangCount);
memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * EShLangCount);
memset(intermediates, 0, sizeof(TIntermediate*) * EShLangCount);
profile = ENoProfile;
version = 0;
autoPushConstantMaxSize = 128;
autoPushConstantBlockPacking = ElpStd430;
}
TGlslIoMapper::~TGlslIoMapper() {
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (inVarMaps[stage] != nullptr) {
delete inVarMaps[stage];
inVarMaps[stage] = nullptr;
}
if (outVarMaps[stage] != nullptr) {
delete outVarMaps[stage];
outVarMaps[stage] = nullptr;
}
if (uniformVarMap[stage] != nullptr) {
delete uniformVarMap[stage];
uniformVarMap[stage] = nullptr;
}
if (intermediates[stage] != nullptr)
intermediates[stage] = nullptr;
}
}
// Map I/O variables to provided offsets, and make bindings for
// unbound but live variables.
//
@ -1677,7 +1838,8 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
std::for_each(uniformVector.begin(), uniformVector.end(),
[this](TVarLivePair& p) {
if (p.first == autoPushConstantBlockName) {
p.second.upgradedToPushConstant = true;
p.second.upgradedToPushConstantPacking = autoPushConstantBlockPacking;
p.second.newSet = TQualifier::layoutSetEnd;
}
});
}
@ -1690,8 +1852,8 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
std::for_each(uniformVector.begin(), uniformVector.end(), [pUniformVarMap, stage](TVarLivePair p) {
auto at = pUniformVarMap[stage]->find(p.second.symbol->getAccessName());
if (at != pUniformVarMap[stage]->end() && at->second.id == p.second.id){
if (p.second.upgradedToPushConstant) {
at->second.upgradedToPushConstant = true;
if (p.second.upgradedToPushConstantPacking != ElpNone) {
at->second.upgradedToPushConstantPacking = p.second.upgradedToPushConstantPacking;
} else {
int resolvedBinding = at->second.newBinding;
at->second = p.second;

View file

@ -37,7 +37,6 @@
#define _IOMAPPER_INCLUDED
#include <cstdint>
#include "LiveTraverser.h"
#include <unordered_map>
#include <unordered_set>
//
@ -49,84 +48,7 @@ class TInfoSink;
namespace glslang {
class TIntermediate;
struct TVarEntryInfo {
long long id;
TIntermSymbol* symbol;
bool live;
bool upgradedToPushConstant;
int newBinding;
int newSet;
int newLocation;
int newComponent;
int newIndex;
EShLanguage stage;
void clearNewAssignments() {
upgradedToPushConstant = false;
newBinding = -1;
newSet = -1;
newLocation = -1;
newComponent = -1;
newIndex = -1;
}
struct TOrderById {
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; }
};
struct TOrderByPriority {
// ordering:
// 1) has both binding and set
// 2) has binding but no set
// 3) has no binding but set
// 4) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (lPoints == rPoints)
return l.id < r.id;
return lPoints > rPoints;
}
};
struct TOrderByPriorityAndLive {
// ordering:
// 1) do live variables first
// 2) has both binding and set
// 3) has binding but no set
// 4) has no binding but set
// 5) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (l.live != r.live)
return l.live > r.live;
if (lPoints != rPoints)
return lPoints > rPoints;
return l.id < r.id;
}
};
};
struct TVarEntryInfo;
// Base class for shared TIoMapResolver services, used by several derivations.
struct TDefaultIoResolverBase : public glslang::TIoMapResolver {
public:
@ -198,12 +120,12 @@ protected:
}
static bool isTextureType(const glslang::TType& type) {
return (type.getBasicType() == glslang::EbtSampler &&
return (type.getBasicType() == glslang::EbtSampler && !type.getSampler().isCombined() &&
(type.getSampler().isTexture() || type.getSampler().isSubpass()));
}
static bool isUboType(const glslang::TType& type) {
return type.getQualifier().storage == EvqUniform;
return type.getQualifier().storage == EvqUniform && type.isStruct();
}
static bool isImageType(const glslang::TType& type) {
@ -214,6 +136,24 @@ protected:
return type.getQualifier().storage == EvqBuffer;
}
static bool isCombinedSamplerType(const glslang::TType& type) {
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isCombined();
}
static bool isAsType(const glslang::TType& type) {
return type.getBasicType() == glslang::EbtAccStruct;
}
static bool isTensorType(const glslang::TType& type) {
return type.isTensorARM();
}
static bool isValidGlslType(const glslang::TType& type) {
// at most one must be true
return (isSamplerType(type) + isTextureType(type) + isUboType(type) + isImageType(type) +
isSsboType(type) + isCombinedSamplerType(type) + isAsType(type) + isTensorType(type)) <= 1;
}
// Return true if this is a SRV (shader resource view) type:
static bool isSrvType(const glslang::TType& type) {
return isTextureType(type) || type.getQualifier().storage == EvqBuffer;
@ -267,82 +207,22 @@ protected:
typedef std::map<TString, TVarEntryInfo> TVarLiveMap;
// override function "operator=", if a vector<const _Kty, _Ty> being sort,
// when use vc++, the sort function will call :
// pair& operator=(const pair<_Other1, _Other2>& _Right)
// {
// first = _Right.first;
// second = _Right.second;
// return (*this);
// }
// that will make a const type handing on left.
// override this function can avoid a compiler error.
// In the future, if the vc++ compiler can handle such a situation,
// this part of the code will be removed.
struct TVarLivePair : std::pair<const TString, TVarEntryInfo> {
TVarLivePair(const std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {}
TVarLivePair& operator=(const TVarLivePair& _Right) {
const_cast<TString&>(first) = _Right.first;
second = _Right.second;
return (*this);
}
TVarLivePair(const TVarLivePair& src) : pair(src) { }
};
typedef std::vector<TVarLivePair> TVarLiveVector;
// I/O mapper
class TIoMapper {
public:
TIoMapper() {}
virtual ~TIoMapper() {}
// grow the reflection stage by stage
bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*);
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
};
// I/O mapper for GLSL
class TGlslIoMapper : public TIoMapper {
public:
TGlslIoMapper() {
memset(inVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(outVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
profile = ENoProfile;
version = 0;
autoPushConstantMaxSize = 128;
autoPushConstantBlockPacking = ElpStd430;
}
virtual ~TGlslIoMapper() {
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (inVarMaps[stage] != nullptr) {
delete inVarMaps[stage];
inVarMaps[stage] = nullptr;
}
if (outVarMaps[stage] != nullptr) {
delete outVarMaps[stage];
outVarMaps[stage] = nullptr;
}
if (uniformVarMap[stage] != nullptr) {
delete uniformVarMap[stage];
uniformVarMap[stage] = nullptr;
}
if (intermediates[stage] != nullptr)
intermediates[stage] = nullptr;
}
}
TGlslIoMapper();
virtual ~TGlslIoMapper();
// If set, the uniform block with the given name will be changed to be backed by
// push_constant if it's size is <= maxSize
void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
bool setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) override {
autoPushConstantBlockName = name;
autoPushConstantMaxSize = maxSize;
autoPushConstantBlockPacking = packing;
return true;
}
// grow the reflection stage by stage
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
bool doMap(TIoMapResolver*, TInfoSink&) override;
TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount],
*uniformVarMap[EShLangCount];
TIntermediate* intermediates[EShLangCount];
bool hadError = false;
EProfile profile;
@ -352,6 +232,8 @@ private:
TString autoPushConstantBlockName;
unsigned int autoPushConstantMaxSize;
TLayoutPacking autoPushConstantBlockPacking;
TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount],
*uniformVarMap[EShLangCount];
};
} // end namespace glslang

View file

@ -46,34 +46,46 @@
// even if no merging was done (i.e., the stage was only one compilation unit).
//
#include "glslang/Public/ShaderLang.h"
#include "localintermediate.h"
#include "../Include/InfoSink.h"
#include "SymbolTable.h"
#include "LiveTraverser.h"
namespace glslang {
//
// Link-time error emitter.
//
void TIntermediate::error(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
void TIntermediate::error(TInfoSink& infoSink, const TSourceLoc* loc, EShMessages messages, const char* message,
EShLanguage unitStage)
{
infoSink.info.prefix(EPrefixError);
if (unitStage < EShLangCount)
infoSink.info << "Linking " << StageName(getStage()) << " and " << StageName(unitStage) << " stages: " << message << "\n";
else
if (loc)
infoSink.info.location(*loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
if (unitStage == EShLangCount)
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
else if (language == EShLangCount)
infoSink.info << "Linking " << StageName(unitStage) << " stage: " << message << "\n";
else
infoSink.info << "Linking " << StageName(language) << " and " << StageName(unitStage) << " stages: " << message << "\n";
++numErrors;
}
// Link-time warning.
void TIntermediate::warn(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
void TIntermediate::warn(TInfoSink& infoSink, const TSourceLoc* loc, EShMessages messages, const char* message,
EShLanguage unitStage)
{
infoSink.info.prefix(EPrefixWarning);
if (unitStage < EShLangCount)
infoSink.info << "Linking " << StageName(language) << " and " << StageName(unitStage) << " stages: " << message << "\n";
else
if (loc)
infoSink.info.location(*loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
if (unitStage == EShLangCount)
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
else if (language == EShLangCount)
infoSink.info << "Linking " << StageName(unitStage) << " stage: " << message << "\n";
else
infoSink.info << "Linking " << StageName(language) << " and " << StageName(unitStage) << " stages: " << message << "\n";
}
// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block
@ -113,10 +125,67 @@ void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
}
static inline bool isSameInterface(TIntermSymbol* symbol, TIntermSymbol* unitSymbol) {
EShLanguage stage = symbol->getStage();
EShLanguage unitStage = unitSymbol->getStage();
return // 1) same stage and same shader interface
(stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) ||
// 2) accross stages and both are uniform or buffer
(symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) ||
(symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) ||
// 3) in/out matched across stage boundary
(stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) ||
(unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut);
}
static bool isSameSymbol(TIntermSymbol* symbol1, TIntermSymbol* symbol2) {
// If they are both blocks in the same shader interface,
// match by the block-name, not the identifier name.
if (symbol1->getType().getBasicType() == EbtBlock && symbol2->getType().getBasicType() == EbtBlock) {
if (isSameInterface(symbol1, symbol2)) {
return symbol1->getType().getTypeName() == symbol2->getType().getTypeName();
}
} else if (symbol1->getName() == symbol2->getName())
return true;
return false;
}
//
// merge implicit array sizes for uniform/buffer objects
//
void TIntermediate::mergeImplicitArraySizes(TInfoSink&, TIntermediate& unit) {
if (unit.treeRoot == nullptr || treeRoot == nullptr)
return;
// Get the linker-object lists
TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
TIntermSequence unitLinkerObjects = unit.findLinkerObjects()->getSequence();
// filter unitLinkerObjects to only contain uniforms
auto end = std::remove_if(unitLinkerObjects.begin(), unitLinkerObjects.end(),
[](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqUniform &&
node->getAsSymbolNode()->getQualifier().storage != EvqBuffer; });
unitLinkerObjects.resize(end - unitLinkerObjects.begin());
std::size_t initialNumLinkerObjects = linkerObjects.size();
for (unsigned int unitLinkObj = 0; unitLinkObj < unitLinkerObjects.size(); ++unitLinkObj) {
for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) {
TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
assert(symbol && unitSymbol);
if (isSameSymbol(symbol, unitSymbol)) {
// Update implicit array sizes
mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType());
}
}
}
}
//
// do error checking on the shader boundary in / out vars
//
void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) {
void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit, EShMessages messages) {
if (unit.treeRoot == nullptr || treeRoot == nullptr)
return;
@ -137,7 +206,272 @@ void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) {
// do matching and error checking
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
// TODO: final check; make sure that any statically used `in` have matching `out` written to
if ((messages & EShMsgValidateCrossStageIO) == 0)
return;
// The OpenGL Shading Language, Version 4.60.8 (https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf)
// 4.3.4 Input Variables
// Only the input variables that are statically read need to be written by the previous stage; it is
// allowed to have superfluous declarations of input variables. This is shown in the following table.
// +------------------------------------------------------------------------------------------------+
// | Treatment of Mismatched Input | Consuming Shader (input variables) |
// | Variables |---------------------------------------------------------|
// | | No | Declared but no | Declared and Static Use |
// | | Declaration | Static Use | |
// |--------------------------------------+-------------+-----------------+-------------------------|
// | Generating Shader | No Declaration | Allowed | Allowed | Link-Time Error |
// | (output variables) |-----------------+-------------+-----------------+-------------------------|
// | | Declared but no | Allowed | Allowed | Allowed (values are |
// | | Static Use | | | undefined) |
// | |-----------------+-------------+-----------------+-------------------------|
// | | Declared and | Allowed | Allowed | Allowed (values are |
// | | Static Use | | | potentially undefined) |
// +------------------------------------------------------------------------------------------------+
// Consumption errors are based on static use only. Compilation may generate a warning, but not an
// error, for any dynamic use the compiler can deduce that might cause consumption of undefined values.
// TODO: implement support for geometry passthrough
if (getGeoPassthroughEXT()) {
unit.warn(infoSink, "GL_NV_geometry_shader_passthrough is enabled, skipping cross-stage IO validation",
getStage());
return;
}
class TIOTraverser : public TLiveTraverser {
public:
TIOTraverser(TIntermediate& i, bool all, TIntermSequence& sequence, TStorageQualifier storage)
: TLiveTraverser(i, all, true, false, false), sequence(sequence), storage(storage)
{
}
virtual void visitSymbol(TIntermSymbol* symbol)
{
if (symbol->getQualifier().storage == storage)
sequence.push_back(symbol);
}
private:
TIntermSequence& sequence;
TStorageQualifier storage;
};
// live symbols only
TIntermSequence unitLiveInputs;
TIOTraverser unitTraverser(unit, false, unitLiveInputs, EvqVaryingIn);
unitTraverser.pushFunction(unit.getEntryPointMangledName().c_str());
while (! unitTraverser.destinations.empty()) {
TIntermNode* destination = unitTraverser.destinations.back();
unitTraverser.destinations.pop_back();
destination->traverse(&unitTraverser);
}
// all symbols
TIntermSequence allOutputs;
TIOTraverser traverser(*this, true, allOutputs, EvqVaryingOut);
getTreeRoot()->traverse(&traverser);
std::unordered_set<int> outputLocations;
for (auto& output : allOutputs) {
if (output->getAsSymbolNode()->getBasicType() == EbtBlock) {
int lastLocation = -1;
if (output->getAsSymbolNode()->getQualifier().hasLocation())
lastLocation = output->getAsSymbolNode()->getQualifier().layoutLocation;
const TTypeList* members = output->getAsSymbolNode()->getType().getStruct();
for (auto& member : *members) {
int location = lastLocation;
if (member.type->getQualifier().hasLocation())
location = member.type->getQualifier().layoutLocation;
if (location != -1) {
int locationSize = TIntermediate::computeTypeLocationSize(*member.type, getStage());
for (int i = 0; i < locationSize; ++i)
outputLocations.insert(location + i);
lastLocation = location + locationSize;
}
}
} else {
int locationSize = TIntermediate::computeTypeLocationSize(output->getAsSymbolNode()->getType(), getStage());
for (int i = 0; i < locationSize; ++i)
outputLocations.insert(output->getAsSymbolNode()->getQualifier().layoutLocation + i);
}
}
// remove unitStage inputs with matching outputs in the current stage
auto liveEnd = std::remove_if(
unitLiveInputs.begin(), unitLiveInputs.end(), [this, &allOutputs, &outputLocations](TIntermNode* input) {
// ignore built-ins
if (input->getAsSymbolNode()->getAccessName().compare(0, 3, "gl_") == 0)
return true;
// try to match by location
if (input->getAsSymbolNode()->getQualifier().hasLocation() &&
outputLocations.find(input->getAsSymbolNode()->getQualifier().layoutLocation) != outputLocations.end())
return true;
if (input->getAsSymbolNode()->getBasicType() == EbtBlock) {
int lastLocation = -1;
if (input->getAsSymbolNode()->getQualifier().hasLocation())
lastLocation = input->getAsSymbolNode()->getQualifier().layoutLocation;
const TTypeList* members = input->getAsSymbolNode()->getType().getStruct();
for (auto& member : *members) {
int location = lastLocation;
if (member.type->getQualifier().hasLocation())
location = member.type->getQualifier().layoutLocation;
if (location != -1) {
int locationSize = TIntermediate::computeTypeLocationSize(*member.type, getStage());
for (int i = 0; i < locationSize; ++i)
if (outputLocations.find(location + i) != outputLocations.end())
return true;
lastLocation = location + locationSize;
}
}
}
// otherwise, try to match by name
return std::any_of(allOutputs.begin(), allOutputs.end(), [input](TIntermNode* output) {
return output->getAsSymbolNode()->getAccessName() == input->getAsSymbolNode()->getAccessName();
});
});
unitLiveInputs.resize(liveEnd - unitLiveInputs.begin());
// check remaining loose unitStage inputs for a matching output block member
liveEnd = std::remove_if(unitLiveInputs.begin(), unitLiveInputs.end(), [&allOutputs](TIntermNode* input) {
return std::any_of(allOutputs.begin(), allOutputs.end(), [input](TIntermNode* output) {
if (output->getAsSymbolNode()->getBasicType() != EbtBlock)
return false;
const TTypeList* members = output->getAsSymbolNode()->getType().getStruct();
return std::any_of(members->begin(), members->end(), [input](TTypeLoc type) {
return type.type->getFieldName() == input->getAsSymbolNode()->getName();
});
});
});
unitLiveInputs.resize(liveEnd - unitLiveInputs.begin());
// finally, check remaining unitStage block inputs for a matching loose output
liveEnd = std::remove_if(
unitLiveInputs.begin(), unitLiveInputs.end(), [&allOutputs](TIntermNode* input) {
if (input->getAsSymbolNode()->getBasicType() != EbtBlock)
return false;
// liveness isn't tracked per member so finding any one live member is the best we can do
const TTypeList* members = input->getAsSymbolNode()->getType().getStruct();
return std::any_of(members->begin(), members->end(), [allOutputs](TTypeLoc type) {
return std::any_of(allOutputs.begin(), allOutputs.end(), [&type](TIntermNode* output) {
return type.type->getFieldName() == output->getAsSymbolNode()->getName();
});
});
});
unitLiveInputs.resize(liveEnd - unitLiveInputs.begin());
// any remaining unitStage inputs have no matching output
std::for_each(unitLiveInputs.begin(), unitLiveInputs.end(), [&](TIntermNode* input) {
unit.error(infoSink, &input->getLoc(), messages,
"Preceding stage has no matching declaration for statically used input:", getStage());
infoSink.info << " "
<< input->getAsSymbolNode()->getType().getCompleteString(
true, true, false, true, input->getAsSymbolNode()->getAccessName())
<< "\n";
});
// TODO: warn about statically read inputs with outputs declared but not written to
}
void TIntermediate::optimizeStageIO(TInfoSink&, TIntermediate& unit)
{
// don't do any input/output demotion on compute, raytracing, or task/mesh stages
// TODO: support task/mesh
if (getStage() > EShLangFragment || unit.getStage() > EShLangFragment) {
return;
}
class TIOTraverser : public TLiveTraverser {
public:
TIOTraverser(TIntermediate& i, bool all, TIntermSequence& sequence, TStorageQualifier storage)
: TLiveTraverser(i, all, true, false, false), sequence(sequence), storage(storage)
{
}
virtual void visitSymbol(TIntermSymbol* symbol)
{
if (symbol->getQualifier().storage == storage) {
sequence.push_back(symbol);
}
}
private:
TIntermSequence& sequence;
TStorageQualifier storage;
};
// live symbols only
TIntermSequence unitLiveInputs;
TIOTraverser unitTraverser(unit, false, unitLiveInputs, EvqVaryingIn);
unitTraverser.pushFunction(unit.getEntryPointMangledName().c_str());
while (! unitTraverser.destinations.empty()) {
TIntermNode* destination = unitTraverser.destinations.back();
unitTraverser.destinations.pop_back();
destination->traverse(&unitTraverser);
}
TIntermSequence allOutputs;
TIntermSequence unitAllInputs;
TIOTraverser allTraverser(*this, true, allOutputs, EvqVaryingOut);
getTreeRoot()->traverse(&allTraverser);
TIOTraverser unitAllTraverser(unit, true, unitAllInputs, EvqVaryingIn);
unit.getTreeRoot()->traverse(&unitAllTraverser);
// find outputs not consumed by the next stage
std::for_each(allOutputs.begin(), allOutputs.end(), [&unitLiveInputs, &unitAllInputs](TIntermNode* output) {
// don't do anything to builtins
if (output->getAsSymbolNode()->getAccessName().compare(0, 3, "gl_") == 0)
return;
// don't demote block outputs (for now)
if (output->getAsSymbolNode()->getBasicType() == EbtBlock)
return;
// check if the (loose) output has a matching loose input
auto isMatchingInput = [output](TIntermNode* input) {
return output->getAsSymbolNode()->getAccessName() == input->getAsSymbolNode()->getAccessName();
};
// check if the (loose) output has a matching block member input
auto isMatchingInputBlockMember = [output](TIntermNode* input) {
// ignore loose inputs
if (input->getAsSymbolNode()->getBasicType() != EbtBlock)
return false;
// don't demote loose outputs with matching input block members
auto isMatchingBlockMember = [output](TTypeLoc type) {
return type.type->getFieldName() == output->getAsSymbolNode()->getName();
};
const TTypeList* members = input->getAsSymbolNode()->getType().getStruct();
return std::any_of(members->begin(), members->end(), isMatchingBlockMember);
};
// determine if the input/output pair should be demoted
// do the faster (and more likely) loose-loose check first
if (std::none_of(unitLiveInputs.begin(), unitLiveInputs.end(), isMatchingInput) &&
std::none_of(unitAllInputs.begin(), unitAllInputs.end(), isMatchingInputBlockMember)) {
// demote any input matching the output
auto demoteMatchingInputs = [output](TIntermNode* input) {
if (output->getAsSymbolNode()->getAccessName() == input->getAsSymbolNode()->getAccessName()) {
// demote input to a plain variable
TIntermSymbol* symbol = input->getAsSymbolNode();
symbol->getQualifier().storage = EvqGlobal;
symbol->getQualifier().clearInterstage();
symbol->getQualifier().clearLayout();
}
};
// demote all matching outputs to a plain variable
TIntermSymbol* symbol = output->getAsSymbolNode();
symbol->getQualifier().storage = EvqGlobal;
symbol->getQualifier().clearInterstage();
symbol->getQualifier().clearLayout();
std::for_each(unitAllInputs.begin(), unitAllInputs.end(), demoteMatchingInputs);
}
});
}
void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
@ -201,6 +535,9 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
error(infoSink, "number of invocations must match between compilation units");
}
// The GLSL specification requires that at least one compilation unit
// must declare the vertices layout, but not all units need to do so.
// However, all declarations must match.
if (vertices == TQualifier::layoutNotSet)
vertices = unit.vertices;
else if (unit.vertices != TQualifier::layoutNotSet && vertices != unit.vertices) {
@ -211,20 +548,30 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
else
assert(0);
}
// The mesh shader extension requires that at least one compilation unit
// must declare the max_primitives layout, but not all units need to do so.
// However, all declarations must match.
if (primitives == TQualifier::layoutNotSet)
primitives = unit.primitives;
else if (primitives != unit.primitives) {
else if (unit.primitives != TQualifier::layoutNotSet && primitives != unit.primitives) {
if (language == EShLangMesh)
error(infoSink, "Contradictory layout max_primitives values");
else
assert(0);
}
// The GLSL specification requires that at least one compilation unit
// must declare the input primitive layout, but not all units need to do so.
// However, all declarations must match.
if (inputPrimitive == ElgNone)
inputPrimitive = unit.inputPrimitive;
else if (unit.inputPrimitive != ElgNone && inputPrimitive != unit.inputPrimitive)
error(infoSink, "Contradictory input layout primitives");
// The GLSL specification requires that at least one compilation unit
// must declare the output primitive layout, but not all units need to do so.
// However, all declarations must match.
if (outputPrimitive == ElgNone)
outputPrimitive = unit.outputPrimitive;
else if (unit.outputPrimitive != ElgNone && outputPrimitive != unit.outputPrimitive)
@ -233,19 +580,27 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
error(infoSink, "gl_FragCoord redeclarations must match across shaders");
// The GLSL specification requires that at least one compilation unit
// must declare the vertex spacing layout, but not all units need to do so.
// However, all declarations must match.
if (vertexSpacing == EvsNone)
vertexSpacing = unit.vertexSpacing;
else if (vertexSpacing != unit.vertexSpacing)
else if (unit.vertexSpacing != EvsNone && vertexSpacing != unit.vertexSpacing)
error(infoSink, "Contradictory input vertex spacing");
// The GLSL specification requires that at least one compilation unit
// must declare the triangle ordering layout, but not all units need to do so.
// However, all declarations must match.
if (vertexOrder == EvoNone)
vertexOrder = unit.vertexOrder;
else if (vertexOrder != unit.vertexOrder)
else if (unit.vertexOrder != EvoNone && vertexOrder != unit.vertexOrder)
error(infoSink, "Contradictory triangle ordering");
MERGE_TRUE(pointMode);
for (int i = 0; i < 3; ++i) {
// The GLSL specification requires that all workgroup size declarations must match
// but not all units have to declare the layout.
if (unit.localSizeNotDefault[i]) {
if (!localSizeNotDefault[i]) {
localSize[i] = unit.localSize[i];
@ -255,9 +610,11 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
error(infoSink, "Contradictory local size");
}
// The GLSL specification requires that all workgroup size specialization
// ids declarations must match, but not all units have to declare the layout.
if (localSizeSpecId[i] == TQualifier::layoutNotSet)
localSizeSpecId[i] = unit.localSizeSpecId[i];
else if (localSizeSpecId[i] != unit.localSizeSpecId[i])
else if (unit.localSizeSpecId[i] != TQualifier::layoutNotSet && localSizeSpecId[i] != unit.localSizeSpecId[i])
error(infoSink, "Contradictory local size specialization ids");
}
@ -266,10 +623,13 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
MERGE_TRUE(nonCoherentColorAttachmentReadEXT);
MERGE_TRUE(nonCoherentDepthAttachmentReadEXT);
MERGE_TRUE(nonCoherentStencilAttachmentReadEXT);
MERGE_TRUE(nonCoherentTileAttachmentReadQCOM);
// The GLSL specification requires that all depth layout redeclarations must match,
// but not all units have to declare the layout.
if (depthLayout == EldNone)
depthLayout = unit.depthLayout;
else if (depthLayout != unit.depthLayout)
else if (unit.depthLayout != EldNone && depthLayout != unit.depthLayout)
error(infoSink, "Contradictory depth layouts");
MERGE_TRUE(depthReplacing);
@ -280,9 +640,11 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
MERGE_TRUE(xfbMode);
for (size_t b = 0; b < xfbBuffers.size(); ++b) {
// The GLSL specification requires that all xfb_stride declarations for
// the same buffer must match, but not all units have to declare the layout.
if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd)
xfbBuffers[b].stride = unit.xfbBuffers[b].stride;
else if (xfbBuffers[b].stride != unit.xfbBuffers[b].stride)
else if (unit.xfbBuffers[b].stride != TQualifier::layoutXfbStrideEnd && xfbBuffers[b].stride != unit.xfbBuffers[b].stride)
error(infoSink, "Contradictory xfb_stride");
xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride);
if (unit.xfbBuffers[b].contains64BitType)
@ -511,17 +873,6 @@ void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, c
globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1);
}
static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) {
return // 1) same stage and same shader interface
(stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) ||
// 2) accross stages and both are uniform or buffer
(symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) ||
(symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) ||
// 3) in/out matched across stage boundary
(stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) ||
(unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut);
}
//
// Global Unfiform block stores any default uniforms (i.e. uniforms without a block)
// If two linked stages declare the same member, they are meant to be the same uniform
@ -611,10 +962,10 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl
// don't need as many checks as when merging symbols, since
// initializers and most qualifiers are stripped when the member is moved into the block
if ((*memberType) != (*unitMemberType)) {
error(infoSink, "Types must match:");
error(infoSink, "Types must match:", unitBlock->getStage());
infoSink.info << " " << memberType->getFieldName() << ": ";
infoSink.info << "\"" << memberType->getCompleteString() << "\" versus ";
infoSink.info << "\"" << unitMemberType->getCompleteString() << "\"\n";
infoSink.info << "\"" << memberType->getCompleteString() << "\" in stage " << StageName(block->getStage()) << " versus ";
infoSink.info << "\"" << unitMemberType->getCompleteString() << "\" in stage " << StageName(unitBlock->getStage()) << "\n";
}
memberIndexUpdates[i] = j;
@ -713,18 +1064,7 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
assert(symbol && unitSymbol);
bool isSameSymbol = false;
// If they are both blocks in the same shader interface,
// match by the block-name, not the identifier name.
if (symbol->getType().getBasicType() == EbtBlock && unitSymbol->getType().getBasicType() == EbtBlock) {
if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) {
isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName();
}
}
else if (symbol->getName() == unitSymbol->getName())
isSameSymbol = true;
if (isSameSymbol) {
if (isSameSymbol(symbol, unitSymbol)) {
// filter out copy
merge = false;
@ -750,18 +1090,39 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
}
else if (symbol->getWritableType().isImplicitlySizedArray() && unitSymbol->getType().isSizedArray()) {
if (symbol->getWritableType().getImplicitArraySize() > unitSymbol->getType().getOuterArraySize())
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.");
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.", unitStage);
}
else if (unitSymbol->getType().isImplicitlySizedArray() && symbol->getWritableType().isSizedArray()) {
if (unitSymbol->getType().getImplicitArraySize() > symbol->getWritableType().getOuterArraySize())
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.");
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.", unitStage);
}
if (symbol->getType().isStruct() && unitSymbol->getType().isStruct() &&
symbol->getType().getStruct()->size() == unitSymbol->getType().getStruct()->size()) {
for (int i = 0; i < (int)symbol->getType().getStruct()->size(); ++i) {
auto& type = (*symbol->getWritableType().getStruct())[i];
auto& unitType = (*unitSymbol->getWritableType().getStruct())[i];
if (type.type->isImplicitlySizedArray() && unitType.type->isImplicitlySizedArray()) {
if (unitType.type->getImplicitArraySize() > type.type->getImplicitArraySize())
type.type->updateImplicitArraySize(unitType.type->getImplicitArraySize());
}
else if (type.type->isImplicitlySizedArray() && unitType.type->isSizedArray()) {
if (type.type->getImplicitArraySize() > unitType.type->getOuterArraySize())
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.", unitStage);
}
else if (type.type->isSizedArray() && unitType.type->isImplicitlySizedArray()) {
if (type.type->getOuterArraySize() < unitType.type->getImplicitArraySize())
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.", unitStage);
}
}
}
// Update implicit array sizes
mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType());
// Check for consistent types/qualification/initializers etc.
mergeErrorCheck(infoSink, *symbol, *unitSymbol, unitStage);
mergeErrorCheck(infoSink, *symbol, *unitSymbol);
}
// If different symbols, verify they arn't push_constant since there can only be one per stage
else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant() && getStage() == unitStage)
@ -803,7 +1164,7 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
}
};
if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) {
if (isSameInterface(symbol, unitSymbol)) {
checkName(symbol->getName());
// check members of other anonymous blocks
@ -847,9 +1208,11 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
//
// This function only does one of intra- or cross-stage matching per call.
//
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, EShLanguage unitStage)
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol)
{
bool crossStage = getStage() != unitStage;
EShLanguage stage = symbol.getStage();
EShLanguage unitStage = unitSymbol.getStage();
bool crossStage = stage != unitStage;
bool writeTypeComparison = false;
bool errorReported = false;
bool printQualifiers = false;
@ -861,10 +1224,10 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
// but, we make an exception if one is an implicit array and the other is sized
// or if the array sizes differ because of the extra array dimension on some in/out boundaries
bool arraysMatch = false;
if (isIoResizeArray(symbol.getType(), getStage()) || isIoResizeArray(unitSymbol.getType(), unitStage)) {
if (isIoResizeArray(symbol.getType(), stage) || isIoResizeArray(unitSymbol.getType(), unitStage)) {
// if the arrays have an extra dimension because of the stage.
// compare dimensions while ignoring the outer dimension
unsigned int firstDim = isIoResizeArray(symbol.getType(), getStage()) ? 1 : 0;
unsigned int firstDim = isIoResizeArray(symbol.getType(), stage) ? 1 : 0;
unsigned int numDim = symbol.getArraySizes()
? symbol.getArraySizes()->getNumDims() : 0;
unsigned int unitFirstDim = isIoResizeArray(unitSymbol.getType(), unitStage) ? 1 : 0;
@ -893,7 +1256,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
if (lpidx >= 0 && rpidx >= 0) {
error(infoSink, "Member names and types must match:", unitStage);
infoSink.info << " Block: " << symbol.getType().getTypeName() << "\n";
infoSink.info << " " << StageName(getStage()) << " stage: \""
infoSink.info << " " << StageName(stage) << " stage: \""
<< (*symbol.getType().getStruct())[lpidx].type->getCompleteString(true, false, false, true,
(*symbol.getType().getStruct())[lpidx].type->getFieldName()) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: \""
@ -901,20 +1264,20 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
(*unitSymbol.getType().getStruct())[rpidx].type->getFieldName()) << "\"\n";
errorReported = true;
} else if (lpidx >= 0 && rpidx == -1) {
TString errmsg = StageName(getStage());
TString errmsg = StageName(stage);
errmsg.append(" block member has no corresponding member in ").append(StageName(unitStage)).append(" block:");
error(infoSink, errmsg.c_str(), unitStage);
infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: "
infoSink.info << " " << StageName(stage) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: "
<< (*symbol.getType().getStruct())[lpidx].type->getFieldName() << "\n";
infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: n/a \n";
errorReported = true;
} else if (lpidx == -1 && rpidx >= 0) {
TString errmsg = StageName(unitStage);
errmsg.append(" block member has no corresponding member in ").append(StageName(getStage())).append(" block:");
errmsg.append(" block member has no corresponding member in ").append(StageName(stage)).append(" block:");
error(infoSink, errmsg.c_str(), unitStage);
infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: "
<< (*unitSymbol.getType().getStruct())[rpidx].type->getFieldName() << "\n";
infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: n/a \n";
infoSink.info << " " << StageName(stage) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: n/a \n";
errorReported = true;
} else {
error(infoSink, "Types must match:", unitStage);
@ -971,7 +1334,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
layoutQualifierError = true;
}
if (layoutQualifierError) {
infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: "
infoSink.info << " " << StageName(stage) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: "
<< (*symbol.getType().getStruct())[li].type->getFieldName() << " \""
<< (*symbol.getType().getStruct())[li].type->getCompleteString(true, true, false, false) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: "
@ -1083,6 +1446,10 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
error(infoSink, "Memory volatil qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().nontemporal != unitSymbol.getQualifier().nontemporal) {
error(infoSink, "Memory nontemporal qualifier must match:", unitStage);
memoryQualifierError = true;
}
if (symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict) {
error(infoSink, "Memory restrict qualifier must match:", unitStage);
memoryQualifierError = true;
@ -1152,24 +1519,24 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock &&
symbol.getType().getStruct() && unitSymbol.getType().getStruct()) {
if (printType) {
infoSink.info << " " << StageName(getStage()) << " stage: \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision,
infoSink.info << " " << StageName(stage) << " stage: \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision,
printType, symbol.getName(), symbol.getType().getTypeName()) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: \"" << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision,
printType, unitSymbol.getName(), unitSymbol.getType().getTypeName()) << "\"\n";
} else {
infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << " Instance: " << symbol.getName()
infoSink.info << " " << StageName(stage) << " stage: Block: " << symbol.getType().getTypeName() << " Instance: " << symbol.getName()
<< ": \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << " Instance: " << unitSymbol.getName()
<< ": \"" << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
}
} else {
if (printType) {
infoSink.info << " " << StageName(getStage()) << " stage: \""
infoSink.info << " " << StageName(stage) << " stage: \""
<< symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType, symbol.getName()) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: \""
<< unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType, unitSymbol.getName()) << "\"\n";
} else {
infoSink.info << " " << StageName(getStage()) << " stage: " << symbol.getName() << " \""
infoSink.info << " " << StageName(stage) << " stage: " << symbol.getName() << " \""
<< symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
infoSink.info << " " << StageName(unitStage) << " stage: " << unitSymbol.getName() << " \""
<< unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
@ -1201,7 +1568,8 @@ void TIntermediate::sharedBlockCheck(TInfoSink& infoSink)
// Do final link-time error checking of a complete (merged) intermediate representation.
// (Much error checking was done during merging).
//
// Also, lock in defaults of things not set, including array sizes.
// Also, lock in defaults of things not set.
// Defer adopting implicit array sizes to later, after all stages are merged.
//
void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
{
@ -1362,23 +1730,6 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
error(infoSink, "Unknown Stage.");
break;
}
// Process the tree for any node-specific work.
class TFinalLinkTraverser : public TIntermTraverser {
public:
TFinalLinkTraverser() { }
virtual ~TFinalLinkTraverser() { }
virtual void visitSymbol(TIntermSymbol* symbol)
{
// Implicitly size arrays.
// If an unsized array is left as unsized, it effectively
// becomes run-time sized.
symbol->getWritableType().adoptImplicitArraySizes(false);
}
} finalLinkTraverser;
treeRoot->traverse(&finalLinkTraverser);
}
//
@ -1635,6 +1986,8 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
set = 1;
else if (qualifier.isHitObjectAttrNV())
set = 2;
else if (qualifier.isHitObjectAttrEXT())
set = 2;
else
return -1;
@ -1673,7 +2026,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
// For raytracing IO (payloads and callabledata) each declaration occupies a single
// slot irrespective of type.
int collision = -1; // no collision
if (qualifier.isAnyPayload() || qualifier.isAnyCallable() || qualifier.isHitObjectAttrNV()) {
if (qualifier.isAnyPayload() || qualifier.isAnyCallable() || qualifier.isHitObjectAttrNV() || qualifier.isHitObjectAttrEXT()) {
TRange range(qualifier.layoutLocation, qualifier.layoutLocation);
collision = checkLocationRT(set, qualifier.layoutLocation);
if (collision < 0)
@ -1689,7 +2042,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
// First range:
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
TRange componentRange(0, 3);
TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch);
// check for collisions
collision = checkLocationRange(set, range, type, typeCollision);
@ -1699,7 +2052,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
// Second range:
TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1);
TRange componentRange2(0, 1);
TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch);
// check for collisions
collision = checkLocationRange(set, range2, type, typeCollision);
@ -1725,7 +2078,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
TBasicType basicTy = type.getBasicType();
if (basicTy == EbtSampler && type.getSampler().isAttachmentEXT())
basicTy = type.getSampler().type;
TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch);
// check for collisions, except for vertex inputs on desktop targeting OpenGL
if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0)
@ -1737,6 +2090,24 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
return collision;
}
// Check that two types can be stored in different components in the same location.
// They must be the same type, except signed/unsigned integers are considered compatible.
static bool checkCompatibleTypes(TBasicType t1, TBasicType t2) {
if (t1 != t2) {
if ((t1 == EbtInt8 && t2 == EbtUint8) ||
(t2 == EbtInt8 && t1 == EbtUint8) ||
(t1 == EbtInt16 && t2 == EbtUint16) ||
(t2 == EbtInt16 && t1 == EbtUint16)||
(t1 == EbtInt && t2 == EbtUint) ||
(t2 == EbtInt && t1 == EbtUint)||
(t1 == EbtInt64 && t2 == EbtUint64) ||
(t2 == EbtInt64 && t1 == EbtUint64)) {
return true;
}
}
return t1 == t2;
}
// Compare a new (the passed in) 'range' against the existing set, and see
// if there are any collisions.
//
@ -1749,10 +2120,12 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp
// there is a collision; pick one
return std::max(range.location.start, usedIo[set][r].location.start);
} else if (range.location.overlap(usedIo[set][r].location) &&
(type.getBasicType() != usedIo[set][r].basicType ||
(!checkCompatibleTypes(type.getBasicType(), usedIo[set][r].basicType) ||
type.getQualifier().centroid != usedIo[set][r].centroid ||
type.getQualifier().smooth != usedIo[set][r].smooth ||
type.getQualifier().flat != usedIo[set][r].flat)) {
type.getQualifier().flat != usedIo[set][r].flat ||
type.getQualifier().sample != usedIo[set][r].sample ||
type.getQualifier().patch != usedIo[set][r].patch)) {
// aliased-type mismatch
typeCollision = true;
return std::max(range.location.start, usedIo[set][r].location.start);
@ -2041,6 +2414,9 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
case EbtUint64:
case EbtDouble: size = 8; return 8;
case EbtFloat16: size = 2; return 2;
case EbtBFloat16: size = 2; return 2;
case EbtFloatE5M2:
case EbtFloatE4M3:
case EbtInt8:
case EbtUint8: size = 1; return 1;
case EbtInt16:

View file

@ -48,6 +48,7 @@
#include <functional>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
class TInfoSink;
@ -99,7 +100,8 @@ private:
// A "call" is a pair: <caller, callee>.
// There can be duplicates. General assumption is the list is small.
struct TCall {
TCall(const TString& pCaller, const TString& pCallee) : caller(pCaller), callee(pCallee) { }
TCall(const TString& pCaller, const TString& pCallee)
: caller(pCaller), callee(pCallee), visited(false), currentPath(false), errorGiven(false) { }
TString caller;
TString callee;
bool visited;
@ -123,8 +125,8 @@ struct TRange {
// within the same location range, component range, and index value. Locations don't alias unless
// all other dimensions of their range overlap.
struct TIoRange {
TIoRange(TRange location, TRange component, TBasicType basicType, int index, bool centroid, bool smooth, bool flat)
: location(location), component(component), basicType(basicType), index(index), centroid(centroid), smooth(smooth), flat(flat)
TIoRange(TRange location, TRange component, TBasicType basicType, int index, bool centroid, bool smooth, bool flat, bool sample, bool patch)
: location(location), component(component), basicType(basicType), index(index), centroid(centroid), smooth(smooth), flat(flat), sample(sample), patch(patch)
{
}
bool overlap(const TIoRange& rhs) const
@ -138,6 +140,8 @@ struct TIoRange {
bool centroid;
bool smooth;
bool flat;
bool sample;
bool patch;
};
// An offset range is a 2-D rectangle; the set of (binding, offset) pairs all lying
@ -265,6 +269,7 @@ public:
gpu_shader_fp64 = 1 << 9,
gpu_shader_int16 = 1 << 10,
gpu_shader_half_float = 1 << 11,
nv_gpu_shader5_types = 1 << 12,
} feature;
void insert(feature f) { features |= f; }
void erase(feature f) { features &= ~f; }
@ -339,6 +344,7 @@ public:
numTaskNVBlocks(0),
layoutPrimitiveCulling(false),
numTaskEXTPayloads(0),
nonCoherentTileAttachmentReadQCOM(false),
autoMapBindings(false),
autoMapLocations(false),
flattenUniformArrays(false),
@ -367,6 +373,12 @@ public:
localSizeSpecId[1] = TQualifier::layoutNotSet;
localSizeSpecId[2] = TQualifier::layoutNotSet;
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
tileShadingRateQCOM[0] = 0;
tileShadingRateQCOM[1] = 0;
tileShadingRateQCOM[2] = 0;
tileShadingRateQCOMNotDefault[0] = false;
tileShadingRateQCOMNotDefault[1] = false;
tileShadingRateQCOMNotDefault[2] = false;
shiftBinding.fill(0);
}
@ -436,6 +448,9 @@ public:
case EShTargetVulkan_1_3:
processes.addProcess("target-env vulkan1.3");
break;
case EShTargetVulkan_1_4:
processes.addProcess("target-env vulkan1.4");
break;
default:
processes.addProcess("target-env vulkanUnknown");
break;
@ -560,8 +575,8 @@ public:
TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const;
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst,
TIntermLoop* addLoop(TIntermNode*, TIntermNode*, TIntermTyped*, bool testFirst, const TSourceLoc&);
TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermNode*, TIntermTyped*, bool testFirst,
const TSourceLoc&, TIntermLoop*&);
TIntermBranch* addBranch(TOperator, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
@ -644,6 +659,21 @@ public:
bool isEsProfile() const { return profile == EEsProfile; }
bool setTileShadingRateQCOM(int dim, int size)
{
if (tileShadingRateQCOMNotDefault[dim])
return size == tileShadingRateQCOM[dim];
tileShadingRateQCOMNotDefault[dim] = true;
tileShadingRateQCOM[dim] = size;
return true;
}
unsigned int getTileShadingRateQCOM(int dim) const { return tileShadingRateQCOM[dim]; }
bool isTileShadingRateQCOMSet() const
{
// Return true if any component has been set (i.e. any component is not default).
return tileShadingRateQCOMNotDefault[0] || tileShadingRateQCOMNotDefault[1] || tileShadingRateQCOMNotDefault[2];
}
void setShiftBinding(TResourceType res, unsigned int shift)
{
shiftBinding[res] = shift;
@ -729,6 +759,21 @@ public:
usePhysicalStorageBuffer = true;
}
bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
void setReplicatedComposites()
{
useReplicatedComposites = true;
}
bool usingReplicatedComposites() const { return useReplicatedComposites; }
void setPromoteUint32Indices()
{
promoteUint32Indices = true;
}
bool usingPromoteUint32Indices() const { return promoteUint32Indices; }
void setShader64BitIndexing()
{
shader64BitIndexing = true;
}
bool usingShader64BitIndexing() const { return shader64BitIndexing; }
void setUseVariablePointers()
{
useVariablePointers = true;
@ -884,6 +929,8 @@ public:
bool getNonCoherentDepthAttachmentReadEXT() const { return nonCoherentDepthAttachmentReadEXT; }
void setNonCoherentStencilAttachmentReadEXT() { nonCoherentStencilAttachmentReadEXT = true; }
bool getNonCoherentStencilAttachmentReadEXT() const { return nonCoherentStencilAttachmentReadEXT; }
void setNonCoherentTileAttachmentReadQCOM() { nonCoherentTileAttachmentReadQCOM = true; }
bool getNonCoherentTileAttachmentReadQCOM() const { return nonCoherentTileAttachmentReadQCOM; }
void setPostDepthCoverage() { postDepthCoverage = true; }
bool getPostDepthCoverage() const { return postDepthCoverage; }
void setEarlyFragmentTests() { earlyFragmentTests = true; }
@ -1024,11 +1071,11 @@ public:
#endif
bool usingScalarBlockLayout() const {
for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt) {
if (*extIt == E_GL_EXT_scalar_block_layout)
return true;
}
return false;
return IsRequestedExtension(E_GL_EXT_scalar_block_layout);
}
bool usingTextureOffsetNonConst() const {
return IsRequestedExtension(E_GL_EXT_texture_offset_non_const);
}
bool IsRequestedExtension(const char* extension) const
@ -1042,7 +1089,9 @@ public:
void mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly);
void mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit);
void checkStageIO(TInfoSink&, TIntermediate&);
void mergeImplicitArraySizes(TInfoSink& infoSink, TIntermediate& unit);
void checkStageIO(TInfoSink&, TIntermediate&, EShMessages);
void optimizeStageIO(TInfoSink&, TIntermediate&);
bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const;
TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
@ -1055,6 +1104,7 @@ public:
int checkLocationRT(int set, int location);
int addUsedOffsets(int binding, int offset, int numOffsets);
bool addUsedConstantId(int id);
GLSLANG_EXPORT_FOR_TESTS
static int computeTypeLocationSize(const TType&, EShLanguage);
static int computeTypeUniformLocationSize(const TType&);
@ -1093,26 +1143,42 @@ public:
// Certain explicit conversions are allowed conditionally
bool getArithemeticInt8Enabled() const {
return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types) ||
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8);
}
bool getArithemeticInt16Enabled() const {
return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
numericFeatures.contains(TNumericFeatures::gpu_shader_int16) ||
numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types) ||
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16);
}
bool getArithemeticFloat16Enabled() const {
return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) ||
numericFeatures.contains(TNumericFeatures::nv_gpu_shader5_types) ||
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16);
}
void updateNumericFeature(TNumericFeatures::feature f, bool on)
{ on ? numericFeatures.insert(f) : numericFeatures.erase(f); }
void setBuiltinAliasLookup(std::unordered_multimap<std::string, std::string> symbolMap) {
builtinAliasLookup = std::move(symbolMap);
}
const std::unordered_multimap<std::string, std::string>& getBuiltinAliasLookup() const {
return builtinAliasLookup;
}
protected:
TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
void error(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
void warn(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
TIntermSymbol* addSymbol(long long Id, const TString&, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
void error(TInfoSink& infoSink, const TSourceLoc* loc, EShMessages messages, const char*, EShLanguage unitStage = EShLangCount);
void error(TInfoSink& infoSink, const char* message, EShLanguage unitStage = EShLangCount) {
error(infoSink, nullptr, EShMsgDefault, message, unitStage);
}
void warn(TInfoSink& infoSink, const TSourceLoc* loc, EShMessages, const char*, EShLanguage unitStage = EShLangCount);
void warn(TInfoSink& infoSink, const char* message, EShLanguage unitStage = EShLangCount) {
warn(infoSink, nullptr, EShMsgDefault, message, unitStage);
}
void mergeCallGraphs(TInfoSink&, TIntermediate&);
void mergeModes(TInfoSink&, TIntermediate&);
void mergeTrees(TInfoSink&, TIntermediate&);
@ -1122,7 +1188,7 @@ protected:
void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects, EShLanguage);
void mergeBlockDefinitions(TInfoSink&, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unitRoot);
void mergeImplicitArraySizes(TType&, const TType&);
void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, EShLanguage);
void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&);
void checkCallGraphCycles(TInfoSink&);
void checkCallGraphBodies(TInfoSink&, bool keepUncalled);
void inOutLocationCheck(TInfoSink&);
@ -1218,6 +1284,10 @@ protected:
bool layoutPrimitiveCulling;
int numTaskEXTPayloads;
bool nonCoherentTileAttachmentReadQCOM;
int tileShadingRateQCOM[3];
bool tileShadingRateQCOMNotDefault[3];
// Base shift values
std::array<unsigned int, EResCount> shiftBinding;
@ -1242,6 +1312,9 @@ protected:
bool subgroupUniformControlFlow;
bool maximallyReconverges;
bool usePhysicalStorageBuffer;
bool useReplicatedComposites { false };
bool promoteUint32Indices { false };
bool shader64BitIndexing { false };
TSpirvRequirement* spirvRequirement;
TSpirvExecutionMode* spirvExecutionMode;
@ -1270,6 +1343,9 @@ protected:
// Included text. First string is a name, second is the included text
std::map<std::string, std::string> includeText;
// Maps from canonical symbol name to alias symbol names
std::unordered_multimap<std::string, std::string> builtinAliasLookup;
// for OpModuleProcessed, or equivalent
TProcesses processes;

View file

@ -103,6 +103,9 @@ public:
virtual void doubleCheck(const TSourceLoc&, const char* op);
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void float16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void bfloat16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void floate5m2ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void floate4m3ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual bool float16Arithmetic();
virtual void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc);
virtual void int16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
@ -121,6 +124,11 @@ public:
virtual void fcoopmatCheckNV(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void intcoopmatCheckNV(const TSourceLoc&, const char *op, bool builtIn = false);
virtual void coopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void coopmatConverisonCheckQCOM(const TSourceLoc& loc, const char* op, bool builtIn = false);
virtual void tensorLayoutViewCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void coopvecCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void intattachmentCheck(const TSourceLoc&, const char *op, bool builtIn = false);
virtual void tensorCheckARM(const TSourceLoc&, const char *op, bool builtIn = false);
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
bool isForwardCompatible() const { return forwardCompatible; }

View file

@ -153,12 +153,57 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
return token;
}
int pendingPoundSymbols = 0;
TPpToken savePound;
// record the definition of the macro
while (token != '\n' && token != EndOfInput) {
mac.body.putToken(token, ppToken);
if (token == '#') {
pendingPoundSymbols++;
if (pendingPoundSymbols == 0) {
savePound = *ppToken;
}
} else if (pendingPoundSymbols == 0) {
mac.body.putToken(token, ppToken);
} else if (pendingPoundSymbols == 1) {
// A single #: stringify
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "stringify (#)");
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, nullptr, "stringify (#)");
bool isArg = false;
if (token == PpAtomIdentifier) {
for (int i = (int)mac.args.size() - 1; i >= 0; i--) {
if (strcmp(atomStrings.getString(mac.args[i]), ppToken->name) == 0) {
isArg = true;
break;
}
}
}
if (!isArg) {
parseContext.ppError(ppToken->loc, "'#' is not followed by a macro parameter.", "#", "");
return token;
}
mac.body.putToken(tStringifyLevelInput::PUSH, ppToken);
mac.body.putToken(token, ppToken);
mac.body.putToken(tStringifyLevelInput::POP, ppToken);
pendingPoundSymbols = 0;
} else if (pendingPoundSymbols % 2 == 0) {
// Any number of pastes '##' in a row: idempotent, just becomes one paste
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, nullptr, "token pasting (##)");
for (int i = 0; i < pendingPoundSymbols / 2; i++) {
mac.body.putToken(PpAtomPaste, &savePound);
}
mac.body.putToken(token, ppToken);
pendingPoundSymbols = 0;
} else {
// An odd number of '#' i.e., mix of paste and stringify: does not give valid preprocessing token
parseContext.ppError(ppToken->loc, "Illegal sequence of paste (##) and stringify (#).", "#", "");
return token;
}
token = scanToken(ppToken);
if (token != '\n' && ppToken->space)
mac.body.putToken(' ', ppToken);
}
if (pendingPoundSymbols != 0) {
parseContext.ppError(ppToken->loc, "Macro ended with incomplete '#' paste/stringify operators", "#", "");
}
// check for duplicate definition
@ -241,6 +286,7 @@ int TPpContext::CPPundef(TPpToken* ppToken)
*/
int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
{
inElseSkip = true;
int depth = 0;
int token = scanToken(ppToken);
@ -297,7 +343,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
elseSeen[elsetracker] = false;
--elsetracker;
}
inElseSkip = false;
return CPPif(ppToken);
}
} else if (nextAtom == PpAtomElse) {
@ -311,7 +357,8 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
}
}
inElseSkip = false;
return token;
}
@ -374,7 +421,7 @@ namespace {
int op_div(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a / b; }
int op_mod(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a % b; }
int op_pos(int a) { return a; }
int op_neg(int a) { return -a; }
int op_neg(int a) { return a == INT_MIN ? INT_MIN : -a; }
int op_cmpl(int a) { return ~a; }
int op_not(int a) { return !a; }
@ -1117,7 +1164,7 @@ int TPpContext::tMacroInput::scan(TPpToken* ppToken)
}
// see if are preceding a ##
if (mac->body.peekUntokenizedPasting()) {
if (mac->body.peekTokenizedPasting(false)) {
prepaste = true;
pasting = true;
}

View file

@ -88,7 +88,8 @@ TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, T
preamble(nullptr), strings(nullptr), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
rootFileName(rootFileName),
currentSourceFile(rootFileName),
disableEscapeSequences(false)
disableEscapeSequences(false),
inElseSkip(false)
{
ifdepth = 0;
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)

View file

@ -311,7 +311,6 @@ public:
int getToken(TParseContextBase&, TPpToken*);
bool atEnd() { return currentPos >= stream.size(); }
bool peekTokenizedPasting(bool lastTokenPastes);
bool peekUntokenizedPasting();
void reset() { currentPos = 0; }
protected:
@ -371,24 +370,8 @@ protected:
break;
popInput();
}
if (!inputStack.empty() && inputStack.back()->isStringInput()) {
if (!inputStack.empty() && inputStack.back()->isStringInput() && !inElseSkip) {
if (token == '\n') {
bool seenNumSign = false;
for (int i = 0; i < (int)lastLineTokens.size() - 1;) {
int curPos = i;
int curToken = lastLineTokens[i++];
if (curToken == '#' && lastLineTokens[i] == '#') {
curToken = PpAtomPaste;
i++;
}
if (curToken == '#') {
if (seenNumSign) {
parseContext.ppError(lastLineTokenLocs[curPos], "(#) can be preceded in its line only by spaces or horizontal tabs", "#", "");
} else {
seenNumSign = true;
}
}
}
lastLineTokens.clear();
lastLineTokenLocs.clear();
} else {
@ -458,6 +441,38 @@ protected:
static const int marker = -3;
};
class tStringifyLevelInput : public tInput {
int what;
tStringifyLevelInput(TPpContext* pp) : tInput(pp) { }
public:
static tStringifyLevelInput popMarker(TPpContext* pp)
{
tStringifyLevelInput sl(pp);
sl.what = POP;
return sl;
}
static tStringifyLevelInput pushMarker(TPpContext* pp)
{
tStringifyLevelInput sl(pp);
sl.what = PUSH;
return sl;
}
int scan(TPpToken*) override
{
if (done)
return EndOfInput;
done = true;
return what;
}
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
static const int PUSH = -4;
static const int POP = -5;
};
class tZeroInput : public tInput {
public:
tZeroInput(TPpContext* pp) : tInput(pp) { }
@ -732,6 +747,9 @@ protected:
std::istringstream strtodStream;
bool disableEscapeSequences;
// True if we're skipping a section enclosed by #if/#ifdef/#elif/#else which was evaluated to
// be inactive, e.g. #if 0
bool inElseSkip;
};
} // end namespace glslang

View file

@ -97,7 +97,6 @@ namespace glslang {
/////////////////////////////////// Floating point constants: /////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
//
// Scan a single- or double-precision floating point constant.
// Assumes that the scanner has seen at least one digit,
// followed by either a decimal '.' or the letter 'e', or a
@ -470,6 +469,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
static const char* const Int64_Extensions[] = {
E_GL_ARB_gpu_shader_int64,
E_GL_EXT_shader_explicit_arithmetic_types,
E_GL_NV_gpu_shader5,
E_GL_EXT_shader_explicit_arithmetic_types_int64 };
static const int Num_Int64_Extensions = sizeof(Int64_Extensions) / sizeof(Int64_Extensions[0]);
@ -1225,7 +1225,9 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
//
int TPpContext::tokenize(TPpToken& ppToken)
{
for(;;) {
int stringifyDepth = 0;
TPpToken stringifiedToken; // Tokens are appended to this as they come in
for (;;) {
int token = scanToken(&ppToken);
// Handle token-pasting logic
@ -1253,6 +1255,20 @@ int TPpContext::tokenize(TPpToken& ppToken)
if (token == '\n')
continue;
if (token == tStringifyLevelInput::PUSH) {
stringifyDepth++;
continue;
}
if (token == tStringifyLevelInput::POP) {
assert(stringifyDepth > 0);
stringifyDepth--;
if (stringifyDepth == 0) {
snprintf(ppToken.name, sizeof(ppToken.name), "%s", stringifiedToken.name);
return PpAtomConstString;
}
continue;
}
// expand macros
if (token == PpAtomIdentifier) {
switch (MacroExpand(&ppToken, false, true)) {
@ -1266,7 +1282,21 @@ int TPpContext::tokenize(TPpToken& ppToken)
}
}
bool needStringSupport = ifdepth == 0 && (token == PpAtomConstString || stringifyDepth > 0);
if (needStringSupport && parseContext.intermediate.getSource() != EShSourceHlsl) {
// HLSL allows string literals.
// GLSL allows string literals with GL_EXT_debug_printf.
const char* const string_literal_EXTs[] = { E_GL_EXT_debug_printf, E_GL_EXT_spirv_intrinsics };
parseContext.requireExtensions(ppToken.loc, 2, string_literal_EXTs, "string literal");
if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf) &&
!parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) {
continue;
}
}
switch (token) {
case PpAtomConstString:
break;
case PpAtomIdentifier:
case PpAtomConstInt:
case PpAtomConstUint:
@ -1280,17 +1310,6 @@ int TPpContext::tokenize(TPpToken& ppToken)
if (ppToken.name[0] == '\0')
continue;
break;
case PpAtomConstString:
// HLSL allows string literals.
// GLSL allows string literals with GL_EXT_debug_printf.
if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) {
const char* const string_literal_EXTs[] = { E_GL_EXT_debug_printf, E_GL_EXT_spirv_intrinsics };
parseContext.requireExtensions(ppToken.loc, 2, string_literal_EXTs, "string literal");
if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf) &&
!parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
continue;
}
break;
case '\'':
parseContext.ppError(ppToken.loc, "character literals not supported", "\'", "");
continue;
@ -1298,6 +1317,17 @@ int TPpContext::tokenize(TPpToken& ppToken)
snprintf(ppToken.name, sizeof(ppToken.name), "%s", atomStrings.getString(token));
break;
}
if (stringifyDepth > 0) {
size_t existingLen = strlen(stringifiedToken.name);
char* dst = stringifiedToken.name + existingLen;
// stringify_depth would determine how many layers of \\\"\\\" are needed, if we wanted to.
if (ppToken.space) {
snprintf(dst, sizeof(stringifiedToken.name) - existingLen - 1, " %s", ppToken.name);
} else {
snprintf(dst, sizeof(stringifiedToken.name) - existingLen, "%s", ppToken.name);
}
continue;
}
return token;
}
@ -1328,6 +1358,7 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
// This covers end of macro expansion
if (endOfReplacementList()) {
// this should be unreachable, incomplete #/## sequences are caught at macro parsing time.
parseContext.ppError(ppToken.loc, "unexpected location; end of replacement list", "##", "");
break;
}

View file

@ -105,7 +105,7 @@ void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken)
}
// Read the next token from a macro token stream.
int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken)
int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken* ppToken)
{
if (atEnd())
return EndOfInput;
@ -113,16 +113,6 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken
int atom = stream[currentPos++].get(*ppToken);
ppToken->loc = parseContext.getCurrentLoc();
// Check for ##, unless the current # is the last character
if (atom == '#') {
if (peekToken('#')) {
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, nullptr, "token pasting (##)");
currentPos++;
atom = PpAtomPaste;
}
}
return atom;
}
@ -146,8 +136,10 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
// 2. last token and we've been told after this there will be a ##
if (! lastTokenPastes)
if (! lastTokenPastes) {
currentPos = savePos;
return false;
}
// Getting here means the last token will be pasted, after this
// Are we at the last non-whitespace token?
@ -167,29 +159,6 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
return !moreTokens;
}
// See if the next non-white-space tokens are two consecutive #
bool TPpContext::TokenStream::peekUntokenizedPasting()
{
// don't return early, have to restore this
size_t savePos = currentPos;
// skip white-space
while (peekToken(' '))
++currentPos;
// check for ##
bool pasting = false;
if (peekToken('#')) {
++currentPos;
if (peekToken('#'))
pasting = true;
}
currentPos = savePos;
return pasting;
}
void TPpContext::pushTokenStreamInput(TokenStream& ts, bool prepasting, bool expanded)
{
pushInput(new tTokenInput(this, &ts, prepasting, expanded));

View file

@ -174,6 +174,9 @@ bool isArithmeticOperation(glslang::TOperator op)
case glslang::EOpMatrixTimesMatrix:
case glslang::EOpDot:
case glslang::EOpDotPackedEXT:
case glslang::EOpDotAccSatEXT:
case glslang::EOpDotPackedAccSatEXT:
case glslang::EOpPostIncrement:
case glslang::EOpPostDecrement:

View file

@ -52,4 +52,5 @@ namespace glslang {
// 'noContraction' means the object is 'precise'; and for arithmetic operation
// nodes, it means the operation should not be contracted.
void PropagateNoContraction(const glslang::TIntermediate& intermediate);
};
} // end namespace glslang

View file

@ -1138,8 +1138,10 @@ void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediat
{
if (stage == EShLangCompute) {
// Remember thread dimensions
for (int dim=0; dim<3; ++dim)
for (int dim=0; dim<3; ++dim) {
localSize[dim] = intermediate.getLocalSize(dim);
tileShadingRateQCOM[dim] = intermediate.getTileShadingRateQCOM(dim);
}
}
}
@ -1270,9 +1272,8 @@ void TReflection::dump()
indexToPipeOutput[i].dump();
printf("\n");
static const char* axis[] = { "X", "Y", "Z" };
if (getLocalSize(0) > 1) {
static const char* axis[] = { "X", "Y", "Z" };
for (int dim=0; dim<3; ++dim)
if (getLocalSize(dim) > 1)
printf("Local size %s: %u\n", axis[dim], getLocalSize(dim));
@ -1280,6 +1281,12 @@ void TReflection::dump()
printf("\n");
}
if (getTileShadingRateQCOM(0) > 1 || getTileShadingRateQCOM(1) > 1) {
for (int dim=0; dim<3; ++dim)
printf("Tile shading rate QCOM %s: %u\n", axis[dim], getTileShadingRateQCOM(dim));
printf("\n");
}
// printf("Live names\n");
// for (TNameToIndex::const_iterator it = nameToIndex.begin(); it != nameToIndex.end(); ++it)
// printf("%s: %d\n", it->first.c_str(), it->second);

View file

@ -37,8 +37,8 @@
#define _REFLECTION_INCLUDED
#include "../Public/ShaderLang.h"
#include "../Include/Types.h"
#include "../Include/BaseTypes.h"
#include "../Include/visibility.h"
#include <list>
#include <set>
@ -58,13 +58,16 @@ public:
TReflection(EShReflectionOptions opts, EShLanguage first, EShLanguage last)
: options(opts), firstStage(first), lastStage(last), badReflection(TObjectReflection::badReflection())
{
for (int dim=0; dim<3; ++dim)
for (int dim=0; dim<3; ++dim) {
localSize[dim] = 0;
tileShadingRateQCOM[dim] = 0;
}
}
virtual ~TReflection() {}
// grow the reflection stage by stage
GLSLANG_EXPORT_FOR_TESTS
bool addStage(EShLanguage, const TIntermediate&);
// for mapping a uniform index to a uniform object's description
@ -167,6 +170,9 @@ public:
// Thread local size
unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
// Tile shading rate QCOM
unsigned getTileShadingRateQCOM(int dim) const { return dim <= 2 ? tileShadingRateQCOM[dim] : 0; }
void dump();
protected:
@ -212,6 +218,7 @@ protected:
TIndices atomicCounterUniformIndices;
unsigned int localSize[3];
unsigned int tileShadingRateQCOM[3];
};
} // end namespace glslang

View file

@ -35,9 +35,10 @@
#ifndef __OSINCLUDE_H
#define __OSINCLUDE_H
#include "../Include/visibility.h"
namespace glslang {
void OS_DumpMemoryCounters();
GLSLANG_EXPORT void OS_DumpMemoryCounters();
} // end namespace glslang

View file

@ -38,20 +38,21 @@
#include <string>
#include "../Include/ResourceLimits.h"
#include "../Include/visibility.h"
// Return pointer to user-writable Resource to pass through API in
// future-proof way.
extern TBuiltInResource* GetResources();
GLSLANG_EXPORT extern TBuiltInResource* GetResources();
// These are the default resources for TBuiltInResources, used for both
// - parsing this string for the case where the user didn't supply one,
// - dumping out a template for user construction of a config file.
extern const TBuiltInResource* GetDefaultResources();
GLSLANG_EXPORT extern const TBuiltInResource* GetDefaultResources();
// Returns the DefaultTBuiltInResource as a human-readable string.
std::string GetDefaultTBuiltInResourceString();
GLSLANG_EXPORT std::string GetDefaultTBuiltInResourceString();
// Decodes the resource limits from |config| to |resources|.
void DecodeResourceLimits(TBuiltInResource* resources, char* config);
GLSLANG_EXPORT void DecodeResourceLimits(TBuiltInResource* resources, char* config);
#endif // _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_

View file

@ -38,6 +38,7 @@
#define _COMPILER_INTERFACE_INCLUDED_
#include "../Include/ResourceLimits.h"
#include "../Include/visibility.h"
#include "../MachineIndependent/Versions.h"
#include <cstring>
@ -49,22 +50,6 @@
#define C_DECL
#endif
#ifdef GLSLANG_IS_SHARED_LIBRARY
#ifdef _WIN32
#ifdef GLSLANG_EXPORTING
#define GLSLANG_EXPORT __declspec(dllexport)
#else
#define GLSLANG_EXPORT __declspec(dllimport)
#endif
#elif __GNUC__ >= 4
#define GLSLANG_EXPORT __attribute__((visibility("default")))
#endif
#endif // GLSLANG_IS_SHARED_LIBRARY
#ifndef GLSLANG_EXPORT
#define GLSLANG_EXPORT
#endif
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler/linker.
@ -171,8 +156,9 @@ typedef enum {
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2
EShTargetVulkan_1_3 = (1 << 22) | (3 << 12), // Vulkan 1.3
EShTargetVulkan_1_4 = (1 << 22) | (4 << 12), // Vulkan 1.4
EShTargetOpenGL_450 = 450, // OpenGL
LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 5),
LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 6),
} EShTargetClientVersion;
typedef EShTargetClientVersion EshTargetClientVersion;
@ -188,6 +174,21 @@ typedef enum {
LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 7),
} EShTargetLanguageVersion;
//
// Following are a series of helper enums for managing layouts and qualifiers,
// used for TPublicType, TType, others.
//
enum TLayoutPacking {
ElpNone,
ElpShared, // default, but different than saying nothing
ElpStd140,
ElpStd430,
ElpPacked,
ElpScalar,
ElpCount // If expanding, see bitfield width below
};
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
@ -270,6 +271,9 @@ enum EShMessages : unsigned {
EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
EShMsgEnhanced = (1 << 15), // enhanced message readability
EShMsgAbsolutePath = (1 << 16), // Output Absolute path for messages
EShMsgDisplayErrorColumn = (1 << 17), // Display error message column aswell as line
EShMsgLinkTimeOptimization = (1 << 18), // perform cross-stage optimizations during linking
EShMsgValidateCrossStageIO = (1 << 19), // validate shader inputs have matching outputs in previous stage
LAST_ELEMENT_MARKER(EShMsgCount),
};
@ -414,6 +418,7 @@ GLSLANG_EXPORT int GetKhronosToolId();
class TIntermediate;
class TProgram;
class TPoolAllocator;
class TIoMapResolver;
// Call this exactly once per process before using anything else
GLSLANG_EXPORT bool InitializeProcess();
@ -429,6 +434,9 @@ enum TResourceType {
EResUbo,
EResSsbo,
EResUav,
EResCombinedSampler,
EResAs,
EResTensor,
EResCount
};
@ -458,56 +466,59 @@ enum TBlockStorageClass
//
// N.B.: Destruct a linked program *before* destructing the shaders linked into it.
//
class TShader {
class GLSLANG_EXPORT TShader {
public:
GLSLANG_EXPORT explicit TShader(EShLanguage);
GLSLANG_EXPORT virtual ~TShader();
GLSLANG_EXPORT void setStrings(const char* const* s, int n);
GLSLANG_EXPORT void setStringsWithLengths(
explicit TShader(EShLanguage);
virtual ~TShader();
void setStrings(const char* const* s, int n);
void setStringsWithLengths(
const char* const* s, const int* l, int n);
GLSLANG_EXPORT void setStringsWithLengthsAndNames(
void setStringsWithLengthsAndNames(
const char* const* s, const int* l, const char* const* names, int n);
void setPreamble(const char* s) { preamble = s; }
GLSLANG_EXPORT void setEntryPoint(const char* entryPoint);
GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
GLSLANG_EXPORT void setUniqueId(unsigned long long id);
GLSLANG_EXPORT void setOverrideVersion(int version);
GLSLANG_EXPORT void setDebugInfo(bool debugInfo);
void setEntryPoint(const char* entryPoint);
void setSourceEntryPoint(const char* sourceEntryPointName);
void addProcesses(const std::vector<std::string>&);
void setUniqueId(unsigned long long id);
void setOverrideVersion(int version);
void setDebugInfo(bool debugInfo);
// IO resolver binding data: see comments in ShaderLang.cpp
GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);
GLSLANG_EXPORT void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
GLSLANG_EXPORT void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
GLSLANG_EXPORT void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
GLSLANG_EXPORT void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
GLSLANG_EXPORT void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
GLSLANG_EXPORT void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
GLSLANG_EXPORT void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
GLSLANG_EXPORT void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
GLSLANG_EXPORT void setResourceSetBinding(const std::vector<std::string>& base);
GLSLANG_EXPORT void setAutoMapBindings(bool map);
GLSLANG_EXPORT void setAutoMapLocations(bool map);
GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc);
GLSLANG_EXPORT void setUniformLocationBase(int base);
GLSLANG_EXPORT void setInvertY(bool invert);
GLSLANG_EXPORT void setDxPositionW(bool dxPosW);
GLSLANG_EXPORT void setEnhancedMsgs();
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 setDxPositionW(bool dxPosW);
void setEnhancedMsgs();
#ifdef ENABLE_HLSL
GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);
void setHlslIoMapping(bool hlslIoMap);
void setFlattenUniformArrays(bool flatten);
#endif
GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat);
GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp);
GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
GLSLANG_EXPORT void addBlockStorageOverride(const char* nameStr, glslang::TBlockStorageClass backing);
void setNoStorageFormat(bool useUnknownFormat);
void setNanMinMaxClamp(bool nanMinMaxClamp);
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
void addBlockStorageOverride(const char* nameStr, glslang::TBlockStorageClass backing);
GLSLANG_EXPORT void setGlobalUniformBlockName(const char* name);
GLSLANG_EXPORT void setAtomicCounterBlockName(const char* name);
GLSLANG_EXPORT void setGlobalUniformSet(unsigned int set);
GLSLANG_EXPORT void setGlobalUniformBinding(unsigned int binding);
GLSLANG_EXPORT void setAtomicCounterBlockSet(unsigned int set);
GLSLANG_EXPORT void setAtomicCounterBlockBinding(unsigned int binding);
void setGlobalUniformBlockName(const char* name);
void setAtomicCounterBlockName(const char* name);
void setGlobalUniformSet(unsigned int set);
void setGlobalUniformBinding(unsigned int binding);
void setAtomicCounterBlockSet(unsigned int set);
void setAtomicCounterBlockBinding(unsigned int binding);
void addSourceText(const char* text, size_t len);
void setSourceFile(const char* file);
// 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
@ -656,7 +667,7 @@ public:
virtual void releaseInclude(IncludeResult*) override { }
};
GLSLANG_EXPORT bool parse(
bool parse(
const TBuiltInResource*, int defaultVersion, EProfile defaultProfile,
bool forceDefaultVersionAndProfile, bool forwardCompatible,
EShMessages, Includer&);
@ -682,14 +693,14 @@ public:
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
// is not an officially supported or fully working path.
GLSLANG_EXPORT bool preprocess(
bool preprocess(
const TBuiltInResource* builtInResources, int defaultVersion,
EProfile defaultProfile, bool forceDefaultVersionAndProfile,
bool forwardCompatible, EShMessages message, std::string* outputString,
Includer& includer);
GLSLANG_EXPORT const char* getInfoLog();
GLSLANG_EXPORT const char* getInfoDebugLog();
const char* getInfoLog();
const char* getInfoDebugLog();
EShLanguage getStage() const { return stage; }
TIntermediate* getIntermediate() const { return intermediate; }
@ -736,15 +747,17 @@ private:
//
// Data needed for just a single object at the granularity exchanged by the reflection API
class TObjectReflection {
class GLSLANG_EXPORT TObjectReflection {
public:
GLSLANG_EXPORT TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
const TType* getType() const { return type; }
GLSLANG_EXPORT int getBinding() const;
GLSLANG_EXPORT void dump() const;
int getBinding() const;
void dump() const;
static TObjectReflection badReflection() { return TObjectReflection(); }
unsigned int layoutLocation() const;
std::string name;
int offset;
int glDefineType;
@ -794,8 +807,7 @@ struct TVarEntryInfo;
//
// NOTE: that still limit checks are applied to bindings and sets
// and may result in an error.
class TIoMapResolver
{
class GLSLANG_EXPORT TIoMapResolver {
public:
virtual ~TIoMapResolver() {}
@ -847,46 +859,61 @@ public:
virtual void addStage(EShLanguage stage, TIntermediate& stageIntermediate) = 0;
};
// I/O mapper
class TIoMapper {
public:
TIoMapper() {}
virtual ~TIoMapper() {}
// grow the reflection stage by stage
bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*);
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
bool virtual setAutoPushConstantBlock(const char*, unsigned int, TLayoutPacking) { return false; }
};
// Get the default GLSL IO mapper
GLSLANG_EXPORT TIoMapper* GetGlslIoMapper();
// 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 {
class GLSLANG_EXPORT TProgram {
public:
GLSLANG_EXPORT TProgram();
GLSLANG_EXPORT virtual ~TProgram();
TProgram();
virtual ~TProgram();
void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
std::list<TShader*>& getShaders(EShLanguage stage) { return stages[stage]; }
// Link Validation interface
GLSLANG_EXPORT bool link(EShMessages);
GLSLANG_EXPORT const char* getInfoLog();
GLSLANG_EXPORT const char* getInfoDebugLog();
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
GLSLANG_EXPORT bool buildReflection(int opts = EShReflectionDefault);
GLSLANG_EXPORT unsigned getLocalSize(int dim) const; // return dim'th local size
GLSLANG_EXPORT int getReflectionIndex(const char *name) const;
GLSLANG_EXPORT int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const;
GLSLANG_EXPORT int getNumUniformVariables() const;
GLSLANG_EXPORT const TObjectReflection& getUniform(int index) const;
GLSLANG_EXPORT int getNumUniformBlocks() const;
GLSLANG_EXPORT const TObjectReflection& getUniformBlock(int index) const;
GLSLANG_EXPORT int getNumPipeInputs() const;
GLSLANG_EXPORT const TObjectReflection& getPipeInput(int index) const;
GLSLANG_EXPORT int getNumPipeOutputs() const;
GLSLANG_EXPORT const TObjectReflection& getPipeOutput(int index) const;
GLSLANG_EXPORT int getNumBufferVariables() const;
GLSLANG_EXPORT const TObjectReflection& getBufferVariable(int index) const;
GLSLANG_EXPORT int getNumBufferBlocks() const;
GLSLANG_EXPORT const TObjectReflection& getBufferBlock(int index) const;
GLSLANG_EXPORT int getNumAtomicCounters() const;
GLSLANG_EXPORT const TObjectReflection& getAtomicCounter(int index) const;
bool buildReflection(int opts = EShReflectionDefault);
unsigned getLocalSize(int dim) const; // return dim'th local size
unsigned getTileShadingRateQCOM(int dim) const; // return dim'th tile shading rate QCOM
int getReflectionIndex(const char *name) const;
int getReflectionPipeIOIndex(const char* name, const bool inOrOut) 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
@ -953,15 +980,19 @@ public:
// returns a TType*
const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); }
GLSLANG_EXPORT void dumpReflection();
void dumpReflection();
// Get the IO resolver to use for mapIO
TIoMapResolver* getGlslIoResolver(EShLanguage stage);
// 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.
GLSLANG_EXPORT bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr);
bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr);
protected:
GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages);
GLSLANG_EXPORT bool crossStageCheck(EShMessages);
bool linkStage(EShLanguage, EShMessages);
bool crossStageCheck(EShMessages);
TPoolAllocator* pool;
std::list<TShader*> stages[EShLangCount];

View file

@ -39,9 +39,9 @@
#include "glslang/Public/ResourceLimits.h"
TBuiltInResource Resources;
static TBuiltInResource Resources;
const TBuiltInResource DefaultTBuiltInResource = {
static const TBuiltInResource DefaultTBuiltInResource = {
/* .MaxLights = */ 32,
/* .MaxClipPlanes = */ 6,
/* .MaxTextureUnits = */ 32,

View file

@ -34,8 +34,8 @@
#ifndef GLSLANG_BUILD_INFO
#define GLSLANG_BUILD_INFO
#define GLSLANG_VERSION_MAJOR 14
#define GLSLANG_VERSION_MINOR 2
#define GLSLANG_VERSION_MAJOR 16
#define GLSLANG_VERSION_MINOR 1
#define GLSLANG_VERSION_PATCH 0
#define GLSLANG_VERSION_FLAVOR ""

View file

@ -1,5 +1,5 @@
diff --git a/thirdparty/glslang/glslang/Include/InfoSink.h b/thirdparty/glslang/glslang/Include/InfoSink.h
index 23f495dcb7..137ede8510 100644
index 262933941d..dec05e651c 100644
--- a/thirdparty/glslang/glslang/Include/InfoSink.h
+++ b/thirdparty/glslang/glslang/Include/InfoSink.h
@@ -36,7 +36,7 @@
@ -11,8 +11,8 @@ index 23f495dcb7..137ede8510 100644
#include <cmath>
namespace glslang {
@@ -101,14 +101,14 @@ public:
snprintf(locText, maxSize, ":%d", loc.line);
@@ -105,14 +105,14 @@ public:
}
if(loc.getFilename() == nullptr && shaderFileName != nullptr && absolute) {
- append(std::filesystem::absolute(shaderFileName).string());

View file

@ -1,12 +0,0 @@
diff --git a/thirdparty/glslang/SPIRV/SpvBuilder.h b/thirdparty/glslang/SPIRV/SpvBuilder.h
index a65a98e337..1499592c4f 100644
--- a/thirdparty/glslang/SPIRV/SpvBuilder.h
+++ b/thirdparty/glslang/SPIRV/SpvBuilder.h
@@ -56,6 +56,7 @@ namespace spv {
}
#include <algorithm>
+#include <cstdint>
#include <map>
#include <memory>
#include <set>

View file

@ -81,31 +81,105 @@ bool CFG::is_back_edge(uint32_t to) const
// We have a back edge if the visit order is set with the temporary magic value 0.
// Crossing edges will have already been recorded with a visit order.
auto itr = visit_order.find(to);
return itr != end(visit_order) && itr->second.get() == 0;
return itr != end(visit_order) && itr->second.visited_branches && !itr->second.visited_resolve;
}
bool CFG::has_visited_forward_edge(uint32_t to) const
bool CFG::has_visited_branch(uint32_t to) const
{
// If > 0, we have visited the edge already, and this is not a back edge branch.
auto itr = visit_order.find(to);
return itr != end(visit_order) && itr->second.get() > 0;
return itr != end(visit_order) && itr->second.visited_branches;
}
bool CFG::post_order_visit(uint32_t block_id)
void CFG::post_order_visit_entry(uint32_t block)
{
// If we have already branched to this block (back edge), stop recursion.
// If our branches are back-edges, we do not record them.
// We have to record crossing edges however.
if (has_visited_forward_edge(block_id))
return true;
else if (is_back_edge(block_id))
return false;
visit_stack.push_back(block);
// Block back-edges from recursively revisiting ourselves.
visit_order[block_id].get() = 0;
while (!visit_stack.empty())
{
bool keep_iterating;
do
{
// Reverse the order to allow for stack-like behavior and preserves the visit order from recursive algorithm.
// Traverse depth first.
uint32_t to_visit = visit_stack.back();
last_visited_size = visit_stack.size();
post_order_visit_branches(to_visit);
keep_iterating = last_visited_size != visit_stack.size();
if (keep_iterating)
std::reverse(visit_stack.begin() + last_visited_size, visit_stack.end());
} while (keep_iterating);
// We've reached the end of some tree leaf. Resolve the stack.
// Any node which has been visited for real can be popped now.
while (!visit_stack.empty() && visit_order[visit_stack.back()].visited_branches)
{
post_order_visit_resolve(visit_stack.back());
visit_stack.pop_back();
}
}
}
void CFG::visit_branch(uint32_t block_id)
{
// Prune obvious duplicates.
if (std::find(visit_stack.begin() + last_visited_size, visit_stack.end(), block_id) == visit_stack.end() &&
!has_visited_branch(block_id))
{
visit_stack.push_back(block_id);
}
}
void CFG::post_order_visit_branches(uint32_t block_id)
{
auto &block = compiler.get<SPIRBlock>(block_id);
auto &visit = visit_order[block_id];
if (visit.visited_branches)
return;
visit.visited_branches = true;
if (block.merge == SPIRBlock::MergeLoop)
visit_branch(block.merge_block);
else if (block.merge == SPIRBlock::MergeSelection)
visit_branch(block.next_block);
// First visit our branch targets.
switch (block.terminator)
{
case SPIRBlock::Direct:
visit_branch(block.next_block);
break;
case SPIRBlock::Select:
visit_branch(block.true_block);
visit_branch(block.false_block);
break;
case SPIRBlock::MultiSelect:
{
const auto &cases = compiler.get_case_list(block);
for (const auto &target : cases)
visit_branch(target.block);
if (block.default_block)
visit_branch(block.default_block);
break;
}
default:
break;
}
}
void CFG::post_order_visit_resolve(uint32_t block_id)
{
auto &block = compiler.get<SPIRBlock>(block_id);
auto &visit_block = visit_order[block_id];
assert(visit_block.visited_branches);
auto &visited = visit_order[block_id].visited_resolve;
if (visited)
return;
// If this is a loop header, add an implied branch to the merge target.
// This is needed to avoid annoying cases with do { ... } while(false) loops often generated by inliners.
// To the CFG, this is linear control flow, but we risk picking the do/while scope as our dominating block.
@ -116,21 +190,21 @@ bool CFG::post_order_visit(uint32_t block_id)
// is lower than inside the loop, which is going to be key for some traversal algorithms like post-dominance analysis.
// For selection constructs true/false blocks will end up visiting the merge block directly and it works out fine,
// but for loops, only the header might end up actually branching to merge block.
if (block.merge == SPIRBlock::MergeLoop && post_order_visit(block.merge_block))
if (block.merge == SPIRBlock::MergeLoop && !is_back_edge(block.merge_block))
add_branch(block_id, block.merge_block);
// First visit our branch targets.
switch (block.terminator)
{
case SPIRBlock::Direct:
if (post_order_visit(block.next_block))
if (!is_back_edge(block.next_block))
add_branch(block_id, block.next_block);
break;
case SPIRBlock::Select:
if (post_order_visit(block.true_block))
if (!is_back_edge(block.true_block))
add_branch(block_id, block.true_block);
if (post_order_visit(block.false_block))
if (!is_back_edge(block.false_block))
add_branch(block_id, block.false_block);
break;
@ -139,10 +213,10 @@ bool CFG::post_order_visit(uint32_t block_id)
const auto &cases = compiler.get_case_list(block);
for (const auto &target : cases)
{
if (post_order_visit(target.block))
if (!is_back_edge(target.block))
add_branch(block_id, target.block);
}
if (block.default_block && post_order_visit(block.default_block))
if (block.default_block && !is_back_edge(block.default_block))
add_branch(block_id, block.default_block);
break;
}
@ -157,7 +231,7 @@ bool CFG::post_order_visit(uint32_t block_id)
// We can use the variable without a Phi since there is only one possible parent here.
// However, in this case, we need to hoist out the inner variable to outside the branch.
// Use same strategy as loops.
if (block.merge == SPIRBlock::MergeSelection && post_order_visit(block.next_block))
if (block.merge == SPIRBlock::MergeSelection && !is_back_edge(block.next_block))
{
// If there is only one preceding edge to the merge block and it's not ourselves, we need a fixup.
// Add a fake branch so any dominator in either the if (), or else () block, or a lone case statement
@ -201,10 +275,9 @@ bool CFG::post_order_visit(uint32_t block_id)
}
}
// Then visit ourselves. Start counting at one, to let 0 be a magic value for testing back vs. crossing edges.
visit_order[block_id].get() = ++visit_count;
visited = true;
visit_block.order = ++visit_count;
post_order.push_back(block_id);
return true;
}
void CFG::build_post_order_visit_order()
@ -213,11 +286,12 @@ void CFG::build_post_order_visit_order()
visit_count = 0;
visit_order.clear();
post_order.clear();
post_order_visit(block);
post_order_visit_entry(block);
}
void CFG::add_branch(uint32_t from, uint32_t to)
{
assert(from && to);
const auto add_unique = [](SmallVector<uint32_t> &l, uint32_t value) {
auto itr = find(begin(l), end(l), value);
if (itr == end(l))

View file

@ -68,7 +68,7 @@ public:
{
auto itr = visit_order.find(block);
assert(itr != std::end(visit_order));
int v = itr->second.get();
int v = itr->second.order;
assert(v > 0);
return uint32_t(v);
}
@ -114,17 +114,9 @@ public:
private:
struct VisitOrder
{
int &get()
{
return v;
}
const int &get() const
{
return v;
}
int v = -1;
int order = -1;
bool visited_resolve = false;
bool visited_branches = false;
};
Compiler &compiler;
@ -139,11 +131,17 @@ private:
void add_branch(uint32_t from, uint32_t to);
void build_post_order_visit_order();
void build_immediate_dominators();
bool post_order_visit(uint32_t block);
void post_order_visit_branches(uint32_t block);
void post_order_visit_resolve(uint32_t block);
void post_order_visit_entry(uint32_t block);
uint32_t visit_count = 0;
bool is_back_edge(uint32_t to) const;
bool has_visited_forward_edge(uint32_t to) const;
bool has_visited_branch(uint32_t to) const;
void visit_branch(uint32_t block_id);
SmallVector<uint32_t> visit_stack;
size_t last_visited_size = 0;
};
class DominatorBuilder

View file

@ -27,8 +27,17 @@
#ifndef SPV_ENABLE_UTILITY_CODE
#define SPV_ENABLE_UTILITY_CODE
#endif
#include "spirv.hpp"
// Pragmatic hack to avoid symbol conflicts when including both hpp11 and hpp headers in same translation unit.
// This is an unfortunate SPIRV-Headers issue that we cannot easily deal with ourselves.
#ifdef SPIRV_CROSS_SPV_HEADER_NAMESPACE_OVERRIDE
#define spv SPIRV_CROSS_SPV_HEADER_NAMESPACE_OVERRIDE
#define SPIRV_CROSS_SPV_HEADER_NAMESPACE SPIRV_CROSS_SPV_HEADER_NAMESPACE_OVERRIDE
#else
#define SPIRV_CROSS_SPV_HEADER_NAMESPACE spv
#endif
#include "spirv.hpp"
#include "spirv_cross_containers.hpp"
#include "spirv_cross_error_handling.hpp"
#include <functional>
@ -574,6 +583,7 @@ struct SPIRType : IVariant
Sampler,
AccelerationStructure,
RayQuery,
CoopVecNV,
// Keep internal types at the end.
ControlPointArray,
@ -583,7 +593,9 @@ struct SPIRType : IVariant
MeshGridProperties,
BFloat16,
FloatE4M3,
FloatE5M2
FloatE5M2,
Tensor
};
// Scalar/vector/matrix support.
@ -608,13 +620,29 @@ struct SPIRType : IVariant
bool pointer = false;
bool forward_pointer = false;
struct
union
{
uint32_t use_id = 0;
uint32_t rows_id = 0;
uint32_t columns_id = 0;
uint32_t scope_id = 0;
} cooperative;
struct
{
uint32_t use_id;
uint32_t rows_id;
uint32_t columns_id;
uint32_t scope_id;
} cooperative;
struct
{
uint32_t component_type_id;
uint32_t component_count_id;
} coopVecNV;
struct
{
uint32_t type;
uint32_t rank;
uint32_t shape;
} tensor;
} ext;
spv::StorageClass storage = spv::StorageClassGeneric;
@ -672,6 +700,12 @@ struct SPIRExtension : IVariant
NonSemanticGeneric
};
enum ShaderDebugInfoOps
{
DebugLine = 103,
DebugSource = 35
};
explicit SPIRExtension(Extension ext_)
: ext(ext_)
{
@ -698,6 +732,10 @@ struct SPIREntryPoint
std::string name;
std::string orig_name;
std::unordered_map<uint32_t, uint32_t> fp_fast_math_defaults;
bool signed_zero_inf_nan_preserve_8 = false;
bool signed_zero_inf_nan_preserve_16 = false;
bool signed_zero_inf_nan_preserve_32 = false;
bool signed_zero_inf_nan_preserve_64 = false;
SmallVector<VariableID> interface_variables;
Bitset flags;
@ -930,6 +968,7 @@ struct SPIRBlock : IVariant
// All access to these variables are dominated by this block,
// so before branching anywhere we need to make sure that we declare these variables.
SmallVector<VariableID> dominated_variables;
SmallVector<bool> rearm_dominated_variables;
// These are variables which should be declared in a for loop header, if we
// fail to use a classic for-loop,
@ -1825,7 +1864,8 @@ private:
static inline bool type_is_floating_point(const SPIRType &type)
{
return type.basetype == SPIRType::Half || type.basetype == SPIRType::Float || type.basetype == SPIRType::Double;
return type.basetype == SPIRType::Half || type.basetype == SPIRType::Float || type.basetype == SPIRType::Double ||
type.basetype == SPIRType::BFloat16 || type.basetype == SPIRType::FloatE5M2 || type.basetype == SPIRType::FloatE4M3;
}
static inline bool type_is_integral(const SPIRType &type)
@ -2010,4 +2050,7 @@ struct hash<SPIRV_CROSS_NAMESPACE::TypedID<type>>
};
} // namespace std
#ifdef SPIRV_CROSS_SPV_HEADER_NAMESPACE_OVERRIDE
#undef spv
#endif
#endif

View file

@ -31,7 +31,7 @@
#include <utility>
using namespace std;
using namespace spv;
using namespace SPIRV_CROSS_SPV_HEADER_NAMESPACE;
using namespace SPIRV_CROSS_NAMESPACE;
Compiler::Compiler(vector<uint32_t> ir_)
@ -280,6 +280,9 @@ bool Compiler::block_is_pure(const SPIRBlock &block)
// This is a global side effect of the function.
return false;
case OpTensorReadARM:
return false;
case OpExtInst:
{
uint32_t extension_set = ops[2];
@ -373,6 +376,7 @@ void Compiler::register_global_read_dependencies(const SPIRBlock &block, uint32_
case OpLoad:
case OpCooperativeMatrixLoadKHR:
case OpCooperativeVectorLoadNV:
case OpImageRead:
{
// If we're in a storage class which does not get invalidated, adding dependencies here is no big deal.
@ -624,7 +628,7 @@ bool Compiler::is_immutable(uint32_t id) const
return false;
}
static inline bool storage_class_is_interface(spv::StorageClass storage)
static inline bool storage_class_is_interface(StorageClass storage)
{
switch (storage)
{
@ -657,8 +661,8 @@ bool Compiler::is_hidden_variable(const SPIRVariable &var, bool include_builtins
// In SPIR-V 1.4 and up we must also use the active variable interface to disable global variables
// which are not part of the entry point.
if (ir.get_spirv_version() >= 0x10400 && var.storage != spv::StorageClassGeneric &&
var.storage != spv::StorageClassFunction && !interface_variable_exists_in_entry_point(var.self))
if (ir.get_spirv_version() >= 0x10400 && var.storage != StorageClassGeneric &&
var.storage != StorageClassFunction && !interface_variable_exists_in_entry_point(var.self))
{
return true;
}
@ -738,6 +742,14 @@ bool Compiler::is_physical_pointer(const SPIRType &type) const
return type.op == OpTypePointer && type.storage == StorageClassPhysicalStorageBuffer;
}
bool Compiler::is_physical_or_buffer_pointer(const SPIRType &type) const
{
return type.op == OpTypePointer &&
(type.storage == StorageClassPhysicalStorageBuffer || type.storage == StorageClassUniform ||
type.storage == StorageClassStorageBuffer || type.storage == StorageClassWorkgroup ||
type.storage == StorageClassPushConstant);
}
bool Compiler::is_physical_pointer_to_buffer_block(const SPIRType &type) const
{
return is_physical_pointer(type) && get_pointee_type(type).self == type.parent_type &&
@ -1152,6 +1164,11 @@ ShaderResources Compiler::get_shader_resources(const unordered_set<VariableID> *
{
res.acceleration_structures.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
}
// Tensors
else if (type.basetype == SPIRType::Tensor)
{
res.tensors.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
}
else
{
res.gl_plain_uniforms.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
@ -1169,11 +1186,8 @@ bool Compiler::type_is_top_level_block(const SPIRType &type) const
return has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock);
}
bool Compiler::type_is_block_like(const SPIRType &type) const
bool Compiler::type_is_explicit_layout(const SPIRType &type) const
{
if (type_is_top_level_block(type))
return true;
if (type.basetype == SPIRType::Struct)
{
// Block-like types may have Offset decorations.
@ -1185,6 +1199,14 @@ bool Compiler::type_is_block_like(const SPIRType &type) const
return false;
}
bool Compiler::type_is_block_like(const SPIRType &type) const
{
if (type_is_top_level_block(type))
return true;
else
return type_is_explicit_layout(type);
}
void Compiler::parse_fixup()
{
// Figure out specialization constants for work group sizes.
@ -1327,7 +1349,7 @@ const SPIRType &Compiler::get_pointee_type(uint32_t type_id) const
uint32_t Compiler::get_variable_data_type_id(const SPIRVariable &var) const
{
if (var.phi_variable || var.storage == spv::StorageClass::StorageClassAtomicCounter)
if (var.phi_variable || var.storage == StorageClassAtomicCounter)
return var.basetype;
return get_pointee_type_id(var.basetype);
}
@ -1364,7 +1386,7 @@ bool Compiler::is_sampled_image_type(const SPIRType &type)
type.image.dim != DimBuffer;
}
void Compiler::set_member_decoration_string(TypeID id, uint32_t index, spv::Decoration decoration,
void Compiler::set_member_decoration_string(TypeID id, uint32_t index, Decoration decoration,
const std::string &argument)
{
ir.set_member_decoration_string(id, index, decoration, argument);
@ -1425,7 +1447,7 @@ void Compiler::unset_member_decoration(TypeID id, uint32_t index, Decoration dec
ir.unset_member_decoration(id, index, decoration);
}
void Compiler::set_decoration_string(ID id, spv::Decoration decoration, const std::string &argument)
void Compiler::set_decoration_string(ID id, Decoration decoration, const std::string &argument)
{
ir.set_decoration_string(id, decoration, argument);
}
@ -1588,7 +1610,7 @@ void Compiler::unset_decoration(ID id, Decoration decoration)
ir.unset_decoration(id, decoration);
}
bool Compiler::get_binary_offset_for_decoration(VariableID id, spv::Decoration decoration, uint32_t &word_offset) const
bool Compiler::get_binary_offset_for_decoration(VariableID id, Decoration decoration, uint32_t &word_offset) const
{
auto *m = ir.find_meta(id);
if (!m)
@ -1893,6 +1915,15 @@ bool Compiler::traverse_all_reachable_opcodes(const SPIRBlock &block, OpcodeHand
handler.set_current_block(block);
handler.rearm_current_block(block);
if (handler.enable_result_types)
{
for (auto &phi: block.phi_variables)
{
auto &v = get<SPIRVariable>(phi.function_variable);
handler.result_types[phi.function_variable] = v.basetype;
}
}
// Ideally, perhaps traverse the CFG instead of all blocks in order to eliminate dead blocks,
// but this shouldn't be a problem in practice unless the SPIR-V is doing insane things like recursing
// inside dead blocks ...
@ -1904,11 +1935,24 @@ bool Compiler::traverse_all_reachable_opcodes(const SPIRBlock &block, OpcodeHand
if (!handler.handle(op, ops, i.length))
return false;
if (handler.enable_result_types)
{
// If it has one, keep track of the instruction's result type, mapped by ID
uint32_t result_type, result_id;
if (instruction_to_result_type(result_type, result_id, op, ops, i.length))
handler.result_types[result_id] = result_type;
}
if (op == OpFunctionCall)
{
auto &func = get<SPIRFunction>(ops[2]);
if (handler.follow_function_call(func))
{
if (handler.enable_result_types)
for (auto &arg : func.arguments)
if (!arg.alias_global_variable)
handler.result_types[arg.id] = arg.type;
if (!handler.begin_function_scope(ops, i.length))
return false;
if (!traverse_all_reachable_opcodes(get<SPIRFunction>(ops[2]), handler))
@ -2443,7 +2487,7 @@ uint32_t Compiler::get_work_group_size_specialization_constants(SpecializationCo
return execution.workgroup_size.constant;
}
uint32_t Compiler::get_execution_mode_argument(spv::ExecutionMode mode, uint32_t index) const
uint32_t Compiler::get_execution_mode_argument(ExecutionMode mode, uint32_t index) const
{
auto &execution = get_entry_point();
switch (mode)
@ -2629,14 +2673,14 @@ SmallVector<EntryPoint> Compiler::get_entry_points_and_stages() const
return entries;
}
void Compiler::rename_entry_point(const std::string &old_name, const std::string &new_name, spv::ExecutionModel model)
void Compiler::rename_entry_point(const std::string &old_name, const std::string &new_name, ExecutionModel model)
{
auto &entry = get_entry_point(old_name, model);
entry.orig_name = new_name;
entry.name = new_name;
}
void Compiler::set_entry_point(const std::string &name, spv::ExecutionModel model)
void Compiler::set_entry_point(const std::string &name, ExecutionModel model)
{
auto &entry = get_entry_point(name, model);
ir.default_entry_point = entry.self;
@ -3332,7 +3376,7 @@ void Compiler::analyze_parameter_preservation(
Compiler::AnalyzeVariableScopeAccessHandler::AnalyzeVariableScopeAccessHandler(Compiler &compiler_,
SPIRFunction &entry_)
: compiler(compiler_)
: OpcodeHandler(compiler_)
, entry(entry_)
{
}
@ -3450,11 +3494,11 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle_terminator(const SPIRBl
return true;
}
bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint32_t *args, uint32_t length)
bool Compiler::AnalyzeVariableScopeAccessHandler::handle(Op op, const uint32_t *args, uint32_t length)
{
// Keep track of the types of temporaries, so we can hoist them out as necessary.
uint32_t result_type = 0, result_id = 0;
if (compiler.instruction_to_result_type(result_type, result_id, op, args, length))
if (instruction_to_result_type(result_type, result_id, op, args, length))
{
// For some opcodes, we will need to override the result id.
// If we need to hoist the temporary, the temporary type is the input, not the result.
@ -3797,7 +3841,7 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
}
Compiler::StaticExpressionAccessHandler::StaticExpressionAccessHandler(Compiler &compiler_, uint32_t variable_id_)
: compiler(compiler_)
: OpcodeHandler(compiler_)
, variable_id(variable_id_)
{
}
@ -3807,7 +3851,7 @@ bool Compiler::StaticExpressionAccessHandler::follow_function_call(const SPIRFun
return false;
}
bool Compiler::StaticExpressionAccessHandler::handle(spv::Op op, const uint32_t *args, uint32_t length)
bool Compiler::StaticExpressionAccessHandler::handle(Op op, const uint32_t *args, uint32_t length)
{
switch (op)
{
@ -4338,6 +4382,7 @@ bool Compiler::may_read_undefined_variable_in_block(const SPIRBlock &block, uint
case OpCopyObject:
case OpLoad:
case OpCooperativeVectorLoadNV:
case OpCooperativeMatrixLoadKHR:
if (ops[2] == var)
return true;
@ -4366,7 +4411,7 @@ bool Compiler::may_read_undefined_variable_in_block(const SPIRBlock &block, uint
return true;
}
bool Compiler::GeometryEmitDisocveryHandler::handle(spv::Op opcode, const uint32_t *, uint32_t)
bool Compiler::GeometryEmitDisocveryHandler::handle(Op opcode, const uint32_t *, uint32_t)
{
if (opcode == OpEmitVertex || opcode == OpEndPrimitive)
{
@ -4384,8 +4429,9 @@ bool Compiler::GeometryEmitDisocveryHandler::begin_function_scope(const uint32_t
return true;
}
bool Compiler::GeometryEmitDisocveryHandler::end_function_scope([[maybe_unused]] const uint32_t *stream, uint32_t)
bool Compiler::GeometryEmitDisocveryHandler::end_function_scope(const uint32_t *stream, uint32_t)
{
(void)stream;
assert(function_stack.back() == &compiler.get<SPIRFunction>(stream[2]));
function_stack.pop_back();
@ -4506,7 +4552,7 @@ void Compiler::ActiveBuiltinHandler::add_if_builtin_or_block(uint32_t id)
add_if_builtin(id, true);
}
bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args, uint32_t length)
bool Compiler::ActiveBuiltinHandler::handle(Op opcode, const uint32_t *args, uint32_t length)
{
switch (opcode)
{
@ -4701,7 +4747,7 @@ void Compiler::analyze_image_and_sampler_usage()
comparison_ids.insert(combined.combined_id);
}
bool Compiler::CombinedImageSamplerDrefHandler::handle(spv::Op opcode, const uint32_t *args, uint32_t)
bool Compiler::CombinedImageSamplerDrefHandler::handle(Op opcode, const uint32_t *args, uint32_t)
{
// Mark all sampled images which are used with Dref.
switch (opcode)
@ -4810,11 +4856,11 @@ void Compiler::build_function_control_flow_graphs_and_analyze()
}
Compiler::CFGBuilder::CFGBuilder(Compiler &compiler_)
: compiler(compiler_)
: OpcodeHandler(compiler_)
{
}
bool Compiler::CFGBuilder::handle(spv::Op, const uint32_t *, uint32_t)
bool Compiler::CFGBuilder::handle(Op, const uint32_t *, uint32_t)
{
return true;
}
@ -4990,7 +5036,7 @@ void Compiler::make_constant_null(uint32_t id, uint32_t type)
}
}
const SmallVector<spv::Capability> &Compiler::get_declared_capabilities() const
const SmallVector<Capability> &Compiler::get_declared_capabilities() const
{
return ir.declared_capabilities;
}
@ -5065,7 +5111,7 @@ bool Compiler::reflection_ssbo_instance_name_is_significant() const
return aliased_ssbo_types;
}
bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, spv::Op op,
bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, Op op,
const uint32_t *args, uint32_t length)
{
if (length < 2)
@ -5112,7 +5158,7 @@ Bitset Compiler::combined_decoration_for_member(const SPIRType &type, uint32_t i
return flags;
}
bool Compiler::is_desktop_only_format(spv::ImageFormat format)
bool Compiler::is_desktop_only_format(ImageFormat format)
{
switch (format)
{
@ -5155,7 +5201,7 @@ bool Compiler::is_depth_image(const SPIRType &type, uint32_t id) const
bool Compiler::type_is_opaque_value(const SPIRType &type) const
{
return !type.pointer && (type.basetype == SPIRType::SampledImage || type.basetype == SPIRType::Image ||
type.basetype == SPIRType::Sampler);
type.basetype == SPIRType::Sampler || type.basetype == SPIRType::Tensor);
}
// Make these member functions so we can easily break on any force_recompile events.
@ -5182,7 +5228,7 @@ void Compiler::clear_force_recompile()
}
Compiler::PhysicalStorageBufferPointerHandler::PhysicalStorageBufferPointerHandler(Compiler &compiler_)
: compiler(compiler_)
: OpcodeHandler(compiler_)
{
}
@ -5231,7 +5277,7 @@ bool Compiler::PhysicalStorageBufferPointerHandler::type_is_bda_block_entry(uint
uint32_t Compiler::PhysicalStorageBufferPointerHandler::get_minimum_scalar_alignment(const SPIRType &type) const
{
if (type.storage == spv::StorageClassPhysicalStorageBuffer)
if (type.storage == StorageClassPhysicalStorageBuffer)
return 8;
else if (type.basetype == SPIRType::Struct)
{
@ -5473,6 +5519,7 @@ bool Compiler::InterlockedResourceAccessHandler::handle(Op opcode, const uint32_
{
case OpLoad:
case OpCooperativeMatrixLoadKHR:
case OpCooperativeVectorLoadNV:
{
if (length < 3)
return false;
@ -5551,6 +5598,7 @@ bool Compiler::InterlockedResourceAccessHandler::handle(Op opcode, const uint32_
case OpImageWrite:
case OpAtomicStore:
case OpCooperativeMatrixStoreKHR:
case OpCooperativeVectorStoreNV:
{
if (length < 1)
return false;
@ -5747,3 +5795,13 @@ void Compiler::add_loop_level()
{
current_loop_level++;
}
const SPIRType *Compiler::OpcodeHandler::get_expression_result_type(uint32_t id) const
{
auto itr = result_types.find(id);
if (itr == result_types.end())
return nullptr;
return &compiler.get<SPIRType>(itr->second);
}

View file

@ -27,12 +27,20 @@
#ifndef SPV_ENABLE_UTILITY_CODE
#define SPV_ENABLE_UTILITY_CODE
#endif
// Pragmatic hack to avoid symbol conflicts when including both hpp11 and hpp headers in same translation unit.
// This is an unfortunate SPIRV-Headers issue that we cannot easily deal with ourselves.
#ifdef SPIRV_CROSS_SPV_HEADER_NAMESPACE_OVERRIDE
#define spv SPIRV_CROSS_SPV_HEADER_NAMESPACE_OVERRIDE
#endif
#include "spirv.hpp"
#include "spirv_cfg.hpp"
#include "spirv_cross_parsed_ir.hpp"
namespace SPIRV_CROSS_NAMESPACE
{
using namespace SPIRV_CROSS_SPV_HEADER_NAMESPACE;
struct Resource
{
// Resources are identified with their SPIR-V ID.
@ -69,7 +77,7 @@ struct BuiltInResource
// A builtin present here does not necessarily mean it's considered an active builtin,
// since variable ID "activeness" is only tracked on OpVariable level, not Block members.
// For that, update_active_builtins() -> has_active_builtin() can be used to further refine the reflection.
spv::BuiltIn builtin;
BuiltIn builtin;
// This is the actual value type of the builtin.
// Typically float4, float, array<float, N> for the gl_PerVertex builtins.
@ -95,6 +103,7 @@ struct ShaderResources
SmallVector<Resource> atomic_counters;
SmallVector<Resource> acceleration_structures;
SmallVector<Resource> gl_plain_uniforms;
SmallVector<Resource> tensors;
// There can only be one push constant block,
// but keep the vector in case this restriction is lifted in the future.
@ -151,7 +160,7 @@ enum BufferPackingStandard
struct EntryPoint
{
std::string name;
spv::ExecutionModel execution_model;
ExecutionModel execution_model;
};
class Compiler
@ -182,8 +191,8 @@ public:
const std::string &get_name(ID id) const;
// Applies a decoration to an ID. Effectively injects OpDecorate.
void set_decoration(ID id, spv::Decoration decoration, uint32_t argument = 0);
void set_decoration_string(ID id, spv::Decoration decoration, const std::string &argument);
void set_decoration(ID id, Decoration decoration, uint32_t argument = 0);
void set_decoration_string(ID id, Decoration decoration, const std::string &argument);
// Overrides the identifier OpName of an ID.
// Identifiers beginning with underscores or identifiers which contain double underscores
@ -191,22 +200,22 @@ public:
void set_name(ID id, const std::string &name);
// Gets a bitmask for the decorations which are applied to ID.
// I.e. (1ull << spv::DecorationFoo) | (1ull << spv::DecorationBar)
// I.e. (1ull << DecorationFoo) | (1ull << DecorationBar)
const Bitset &get_decoration_bitset(ID id) const;
// Returns whether the decoration has been applied to the ID.
bool has_decoration(ID id, spv::Decoration decoration) const;
bool has_decoration(ID id, Decoration decoration) const;
// Gets the value for decorations which take arguments.
// If the decoration is a boolean (i.e. spv::DecorationNonWritable),
// If the decoration is a boolean (i.e. DecorationNonWritable),
// 1 will be returned.
// If decoration doesn't exist or decoration is not recognized,
// 0 will be returned.
uint32_t get_decoration(ID id, spv::Decoration decoration) const;
const std::string &get_decoration_string(ID id, spv::Decoration decoration) const;
uint32_t get_decoration(ID id, Decoration decoration) const;
const std::string &get_decoration_string(ID id, Decoration decoration) const;
// Removes the decoration for an ID.
void unset_decoration(ID id, spv::Decoration decoration);
void unset_decoration(ID id, Decoration decoration);
// Gets the SPIR-V type associated with ID.
// Mostly used with Resource::type_id and Resource::base_type_id to parse the underlying type of a resource.
@ -216,7 +225,7 @@ public:
const SPIRType &get_type_from_variable(VariableID id) const;
// Gets the underlying storage class for an OpVariable.
spv::StorageClass get_storage_class(VariableID id) const;
StorageClass get_storage_class(VariableID id) const;
// If get_name() is an empty string, get the fallback name which will be used
// instead in the disassembled source.
@ -231,8 +240,8 @@ public:
const std::string &get_member_name(TypeID id, uint32_t index) const;
// Given an OpTypeStruct in ID, obtain the OpMemberDecoration for member number "index".
uint32_t get_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration) const;
const std::string &get_member_decoration_string(TypeID id, uint32_t index, spv::Decoration decoration) const;
uint32_t get_member_decoration(TypeID id, uint32_t index, Decoration decoration) const;
const std::string &get_member_decoration_string(TypeID id, uint32_t index, Decoration decoration) const;
// Sets the member identifier for OpTypeStruct ID, member number "index".
void set_member_name(TypeID id, uint32_t index, const std::string &name);
@ -245,15 +254,15 @@ public:
const Bitset &get_member_decoration_bitset(TypeID id, uint32_t index) const;
// Returns whether the decoration has been applied to a member of a struct.
bool has_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration) const;
bool has_member_decoration(TypeID id, uint32_t index, Decoration decoration) const;
// Similar to set_decoration, but for struct members.
void set_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration, uint32_t argument = 0);
void set_member_decoration_string(TypeID id, uint32_t index, spv::Decoration decoration,
void set_member_decoration(TypeID id, uint32_t index, Decoration decoration, uint32_t argument = 0);
void set_member_decoration_string(TypeID id, uint32_t index, Decoration decoration,
const std::string &argument);
// Unsets a member decoration, similar to unset_decoration.
void unset_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration);
void unset_member_decoration(TypeID id, uint32_t index, Decoration decoration);
// Gets the fallback name for a member, similar to get_fallback_name.
virtual const std::string get_fallback_member_name(uint32_t index) const
@ -339,28 +348,28 @@ public:
// Names for entry points in the SPIR-V module may alias if they belong to different execution models.
// To disambiguate, we must pass along with the entry point names the execution model.
SmallVector<EntryPoint> get_entry_points_and_stages() const;
void set_entry_point(const std::string &entry, spv::ExecutionModel execution_model);
void set_entry_point(const std::string &entry, ExecutionModel execution_model);
// Renames an entry point from old_name to new_name.
// If old_name is currently selected as the current entry point, it will continue to be the current entry point,
// albeit with a new name.
// get_entry_points() is essentially invalidated at this point.
void rename_entry_point(const std::string &old_name, const std::string &new_name,
spv::ExecutionModel execution_model);
const SPIREntryPoint &get_entry_point(const std::string &name, spv::ExecutionModel execution_model) const;
SPIREntryPoint &get_entry_point(const std::string &name, spv::ExecutionModel execution_model);
ExecutionModel execution_model);
const SPIREntryPoint &get_entry_point(const std::string &name, ExecutionModel execution_model) const;
SPIREntryPoint &get_entry_point(const std::string &name, ExecutionModel execution_model);
const std::string &get_cleansed_entry_point_name(const std::string &name,
spv::ExecutionModel execution_model) const;
ExecutionModel execution_model) const;
// Traverses all reachable opcodes and sets active_builtins to a bitmask of all builtin variables which are accessed in the shader.
void update_active_builtins();
bool has_active_builtin(spv::BuiltIn builtin, spv::StorageClass storage) const;
bool has_active_builtin(BuiltIn builtin, StorageClass storage) const;
// Query and modify OpExecutionMode.
const Bitset &get_execution_mode_bitset() const;
void unset_execution_mode(spv::ExecutionMode mode);
void set_execution_mode(spv::ExecutionMode mode, uint32_t arg0 = 0, uint32_t arg1 = 0, uint32_t arg2 = 0);
void unset_execution_mode(ExecutionMode mode);
void set_execution_mode(ExecutionMode mode, uint32_t arg0 = 0, uint32_t arg1 = 0, uint32_t arg2 = 0);
// Gets argument for an execution mode (LocalSize, Invocations, OutputVertices).
// For LocalSize or LocalSizeId, the index argument is used to select the dimension (X = 0, Y = 1, Z = 2).
@ -368,8 +377,8 @@ public:
// LocalSizeId query returns an ID. If LocalSizeId execution mode is not used, it returns 0.
// LocalSize always returns a literal. If execution mode is LocalSizeId,
// the literal (spec constant or not) is still returned.
uint32_t get_execution_mode_argument(spv::ExecutionMode mode, uint32_t index = 0) const;
spv::ExecutionModel get_execution_model() const;
uint32_t get_execution_mode_argument(ExecutionMode mode, uint32_t index = 0) const;
ExecutionModel get_execution_model() const;
bool is_tessellation_shader() const;
bool is_tessellating_triangles() const;
@ -482,7 +491,7 @@ public:
// If the decoration was declared, sets the word_offset to an offset into the provided SPIR-V binary buffer and returns true,
// otherwise, returns false.
// If the decoration does not have any value attached to it (e.g. DecorationRelaxedPrecision), this function will also return false.
bool get_binary_offset_for_decoration(VariableID id, spv::Decoration decoration, uint32_t &word_offset) const;
bool get_binary_offset_for_decoration(VariableID id, Decoration decoration, uint32_t &word_offset) const;
// HLSL counter buffer reflection interface.
// Append/Consume/Increment/Decrement in HLSL is implemented as two "neighbor" buffer objects where
@ -508,7 +517,7 @@ public:
bool buffer_get_hlsl_counter_buffer(VariableID id, uint32_t &counter_id) const;
// Gets the list of all SPIR-V Capabilities which were declared in the SPIR-V module.
const SmallVector<spv::Capability> &get_declared_capabilities() const;
const SmallVector<Capability> &get_declared_capabilities() const;
// Gets the list of all SPIR-V extensions which were declared in the SPIR-V module.
const SmallVector<std::string> &get_declared_extensions() const;
@ -671,20 +680,21 @@ protected:
const SPIREntryPoint &get_entry_point() const;
SPIREntryPoint &get_entry_point();
static bool is_tessellation_shader(spv::ExecutionModel model);
static bool is_tessellation_shader(ExecutionModel model);
virtual std::string to_name(uint32_t id, bool allow_alias = true) const;
bool is_builtin_variable(const SPIRVariable &var) const;
bool is_builtin_type(const SPIRType &type) const;
bool is_hidden_variable(const SPIRVariable &var, bool include_builtins = false) const;
bool is_immutable(uint32_t id) const;
bool is_member_builtin(const SPIRType &type, uint32_t index, spv::BuiltIn *builtin) const;
bool is_member_builtin(const SPIRType &type, uint32_t index, BuiltIn *builtin) const;
bool is_scalar(const SPIRType &type) const;
bool is_vector(const SPIRType &type) const;
bool is_matrix(const SPIRType &type) const;
bool is_array(const SPIRType &type) const;
bool is_pointer(const SPIRType &type) const;
bool is_physical_pointer(const SPIRType &type) const;
bool is_physical_or_buffer_pointer(const SPIRType &type) const;
bool is_physical_pointer_to_buffer_block(const SPIRType &type) const;
static bool is_runtime_size_array(const SPIRType &type);
uint32_t expression_type_id(uint32_t id) const;
@ -787,11 +797,12 @@ protected:
// Used internally to implement various traversals for queries.
struct OpcodeHandler
{
explicit OpcodeHandler(Compiler &compiler_) : compiler(compiler_) {}
virtual ~OpcodeHandler() = default;
// Return true if traversal should continue.
// If false, traversal will end immediately.
virtual bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) = 0;
virtual bool handle(Op opcode, const uint32_t *args, uint32_t length) = 0;
virtual bool handle_terminator(const SPIRBlock &)
{
return true;
@ -822,20 +833,40 @@ protected:
{
return true;
}
Compiler &compiler;
std::unordered_map<uint32_t, uint32_t> result_types;
const SPIRType *get_expression_result_type(uint32_t id) const;
bool enable_result_types = false;
template <typename T> T &get(uint32_t id)
{
return compiler.get<T>(id);
}
template <typename T> const T &get(uint32_t id) const
{
return compiler.get<T>(id);
}
template <typename T, typename... P>
T &set(uint32_t id, P &&... args)
{
return compiler.set<T>(id, std::forward<P>(args)...);
}
};
struct BufferAccessHandler : OpcodeHandler
{
BufferAccessHandler(const Compiler &compiler_, SmallVector<BufferRange> &ranges_, uint32_t id_)
: compiler(compiler_)
: OpcodeHandler(const_cast<Compiler &>(compiler_))
, ranges(ranges_)
, id(id_)
{
}
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
bool handle(Op opcode, const uint32_t *args, uint32_t length) override;
const Compiler &compiler;
SmallVector<BufferRange> &ranges;
uint32_t id;
@ -845,29 +876,26 @@ protected:
struct InterfaceVariableAccessHandler : OpcodeHandler
{
InterfaceVariableAccessHandler(const Compiler &compiler_, std::unordered_set<VariableID> &variables_)
: compiler(compiler_)
: OpcodeHandler(const_cast<Compiler &>(compiler_))
, variables(variables_)
{
}
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
bool handle(Op opcode, const uint32_t *args, uint32_t length) override;
const Compiler &compiler;
std::unordered_set<VariableID> &variables;
};
struct CombinedImageSamplerHandler : OpcodeHandler
{
CombinedImageSamplerHandler(Compiler &compiler_)
: compiler(compiler_)
explicit CombinedImageSamplerHandler(Compiler &compiler_)
: OpcodeHandler(compiler_)
{
}
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
bool handle(Op opcode, const uint32_t *args, uint32_t length) override;
bool begin_function_scope(const uint32_t *args, uint32_t length) override;
bool end_function_scope(const uint32_t *args, uint32_t length) override;
Compiler &compiler;
// Each function in the call stack needs its own remapping for parameters so we can deduce which global variable each texture/sampler the parameter is statically bound to.
std::stack<std::unordered_map<uint32_t, uint32_t>> parameter_remapping;
std::stack<SPIRFunction *> functions;
@ -881,27 +909,24 @@ protected:
struct DummySamplerForCombinedImageHandler : OpcodeHandler
{
DummySamplerForCombinedImageHandler(Compiler &compiler_)
: compiler(compiler_)
explicit DummySamplerForCombinedImageHandler(Compiler &compiler_)
: OpcodeHandler(compiler_)
{
}
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
Compiler &compiler;
bool handle(Op opcode, const uint32_t *args, uint32_t length) override;
bool need_dummy_sampler = false;
};
struct ActiveBuiltinHandler : OpcodeHandler
{
ActiveBuiltinHandler(Compiler &compiler_)
: compiler(compiler_)
explicit ActiveBuiltinHandler(Compiler &compiler_)
: OpcodeHandler(compiler_)
{
}
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
Compiler &compiler;
bool handle(Op opcode, const uint32_t *args, uint32_t length) override;
void handle_builtin(const SPIRType &type, spv::BuiltIn builtin, const Bitset &decoration_flags);
void handle_builtin(const SPIRType &type, BuiltIn builtin, const Bitset &decoration_flags);
void add_if_builtin(uint32_t id);
void add_if_builtin_or_block(uint32_t id);
void add_if_builtin(uint32_t id, bool allow_blocks);
@ -953,13 +978,12 @@ protected:
struct CombinedImageSamplerDrefHandler : OpcodeHandler
{
CombinedImageSamplerDrefHandler(Compiler &compiler_)
: compiler(compiler_)
explicit CombinedImageSamplerDrefHandler(Compiler &compiler_)
: OpcodeHandler(compiler_)
{
}
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
bool handle(Op opcode, const uint32_t *args, uint32_t length) override;
Compiler &compiler;
std::unordered_set<uint32_t> dref_combined_samplers;
};
@ -967,14 +991,13 @@ protected:
{
CombinedImageSamplerUsageHandler(Compiler &compiler_,
const std::unordered_set<uint32_t> &dref_combined_samplers_)
: compiler(compiler_)
: OpcodeHandler(compiler_)
, dref_combined_samplers(dref_combined_samplers_)
{
}
bool begin_function_scope(const uint32_t *args, uint32_t length) override;
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
Compiler &compiler;
bool handle(Op opcode, const uint32_t *args, uint32_t length) override;
const std::unordered_set<uint32_t> &dref_combined_samplers;
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> dependency_hierarchy;
@ -996,8 +1019,7 @@ protected:
explicit CFGBuilder(Compiler &compiler_);
bool follow_function_call(const SPIRFunction &func) override;
bool handle(spv::Op op, const uint32_t *args, uint32_t length) override;
Compiler &compiler;
bool handle(Op op, const uint32_t *args, uint32_t length) override;
std::unordered_map<uint32_t, std::unique_ptr<CFG>> function_cfgs;
};
@ -1011,10 +1033,9 @@ protected:
void notify_variable_access(uint32_t id, uint32_t block);
bool id_is_phi_variable(uint32_t id) const;
bool id_is_potential_temporary(uint32_t id) const;
bool handle(spv::Op op, const uint32_t *args, uint32_t length) override;
bool handle(Op op, const uint32_t *args, uint32_t length) override;
bool handle_terminator(const SPIRBlock &block) override;
Compiler &compiler;
SPIRFunction &entry;
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> accessed_variables_to_block;
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> accessed_temporaries_to_block;
@ -1032,9 +1053,8 @@ protected:
{
StaticExpressionAccessHandler(Compiler &compiler_, uint32_t variable_id_);
bool follow_function_call(const SPIRFunction &) override;
bool handle(spv::Op op, const uint32_t *args, uint32_t length) override;
bool handle(Op op, const uint32_t *args, uint32_t length) override;
Compiler &compiler;
uint32_t variable_id;
uint32_t static_expression = 0;
uint32_t write_count = 0;
@ -1048,8 +1068,7 @@ protected:
struct PhysicalStorageBufferPointerHandler : OpcodeHandler
{
explicit PhysicalStorageBufferPointerHandler(Compiler &compiler_);
bool handle(spv::Op op, const uint32_t *args, uint32_t length) override;
Compiler &compiler;
bool handle(Op op, const uint32_t *args, uint32_t length) override;
std::unordered_set<uint32_t> non_block_types;
std::unordered_map<uint32_t, PhysicalBlockMeta> physical_block_type_meta;
@ -1076,12 +1095,11 @@ protected:
struct GeometryEmitDisocveryHandler : OpcodeHandler
{
explicit GeometryEmitDisocveryHandler(Compiler &compiler_)
: compiler(compiler_)
: OpcodeHandler(compiler_)
{
}
Compiler &compiler;
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
bool handle(Op opcode, const uint32_t *args, uint32_t length) override;
bool begin_function_scope(const uint32_t *, uint32_t) override;
bool end_function_scope(const uint32_t *, uint32_t) override;
SmallVector<SPIRFunction *> function_stack;
@ -1096,16 +1114,15 @@ protected:
struct InterlockedResourceAccessHandler : OpcodeHandler
{
InterlockedResourceAccessHandler(Compiler &compiler_, uint32_t entry_point_id)
: compiler(compiler_)
: OpcodeHandler(compiler_)
{
call_stack.push_back(entry_point_id);
}
bool handle(spv::Op op, const uint32_t *args, uint32_t length) override;
bool handle(Op op, const uint32_t *args, uint32_t length) override;
bool begin_function_scope(const uint32_t *args, uint32_t length) override;
bool end_function_scope(const uint32_t *args, uint32_t length) override;
Compiler &compiler;
bool in_crit_sec = false;
uint32_t interlock_function_id = 0;
@ -1121,17 +1138,16 @@ protected:
struct InterlockedResourceAccessPrepassHandler : OpcodeHandler
{
InterlockedResourceAccessPrepassHandler(Compiler &compiler_, uint32_t entry_point_id)
: compiler(compiler_)
: OpcodeHandler(compiler_)
{
call_stack.push_back(entry_point_id);
}
void rearm_current_block(const SPIRBlock &block) override;
bool handle(spv::Op op, const uint32_t *args, uint32_t length) override;
bool handle(Op op, const uint32_t *args, uint32_t length) override;
bool begin_function_scope(const uint32_t *args, uint32_t length) override;
bool end_function_scope(const uint32_t *args, uint32_t length) override;
Compiler &compiler;
uint32_t interlock_function_id = 0;
uint32_t current_block_id = 0;
bool split_function_case = false;
@ -1148,11 +1164,11 @@ protected:
std::unordered_map<uint32_t, std::string> declared_block_names;
bool instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, spv::Op op, const uint32_t *args,
uint32_t length);
static bool instruction_to_result_type(
uint32_t &result_type, uint32_t &result_id, Op op, const uint32_t *args, uint32_t length);
Bitset combined_decoration_for_member(const SPIRType &type, uint32_t index) const;
static bool is_desktop_only_format(spv::ImageFormat format);
static bool is_desktop_only_format(ImageFormat format);
bool is_depth_image(const SPIRType &type, uint32_t id) const;
@ -1171,6 +1187,7 @@ protected:
bool type_contains_recursion(const SPIRType &type);
bool type_is_array_of_pointers(const SPIRType &type) const;
bool type_is_block_like(const SPIRType &type) const;
bool type_is_explicit_layout(const SPIRType &type) const;
bool type_is_top_level_block(const SPIRType &type) const;
bool type_is_opaque_value(const SPIRType &type) const;
@ -1196,4 +1213,8 @@ private:
};
} // namespace SPIRV_CROSS_NAMESPACE
#ifdef SPIRV_CROSS_SPV_HEADER_NAMESPACE_OVERRIDE
#undef spv
#endif
#endif

View file

@ -26,7 +26,7 @@
#include <assert.h>
using namespace std;
using namespace spv;
using namespace SPIRV_CROSS_SPV_HEADER_NAMESPACE;
namespace SPIRV_CROSS_NAMESPACE
{
@ -527,8 +527,27 @@ void ParsedIR::mark_used_as_array_length(ID id)
switch (ids[id].get_type())
{
case TypeConstant:
get<SPIRConstant>(id).is_used_as_array_length = true;
{
auto &c = get<SPIRConstant>(id);
c.is_used_as_array_length = true;
// Mark composite dependencies as well.
for (auto &sub_id: c.m.id)
if (sub_id)
mark_used_as_array_length(sub_id);
for (uint32_t col = 0; col < c.m.columns; col++)
{
for (auto &sub_id : c.m.c[col].id)
if (sub_id)
mark_used_as_array_length(sub_id);
}
for (auto &sub_id : c.subconstants)
if (sub_id)
mark_used_as_array_length(sub_id);
break;
}
case TypeConstantOp:
{

View file

@ -30,6 +30,7 @@
namespace SPIRV_CROSS_NAMESPACE
{
using namespace SPIRV_CROSS_SPV_HEADER_NAMESPACE;
// This data structure holds all information needed to perform cross-compilation and reflection.
// It is the output of the Parser, but any implementation could create this structure.
@ -87,7 +88,7 @@ public:
// Declared capabilities and extensions in the SPIR-V module.
// Not really used except for reflection at the moment.
SmallVector<spv::Capability> declared_capabilities;
SmallVector<Capability> declared_capabilities;
SmallVector<std::string> declared_extensions;
// Meta data about blocks. The cross-compiler needs to query if a block is either of these types.
@ -111,6 +112,7 @@ public:
struct Source
{
SourceLanguage lang = SourceLanguageUnknown;
uint32_t version = 0;
bool es = false;
bool known = false;
@ -121,8 +123,8 @@ public:
Source source;
spv::AddressingModel addressing_model = spv::AddressingModelMax;
spv::MemoryModel memory_model = spv::MemoryModelMax;
AddressingModel addressing_model = AddressingModelMax;
MemoryModel memory_model = MemoryModelMax;
// Decoration handling methods.
// Can be useful for simple "raw" reflection.
@ -130,25 +132,25 @@ public:
// and might as well just have the whole suite of decoration/name handling in one place.
void set_name(ID id, const std::string &name);
const std::string &get_name(ID id) const;
void set_decoration(ID id, spv::Decoration decoration, uint32_t argument = 0);
void set_decoration_string(ID id, spv::Decoration decoration, const std::string &argument);
bool has_decoration(ID id, spv::Decoration decoration) const;
uint32_t get_decoration(ID id, spv::Decoration decoration) const;
const std::string &get_decoration_string(ID id, spv::Decoration decoration) const;
void set_decoration(ID id, Decoration decoration, uint32_t argument = 0);
void set_decoration_string(ID id, Decoration decoration, const std::string &argument);
bool has_decoration(ID id, Decoration decoration) const;
uint32_t get_decoration(ID id, Decoration decoration) const;
const std::string &get_decoration_string(ID id, Decoration decoration) const;
const Bitset &get_decoration_bitset(ID id) const;
void unset_decoration(ID id, spv::Decoration decoration);
void unset_decoration(ID id, Decoration decoration);
// Decoration handling methods (for members of a struct).
void set_member_name(TypeID id, uint32_t index, const std::string &name);
const std::string &get_member_name(TypeID id, uint32_t index) const;
void set_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration, uint32_t argument = 0);
void set_member_decoration_string(TypeID id, uint32_t index, spv::Decoration decoration,
void set_member_decoration(TypeID id, uint32_t index, Decoration decoration, uint32_t argument = 0);
void set_member_decoration_string(TypeID id, uint32_t index, Decoration decoration,
const std::string &argument);
uint32_t get_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration) const;
const std::string &get_member_decoration_string(TypeID id, uint32_t index, spv::Decoration decoration) const;
bool has_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration) const;
uint32_t get_member_decoration(TypeID id, uint32_t index, Decoration decoration) const;
const std::string &get_member_decoration_string(TypeID id, uint32_t index, Decoration decoration) const;
bool has_member_decoration(TypeID id, uint32_t index, Decoration decoration) const;
const Bitset &get_member_decoration_bitset(TypeID id, uint32_t index) const;
void unset_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration);
void unset_member_decoration(TypeID id, uint32_t index, Decoration decoration);
void mark_used_as_array_length(ID id);
uint32_t increase_bound_by(uint32_t count);

View file

@ -0,0 +1,77 @@
/*
* Copyright 2015-2021 Arm Limited
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* At your option, you may choose to accept this material under either:
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
*/
#include "spirv_cross_util.hpp"
#include "spirv_common.hpp"
using namespace SPIRV_CROSS_SPV_HEADER_NAMESPACE;
using namespace SPIRV_CROSS_NAMESPACE;
namespace spirv_cross_util
{
void rename_interface_variable(Compiler &compiler, const SmallVector<Resource> &resources, uint32_t location,
const std::string &name)
{
for (auto &v : resources)
{
if (!compiler.has_decoration(v.id, DecorationLocation))
continue;
auto loc = compiler.get_decoration(v.id, DecorationLocation);
if (loc != location)
continue;
auto &type = compiler.get_type(v.base_type_id);
// This is more of a friendly variant. If we need to rename interface variables, we might have to rename
// structs as well and make sure all the names match up.
if (type.basetype == SPIRType::Struct)
{
compiler.set_name(v.base_type_id, join("SPIRV_Cross_Interface_Location", location));
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
compiler.set_member_name(v.base_type_id, i, join("InterfaceMember", i));
}
compiler.set_name(v.id, name);
}
}
void inherit_combined_sampler_bindings(Compiler &compiler)
{
auto &samplers = compiler.get_combined_image_samplers();
for (auto &s : samplers)
{
if (compiler.has_decoration(s.image_id, DecorationDescriptorSet))
{
uint32_t set = compiler.get_decoration(s.image_id, DecorationDescriptorSet);
compiler.set_decoration(s.combined_id, DecorationDescriptorSet, set);
}
if (compiler.has_decoration(s.image_id, DecorationBinding))
{
uint32_t binding = compiler.get_decoration(s.image_id, DecorationBinding);
compiler.set_decoration(s.combined_id, DecorationBinding, binding);
}
}
}
} // namespace spirv_cross_util

View file

@ -0,0 +1,37 @@
/*
* Copyright 2015-2021 Arm Limited
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* At your option, you may choose to accept this material under either:
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
*/
#ifndef SPIRV_CROSS_UTIL_HPP
#define SPIRV_CROSS_UTIL_HPP
#include "spirv_cross.hpp"
namespace spirv_cross_util
{
void rename_interface_variable(SPIRV_CROSS_NAMESPACE::Compiler &compiler,
const SPIRV_CROSS_NAMESPACE::SmallVector<SPIRV_CROSS_NAMESPACE::Resource> &resources,
uint32_t location, const std::string &name);
void inherit_combined_sampler_bindings(SPIRV_CROSS_NAMESPACE::Compiler &compiler);
} // namespace spirv_cross_util
#endif

File diff suppressed because it is too large Load diff

View file

@ -32,6 +32,9 @@
namespace SPIRV_CROSS_NAMESPACE
{
using namespace SPIRV_CROSS_SPV_HEADER_NAMESPACE;
struct GlslConstantNameMapping;
enum PlsFormat
{
PlsNone = 0,
@ -287,7 +290,7 @@ public:
// This option is only meaningful for MSL and HLSL, since GLSL matches by location directly.
// Masking builtins only takes effect if the builtin in question is part of the stage output interface.
void mask_stage_output_by_location(uint32_t location, uint32_t component);
void mask_stage_output_by_builtin(spv::BuiltIn builtin);
void mask_stage_output_by_builtin(BuiltIn builtin);
// Allow to control how to format float literals in the output.
// Set to "nullptr" to use the default "convert_to_string" function.
@ -387,7 +390,7 @@ protected:
};
// TODO remove this function when all subgroup ops are supported (or make it always return true)
static bool is_supported_subgroup_op_in_opengl(spv::Op op, const uint32_t *ops);
static bool is_supported_subgroup_op_in_opengl(Op op, const uint32_t *ops);
void reset(uint32_t iteration_count);
void emit_function(SPIRFunction &func, const Bitset &return_flags);
@ -414,7 +417,7 @@ protected:
// For relax_nan_checks.
GLSLstd450 get_remapped_glsl_op(GLSLstd450 std450_op) const;
spv::Op get_remapped_spirv_op(spv::Op op) const;
Op get_remapped_spirv_op(Op op) const;
virtual void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
uint32_t count);
@ -426,6 +429,8 @@ protected:
const uint32_t *args, uint32_t count);
virtual void emit_spv_amd_gcn_shader_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
uint32_t count);
void emit_non_semantic_shader_debug_info(uint32_t result_type, uint32_t result_id, uint32_t op,
const uint32_t *args, uint32_t count);
virtual void emit_header();
void emit_line_directive(uint32_t file_id, uint32_t line_literal);
void build_workgroup_size(SmallVector<std::string> &arguments, const SpecializationConstant &x,
@ -439,7 +444,7 @@ protected:
SmallVector<uint32_t> &inherited_expressions);
virtual void emit_subgroup_op(const Instruction &i);
virtual std::string type_to_glsl(const SPIRType &type, uint32_t id = 0);
virtual std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage);
virtual std::string builtin_to_glsl(BuiltIn builtin, StorageClass storage);
virtual void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
const std::string &qualifier = "", uint32_t base_offset = 0);
virtual void emit_struct_padding_target(const SPIRType &type);
@ -451,7 +456,7 @@ protected:
virtual std::string constant_expression_vector(const SPIRConstant &c, uint32_t vector);
virtual void emit_fixup();
virtual std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id = 0);
virtual bool variable_decl_is_remapped_storage(const SPIRVariable &var, spv::StorageClass storage) const;
virtual bool variable_decl_is_remapped_storage(const SPIRVariable &var, StorageClass storage) const;
virtual std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id);
virtual void emit_workgroup_initialization(const SPIRVariable &var);
@ -496,7 +501,7 @@ protected:
virtual std::string unpack_expression_type(std::string expr_str, const SPIRType &type, uint32_t physical_type_id,
bool packed_type, bool row_major);
virtual bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const;
virtual bool builtin_translates_to_nonarray(BuiltIn builtin) const;
virtual bool is_user_type_structured(uint32_t id) const;
@ -662,20 +667,21 @@ protected:
bool workgroup_size_is_hidden = false;
bool requires_relaxed_precision_analysis = false;
bool implicit_c_integer_promotion_rules = false;
bool supports_spec_constant_array_size = true;
} backend;
void emit_struct(SPIRType &type);
void emit_resources();
void emit_extension_workarounds(spv::ExecutionModel model);
void emit_subgroup_arithmetic_workaround(const std::string &func, spv::Op op, spv::GroupOperation group_op);
void emit_extension_workarounds(ExecutionModel model);
void emit_subgroup_arithmetic_workaround(const std::string &func, Op op, GroupOperation group_op);
void emit_polyfills(uint32_t polyfills, bool relaxed);
void emit_buffer_block_native(const SPIRVariable &var);
void emit_buffer_reference_block(uint32_t type_id, bool forward_declaration);
void emit_buffer_block_legacy(const SPIRVariable &var);
void emit_buffer_block_flattened(const SPIRVariable &type);
void fixup_implicit_builtin_block_names(spv::ExecutionModel model);
void emit_declared_builtin_block(spv::StorageClass storage, spv::ExecutionModel model);
bool should_force_emit_builtin_block(spv::StorageClass storage);
void fixup_implicit_builtin_block_names(ExecutionModel model);
void emit_declared_builtin_block(StorageClass storage, ExecutionModel model);
bool should_force_emit_builtin_block(StorageClass storage);
void emit_push_constant_block_vulkan(const SPIRVariable &var);
void emit_push_constant_block_glsl(const SPIRVariable &var);
void emit_interface_block(const SPIRVariable &type);
@ -685,6 +691,8 @@ protected:
void emit_flattened_io_block_member(const std::string &basename, const SPIRType &type, const char *qual,
const SmallVector<uint32_t> &indices);
void emit_block_chain(SPIRBlock &block);
BlockID emit_block_chain_inner(SPIRBlock &block);
void emit_block_chain_cleanup(SPIRBlock &block);
void emit_hoisted_temporaries(SmallVector<std::pair<TypeID, ID>> &temporaries);
int get_constant_mapping_to_workgroup_component(const SPIRConstant &constant) const;
void emit_constant(const SPIRConstant &constant);
@ -755,6 +763,7 @@ protected:
bool expression_read_implies_multiple_reads(uint32_t id) const;
SPIRExpression &emit_op(uint32_t result_type, uint32_t result_id, const std::string &rhs, bool forward_rhs,
bool suppress_usage_tracking = false);
void emit_transposed_op(uint32_t result_type, uint32_t result_id, const std::string &rhs, bool forward_rhs);
void access_chain_internal_append_index(std::string &expr, uint32_t base, const SPIRType *type,
AccessChainFlags flags, bool &access_chain_is_arrayed, uint32_t index);
@ -766,12 +775,12 @@ protected:
// Relevant for PtrAccessChain / BDA.
virtual uint32_t get_physical_type_stride(const SPIRType &type) const;
spv::StorageClass get_expression_effective_storage_class(uint32_t ptr);
StorageClass get_expression_effective_storage_class(uint32_t ptr);
virtual bool access_chain_needs_stage_io_builtin_translation(uint32_t base);
virtual bool check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type);
virtual bool prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type,
spv::StorageClass storage, bool &is_packed);
StorageClass storage, bool &is_packed);
std::string access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type,
AccessChainMeta *meta = nullptr, bool ptr_chain = false);
@ -797,11 +806,16 @@ protected:
const char *index_to_swizzle(uint32_t index);
std::string remap_swizzle(const SPIRType &result_type, uint32_t input_components, const std::string &expr);
std::string declare_temporary(uint32_t type, uint32_t id);
bool can_declare_inline_temporary(uint32_t id) const;
void emit_uninitialized_temporary(uint32_t type, uint32_t id);
SPIRExpression &emit_uninitialized_temporary_expression(uint32_t type, uint32_t id);
virtual void append_global_func_args(const SPIRFunction &func, uint32_t index, SmallVector<std::string> &arglist);
std::string to_non_uniform_aware_expression(uint32_t id);
std::string to_atomic_ptr_expression(uint32_t id);
std::string to_pretty_expression_if_int_constant(
uint32_t id,
const GlslConstantNameMapping *mapping_start, const GlslConstantNameMapping *mapping_end,
bool register_expression_read = true);
std::string to_expression(uint32_t id, bool register_expression_read = true);
std::string to_composite_constructor_expression(const SPIRType &parent_type, uint32_t id, bool block_like_type);
std::string to_rerolled_array_expression(const SPIRType &parent_type, const std::string &expr, const SPIRType &type);
@ -830,15 +844,15 @@ protected:
void emit_output_variable_initializer(const SPIRVariable &var);
std::string to_precision_qualifiers_glsl(uint32_t id);
virtual const char *to_storage_qualifiers_glsl(const SPIRVariable &var);
std::string flags_to_qualifiers_glsl(const SPIRType &type, const Bitset &flags);
const char *format_to_glsl(spv::ImageFormat format);
std::string flags_to_qualifiers_glsl(const SPIRType &type, uint32_t id, const Bitset &flags);
const char *format_to_glsl(ImageFormat format);
virtual std::string layout_for_member(const SPIRType &type, uint32_t index);
virtual std::string to_interpolation_qualifiers(const Bitset &flags);
std::string layout_for_variable(const SPIRVariable &variable);
std::string to_combined_image_sampler(VariableID image_id, VariableID samp_id);
virtual bool skip_argument(uint32_t id) const;
virtual bool emit_array_copy(const char *expr, uint32_t lhs_id, uint32_t rhs_id,
spv::StorageClass lhs_storage, spv::StorageClass rhs_storage);
StorageClass lhs_storage, StorageClass rhs_storage);
virtual void emit_block_hints(const SPIRBlock &block);
virtual std::string to_initializer_expression(const SPIRVariable &var);
virtual std::string to_zero_initialized_expression(uint32_t type_id);
@ -1013,7 +1027,7 @@ protected:
bool type_is_empty(const SPIRType &type);
bool can_use_io_location(spv::StorageClass storage, bool block);
bool can_use_io_location(StorageClass storage, bool block);
const Instruction *get_next_instruction_in_block(const Instruction &instr);
static uint32_t mask_relevant_memory_semantics(uint32_t semantics);
@ -1028,7 +1042,7 @@ protected:
// Builtins in GLSL are always specific signedness, but the SPIR-V can declare them
// as either unsigned or signed.
// Sometimes we will need to automatically perform casts on load and store to make this work.
virtual SPIRType::BaseType get_builtin_basetype(spv::BuiltIn builtin, SPIRType::BaseType default_type);
virtual SPIRType::BaseType get_builtin_basetype(BuiltIn builtin, SPIRType::BaseType default_type);
virtual void cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type);
virtual void cast_from_variable_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type);
void unroll_array_from_complex_load(uint32_t target_id, uint32_t source_id, std::string &expr);
@ -1057,7 +1071,7 @@ protected:
static const char *vector_swizzle(int vecsize, int index);
bool is_stage_output_location_masked(uint32_t location, uint32_t component) const;
bool is_stage_output_builtin_masked(spv::BuiltIn builtin) const;
bool is_stage_output_builtin_masked(BuiltIn builtin) const;
bool is_stage_output_variable_masked(const SPIRVariable &var) const;
bool is_stage_output_block_member_masked(const SPIRVariable &var, uint32_t index, bool strip_array) const;
bool is_per_primitive_variable(const SPIRVariable &var) const;
@ -1070,6 +1084,9 @@ protected:
std::string format_float(float value) const;
std::string format_double(double value) const;
uint32_t get_fp_fast_math_flags_for_op(uint32_t result_type, uint32_t id) const;
bool has_legacy_nocontract(uint32_t result_type, uint32_t id) const;
private:
void init();

File diff suppressed because it is too large Load diff

View file

@ -33,6 +33,7 @@
namespace SPIRV_CROSS_NAMESPACE
{
using namespace SPIRV_CROSS_SPV_HEADER_NAMESPACE;
// Indicates the format of a shader interface variable. Currently limited to specifying
// if the input is an 8-bit unsigned integer, 16-bit unsigned integer, or
@ -78,7 +79,7 @@ struct MSLShaderInterfaceVariable
uint32_t location = 0;
uint32_t component = 0;
MSLShaderVariableFormat format = MSL_SHADER_VARIABLE_FORMAT_OTHER;
spv::BuiltIn builtin = spv::BuiltInMax;
BuiltIn builtin = BuiltInMax;
uint32_t vecsize = 0;
MSLShaderVariableRate rate = MSL_SHADER_VARIABLE_RATE_PER_VERTEX;
};
@ -104,7 +105,7 @@ struct MSLShaderInterfaceVariable
// become a [[buffer(N)]], [[texture(N)]] or [[sampler(N)]] depending on the resource types used.
struct MSLResourceBinding
{
spv::ExecutionModel stage = spv::ExecutionModelMax;
ExecutionModel stage = ExecutionModelMax;
SPIRType::BaseType basetype = SPIRType::Unknown;
uint32_t desc_set = 0;
uint32_t binding = 0;
@ -591,9 +592,9 @@ public:
// rasterization if vertex shader requires rasterization to be disabled.
bool get_is_rasterization_disabled() const
{
return is_rasterization_disabled && (get_entry_point().model == spv::ExecutionModelVertex ||
get_entry_point().model == spv::ExecutionModelTessellationControl ||
get_entry_point().model == spv::ExecutionModelTessellationEvaluation);
return is_rasterization_disabled && (get_entry_point().model == ExecutionModelVertex ||
get_entry_point().model == ExecutionModelTessellationControl ||
get_entry_point().model == ExecutionModelTessellationEvaluation);
}
// Provide feedback to calling API to allow it to pass an auxiliary
@ -706,20 +707,20 @@ public:
// This is typical for tessellation builtin inputs such as tess levels, gl_Position, etc.
// This returns k_unknown_location if the location was explicitly assigned with
// add_msl_shader_input or the builtin is not used, otherwise returns N in [[attribute(N)]].
uint32_t get_automatic_builtin_input_location(spv::BuiltIn builtin) const;
uint32_t get_automatic_builtin_input_location(BuiltIn builtin) const;
// If not using add_msl_shader_output, it's possible
// that certain builtin attributes need to be automatically assigned locations.
// This is typical for tessellation builtin outputs such as tess levels, gl_Position, etc.
// This returns k_unknown_location if the location were explicitly assigned with
// add_msl_shader_output or the builtin were not used, otherwise returns N in [[attribute(N)]].
uint32_t get_automatic_builtin_output_location(spv::BuiltIn builtin) const;
uint32_t get_automatic_builtin_output_location(BuiltIn builtin) const;
// NOTE: Only resources which are remapped using add_msl_resource_binding will be reported here.
// Constexpr samplers are always assumed to be emitted.
// No specific MSLResourceBinding remapping is required for constexpr samplers as long as they are remapped
// by remap_constexpr_sampler(_by_binding).
bool is_msl_resource_binding_used(spv::ExecutionModel model, uint32_t set, uint32_t binding) const;
bool is_msl_resource_binding_used(ExecutionModel model, uint32_t set, uint32_t binding) const;
// This must only be called after a successful call to CompilerMSL::compile().
// For a variable resource ID obtained through reflection API, report the automatically assigned resource index.
@ -777,7 +778,7 @@ public:
// If incl_ops is enabled, the FPFastMathMode of any SPIR-V operations are also included in the bitwise-AND
// to determine the minimal fast-math that applies to all default execution modes and all operations.
// The returned value is also affected by execution modes SignedZeroInfNanPreserve and ContractionOff.
uint32_t get_fp_fast_math_flags(bool incl_ops);
uint32_t get_fp_fast_math_flags(bool incl_ops) const;
protected:
// An enum of SPIR-V functions that are implemented in additional
@ -931,14 +932,14 @@ protected:
std::string type_to_array_glsl(const SPIRType &type, uint32_t variable_id) override;
std::string constant_op_expression(const SPIRConstantOp &cop) override;
bool variable_decl_is_remapped_storage(const SPIRVariable &variable, spv::StorageClass storage) const override;
bool variable_decl_is_remapped_storage(const SPIRVariable &variable, StorageClass storage) const override;
// GCC workaround of lambdas calling protected functions (for older GCC versions)
std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id = 0) override;
std::string image_type_glsl(const SPIRType &type, uint32_t id, bool member) override;
std::string sampler_type(const SPIRType &type, uint32_t id, bool member);
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override;
std::string builtin_to_glsl(BuiltIn builtin, StorageClass storage) override;
std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id) override;
std::string to_name(uint32_t id, bool allow_alias = true) const override;
std::string to_function_name(const TextureFunctionNameArguments &args) override;
@ -950,7 +951,7 @@ protected:
bool is_packed, bool row_major) override;
// Returns true for BuiltInSampleMask because gl_SampleMask[] is an array in SPIR-V, but [[sample_mask]] is a scalar in Metal.
bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override;
bool builtin_translates_to_nonarray(BuiltIn builtin) const override;
std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override;
bool emit_complex_bitcast(uint32_t result_id, uint32_t id, uint32_t op0) override;
@ -990,8 +991,8 @@ protected:
void extract_global_variables_from_function(uint32_t func_id, std::set<uint32_t> &added_arg_ids,
std::unordered_set<uint32_t> &global_var_ids,
std::unordered_set<uint32_t> &processed_func_ids);
uint32_t add_interface_block(spv::StorageClass storage, bool patch = false);
uint32_t add_interface_block_pointer(uint32_t ib_var_id, spv::StorageClass storage);
uint32_t add_interface_block(StorageClass storage, bool patch = false);
uint32_t add_interface_block_pointer(uint32_t ib_var_id, StorageClass storage);
uint32_t add_meshlet_block(bool per_primitive);
struct InterfaceBlockMeta
@ -1012,23 +1013,23 @@ protected:
std::string to_tesc_invocation_id();
void emit_local_masked_variable(const SPIRVariable &masked_var, bool strip_array);
void add_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, SPIRType &ib_type,
void add_variable_to_interface_block(StorageClass storage, const std::string &ib_var_ref, SPIRType &ib_type,
SPIRVariable &var, InterfaceBlockMeta &meta);
void add_composite_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref,
void add_composite_variable_to_interface_block(StorageClass storage, const std::string &ib_var_ref,
SPIRType &ib_type, SPIRVariable &var, InterfaceBlockMeta &meta);
void add_plain_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref,
void add_plain_variable_to_interface_block(StorageClass storage, const std::string &ib_var_ref,
SPIRType &ib_type, SPIRVariable &var, InterfaceBlockMeta &meta);
bool add_component_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref,
bool add_component_variable_to_interface_block(StorageClass storage, const std::string &ib_var_ref,
SPIRVariable &var, const SPIRType &type,
InterfaceBlockMeta &meta);
void add_plain_member_variable_to_interface_block(spv::StorageClass storage,
void add_plain_member_variable_to_interface_block(StorageClass storage,
const std::string &ib_var_ref, SPIRType &ib_type,
SPIRVariable &var, SPIRType &var_type,
uint32_t mbr_idx, InterfaceBlockMeta &meta,
const std::string &mbr_name_qual,
const std::string &var_chain_qual,
uint32_t &location, uint32_t &var_mbr_idx);
void add_composite_member_variable_to_interface_block(spv::StorageClass storage,
void add_composite_member_variable_to_interface_block(StorageClass storage,
const std::string &ib_var_ref, SPIRType &ib_type,
SPIRVariable &var, SPIRType &var_type,
uint32_t mbr_idx, InterfaceBlockMeta &meta,
@ -1040,11 +1041,11 @@ protected:
void add_tess_level_input(const std::string &base_ref, const std::string &mbr_name, SPIRVariable &var);
void ensure_struct_members_valid_vecsizes(SPIRType &struct_type, uint32_t &location);
void fix_up_interface_member_indices(spv::StorageClass storage, uint32_t ib_type_id);
void fix_up_interface_member_indices(StorageClass storage, uint32_t ib_type_id);
void mark_location_as_used_by_shader(uint32_t location, const SPIRType &type,
spv::StorageClass storage, bool fallback = false);
uint32_t ensure_correct_builtin_type(uint32_t type_id, spv::BuiltIn builtin);
StorageClass storage, bool fallback = false);
uint32_t ensure_correct_builtin_type(uint32_t type_id, BuiltIn builtin);
uint32_t ensure_correct_input_type(uint32_t type_id, uint32_t location, uint32_t component,
uint32_t num_components, bool strip_array);
@ -1059,6 +1060,9 @@ protected:
void fix_up_shader_inputs_outputs();
bool entry_point_is_vertex() const;
bool entry_point_returns_stage_output() const;
bool entry_point_requires_const_device_buffers() const;
std::string func_type_decl(SPIRType &type);
std::string entry_point_args_classic(bool append_comma);
std::string entry_point_args_argument_buffer(bool append_comma);
@ -1072,23 +1076,23 @@ protected:
std::string to_buffer_size_expression(uint32_t id);
bool is_sample_rate() const;
bool is_intersection_query() const;
bool is_direct_input_builtin(spv::BuiltIn builtin);
std::string builtin_qualifier(spv::BuiltIn builtin);
std::string builtin_type_decl(spv::BuiltIn builtin, uint32_t id = 0);
std::string built_in_func_arg(spv::BuiltIn builtin, bool prefix_comma);
bool is_direct_input_builtin(BuiltIn builtin);
std::string builtin_qualifier(BuiltIn builtin);
std::string builtin_type_decl(BuiltIn builtin, uint32_t id = 0);
std::string built_in_func_arg(BuiltIn builtin, bool prefix_comma);
std::string member_attribute_qualifier(const SPIRType &type, uint32_t index);
std::string member_location_attribute_qualifier(const SPIRType &type, uint32_t index);
std::string argument_decl(const SPIRFunction::Parameter &arg);
const char *descriptor_address_space(uint32_t id, spv::StorageClass storage, const char *plain_address_space) const;
const char *descriptor_address_space(uint32_t id, StorageClass storage, const char *plain_address_space) const;
std::string round_fp_tex_coords(std::string tex_coords, bool coord_is_fp);
uint32_t get_metal_resource_index(SPIRVariable &var, SPIRType::BaseType basetype, uint32_t plane = 0);
uint32_t get_member_location(uint32_t type_id, uint32_t index, uint32_t *comp = nullptr) const;
uint32_t get_or_allocate_builtin_input_member_location(spv::BuiltIn builtin,
uint32_t get_or_allocate_builtin_input_member_location(BuiltIn builtin,
uint32_t type_id, uint32_t index, uint32_t *comp = nullptr);
uint32_t get_or_allocate_builtin_output_member_location(spv::BuiltIn builtin,
uint32_t get_or_allocate_builtin_output_member_location(BuiltIn builtin,
uint32_t type_id, uint32_t index, uint32_t *comp = nullptr);
uint32_t get_physical_tess_level_array_size(spv::BuiltIn builtin) const;
uint32_t get_physical_tess_level_array_size(BuiltIn builtin) const;
uint32_t get_physical_type_stride(const SPIRType &type) const override;
@ -1122,7 +1126,9 @@ protected:
void mark_struct_members_packed(const SPIRType &type);
void ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t index);
bool validate_member_packing_rules_msl(const SPIRType &type, uint32_t index) const;
std::string get_argument_address_space(const SPIRVariable &argument);
std::string get_variable_address_space(const SPIRVariable &argument);
// Special case of get_variable_address_space which is only used for leaf functions.
std::string get_leaf_argument_address_space(const SPIRVariable &argument);
std::string get_type_address_space(const SPIRType &type, uint32_t id, bool argument = false);
bool decoration_flags_signal_volatile(const Bitset &flags) const;
bool decoration_flags_signal_coherent(const Bitset &flags) const;
@ -1134,7 +1140,7 @@ protected:
std::string get_tess_factor_struct_name();
SPIRType &get_uint_type();
uint32_t get_uint_type_id();
void emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, spv::Op opcode,
void emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, Op opcode,
uint32_t mem_order_1, uint32_t mem_order_2, bool has_mem_order_2, uint32_t op0, uint32_t op1 = 0,
bool op1_is_pointer = false, bool op1_is_literal = false, uint32_t op2 = 0);
const char *get_memory_order(uint32_t spv_mem_sem);
@ -1142,7 +1148,7 @@ protected:
void add_typedef_line(const std::string &line);
void emit_barrier(uint32_t id_exe_scope, uint32_t id_mem_scope, uint32_t id_mem_sem);
bool emit_array_copy(const char *expr, uint32_t lhs_id, uint32_t rhs_id,
spv::StorageClass lhs_storage, spv::StorageClass rhs_storage) override;
StorageClass lhs_storage, StorageClass rhs_storage) override;
void build_implicit_builtins();
uint32_t build_constant_uint_array_pointer();
void emit_entry_point_declarations() override;
@ -1192,7 +1198,7 @@ protected:
void analyze_workgroup_variables();
bool access_chain_needs_stage_io_builtin_translation(uint32_t base) override;
bool prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage,
bool prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, StorageClass storage,
bool &is_packed) override;
void fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t length);
bool check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type) override;
@ -1201,9 +1207,9 @@ protected:
bool emit_tessellation_io_load(uint32_t result_type, uint32_t id, uint32_t ptr);
bool is_out_of_bounds_tessellation_level(uint32_t id_lhs);
void ensure_builtin(spv::StorageClass storage, spv::BuiltIn builtin);
void ensure_builtin(StorageClass storage, BuiltIn builtin);
void mark_implicit_builtin(spv::StorageClass storage, spv::BuiltIn builtin, uint32_t id);
void mark_implicit_builtin(StorageClass storage, BuiltIn builtin, uint32_t id);
std::string convert_to_f32(const std::string &expr, uint32_t components);
@ -1264,6 +1270,7 @@ protected:
bool using_builtin_array() const;
bool is_rasterization_disabled = false;
bool has_descriptor_side_effects_buffer = false;
bool capture_output_to_buffer = false;
bool needs_swizzle_buffer_def = false;
bool used_swizzle_buffer = false;
@ -1274,6 +1281,7 @@ protected:
bool needs_sample_id = false;
bool needs_helper_invocation = false;
bool needs_workgroup_zero_init = false;
bool needs_point_size_output = false;
bool writes_to_depth = false;
bool writes_to_point_size = false;
std::string qual_pos_var_name;
@ -1292,7 +1300,7 @@ protected:
std::string patch_output_buffer_var_name = "spvPatchOut";
std::string tess_factor_buffer_var_name = "spvTessLevel";
std::string index_buffer_var_name = "spvIndices";
spv::Op previous_instruction_opcode = spv::OpNop;
Op previous_instruction_opcode = OpNop;
// Must be ordered since declaration is in a specific order.
std::map<uint32_t, MSLConstexprSampler> constexpr_samplers_by_id;
@ -1300,7 +1308,6 @@ protected:
const MSLConstexprSampler *find_constexpr_sampler(uint32_t id) const;
std::unordered_set<uint32_t> buffers_requiring_array_length;
SmallVector<std::pair<uint32_t, uint32_t>> buffer_aliases_argument;
SmallVector<uint32_t> buffer_aliases_discrete;
std::unordered_set<uint32_t> atomic_image_vars_emulated; // Emulate texture2D atomic operations
std::unordered_set<uint32_t> pull_model_inputs;
@ -1309,7 +1316,13 @@ protected:
SmallVector<SPIRVariable *> entry_point_bindings;
// Must be ordered since array is in a specific order.
std::map<SetBindingPair, std::pair<uint32_t, uint32_t>> buffers_requiring_dynamic_offset;
struct DynamicBuffer
{
uint32_t base_index;
uint32_t var_id;
std::string mbr_name;
};
std::map<SetBindingPair, DynamicBuffer> buffers_requiring_dynamic_offset;
SmallVector<uint32_t> disabled_frag_outputs;
@ -1346,7 +1359,7 @@ protected:
bool type_is_msl_framebuffer_fetch(const SPIRType &type) const;
bool is_supported_argument_buffer_type(const SPIRType &type) const;
bool variable_storage_requires_stage_io(spv::StorageClass storage) const;
bool variable_storage_requires_stage_io(StorageClass storage) const;
bool needs_manual_helper_invocation_updates() const
{
@ -1354,7 +1367,7 @@ protected:
}
bool needs_frag_discard_checks() const
{
return get_execution_model() == spv::ExecutionModelFragment && msl_options.supports_msl_version(2, 3) &&
return get_execution_model() == ExecutionModelFragment && msl_options.supports_msl_version(2, 3) &&
msl_options.check_discarded_frag_stores && frag_shader_needs_discard_checks;
}
@ -1364,17 +1377,17 @@ protected:
// OpcodeHandler that handles several MSL preprocessing operations.
struct OpCodePreprocessor : OpcodeHandler
{
OpCodePreprocessor(CompilerMSL &compiler_)
: compiler(compiler_)
explicit OpCodePreprocessor(CompilerMSL &compiler_)
: OpcodeHandler(compiler_), self(compiler_)
{
enable_result_types = true;
}
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
CompilerMSL::SPVFuncImpl get_spv_func_impl(spv::Op opcode, const uint32_t *args, uint32_t length);
bool handle(Op opcode, const uint32_t *args, uint32_t length) override;
CompilerMSL::SPVFuncImpl get_spv_func_impl(Op opcode, const uint32_t *args, uint32_t length);
void check_resource_write(uint32_t var_id);
CompilerMSL &compiler;
std::unordered_map<uint32_t, uint32_t> result_types;
CompilerMSL &self;
std::unordered_map<uint32_t, uint32_t> image_pointers_emulated; // Emulate texture2D atomic operations
bool suppress_missing_prototypes = false;
bool uses_atomics = false;
@ -1391,14 +1404,13 @@ protected:
// OpcodeHandler that scans for uses of sampled images
struct SampledImageScanner : OpcodeHandler
{
SampledImageScanner(CompilerMSL &compiler_)
: compiler(compiler_)
explicit SampledImageScanner(CompilerMSL &compiler_)
: OpcodeHandler(compiler_), self(compiler_)
{
}
bool handle(spv::Op opcode, const uint32_t *args, uint32_t) override;
CompilerMSL &compiler;
CompilerMSL &self;
bool handle(Op opcode, const uint32_t *args, uint32_t) override;
};
// Sorts the members of a SPIRType and associated Meta info based on a settable sorting

View file

@ -25,7 +25,7 @@
#include <assert.h>
using namespace std;
using namespace spv;
using namespace SPIRV_CROSS_SPV_HEADER_NAMESPACE;
namespace SPIRV_CROSS_NAMESPACE
{
@ -213,8 +213,8 @@ void Parser::parse(const Instruction &instruction)
case OpSource:
{
auto lang = static_cast<SourceLanguage>(ops[0]);
switch (lang)
ir.source.lang = static_cast<SourceLanguage>(ops[0]);
switch (ir.source.lang)
{
case SourceLanguageESSL:
ir.source.es = true;
@ -318,6 +318,19 @@ void Parser::parse(const Instruction &instruction)
ir.load_type_width.insert({ ops[1], type->width });
}
}
else if (op == OpExtInst)
{
// Don't want to deal with ForwardRefs here.
auto &ext = get<SPIRExtension>(ops[2]);
if (ext.ext == SPIRExtension::NonSemanticShaderDebugInfo)
{
// Parse global ShaderDebugInfo we care about.
// Just forward the string information.
if (ops[3] == SPIRExtension::DebugSource)
set<SPIRString>(ops[1], get<SPIRString>(ops[4]).str);
}
}
break;
}
@ -369,6 +382,30 @@ void Parser::parse(const Instruction &instruction)
execution.output_primitives = ops[2];
break;
case ExecutionModeSignedZeroInfNanPreserve:
switch (ops[2])
{
case 8:
execution.signed_zero_inf_nan_preserve_8 = true;
break;
case 16:
execution.signed_zero_inf_nan_preserve_16 = true;
break;
case 32:
execution.signed_zero_inf_nan_preserve_32 = true;
break;
case 64:
execution.signed_zero_inf_nan_preserve_64 = true;
break;
default:
SPIRV_CROSS_THROW("Invalid bit-width for SignedZeroInfNanPreserve.");
}
break;
default:
break;
}
@ -557,7 +594,7 @@ void Parser::parse(const Instruction &instruction)
{
if (length > 2)
{
if (ops[2] == spv::FPEncodingBFloat16KHR)
if (ops[2] == FPEncodingBFloat16KHR)
type.basetype = SPIRType::BFloat16;
else
SPIRV_CROSS_THROW("Unrecognized encoding for OpTypeFloat 16.");
@ -569,9 +606,9 @@ void Parser::parse(const Instruction &instruction)
{
if (length < 2)
SPIRV_CROSS_THROW("Missing encoding for OpTypeFloat 8.");
else if (ops[2] == spv::FPEncodingFloat8E4M3EXT)
else if (ops[2] == FPEncodingFloat8E4M3EXT)
type.basetype = SPIRType::FloatE4M3;
else if (ops[2] == spv::FPEncodingFloat8E5M2EXT)
else if (ops[2] == FPEncodingFloat8E5M2EXT)
type.basetype = SPIRType::FloatE5M2;
else
SPIRV_CROSS_THROW("Invalid encoding for OpTypeFloat 8.");
@ -633,15 +670,33 @@ void Parser::parse(const Instruction &instruction)
auto &matrixbase = set<SPIRType>(id, base);
matrixbase.op = op;
matrixbase.cooperative.scope_id = ops[2];
matrixbase.cooperative.rows_id = ops[3];
matrixbase.cooperative.columns_id = ops[4];
matrixbase.cooperative.use_id = ops[5];
matrixbase.ext.cooperative.scope_id = ops[2];
matrixbase.ext.cooperative.rows_id = ops[3];
matrixbase.ext.cooperative.columns_id = ops[4];
matrixbase.ext.cooperative.use_id = ops[5];
matrixbase.self = id;
matrixbase.parent_type = ops[1];
break;
}
case OpTypeCooperativeVectorNV:
{
uint32_t id = ops[0];
auto &type = set<SPIRType>(id, op);
type.basetype = SPIRType::CoopVecNV;
type.op = op;
type.ext.coopVecNV.component_type_id = ops[1];
type.ext.coopVecNV.component_count_id = ops[2];
type.parent_type = ops[1];
// CoopVec-Nv can be used with integer operations like SMax where
// where spirv-opt does explicit checks on integer bitwidth
auto component_type = get<SPIRType>(type.ext.coopVecNV.component_type_id);
type.width = component_type.width;
break;
}
case OpTypeArray:
{
uint32_t id = ops[0];
@ -839,6 +894,20 @@ void Parser::parse(const Instruction &instruction)
break;
}
case OpTypeTensorARM:
{
uint32_t id = ops[0];
auto &type = set<SPIRType>(id, op);
type.basetype = SPIRType::Tensor;
type.ext.tensor = {};
type.ext.tensor.type = ops[1];
if (length >= 3)
type.ext.tensor.rank = ops[2];
if (length >= 4)
type.ext.tensor.shape = ops[3];
break;
}
// Variable declaration
// All variables are essentially pointers with a storage qualifier.
case OpVariable:
@ -875,7 +944,7 @@ void Parser::parse(const Instruction &instruction)
uint32_t id = ops[1];
// Instead of a temporary, create a new function-wide temporary with this ID instead.
auto &var = set<SPIRVariable>(id, result_type, spv::StorageClassFunction);
auto &var = set<SPIRVariable>(id, result_type, StorageClassFunction);
var.phi_variable = true;
current_function->add_local_variable(id);

View file

@ -25,7 +25,7 @@
#include "spirv_glsl.hpp"
#include <iomanip>
using namespace spv;
using namespace SPIRV_CROSS_SPV_HEADER_NAMESPACE;
using namespace SPIRV_CROSS_NAMESPACE;
using namespace std;
@ -449,7 +449,7 @@ void CompilerReflection::emit_type_member_qualifiers(const SPIRType &type, uint3
}
}
string CompilerReflection::execution_model_to_str(spv::ExecutionModel model)
string CompilerReflection::execution_model_to_str(ExecutionModel model)
{
switch (model)
{
@ -477,6 +477,12 @@ string CompilerReflection::execution_model_to_str(spv::ExecutionModel model)
return "rmiss";
case ExecutionModelCallableNV:
return "rcall";
case ExecutionModelMeshNV:
case ExecutionModelMeshEXT:
return "mesh";
case ExecutionModelTaskNV:
case ExecutionModelTaskEXT:
return "task";
default:
return "???";
}
@ -504,7 +510,9 @@ void CompilerReflection::emit_entry_points()
json_stream->begin_json_object();
json_stream->emit_json_key_value("name", e.name);
json_stream->emit_json_key_value("mode", execution_model_to_str(e.execution_model));
if (e.execution_model == ExecutionModelGLCompute)
if (e.execution_model == ExecutionModelGLCompute || e.execution_model == ExecutionModelMeshEXT ||
e.execution_model == ExecutionModelMeshNV || e.execution_model == ExecutionModelTaskEXT ||
e.execution_model == ExecutionModelTaskNV)
{
const auto &spv_entry = get_entry_point(e.name, e.execution_model);
@ -547,6 +555,7 @@ void CompilerReflection::emit_resources()
emit_resources("push_constants", res.push_constant_buffers);
emit_resources("counters", res.atomic_counters);
emit_resources("acceleration_structures", res.acceleration_structures);
emit_resources("tensors", res.tensors);
}
void CompilerReflection::emit_resources(const char *tag, const SmallVector<Resource> &resources)

View file

@ -34,6 +34,7 @@ class Stream;
namespace SPIRV_CROSS_NAMESPACE
{
using namespace SPIRV_CROSS_SPV_HEADER_NAMESPACE;
class CompilerReflection : public CompilerGLSL
{
using Parent = CompilerGLSL;
@ -67,7 +68,7 @@ public:
std::string compile() override;
private:
static std::string execution_model_to_str(spv::ExecutionModel model);
static std::string execution_model_to_str(ExecutionModel model);
void emit_entry_points();
void emit_types();

View file

@ -24,3 +24,4 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

View file

@ -195,6 +195,7 @@ typedef enum SpvExecutionMode_ {
SpvExecutionModeSampleInterlockUnorderedEXT = 5369,
SpvExecutionModeShadingRateInterlockOrderedEXT = 5370,
SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371,
SpvExecutionModeShader64BitIndexingEXT = 5427,
SpvExecutionModeSharedLocalMemorySizeINTEL = 5618,
SpvExecutionModeRoundingModeRTPINTEL = 5620,
SpvExecutionModeRoundingModeRTNINTEL = 5621,
@ -249,8 +250,11 @@ typedef enum SpvStorageClass_ {
SpvStorageClassPhysicalStorageBufferEXT = 5349,
SpvStorageClassHitObjectAttributeNV = 5385,
SpvStorageClassTaskPayloadWorkgroupEXT = 5402,
SpvStorageClassHitObjectAttributeEXT = 5411,
SpvStorageClassCodeSectionINTEL = 5605,
SpvStorageClassDeviceOnlyALTERA = 5936,
SpvStorageClassDeviceOnlyINTEL = 5936,
SpvStorageClassHostOnlyALTERA = 5937,
SpvStorageClassHostOnlyINTEL = 5937,
SpvStorageClassMax = 0x7fffffff,
} SpvStorageClass;
@ -489,6 +493,7 @@ typedef enum SpvFunctionParameterAttribute_ {
SpvFunctionParameterAttributeNoCapture = 5,
SpvFunctionParameterAttributeNoWrite = 6,
SpvFunctionParameterAttributeNoReadWrite = 7,
SpvFunctionParameterAttributeRuntimeAlignedALTERA = 5940,
SpvFunctionParameterAttributeRuntimeAlignedINTEL = 5940,
SpvFunctionParameterAttributeMax = 0x7fffffff,
} SpvFunctionParameterAttribute;
@ -573,6 +578,7 @@ typedef enum SpvDecoration_ {
SpvDecorationAliasedPointer = 5356,
SpvDecorationAliasedPointerEXT = 5356,
SpvDecorationHitObjectShaderRecordBufferNV = 5386,
SpvDecorationHitObjectShaderRecordBufferEXT = 5389,
SpvDecorationBindlessSamplerNV = 5398,
SpvDecorationBindlessImageNV = 5399,
SpvDecorationBoundSamplerNV = 5400,
@ -593,54 +599,95 @@ typedef enum SpvDecoration_ {
SpvDecorationUserTypeGOOGLE = 5636,
SpvDecorationFunctionRoundingModeINTEL = 5822,
SpvDecorationFunctionDenormModeINTEL = 5823,
SpvDecorationRegisterALTERA = 5825,
SpvDecorationRegisterINTEL = 5825,
SpvDecorationMemoryALTERA = 5826,
SpvDecorationMemoryINTEL = 5826,
SpvDecorationNumbanksALTERA = 5827,
SpvDecorationNumbanksINTEL = 5827,
SpvDecorationBankwidthALTERA = 5828,
SpvDecorationBankwidthINTEL = 5828,
SpvDecorationMaxPrivateCopiesALTERA = 5829,
SpvDecorationMaxPrivateCopiesINTEL = 5829,
SpvDecorationSinglepumpALTERA = 5830,
SpvDecorationSinglepumpINTEL = 5830,
SpvDecorationDoublepumpALTERA = 5831,
SpvDecorationDoublepumpINTEL = 5831,
SpvDecorationMaxReplicatesALTERA = 5832,
SpvDecorationMaxReplicatesINTEL = 5832,
SpvDecorationSimpleDualPortALTERA = 5833,
SpvDecorationSimpleDualPortINTEL = 5833,
SpvDecorationMergeALTERA = 5834,
SpvDecorationMergeINTEL = 5834,
SpvDecorationBankBitsALTERA = 5835,
SpvDecorationBankBitsINTEL = 5835,
SpvDecorationForcePow2DepthALTERA = 5836,
SpvDecorationForcePow2DepthINTEL = 5836,
SpvDecorationStridesizeALTERA = 5883,
SpvDecorationStridesizeINTEL = 5883,
SpvDecorationWordsizeALTERA = 5884,
SpvDecorationWordsizeINTEL = 5884,
SpvDecorationTrueDualPortALTERA = 5885,
SpvDecorationTrueDualPortINTEL = 5885,
SpvDecorationBurstCoalesceALTERA = 5899,
SpvDecorationBurstCoalesceINTEL = 5899,
SpvDecorationCacheSizeALTERA = 5900,
SpvDecorationCacheSizeINTEL = 5900,
SpvDecorationDontStaticallyCoalesceALTERA = 5901,
SpvDecorationDontStaticallyCoalesceINTEL = 5901,
SpvDecorationPrefetchALTERA = 5902,
SpvDecorationPrefetchINTEL = 5902,
SpvDecorationStallEnableALTERA = 5905,
SpvDecorationStallEnableINTEL = 5905,
SpvDecorationFuseLoopsInFunctionALTERA = 5907,
SpvDecorationFuseLoopsInFunctionINTEL = 5907,
SpvDecorationMathOpDSPModeALTERA = 5909,
SpvDecorationMathOpDSPModeINTEL = 5909,
SpvDecorationAliasScopeINTEL = 5914,
SpvDecorationNoAliasINTEL = 5915,
SpvDecorationInitiationIntervalALTERA = 5917,
SpvDecorationInitiationIntervalINTEL = 5917,
SpvDecorationMaxConcurrencyALTERA = 5918,
SpvDecorationMaxConcurrencyINTEL = 5918,
SpvDecorationPipelineEnableALTERA = 5919,
SpvDecorationPipelineEnableINTEL = 5919,
SpvDecorationBufferLocationALTERA = 5921,
SpvDecorationBufferLocationINTEL = 5921,
SpvDecorationIOPipeStorageALTERA = 5944,
SpvDecorationIOPipeStorageINTEL = 5944,
SpvDecorationFunctionFloatingPointModeINTEL = 6080,
SpvDecorationSingleElementVectorINTEL = 6085,
SpvDecorationVectorComputeCallableFunctionINTEL = 6087,
SpvDecorationMediaBlockIOINTEL = 6140,
SpvDecorationStallFreeALTERA = 6151,
SpvDecorationStallFreeINTEL = 6151,
SpvDecorationFPMaxErrorDecorationINTEL = 6170,
SpvDecorationLatencyControlLabelALTERA = 6172,
SpvDecorationLatencyControlLabelINTEL = 6172,
SpvDecorationLatencyControlConstraintALTERA = 6173,
SpvDecorationLatencyControlConstraintINTEL = 6173,
SpvDecorationConduitKernelArgumentALTERA = 6175,
SpvDecorationConduitKernelArgumentINTEL = 6175,
SpvDecorationRegisterMapKernelArgumentALTERA = 6176,
SpvDecorationRegisterMapKernelArgumentINTEL = 6176,
SpvDecorationMMHostInterfaceAddressWidthALTERA = 6177,
SpvDecorationMMHostInterfaceAddressWidthINTEL = 6177,
SpvDecorationMMHostInterfaceDataWidthALTERA = 6178,
SpvDecorationMMHostInterfaceDataWidthINTEL = 6178,
SpvDecorationMMHostInterfaceLatencyALTERA = 6179,
SpvDecorationMMHostInterfaceLatencyINTEL = 6179,
SpvDecorationMMHostInterfaceReadWriteModeALTERA = 6180,
SpvDecorationMMHostInterfaceReadWriteModeINTEL = 6180,
SpvDecorationMMHostInterfaceMaxBurstALTERA = 6181,
SpvDecorationMMHostInterfaceMaxBurstINTEL = 6181,
SpvDecorationMMHostInterfaceWaitRequestALTERA = 6182,
SpvDecorationMMHostInterfaceWaitRequestINTEL = 6182,
SpvDecorationStableKernelArgumentALTERA = 6183,
SpvDecorationStableKernelArgumentINTEL = 6183,
SpvDecorationHostAccessINTEL = 6188,
SpvDecorationInitModeALTERA = 6190,
SpvDecorationInitModeINTEL = 6190,
SpvDecorationImplementInRegisterMapALTERA = 6191,
SpvDecorationImplementInRegisterMapINTEL = 6191,
SpvDecorationConditionalINTEL = 6247,
SpvDecorationCacheControlLoadINTEL = 6442,
@ -822,15 +869,25 @@ typedef enum SpvLoopControlShift_ {
SpvLoopControlIterationMultipleShift = 6,
SpvLoopControlPeelCountShift = 7,
SpvLoopControlPartialCountShift = 8,
SpvLoopControlInitiationIntervalALTERAShift = 16,
SpvLoopControlInitiationIntervalINTELShift = 16,
SpvLoopControlMaxConcurrencyALTERAShift = 17,
SpvLoopControlMaxConcurrencyINTELShift = 17,
SpvLoopControlDependencyArrayALTERAShift = 18,
SpvLoopControlDependencyArrayINTELShift = 18,
SpvLoopControlPipelineEnableALTERAShift = 19,
SpvLoopControlPipelineEnableINTELShift = 19,
SpvLoopControlLoopCoalesceALTERAShift = 20,
SpvLoopControlLoopCoalesceINTELShift = 20,
SpvLoopControlMaxInterleavingALTERAShift = 21,
SpvLoopControlMaxInterleavingINTELShift = 21,
SpvLoopControlSpeculatedIterationsALTERAShift = 22,
SpvLoopControlSpeculatedIterationsINTELShift = 22,
SpvLoopControlNoFusionALTERAShift = 23,
SpvLoopControlNoFusionINTELShift = 23,
SpvLoopControlLoopCountALTERAShift = 24,
SpvLoopControlLoopCountINTELShift = 24,
SpvLoopControlMaxReinvocationDelayALTERAShift = 25,
SpvLoopControlMaxReinvocationDelayINTELShift = 25,
SpvLoopControlMax = 0x7fffffff,
} SpvLoopControlShift;
@ -846,15 +903,25 @@ typedef enum SpvLoopControlMask_ {
SpvLoopControlIterationMultipleMask = 0x00000040,
SpvLoopControlPeelCountMask = 0x00000080,
SpvLoopControlPartialCountMask = 0x00000100,
SpvLoopControlInitiationIntervalALTERAMask = 0x00010000,
SpvLoopControlInitiationIntervalINTELMask = 0x00010000,
SpvLoopControlMaxConcurrencyALTERAMask = 0x00020000,
SpvLoopControlMaxConcurrencyINTELMask = 0x00020000,
SpvLoopControlDependencyArrayALTERAMask = 0x00040000,
SpvLoopControlDependencyArrayINTELMask = 0x00040000,
SpvLoopControlPipelineEnableALTERAMask = 0x00080000,
SpvLoopControlPipelineEnableINTELMask = 0x00080000,
SpvLoopControlLoopCoalesceALTERAMask = 0x00100000,
SpvLoopControlLoopCoalesceINTELMask = 0x00100000,
SpvLoopControlMaxInterleavingALTERAMask = 0x00200000,
SpvLoopControlMaxInterleavingINTELMask = 0x00200000,
SpvLoopControlSpeculatedIterationsALTERAMask = 0x00400000,
SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000,
SpvLoopControlNoFusionALTERAMask = 0x00800000,
SpvLoopControlNoFusionINTELMask = 0x00800000,
SpvLoopControlLoopCountALTERAMask = 0x01000000,
SpvLoopControlLoopCountINTELMask = 0x01000000,
SpvLoopControlMaxReinvocationDelayALTERAMask = 0x02000000,
SpvLoopControlMaxReinvocationDelayINTELMask = 0x02000000,
} SpvLoopControlMask;
@ -1188,6 +1255,7 @@ typedef enum SpvCapability_ {
SpvCapabilityDisplacementMicromapNV = 5380,
SpvCapabilityRayTracingOpacityMicromapEXT = 5381,
SpvCapabilityShaderInvocationReorderNV = 5383,
SpvCapabilityShaderInvocationReorderEXT = 5388,
SpvCapabilityBindlessTextureNV = 5390,
SpvCapabilityRayQueryPositionFetchKHR = 5391,
SpvCapabilityCooperativeVectorNV = 5394,
@ -1196,6 +1264,7 @@ typedef enum SpvCapability_ {
SpvCapabilityRawAccessChainsNV = 5414,
SpvCapabilityRayTracingSpheresGeometryNV = 5418,
SpvCapabilityRayTracingLinearSweptSpheresGeometryNV = 5419,
SpvCapabilityShader64BitIndexingEXT = 5426,
SpvCapabilityCooperativeMatrixReductionsNV = 5430,
SpvCapabilityCooperativeMatrixConversionsNV = 5431,
SpvCapabilityCooperativeMatrixPerElementOperationsNV = 5432,
@ -1225,26 +1294,42 @@ typedef enum SpvCapability_ {
SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
SpvCapabilityVariableLengthArrayINTEL = 5817,
SpvCapabilityFunctionFloatControlINTEL = 5821,
SpvCapabilityFPGAMemoryAttributesALTERA = 5824,
SpvCapabilityFPGAMemoryAttributesINTEL = 5824,
SpvCapabilityFPFastMathModeINTEL = 5837,
SpvCapabilityArbitraryPrecisionIntegersALTERA = 5844,
SpvCapabilityArbitraryPrecisionIntegersINTEL = 5844,
SpvCapabilityArbitraryPrecisionFloatingPointALTERA = 5845,
SpvCapabilityArbitraryPrecisionFloatingPointINTEL = 5845,
SpvCapabilityUnstructuredLoopControlsINTEL = 5886,
SpvCapabilityFPGALoopControlsALTERA = 5888,
SpvCapabilityFPGALoopControlsINTEL = 5888,
SpvCapabilityKernelAttributesINTEL = 5892,
SpvCapabilityFPGAKernelAttributesINTEL = 5897,
SpvCapabilityFPGAMemoryAccessesALTERA = 5898,
SpvCapabilityFPGAMemoryAccessesINTEL = 5898,
SpvCapabilityFPGAClusterAttributesALTERA = 5904,
SpvCapabilityFPGAClusterAttributesINTEL = 5904,
SpvCapabilityLoopFuseALTERA = 5906,
SpvCapabilityLoopFuseINTEL = 5906,
SpvCapabilityFPGADSPControlALTERA = 5908,
SpvCapabilityFPGADSPControlINTEL = 5908,
SpvCapabilityMemoryAccessAliasingINTEL = 5910,
SpvCapabilityFPGAInvocationPipeliningAttributesALTERA = 5916,
SpvCapabilityFPGAInvocationPipeliningAttributesINTEL = 5916,
SpvCapabilityFPGABufferLocationALTERA = 5920,
SpvCapabilityFPGABufferLocationINTEL = 5920,
SpvCapabilityArbitraryPrecisionFixedPointALTERA = 5922,
SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922,
SpvCapabilityUSMStorageClassesALTERA = 5935,
SpvCapabilityUSMStorageClassesINTEL = 5935,
SpvCapabilityRuntimeAlignedAttributeALTERA = 5939,
SpvCapabilityRuntimeAlignedAttributeINTEL = 5939,
SpvCapabilityIOPipesALTERA = 5943,
SpvCapabilityIOPipesINTEL = 5943,
SpvCapabilityBlockingPipesALTERA = 5945,
SpvCapabilityBlockingPipesINTEL = 5945,
SpvCapabilityFPGARegALTERA = 5948,
SpvCapabilityFPGARegINTEL = 5948,
SpvCapabilityDotProductInputAll = 6016,
SpvCapabilityDotProductInputAllKHR = 6016,
@ -1260,6 +1345,7 @@ typedef enum SpvCapability_ {
SpvCapabilityBitInstructions = 6025,
SpvCapabilityGroupNonUniformRotateKHR = 6026,
SpvCapabilityFloatControls2 = 6029,
SpvCapabilityFMAKHR = 6030,
SpvCapabilityAtomicFloat32AddEXT = 6033,
SpvCapabilityAtomicFloat64AddEXT = 6034,
SpvCapabilityLongCompositesINTEL = 6089,
@ -1270,13 +1356,18 @@ typedef enum SpvCapability_ {
SpvCapabilityBFloat16ConversionINTEL = 6115,
SpvCapabilitySplitBarrierINTEL = 6141,
SpvCapabilityArithmeticFenceEXT = 6144,
SpvCapabilityFPGAClusterAttributesV2ALTERA = 6150,
SpvCapabilityFPGAClusterAttributesV2INTEL = 6150,
SpvCapabilityFPGAKernelAttributesv2INTEL = 6161,
SpvCapabilityTaskSequenceALTERA = 6162,
SpvCapabilityTaskSequenceINTEL = 6162,
SpvCapabilityFPMaxErrorINTEL = 6169,
SpvCapabilityFPGALatencyControlALTERA = 6171,
SpvCapabilityFPGALatencyControlINTEL = 6171,
SpvCapabilityFPGAArgumentInterfacesALTERA = 6174,
SpvCapabilityFPGAArgumentInterfacesINTEL = 6174,
SpvCapabilityGlobalVariableHostAccessINTEL = 6187,
SpvCapabilityGlobalVariableFPGADecorationsALTERA = 6189,
SpvCapabilityGlobalVariableFPGADecorationsINTEL = 6189,
SpvCapabilitySubgroupBufferPrefetchINTEL = 6220,
SpvCapabilitySubgroup2DBlockIOINTEL = 6228,
@ -1488,7 +1579,9 @@ typedef enum SpvTensorOperandsMask_ {
} SpvTensorOperandsMask;
typedef enum SpvInitializationModeQualifier_ {
SpvInitializationModeQualifierInitOnDeviceReprogramALTERA = 0,
SpvInitializationModeQualifierInitOnDeviceReprogramINTEL = 0,
SpvInitializationModeQualifierInitOnDeviceResetALTERA = 1,
SpvInitializationModeQualifierInitOnDeviceResetINTEL = 1,
SpvInitializationModeQualifierMax = 0x7fffffff,
} SpvInitializationModeQualifier;
@ -1975,6 +2068,7 @@ typedef enum SpvOp_ {
SpvOpUntypedInBoundsPtrAccessChainKHR = 4424,
SpvOpUntypedArrayLengthKHR = 4425,
SpvOpUntypedPrefetchKHR = 4426,
SpvOpFmaKHR = 4427,
SpvOpSubgroupAllKHR = 4428,
SpvOpSubgroupAnyKHR = 4429,
SpvOpSubgroupAllEqualKHR = 4430,
@ -2095,6 +2189,36 @@ typedef enum SpvOp_ {
SpvOpFetchMicroTriangleVertexBarycentricNV = 5301,
SpvOpCooperativeVectorLoadNV = 5302,
SpvOpCooperativeVectorStoreNV = 5303,
SpvOpHitObjectRecordFromQueryEXT = 5304,
SpvOpHitObjectRecordMissEXT = 5305,
SpvOpHitObjectRecordMissMotionEXT = 5306,
SpvOpHitObjectGetIntersectionTriangleVertexPositionsEXT = 5307,
SpvOpHitObjectGetRayFlagsEXT = 5308,
SpvOpHitObjectSetShaderBindingTableRecordIndexEXT = 5309,
SpvOpHitObjectReorderExecuteShaderEXT = 5310,
SpvOpHitObjectTraceReorderExecuteEXT = 5311,
SpvOpHitObjectTraceMotionReorderExecuteEXT = 5312,
SpvOpTypeHitObjectEXT = 5313,
SpvOpReorderThreadWithHintEXT = 5314,
SpvOpReorderThreadWithHitObjectEXT = 5315,
SpvOpHitObjectTraceRayEXT = 5316,
SpvOpHitObjectTraceRayMotionEXT = 5317,
SpvOpHitObjectRecordEmptyEXT = 5318,
SpvOpHitObjectExecuteShaderEXT = 5319,
SpvOpHitObjectGetCurrentTimeEXT = 5320,
SpvOpHitObjectGetAttributesEXT = 5321,
SpvOpHitObjectGetHitKindEXT = 5322,
SpvOpHitObjectGetPrimitiveIndexEXT = 5323,
SpvOpHitObjectGetGeometryIndexEXT = 5324,
SpvOpHitObjectGetInstanceIdEXT = 5325,
SpvOpHitObjectGetInstanceCustomIndexEXT = 5326,
SpvOpHitObjectGetObjectRayOriginEXT = 5327,
SpvOpHitObjectGetObjectRayDirectionEXT = 5328,
SpvOpHitObjectGetWorldRayDirectionEXT = 5329,
SpvOpHitObjectGetWorldRayOriginEXT = 5330,
SpvOpHitObjectGetObjectToWorldEXT = 5331,
SpvOpHitObjectGetWorldToObjectEXT = 5332,
SpvOpHitObjectGetRayTMaxEXT = 5333,
SpvOpReportIntersectionKHR = 5334,
SpvOpReportIntersectionNV = 5334,
SpvOpIgnoreIntersectionNV = 5335,
@ -2109,6 +2233,12 @@ typedef enum SpvOp_ {
SpvOpRayQueryGetClusterIdNV = 5345,
SpvOpRayQueryGetIntersectionClusterIdNV = 5345,
SpvOpHitObjectGetClusterIdNV = 5346,
SpvOpHitObjectGetRayTMinEXT = 5347,
SpvOpHitObjectGetShaderBindingTableRecordIndexEXT = 5348,
SpvOpHitObjectGetShaderRecordBufferHandleEXT = 5349,
SpvOpHitObjectIsEmptyEXT = 5350,
SpvOpHitObjectIsHitEXT = 5351,
SpvOpHitObjectIsMissEXT = 5352,
SpvOpTypeCooperativeMatrixNV = 5358,
SpvOpCooperativeMatrixLoadNV = 5359,
SpvOpCooperativeMatrixStoreNV = 5360,
@ -2315,23 +2445,41 @@ typedef enum SpvOp_ {
SpvOpVariableLengthArrayINTEL = 5818,
SpvOpSaveMemoryINTEL = 5819,
SpvOpRestoreMemoryINTEL = 5820,
SpvOpArbitraryFloatSinCosPiALTERA = 5840,
SpvOpArbitraryFloatSinCosPiINTEL = 5840,
SpvOpArbitraryFloatCastALTERA = 5841,
SpvOpArbitraryFloatCastINTEL = 5841,
SpvOpArbitraryFloatCastFromIntALTERA = 5842,
SpvOpArbitraryFloatCastFromIntINTEL = 5842,
SpvOpArbitraryFloatCastToIntALTERA = 5843,
SpvOpArbitraryFloatCastToIntINTEL = 5843,
SpvOpArbitraryFloatAddALTERA = 5846,
SpvOpArbitraryFloatAddINTEL = 5846,
SpvOpArbitraryFloatSubALTERA = 5847,
SpvOpArbitraryFloatSubINTEL = 5847,
SpvOpArbitraryFloatMulALTERA = 5848,
SpvOpArbitraryFloatMulINTEL = 5848,
SpvOpArbitraryFloatDivALTERA = 5849,
SpvOpArbitraryFloatDivINTEL = 5849,
SpvOpArbitraryFloatGTALTERA = 5850,
SpvOpArbitraryFloatGTINTEL = 5850,
SpvOpArbitraryFloatGEALTERA = 5851,
SpvOpArbitraryFloatGEINTEL = 5851,
SpvOpArbitraryFloatLTALTERA = 5852,
SpvOpArbitraryFloatLTINTEL = 5852,
SpvOpArbitraryFloatLEALTERA = 5853,
SpvOpArbitraryFloatLEINTEL = 5853,
SpvOpArbitraryFloatEQALTERA = 5854,
SpvOpArbitraryFloatEQINTEL = 5854,
SpvOpArbitraryFloatRecipALTERA = 5855,
SpvOpArbitraryFloatRecipINTEL = 5855,
SpvOpArbitraryFloatRSqrtALTERA = 5856,
SpvOpArbitraryFloatRSqrtINTEL = 5856,
SpvOpArbitraryFloatCbrtALTERA = 5857,
SpvOpArbitraryFloatCbrtINTEL = 5857,
SpvOpArbitraryFloatHypotALTERA = 5858,
SpvOpArbitraryFloatHypotINTEL = 5858,
SpvOpArbitraryFloatSqrtALTERA = 5859,
SpvOpArbitraryFloatSqrtINTEL = 5859,
SpvOpArbitraryFloatLogINTEL = 5860,
SpvOpArbitraryFloatLog2INTEL = 5861,
@ -2360,21 +2508,37 @@ typedef enum SpvOp_ {
SpvOpAliasDomainDeclINTEL = 5911,
SpvOpAliasScopeDeclINTEL = 5912,
SpvOpAliasScopeListDeclINTEL = 5913,
SpvOpFixedSqrtALTERA = 5923,
SpvOpFixedSqrtINTEL = 5923,
SpvOpFixedRecipALTERA = 5924,
SpvOpFixedRecipINTEL = 5924,
SpvOpFixedRsqrtALTERA = 5925,
SpvOpFixedRsqrtINTEL = 5925,
SpvOpFixedSinALTERA = 5926,
SpvOpFixedSinINTEL = 5926,
SpvOpFixedCosALTERA = 5927,
SpvOpFixedCosINTEL = 5927,
SpvOpFixedSinCosALTERA = 5928,
SpvOpFixedSinCosINTEL = 5928,
SpvOpFixedSinPiALTERA = 5929,
SpvOpFixedSinPiINTEL = 5929,
SpvOpFixedCosPiALTERA = 5930,
SpvOpFixedCosPiINTEL = 5930,
SpvOpFixedSinCosPiALTERA = 5931,
SpvOpFixedSinCosPiINTEL = 5931,
SpvOpFixedLogALTERA = 5932,
SpvOpFixedLogINTEL = 5932,
SpvOpFixedExpALTERA = 5933,
SpvOpFixedExpINTEL = 5933,
SpvOpPtrCastToCrossWorkgroupALTERA = 5934,
SpvOpPtrCastToCrossWorkgroupINTEL = 5934,
SpvOpCrossWorkgroupCastToPtrALTERA = 5938,
SpvOpCrossWorkgroupCastToPtrINTEL = 5938,
SpvOpReadPipeBlockingALTERA = 5946,
SpvOpReadPipeBlockingINTEL = 5946,
SpvOpWritePipeBlockingALTERA = 5947,
SpvOpWritePipeBlockingINTEL = 5947,
SpvOpFPGARegALTERA = 5949,
SpvOpFPGARegINTEL = 5949,
SpvOpRayQueryGetRayTMinKHR = 6016,
SpvOpRayQueryGetRayFlagsKHR = 6017,
@ -2404,10 +2568,15 @@ typedef enum SpvOp_ {
SpvOpControlBarrierArriveINTEL = 6142,
SpvOpControlBarrierWaitINTEL = 6143,
SpvOpArithmeticFenceEXT = 6145,
SpvOpTaskSequenceCreateALTERA = 6163,
SpvOpTaskSequenceCreateINTEL = 6163,
SpvOpTaskSequenceAsyncALTERA = 6164,
SpvOpTaskSequenceAsyncINTEL = 6164,
SpvOpTaskSequenceGetALTERA = 6165,
SpvOpTaskSequenceGetINTEL = 6165,
SpvOpTaskSequenceReleaseALTERA = 6166,
SpvOpTaskSequenceReleaseINTEL = 6166,
SpvOpTypeTaskSequenceALTERA = 6199,
SpvOpTypeTaskSequenceINTEL = 6199,
SpvOpSubgroupBlockPrefetchINTEL = 6221,
SpvOpSubgroup2DBlockLoadINTEL = 6231,
@ -2819,6 +2988,7 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpUntypedInBoundsPtrAccessChainKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpUntypedArrayLengthKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpUntypedPrefetchKHR: *hasResult = false; *hasResultType = false; break;
case SpvOpFmaKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
@ -2933,6 +3103,36 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break;
case SpvOpCooperativeVectorLoadNV: *hasResult = true; *hasResultType = true; break;
case SpvOpCooperativeVectorStoreNV: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectRecordFromQueryEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectRecordMissEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectRecordMissMotionEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectGetIntersectionTriangleVertexPositionsEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetRayFlagsEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectSetShaderBindingTableRecordIndexEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectReorderExecuteShaderEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectTraceReorderExecuteEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectTraceMotionReorderExecuteEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpTypeHitObjectEXT: *hasResult = true; *hasResultType = false; break;
case SpvOpReorderThreadWithHintEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpReorderThreadWithHitObjectEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectTraceRayEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectTraceRayMotionEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectRecordEmptyEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectExecuteShaderEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectGetCurrentTimeEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetAttributesEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectGetHitKindEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetPrimitiveIndexEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetGeometryIndexEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetInstanceIdEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetInstanceCustomIndexEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetObjectRayOriginEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetObjectRayDirectionEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetWorldRayDirectionEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetWorldRayOriginEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetObjectToWorldEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetWorldToObjectEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetRayTMaxEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpReportIntersectionKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
@ -2944,6 +3144,12 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
case SpvOpRayQueryGetIntersectionClusterIdNV: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetClusterIdNV: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetRayTMinEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetShaderBindingTableRecordIndexEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectGetShaderRecordBufferHandleEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectIsEmptyEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectIsHitEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectIsMissEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
case SpvOpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break;
case SpvOpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break;
@ -3147,24 +3353,24 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break;
case SpvOpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatSinCosPiALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatCastALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatCastFromIntALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatCastToIntALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatAddALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatSubALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatMulALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatDivALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatGTALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatGEALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatLTALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatLEALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatEQALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatRecipALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatRSqrtALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatCbrtALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatHypotALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatSqrtALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break;
@ -3192,22 +3398,22 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break;
case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break;
case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break;
case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedSinINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedCosINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedLogINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedExpINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedSqrtALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedRecipALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedRsqrtALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedSinALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedCosALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedSinCosALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedSinPiALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedCosPiALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedSinCosPiALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedLogALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFixedExpALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpPtrCastToCrossWorkgroupALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpCrossWorkgroupCastToPtrALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpReadPipeBlockingALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpWritePipeBlockingALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpFPGARegALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break;
@ -3236,11 +3442,11 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break;
case SpvOpArithmeticFenceEXT: *hasResult = true; *hasResultType = true; break;
case SpvOpTaskSequenceCreateINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpTaskSequenceAsyncINTEL: *hasResult = false; *hasResultType = false; break;
case SpvOpTaskSequenceGetINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpTaskSequenceReleaseINTEL: *hasResult = false; *hasResultType = false; break;
case SpvOpTypeTaskSequenceINTEL: *hasResult = true; *hasResultType = false; break;
case SpvOpTaskSequenceCreateALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpTaskSequenceAsyncALTERA: *hasResult = false; *hasResultType = false; break;
case SpvOpTaskSequenceGetALTERA: *hasResult = true; *hasResultType = true; break;
case SpvOpTaskSequenceReleaseALTERA: *hasResult = false; *hasResultType = false; break;
case SpvOpTypeTaskSequenceALTERA: *hasResult = true; *hasResultType = false; break;
case SpvOpSubgroupBlockPrefetchINTEL: *hasResult = false; *hasResultType = false; break;
case SpvOpSubgroup2DBlockLoadINTEL: *hasResult = false; *hasResultType = false; break;
case SpvOpSubgroup2DBlockLoadTransformINTEL: *hasResult = false; *hasResultType = false; break;
@ -3416,6 +3622,7 @@ inline const char* SpvExecutionModeToString(SpvExecutionMode value) {
case SpvExecutionModeSampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT";
case SpvExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT";
case SpvExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT";
case SpvExecutionModeShader64BitIndexingEXT: return "Shader64BitIndexingEXT";
case SpvExecutionModeSharedLocalMemorySizeINTEL: return "SharedLocalMemorySizeINTEL";
case SpvExecutionModeRoundingModeRTPINTEL: return "RoundingModeRTPINTEL";
case SpvExecutionModeRoundingModeRTNINTEL: return "RoundingModeRTNINTEL";
@ -3465,9 +3672,10 @@ inline const char* SpvStorageClassToString(SpvStorageClass value) {
case SpvStorageClassPhysicalStorageBuffer: return "PhysicalStorageBuffer";
case SpvStorageClassHitObjectAttributeNV: return "HitObjectAttributeNV";
case SpvStorageClassTaskPayloadWorkgroupEXT: return "TaskPayloadWorkgroupEXT";
case SpvStorageClassHitObjectAttributeEXT: return "HitObjectAttributeEXT";
case SpvStorageClassCodeSectionINTEL: return "CodeSectionINTEL";
case SpvStorageClassDeviceOnlyINTEL: return "DeviceOnlyINTEL";
case SpvStorageClassHostOnlyINTEL: return "HostOnlyINTEL";
case SpvStorageClassDeviceOnlyALTERA: return "DeviceOnlyALTERA";
case SpvStorageClassHostOnlyALTERA: return "HostOnlyALTERA";
default: return "Unknown";
}
}
@ -3649,7 +3857,7 @@ inline const char* SpvFunctionParameterAttributeToString(SpvFunctionParameterAtt
case SpvFunctionParameterAttributeNoCapture: return "NoCapture";
case SpvFunctionParameterAttributeNoWrite: return "NoWrite";
case SpvFunctionParameterAttributeNoReadWrite: return "NoReadWrite";
case SpvFunctionParameterAttributeRuntimeAlignedINTEL: return "RuntimeAlignedINTEL";
case SpvFunctionParameterAttributeRuntimeAlignedALTERA: return "RuntimeAlignedALTERA";
default: return "Unknown";
}
}
@ -3730,6 +3938,7 @@ inline const char* SpvDecorationToString(SpvDecoration value) {
case SpvDecorationRestrictPointer: return "RestrictPointer";
case SpvDecorationAliasedPointer: return "AliasedPointer";
case SpvDecorationHitObjectShaderRecordBufferNV: return "HitObjectShaderRecordBufferNV";
case SpvDecorationHitObjectShaderRecordBufferEXT: return "HitObjectShaderRecordBufferEXT";
case SpvDecorationBindlessSamplerNV: return "BindlessSamplerNV";
case SpvDecorationBindlessImageNV: return "BindlessImageNV";
case SpvDecorationBoundSamplerNV: return "BoundSamplerNV";
@ -3748,55 +3957,55 @@ inline const char* SpvDecorationToString(SpvDecoration value) {
case SpvDecorationUserTypeGOOGLE: return "UserTypeGOOGLE";
case SpvDecorationFunctionRoundingModeINTEL: return "FunctionRoundingModeINTEL";
case SpvDecorationFunctionDenormModeINTEL: return "FunctionDenormModeINTEL";
case SpvDecorationRegisterINTEL: return "RegisterINTEL";
case SpvDecorationMemoryINTEL: return "MemoryINTEL";
case SpvDecorationNumbanksINTEL: return "NumbanksINTEL";
case SpvDecorationBankwidthINTEL: return "BankwidthINTEL";
case SpvDecorationMaxPrivateCopiesINTEL: return "MaxPrivateCopiesINTEL";
case SpvDecorationSinglepumpINTEL: return "SinglepumpINTEL";
case SpvDecorationDoublepumpINTEL: return "DoublepumpINTEL";
case SpvDecorationMaxReplicatesINTEL: return "MaxReplicatesINTEL";
case SpvDecorationSimpleDualPortINTEL: return "SimpleDualPortINTEL";
case SpvDecorationMergeINTEL: return "MergeINTEL";
case SpvDecorationBankBitsINTEL: return "BankBitsINTEL";
case SpvDecorationForcePow2DepthINTEL: return "ForcePow2DepthINTEL";
case SpvDecorationStridesizeINTEL: return "StridesizeINTEL";
case SpvDecorationWordsizeINTEL: return "WordsizeINTEL";
case SpvDecorationTrueDualPortINTEL: return "TrueDualPortINTEL";
case SpvDecorationBurstCoalesceINTEL: return "BurstCoalesceINTEL";
case SpvDecorationCacheSizeINTEL: return "CacheSizeINTEL";
case SpvDecorationDontStaticallyCoalesceINTEL: return "DontStaticallyCoalesceINTEL";
case SpvDecorationPrefetchINTEL: return "PrefetchINTEL";
case SpvDecorationStallEnableINTEL: return "StallEnableINTEL";
case SpvDecorationFuseLoopsInFunctionINTEL: return "FuseLoopsInFunctionINTEL";
case SpvDecorationMathOpDSPModeINTEL: return "MathOpDSPModeINTEL";
case SpvDecorationRegisterALTERA: return "RegisterALTERA";
case SpvDecorationMemoryALTERA: return "MemoryALTERA";
case SpvDecorationNumbanksALTERA: return "NumbanksALTERA";
case SpvDecorationBankwidthALTERA: return "BankwidthALTERA";
case SpvDecorationMaxPrivateCopiesALTERA: return "MaxPrivateCopiesALTERA";
case SpvDecorationSinglepumpALTERA: return "SinglepumpALTERA";
case SpvDecorationDoublepumpALTERA: return "DoublepumpALTERA";
case SpvDecorationMaxReplicatesALTERA: return "MaxReplicatesALTERA";
case SpvDecorationSimpleDualPortALTERA: return "SimpleDualPortALTERA";
case SpvDecorationMergeALTERA: return "MergeALTERA";
case SpvDecorationBankBitsALTERA: return "BankBitsALTERA";
case SpvDecorationForcePow2DepthALTERA: return "ForcePow2DepthALTERA";
case SpvDecorationStridesizeALTERA: return "StridesizeALTERA";
case SpvDecorationWordsizeALTERA: return "WordsizeALTERA";
case SpvDecorationTrueDualPortALTERA: return "TrueDualPortALTERA";
case SpvDecorationBurstCoalesceALTERA: return "BurstCoalesceALTERA";
case SpvDecorationCacheSizeALTERA: return "CacheSizeALTERA";
case SpvDecorationDontStaticallyCoalesceALTERA: return "DontStaticallyCoalesceALTERA";
case SpvDecorationPrefetchALTERA: return "PrefetchALTERA";
case SpvDecorationStallEnableALTERA: return "StallEnableALTERA";
case SpvDecorationFuseLoopsInFunctionALTERA: return "FuseLoopsInFunctionALTERA";
case SpvDecorationMathOpDSPModeALTERA: return "MathOpDSPModeALTERA";
case SpvDecorationAliasScopeINTEL: return "AliasScopeINTEL";
case SpvDecorationNoAliasINTEL: return "NoAliasINTEL";
case SpvDecorationInitiationIntervalINTEL: return "InitiationIntervalINTEL";
case SpvDecorationMaxConcurrencyINTEL: return "MaxConcurrencyINTEL";
case SpvDecorationPipelineEnableINTEL: return "PipelineEnableINTEL";
case SpvDecorationBufferLocationINTEL: return "BufferLocationINTEL";
case SpvDecorationIOPipeStorageINTEL: return "IOPipeStorageINTEL";
case SpvDecorationInitiationIntervalALTERA: return "InitiationIntervalALTERA";
case SpvDecorationMaxConcurrencyALTERA: return "MaxConcurrencyALTERA";
case SpvDecorationPipelineEnableALTERA: return "PipelineEnableALTERA";
case SpvDecorationBufferLocationALTERA: return "BufferLocationALTERA";
case SpvDecorationIOPipeStorageALTERA: return "IOPipeStorageALTERA";
case SpvDecorationFunctionFloatingPointModeINTEL: return "FunctionFloatingPointModeINTEL";
case SpvDecorationSingleElementVectorINTEL: return "SingleElementVectorINTEL";
case SpvDecorationVectorComputeCallableFunctionINTEL: return "VectorComputeCallableFunctionINTEL";
case SpvDecorationMediaBlockIOINTEL: return "MediaBlockIOINTEL";
case SpvDecorationStallFreeINTEL: return "StallFreeINTEL";
case SpvDecorationStallFreeALTERA: return "StallFreeALTERA";
case SpvDecorationFPMaxErrorDecorationINTEL: return "FPMaxErrorDecorationINTEL";
case SpvDecorationLatencyControlLabelINTEL: return "LatencyControlLabelINTEL";
case SpvDecorationLatencyControlConstraintINTEL: return "LatencyControlConstraintINTEL";
case SpvDecorationConduitKernelArgumentINTEL: return "ConduitKernelArgumentINTEL";
case SpvDecorationRegisterMapKernelArgumentINTEL: return "RegisterMapKernelArgumentINTEL";
case SpvDecorationMMHostInterfaceAddressWidthINTEL: return "MMHostInterfaceAddressWidthINTEL";
case SpvDecorationMMHostInterfaceDataWidthINTEL: return "MMHostInterfaceDataWidthINTEL";
case SpvDecorationMMHostInterfaceLatencyINTEL: return "MMHostInterfaceLatencyINTEL";
case SpvDecorationMMHostInterfaceReadWriteModeINTEL: return "MMHostInterfaceReadWriteModeINTEL";
case SpvDecorationMMHostInterfaceMaxBurstINTEL: return "MMHostInterfaceMaxBurstINTEL";
case SpvDecorationMMHostInterfaceWaitRequestINTEL: return "MMHostInterfaceWaitRequestINTEL";
case SpvDecorationStableKernelArgumentINTEL: return "StableKernelArgumentINTEL";
case SpvDecorationLatencyControlLabelALTERA: return "LatencyControlLabelALTERA";
case SpvDecorationLatencyControlConstraintALTERA: return "LatencyControlConstraintALTERA";
case SpvDecorationConduitKernelArgumentALTERA: return "ConduitKernelArgumentALTERA";
case SpvDecorationRegisterMapKernelArgumentALTERA: return "RegisterMapKernelArgumentALTERA";
case SpvDecorationMMHostInterfaceAddressWidthALTERA: return "MMHostInterfaceAddressWidthALTERA";
case SpvDecorationMMHostInterfaceDataWidthALTERA: return "MMHostInterfaceDataWidthALTERA";
case SpvDecorationMMHostInterfaceLatencyALTERA: return "MMHostInterfaceLatencyALTERA";
case SpvDecorationMMHostInterfaceReadWriteModeALTERA: return "MMHostInterfaceReadWriteModeALTERA";
case SpvDecorationMMHostInterfaceMaxBurstALTERA: return "MMHostInterfaceMaxBurstALTERA";
case SpvDecorationMMHostInterfaceWaitRequestALTERA: return "MMHostInterfaceWaitRequestALTERA";
case SpvDecorationStableKernelArgumentALTERA: return "StableKernelArgumentALTERA";
case SpvDecorationHostAccessINTEL: return "HostAccessINTEL";
case SpvDecorationInitModeINTEL: return "InitModeINTEL";
case SpvDecorationImplementInRegisterMapINTEL: return "ImplementInRegisterMapINTEL";
case SpvDecorationInitModeALTERA: return "InitModeALTERA";
case SpvDecorationImplementInRegisterMapALTERA: return "ImplementInRegisterMapALTERA";
case SpvDecorationConditionalINTEL: return "ConditionalINTEL";
case SpvDecorationCacheControlLoadINTEL: return "CacheControlLoadINTEL";
case SpvDecorationCacheControlStoreINTEL: return "CacheControlStoreINTEL";
@ -4147,6 +4356,7 @@ inline const char* SpvCapabilityToString(SpvCapability value) {
case SpvCapabilityDisplacementMicromapNV: return "DisplacementMicromapNV";
case SpvCapabilityRayTracingOpacityMicromapEXT: return "RayTracingOpacityMicromapEXT";
case SpvCapabilityShaderInvocationReorderNV: return "ShaderInvocationReorderNV";
case SpvCapabilityShaderInvocationReorderEXT: return "ShaderInvocationReorderEXT";
case SpvCapabilityBindlessTextureNV: return "BindlessTextureNV";
case SpvCapabilityRayQueryPositionFetchKHR: return "RayQueryPositionFetchKHR";
case SpvCapabilityCooperativeVectorNV: return "CooperativeVectorNV";
@ -4155,6 +4365,7 @@ inline const char* SpvCapabilityToString(SpvCapability value) {
case SpvCapabilityRawAccessChainsNV: return "RawAccessChainsNV";
case SpvCapabilityRayTracingSpheresGeometryNV: return "RayTracingSpheresGeometryNV";
case SpvCapabilityRayTracingLinearSweptSpheresGeometryNV: return "RayTracingLinearSweptSpheresGeometryNV";
case SpvCapabilityShader64BitIndexingEXT: return "Shader64BitIndexingEXT";
case SpvCapabilityCooperativeMatrixReductionsNV: return "CooperativeMatrixReductionsNV";
case SpvCapabilityCooperativeMatrixConversionsNV: return "CooperativeMatrixConversionsNV";
case SpvCapabilityCooperativeMatrixPerElementOperationsNV: return "CooperativeMatrixPerElementOperationsNV";
@ -4184,27 +4395,27 @@ inline const char* SpvCapabilityToString(SpvCapability value) {
case SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL: return "SubgroupAvcMotionEstimationChromaINTEL";
case SpvCapabilityVariableLengthArrayINTEL: return "VariableLengthArrayINTEL";
case SpvCapabilityFunctionFloatControlINTEL: return "FunctionFloatControlINTEL";
case SpvCapabilityFPGAMemoryAttributesINTEL: return "FPGAMemoryAttributesINTEL";
case SpvCapabilityFPGAMemoryAttributesALTERA: return "FPGAMemoryAttributesALTERA";
case SpvCapabilityFPFastMathModeINTEL: return "FPFastMathModeINTEL";
case SpvCapabilityArbitraryPrecisionIntegersINTEL: return "ArbitraryPrecisionIntegersINTEL";
case SpvCapabilityArbitraryPrecisionFloatingPointINTEL: return "ArbitraryPrecisionFloatingPointINTEL";
case SpvCapabilityArbitraryPrecisionIntegersALTERA: return "ArbitraryPrecisionIntegersALTERA";
case SpvCapabilityArbitraryPrecisionFloatingPointALTERA: return "ArbitraryPrecisionFloatingPointALTERA";
case SpvCapabilityUnstructuredLoopControlsINTEL: return "UnstructuredLoopControlsINTEL";
case SpvCapabilityFPGALoopControlsINTEL: return "FPGALoopControlsINTEL";
case SpvCapabilityFPGALoopControlsALTERA: return "FPGALoopControlsALTERA";
case SpvCapabilityKernelAttributesINTEL: return "KernelAttributesINTEL";
case SpvCapabilityFPGAKernelAttributesINTEL: return "FPGAKernelAttributesINTEL";
case SpvCapabilityFPGAMemoryAccessesINTEL: return "FPGAMemoryAccessesINTEL";
case SpvCapabilityFPGAClusterAttributesINTEL: return "FPGAClusterAttributesINTEL";
case SpvCapabilityLoopFuseINTEL: return "LoopFuseINTEL";
case SpvCapabilityFPGADSPControlINTEL: return "FPGADSPControlINTEL";
case SpvCapabilityFPGAMemoryAccessesALTERA: return "FPGAMemoryAccessesALTERA";
case SpvCapabilityFPGAClusterAttributesALTERA: return "FPGAClusterAttributesALTERA";
case SpvCapabilityLoopFuseALTERA: return "LoopFuseALTERA";
case SpvCapabilityFPGADSPControlALTERA: return "FPGADSPControlALTERA";
case SpvCapabilityMemoryAccessAliasingINTEL: return "MemoryAccessAliasingINTEL";
case SpvCapabilityFPGAInvocationPipeliningAttributesINTEL: return "FPGAInvocationPipeliningAttributesINTEL";
case SpvCapabilityFPGABufferLocationINTEL: return "FPGABufferLocationINTEL";
case SpvCapabilityArbitraryPrecisionFixedPointINTEL: return "ArbitraryPrecisionFixedPointINTEL";
case SpvCapabilityUSMStorageClassesINTEL: return "USMStorageClassesINTEL";
case SpvCapabilityRuntimeAlignedAttributeINTEL: return "RuntimeAlignedAttributeINTEL";
case SpvCapabilityIOPipesINTEL: return "IOPipesINTEL";
case SpvCapabilityBlockingPipesINTEL: return "BlockingPipesINTEL";
case SpvCapabilityFPGARegINTEL: return "FPGARegINTEL";
case SpvCapabilityFPGAInvocationPipeliningAttributesALTERA: return "FPGAInvocationPipeliningAttributesALTERA";
case SpvCapabilityFPGABufferLocationALTERA: return "FPGABufferLocationALTERA";
case SpvCapabilityArbitraryPrecisionFixedPointALTERA: return "ArbitraryPrecisionFixedPointALTERA";
case SpvCapabilityUSMStorageClassesALTERA: return "USMStorageClassesALTERA";
case SpvCapabilityRuntimeAlignedAttributeALTERA: return "RuntimeAlignedAttributeALTERA";
case SpvCapabilityIOPipesALTERA: return "IOPipesALTERA";
case SpvCapabilityBlockingPipesALTERA: return "BlockingPipesALTERA";
case SpvCapabilityFPGARegALTERA: return "FPGARegALTERA";
case SpvCapabilityDotProductInputAll: return "DotProductInputAll";
case SpvCapabilityDotProductInput4x8Bit: return "DotProductInput4x8Bit";
case SpvCapabilityDotProductInput4x8BitPacked: return "DotProductInput4x8BitPacked";
@ -4215,6 +4426,7 @@ inline const char* SpvCapabilityToString(SpvCapability value) {
case SpvCapabilityBitInstructions: return "BitInstructions";
case SpvCapabilityGroupNonUniformRotateKHR: return "GroupNonUniformRotateKHR";
case SpvCapabilityFloatControls2: return "FloatControls2";
case SpvCapabilityFMAKHR: return "FMAKHR";
case SpvCapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
case SpvCapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
case SpvCapabilityLongCompositesINTEL: return "LongCompositesINTEL";
@ -4224,14 +4436,14 @@ inline const char* SpvCapabilityToString(SpvCapability value) {
case SpvCapabilityBFloat16ConversionINTEL: return "BFloat16ConversionINTEL";
case SpvCapabilitySplitBarrierINTEL: return "SplitBarrierINTEL";
case SpvCapabilityArithmeticFenceEXT: return "ArithmeticFenceEXT";
case SpvCapabilityFPGAClusterAttributesV2INTEL: return "FPGAClusterAttributesV2INTEL";
case SpvCapabilityFPGAClusterAttributesV2ALTERA: return "FPGAClusterAttributesV2ALTERA";
case SpvCapabilityFPGAKernelAttributesv2INTEL: return "FPGAKernelAttributesv2INTEL";
case SpvCapabilityTaskSequenceINTEL: return "TaskSequenceINTEL";
case SpvCapabilityTaskSequenceALTERA: return "TaskSequenceALTERA";
case SpvCapabilityFPMaxErrorINTEL: return "FPMaxErrorINTEL";
case SpvCapabilityFPGALatencyControlINTEL: return "FPGALatencyControlINTEL";
case SpvCapabilityFPGAArgumentInterfacesINTEL: return "FPGAArgumentInterfacesINTEL";
case SpvCapabilityFPGALatencyControlALTERA: return "FPGALatencyControlALTERA";
case SpvCapabilityFPGAArgumentInterfacesALTERA: return "FPGAArgumentInterfacesALTERA";
case SpvCapabilityGlobalVariableHostAccessINTEL: return "GlobalVariableHostAccessINTEL";
case SpvCapabilityGlobalVariableFPGADecorationsINTEL: return "GlobalVariableFPGADecorationsINTEL";
case SpvCapabilityGlobalVariableFPGADecorationsALTERA: return "GlobalVariableFPGADecorationsALTERA";
case SpvCapabilitySubgroupBufferPrefetchINTEL: return "SubgroupBufferPrefetchINTEL";
case SpvCapabilitySubgroup2DBlockIOINTEL: return "Subgroup2DBlockIOINTEL";
case SpvCapabilitySubgroup2DBlockTransformINTEL: return "Subgroup2DBlockTransformINTEL";
@ -4355,8 +4567,8 @@ inline const char* SpvTensorClampModeToString(SpvTensorClampMode value) {
inline const char* SpvInitializationModeQualifierToString(SpvInitializationModeQualifier value) {
switch (value) {
case SpvInitializationModeQualifierInitOnDeviceReprogramINTEL: return "InitOnDeviceReprogramINTEL";
case SpvInitializationModeQualifierInitOnDeviceResetINTEL: return "InitOnDeviceResetINTEL";
case SpvInitializationModeQualifierInitOnDeviceReprogramALTERA: return "InitOnDeviceReprogramALTERA";
case SpvInitializationModeQualifierInitOnDeviceResetALTERA: return "InitOnDeviceResetALTERA";
default: return "Unknown";
}
}
@ -4810,6 +5022,7 @@ inline const char* SpvOpToString(SpvOp value) {
case SpvOpUntypedInBoundsPtrAccessChainKHR: return "OpUntypedInBoundsPtrAccessChainKHR";
case SpvOpUntypedArrayLengthKHR: return "OpUntypedArrayLengthKHR";
case SpvOpUntypedPrefetchKHR: return "OpUntypedPrefetchKHR";
case SpvOpFmaKHR: return "OpFmaKHR";
case SpvOpSubgroupAllKHR: return "OpSubgroupAllKHR";
case SpvOpSubgroupAnyKHR: return "OpSubgroupAnyKHR";
case SpvOpSubgroupAllEqualKHR: return "OpSubgroupAllEqualKHR";
@ -4924,6 +5137,36 @@ inline const char* SpvOpToString(SpvOp value) {
case SpvOpFetchMicroTriangleVertexBarycentricNV: return "OpFetchMicroTriangleVertexBarycentricNV";
case SpvOpCooperativeVectorLoadNV: return "OpCooperativeVectorLoadNV";
case SpvOpCooperativeVectorStoreNV: return "OpCooperativeVectorStoreNV";
case SpvOpHitObjectRecordFromQueryEXT: return "OpHitObjectRecordFromQueryEXT";
case SpvOpHitObjectRecordMissEXT: return "OpHitObjectRecordMissEXT";
case SpvOpHitObjectRecordMissMotionEXT: return "OpHitObjectRecordMissMotionEXT";
case SpvOpHitObjectGetIntersectionTriangleVertexPositionsEXT: return "OpHitObjectGetIntersectionTriangleVertexPositionsEXT";
case SpvOpHitObjectGetRayFlagsEXT: return "OpHitObjectGetRayFlagsEXT";
case SpvOpHitObjectSetShaderBindingTableRecordIndexEXT: return "OpHitObjectSetShaderBindingTableRecordIndexEXT";
case SpvOpHitObjectReorderExecuteShaderEXT: return "OpHitObjectReorderExecuteShaderEXT";
case SpvOpHitObjectTraceReorderExecuteEXT: return "OpHitObjectTraceReorderExecuteEXT";
case SpvOpHitObjectTraceMotionReorderExecuteEXT: return "OpHitObjectTraceMotionReorderExecuteEXT";
case SpvOpTypeHitObjectEXT: return "OpTypeHitObjectEXT";
case SpvOpReorderThreadWithHintEXT: return "OpReorderThreadWithHintEXT";
case SpvOpReorderThreadWithHitObjectEXT: return "OpReorderThreadWithHitObjectEXT";
case SpvOpHitObjectTraceRayEXT: return "OpHitObjectTraceRayEXT";
case SpvOpHitObjectTraceRayMotionEXT: return "OpHitObjectTraceRayMotionEXT";
case SpvOpHitObjectRecordEmptyEXT: return "OpHitObjectRecordEmptyEXT";
case SpvOpHitObjectExecuteShaderEXT: return "OpHitObjectExecuteShaderEXT";
case SpvOpHitObjectGetCurrentTimeEXT: return "OpHitObjectGetCurrentTimeEXT";
case SpvOpHitObjectGetAttributesEXT: return "OpHitObjectGetAttributesEXT";
case SpvOpHitObjectGetHitKindEXT: return "OpHitObjectGetHitKindEXT";
case SpvOpHitObjectGetPrimitiveIndexEXT: return "OpHitObjectGetPrimitiveIndexEXT";
case SpvOpHitObjectGetGeometryIndexEXT: return "OpHitObjectGetGeometryIndexEXT";
case SpvOpHitObjectGetInstanceIdEXT: return "OpHitObjectGetInstanceIdEXT";
case SpvOpHitObjectGetInstanceCustomIndexEXT: return "OpHitObjectGetInstanceCustomIndexEXT";
case SpvOpHitObjectGetObjectRayOriginEXT: return "OpHitObjectGetObjectRayOriginEXT";
case SpvOpHitObjectGetObjectRayDirectionEXT: return "OpHitObjectGetObjectRayDirectionEXT";
case SpvOpHitObjectGetWorldRayDirectionEXT: return "OpHitObjectGetWorldRayDirectionEXT";
case SpvOpHitObjectGetWorldRayOriginEXT: return "OpHitObjectGetWorldRayOriginEXT";
case SpvOpHitObjectGetObjectToWorldEXT: return "OpHitObjectGetObjectToWorldEXT";
case SpvOpHitObjectGetWorldToObjectEXT: return "OpHitObjectGetWorldToObjectEXT";
case SpvOpHitObjectGetRayTMaxEXT: return "OpHitObjectGetRayTMaxEXT";
case SpvOpReportIntersectionKHR: return "OpReportIntersectionKHR";
case SpvOpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV";
case SpvOpTerminateRayNV: return "OpTerminateRayNV";
@ -4935,6 +5178,12 @@ inline const char* SpvOpToString(SpvOp value) {
case SpvOpExecuteCallableNV: return "OpExecuteCallableNV";
case SpvOpRayQueryGetClusterIdNV: return "OpRayQueryGetClusterIdNV";
case SpvOpHitObjectGetClusterIdNV: return "OpHitObjectGetClusterIdNV";
case SpvOpHitObjectGetRayTMinEXT: return "OpHitObjectGetRayTMinEXT";
case SpvOpHitObjectGetShaderBindingTableRecordIndexEXT: return "OpHitObjectGetShaderBindingTableRecordIndexEXT";
case SpvOpHitObjectGetShaderRecordBufferHandleEXT: return "OpHitObjectGetShaderRecordBufferHandleEXT";
case SpvOpHitObjectIsEmptyEXT: return "OpHitObjectIsEmptyEXT";
case SpvOpHitObjectIsHitEXT: return "OpHitObjectIsHitEXT";
case SpvOpHitObjectIsMissEXT: return "OpHitObjectIsMissEXT";
case SpvOpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV";
case SpvOpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV";
case SpvOpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV";
@ -5138,24 +5387,24 @@ inline const char* SpvOpToString(SpvOp value) {
case SpvOpVariableLengthArrayINTEL: return "OpVariableLengthArrayINTEL";
case SpvOpSaveMemoryINTEL: return "OpSaveMemoryINTEL";
case SpvOpRestoreMemoryINTEL: return "OpRestoreMemoryINTEL";
case SpvOpArbitraryFloatSinCosPiINTEL: return "OpArbitraryFloatSinCosPiINTEL";
case SpvOpArbitraryFloatCastINTEL: return "OpArbitraryFloatCastINTEL";
case SpvOpArbitraryFloatCastFromIntINTEL: return "OpArbitraryFloatCastFromIntINTEL";
case SpvOpArbitraryFloatCastToIntINTEL: return "OpArbitraryFloatCastToIntINTEL";
case SpvOpArbitraryFloatAddINTEL: return "OpArbitraryFloatAddINTEL";
case SpvOpArbitraryFloatSubINTEL: return "OpArbitraryFloatSubINTEL";
case SpvOpArbitraryFloatMulINTEL: return "OpArbitraryFloatMulINTEL";
case SpvOpArbitraryFloatDivINTEL: return "OpArbitraryFloatDivINTEL";
case SpvOpArbitraryFloatGTINTEL: return "OpArbitraryFloatGTINTEL";
case SpvOpArbitraryFloatGEINTEL: return "OpArbitraryFloatGEINTEL";
case SpvOpArbitraryFloatLTINTEL: return "OpArbitraryFloatLTINTEL";
case SpvOpArbitraryFloatLEINTEL: return "OpArbitraryFloatLEINTEL";
case SpvOpArbitraryFloatEQINTEL: return "OpArbitraryFloatEQINTEL";
case SpvOpArbitraryFloatRecipINTEL: return "OpArbitraryFloatRecipINTEL";
case SpvOpArbitraryFloatRSqrtINTEL: return "OpArbitraryFloatRSqrtINTEL";
case SpvOpArbitraryFloatCbrtINTEL: return "OpArbitraryFloatCbrtINTEL";
case SpvOpArbitraryFloatHypotINTEL: return "OpArbitraryFloatHypotINTEL";
case SpvOpArbitraryFloatSqrtINTEL: return "OpArbitraryFloatSqrtINTEL";
case SpvOpArbitraryFloatSinCosPiALTERA: return "OpArbitraryFloatSinCosPiALTERA";
case SpvOpArbitraryFloatCastALTERA: return "OpArbitraryFloatCastALTERA";
case SpvOpArbitraryFloatCastFromIntALTERA: return "OpArbitraryFloatCastFromIntALTERA";
case SpvOpArbitraryFloatCastToIntALTERA: return "OpArbitraryFloatCastToIntALTERA";
case SpvOpArbitraryFloatAddALTERA: return "OpArbitraryFloatAddALTERA";
case SpvOpArbitraryFloatSubALTERA: return "OpArbitraryFloatSubALTERA";
case SpvOpArbitraryFloatMulALTERA: return "OpArbitraryFloatMulALTERA";
case SpvOpArbitraryFloatDivALTERA: return "OpArbitraryFloatDivALTERA";
case SpvOpArbitraryFloatGTALTERA: return "OpArbitraryFloatGTALTERA";
case SpvOpArbitraryFloatGEALTERA: return "OpArbitraryFloatGEALTERA";
case SpvOpArbitraryFloatLTALTERA: return "OpArbitraryFloatLTALTERA";
case SpvOpArbitraryFloatLEALTERA: return "OpArbitraryFloatLEALTERA";
case SpvOpArbitraryFloatEQALTERA: return "OpArbitraryFloatEQALTERA";
case SpvOpArbitraryFloatRecipALTERA: return "OpArbitraryFloatRecipALTERA";
case SpvOpArbitraryFloatRSqrtALTERA: return "OpArbitraryFloatRSqrtALTERA";
case SpvOpArbitraryFloatCbrtALTERA: return "OpArbitraryFloatCbrtALTERA";
case SpvOpArbitraryFloatHypotALTERA: return "OpArbitraryFloatHypotALTERA";
case SpvOpArbitraryFloatSqrtALTERA: return "OpArbitraryFloatSqrtALTERA";
case SpvOpArbitraryFloatLogINTEL: return "OpArbitraryFloatLogINTEL";
case SpvOpArbitraryFloatLog2INTEL: return "OpArbitraryFloatLog2INTEL";
case SpvOpArbitraryFloatLog10INTEL: return "OpArbitraryFloatLog10INTEL";
@ -5183,22 +5432,22 @@ inline const char* SpvOpToString(SpvOp value) {
case SpvOpAliasDomainDeclINTEL: return "OpAliasDomainDeclINTEL";
case SpvOpAliasScopeDeclINTEL: return "OpAliasScopeDeclINTEL";
case SpvOpAliasScopeListDeclINTEL: return "OpAliasScopeListDeclINTEL";
case SpvOpFixedSqrtINTEL: return "OpFixedSqrtINTEL";
case SpvOpFixedRecipINTEL: return "OpFixedRecipINTEL";
case SpvOpFixedRsqrtINTEL: return "OpFixedRsqrtINTEL";
case SpvOpFixedSinINTEL: return "OpFixedSinINTEL";
case SpvOpFixedCosINTEL: return "OpFixedCosINTEL";
case SpvOpFixedSinCosINTEL: return "OpFixedSinCosINTEL";
case SpvOpFixedSinPiINTEL: return "OpFixedSinPiINTEL";
case SpvOpFixedCosPiINTEL: return "OpFixedCosPiINTEL";
case SpvOpFixedSinCosPiINTEL: return "OpFixedSinCosPiINTEL";
case SpvOpFixedLogINTEL: return "OpFixedLogINTEL";
case SpvOpFixedExpINTEL: return "OpFixedExpINTEL";
case SpvOpPtrCastToCrossWorkgroupINTEL: return "OpPtrCastToCrossWorkgroupINTEL";
case SpvOpCrossWorkgroupCastToPtrINTEL: return "OpCrossWorkgroupCastToPtrINTEL";
case SpvOpReadPipeBlockingINTEL: return "OpReadPipeBlockingINTEL";
case SpvOpWritePipeBlockingINTEL: return "OpWritePipeBlockingINTEL";
case SpvOpFPGARegINTEL: return "OpFPGARegINTEL";
case SpvOpFixedSqrtALTERA: return "OpFixedSqrtALTERA";
case SpvOpFixedRecipALTERA: return "OpFixedRecipALTERA";
case SpvOpFixedRsqrtALTERA: return "OpFixedRsqrtALTERA";
case SpvOpFixedSinALTERA: return "OpFixedSinALTERA";
case SpvOpFixedCosALTERA: return "OpFixedCosALTERA";
case SpvOpFixedSinCosALTERA: return "OpFixedSinCosALTERA";
case SpvOpFixedSinPiALTERA: return "OpFixedSinPiALTERA";
case SpvOpFixedCosPiALTERA: return "OpFixedCosPiALTERA";
case SpvOpFixedSinCosPiALTERA: return "OpFixedSinCosPiALTERA";
case SpvOpFixedLogALTERA: return "OpFixedLogALTERA";
case SpvOpFixedExpALTERA: return "OpFixedExpALTERA";
case SpvOpPtrCastToCrossWorkgroupALTERA: return "OpPtrCastToCrossWorkgroupALTERA";
case SpvOpCrossWorkgroupCastToPtrALTERA: return "OpCrossWorkgroupCastToPtrALTERA";
case SpvOpReadPipeBlockingALTERA: return "OpReadPipeBlockingALTERA";
case SpvOpWritePipeBlockingALTERA: return "OpWritePipeBlockingALTERA";
case SpvOpFPGARegALTERA: return "OpFPGARegALTERA";
case SpvOpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR";
case SpvOpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR";
case SpvOpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR";
@ -5227,11 +5476,11 @@ inline const char* SpvOpToString(SpvOp value) {
case SpvOpControlBarrierArriveINTEL: return "OpControlBarrierArriveINTEL";
case SpvOpControlBarrierWaitINTEL: return "OpControlBarrierWaitINTEL";
case SpvOpArithmeticFenceEXT: return "OpArithmeticFenceEXT";
case SpvOpTaskSequenceCreateINTEL: return "OpTaskSequenceCreateINTEL";
case SpvOpTaskSequenceAsyncINTEL: return "OpTaskSequenceAsyncINTEL";
case SpvOpTaskSequenceGetINTEL: return "OpTaskSequenceGetINTEL";
case SpvOpTaskSequenceReleaseINTEL: return "OpTaskSequenceReleaseINTEL";
case SpvOpTypeTaskSequenceINTEL: return "OpTypeTaskSequenceINTEL";
case SpvOpTaskSequenceCreateALTERA: return "OpTaskSequenceCreateALTERA";
case SpvOpTaskSequenceAsyncALTERA: return "OpTaskSequenceAsyncALTERA";
case SpvOpTaskSequenceGetALTERA: return "OpTaskSequenceGetALTERA";
case SpvOpTaskSequenceReleaseALTERA: return "OpTaskSequenceReleaseALTERA";
case SpvOpTypeTaskSequenceALTERA: return "OpTypeTaskSequenceALTERA";
case SpvOpSubgroupBlockPrefetchINTEL: return "OpSubgroupBlockPrefetchINTEL";
case SpvOpSubgroup2DBlockLoadINTEL: return "OpSubgroup2DBlockLoadINTEL";
case SpvOpSubgroup2DBlockLoadTransformINTEL: return "OpSubgroup2DBlockLoadTransformINTEL";

View file

@ -191,6 +191,7 @@ enum ExecutionMode {
ExecutionModeSampleInterlockUnorderedEXT = 5369,
ExecutionModeShadingRateInterlockOrderedEXT = 5370,
ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
ExecutionModeShader64BitIndexingEXT = 5427,
ExecutionModeSharedLocalMemorySizeINTEL = 5618,
ExecutionModeRoundingModeRTPINTEL = 5620,
ExecutionModeRoundingModeRTNINTEL = 5621,
@ -245,8 +246,11 @@ enum StorageClass {
StorageClassPhysicalStorageBufferEXT = 5349,
StorageClassHitObjectAttributeNV = 5385,
StorageClassTaskPayloadWorkgroupEXT = 5402,
StorageClassHitObjectAttributeEXT = 5411,
StorageClassCodeSectionINTEL = 5605,
StorageClassDeviceOnlyALTERA = 5936,
StorageClassDeviceOnlyINTEL = 5936,
StorageClassHostOnlyALTERA = 5937,
StorageClassHostOnlyINTEL = 5937,
StorageClassMax = 0x7fffffff,
};
@ -485,6 +489,7 @@ enum FunctionParameterAttribute {
FunctionParameterAttributeNoCapture = 5,
FunctionParameterAttributeNoWrite = 6,
FunctionParameterAttributeNoReadWrite = 7,
FunctionParameterAttributeRuntimeAlignedALTERA = 5940,
FunctionParameterAttributeRuntimeAlignedINTEL = 5940,
FunctionParameterAttributeMax = 0x7fffffff,
};
@ -569,6 +574,7 @@ enum Decoration {
DecorationAliasedPointer = 5356,
DecorationAliasedPointerEXT = 5356,
DecorationHitObjectShaderRecordBufferNV = 5386,
DecorationHitObjectShaderRecordBufferEXT = 5389,
DecorationBindlessSamplerNV = 5398,
DecorationBindlessImageNV = 5399,
DecorationBoundSamplerNV = 5400,
@ -589,54 +595,95 @@ enum Decoration {
DecorationUserTypeGOOGLE = 5636,
DecorationFunctionRoundingModeINTEL = 5822,
DecorationFunctionDenormModeINTEL = 5823,
DecorationRegisterALTERA = 5825,
DecorationRegisterINTEL = 5825,
DecorationMemoryALTERA = 5826,
DecorationMemoryINTEL = 5826,
DecorationNumbanksALTERA = 5827,
DecorationNumbanksINTEL = 5827,
DecorationBankwidthALTERA = 5828,
DecorationBankwidthINTEL = 5828,
DecorationMaxPrivateCopiesALTERA = 5829,
DecorationMaxPrivateCopiesINTEL = 5829,
DecorationSinglepumpALTERA = 5830,
DecorationSinglepumpINTEL = 5830,
DecorationDoublepumpALTERA = 5831,
DecorationDoublepumpINTEL = 5831,
DecorationMaxReplicatesALTERA = 5832,
DecorationMaxReplicatesINTEL = 5832,
DecorationSimpleDualPortALTERA = 5833,
DecorationSimpleDualPortINTEL = 5833,
DecorationMergeALTERA = 5834,
DecorationMergeINTEL = 5834,
DecorationBankBitsALTERA = 5835,
DecorationBankBitsINTEL = 5835,
DecorationForcePow2DepthALTERA = 5836,
DecorationForcePow2DepthINTEL = 5836,
DecorationStridesizeALTERA = 5883,
DecorationStridesizeINTEL = 5883,
DecorationWordsizeALTERA = 5884,
DecorationWordsizeINTEL = 5884,
DecorationTrueDualPortALTERA = 5885,
DecorationTrueDualPortINTEL = 5885,
DecorationBurstCoalesceALTERA = 5899,
DecorationBurstCoalesceINTEL = 5899,
DecorationCacheSizeALTERA = 5900,
DecorationCacheSizeINTEL = 5900,
DecorationDontStaticallyCoalesceALTERA = 5901,
DecorationDontStaticallyCoalesceINTEL = 5901,
DecorationPrefetchALTERA = 5902,
DecorationPrefetchINTEL = 5902,
DecorationStallEnableALTERA = 5905,
DecorationStallEnableINTEL = 5905,
DecorationFuseLoopsInFunctionALTERA = 5907,
DecorationFuseLoopsInFunctionINTEL = 5907,
DecorationMathOpDSPModeALTERA = 5909,
DecorationMathOpDSPModeINTEL = 5909,
DecorationAliasScopeINTEL = 5914,
DecorationNoAliasINTEL = 5915,
DecorationInitiationIntervalALTERA = 5917,
DecorationInitiationIntervalINTEL = 5917,
DecorationMaxConcurrencyALTERA = 5918,
DecorationMaxConcurrencyINTEL = 5918,
DecorationPipelineEnableALTERA = 5919,
DecorationPipelineEnableINTEL = 5919,
DecorationBufferLocationALTERA = 5921,
DecorationBufferLocationINTEL = 5921,
DecorationIOPipeStorageALTERA = 5944,
DecorationIOPipeStorageINTEL = 5944,
DecorationFunctionFloatingPointModeINTEL = 6080,
DecorationSingleElementVectorINTEL = 6085,
DecorationVectorComputeCallableFunctionINTEL = 6087,
DecorationMediaBlockIOINTEL = 6140,
DecorationStallFreeALTERA = 6151,
DecorationStallFreeINTEL = 6151,
DecorationFPMaxErrorDecorationINTEL = 6170,
DecorationLatencyControlLabelALTERA = 6172,
DecorationLatencyControlLabelINTEL = 6172,
DecorationLatencyControlConstraintALTERA = 6173,
DecorationLatencyControlConstraintINTEL = 6173,
DecorationConduitKernelArgumentALTERA = 6175,
DecorationConduitKernelArgumentINTEL = 6175,
DecorationRegisterMapKernelArgumentALTERA = 6176,
DecorationRegisterMapKernelArgumentINTEL = 6176,
DecorationMMHostInterfaceAddressWidthALTERA = 6177,
DecorationMMHostInterfaceAddressWidthINTEL = 6177,
DecorationMMHostInterfaceDataWidthALTERA = 6178,
DecorationMMHostInterfaceDataWidthINTEL = 6178,
DecorationMMHostInterfaceLatencyALTERA = 6179,
DecorationMMHostInterfaceLatencyINTEL = 6179,
DecorationMMHostInterfaceReadWriteModeALTERA = 6180,
DecorationMMHostInterfaceReadWriteModeINTEL = 6180,
DecorationMMHostInterfaceMaxBurstALTERA = 6181,
DecorationMMHostInterfaceMaxBurstINTEL = 6181,
DecorationMMHostInterfaceWaitRequestALTERA = 6182,
DecorationMMHostInterfaceWaitRequestINTEL = 6182,
DecorationStableKernelArgumentALTERA = 6183,
DecorationStableKernelArgumentINTEL = 6183,
DecorationHostAccessINTEL = 6188,
DecorationInitModeALTERA = 6190,
DecorationInitModeINTEL = 6190,
DecorationImplementInRegisterMapALTERA = 6191,
DecorationImplementInRegisterMapINTEL = 6191,
DecorationConditionalINTEL = 6247,
DecorationCacheControlLoadINTEL = 6442,
@ -818,15 +865,25 @@ enum LoopControlShift {
LoopControlIterationMultipleShift = 6,
LoopControlPeelCountShift = 7,
LoopControlPartialCountShift = 8,
LoopControlInitiationIntervalALTERAShift = 16,
LoopControlInitiationIntervalINTELShift = 16,
LoopControlMaxConcurrencyALTERAShift = 17,
LoopControlMaxConcurrencyINTELShift = 17,
LoopControlDependencyArrayALTERAShift = 18,
LoopControlDependencyArrayINTELShift = 18,
LoopControlPipelineEnableALTERAShift = 19,
LoopControlPipelineEnableINTELShift = 19,
LoopControlLoopCoalesceALTERAShift = 20,
LoopControlLoopCoalesceINTELShift = 20,
LoopControlMaxInterleavingALTERAShift = 21,
LoopControlMaxInterleavingINTELShift = 21,
LoopControlSpeculatedIterationsALTERAShift = 22,
LoopControlSpeculatedIterationsINTELShift = 22,
LoopControlNoFusionALTERAShift = 23,
LoopControlNoFusionINTELShift = 23,
LoopControlLoopCountALTERAShift = 24,
LoopControlLoopCountINTELShift = 24,
LoopControlMaxReinvocationDelayALTERAShift = 25,
LoopControlMaxReinvocationDelayINTELShift = 25,
LoopControlMax = 0x7fffffff,
};
@ -842,15 +899,25 @@ enum LoopControlMask {
LoopControlIterationMultipleMask = 0x00000040,
LoopControlPeelCountMask = 0x00000080,
LoopControlPartialCountMask = 0x00000100,
LoopControlInitiationIntervalALTERAMask = 0x00010000,
LoopControlInitiationIntervalINTELMask = 0x00010000,
LoopControlMaxConcurrencyALTERAMask = 0x00020000,
LoopControlMaxConcurrencyINTELMask = 0x00020000,
LoopControlDependencyArrayALTERAMask = 0x00040000,
LoopControlDependencyArrayINTELMask = 0x00040000,
LoopControlPipelineEnableALTERAMask = 0x00080000,
LoopControlPipelineEnableINTELMask = 0x00080000,
LoopControlLoopCoalesceALTERAMask = 0x00100000,
LoopControlLoopCoalesceINTELMask = 0x00100000,
LoopControlMaxInterleavingALTERAMask = 0x00200000,
LoopControlMaxInterleavingINTELMask = 0x00200000,
LoopControlSpeculatedIterationsALTERAMask = 0x00400000,
LoopControlSpeculatedIterationsINTELMask = 0x00400000,
LoopControlNoFusionALTERAMask = 0x00800000,
LoopControlNoFusionINTELMask = 0x00800000,
LoopControlLoopCountALTERAMask = 0x01000000,
LoopControlLoopCountINTELMask = 0x01000000,
LoopControlMaxReinvocationDelayALTERAMask = 0x02000000,
LoopControlMaxReinvocationDelayINTELMask = 0x02000000,
};
@ -1184,6 +1251,7 @@ enum Capability {
CapabilityDisplacementMicromapNV = 5380,
CapabilityRayTracingOpacityMicromapEXT = 5381,
CapabilityShaderInvocationReorderNV = 5383,
CapabilityShaderInvocationReorderEXT = 5388,
CapabilityBindlessTextureNV = 5390,
CapabilityRayQueryPositionFetchKHR = 5391,
CapabilityCooperativeVectorNV = 5394,
@ -1192,6 +1260,7 @@ enum Capability {
CapabilityRawAccessChainsNV = 5414,
CapabilityRayTracingSpheresGeometryNV = 5418,
CapabilityRayTracingLinearSweptSpheresGeometryNV = 5419,
CapabilityShader64BitIndexingEXT = 5426,
CapabilityCooperativeMatrixReductionsNV = 5430,
CapabilityCooperativeMatrixConversionsNV = 5431,
CapabilityCooperativeMatrixPerElementOperationsNV = 5432,
@ -1221,26 +1290,42 @@ enum Capability {
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
CapabilityVariableLengthArrayINTEL = 5817,
CapabilityFunctionFloatControlINTEL = 5821,
CapabilityFPGAMemoryAttributesALTERA = 5824,
CapabilityFPGAMemoryAttributesINTEL = 5824,
CapabilityFPFastMathModeINTEL = 5837,
CapabilityArbitraryPrecisionIntegersALTERA = 5844,
CapabilityArbitraryPrecisionIntegersINTEL = 5844,
CapabilityArbitraryPrecisionFloatingPointALTERA = 5845,
CapabilityArbitraryPrecisionFloatingPointINTEL = 5845,
CapabilityUnstructuredLoopControlsINTEL = 5886,
CapabilityFPGALoopControlsALTERA = 5888,
CapabilityFPGALoopControlsINTEL = 5888,
CapabilityKernelAttributesINTEL = 5892,
CapabilityFPGAKernelAttributesINTEL = 5897,
CapabilityFPGAMemoryAccessesALTERA = 5898,
CapabilityFPGAMemoryAccessesINTEL = 5898,
CapabilityFPGAClusterAttributesALTERA = 5904,
CapabilityFPGAClusterAttributesINTEL = 5904,
CapabilityLoopFuseALTERA = 5906,
CapabilityLoopFuseINTEL = 5906,
CapabilityFPGADSPControlALTERA = 5908,
CapabilityFPGADSPControlINTEL = 5908,
CapabilityMemoryAccessAliasingINTEL = 5910,
CapabilityFPGAInvocationPipeliningAttributesALTERA = 5916,
CapabilityFPGAInvocationPipeliningAttributesINTEL = 5916,
CapabilityFPGABufferLocationALTERA = 5920,
CapabilityFPGABufferLocationINTEL = 5920,
CapabilityArbitraryPrecisionFixedPointALTERA = 5922,
CapabilityArbitraryPrecisionFixedPointINTEL = 5922,
CapabilityUSMStorageClassesALTERA = 5935,
CapabilityUSMStorageClassesINTEL = 5935,
CapabilityRuntimeAlignedAttributeALTERA = 5939,
CapabilityRuntimeAlignedAttributeINTEL = 5939,
CapabilityIOPipesALTERA = 5943,
CapabilityIOPipesINTEL = 5943,
CapabilityBlockingPipesALTERA = 5945,
CapabilityBlockingPipesINTEL = 5945,
CapabilityFPGARegALTERA = 5948,
CapabilityFPGARegINTEL = 5948,
CapabilityDotProductInputAll = 6016,
CapabilityDotProductInputAllKHR = 6016,
@ -1256,6 +1341,7 @@ enum Capability {
CapabilityBitInstructions = 6025,
CapabilityGroupNonUniformRotateKHR = 6026,
CapabilityFloatControls2 = 6029,
CapabilityFMAKHR = 6030,
CapabilityAtomicFloat32AddEXT = 6033,
CapabilityAtomicFloat64AddEXT = 6034,
CapabilityLongCompositesINTEL = 6089,
@ -1266,13 +1352,18 @@ enum Capability {
CapabilityBFloat16ConversionINTEL = 6115,
CapabilitySplitBarrierINTEL = 6141,
CapabilityArithmeticFenceEXT = 6144,
CapabilityFPGAClusterAttributesV2ALTERA = 6150,
CapabilityFPGAClusterAttributesV2INTEL = 6150,
CapabilityFPGAKernelAttributesv2INTEL = 6161,
CapabilityTaskSequenceALTERA = 6162,
CapabilityTaskSequenceINTEL = 6162,
CapabilityFPMaxErrorINTEL = 6169,
CapabilityFPGALatencyControlALTERA = 6171,
CapabilityFPGALatencyControlINTEL = 6171,
CapabilityFPGAArgumentInterfacesALTERA = 6174,
CapabilityFPGAArgumentInterfacesINTEL = 6174,
CapabilityGlobalVariableHostAccessINTEL = 6187,
CapabilityGlobalVariableFPGADecorationsALTERA = 6189,
CapabilityGlobalVariableFPGADecorationsINTEL = 6189,
CapabilitySubgroupBufferPrefetchINTEL = 6220,
CapabilitySubgroup2DBlockIOINTEL = 6228,
@ -1484,7 +1575,9 @@ enum TensorOperandsMask {
};
enum InitializationModeQualifier {
InitializationModeQualifierInitOnDeviceReprogramALTERA = 0,
InitializationModeQualifierInitOnDeviceReprogramINTEL = 0,
InitializationModeQualifierInitOnDeviceResetALTERA = 1,
InitializationModeQualifierInitOnDeviceResetINTEL = 1,
InitializationModeQualifierMax = 0x7fffffff,
};
@ -1971,6 +2064,7 @@ enum Op {
OpUntypedInBoundsPtrAccessChainKHR = 4424,
OpUntypedArrayLengthKHR = 4425,
OpUntypedPrefetchKHR = 4426,
OpFmaKHR = 4427,
OpSubgroupAllKHR = 4428,
OpSubgroupAnyKHR = 4429,
OpSubgroupAllEqualKHR = 4430,
@ -2091,6 +2185,36 @@ enum Op {
OpFetchMicroTriangleVertexBarycentricNV = 5301,
OpCooperativeVectorLoadNV = 5302,
OpCooperativeVectorStoreNV = 5303,
OpHitObjectRecordFromQueryEXT = 5304,
OpHitObjectRecordMissEXT = 5305,
OpHitObjectRecordMissMotionEXT = 5306,
OpHitObjectGetIntersectionTriangleVertexPositionsEXT = 5307,
OpHitObjectGetRayFlagsEXT = 5308,
OpHitObjectSetShaderBindingTableRecordIndexEXT = 5309,
OpHitObjectReorderExecuteShaderEXT = 5310,
OpHitObjectTraceReorderExecuteEXT = 5311,
OpHitObjectTraceMotionReorderExecuteEXT = 5312,
OpTypeHitObjectEXT = 5313,
OpReorderThreadWithHintEXT = 5314,
OpReorderThreadWithHitObjectEXT = 5315,
OpHitObjectTraceRayEXT = 5316,
OpHitObjectTraceRayMotionEXT = 5317,
OpHitObjectRecordEmptyEXT = 5318,
OpHitObjectExecuteShaderEXT = 5319,
OpHitObjectGetCurrentTimeEXT = 5320,
OpHitObjectGetAttributesEXT = 5321,
OpHitObjectGetHitKindEXT = 5322,
OpHitObjectGetPrimitiveIndexEXT = 5323,
OpHitObjectGetGeometryIndexEXT = 5324,
OpHitObjectGetInstanceIdEXT = 5325,
OpHitObjectGetInstanceCustomIndexEXT = 5326,
OpHitObjectGetObjectRayOriginEXT = 5327,
OpHitObjectGetObjectRayDirectionEXT = 5328,
OpHitObjectGetWorldRayDirectionEXT = 5329,
OpHitObjectGetWorldRayOriginEXT = 5330,
OpHitObjectGetObjectToWorldEXT = 5331,
OpHitObjectGetWorldToObjectEXT = 5332,
OpHitObjectGetRayTMaxEXT = 5333,
OpReportIntersectionKHR = 5334,
OpReportIntersectionNV = 5334,
OpIgnoreIntersectionNV = 5335,
@ -2105,6 +2229,12 @@ enum Op {
OpRayQueryGetClusterIdNV = 5345,
OpRayQueryGetIntersectionClusterIdNV = 5345,
OpHitObjectGetClusterIdNV = 5346,
OpHitObjectGetRayTMinEXT = 5347,
OpHitObjectGetShaderBindingTableRecordIndexEXT = 5348,
OpHitObjectGetShaderRecordBufferHandleEXT = 5349,
OpHitObjectIsEmptyEXT = 5350,
OpHitObjectIsHitEXT = 5351,
OpHitObjectIsMissEXT = 5352,
OpTypeCooperativeMatrixNV = 5358,
OpCooperativeMatrixLoadNV = 5359,
OpCooperativeMatrixStoreNV = 5360,
@ -2311,23 +2441,41 @@ enum Op {
OpVariableLengthArrayINTEL = 5818,
OpSaveMemoryINTEL = 5819,
OpRestoreMemoryINTEL = 5820,
OpArbitraryFloatSinCosPiALTERA = 5840,
OpArbitraryFloatSinCosPiINTEL = 5840,
OpArbitraryFloatCastALTERA = 5841,
OpArbitraryFloatCastINTEL = 5841,
OpArbitraryFloatCastFromIntALTERA = 5842,
OpArbitraryFloatCastFromIntINTEL = 5842,
OpArbitraryFloatCastToIntALTERA = 5843,
OpArbitraryFloatCastToIntINTEL = 5843,
OpArbitraryFloatAddALTERA = 5846,
OpArbitraryFloatAddINTEL = 5846,
OpArbitraryFloatSubALTERA = 5847,
OpArbitraryFloatSubINTEL = 5847,
OpArbitraryFloatMulALTERA = 5848,
OpArbitraryFloatMulINTEL = 5848,
OpArbitraryFloatDivALTERA = 5849,
OpArbitraryFloatDivINTEL = 5849,
OpArbitraryFloatGTALTERA = 5850,
OpArbitraryFloatGTINTEL = 5850,
OpArbitraryFloatGEALTERA = 5851,
OpArbitraryFloatGEINTEL = 5851,
OpArbitraryFloatLTALTERA = 5852,
OpArbitraryFloatLTINTEL = 5852,
OpArbitraryFloatLEALTERA = 5853,
OpArbitraryFloatLEINTEL = 5853,
OpArbitraryFloatEQALTERA = 5854,
OpArbitraryFloatEQINTEL = 5854,
OpArbitraryFloatRecipALTERA = 5855,
OpArbitraryFloatRecipINTEL = 5855,
OpArbitraryFloatRSqrtALTERA = 5856,
OpArbitraryFloatRSqrtINTEL = 5856,
OpArbitraryFloatCbrtALTERA = 5857,
OpArbitraryFloatCbrtINTEL = 5857,
OpArbitraryFloatHypotALTERA = 5858,
OpArbitraryFloatHypotINTEL = 5858,
OpArbitraryFloatSqrtALTERA = 5859,
OpArbitraryFloatSqrtINTEL = 5859,
OpArbitraryFloatLogINTEL = 5860,
OpArbitraryFloatLog2INTEL = 5861,
@ -2356,21 +2504,37 @@ enum Op {
OpAliasDomainDeclINTEL = 5911,
OpAliasScopeDeclINTEL = 5912,
OpAliasScopeListDeclINTEL = 5913,
OpFixedSqrtALTERA = 5923,
OpFixedSqrtINTEL = 5923,
OpFixedRecipALTERA = 5924,
OpFixedRecipINTEL = 5924,
OpFixedRsqrtALTERA = 5925,
OpFixedRsqrtINTEL = 5925,
OpFixedSinALTERA = 5926,
OpFixedSinINTEL = 5926,
OpFixedCosALTERA = 5927,
OpFixedCosINTEL = 5927,
OpFixedSinCosALTERA = 5928,
OpFixedSinCosINTEL = 5928,
OpFixedSinPiALTERA = 5929,
OpFixedSinPiINTEL = 5929,
OpFixedCosPiALTERA = 5930,
OpFixedCosPiINTEL = 5930,
OpFixedSinCosPiALTERA = 5931,
OpFixedSinCosPiINTEL = 5931,
OpFixedLogALTERA = 5932,
OpFixedLogINTEL = 5932,
OpFixedExpALTERA = 5933,
OpFixedExpINTEL = 5933,
OpPtrCastToCrossWorkgroupALTERA = 5934,
OpPtrCastToCrossWorkgroupINTEL = 5934,
OpCrossWorkgroupCastToPtrALTERA = 5938,
OpCrossWorkgroupCastToPtrINTEL = 5938,
OpReadPipeBlockingALTERA = 5946,
OpReadPipeBlockingINTEL = 5946,
OpWritePipeBlockingALTERA = 5947,
OpWritePipeBlockingINTEL = 5947,
OpFPGARegALTERA = 5949,
OpFPGARegINTEL = 5949,
OpRayQueryGetRayTMinKHR = 6016,
OpRayQueryGetRayFlagsKHR = 6017,
@ -2400,10 +2564,15 @@ enum Op {
OpControlBarrierArriveINTEL = 6142,
OpControlBarrierWaitINTEL = 6143,
OpArithmeticFenceEXT = 6145,
OpTaskSequenceCreateALTERA = 6163,
OpTaskSequenceCreateINTEL = 6163,
OpTaskSequenceAsyncALTERA = 6164,
OpTaskSequenceAsyncINTEL = 6164,
OpTaskSequenceGetALTERA = 6165,
OpTaskSequenceGetINTEL = 6165,
OpTaskSequenceReleaseALTERA = 6166,
OpTaskSequenceReleaseINTEL = 6166,
OpTypeTaskSequenceALTERA = 6199,
OpTypeTaskSequenceINTEL = 6199,
OpSubgroupBlockPrefetchINTEL = 6221,
OpSubgroup2DBlockLoadINTEL = 6231,
@ -2815,6 +2984,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpUntypedInBoundsPtrAccessChainKHR: *hasResult = true; *hasResultType = true; break;
case OpUntypedArrayLengthKHR: *hasResult = true; *hasResultType = true; break;
case OpUntypedPrefetchKHR: *hasResult = false; *hasResultType = false; break;
case OpFmaKHR: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
@ -2929,6 +3099,36 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break;
case OpCooperativeVectorLoadNV: *hasResult = true; *hasResultType = true; break;
case OpCooperativeVectorStoreNV: *hasResult = false; *hasResultType = false; break;
case OpHitObjectRecordFromQueryEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectRecordMissEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectRecordMissMotionEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectGetIntersectionTriangleVertexPositionsEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetRayFlagsEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectSetShaderBindingTableRecordIndexEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectReorderExecuteShaderEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectTraceReorderExecuteEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectTraceMotionReorderExecuteEXT: *hasResult = false; *hasResultType = false; break;
case OpTypeHitObjectEXT: *hasResult = true; *hasResultType = false; break;
case OpReorderThreadWithHintEXT: *hasResult = false; *hasResultType = false; break;
case OpReorderThreadWithHitObjectEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectTraceRayEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectTraceRayMotionEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectRecordEmptyEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectExecuteShaderEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectGetCurrentTimeEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetAttributesEXT: *hasResult = false; *hasResultType = false; break;
case OpHitObjectGetHitKindEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetPrimitiveIndexEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetGeometryIndexEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetInstanceIdEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetInstanceCustomIndexEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetObjectRayOriginEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetObjectRayDirectionEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetWorldRayDirectionEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetWorldRayOriginEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetObjectToWorldEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetWorldToObjectEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetRayTMaxEXT: *hasResult = true; *hasResultType = true; break;
case OpReportIntersectionKHR: *hasResult = true; *hasResultType = true; break;
case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
@ -2940,6 +3140,12 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
case OpRayQueryGetIntersectionClusterIdNV: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetClusterIdNV: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetRayTMinEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetShaderBindingTableRecordIndexEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectGetShaderRecordBufferHandleEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectIsEmptyEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectIsHitEXT: *hasResult = true; *hasResultType = true; break;
case OpHitObjectIsMissEXT: *hasResult = true; *hasResultType = true; break;
case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
case OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break;
case OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break;
@ -3143,24 +3349,24 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break;
case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break;
case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break;
case OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatSinCosPiALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCastALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCastFromIntALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCastToIntALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatAddALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatSubALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatMulALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatDivALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatGTALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatGEALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLTALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLEALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatEQALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatRecipALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatRSqrtALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatCbrtALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatHypotALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatSqrtALTERA: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break;
case OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break;
@ -3188,22 +3394,22 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break;
case OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break;
case OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break;
case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break;
case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break;
case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break;
case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
case OpFixedSqrtALTERA: *hasResult = true; *hasResultType = true; break;
case OpFixedRecipALTERA: *hasResult = true; *hasResultType = true; break;
case OpFixedRsqrtALTERA: *hasResult = true; *hasResultType = true; break;
case OpFixedSinALTERA: *hasResult = true; *hasResultType = true; break;
case OpFixedCosALTERA: *hasResult = true; *hasResultType = true; break;
case OpFixedSinCosALTERA: *hasResult = true; *hasResultType = true; break;
case OpFixedSinPiALTERA: *hasResult = true; *hasResultType = true; break;
case OpFixedCosPiALTERA: *hasResult = true; *hasResultType = true; break;
case OpFixedSinCosPiALTERA: *hasResult = true; *hasResultType = true; break;
case OpFixedLogALTERA: *hasResult = true; *hasResultType = true; break;
case OpFixedExpALTERA: *hasResult = true; *hasResultType = true; break;
case OpPtrCastToCrossWorkgroupALTERA: *hasResult = true; *hasResultType = true; break;
case OpCrossWorkgroupCastToPtrALTERA: *hasResult = true; *hasResultType = true; break;
case OpReadPipeBlockingALTERA: *hasResult = true; *hasResultType = true; break;
case OpWritePipeBlockingALTERA: *hasResult = true; *hasResultType = true; break;
case OpFPGARegALTERA: *hasResult = true; *hasResultType = true; break;
case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break;
case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break;
case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break;
@ -3232,11 +3438,11 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
case OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break;
case OpArithmeticFenceEXT: *hasResult = true; *hasResultType = true; break;
case OpTaskSequenceCreateINTEL: *hasResult = true; *hasResultType = true; break;
case OpTaskSequenceAsyncINTEL: *hasResult = false; *hasResultType = false; break;
case OpTaskSequenceGetINTEL: *hasResult = true; *hasResultType = true; break;
case OpTaskSequenceReleaseINTEL: *hasResult = false; *hasResultType = false; break;
case OpTypeTaskSequenceINTEL: *hasResult = true; *hasResultType = false; break;
case OpTaskSequenceCreateALTERA: *hasResult = true; *hasResultType = true; break;
case OpTaskSequenceAsyncALTERA: *hasResult = false; *hasResultType = false; break;
case OpTaskSequenceGetALTERA: *hasResult = true; *hasResultType = true; break;
case OpTaskSequenceReleaseALTERA: *hasResult = false; *hasResultType = false; break;
case OpTypeTaskSequenceALTERA: *hasResult = true; *hasResultType = false; break;
case OpSubgroupBlockPrefetchINTEL: *hasResult = false; *hasResultType = false; break;
case OpSubgroup2DBlockLoadINTEL: *hasResult = false; *hasResultType = false; break;
case OpSubgroup2DBlockLoadTransformINTEL: *hasResult = false; *hasResultType = false; break;
@ -3412,6 +3618,7 @@ inline const char* ExecutionModeToString(ExecutionMode value) {
case ExecutionModeSampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT";
case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT";
case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT";
case ExecutionModeShader64BitIndexingEXT: return "Shader64BitIndexingEXT";
case ExecutionModeSharedLocalMemorySizeINTEL: return "SharedLocalMemorySizeINTEL";
case ExecutionModeRoundingModeRTPINTEL: return "RoundingModeRTPINTEL";
case ExecutionModeRoundingModeRTNINTEL: return "RoundingModeRTNINTEL";
@ -3461,9 +3668,10 @@ inline const char* StorageClassToString(StorageClass value) {
case StorageClassPhysicalStorageBuffer: return "PhysicalStorageBuffer";
case StorageClassHitObjectAttributeNV: return "HitObjectAttributeNV";
case StorageClassTaskPayloadWorkgroupEXT: return "TaskPayloadWorkgroupEXT";
case StorageClassHitObjectAttributeEXT: return "HitObjectAttributeEXT";
case StorageClassCodeSectionINTEL: return "CodeSectionINTEL";
case StorageClassDeviceOnlyINTEL: return "DeviceOnlyINTEL";
case StorageClassHostOnlyINTEL: return "HostOnlyINTEL";
case StorageClassDeviceOnlyALTERA: return "DeviceOnlyALTERA";
case StorageClassHostOnlyALTERA: return "HostOnlyALTERA";
default: return "Unknown";
}
}
@ -3645,7 +3853,7 @@ inline const char* FunctionParameterAttributeToString(FunctionParameterAttribute
case FunctionParameterAttributeNoCapture: return "NoCapture";
case FunctionParameterAttributeNoWrite: return "NoWrite";
case FunctionParameterAttributeNoReadWrite: return "NoReadWrite";
case FunctionParameterAttributeRuntimeAlignedINTEL: return "RuntimeAlignedINTEL";
case FunctionParameterAttributeRuntimeAlignedALTERA: return "RuntimeAlignedALTERA";
default: return "Unknown";
}
}
@ -3726,6 +3934,7 @@ inline const char* DecorationToString(Decoration value) {
case DecorationRestrictPointer: return "RestrictPointer";
case DecorationAliasedPointer: return "AliasedPointer";
case DecorationHitObjectShaderRecordBufferNV: return "HitObjectShaderRecordBufferNV";
case DecorationHitObjectShaderRecordBufferEXT: return "HitObjectShaderRecordBufferEXT";
case DecorationBindlessSamplerNV: return "BindlessSamplerNV";
case DecorationBindlessImageNV: return "BindlessImageNV";
case DecorationBoundSamplerNV: return "BoundSamplerNV";
@ -3744,55 +3953,55 @@ inline const char* DecorationToString(Decoration value) {
case DecorationUserTypeGOOGLE: return "UserTypeGOOGLE";
case DecorationFunctionRoundingModeINTEL: return "FunctionRoundingModeINTEL";
case DecorationFunctionDenormModeINTEL: return "FunctionDenormModeINTEL";
case DecorationRegisterINTEL: return "RegisterINTEL";
case DecorationMemoryINTEL: return "MemoryINTEL";
case DecorationNumbanksINTEL: return "NumbanksINTEL";
case DecorationBankwidthINTEL: return "BankwidthINTEL";
case DecorationMaxPrivateCopiesINTEL: return "MaxPrivateCopiesINTEL";
case DecorationSinglepumpINTEL: return "SinglepumpINTEL";
case DecorationDoublepumpINTEL: return "DoublepumpINTEL";
case DecorationMaxReplicatesINTEL: return "MaxReplicatesINTEL";
case DecorationSimpleDualPortINTEL: return "SimpleDualPortINTEL";
case DecorationMergeINTEL: return "MergeINTEL";
case DecorationBankBitsINTEL: return "BankBitsINTEL";
case DecorationForcePow2DepthINTEL: return "ForcePow2DepthINTEL";
case DecorationStridesizeINTEL: return "StridesizeINTEL";
case DecorationWordsizeINTEL: return "WordsizeINTEL";
case DecorationTrueDualPortINTEL: return "TrueDualPortINTEL";
case DecorationBurstCoalesceINTEL: return "BurstCoalesceINTEL";
case DecorationCacheSizeINTEL: return "CacheSizeINTEL";
case DecorationDontStaticallyCoalesceINTEL: return "DontStaticallyCoalesceINTEL";
case DecorationPrefetchINTEL: return "PrefetchINTEL";
case DecorationStallEnableINTEL: return "StallEnableINTEL";
case DecorationFuseLoopsInFunctionINTEL: return "FuseLoopsInFunctionINTEL";
case DecorationMathOpDSPModeINTEL: return "MathOpDSPModeINTEL";
case DecorationRegisterALTERA: return "RegisterALTERA";
case DecorationMemoryALTERA: return "MemoryALTERA";
case DecorationNumbanksALTERA: return "NumbanksALTERA";
case DecorationBankwidthALTERA: return "BankwidthALTERA";
case DecorationMaxPrivateCopiesALTERA: return "MaxPrivateCopiesALTERA";
case DecorationSinglepumpALTERA: return "SinglepumpALTERA";
case DecorationDoublepumpALTERA: return "DoublepumpALTERA";
case DecorationMaxReplicatesALTERA: return "MaxReplicatesALTERA";
case DecorationSimpleDualPortALTERA: return "SimpleDualPortALTERA";
case DecorationMergeALTERA: return "MergeALTERA";
case DecorationBankBitsALTERA: return "BankBitsALTERA";
case DecorationForcePow2DepthALTERA: return "ForcePow2DepthALTERA";
case DecorationStridesizeALTERA: return "StridesizeALTERA";
case DecorationWordsizeALTERA: return "WordsizeALTERA";
case DecorationTrueDualPortALTERA: return "TrueDualPortALTERA";
case DecorationBurstCoalesceALTERA: return "BurstCoalesceALTERA";
case DecorationCacheSizeALTERA: return "CacheSizeALTERA";
case DecorationDontStaticallyCoalesceALTERA: return "DontStaticallyCoalesceALTERA";
case DecorationPrefetchALTERA: return "PrefetchALTERA";
case DecorationStallEnableALTERA: return "StallEnableALTERA";
case DecorationFuseLoopsInFunctionALTERA: return "FuseLoopsInFunctionALTERA";
case DecorationMathOpDSPModeALTERA: return "MathOpDSPModeALTERA";
case DecorationAliasScopeINTEL: return "AliasScopeINTEL";
case DecorationNoAliasINTEL: return "NoAliasINTEL";
case DecorationInitiationIntervalINTEL: return "InitiationIntervalINTEL";
case DecorationMaxConcurrencyINTEL: return "MaxConcurrencyINTEL";
case DecorationPipelineEnableINTEL: return "PipelineEnableINTEL";
case DecorationBufferLocationINTEL: return "BufferLocationINTEL";
case DecorationIOPipeStorageINTEL: return "IOPipeStorageINTEL";
case DecorationInitiationIntervalALTERA: return "InitiationIntervalALTERA";
case DecorationMaxConcurrencyALTERA: return "MaxConcurrencyALTERA";
case DecorationPipelineEnableALTERA: return "PipelineEnableALTERA";
case DecorationBufferLocationALTERA: return "BufferLocationALTERA";
case DecorationIOPipeStorageALTERA: return "IOPipeStorageALTERA";
case DecorationFunctionFloatingPointModeINTEL: return "FunctionFloatingPointModeINTEL";
case DecorationSingleElementVectorINTEL: return "SingleElementVectorINTEL";
case DecorationVectorComputeCallableFunctionINTEL: return "VectorComputeCallableFunctionINTEL";
case DecorationMediaBlockIOINTEL: return "MediaBlockIOINTEL";
case DecorationStallFreeINTEL: return "StallFreeINTEL";
case DecorationStallFreeALTERA: return "StallFreeALTERA";
case DecorationFPMaxErrorDecorationINTEL: return "FPMaxErrorDecorationINTEL";
case DecorationLatencyControlLabelINTEL: return "LatencyControlLabelINTEL";
case DecorationLatencyControlConstraintINTEL: return "LatencyControlConstraintINTEL";
case DecorationConduitKernelArgumentINTEL: return "ConduitKernelArgumentINTEL";
case DecorationRegisterMapKernelArgumentINTEL: return "RegisterMapKernelArgumentINTEL";
case DecorationMMHostInterfaceAddressWidthINTEL: return "MMHostInterfaceAddressWidthINTEL";
case DecorationMMHostInterfaceDataWidthINTEL: return "MMHostInterfaceDataWidthINTEL";
case DecorationMMHostInterfaceLatencyINTEL: return "MMHostInterfaceLatencyINTEL";
case DecorationMMHostInterfaceReadWriteModeINTEL: return "MMHostInterfaceReadWriteModeINTEL";
case DecorationMMHostInterfaceMaxBurstINTEL: return "MMHostInterfaceMaxBurstINTEL";
case DecorationMMHostInterfaceWaitRequestINTEL: return "MMHostInterfaceWaitRequestINTEL";
case DecorationStableKernelArgumentINTEL: return "StableKernelArgumentINTEL";
case DecorationLatencyControlLabelALTERA: return "LatencyControlLabelALTERA";
case DecorationLatencyControlConstraintALTERA: return "LatencyControlConstraintALTERA";
case DecorationConduitKernelArgumentALTERA: return "ConduitKernelArgumentALTERA";
case DecorationRegisterMapKernelArgumentALTERA: return "RegisterMapKernelArgumentALTERA";
case DecorationMMHostInterfaceAddressWidthALTERA: return "MMHostInterfaceAddressWidthALTERA";
case DecorationMMHostInterfaceDataWidthALTERA: return "MMHostInterfaceDataWidthALTERA";
case DecorationMMHostInterfaceLatencyALTERA: return "MMHostInterfaceLatencyALTERA";
case DecorationMMHostInterfaceReadWriteModeALTERA: return "MMHostInterfaceReadWriteModeALTERA";
case DecorationMMHostInterfaceMaxBurstALTERA: return "MMHostInterfaceMaxBurstALTERA";
case DecorationMMHostInterfaceWaitRequestALTERA: return "MMHostInterfaceWaitRequestALTERA";
case DecorationStableKernelArgumentALTERA: return "StableKernelArgumentALTERA";
case DecorationHostAccessINTEL: return "HostAccessINTEL";
case DecorationInitModeINTEL: return "InitModeINTEL";
case DecorationImplementInRegisterMapINTEL: return "ImplementInRegisterMapINTEL";
case DecorationInitModeALTERA: return "InitModeALTERA";
case DecorationImplementInRegisterMapALTERA: return "ImplementInRegisterMapALTERA";
case DecorationConditionalINTEL: return "ConditionalINTEL";
case DecorationCacheControlLoadINTEL: return "CacheControlLoadINTEL";
case DecorationCacheControlStoreINTEL: return "CacheControlStoreINTEL";
@ -4143,6 +4352,7 @@ inline const char* CapabilityToString(Capability value) {
case CapabilityDisplacementMicromapNV: return "DisplacementMicromapNV";
case CapabilityRayTracingOpacityMicromapEXT: return "RayTracingOpacityMicromapEXT";
case CapabilityShaderInvocationReorderNV: return "ShaderInvocationReorderNV";
case CapabilityShaderInvocationReorderEXT: return "ShaderInvocationReorderEXT";
case CapabilityBindlessTextureNV: return "BindlessTextureNV";
case CapabilityRayQueryPositionFetchKHR: return "RayQueryPositionFetchKHR";
case CapabilityCooperativeVectorNV: return "CooperativeVectorNV";
@ -4151,6 +4361,7 @@ inline const char* CapabilityToString(Capability value) {
case CapabilityRawAccessChainsNV: return "RawAccessChainsNV";
case CapabilityRayTracingSpheresGeometryNV: return "RayTracingSpheresGeometryNV";
case CapabilityRayTracingLinearSweptSpheresGeometryNV: return "RayTracingLinearSweptSpheresGeometryNV";
case CapabilityShader64BitIndexingEXT: return "Shader64BitIndexingEXT";
case CapabilityCooperativeMatrixReductionsNV: return "CooperativeMatrixReductionsNV";
case CapabilityCooperativeMatrixConversionsNV: return "CooperativeMatrixConversionsNV";
case CapabilityCooperativeMatrixPerElementOperationsNV: return "CooperativeMatrixPerElementOperationsNV";
@ -4180,27 +4391,27 @@ inline const char* CapabilityToString(Capability value) {
case CapabilitySubgroupAvcMotionEstimationChromaINTEL: return "SubgroupAvcMotionEstimationChromaINTEL";
case CapabilityVariableLengthArrayINTEL: return "VariableLengthArrayINTEL";
case CapabilityFunctionFloatControlINTEL: return "FunctionFloatControlINTEL";
case CapabilityFPGAMemoryAttributesINTEL: return "FPGAMemoryAttributesINTEL";
case CapabilityFPGAMemoryAttributesALTERA: return "FPGAMemoryAttributesALTERA";
case CapabilityFPFastMathModeINTEL: return "FPFastMathModeINTEL";
case CapabilityArbitraryPrecisionIntegersINTEL: return "ArbitraryPrecisionIntegersINTEL";
case CapabilityArbitraryPrecisionFloatingPointINTEL: return "ArbitraryPrecisionFloatingPointINTEL";
case CapabilityArbitraryPrecisionIntegersALTERA: return "ArbitraryPrecisionIntegersALTERA";
case CapabilityArbitraryPrecisionFloatingPointALTERA: return "ArbitraryPrecisionFloatingPointALTERA";
case CapabilityUnstructuredLoopControlsINTEL: return "UnstructuredLoopControlsINTEL";
case CapabilityFPGALoopControlsINTEL: return "FPGALoopControlsINTEL";
case CapabilityFPGALoopControlsALTERA: return "FPGALoopControlsALTERA";
case CapabilityKernelAttributesINTEL: return "KernelAttributesINTEL";
case CapabilityFPGAKernelAttributesINTEL: return "FPGAKernelAttributesINTEL";
case CapabilityFPGAMemoryAccessesINTEL: return "FPGAMemoryAccessesINTEL";
case CapabilityFPGAClusterAttributesINTEL: return "FPGAClusterAttributesINTEL";
case CapabilityLoopFuseINTEL: return "LoopFuseINTEL";
case CapabilityFPGADSPControlINTEL: return "FPGADSPControlINTEL";
case CapabilityFPGAMemoryAccessesALTERA: return "FPGAMemoryAccessesALTERA";
case CapabilityFPGAClusterAttributesALTERA: return "FPGAClusterAttributesALTERA";
case CapabilityLoopFuseALTERA: return "LoopFuseALTERA";
case CapabilityFPGADSPControlALTERA: return "FPGADSPControlALTERA";
case CapabilityMemoryAccessAliasingINTEL: return "MemoryAccessAliasingINTEL";
case CapabilityFPGAInvocationPipeliningAttributesINTEL: return "FPGAInvocationPipeliningAttributesINTEL";
case CapabilityFPGABufferLocationINTEL: return "FPGABufferLocationINTEL";
case CapabilityArbitraryPrecisionFixedPointINTEL: return "ArbitraryPrecisionFixedPointINTEL";
case CapabilityUSMStorageClassesINTEL: return "USMStorageClassesINTEL";
case CapabilityRuntimeAlignedAttributeINTEL: return "RuntimeAlignedAttributeINTEL";
case CapabilityIOPipesINTEL: return "IOPipesINTEL";
case CapabilityBlockingPipesINTEL: return "BlockingPipesINTEL";
case CapabilityFPGARegINTEL: return "FPGARegINTEL";
case CapabilityFPGAInvocationPipeliningAttributesALTERA: return "FPGAInvocationPipeliningAttributesALTERA";
case CapabilityFPGABufferLocationALTERA: return "FPGABufferLocationALTERA";
case CapabilityArbitraryPrecisionFixedPointALTERA: return "ArbitraryPrecisionFixedPointALTERA";
case CapabilityUSMStorageClassesALTERA: return "USMStorageClassesALTERA";
case CapabilityRuntimeAlignedAttributeALTERA: return "RuntimeAlignedAttributeALTERA";
case CapabilityIOPipesALTERA: return "IOPipesALTERA";
case CapabilityBlockingPipesALTERA: return "BlockingPipesALTERA";
case CapabilityFPGARegALTERA: return "FPGARegALTERA";
case CapabilityDotProductInputAll: return "DotProductInputAll";
case CapabilityDotProductInput4x8Bit: return "DotProductInput4x8Bit";
case CapabilityDotProductInput4x8BitPacked: return "DotProductInput4x8BitPacked";
@ -4211,6 +4422,7 @@ inline const char* CapabilityToString(Capability value) {
case CapabilityBitInstructions: return "BitInstructions";
case CapabilityGroupNonUniformRotateKHR: return "GroupNonUniformRotateKHR";
case CapabilityFloatControls2: return "FloatControls2";
case CapabilityFMAKHR: return "FMAKHR";
case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
case CapabilityLongCompositesINTEL: return "LongCompositesINTEL";
@ -4220,14 +4432,14 @@ inline const char* CapabilityToString(Capability value) {
case CapabilityBFloat16ConversionINTEL: return "BFloat16ConversionINTEL";
case CapabilitySplitBarrierINTEL: return "SplitBarrierINTEL";
case CapabilityArithmeticFenceEXT: return "ArithmeticFenceEXT";
case CapabilityFPGAClusterAttributesV2INTEL: return "FPGAClusterAttributesV2INTEL";
case CapabilityFPGAClusterAttributesV2ALTERA: return "FPGAClusterAttributesV2ALTERA";
case CapabilityFPGAKernelAttributesv2INTEL: return "FPGAKernelAttributesv2INTEL";
case CapabilityTaskSequenceINTEL: return "TaskSequenceINTEL";
case CapabilityTaskSequenceALTERA: return "TaskSequenceALTERA";
case CapabilityFPMaxErrorINTEL: return "FPMaxErrorINTEL";
case CapabilityFPGALatencyControlINTEL: return "FPGALatencyControlINTEL";
case CapabilityFPGAArgumentInterfacesINTEL: return "FPGAArgumentInterfacesINTEL";
case CapabilityFPGALatencyControlALTERA: return "FPGALatencyControlALTERA";
case CapabilityFPGAArgumentInterfacesALTERA: return "FPGAArgumentInterfacesALTERA";
case CapabilityGlobalVariableHostAccessINTEL: return "GlobalVariableHostAccessINTEL";
case CapabilityGlobalVariableFPGADecorationsINTEL: return "GlobalVariableFPGADecorationsINTEL";
case CapabilityGlobalVariableFPGADecorationsALTERA: return "GlobalVariableFPGADecorationsALTERA";
case CapabilitySubgroupBufferPrefetchINTEL: return "SubgroupBufferPrefetchINTEL";
case CapabilitySubgroup2DBlockIOINTEL: return "Subgroup2DBlockIOINTEL";
case CapabilitySubgroup2DBlockTransformINTEL: return "Subgroup2DBlockTransformINTEL";
@ -4351,8 +4563,8 @@ inline const char* TensorClampModeToString(TensorClampMode value) {
inline const char* InitializationModeQualifierToString(InitializationModeQualifier value) {
switch (value) {
case InitializationModeQualifierInitOnDeviceReprogramINTEL: return "InitOnDeviceReprogramINTEL";
case InitializationModeQualifierInitOnDeviceResetINTEL: return "InitOnDeviceResetINTEL";
case InitializationModeQualifierInitOnDeviceReprogramALTERA: return "InitOnDeviceReprogramALTERA";
case InitializationModeQualifierInitOnDeviceResetALTERA: return "InitOnDeviceResetALTERA";
default: return "Unknown";
}
}
@ -4806,6 +5018,7 @@ inline const char* OpToString(Op value) {
case OpUntypedInBoundsPtrAccessChainKHR: return "OpUntypedInBoundsPtrAccessChainKHR";
case OpUntypedArrayLengthKHR: return "OpUntypedArrayLengthKHR";
case OpUntypedPrefetchKHR: return "OpUntypedPrefetchKHR";
case OpFmaKHR: return "OpFmaKHR";
case OpSubgroupAllKHR: return "OpSubgroupAllKHR";
case OpSubgroupAnyKHR: return "OpSubgroupAnyKHR";
case OpSubgroupAllEqualKHR: return "OpSubgroupAllEqualKHR";
@ -4920,6 +5133,36 @@ inline const char* OpToString(Op value) {
case OpFetchMicroTriangleVertexBarycentricNV: return "OpFetchMicroTriangleVertexBarycentricNV";
case OpCooperativeVectorLoadNV: return "OpCooperativeVectorLoadNV";
case OpCooperativeVectorStoreNV: return "OpCooperativeVectorStoreNV";
case OpHitObjectRecordFromQueryEXT: return "OpHitObjectRecordFromQueryEXT";
case OpHitObjectRecordMissEXT: return "OpHitObjectRecordMissEXT";
case OpHitObjectRecordMissMotionEXT: return "OpHitObjectRecordMissMotionEXT";
case OpHitObjectGetIntersectionTriangleVertexPositionsEXT: return "OpHitObjectGetIntersectionTriangleVertexPositionsEXT";
case OpHitObjectGetRayFlagsEXT: return "OpHitObjectGetRayFlagsEXT";
case OpHitObjectSetShaderBindingTableRecordIndexEXT: return "OpHitObjectSetShaderBindingTableRecordIndexEXT";
case OpHitObjectReorderExecuteShaderEXT: return "OpHitObjectReorderExecuteShaderEXT";
case OpHitObjectTraceReorderExecuteEXT: return "OpHitObjectTraceReorderExecuteEXT";
case OpHitObjectTraceMotionReorderExecuteEXT: return "OpHitObjectTraceMotionReorderExecuteEXT";
case OpTypeHitObjectEXT: return "OpTypeHitObjectEXT";
case OpReorderThreadWithHintEXT: return "OpReorderThreadWithHintEXT";
case OpReorderThreadWithHitObjectEXT: return "OpReorderThreadWithHitObjectEXT";
case OpHitObjectTraceRayEXT: return "OpHitObjectTraceRayEXT";
case OpHitObjectTraceRayMotionEXT: return "OpHitObjectTraceRayMotionEXT";
case OpHitObjectRecordEmptyEXT: return "OpHitObjectRecordEmptyEXT";
case OpHitObjectExecuteShaderEXT: return "OpHitObjectExecuteShaderEXT";
case OpHitObjectGetCurrentTimeEXT: return "OpHitObjectGetCurrentTimeEXT";
case OpHitObjectGetAttributesEXT: return "OpHitObjectGetAttributesEXT";
case OpHitObjectGetHitKindEXT: return "OpHitObjectGetHitKindEXT";
case OpHitObjectGetPrimitiveIndexEXT: return "OpHitObjectGetPrimitiveIndexEXT";
case OpHitObjectGetGeometryIndexEXT: return "OpHitObjectGetGeometryIndexEXT";
case OpHitObjectGetInstanceIdEXT: return "OpHitObjectGetInstanceIdEXT";
case OpHitObjectGetInstanceCustomIndexEXT: return "OpHitObjectGetInstanceCustomIndexEXT";
case OpHitObjectGetObjectRayOriginEXT: return "OpHitObjectGetObjectRayOriginEXT";
case OpHitObjectGetObjectRayDirectionEXT: return "OpHitObjectGetObjectRayDirectionEXT";
case OpHitObjectGetWorldRayDirectionEXT: return "OpHitObjectGetWorldRayDirectionEXT";
case OpHitObjectGetWorldRayOriginEXT: return "OpHitObjectGetWorldRayOriginEXT";
case OpHitObjectGetObjectToWorldEXT: return "OpHitObjectGetObjectToWorldEXT";
case OpHitObjectGetWorldToObjectEXT: return "OpHitObjectGetWorldToObjectEXT";
case OpHitObjectGetRayTMaxEXT: return "OpHitObjectGetRayTMaxEXT";
case OpReportIntersectionKHR: return "OpReportIntersectionKHR";
case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV";
case OpTerminateRayNV: return "OpTerminateRayNV";
@ -4931,6 +5174,12 @@ inline const char* OpToString(Op value) {
case OpExecuteCallableNV: return "OpExecuteCallableNV";
case OpRayQueryGetClusterIdNV: return "OpRayQueryGetClusterIdNV";
case OpHitObjectGetClusterIdNV: return "OpHitObjectGetClusterIdNV";
case OpHitObjectGetRayTMinEXT: return "OpHitObjectGetRayTMinEXT";
case OpHitObjectGetShaderBindingTableRecordIndexEXT: return "OpHitObjectGetShaderBindingTableRecordIndexEXT";
case OpHitObjectGetShaderRecordBufferHandleEXT: return "OpHitObjectGetShaderRecordBufferHandleEXT";
case OpHitObjectIsEmptyEXT: return "OpHitObjectIsEmptyEXT";
case OpHitObjectIsHitEXT: return "OpHitObjectIsHitEXT";
case OpHitObjectIsMissEXT: return "OpHitObjectIsMissEXT";
case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV";
case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV";
case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV";
@ -5134,24 +5383,24 @@ inline const char* OpToString(Op value) {
case OpVariableLengthArrayINTEL: return "OpVariableLengthArrayINTEL";
case OpSaveMemoryINTEL: return "OpSaveMemoryINTEL";
case OpRestoreMemoryINTEL: return "OpRestoreMemoryINTEL";
case OpArbitraryFloatSinCosPiINTEL: return "OpArbitraryFloatSinCosPiINTEL";
case OpArbitraryFloatCastINTEL: return "OpArbitraryFloatCastINTEL";
case OpArbitraryFloatCastFromIntINTEL: return "OpArbitraryFloatCastFromIntINTEL";
case OpArbitraryFloatCastToIntINTEL: return "OpArbitraryFloatCastToIntINTEL";
case OpArbitraryFloatAddINTEL: return "OpArbitraryFloatAddINTEL";
case OpArbitraryFloatSubINTEL: return "OpArbitraryFloatSubINTEL";
case OpArbitraryFloatMulINTEL: return "OpArbitraryFloatMulINTEL";
case OpArbitraryFloatDivINTEL: return "OpArbitraryFloatDivINTEL";
case OpArbitraryFloatGTINTEL: return "OpArbitraryFloatGTINTEL";
case OpArbitraryFloatGEINTEL: return "OpArbitraryFloatGEINTEL";
case OpArbitraryFloatLTINTEL: return "OpArbitraryFloatLTINTEL";
case OpArbitraryFloatLEINTEL: return "OpArbitraryFloatLEINTEL";
case OpArbitraryFloatEQINTEL: return "OpArbitraryFloatEQINTEL";
case OpArbitraryFloatRecipINTEL: return "OpArbitraryFloatRecipINTEL";
case OpArbitraryFloatRSqrtINTEL: return "OpArbitraryFloatRSqrtINTEL";
case OpArbitraryFloatCbrtINTEL: return "OpArbitraryFloatCbrtINTEL";
case OpArbitraryFloatHypotINTEL: return "OpArbitraryFloatHypotINTEL";
case OpArbitraryFloatSqrtINTEL: return "OpArbitraryFloatSqrtINTEL";
case OpArbitraryFloatSinCosPiALTERA: return "OpArbitraryFloatSinCosPiALTERA";
case OpArbitraryFloatCastALTERA: return "OpArbitraryFloatCastALTERA";
case OpArbitraryFloatCastFromIntALTERA: return "OpArbitraryFloatCastFromIntALTERA";
case OpArbitraryFloatCastToIntALTERA: return "OpArbitraryFloatCastToIntALTERA";
case OpArbitraryFloatAddALTERA: return "OpArbitraryFloatAddALTERA";
case OpArbitraryFloatSubALTERA: return "OpArbitraryFloatSubALTERA";
case OpArbitraryFloatMulALTERA: return "OpArbitraryFloatMulALTERA";
case OpArbitraryFloatDivALTERA: return "OpArbitraryFloatDivALTERA";
case OpArbitraryFloatGTALTERA: return "OpArbitraryFloatGTALTERA";
case OpArbitraryFloatGEALTERA: return "OpArbitraryFloatGEALTERA";
case OpArbitraryFloatLTALTERA: return "OpArbitraryFloatLTALTERA";
case OpArbitraryFloatLEALTERA: return "OpArbitraryFloatLEALTERA";
case OpArbitraryFloatEQALTERA: return "OpArbitraryFloatEQALTERA";
case OpArbitraryFloatRecipALTERA: return "OpArbitraryFloatRecipALTERA";
case OpArbitraryFloatRSqrtALTERA: return "OpArbitraryFloatRSqrtALTERA";
case OpArbitraryFloatCbrtALTERA: return "OpArbitraryFloatCbrtALTERA";
case OpArbitraryFloatHypotALTERA: return "OpArbitraryFloatHypotALTERA";
case OpArbitraryFloatSqrtALTERA: return "OpArbitraryFloatSqrtALTERA";
case OpArbitraryFloatLogINTEL: return "OpArbitraryFloatLogINTEL";
case OpArbitraryFloatLog2INTEL: return "OpArbitraryFloatLog2INTEL";
case OpArbitraryFloatLog10INTEL: return "OpArbitraryFloatLog10INTEL";
@ -5179,22 +5428,22 @@ inline const char* OpToString(Op value) {
case OpAliasDomainDeclINTEL: return "OpAliasDomainDeclINTEL";
case OpAliasScopeDeclINTEL: return "OpAliasScopeDeclINTEL";
case OpAliasScopeListDeclINTEL: return "OpAliasScopeListDeclINTEL";
case OpFixedSqrtINTEL: return "OpFixedSqrtINTEL";
case OpFixedRecipINTEL: return "OpFixedRecipINTEL";
case OpFixedRsqrtINTEL: return "OpFixedRsqrtINTEL";
case OpFixedSinINTEL: return "OpFixedSinINTEL";
case OpFixedCosINTEL: return "OpFixedCosINTEL";
case OpFixedSinCosINTEL: return "OpFixedSinCosINTEL";
case OpFixedSinPiINTEL: return "OpFixedSinPiINTEL";
case OpFixedCosPiINTEL: return "OpFixedCosPiINTEL";
case OpFixedSinCosPiINTEL: return "OpFixedSinCosPiINTEL";
case OpFixedLogINTEL: return "OpFixedLogINTEL";
case OpFixedExpINTEL: return "OpFixedExpINTEL";
case OpPtrCastToCrossWorkgroupINTEL: return "OpPtrCastToCrossWorkgroupINTEL";
case OpCrossWorkgroupCastToPtrINTEL: return "OpCrossWorkgroupCastToPtrINTEL";
case OpReadPipeBlockingINTEL: return "OpReadPipeBlockingINTEL";
case OpWritePipeBlockingINTEL: return "OpWritePipeBlockingINTEL";
case OpFPGARegINTEL: return "OpFPGARegINTEL";
case OpFixedSqrtALTERA: return "OpFixedSqrtALTERA";
case OpFixedRecipALTERA: return "OpFixedRecipALTERA";
case OpFixedRsqrtALTERA: return "OpFixedRsqrtALTERA";
case OpFixedSinALTERA: return "OpFixedSinALTERA";
case OpFixedCosALTERA: return "OpFixedCosALTERA";
case OpFixedSinCosALTERA: return "OpFixedSinCosALTERA";
case OpFixedSinPiALTERA: return "OpFixedSinPiALTERA";
case OpFixedCosPiALTERA: return "OpFixedCosPiALTERA";
case OpFixedSinCosPiALTERA: return "OpFixedSinCosPiALTERA";
case OpFixedLogALTERA: return "OpFixedLogALTERA";
case OpFixedExpALTERA: return "OpFixedExpALTERA";
case OpPtrCastToCrossWorkgroupALTERA: return "OpPtrCastToCrossWorkgroupALTERA";
case OpCrossWorkgroupCastToPtrALTERA: return "OpCrossWorkgroupCastToPtrALTERA";
case OpReadPipeBlockingALTERA: return "OpReadPipeBlockingALTERA";
case OpWritePipeBlockingALTERA: return "OpWritePipeBlockingALTERA";
case OpFPGARegALTERA: return "OpFPGARegALTERA";
case OpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR";
case OpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR";
case OpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR";
@ -5223,11 +5472,11 @@ inline const char* OpToString(Op value) {
case OpControlBarrierArriveINTEL: return "OpControlBarrierArriveINTEL";
case OpControlBarrierWaitINTEL: return "OpControlBarrierWaitINTEL";
case OpArithmeticFenceEXT: return "OpArithmeticFenceEXT";
case OpTaskSequenceCreateINTEL: return "OpTaskSequenceCreateINTEL";
case OpTaskSequenceAsyncINTEL: return "OpTaskSequenceAsyncINTEL";
case OpTaskSequenceGetINTEL: return "OpTaskSequenceGetINTEL";
case OpTaskSequenceReleaseINTEL: return "OpTaskSequenceReleaseINTEL";
case OpTypeTaskSequenceINTEL: return "OpTypeTaskSequenceINTEL";
case OpTaskSequenceCreateALTERA: return "OpTaskSequenceCreateALTERA";
case OpTaskSequenceAsyncALTERA: return "OpTaskSequenceAsyncALTERA";
case OpTaskSequenceGetALTERA: return "OpTaskSequenceGetALTERA";
case OpTaskSequenceReleaseALTERA: return "OpTaskSequenceReleaseALTERA";
case OpTypeTaskSequenceALTERA: return "OpTypeTaskSequenceALTERA";
case OpSubgroupBlockPrefetchINTEL: return "OpSubgroupBlockPrefetchINTEL";
case OpSubgroup2DBlockLoadINTEL: return "OpSubgroup2DBlockLoadINTEL";
case OpSubgroup2DBlockLoadTransformINTEL: return "OpSubgroup2DBlockLoadTransformINTEL";

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more