Merge pull request #114075 from akien-mga/vulkan-sdk-1.4.335.0
Vulkan: Update all components to Vulkan SDK 1.4.335.0
This commit is contained in:
commit
cb04441dad
174 changed files with 227554 additions and 110637 deletions
|
|
@ -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,19 +618,19 @@ 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
|
||||
Comment: Vulkan Memory Allocator
|
||||
Copyright: 2017-2024, Advanced Micro Devices, Inc.
|
||||
Copyright: 2017-2025, Advanced Micro Devices, Inc.
|
||||
License: Expat
|
||||
|
||||
Files: thirdparty/wayland/*
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ elif env["platform"] == "windows":
|
|||
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_WIN32_KHR"])
|
||||
|
||||
# Build Vulkan memory allocator and volk
|
||||
|
||||
# We don't use it for now, and it depends on Windows APIs.
|
||||
env.AppendUnique(CPPDEFINES=["VMA_EXTERNAL_MEMORY_WIN32=0"])
|
||||
|
||||
env_thirdparty_vma = env.Clone()
|
||||
env_thirdparty_vma.disable_warnings()
|
||||
thirdparty_sources_vma = [thirdparty_dir + "/vk_mem_alloc.cpp"]
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ if env["builtin_glslang"]:
|
|||
"SPIRV/Logger.cpp",
|
||||
"SPIRV/SpvBuilder.cpp",
|
||||
"SPIRV/SpvPostProcess.cpp",
|
||||
"SPIRV/SPVRemapper.cpp",
|
||||
"SPIRV/SpvTools.cpp",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1249,7 +1249,6 @@ void CopyEffects::octmap_filter(RID p_source_octmap, const Vector<RID> &p_dest_o
|
|||
OctmapFilterPushConstant push_constant;
|
||||
push_constant.border_size[0] = p_border_size;
|
||||
push_constant.border_size[1] = 1.0f - p_border_size * 2.0f;
|
||||
push_constant.size = 320;
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
for (int i = 0; i < p_dest_octmap.size(); i++) {
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ private:
|
|||
|
||||
struct CopyToOctmapPushConstant {
|
||||
float border_size;
|
||||
float pad[3];
|
||||
uint32_t pad[3];
|
||||
};
|
||||
|
||||
struct CopyToOctmap {
|
||||
|
|
@ -282,8 +282,8 @@ private:
|
|||
|
||||
struct OctmapFilterPushConstant {
|
||||
float border_size[2];
|
||||
uint32_t size;
|
||||
uint32_t pad;
|
||||
uint32_t pad1;
|
||||
uint32_t pad2;
|
||||
};
|
||||
|
||||
struct OctmapFilterRasterPushConstant {
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ private:
|
|||
float reprojection_matrix[16];
|
||||
float resolution[2];
|
||||
uint32_t force_derive_from_depth;
|
||||
float pad;
|
||||
uint32_t pad;
|
||||
};
|
||||
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ private:
|
|||
float upscaled_height;
|
||||
float sharpness;
|
||||
int pass;
|
||||
int _unused0, _unused1;
|
||||
int pad[2];
|
||||
};
|
||||
|
||||
FsrUpscaleShaderRD fsr_shader;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ layout(set = 0, binding = 0) uniform samplerCube source_cube;
|
|||
|
||||
layout(push_constant, std430) uniform Params {
|
||||
float border_size;
|
||||
uint pad1;
|
||||
uint pad2;
|
||||
uint pad3;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ layout(push_constant, std430) uniform Params {
|
|||
float upscaled_height;
|
||||
float sharpness;
|
||||
int pass;
|
||||
int pad1;
|
||||
int pad2;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ layout(location = 0) out vec4 frag_color;
|
|||
layout(push_constant, std430) uniform Params {
|
||||
highp mat4 reprojection_matrix;
|
||||
vec2 resolution;
|
||||
bool force_derive_from_depth;
|
||||
uint force_derive_from_depth;
|
||||
uint pad;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ void main() {
|
|||
vec2 cell_pos_pixel = floor(pos_pixel / cell_size) * cell_size + (cell_size * 0.5f);
|
||||
vec2 cell_pos_uv = cell_pos_pixel / params.resolution;
|
||||
vec2 cell_pos_velocity = textureLod(source_velocity, cell_pos_uv, 0.0f).xy;
|
||||
bool derive_velocity = params.force_derive_from_depth || all(lessThanEqual(cell_pos_velocity, vec2(-1.0f, -1.0f)));
|
||||
bool derive_velocity = bool(params.force_derive_from_depth) || all(lessThanEqual(cell_pos_velocity, vec2(-1.0f, -1.0f)));
|
||||
if (derive_velocity) {
|
||||
float depth = textureLod(source_depth, cell_pos_uv, 0.0f).x;
|
||||
cell_pos_velocity = derive_motion_vector(cell_pos_uv, depth, params.reprojection_matrix);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ layout(OCTMAP_FORMAT, set = 1, binding = 0) uniform restrict writeonly image2D d
|
|||
layout(push_constant, std430) uniform Params {
|
||||
float border_size;
|
||||
uint size;
|
||||
uint pad;
|
||||
uint pad1;
|
||||
uint pad2;
|
||||
}
|
||||
params;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,10 @@
|
|||
#include "../oct_inc.glsl"
|
||||
|
||||
layout(push_constant, std430) uniform Params {
|
||||
float border_size;
|
||||
uint size;
|
||||
uint pad1;
|
||||
uint pad2;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
@ -64,7 +67,10 @@ void main() {
|
|||
#include "../oct_inc.glsl"
|
||||
|
||||
layout(push_constant, std430) uniform Params {
|
||||
float border_size;
|
||||
uint size;
|
||||
uint pad1;
|
||||
uint pad2;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ layout(push_constant, std430) uniform Params {
|
|||
float depth_tolerance;
|
||||
bool orthogonal;
|
||||
int view_index;
|
||||
int pad1;
|
||||
int pad2;
|
||||
int pad3;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ layout(rgba8, set = 0, binding = 3) uniform restrict writeonly image2D dest_norm
|
|||
|
||||
layout(push_constant, std430) uniform Params {
|
||||
ivec2 screen_size;
|
||||
ivec2 pad;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ layout(set = 0, binding = 1) uniform restrict writeonly image2D dest;
|
|||
layout(push_constant, std430) uniform Params {
|
||||
ivec2 screen_size;
|
||||
uint mip_level;
|
||||
int pad;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ layout(r32f, set = 0, binding = 1) uniform restrict writeonly image2D dest;
|
|||
|
||||
layout(push_constant, std430) uniform Params {
|
||||
ivec2 screen_size;
|
||||
ivec2 pad;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ layout(rgba16f, set = 0, binding = 6) uniform restrict writeonly image2D output_
|
|||
|
||||
layout(push_constant, std430) uniform Params {
|
||||
ivec2 screen_size;
|
||||
ivec2 pad;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
|
|||
|
|
@ -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++) {
|
||||
|
|
|
|||
33
thirdparty/README.md
vendored
33
thirdparty/README.md
vendored
|
|
@ -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:
|
||||
|
|
@ -1160,7 +1163,7 @@ Files extracted from upstream source:
|
|||
SDK release: https://github.com/KhronosGroup/Vulkan-Utility-Libraries/blob/main/include/vulkan/vk_enum_string_helper.h
|
||||
|
||||
`vk_mem_alloc.h` is taken from https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
|
||||
Version: 3.1.0 (009ecd192c1289c7529bff248a16cfe896254816, 2024)
|
||||
Version: 3.3.0 (1d8f600fd424278486eade7ed3e877c99f0846b1, 2025)
|
||||
`vk_mem_alloc.cpp` is a Godot file and should be preserved on updates.
|
||||
|
||||
Patches:
|
||||
|
|
|
|||
3
thirdparty/glslang/LICENSE.txt
vendored
3
thirdparty/glslang/LICENSE.txt
vendored
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
8
thirdparty/glslang/SPIRV/GLSL.ext.ARM.h
vendored
8
thirdparty/glslang/SPIRV/GLSL.ext.ARM.h
vendored
|
|
@ -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
|
||||
|
|
|
|||
3
thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
vendored
3
thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
vendored
|
|
@ -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
|
||||
|
|
|
|||
5
thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
vendored
5
thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
vendored
|
|
@ -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
|
||||
|
|
|
|||
19
thirdparty/glslang/SPIRV/GLSL.ext.NV.h
vendored
19
thirdparty/glslang/SPIRV/GLSL.ext.NV.h
vendored
|
|
@ -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
|
||||
|
|
|
|||
13
thirdparty/glslang/SPIRV/GLSL.ext.QCOM.h
vendored
13
thirdparty/glslang/SPIRV/GLSL.ext.QCOM.h
vendored
|
|
@ -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
|
||||
|
|
|
|||
4807
thirdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
4807
thirdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
File diff suppressed because it is too large
Load diff
18
thirdparty/glslang/SPIRV/GlslangToSpv.h
vendored
18
thirdparty/glslang/SPIRV/GlslangToSpv.h
vendored
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
2
thirdparty/glslang/SPIRV/InReadableOrder.cpp
vendored
2
thirdparty/glslang/SPIRV/InReadableOrder.cpp
vendored
|
|
@ -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();
|
||||
|
|
|
|||
3
thirdparty/glslang/SPIRV/Logger.h
vendored
3
thirdparty/glslang/SPIRV/Logger.h
vendored
|
|
@ -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() {}
|
||||
|
||||
|
|
|
|||
1527
thirdparty/glslang/SPIRV/SPVRemapper.cpp
vendored
1527
thirdparty/glslang/SPIRV/SPVRemapper.cpp
vendored
File diff suppressed because it is too large
Load diff
284
thirdparty/glslang/SPIRV/SPVRemapper.h
vendored
284
thirdparty/glslang/SPIRV/SPVRemapper.h
vendored
|
|
@ -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
|
||||
1818
thirdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
1818
thirdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
File diff suppressed because it is too large
Load diff
300
thirdparty/glslang/SPIRV/SpvBuilder.h
vendored
300
thirdparty/glslang/SPIRV/SpvBuilder.h
vendored
|
|
@ -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
|
||||
|
|
|
|||
369
thirdparty/glslang/SPIRV/SpvPostProcess.cpp
vendored
369
thirdparty/glslang/SPIRV/SpvPostProcess.cpp
vendored
|
|
@ -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
|
||||
|
|
|
|||
22
thirdparty/glslang/SPIRV/SpvTools.cpp
vendored
22
thirdparty/glslang/SPIRV/SpvTools.cpp
vendored
|
|
@ -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
|
||||
|
|
|
|||
45
thirdparty/glslang/SPIRV/SpvTools.h
vendored
45
thirdparty/glslang/SPIRV/SpvTools.h
vendored
|
|
@ -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
|
||||
|
||||
|
|
|
|||
194
thirdparty/glslang/SPIRV/disassemble.cpp
vendored
194
thirdparty/glslang/SPIRV/disassemble.cpp
vendored
|
|
@ -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
|
||||
|
|
|
|||
4
thirdparty/glslang/SPIRV/disassemble.h
vendored
4
thirdparty/glslang/SPIRV/disassemble.h
vendored
|
|
@ -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
|
||||
|
||||
|
|
|
|||
4571
thirdparty/glslang/SPIRV/doc.cpp
vendored
4571
thirdparty/glslang/SPIRV/doc.cpp
vendored
File diff suppressed because it is too large
Load diff
3
thirdparty/glslang/SPIRV/doc.h
vendored
3
thirdparty/glslang/SPIRV/doc.h
vendored
|
|
@ -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,
|
||||
|
||||
|
|
|
|||
117
thirdparty/glslang/SPIRV/hex_float.h
vendored
117
thirdparty/glslang/SPIRV/hex_float.h
vendored
|
|
@ -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) {
|
||||
|
|
|
|||
148
thirdparty/glslang/SPIRV/spvIR.h
vendored
148
thirdparty/glslang/SPIRV/spvIR.h
vendored
|
|
@ -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
88
thirdparty/glslang/SPIRV/spvUtil.h
vendored
Normal 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
|
||||
66
thirdparty/glslang/glslang/Include/BaseTypes.h
vendored
66
thirdparty/glslang/glslang/Include/BaseTypes.h
vendored
|
|
@ -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;
|
||||
|
|
|
|||
5
thirdparty/glslang/glslang/Include/Common.h
vendored
5
thirdparty/glslang/glslang/Include/Common.h
vendored
|
|
@ -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"
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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]; }
|
||||
|
|
|
|||
14
thirdparty/glslang/glslang/Include/InfoSink.h
vendored
14
thirdparty/glslang/glslang/Include/InfoSink.h
vendored
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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*) {
|
||||
|
|
|
|||
294
thirdparty/glslang/glslang/Include/Types.h
vendored
294
thirdparty/glslang/glslang/Include/Types.h
vendored
|
|
@ -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
|
||||
|
|
|
|||
11
thirdparty/glslang/glslang/Include/arrays.h
vendored
11
thirdparty/glslang/glslang/Include/arrays.h
vendored
|
|
@ -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; }
|
||||
|
|
|
|||
408
thirdparty/glslang/glslang/Include/intermediate.h
vendored
408
thirdparty/glslang/glslang/Include/intermediate.h
vendored
|
|
@ -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&);
|
||||
|
||||
|
|
|
|||
58
thirdparty/glslang/glslang/Include/visibility.h
vendored
Normal file
58
thirdparty/glslang/glslang/Include/visibility.h
vendored
Normal 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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
1160
thirdparty/glslang/glslang/MachineIndependent/Scan.cpp
vendored
1160
thirdparty/glslang/glslang/MachineIndependent/Scan.cpp
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
223
thirdparty/glslang/glslang/Public/ShaderLang.h
vendored
223
thirdparty/glslang/glslang/Public/ShaderLang.h
vendored
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
4
thirdparty/glslang/glslang/build_info.h
vendored
4
thirdparty/glslang/glslang/build_info.h
vendored
|
|
@ -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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
124
thirdparty/spirv-cross/spirv_cfg.cpp
vendored
124
thirdparty/spirv-cross/spirv_cfg.cpp
vendored
|
|
@ -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))
|
||||
|
|
|
|||
26
thirdparty/spirv-cross/spirv_cfg.hpp
vendored
26
thirdparty/spirv-cross/spirv_cfg.hpp
vendored
|
|
@ -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
|
||||
|
|
|
|||
61
thirdparty/spirv-cross/spirv_common.hpp
vendored
61
thirdparty/spirv-cross/spirv_common.hpp
vendored
|
|
@ -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
|
||||
|
|
|
|||
122
thirdparty/spirv-cross/spirv_cross.cpp
vendored
122
thirdparty/spirv-cross/spirv_cross.cpp
vendored
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
181
thirdparty/spirv-cross/spirv_cross.hpp
vendored
181
thirdparty/spirv-cross/spirv_cross.hpp
vendored
|
|
@ -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
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue