mirror of
https://github.com/love2d/love.git
synced 2026-08-19 20:19:42 +02:00
Update glslang
This commit is contained in:
+2
-1
@@ -1338,7 +1338,6 @@ set(LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT
|
|||||||
src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp
|
src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp
|
||||||
src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h
|
src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h
|
||||||
src/libraries/glslang/glslang/MachineIndependent/parseVersions.h
|
src/libraries/glslang/glslang/MachineIndependent/parseVersions.h
|
||||||
src/libraries/glslang/glslang/MachineIndependent/pch.cpp
|
|
||||||
src/libraries/glslang/glslang/MachineIndependent/pch.h
|
src/libraries/glslang/glslang/MachineIndependent/pch.h
|
||||||
src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp
|
src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp
|
||||||
src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp
|
src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp
|
||||||
@@ -1379,6 +1378,7 @@ set(LOVE_SRC_3P_GLSLANG_GLSLANG_PUBLIC
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(LOVE_SRC_3P_GLSLANG_GLSLANG
|
set(LOVE_SRC_3P_GLSLANG_GLSLANG
|
||||||
|
src/libraries/glslang/glslang/build_info.h
|
||||||
${LOVE_SRC_3P_GLSLANG_GLSLANG_GENERICCODEGEN}
|
${LOVE_SRC_3P_GLSLANG_GLSLANG_GENERICCODEGEN}
|
||||||
${LOVE_SRC_3P_GLSLANG_GLSLANG_INCLUDE}
|
${LOVE_SRC_3P_GLSLANG_GLSLANG_INCLUDE}
|
||||||
${LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT}
|
${LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT}
|
||||||
@@ -1408,6 +1408,7 @@ set(LOVE_SRC_3P_GLSLANG_SPIRV
|
|||||||
src/libraries/glslang/SPIRV/InReadableOrder.cpp
|
src/libraries/glslang/SPIRV/InReadableOrder.cpp
|
||||||
src/libraries/glslang/SPIRV/Logger.cpp
|
src/libraries/glslang/SPIRV/Logger.cpp
|
||||||
src/libraries/glslang/SPIRV/Logger.h
|
src/libraries/glslang/SPIRV/Logger.h
|
||||||
|
src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h
|
||||||
src/libraries/glslang/SPIRV/spirv.hpp
|
src/libraries/glslang/SPIRV/spirv.hpp
|
||||||
src/libraries/glslang/SPIRV/SpvBuilder.cpp
|
src/libraries/glslang/SPIRV/SpvBuilder.cpp
|
||||||
src/libraries/glslang/SPIRV/SpvBuilder.h
|
src/libraries/glslang/SPIRV/SpvBuilder.h
|
||||||
|
|||||||
@@ -795,8 +795,6 @@
|
|||||||
FA1E88831DF363DB00E808AA /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1E88811DF363DB00E808AA /* Filter.cpp */; };
|
FA1E88831DF363DB00E808AA /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1E88811DF363DB00E808AA /* Filter.cpp */; };
|
||||||
FA1E88841DF363DB00E808AA /* Filter.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1E88821DF363DB00E808AA /* Filter.h */; };
|
FA1E88841DF363DB00E808AA /* Filter.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1E88821DF363DB00E808AA /* Filter.h */; };
|
||||||
FA1E88851DF363E100E808AA /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1E88811DF363DB00E808AA /* Filter.cpp */; };
|
FA1E88851DF363E100E808AA /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1E88811DF363DB00E808AA /* Filter.cpp */; };
|
||||||
FA24348421D401CB00B8918A /* pch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA24348021D401CB00B8918A /* pch.cpp */; };
|
|
||||||
FA24348521D401CB00B8918A /* pch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA24348021D401CB00B8918A /* pch.cpp */; };
|
|
||||||
FA24348621D401CB00B8918A /* attribute.h in Headers */ = {isa = PBXBuildFile; fileRef = FA24348121D401CB00B8918A /* attribute.h */; };
|
FA24348621D401CB00B8918A /* attribute.h in Headers */ = {isa = PBXBuildFile; fileRef = FA24348121D401CB00B8918A /* attribute.h */; };
|
||||||
FA24348721D401CB00B8918A /* attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA24348221D401CB00B8918A /* attribute.cpp */; };
|
FA24348721D401CB00B8918A /* attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA24348221D401CB00B8918A /* attribute.cpp */; };
|
||||||
FA24348821D401CB00B8918A /* attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA24348221D401CB00B8918A /* attribute.cpp */; };
|
FA24348821D401CB00B8918A /* attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA24348221D401CB00B8918A /* attribute.cpp */; };
|
||||||
@@ -1799,7 +1797,6 @@
|
|||||||
FA1E887D1DF363CD00E808AA /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = "<group>"; };
|
FA1E887D1DF363CD00E808AA /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = "<group>"; };
|
||||||
FA1E88811DF363DB00E808AA /* Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Filter.cpp; sourceTree = "<group>"; };
|
FA1E88811DF363DB00E808AA /* Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Filter.cpp; sourceTree = "<group>"; };
|
||||||
FA1E88821DF363DB00E808AA /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = "<group>"; };
|
FA1E88821DF363DB00E808AA /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = "<group>"; };
|
||||||
FA24348021D401CB00B8918A /* pch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pch.cpp; sourceTree = "<group>"; };
|
|
||||||
FA24348121D401CB00B8918A /* attribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = attribute.h; sourceTree = "<group>"; };
|
FA24348121D401CB00B8918A /* attribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = attribute.h; sourceTree = "<group>"; };
|
||||||
FA24348221D401CB00B8918A /* attribute.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = attribute.cpp; sourceTree = "<group>"; };
|
FA24348221D401CB00B8918A /* attribute.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = attribute.cpp; sourceTree = "<group>"; };
|
||||||
FA24348321D401CB00B8918A /* pch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pch.h; sourceTree = "<group>"; };
|
FA24348321D401CB00B8918A /* pch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pch.h; sourceTree = "<group>"; };
|
||||||
@@ -2009,6 +2006,8 @@
|
|||||||
FAE272501C05A15B00A67640 /* ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = "<group>"; };
|
FAE272501C05A15B00A67640 /* ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = "<group>"; };
|
||||||
FAE272511C05A15B00A67640 /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = "<group>"; };
|
FAE272511C05A15B00A67640 /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = "<group>"; };
|
||||||
FAE64A7D2071359C00BC7981 /* libfreetype.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libfreetype.a; sourceTree = "<group>"; };
|
FAE64A7D2071359C00BC7981 /* libfreetype.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libfreetype.a; sourceTree = "<group>"; };
|
||||||
|
FAEC22942534EE6700EBD925 /* NonSemanticDebugPrintf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NonSemanticDebugPrintf.h; sourceTree = "<group>"; };
|
||||||
|
FAEC229F2534F25100EBD925 /* build_info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = build_info.h; sourceTree = "<group>"; };
|
||||||
FAECA1B01F3164700095D008 /* CompressedSlice.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedSlice.cpp; sourceTree = "<group>"; };
|
FAECA1B01F3164700095D008 /* CompressedSlice.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedSlice.cpp; sourceTree = "<group>"; };
|
||||||
FAECA1B11F3164700095D008 /* CompressedSlice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CompressedSlice.h; sourceTree = "<group>"; };
|
FAECA1B11F3164700095D008 /* CompressedSlice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CompressedSlice.h; sourceTree = "<group>"; };
|
||||||
FAF13FC21E20934C00F898D2 /* CodeGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGen.cpp; sourceTree = "<group>"; };
|
FAF13FC21E20934C00F898D2 /* CodeGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGen.cpp; sourceTree = "<group>"; };
|
||||||
@@ -3591,6 +3590,7 @@
|
|||||||
FAF13FC01E20934C00F898D2 /* glslang */ = {
|
FAF13FC01E20934C00F898D2 /* glslang */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
FAEC229F2534F25100EBD925 /* build_info.h */,
|
||||||
FAF13FC11E20934C00F898D2 /* GenericCodeGen */,
|
FAF13FC11E20934C00F898D2 /* GenericCodeGen */,
|
||||||
FAF13FC41E20934C00F898D2 /* Include */,
|
FAF13FC41E20934C00F898D2 /* Include */,
|
||||||
FAF13FD21E20934C00F898D2 /* MachineIndependent */,
|
FAF13FD21E20934C00F898D2 /* MachineIndependent */,
|
||||||
@@ -3654,7 +3654,6 @@
|
|||||||
FAF13FE61E20934C00F898D2 /* ParseHelper.cpp */,
|
FAF13FE61E20934C00F898D2 /* ParseHelper.cpp */,
|
||||||
FAF13FE71E20934C00F898D2 /* ParseHelper.h */,
|
FAF13FE71E20934C00F898D2 /* ParseHelper.h */,
|
||||||
FAF13FE81E20934C00F898D2 /* parseVersions.h */,
|
FAF13FE81E20934C00F898D2 /* parseVersions.h */,
|
||||||
FA24348021D401CB00B8918A /* pch.cpp */,
|
|
||||||
FA24348321D401CB00B8918A /* pch.h */,
|
FA24348321D401CB00B8918A /* pch.h */,
|
||||||
FAF13FE91E20934C00F898D2 /* PoolAlloc.cpp */,
|
FAF13FE91E20934C00F898D2 /* PoolAlloc.cpp */,
|
||||||
FAF13FEA1E20934C00F898D2 /* preprocessor */,
|
FAF13FEA1E20934C00F898D2 /* preprocessor */,
|
||||||
@@ -3743,6 +3742,7 @@
|
|||||||
FAF6C9C623C2DE2900D7B5BC /* InReadableOrder.cpp */,
|
FAF6C9C623C2DE2900D7B5BC /* InReadableOrder.cpp */,
|
||||||
FAF6C9D523C2DE2900D7B5BC /* Logger.cpp */,
|
FAF6C9D523C2DE2900D7B5BC /* Logger.cpp */,
|
||||||
FAF6C9D723C2DE2900D7B5BC /* Logger.h */,
|
FAF6C9D723C2DE2900D7B5BC /* Logger.h */,
|
||||||
|
FAEC22942534EE6700EBD925 /* NonSemanticDebugPrintf.h */,
|
||||||
FAF6C9C923C2DE2900D7B5BC /* spirv.hpp */,
|
FAF6C9C923C2DE2900D7B5BC /* spirv.hpp */,
|
||||||
FAF6C9CA23C2DE2900D7B5BC /* SpvBuilder.cpp */,
|
FAF6C9CA23C2DE2900D7B5BC /* SpvBuilder.cpp */,
|
||||||
FAF6C9C223C2DE2900D7B5BC /* SpvBuilder.h */,
|
FAF6C9C223C2DE2900D7B5BC /* SpvBuilder.h */,
|
||||||
@@ -4329,7 +4329,6 @@
|
|||||||
FA91DA8C1F377C3900C80E33 /* deprecation.cpp in Sources */,
|
FA91DA8C1F377C3900C80E33 /* deprecation.cpp in Sources */,
|
||||||
FA6A2B6B1F5F7F560074C308 /* DataView.cpp in Sources */,
|
FA6A2B6B1F5F7F560074C308 /* DataView.cpp in Sources */,
|
||||||
FA0B7E401A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */,
|
FA0B7E401A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */,
|
||||||
FA24348521D401CB00B8918A /* pch.cpp in Sources */,
|
|
||||||
FA0B7DEC1A95902C000E1D17 /* Cursor.cpp in Sources */,
|
FA0B7DEC1A95902C000E1D17 /* Cursor.cpp in Sources */,
|
||||||
FA0B7D871A95902C000E1D17 /* ImageData.cpp in Sources */,
|
FA0B7D871A95902C000E1D17 /* ImageData.cpp in Sources */,
|
||||||
FA0B7E101A95902C000E1D17 /* FrictionJoint.cpp in Sources */,
|
FA0B7E101A95902C000E1D17 /* FrictionJoint.cpp in Sources */,
|
||||||
@@ -4728,7 +4727,6 @@
|
|||||||
FA0B7DB71A95902C000E1D17 /* Joystick.cpp in Sources */,
|
FA0B7DB71A95902C000E1D17 /* Joystick.cpp in Sources */,
|
||||||
FA0B7A321A958EA3000E1D17 /* b2Collision.cpp in Sources */,
|
FA0B7A321A958EA3000E1D17 /* b2Collision.cpp in Sources */,
|
||||||
FA91DA8B1F377C3900C80E33 /* deprecation.cpp in Sources */,
|
FA91DA8B1F377C3900C80E33 /* deprecation.cpp in Sources */,
|
||||||
FA24348421D401CB00B8918A /* pch.cpp in Sources */,
|
|
||||||
FA0B7E3F1A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */,
|
FA0B7E3F1A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */,
|
||||||
FA0B7DEB1A95902C000E1D17 /* Cursor.cpp in Sources */,
|
FA0B7DEB1A95902C000E1D17 /* Cursor.cpp in Sources */,
|
||||||
FA0B7D861A95902C000E1D17 /* ImageData.cpp in Sources */,
|
FA0B7D861A95902C000E1D17 /* ImageData.cpp in Sources */,
|
||||||
|
|||||||
@@ -35,5 +35,6 @@ static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shade
|
|||||||
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
|
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
|
||||||
static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
|
static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
|
||||||
static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation";
|
static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation";
|
||||||
|
static const char* const E_SPV_EXT_shader_atomic_float_add = "SPV_EXT_shader_atomic_float_add";
|
||||||
|
|
||||||
#endif // #ifndef GLSLextEXT_H
|
#endif // #ifndef GLSLextEXT_H
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright (c) 2014-2016 The Khronos Group Inc.
|
** Copyright (c) 2014-2020 The Khronos Group Inc.
|
||||||
|
** Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
**
|
**
|
||||||
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
** of this software and/or associated documentation files (the "Materials"),
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
@@ -44,5 +45,7 @@ static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physi
|
|||||||
static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer";
|
static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer";
|
||||||
static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock";
|
static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock";
|
||||||
static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock";
|
static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock";
|
||||||
|
static const char* const E_SPV_KHR_non_semantic_info = "SPV_KHR_non_semantic_info";
|
||||||
|
static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_tracing";
|
||||||
|
static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query";
|
||||||
#endif // #ifndef GLSLextKHR_H
|
#endif // #ifndef GLSLextKHR_H
|
||||||
|
|||||||
Executable → Regular
+711
-274
File diff suppressed because it is too large
Load Diff
Executable → Regular
@@ -69,4 +69,4 @@ std::string SpvBuildLogger::getAllMessages() const {
|
|||||||
|
|
||||||
} // end spv namespace
|
} // end spv namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (c) 2020 The Khronos Group Inc.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and/or associated documentation files (the
|
||||||
|
// "Materials"), to deal in the Materials without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
// permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included
|
||||||
|
// in all copies or substantial portions of the Materials.
|
||||||
|
//
|
||||||
|
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
|
||||||
|
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
|
||||||
|
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
|
||||||
|
// https://www.khronos.org/registry/
|
||||||
|
//
|
||||||
|
// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
|
||||||
|
#define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NonSemanticDebugPrintfRevision = 1,
|
||||||
|
NonSemanticDebugPrintfRevision_BitWidthPadding = 0x7fffffff
|
||||||
|
};
|
||||||
|
|
||||||
|
enum NonSemanticDebugPrintfInstructions {
|
||||||
|
NonSemanticDebugPrintfDebugPrintf = 1,
|
||||||
|
NonSemanticDebugPrintfInstructionsMax = 0x7fffffff
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
|
||||||
@@ -625,6 +625,9 @@ namespace spv {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case spv::OperandVariableLiteralStrings:
|
||||||
|
return nextInst;
|
||||||
|
|
||||||
// Execution mode might have extra literal operands. Skip them.
|
// Execution mode might have extra literal operands. Skip them.
|
||||||
case spv::OperandExecutionMode:
|
case spv::OperandExecutionMode:
|
||||||
return nextInst;
|
return nextInst;
|
||||||
@@ -827,7 +830,15 @@ namespace spv {
|
|||||||
[&](spv::Id& id) {
|
[&](spv::Id& id) {
|
||||||
if (thisOpCode != spv::OpNop) {
|
if (thisOpCode != spv::OpNop) {
|
||||||
++idCounter;
|
++idCounter;
|
||||||
const std::uint32_t hashval = opCounter[thisOpCode] * thisOpCode * 50047 + idCounter + fnId * 117;
|
const std::uint32_t hashval =
|
||||||
|
// Explicitly cast operands to unsigned int to avoid integer
|
||||||
|
// promotion to signed int followed by integer overflow,
|
||||||
|
// which would result in undefined behavior.
|
||||||
|
static_cast<unsigned int>(opCounter[thisOpCode])
|
||||||
|
* thisOpCode
|
||||||
|
* 50047
|
||||||
|
+ idCounter
|
||||||
|
+ static_cast<unsigned int>(fnId) * 117;
|
||||||
|
|
||||||
if (isOldIdUnmapped(id))
|
if (isOldIdUnmapped(id))
|
||||||
localId(id, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
|
localId(id, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -496,7 +497,8 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
|
|||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format)
|
Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled,
|
||||||
|
ImageFormat format)
|
||||||
{
|
{
|
||||||
assert(sampled == 1 || sampled == 2);
|
assert(sampled == 1 || sampled == 2);
|
||||||
|
|
||||||
@@ -601,16 +603,31 @@ Id Builder::makeSampledImageType(Id imageType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
Id Builder::makeAccelerationStructureNVType()
|
Id Builder::makeAccelerationStructureType()
|
||||||
{
|
{
|
||||||
Instruction *type;
|
Instruction *type;
|
||||||
if (groupedTypes[OpTypeAccelerationStructureNV].size() == 0) {
|
if (groupedTypes[OpTypeAccelerationStructureKHR].size() == 0) {
|
||||||
type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureNV);
|
type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureKHR);
|
||||||
groupedTypes[OpTypeAccelerationStructureNV].push_back(type);
|
groupedTypes[OpTypeAccelerationStructureKHR].push_back(type);
|
||||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||||
module.mapInstruction(type);
|
module.mapInstruction(type);
|
||||||
} else {
|
} else {
|
||||||
type = groupedTypes[OpTypeAccelerationStructureNV].back();
|
type = groupedTypes[OpTypeAccelerationStructureKHR].back();
|
||||||
|
}
|
||||||
|
|
||||||
|
return type->getResultId();
|
||||||
|
}
|
||||||
|
|
||||||
|
Id Builder::makeRayQueryType()
|
||||||
|
{
|
||||||
|
Instruction *type;
|
||||||
|
if (groupedTypes[OpTypeRayQueryProvisionalKHR].size() == 0) {
|
||||||
|
type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryProvisionalKHR);
|
||||||
|
groupedTypes[OpTypeRayQueryProvisionalKHR].push_back(type);
|
||||||
|
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||||
|
module.mapInstruction(type);
|
||||||
|
} else {
|
||||||
|
type = groupedTypes[OpTypeRayQueryProvisionalKHR].back();
|
||||||
}
|
}
|
||||||
|
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
@@ -1166,6 +1183,28 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int val
|
|||||||
executionModes.push_back(std::unique_ptr<Instruction>(instr));
|
executionModes.push_back(std::unique_ptr<Instruction>(instr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const std::vector<unsigned>& literals)
|
||||||
|
{
|
||||||
|
Instruction* instr = new Instruction(OpExecutionMode);
|
||||||
|
instr->addIdOperand(entryPoint->getId());
|
||||||
|
instr->addImmediateOperand(mode);
|
||||||
|
for (auto literal : literals)
|
||||||
|
instr->addImmediateOperand(literal);
|
||||||
|
|
||||||
|
executionModes.push_back(std::unique_ptr<Instruction>(instr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, const std::vector<Id>& operandIds)
|
||||||
|
{
|
||||||
|
Instruction* instr = new Instruction(OpExecutionModeId);
|
||||||
|
instr->addIdOperand(entryPoint->getId());
|
||||||
|
instr->addImmediateOperand(mode);
|
||||||
|
for (auto operandId : operandIds)
|
||||||
|
instr->addIdOperand(operandId);
|
||||||
|
|
||||||
|
executionModes.push_back(std::unique_ptr<Instruction>(instr));
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::addName(Id id, const char* string)
|
void Builder::addName(Id id, const char* string)
|
||||||
{
|
{
|
||||||
Instruction* name = new Instruction(OpName);
|
Instruction* name = new Instruction(OpName);
|
||||||
@@ -1204,7 +1243,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s)
|
|||||||
if (decoration == spv::DecorationMax)
|
if (decoration == spv::DecorationMax)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Instruction* dec = new Instruction(OpDecorateStringGOOGLE);
|
Instruction* dec = new Instruction(OpDecorateString);
|
||||||
dec->addIdOperand(id);
|
dec->addIdOperand(id);
|
||||||
dec->addImmediateOperand(decoration);
|
dec->addImmediateOperand(decoration);
|
||||||
dec->addStringOperand(s);
|
dec->addStringOperand(s);
|
||||||
@@ -1212,6 +1251,34 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s)
|
|||||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::addDecoration(Id id, Decoration decoration, const std::vector<unsigned>& literals)
|
||||||
|
{
|
||||||
|
if (decoration == spv::DecorationMax)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Instruction* dec = new Instruction(OpDecorate);
|
||||||
|
dec->addIdOperand(id);
|
||||||
|
dec->addImmediateOperand(decoration);
|
||||||
|
for (auto literal : literals)
|
||||||
|
dec->addImmediateOperand(literal);
|
||||||
|
|
||||||
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::addDecoration(Id id, Decoration decoration, const std::vector<const char*>& strings)
|
||||||
|
{
|
||||||
|
if (decoration == spv::DecorationMax)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Instruction* dec = new Instruction(OpDecorateString);
|
||||||
|
dec->addIdOperand(id);
|
||||||
|
dec->addImmediateOperand(decoration);
|
||||||
|
for (auto string : strings)
|
||||||
|
dec->addStringOperand(string);
|
||||||
|
|
||||||
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
|
void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
|
||||||
{
|
{
|
||||||
if (decoration == spv::DecorationMax)
|
if (decoration == spv::DecorationMax)
|
||||||
@@ -1225,6 +1292,21 @@ void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
|
|||||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::addDecorationId(Id id, Decoration decoration, const std::vector<Id>& operandIds)
|
||||||
|
{
|
||||||
|
if(decoration == spv::DecorationMax)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Instruction* dec = new Instruction(OpDecorateId);
|
||||||
|
dec->addIdOperand(id);
|
||||||
|
dec->addImmediateOperand(decoration);
|
||||||
|
|
||||||
|
for (auto operandId : operandIds)
|
||||||
|
dec->addIdOperand(operandId);
|
||||||
|
|
||||||
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
|
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
|
||||||
{
|
{
|
||||||
if (decoration == spv::DecorationMax)
|
if (decoration == spv::DecorationMax)
|
||||||
@@ -1254,6 +1336,36 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
|
|||||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<unsigned>& literals)
|
||||||
|
{
|
||||||
|
if (decoration == spv::DecorationMax)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Instruction* dec = new Instruction(OpMemberDecorate);
|
||||||
|
dec->addIdOperand(id);
|
||||||
|
dec->addImmediateOperand(member);
|
||||||
|
dec->addImmediateOperand(decoration);
|
||||||
|
for (auto literal : literals)
|
||||||
|
dec->addImmediateOperand(literal);
|
||||||
|
|
||||||
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<const char*>& strings)
|
||||||
|
{
|
||||||
|
if (decoration == spv::DecorationMax)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Instruction* dec = new Instruction(OpMemberDecorateString);
|
||||||
|
dec->addIdOperand(id);
|
||||||
|
dec->addImmediateOperand(member);
|
||||||
|
dec->addImmediateOperand(decoration);
|
||||||
|
for (auto string : strings)
|
||||||
|
dec->addStringOperand(string);
|
||||||
|
|
||||||
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Function* Builder::makeEntryPoint(const char* entryPoint)
|
Function* Builder::makeEntryPoint(const char* entryPoint)
|
||||||
{
|
{
|
||||||
@@ -1270,7 +1382,8 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
|
|||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
|
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
|
||||||
const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& decorations, Block **entry)
|
const std::vector<Id>& paramTypes,
|
||||||
|
const std::vector<std::vector<Decoration>>& decorations, Block **entry)
|
||||||
{
|
{
|
||||||
// Make the function and initial instructions in it
|
// Make the function and initial instructions in it
|
||||||
Id typeId = makeFunctionType(returnType, paramTypes);
|
Id typeId = makeFunctionType(returnType, paramTypes);
|
||||||
@@ -1279,9 +1392,12 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
|
|||||||
|
|
||||||
// Set up the precisions
|
// Set up the precisions
|
||||||
setPrecision(function->getId(), precision);
|
setPrecision(function->getId(), precision);
|
||||||
|
function->setReturnPrecision(precision);
|
||||||
for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) {
|
for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) {
|
||||||
for (int d = 0; d < (int)decorations[p].size(); ++d)
|
for (int d = 0; d < (int)decorations[p].size(); ++d) {
|
||||||
addDecoration(firstParamId + p, decorations[p][d]);
|
addDecoration(firstParamId + p, decorations[p][d]);
|
||||||
|
function->addParamPrecision(p, decorations[p][d]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CFG
|
// CFG
|
||||||
@@ -1338,7 +1454,7 @@ void Builder::makeDiscard()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Id Builder::createVariable(StorageClass storageClass, Id type, const char* name, Id initializer)
|
Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name, Id initializer)
|
||||||
{
|
{
|
||||||
Id pointerType = makePointer(storageClass, type);
|
Id pointerType = makePointer(storageClass, type);
|
||||||
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
|
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
|
||||||
@@ -1360,6 +1476,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name,
|
|||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
addName(inst->getResultId(), name);
|
addName(inst->getResultId(), name);
|
||||||
|
setPrecision(inst->getResultId(), precision);
|
||||||
|
|
||||||
return inst->getResultId();
|
return inst->getResultId();
|
||||||
}
|
}
|
||||||
@@ -1373,7 +1490,8 @@ Id Builder::createUndefined(Id type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// av/vis/nonprivate are unnecessary and illegal for some storage classes.
|
// av/vis/nonprivate are unnecessary and illegal for some storage classes.
|
||||||
spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const
|
spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
|
||||||
|
const
|
||||||
{
|
{
|
||||||
switch (sc) {
|
switch (sc) {
|
||||||
case spv::StorageClassUniform:
|
case spv::StorageClassUniform:
|
||||||
@@ -1392,7 +1510,8 @@ spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
|
void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope,
|
||||||
|
unsigned int alignment)
|
||||||
{
|
{
|
||||||
Instruction* store = new Instruction(OpStore);
|
Instruction* store = new Instruction(OpStore);
|
||||||
store->addIdOperand(lValue);
|
store->addIdOperand(lValue);
|
||||||
@@ -1414,7 +1533,8 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
|
Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMask memoryAccess,
|
||||||
|
spv::Scope scope, unsigned int alignment)
|
||||||
{
|
{
|
||||||
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
|
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
|
||||||
load->addIdOperand(lValue);
|
load->addIdOperand(lValue);
|
||||||
@@ -1432,6 +1552,7 @@ Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
|
||||||
|
setPrecision(load->getResultId(), precision);
|
||||||
|
|
||||||
return load->getResultId();
|
return load->getResultId();
|
||||||
}
|
}
|
||||||
@@ -1495,7 +1616,8 @@ Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index)
|
|||||||
// Generate code for spec constants if in spec constant operation
|
// Generate code for spec constants if in spec constant operation
|
||||||
// generation mode.
|
// generation mode.
|
||||||
if (generatingOpCodeForSpecConst) {
|
if (generatingOpCodeForSpecConst) {
|
||||||
return createSpecConstantOp(OpCompositeExtract, typeId, std::vector<Id>(1, composite), std::vector<Id>(1, index));
|
return createSpecConstantOp(OpCompositeExtract, typeId, std::vector<Id>(1, composite),
|
||||||
|
std::vector<Id>(1, index));
|
||||||
}
|
}
|
||||||
Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);
|
Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);
|
||||||
extract->addIdOperand(composite);
|
extract->addIdOperand(composite);
|
||||||
@@ -1697,7 +1819,8 @@ Id Builder::createOp(Op opCode, Id typeId, const std::vector<IdImmediate>& opera
|
|||||||
return op->getResultId();
|
return op->getResultId();
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands, const std::vector<unsigned>& literals)
|
Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands,
|
||||||
|
const std::vector<unsigned>& literals)
|
||||||
{
|
{
|
||||||
Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp);
|
Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp);
|
||||||
op->addImmediateOperand((unsigned) opCode);
|
op->addImmediateOperand((unsigned) opCode);
|
||||||
@@ -2144,7 +2267,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
|
|||||||
Op op;
|
Op op;
|
||||||
switch (getMostBasicTypeClass(valueType)) {
|
switch (getMostBasicTypeClass(valueType)) {
|
||||||
case OpTypeFloat:
|
case OpTypeFloat:
|
||||||
op = equal ? OpFOrdEqual : OpFOrdNotEqual;
|
op = equal ? OpFOrdEqual : OpFUnordNotEqual;
|
||||||
break;
|
break;
|
||||||
case OpTypeInt:
|
case OpTypeInt:
|
||||||
default:
|
default:
|
||||||
@@ -2187,7 +2310,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
|
|||||||
if (constituent == 0)
|
if (constituent == 0)
|
||||||
resultId = subResultId;
|
resultId = subResultId;
|
||||||
else
|
else
|
||||||
resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), precision);
|
resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId),
|
||||||
|
precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultId;
|
return resultId;
|
||||||
@@ -2196,7 +2320,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
|
|||||||
// OpCompositeConstruct
|
// OpCompositeConstruct
|
||||||
Id Builder::createCompositeConstruct(Id typeId, const std::vector<Id>& constituents)
|
Id Builder::createCompositeConstruct(Id typeId, const std::vector<Id>& constituents)
|
||||||
{
|
{
|
||||||
assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && getNumTypeConstituents(typeId) == (int)constituents.size()));
|
assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 &&
|
||||||
|
getNumTypeConstituents(typeId) == (int)constituents.size()));
|
||||||
|
|
||||||
if (generatingOpCodeForSpecConst) {
|
if (generatingOpCodeForSpecConst) {
|
||||||
// Sometime, even in spec-constant-op mode, the constant composite to be
|
// Sometime, even in spec-constant-op mode, the constant composite to be
|
||||||
@@ -2609,7 +2734,8 @@ void Builder::clearAccessChain()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType,
|
||||||
|
AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
||||||
{
|
{
|
||||||
accessChain.coherentFlags |= coherentFlags;
|
accessChain.coherentFlags |= coherentFlags;
|
||||||
accessChain.alignment |= alignment;
|
accessChain.alignment |= alignment;
|
||||||
@@ -2649,7 +2775,7 @@ void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, sp
|
|||||||
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
|
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
|
||||||
// extract and insert elements to perform writeMask and/or swizzle.
|
// extract and insert elements to perform writeMask and/or swizzle.
|
||||||
if (accessChain.swizzle.size() > 0) {
|
if (accessChain.swizzle.size() > 0) {
|
||||||
Id tempBaseId = createLoad(base);
|
Id tempBaseId = createLoad(base, spv::NoPrecision);
|
||||||
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2663,7 +2789,8 @@ void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, sp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
|
Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType,
|
||||||
|
spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
|
||||||
{
|
{
|
||||||
Id id;
|
Id id;
|
||||||
|
|
||||||
@@ -2687,17 +2814,19 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
|||||||
|
|
||||||
if (constant) {
|
if (constant) {
|
||||||
id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
|
id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
|
||||||
|
setPrecision(id, precision);
|
||||||
} else {
|
} else {
|
||||||
Id lValue = NoResult;
|
Id lValue = NoResult;
|
||||||
if (spvVersion >= Spv_1_4) {
|
if (spvVersion >= Spv_1_4 && isValidInitializer(accessChain.base)) {
|
||||||
// make a new function variable for this r-value, using an initializer,
|
// make a new function variable for this r-value, using an initializer,
|
||||||
// and mark it as NonWritable so that downstream it can be detected as a lookup
|
// and mark it as NonWritable so that downstream it can be detected as a lookup
|
||||||
// table
|
// table
|
||||||
lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable",
|
lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base),
|
||||||
accessChain.base);
|
"indexable", accessChain.base);
|
||||||
addDecoration(lValue, DecorationNonWritable);
|
addDecoration(lValue, DecorationNonWritable);
|
||||||
} else {
|
} else {
|
||||||
lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
|
lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base),
|
||||||
|
"indexable");
|
||||||
// store into it
|
// store into it
|
||||||
createStore(accessChain.base, lValue);
|
createStore(accessChain.base, lValue);
|
||||||
}
|
}
|
||||||
@@ -2706,9 +2835,8 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
|||||||
accessChain.isRValue = false;
|
accessChain.isRValue = false;
|
||||||
|
|
||||||
// load through the access chain
|
// load through the access chain
|
||||||
id = createLoad(collapseAccessChain());
|
id = createLoad(collapseAccessChain(), precision);
|
||||||
}
|
}
|
||||||
setPrecision(id, precision);
|
|
||||||
} else
|
} else
|
||||||
id = accessChain.base; // no precision, it was set when this was defined
|
id = accessChain.base; // no precision, it was set when this was defined
|
||||||
} else {
|
} else {
|
||||||
@@ -2721,8 +2849,13 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load through the access chain
|
// load through the access chain
|
||||||
id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment);
|
id = collapseAccessChain();
|
||||||
setPrecision(id, precision);
|
// Apply nonuniform both to the access chain and the loaded value.
|
||||||
|
// Buffer accesses need the access chain decorated, and this is where
|
||||||
|
// loaded image types get decorated. TODO: This should maybe move to
|
||||||
|
// createImageTextureFunctionCall.
|
||||||
|
addDecoration(id, nonUniform);
|
||||||
|
id = createLoad(id, precision, memoryAccess, scope, alignment);
|
||||||
addDecoration(id, nonUniform);
|
addDecoration(id, nonUniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3075,7 +3208,8 @@ void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
|
|||||||
dumpSourceInstructions(iItr->first, *iItr->second, out);
|
dumpSourceInstructions(iItr->first, *iItr->second, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector<std::unique_ptr<Instruction> >& instructions) const
|
void Builder::dumpInstructions(std::vector<unsigned int>& out,
|
||||||
|
const std::vector<std::unique_ptr<Instruction> >& instructions) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)instructions.size(); ++i) {
|
for (int i = 0; i < (int)instructions.size(); ++i) {
|
||||||
instructions[i]->dump(out);
|
instructions[i]->dump(out);
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2020 Google, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -94,6 +95,7 @@ public:
|
|||||||
const char* file_c_str = str.c_str();
|
const char* file_c_str = str.c_str();
|
||||||
fileString->addStringOperand(file_c_str);
|
fileString->addStringOperand(file_c_str);
|
||||||
strings.push_back(std::unique_ptr<Instruction>(fileString));
|
strings.push_back(std::unique_ptr<Instruction>(fileString));
|
||||||
|
module.mapInstruction(fileString);
|
||||||
stringIds[file_c_str] = strId;
|
stringIds[file_c_str] = strId;
|
||||||
return strId;
|
return strId;
|
||||||
}
|
}
|
||||||
@@ -181,7 +183,9 @@ public:
|
|||||||
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
|
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
|
||||||
|
|
||||||
// accelerationStructureNV type
|
// accelerationStructureNV type
|
||||||
Id makeAccelerationStructureNVType();
|
Id makeAccelerationStructureType();
|
||||||
|
// rayQueryEXT type
|
||||||
|
Id makeRayQueryType();
|
||||||
|
|
||||||
// For querying about types.
|
// For querying about types.
|
||||||
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
|
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
|
||||||
@@ -196,7 +200,8 @@ public:
|
|||||||
Id getContainedTypeId(Id typeId) const;
|
Id getContainedTypeId(Id typeId) const;
|
||||||
Id getContainedTypeId(Id typeId, int) const;
|
Id getContainedTypeId(Id typeId, int) const;
|
||||||
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
|
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
|
||||||
ImageFormat getImageTypeFormat(Id typeId) const { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
|
ImageFormat getImageTypeFormat(Id typeId) const
|
||||||
|
{ return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
|
||||||
|
|
||||||
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
|
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
|
||||||
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
|
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
|
||||||
@@ -206,12 +211,17 @@ public:
|
|||||||
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
|
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
|
||||||
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
|
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
|
||||||
|
|
||||||
bool isBoolType(Id typeId) { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
|
bool isBoolType(Id typeId)
|
||||||
bool isIntType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
|
{ return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
|
||||||
bool isUintType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
|
bool isIntType(Id typeId) const
|
||||||
|
{ return getTypeClass(typeId) == 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 isFloatType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat; }
|
||||||
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
|
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
|
||||||
bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; }
|
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 isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
|
||||||
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
|
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
|
||||||
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
|
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
|
||||||
@@ -221,7 +231,8 @@ public:
|
|||||||
#else
|
#else
|
||||||
bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; }
|
bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; }
|
||||||
#endif
|
#endif
|
||||||
bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
|
bool isAggregateType(Id typeId) const
|
||||||
|
{ return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
|
||||||
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
|
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
|
||||||
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
||||||
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
||||||
@@ -233,9 +244,17 @@ public:
|
|||||||
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
|
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) == OpConstant; }
|
||||||
bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
|
bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
|
||||||
unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); }
|
unsigned int getConstantScalar(Id resultId) const
|
||||||
|
{ return module.getInstruction(resultId)->getImmediateOperand(0); }
|
||||||
StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
|
StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
|
||||||
|
|
||||||
|
bool isVariableOpCode(Op opcode) const { return opcode == OpVariable; }
|
||||||
|
bool isVariable(Id resultId) const { return isVariableOpCode(getOpCode(resultId)); }
|
||||||
|
bool isGlobalStorage(Id resultId) const { return getStorageClass(resultId) != StorageClassFunction; }
|
||||||
|
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); }
|
||||||
|
|
||||||
int getScalarTypeWidth(Id typeId) const
|
int getScalarTypeWidth(Id typeId) const
|
||||||
{
|
{
|
||||||
Id scalarTypeId = getScalarTypeId(typeId);
|
Id scalarTypeId = getScalarTypeId(typeId);
|
||||||
@@ -275,14 +294,22 @@ public:
|
|||||||
|
|
||||||
// For making new constants (will return old constant if the requested one was already made).
|
// For making new constants (will return old constant if the requested one was already made).
|
||||||
Id makeBoolConstant(bool b, bool specConstant = false);
|
Id makeBoolConstant(bool b, bool specConstant = false);
|
||||||
Id makeInt8Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
|
Id makeInt8Constant(int i, bool specConstant = false)
|
||||||
Id makeUint8Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(8), u, specConstant); }
|
{ return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
|
||||||
Id makeInt16Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); }
|
Id makeUint8Constant(unsigned u, bool specConstant = false)
|
||||||
Id makeUint16Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(16), u, specConstant); }
|
{ return makeIntConstant(makeUintType(8), u, specConstant); }
|
||||||
Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
|
Id makeInt16Constant(int i, bool specConstant = false)
|
||||||
Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); }
|
{ return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); }
|
||||||
Id makeInt64Constant(long long i, bool specConstant = false) { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
|
Id makeUint16Constant(unsigned u, bool specConstant = false)
|
||||||
Id makeUint64Constant(unsigned long long u, bool specConstant = false) { return makeInt64Constant(makeUintType(64), u, specConstant); }
|
{ return makeIntConstant(makeUintType(16), u, specConstant); }
|
||||||
|
Id makeIntConstant(int i, bool specConstant = false)
|
||||||
|
{ return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
|
||||||
|
Id makeUintConstant(unsigned u, bool specConstant = false)
|
||||||
|
{ return makeIntConstant(makeUintType(32), 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)
|
||||||
|
{ return makeInt64Constant(makeUintType(64), u, specConstant); }
|
||||||
Id makeFloatConstant(float f, bool specConstant = false);
|
Id makeFloatConstant(float f, bool specConstant = false);
|
||||||
Id makeDoubleConstant(double d, bool specConstant = false);
|
Id makeDoubleConstant(double d, bool specConstant = false);
|
||||||
Id makeFloat16Constant(float f16, bool specConstant = false);
|
Id makeFloat16Constant(float f16, bool specConstant = false);
|
||||||
@@ -294,13 +321,20 @@ public:
|
|||||||
// Methods for adding information outside the CFG.
|
// Methods for adding information outside the CFG.
|
||||||
Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
|
Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
|
||||||
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
|
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
|
||||||
|
void addExecutionMode(Function*, ExecutionMode mode, const std::vector<unsigned>& literals);
|
||||||
|
void addExecutionModeId(Function*, ExecutionMode mode, const std::vector<Id>& operandIds);
|
||||||
void addName(Id, const char* name);
|
void addName(Id, const char* name);
|
||||||
void addMemberName(Id, int member, const char* name);
|
void addMemberName(Id, int member, const char* name);
|
||||||
void addDecoration(Id, Decoration, int num = -1);
|
void addDecoration(Id, Decoration, int num = -1);
|
||||||
void addDecoration(Id, Decoration, const char*);
|
void addDecoration(Id, Decoration, const char*);
|
||||||
|
void addDecoration(Id, Decoration, const std::vector<unsigned>& literals);
|
||||||
|
void addDecoration(Id, Decoration, const std::vector<const char*>& strings);
|
||||||
void addDecorationId(Id id, Decoration, Id idDecoration);
|
void addDecorationId(Id id, Decoration, Id idDecoration);
|
||||||
|
void addDecorationId(Id id, Decoration, const std::vector<Id>& operandIds);
|
||||||
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
||||||
void addMemberDecoration(Id, unsigned int member, Decoration, const char*);
|
void addMemberDecoration(Id, unsigned int member, Decoration, const char*);
|
||||||
|
void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<unsigned>& literals);
|
||||||
|
void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<const char*>& strings);
|
||||||
|
|
||||||
// At the end of what block do the next create*() instructions go?
|
// At the end of what block do the next create*() instructions go?
|
||||||
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
||||||
@@ -313,8 +347,8 @@ public:
|
|||||||
// Make a shader-style function, and create its entry block if entry is non-zero.
|
// Make a shader-style function, and create its entry block if entry is non-zero.
|
||||||
// Return the function, pass back the entry.
|
// Return the function, pass back the entry.
|
||||||
// The returned pointer is only valid for the lifetime of this builder.
|
// The returned pointer is only valid for the lifetime of this builder.
|
||||||
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector<Id>& paramTypes,
|
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name,
|
||||||
const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
|
const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
|
||||||
|
|
||||||
// Create a return. An 'implicit' return is one not appearing in the source
|
// Create a return. An 'implicit' return is one not appearing in the source
|
||||||
// code. In the case of an implicit return, no post-return block is inserted.
|
// code. In the case of an implicit return, no post-return block is inserted.
|
||||||
@@ -327,16 +361,20 @@ public:
|
|||||||
void makeDiscard();
|
void makeDiscard();
|
||||||
|
|
||||||
// Create a global or function local or IO variable.
|
// Create a global or function local or IO variable.
|
||||||
Id createVariable(StorageClass, Id type, const char* name = 0, Id initializer = NoResult);
|
Id createVariable(Decoration precision, StorageClass, Id type, const char* name = nullptr,
|
||||||
|
Id initializer = NoResult);
|
||||||
|
|
||||||
// Create an intermediate with an undefined value.
|
// Create an intermediate with an undefined value.
|
||||||
Id createUndefined(Id type);
|
Id createUndefined(Id type);
|
||||||
|
|
||||||
// Store into an Id and return the l-value
|
// 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::MemoryAccessMaskNone,
|
||||||
|
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
// Load from an Id and return it
|
// Load from an Id and return it
|
||||||
Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
Id createLoad(Id lValue, spv::Decoration precision,
|
||||||
|
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
|
||||||
|
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
// Create an OpAccessChain instruction
|
// Create an OpAccessChain instruction
|
||||||
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
||||||
@@ -495,7 +533,7 @@ public:
|
|||||||
// recursion stack can hold the memory for it.
|
// 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, unsigned int control, int numSegments, const std::vector<int>& caseValues,
|
||||||
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB); // return argument
|
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB);
|
||||||
|
|
||||||
// Add a branch to the innermost switch's merge block.
|
// Add a branch to the innermost switch's merge block.
|
||||||
void addSwitchBreak();
|
void addSwitchBreak();
|
||||||
@@ -512,7 +550,7 @@ public:
|
|||||||
Block &head, &body, &merge, &continue_target;
|
Block &head, &body, &merge, &continue_target;
|
||||||
private:
|
private:
|
||||||
LoopBlocks();
|
LoopBlocks();
|
||||||
LoopBlocks& operator=(const LoopBlocks&);
|
LoopBlocks& operator=(const LoopBlocks&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start a new loop and prepare the builder to generate code for it. Until
|
// Start a new loop and prepare the builder to generate code for it. Until
|
||||||
@@ -569,10 +607,13 @@ public:
|
|||||||
std::vector<Id> indexChain;
|
std::vector<Id> indexChain;
|
||||||
Id instr; // cache the instruction that generates this access chain
|
Id instr; // cache the instruction that generates this access chain
|
||||||
std::vector<unsigned> swizzle; // each std::vector element selects the next GLSL component number
|
std::vector<unsigned> swizzle; // each std::vector element selects the next GLSL component number
|
||||||
Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
|
Id component; // a dynamic component index, can coexist with a swizzle,
|
||||||
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
|
// done after the swizzle, NoResult if not present
|
||||||
|
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied;
|
||||||
|
// NoType unless a swizzle or component is present
|
||||||
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
|
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
|
||||||
unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment. Only tracks base and (optional) component selection alignment.
|
unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment.
|
||||||
|
// Only tracks base and (optional) component selection alignment.
|
||||||
|
|
||||||
// Accumulate whether anything in the chain of structures has coherent decorations.
|
// Accumulate whether anything in the chain of structures has coherent decorations.
|
||||||
struct CoherentFlags {
|
struct CoherentFlags {
|
||||||
@@ -583,12 +624,17 @@ public:
|
|||||||
CoherentFlags operator |=(const CoherentFlags &other) { return *this; }
|
CoherentFlags operator |=(const CoherentFlags &other) { return *this; }
|
||||||
#else
|
#else
|
||||||
bool isVolatile() const { return volatil; }
|
bool isVolatile() const { return volatil; }
|
||||||
|
bool anyCoherent() const {
|
||||||
|
return coherent || devicecoherent || queuefamilycoherent || workgroupcoherent ||
|
||||||
|
subgroupcoherent || shadercallcoherent;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned coherent : 1;
|
unsigned coherent : 1;
|
||||||
unsigned devicecoherent : 1;
|
unsigned devicecoherent : 1;
|
||||||
unsigned queuefamilycoherent : 1;
|
unsigned queuefamilycoherent : 1;
|
||||||
unsigned workgroupcoherent : 1;
|
unsigned workgroupcoherent : 1;
|
||||||
unsigned subgroupcoherent : 1;
|
unsigned subgroupcoherent : 1;
|
||||||
|
unsigned shadercallcoherent : 1;
|
||||||
unsigned nonprivate : 1;
|
unsigned nonprivate : 1;
|
||||||
unsigned volatil : 1;
|
unsigned volatil : 1;
|
||||||
unsigned isImage : 1;
|
unsigned isImage : 1;
|
||||||
@@ -599,6 +645,7 @@ public:
|
|||||||
queuefamilycoherent = 0;
|
queuefamilycoherent = 0;
|
||||||
workgroupcoherent = 0;
|
workgroupcoherent = 0;
|
||||||
subgroupcoherent = 0;
|
subgroupcoherent = 0;
|
||||||
|
shadercallcoherent = 0;
|
||||||
nonprivate = 0;
|
nonprivate = 0;
|
||||||
volatil = 0;
|
volatil = 0;
|
||||||
isImage = 0;
|
isImage = 0;
|
||||||
@@ -610,6 +657,7 @@ public:
|
|||||||
queuefamilycoherent |= other.queuefamilycoherent;
|
queuefamilycoherent |= other.queuefamilycoherent;
|
||||||
workgroupcoherent |= other.workgroupcoherent;
|
workgroupcoherent |= other.workgroupcoherent;
|
||||||
subgroupcoherent |= other.subgroupcoherent;
|
subgroupcoherent |= other.subgroupcoherent;
|
||||||
|
shadercallcoherent |= other.shadercallcoherent;
|
||||||
nonprivate |= other.nonprivate;
|
nonprivate |= other.nonprivate;
|
||||||
volatil |= other.volatil;
|
volatil |= other.volatil;
|
||||||
isImage |= other.isImage;
|
isImage |= other.isImage;
|
||||||
@@ -655,11 +703,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
||||||
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
|
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType,
|
||||||
|
AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
|
||||||
|
|
||||||
// push a dynamic component selection onto the access chain, only applicable with a
|
// push a dynamic component selection onto the access chain, only applicable with a
|
||||||
// non-trivial swizzle or no swizzle
|
// non-trivial swizzle or no swizzle
|
||||||
void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags,
|
||||||
|
unsigned int alignment)
|
||||||
{
|
{
|
||||||
if (accessChain.swizzle.size() != 1) {
|
if (accessChain.swizzle.size() != 1) {
|
||||||
accessChain.component = component;
|
accessChain.component = component;
|
||||||
@@ -671,10 +721,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use accessChain and swizzle to store value
|
// use accessChain and swizzle to store value
|
||||||
void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
|
||||||
|
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
// use accessChain and swizzle to load an r-value
|
// use accessChain and swizzle to load an r-value
|
||||||
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType,
|
||||||
|
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax,
|
||||||
|
unsigned int alignment = 0);
|
||||||
|
|
||||||
|
// Return whether or not the access chain can be represented in SPIR-V
|
||||||
|
// as an l-value.
|
||||||
|
// E.g., a[3].yx cannot be, while a[3].y and a[3].y[x] can be.
|
||||||
|
bool isSpvLvalue() const { return accessChain.swizzle.size() <= 1; }
|
||||||
|
|
||||||
// get the direct pointer for an l-value
|
// get the direct pointer for an l-value
|
||||||
Id accessChainGetLValue();
|
Id accessChainGetLValue();
|
||||||
@@ -703,7 +761,8 @@ public:
|
|||||||
|
|
||||||
void createBranch(Block* block);
|
void createBranch(Block* block);
|
||||||
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
|
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
|
||||||
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, const std::vector<unsigned int>& operands);
|
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
|
||||||
|
const std::vector<unsigned int>& operands);
|
||||||
|
|
||||||
// Sets to generate opcode for specialization constants.
|
// Sets to generate opcode for specialization constants.
|
||||||
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
|
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
|
||||||
@@ -729,7 +788,8 @@ public:
|
|||||||
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, 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;
|
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||||
void dumpModuleProcesses(std::vector<unsigned int>&) const;
|
void dumpModuleProcesses(std::vector<unsigned int>&) const;
|
||||||
spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const;
|
spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
|
||||||
|
const;
|
||||||
|
|
||||||
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
||||||
SourceLanguage source;
|
SourceLanguage source;
|
||||||
@@ -764,10 +824,14 @@ public:
|
|||||||
std::vector<std::unique_ptr<Instruction> > externals;
|
std::vector<std::unique_ptr<Instruction> > externals;
|
||||||
std::vector<std::unique_ptr<Function> > functions;
|
std::vector<std::unique_ptr<Function> > functions;
|
||||||
|
|
||||||
// not output, internally used for quick & dirty canonical (unique) creation
|
// not output, internally used for quick & dirty canonical (unique) creation
|
||||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants; // map type opcodes to constant inst.
|
|
||||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants; // map struct-id to constant instructions
|
// map type opcodes to constant inst.
|
||||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes; // map type opcodes to type instructions
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants;
|
||||||
|
// map struct-id to constant instructions
|
||||||
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
|
||||||
|
// map type opcodes to type instructions
|
||||||
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;
|
||||||
|
|
||||||
// stack of switches
|
// stack of switches
|
||||||
std::stack<Block*> switchMerges;
|
std::stack<Block*> switchMerges;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2014-2016 LunarG, Inc.
|
// Copyright (C) 2014-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2018 Google, Inc.
|
// Copyright (C) 2018-2020 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -67,6 +67,8 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
|
|||||||
logger->missingFunctionality("Target version for SPIRV-Tools validator");
|
logger->missingFunctionality("Target version for SPIRV-Tools validator");
|
||||||
return spv_target_env::SPV_ENV_VULKAN_1_1;
|
return spv_target_env::SPV_ENV_VULKAN_1_1;
|
||||||
}
|
}
|
||||||
|
case glslang::EShTargetVulkan_1_2:
|
||||||
|
return spv_target_env::SPV_ENV_VULKAN_1_2;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -78,6 +80,39 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
|
|||||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
|
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Callback passed to spvtools::Optimizer::SetMessageConsumer
|
||||||
|
void OptimizerMesssageConsumer(spv_message_level_t level, const char *source,
|
||||||
|
const spv_position_t &position, const char *message)
|
||||||
|
{
|
||||||
|
auto &out = std::cerr;
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case SPV_MSG_FATAL:
|
||||||
|
case SPV_MSG_INTERNAL_ERROR:
|
||||||
|
case SPV_MSG_ERROR:
|
||||||
|
out << "error: ";
|
||||||
|
break;
|
||||||
|
case SPV_MSG_WARNING:
|
||||||
|
out << "warning: ";
|
||||||
|
break;
|
||||||
|
case SPV_MSG_INFO:
|
||||||
|
case SPV_MSG_DEBUG:
|
||||||
|
out << "info: ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (source)
|
||||||
|
{
|
||||||
|
out << source << ":";
|
||||||
|
}
|
||||||
|
out << position.line << ":" << position.column << ":" << position.index << ":";
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
out << " " << message;
|
||||||
|
}
|
||||||
|
out << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Use the SPIRV-Tools disassembler to print SPIR-V.
|
// Use the SPIRV-Tools disassembler to print SPIR-V.
|
||||||
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
|
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
|
||||||
@@ -126,45 +161,14 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<
|
|||||||
spvContextDestroy(context);
|
spvContextDestroy(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
|
// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process.
|
||||||
// legalizing HLSL SPIR-V.
|
void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>& spirv,
|
spv::SpvBuildLogger* logger, const SpvOptions* options)
|
||||||
spv::SpvBuildLogger*, const SpvOptions* options)
|
|
||||||
{
|
{
|
||||||
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2;
|
spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger);
|
||||||
|
|
||||||
spvtools::Optimizer optimizer(target_env);
|
spvtools::Optimizer optimizer(target_env);
|
||||||
optimizer.SetMessageConsumer(
|
optimizer.SetMessageConsumer(OptimizerMesssageConsumer);
|
||||||
[](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) {
|
|
||||||
auto &out = std::cerr;
|
|
||||||
switch (level)
|
|
||||||
{
|
|
||||||
case SPV_MSG_FATAL:
|
|
||||||
case SPV_MSG_INTERNAL_ERROR:
|
|
||||||
case SPV_MSG_ERROR:
|
|
||||||
out << "error: ";
|
|
||||||
break;
|
|
||||||
case SPV_MSG_WARNING:
|
|
||||||
out << "warning: ";
|
|
||||||
break;
|
|
||||||
case SPV_MSG_INFO:
|
|
||||||
case SPV_MSG_DEBUG:
|
|
||||||
out << "info: ";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (source)
|
|
||||||
{
|
|
||||||
out << source << ":";
|
|
||||||
}
|
|
||||||
out << position.line << ":" << position.column << ":" << position.index << ":";
|
|
||||||
if (message)
|
|
||||||
{
|
|
||||||
out << " " << message;
|
|
||||||
}
|
|
||||||
out << std::endl;
|
|
||||||
});
|
|
||||||
|
|
||||||
// If debug (specifically source line info) is being generated, propagate
|
// If debug (specifically source line info) is being generated, propagate
|
||||||
// line information into all SPIR-V instructions. This avoids loss of
|
// line information into all SPIR-V instructions. This avoids loss of
|
||||||
@@ -173,6 +177,9 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>
|
|||||||
if (options->generateDebugInfo) {
|
if (options->generateDebugInfo) {
|
||||||
optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass());
|
optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass());
|
||||||
}
|
}
|
||||||
|
else if (options->stripDebugInfo) {
|
||||||
|
optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
|
||||||
|
}
|
||||||
optimizer.RegisterPass(spvtools::CreateWrapOpKillPass());
|
optimizer.RegisterPass(spvtools::CreateWrapOpKillPass());
|
||||||
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
||||||
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
|
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
|
||||||
@@ -205,7 +212,27 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>
|
|||||||
}
|
}
|
||||||
|
|
||||||
spvtools::OptimizerOptions spvOptOptions;
|
spvtools::OptimizerOptions spvOptOptions;
|
||||||
spvOptOptions.set_run_validator(false); // The validator may run as a seperate step later on
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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* logger)
|
||||||
|
{
|
||||||
|
spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger);
|
||||||
|
|
||||||
|
spvtools::Optimizer optimizer(target_env);
|
||||||
|
optimizer.SetMessageConsumer(OptimizerMesssageConsumer);
|
||||||
|
|
||||||
|
optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
|
||||||
|
|
||||||
|
spvtools::OptimizerOptions spvOptOptions;
|
||||||
|
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);
|
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,9 +52,10 @@
|
|||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
struct SpvOptions {
|
struct SpvOptions {
|
||||||
SpvOptions() : generateDebugInfo(false), disableOptimizer(true),
|
SpvOptions() : generateDebugInfo(false), stripDebugInfo(false), disableOptimizer(true),
|
||||||
optimizeSize(false), disassemble(false), validate(false) { }
|
optimizeSize(false), disassemble(false), validate(false) { }
|
||||||
bool generateDebugInfo;
|
bool generateDebugInfo;
|
||||||
|
bool stripDebugInfo;
|
||||||
bool disableOptimizer;
|
bool disableOptimizer;
|
||||||
bool optimizeSize;
|
bool optimizeSize;
|
||||||
bool disassemble;
|
bool disassemble;
|
||||||
@@ -70,10 +71,15 @@ void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& s
|
|||||||
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
spv::SpvBuildLogger*, bool prelegalization);
|
spv::SpvBuildLogger*, bool prelegalization);
|
||||||
|
|
||||||
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
|
// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process.
|
||||||
// legalizing HLSL SPIR-V.
|
void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
spv::SpvBuildLogger*, const SpvOptions*);
|
||||||
spv::SpvBuildLogger*, const SpvOptions*);
|
|
||||||
|
// 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*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,6 @@
|
|||||||
|
|
||||||
#include "disassemble.h"
|
#include "disassemble.h"
|
||||||
#include "doc.h"
|
#include "doc.h"
|
||||||
#include "SpvTools.h"
|
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -75,6 +74,7 @@ enum ExtInstSet {
|
|||||||
GLSLextAMDInst,
|
GLSLextAMDInst,
|
||||||
GLSLextNVInst,
|
GLSLextNVInst,
|
||||||
OpenCLExtInst,
|
OpenCLExtInst,
|
||||||
|
NonSemanticDebugPrintfExtInst,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Container class for a single instance of a SPIR-V stream, with methods for disassembly.
|
// Container class for a single instance of a SPIR-V stream, with methods for disassembly.
|
||||||
@@ -480,8 +480,12 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
|||||||
if (opCode == OpExtInst) {
|
if (opCode == OpExtInst) {
|
||||||
ExtInstSet extInstSet = GLSL450Inst;
|
ExtInstSet extInstSet = GLSL450Inst;
|
||||||
const char* name = idDescriptor[stream[word - 2]].c_str();
|
const char* name = idDescriptor[stream[word - 2]].c_str();
|
||||||
if (0 == memcmp("OpenCL", name, 6)) {
|
if (strcmp("OpenCL.std", name) == 0) {
|
||||||
extInstSet = OpenCLExtInst;
|
extInstSet = OpenCLExtInst;
|
||||||
|
} else if (strcmp("OpenCL.DebugInfo.100", name) == 0) {
|
||||||
|
extInstSet = OpenCLExtInst;
|
||||||
|
} else if (strcmp("NonSemantic.DebugPrintf", name) == 0) {
|
||||||
|
extInstSet = NonSemanticDebugPrintfExtInst;
|
||||||
} else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 ||
|
} else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 ||
|
||||||
strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 ||
|
strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 ||
|
||||||
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
|
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
|
||||||
@@ -505,6 +509,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
|||||||
}
|
}
|
||||||
else if (extInstSet == GLSLextNVInst) {
|
else if (extInstSet == GLSLextNVInst) {
|
||||||
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
|
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
|
||||||
|
} else if (extInstSet == NonSemanticDebugPrintfExtInst) {
|
||||||
|
out << "(DebugPrintf)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -512,6 +518,10 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
|||||||
case OperandLiteralString:
|
case OperandLiteralString:
|
||||||
numOperands -= disassembleString();
|
numOperands -= disassembleString();
|
||||||
break;
|
break;
|
||||||
|
case OperandVariableLiteralStrings:
|
||||||
|
while (numOperands > 0)
|
||||||
|
numOperands -= disassembleString();
|
||||||
|
return;
|
||||||
case OperandMemoryAccess:
|
case OperandMemoryAccess:
|
||||||
outputMask(OperandMemoryAccess, stream[word++]);
|
outputMask(OperandMemoryAccess, stream[word++]);
|
||||||
--numOperands;
|
--numOperands;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -99,12 +100,12 @@ const char* ExecutionModelString(int model)
|
|||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
|
|
||||||
case ExecutionModelRayGenerationNV: return "RayGenerationNV";
|
case ExecutionModelRayGenerationKHR: return "RayGenerationKHR";
|
||||||
case ExecutionModelIntersectionNV: return "IntersectionNV";
|
case ExecutionModelIntersectionKHR: return "IntersectionKHR";
|
||||||
case ExecutionModelAnyHitNV: return "AnyHitNV";
|
case ExecutionModelAnyHitKHR: return "AnyHitKHR";
|
||||||
case ExecutionModelClosestHitNV: return "ClosestHitNV";
|
case ExecutionModelClosestHitKHR: return "ClosestHitKHR";
|
||||||
case ExecutionModelMissNV: return "MissNV";
|
case ExecutionModelMissKHR: return "MissKHR";
|
||||||
case ExecutionModelCallableNV: return "CallableNV";
|
case ExecutionModelCallableKHR: return "CallableKHR";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +134,7 @@ const char* MemoryString(int mem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ExecutionModeCeiling = 33;
|
const int ExecutionModeCeiling = 40;
|
||||||
|
|
||||||
const char* ExecutionModeString(int mode)
|
const char* ExecutionModeString(int mode)
|
||||||
{
|
{
|
||||||
@@ -172,7 +173,21 @@ const char* ExecutionModeString(int mode)
|
|||||||
case 31: return "ContractionOff";
|
case 31: return "ContractionOff";
|
||||||
case 32: return "Bad";
|
case 32: return "Bad";
|
||||||
|
|
||||||
case 4446: return "PostDepthCoverage";
|
case ExecutionModeInitializer: return "Initializer";
|
||||||
|
case ExecutionModeFinalizer: return "Finalizer";
|
||||||
|
case ExecutionModeSubgroupSize: return "SubgroupSize";
|
||||||
|
case ExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup";
|
||||||
|
case ExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId";
|
||||||
|
case ExecutionModeLocalSizeId: return "LocalSizeId";
|
||||||
|
case ExecutionModeLocalSizeHintId: return "LocalSizeHintId";
|
||||||
|
|
||||||
|
case ExecutionModePostDepthCoverage: return "PostDepthCoverage";
|
||||||
|
case ExecutionModeDenormPreserve: return "DenormPreserve";
|
||||||
|
case ExecutionModeDenormFlushToZero: return "DenormFlushToZero";
|
||||||
|
case ExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve";
|
||||||
|
case ExecutionModeRoundingModeRTE: return "RoundingModeRTE";
|
||||||
|
case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ";
|
||||||
|
case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT";
|
||||||
|
|
||||||
case ExecutionModeOutputLinesNV: return "OutputLinesNV";
|
case ExecutionModeOutputLinesNV: return "OutputLinesNV";
|
||||||
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
|
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
|
||||||
@@ -187,6 +202,11 @@ const char* ExecutionModeString(int mode)
|
|||||||
case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT";
|
case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT";
|
||||||
case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT";
|
case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT";
|
||||||
|
|
||||||
|
case ExecutionModeMaxWorkgroupSizeINTEL: return "MaxWorkgroupSizeINTEL";
|
||||||
|
case ExecutionModeMaxWorkDimINTEL: return "MaxWorkDimINTEL";
|
||||||
|
case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL";
|
||||||
|
case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL";
|
||||||
|
|
||||||
case ExecutionModeCeiling:
|
case ExecutionModeCeiling:
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
@@ -209,12 +229,12 @@ const char* StorageClassString(int StorageClass)
|
|||||||
case 11: return "Image";
|
case 11: return "Image";
|
||||||
case 12: return "StorageBuffer";
|
case 12: return "StorageBuffer";
|
||||||
|
|
||||||
case StorageClassRayPayloadNV: return "RayPayloadNV";
|
case StorageClassRayPayloadKHR: return "RayPayloadKHR";
|
||||||
case StorageClassHitAttributeNV: return "HitAttributeNV";
|
case StorageClassHitAttributeKHR: return "HitAttributeKHR";
|
||||||
case StorageClassIncomingRayPayloadNV: return "IncomingRayPayloadNV";
|
case StorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR";
|
||||||
case StorageClassShaderRecordBufferNV: return "ShaderRecordBufferNV";
|
case StorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR";
|
||||||
case StorageClassCallableDataNV: return "CallableDataNV";
|
case StorageClassCallableDataKHR: return "CallableDataKHR";
|
||||||
case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV";
|
case StorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR";
|
||||||
|
|
||||||
case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT";
|
case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT";
|
||||||
|
|
||||||
@@ -361,32 +381,33 @@ const char* BuiltInString(int builtIn)
|
|||||||
case 4996: return "BaryCoordSmoothCentroidAMD";
|
case 4996: return "BaryCoordSmoothCentroidAMD";
|
||||||
case 4997: return "BaryCoordSmoothSampleAMD";
|
case 4997: return "BaryCoordSmoothSampleAMD";
|
||||||
case 4998: return "BaryCoordPullModelAMD";
|
case 4998: return "BaryCoordPullModelAMD";
|
||||||
case BuiltInLaunchIdNV: return "LaunchIdNV";
|
case BuiltInLaunchIdKHR: return "LaunchIdKHR";
|
||||||
case BuiltInLaunchSizeNV: return "LaunchSizeNV";
|
case BuiltInLaunchSizeKHR: return "LaunchSizeKHR";
|
||||||
case BuiltInWorldRayOriginNV: return "WorldRayOriginNV";
|
case BuiltInWorldRayOriginKHR: return "WorldRayOriginKHR";
|
||||||
case BuiltInWorldRayDirectionNV: return "WorldRayDirectionNV";
|
case BuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR";
|
||||||
case BuiltInObjectRayOriginNV: return "ObjectRayOriginNV";
|
case BuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR";
|
||||||
case BuiltInObjectRayDirectionNV: return "ObjectRayDirectionNV";
|
case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR";
|
||||||
case BuiltInRayTminNV: return "RayTminNV";
|
case BuiltInRayTminKHR: return "RayTminKHR";
|
||||||
case BuiltInRayTmaxNV: return "RayTmaxNV";
|
case BuiltInRayTmaxKHR: return "RayTmaxKHR";
|
||||||
case BuiltInInstanceCustomIndexNV: return "InstanceCustomIndexNV";
|
case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR";
|
||||||
case BuiltInObjectToWorldNV: return "ObjectToWorldNV";
|
case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR";
|
||||||
case BuiltInWorldToObjectNV: return "WorldToObjectNV";
|
case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR";
|
||||||
case BuiltInHitTNV: return "HitTNV";
|
case BuiltInWorldToObjectKHR: return "WorldToObjectKHR";
|
||||||
case BuiltInHitKindNV: return "HitKindNV";
|
case BuiltInHitTKHR: return "HitTKHR";
|
||||||
case BuiltInIncomingRayFlagsNV: return "IncomingRayFlagsNV";
|
case BuiltInHitKindKHR: return "HitKindKHR";
|
||||||
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
case BuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR";
|
||||||
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
||||||
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
|
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
|
||||||
|
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||||
// case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT
|
// case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT
|
||||||
// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
|
// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
|
||||||
case BuiltInBaryCoordNV: return "BaryCoordNV";
|
case BuiltInBaryCoordNV: return "BaryCoordNV";
|
||||||
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||||
|
|
||||||
case BuiltInFragSizeEXT: return "FragSizeEXT";
|
case BuiltInFragSizeEXT: return "FragSizeEXT";
|
||||||
case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
|
case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
|
||||||
|
|
||||||
case 5264: return "FullyCoveredEXT";
|
case 5264: return "FullyCoveredEXT";
|
||||||
|
|
||||||
@@ -890,6 +911,9 @@ const char* CapabilityString(int info)
|
|||||||
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||||
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
|
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
|
||||||
case CapabilityRayTracingNV: return "RayTracingNV";
|
case CapabilityRayTracingNV: return "RayTracingNV";
|
||||||
|
case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
|
||||||
|
case CapabilityRayQueryProvisionalKHR: return "RayQueryProvisionalKHR";
|
||||||
|
case CapabilityRayTraversalPrimitiveCullingProvisionalKHR: return "RayTraversalPrimitiveCullingProvisionalKHR";
|
||||||
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
|
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
|
||||||
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
|
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
|
||||||
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
||||||
@@ -933,6 +957,9 @@ const char* CapabilityString(int info)
|
|||||||
|
|
||||||
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
|
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
|
||||||
|
|
||||||
|
case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
|
||||||
|
case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1264,6 +1291,7 @@ const char* OpcodeString(int op)
|
|||||||
case 320: return "OpImageSparseRead";
|
case 320: return "OpImageSparseRead";
|
||||||
|
|
||||||
case OpModuleProcessed: return "OpModuleProcessed";
|
case OpModuleProcessed: return "OpModuleProcessed";
|
||||||
|
case OpExecutionModeId: return "OpExecutionModeId";
|
||||||
case OpDecorateId: return "OpDecorateId";
|
case OpDecorateId: return "OpDecorateId";
|
||||||
|
|
||||||
case 333: return "OpGroupNonUniformElect";
|
case 333: return "OpGroupNonUniformElect";
|
||||||
@@ -1308,6 +1336,8 @@ const char* OpcodeString(int op)
|
|||||||
case 4430: return "OpSubgroupAllEqualKHR";
|
case 4430: return "OpSubgroupAllEqualKHR";
|
||||||
case 4432: return "OpSubgroupReadInvocationKHR";
|
case 4432: return "OpSubgroupReadInvocationKHR";
|
||||||
|
|
||||||
|
case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
|
||||||
|
|
||||||
case 5000: return "OpGroupIAddNonUniformAMD";
|
case 5000: return "OpGroupIAddNonUniformAMD";
|
||||||
case 5001: return "OpGroupFAddNonUniformAMD";
|
case 5001: return "OpGroupFAddNonUniformAMD";
|
||||||
case 5002: return "OpGroupFMinNonUniformAMD";
|
case 5002: return "OpGroupFMinNonUniformAMD";
|
||||||
@@ -1326,15 +1356,40 @@ const char* OpcodeString(int op)
|
|||||||
case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
|
case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
|
||||||
|
|
||||||
case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV";
|
case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV";
|
||||||
case OpReportIntersectionNV: return "OpReportIntersectionNV";
|
case OpReportIntersectionKHR: return "OpReportIntersectionKHR";
|
||||||
case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV";
|
case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR";
|
||||||
case OpTerminateRayNV: return "OpTerminateRayNV";
|
case OpTerminateRayKHR: return "OpTerminateRayKHR";
|
||||||
case OpTraceNV: return "OpTraceNV";
|
case OpTraceRayKHR: return "OpTraceRayKHR";
|
||||||
case OpTypeAccelerationStructureNV: return "OpTypeAccelerationStructureNV";
|
case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR";
|
||||||
case OpExecuteCallableNV: return "OpExecuteCallableNV";
|
case OpExecuteCallableKHR: return "OpExecuteCallableKHR";
|
||||||
case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV";
|
case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV";
|
||||||
case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV";
|
case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV";
|
||||||
|
|
||||||
|
case OpTypeRayQueryProvisionalKHR: return "OpTypeRayQueryProvisionalKHR";
|
||||||
|
case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR";
|
||||||
|
case OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR";
|
||||||
|
case OpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR";
|
||||||
|
case OpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR";
|
||||||
|
case OpRayQueryProceedKHR: return "OpRayQueryProceedKHR";
|
||||||
|
case OpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR";
|
||||||
|
case OpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR";
|
||||||
|
case OpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR";
|
||||||
|
case OpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR";
|
||||||
|
case OpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR";
|
||||||
|
case OpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR";
|
||||||
|
case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR";
|
||||||
|
case OpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR";
|
||||||
|
case OpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR";
|
||||||
|
case OpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR";
|
||||||
|
case OpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR";
|
||||||
|
case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR";
|
||||||
|
case OpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR";
|
||||||
|
case OpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR";
|
||||||
|
case OpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR";
|
||||||
|
case OpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR";
|
||||||
|
case OpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR";
|
||||||
|
case OpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR";
|
||||||
|
|
||||||
case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV";
|
case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV";
|
||||||
case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV";
|
case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV";
|
||||||
case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV";
|
case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV";
|
||||||
@@ -1388,6 +1443,7 @@ void Parameterize()
|
|||||||
InstructionDesc[OpMemoryModel].setResultAndType(false, false);
|
InstructionDesc[OpMemoryModel].setResultAndType(false, false);
|
||||||
InstructionDesc[OpEntryPoint].setResultAndType(false, false);
|
InstructionDesc[OpEntryPoint].setResultAndType(false, false);
|
||||||
InstructionDesc[OpExecutionMode].setResultAndType(false, false);
|
InstructionDesc[OpExecutionMode].setResultAndType(false, false);
|
||||||
|
InstructionDesc[OpExecutionModeId].setResultAndType(false, false);
|
||||||
InstructionDesc[OpTypeVoid].setResultAndType(true, false);
|
InstructionDesc[OpTypeVoid].setResultAndType(true, false);
|
||||||
InstructionDesc[OpTypeBool].setResultAndType(true, false);
|
InstructionDesc[OpTypeBool].setResultAndType(true, false);
|
||||||
InstructionDesc[OpTypeInt].setResultAndType(true, false);
|
InstructionDesc[OpTypeInt].setResultAndType(true, false);
|
||||||
@@ -1574,6 +1630,10 @@ void Parameterize()
|
|||||||
InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode, "'Mode'");
|
InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode, "'Mode'");
|
||||||
InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <<Execution_Mode,Execution Mode>>");
|
InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <<Execution_Mode,Execution Mode>>");
|
||||||
|
|
||||||
|
InstructionDesc[OpExecutionModeId].operands.push(OperandId, "'Entry Point'");
|
||||||
|
InstructionDesc[OpExecutionModeId].operands.push(OperandExecutionMode, "'Mode'");
|
||||||
|
InstructionDesc[OpExecutionModeId].operands.push(OperandVariableIds, "See <<Execution_Mode,Execution Mode>>");
|
||||||
|
|
||||||
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Width'");
|
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Width'");
|
||||||
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Signedness'");
|
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Signedness'");
|
||||||
|
|
||||||
@@ -1667,7 +1727,7 @@ void Parameterize()
|
|||||||
|
|
||||||
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'");
|
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'");
|
||||||
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandDecoration, "");
|
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandDecoration, "");
|
||||||
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'");
|
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'");
|
||||||
|
|
||||||
InstructionDesc[OpMemberDecorate].operands.push(OperandId, "'Structure Type'");
|
InstructionDesc[OpMemberDecorate].operands.push(OperandId, "'Structure Type'");
|
||||||
InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'");
|
InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'");
|
||||||
@@ -1677,7 +1737,7 @@ void Parameterize()
|
|||||||
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'");
|
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'");
|
||||||
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'");
|
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'");
|
||||||
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandDecoration, "");
|
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandDecoration, "");
|
||||||
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'");
|
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'");
|
||||||
|
|
||||||
InstructionDesc[OpGroupDecorate].operands.push(OperandId, "'Decoration Group'");
|
InstructionDesc[OpGroupDecorate].operands.push(OperandId, "'Decoration Group'");
|
||||||
InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'");
|
InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'");
|
||||||
@@ -2230,6 +2290,11 @@ void Parameterize()
|
|||||||
InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics, "'Semantics'");
|
InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics, "'Semantics'");
|
||||||
InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Value'");
|
InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Value'");
|
||||||
|
|
||||||
|
InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Pointer'");
|
||||||
|
InstructionDesc[OpAtomicFAddEXT].operands.push(OperandScope, "'Scope'");
|
||||||
|
InstructionDesc[OpAtomicFAddEXT].operands.push(OperandMemorySemantics, "'Semantics'");
|
||||||
|
InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Value'");
|
||||||
|
|
||||||
InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Pointer'");
|
InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Pointer'");
|
||||||
InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'");
|
InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'");
|
||||||
InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'");
|
InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'");
|
||||||
@@ -2694,31 +2759,125 @@ void Parameterize()
|
|||||||
|
|
||||||
InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
|
InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
|
||||||
|
|
||||||
InstructionDesc[OpTypeAccelerationStructureNV].setResultAndType(true, false);
|
InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
|
||||||
|
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'NV Acceleration Structure'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'NV Acceleration Structure'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Flags'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Offset'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Stride'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Stride'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Miss Index'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Miss Index'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Origin'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Origin'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMin'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMin'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Direction'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Direction'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMax'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMax'");
|
||||||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
|
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Payload'");
|
||||||
InstructionDesc[OpTraceNV].setResultAndType(false, false);
|
InstructionDesc[OpTraceRayKHR].setResultAndType(false, false);
|
||||||
|
|
||||||
InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Parameter'");
|
InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Parameter'");
|
||||||
InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Kind'");
|
InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Kind'");
|
||||||
|
|
||||||
InstructionDesc[OpIgnoreIntersectionNV].setResultAndType(false, false);
|
InstructionDesc[OpIgnoreIntersectionKHR].setResultAndType(false, false);
|
||||||
|
|
||||||
InstructionDesc[OpTerminateRayNV].setResultAndType(false, false);
|
InstructionDesc[OpTerminateRayKHR].setResultAndType(false, false);
|
||||||
|
|
||||||
InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "SBT Record Index");
|
InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "SBT Record Index");
|
||||||
InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID");
|
InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "CallableData ID");
|
||||||
InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false);
|
InstructionDesc[OpExecuteCallableKHR].setResultAndType(false, false);
|
||||||
|
|
||||||
|
// Ray Query
|
||||||
|
InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
|
||||||
|
InstructionDesc[OpTypeRayQueryProvisionalKHR].setResultAndType(true, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'AccelerationS'");
|
||||||
|
InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayFlags'");
|
||||||
|
InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'CullMask'");
|
||||||
|
InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Origin'");
|
||||||
|
InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmin'");
|
||||||
|
InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Direction'");
|
||||||
|
InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmax'");
|
||||||
|
InstructionDesc[OpRayQueryInitializeKHR].setResultAndType(false, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryTerminateKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryTerminateKHR].setResultAndType(false, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'THit'");
|
||||||
|
InstructionDesc[OpRayQueryGenerateIntersectionKHR].setResultAndType(false, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryConfirmIntersectionKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryConfirmIntersectionKHR].setResultAndType(false, false);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryProceedKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryProceedKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionTypeKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetRayTMinKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetRayTMinKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetRayFlagsKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetRayFlagsKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionTKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetWorldRayOriginKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetWorldRayOriginKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'RayQuery'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'Committed'");
|
||||||
|
InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].setResultAndType(true, true);
|
||||||
|
|
||||||
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'");
|
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'");
|
||||||
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'");
|
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'");
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ enum OperandClass {
|
|||||||
OperandVariableLiteralId,
|
OperandVariableLiteralId,
|
||||||
OperandLiteralNumber,
|
OperandLiteralNumber,
|
||||||
OperandLiteralString,
|
OperandLiteralString,
|
||||||
|
OperandVariableLiteralStrings,
|
||||||
OperandSource,
|
OperandSource,
|
||||||
OperandExecutionModel,
|
OperandExecutionModel,
|
||||||
OperandAddressing,
|
OperandAddressing,
|
||||||
|
|||||||
@@ -784,8 +784,8 @@ inline std::istream& ParseNormalFloat(std::istream& is, bool negate_value,
|
|||||||
if (val.isInfinity()) {
|
if (val.isInfinity()) {
|
||||||
// Fail the parse. Emulate standard behaviour by setting the value to
|
// Fail the parse. Emulate standard behaviour by setting the value to
|
||||||
// the closest normal value, and set the fail bit on the stream.
|
// the closest normal value, and set the fail bit on the stream.
|
||||||
value.set_value((value.isNegative() | negate_value) ? T::lowest()
|
value.set_value((value.isNegative() || negate_value) ? T::lowest()
|
||||||
: T::max());
|
: T::max());
|
||||||
is.setstate(std::ios_base::failbit);
|
is.setstate(std::ios_base::failbit);
|
||||||
}
|
}
|
||||||
return is;
|
return is;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2014-2019 The Khronos Group Inc.
|
// Copyright (c) 2014-2020 The Khronos Group Inc.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and/or associated documentation files (the "Materials"),
|
// of this software and/or associated documentation files (the "Materials"),
|
||||||
@@ -49,12 +49,12 @@ namespace spv {
|
|||||||
|
|
||||||
typedef unsigned int Id;
|
typedef unsigned int Id;
|
||||||
|
|
||||||
#define SPV_VERSION 0x10400
|
#define SPV_VERSION 0x10500
|
||||||
#define SPV_REVISION 1
|
#define SPV_REVISION 3
|
||||||
|
|
||||||
static const unsigned int MagicNumber = 0x07230203;
|
static const unsigned int MagicNumber = 0x07230203;
|
||||||
static const unsigned int Version = 0x00010400;
|
static const unsigned int Version = 0x00010500;
|
||||||
static const unsigned int Revision = 1;
|
static const unsigned int Revision = 3;
|
||||||
static const unsigned int OpCodeMask = 0xffff;
|
static const unsigned int OpCodeMask = 0xffff;
|
||||||
static const unsigned int WordCountShift = 16;
|
static const unsigned int WordCountShift = 16;
|
||||||
|
|
||||||
@@ -78,11 +78,17 @@ enum ExecutionModel {
|
|||||||
ExecutionModelKernel = 6,
|
ExecutionModelKernel = 6,
|
||||||
ExecutionModelTaskNV = 5267,
|
ExecutionModelTaskNV = 5267,
|
||||||
ExecutionModelMeshNV = 5268,
|
ExecutionModelMeshNV = 5268,
|
||||||
|
ExecutionModelRayGenerationKHR = 5313,
|
||||||
ExecutionModelRayGenerationNV = 5313,
|
ExecutionModelRayGenerationNV = 5313,
|
||||||
|
ExecutionModelIntersectionKHR = 5314,
|
||||||
ExecutionModelIntersectionNV = 5314,
|
ExecutionModelIntersectionNV = 5314,
|
||||||
|
ExecutionModelAnyHitKHR = 5315,
|
||||||
ExecutionModelAnyHitNV = 5315,
|
ExecutionModelAnyHitNV = 5315,
|
||||||
|
ExecutionModelClosestHitKHR = 5316,
|
||||||
ExecutionModelClosestHitNV = 5316,
|
ExecutionModelClosestHitNV = 5316,
|
||||||
|
ExecutionModelMissKHR = 5317,
|
||||||
ExecutionModelMissNV = 5317,
|
ExecutionModelMissNV = 5317,
|
||||||
|
ExecutionModelCallableKHR = 5318,
|
||||||
ExecutionModelCallableNV = 5318,
|
ExecutionModelCallableNV = 5318,
|
||||||
ExecutionModelMax = 0x7fffffff,
|
ExecutionModelMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
@@ -162,6 +168,10 @@ enum ExecutionMode {
|
|||||||
ExecutionModeSampleInterlockUnorderedEXT = 5369,
|
ExecutionModeSampleInterlockUnorderedEXT = 5369,
|
||||||
ExecutionModeShadingRateInterlockOrderedEXT = 5370,
|
ExecutionModeShadingRateInterlockOrderedEXT = 5370,
|
||||||
ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
|
ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
|
||||||
|
ExecutionModeMaxWorkgroupSizeINTEL = 5893,
|
||||||
|
ExecutionModeMaxWorkDimINTEL = 5894,
|
||||||
|
ExecutionModeNoGlobalOffsetINTEL = 5895,
|
||||||
|
ExecutionModeNumSIMDWorkitemsINTEL = 5896,
|
||||||
ExecutionModeMax = 0x7fffffff,
|
ExecutionModeMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -179,14 +189,21 @@ enum StorageClass {
|
|||||||
StorageClassAtomicCounter = 10,
|
StorageClassAtomicCounter = 10,
|
||||||
StorageClassImage = 11,
|
StorageClassImage = 11,
|
||||||
StorageClassStorageBuffer = 12,
|
StorageClassStorageBuffer = 12,
|
||||||
|
StorageClassCallableDataKHR = 5328,
|
||||||
StorageClassCallableDataNV = 5328,
|
StorageClassCallableDataNV = 5328,
|
||||||
|
StorageClassIncomingCallableDataKHR = 5329,
|
||||||
StorageClassIncomingCallableDataNV = 5329,
|
StorageClassIncomingCallableDataNV = 5329,
|
||||||
|
StorageClassRayPayloadKHR = 5338,
|
||||||
StorageClassRayPayloadNV = 5338,
|
StorageClassRayPayloadNV = 5338,
|
||||||
|
StorageClassHitAttributeKHR = 5339,
|
||||||
StorageClassHitAttributeNV = 5339,
|
StorageClassHitAttributeNV = 5339,
|
||||||
|
StorageClassIncomingRayPayloadKHR = 5342,
|
||||||
StorageClassIncomingRayPayloadNV = 5342,
|
StorageClassIncomingRayPayloadNV = 5342,
|
||||||
|
StorageClassShaderRecordBufferKHR = 5343,
|
||||||
StorageClassShaderRecordBufferNV = 5343,
|
StorageClassShaderRecordBufferNV = 5343,
|
||||||
StorageClassPhysicalStorageBuffer = 5349,
|
StorageClassPhysicalStorageBuffer = 5349,
|
||||||
StorageClassPhysicalStorageBufferEXT = 5349,
|
StorageClassPhysicalStorageBufferEXT = 5349,
|
||||||
|
StorageClassCodeSectionINTEL = 5605,
|
||||||
StorageClassMax = 0x7fffffff,
|
StorageClassMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -465,11 +482,24 @@ enum Decoration {
|
|||||||
DecorationRestrictPointerEXT = 5355,
|
DecorationRestrictPointerEXT = 5355,
|
||||||
DecorationAliasedPointer = 5356,
|
DecorationAliasedPointer = 5356,
|
||||||
DecorationAliasedPointerEXT = 5356,
|
DecorationAliasedPointerEXT = 5356,
|
||||||
|
DecorationReferencedIndirectlyINTEL = 5602,
|
||||||
DecorationCounterBuffer = 5634,
|
DecorationCounterBuffer = 5634,
|
||||||
DecorationHlslCounterBufferGOOGLE = 5634,
|
DecorationHlslCounterBufferGOOGLE = 5634,
|
||||||
DecorationHlslSemanticGOOGLE = 5635,
|
DecorationHlslSemanticGOOGLE = 5635,
|
||||||
DecorationUserSemantic = 5635,
|
DecorationUserSemantic = 5635,
|
||||||
DecorationUserTypeGOOGLE = 5636,
|
DecorationUserTypeGOOGLE = 5636,
|
||||||
|
DecorationRegisterINTEL = 5825,
|
||||||
|
DecorationMemoryINTEL = 5826,
|
||||||
|
DecorationNumbanksINTEL = 5827,
|
||||||
|
DecorationBankwidthINTEL = 5828,
|
||||||
|
DecorationMaxPrivateCopiesINTEL = 5829,
|
||||||
|
DecorationSinglepumpINTEL = 5830,
|
||||||
|
DecorationDoublepumpINTEL = 5831,
|
||||||
|
DecorationMaxReplicatesINTEL = 5832,
|
||||||
|
DecorationSimpleDualPortINTEL = 5833,
|
||||||
|
DecorationMergeINTEL = 5834,
|
||||||
|
DecorationBankBitsINTEL = 5835,
|
||||||
|
DecorationForcePow2DepthINTEL = 5836,
|
||||||
DecorationMax = 0x7fffffff,
|
DecorationMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -558,20 +588,35 @@ enum BuiltIn {
|
|||||||
BuiltInFragmentSizeNV = 5292,
|
BuiltInFragmentSizeNV = 5292,
|
||||||
BuiltInFragInvocationCountEXT = 5293,
|
BuiltInFragInvocationCountEXT = 5293,
|
||||||
BuiltInInvocationsPerPixelNV = 5293,
|
BuiltInInvocationsPerPixelNV = 5293,
|
||||||
|
BuiltInLaunchIdKHR = 5319,
|
||||||
BuiltInLaunchIdNV = 5319,
|
BuiltInLaunchIdNV = 5319,
|
||||||
|
BuiltInLaunchSizeKHR = 5320,
|
||||||
BuiltInLaunchSizeNV = 5320,
|
BuiltInLaunchSizeNV = 5320,
|
||||||
|
BuiltInWorldRayOriginKHR = 5321,
|
||||||
BuiltInWorldRayOriginNV = 5321,
|
BuiltInWorldRayOriginNV = 5321,
|
||||||
|
BuiltInWorldRayDirectionKHR = 5322,
|
||||||
BuiltInWorldRayDirectionNV = 5322,
|
BuiltInWorldRayDirectionNV = 5322,
|
||||||
|
BuiltInObjectRayOriginKHR = 5323,
|
||||||
BuiltInObjectRayOriginNV = 5323,
|
BuiltInObjectRayOriginNV = 5323,
|
||||||
|
BuiltInObjectRayDirectionKHR = 5324,
|
||||||
BuiltInObjectRayDirectionNV = 5324,
|
BuiltInObjectRayDirectionNV = 5324,
|
||||||
|
BuiltInRayTminKHR = 5325,
|
||||||
BuiltInRayTminNV = 5325,
|
BuiltInRayTminNV = 5325,
|
||||||
|
BuiltInRayTmaxKHR = 5326,
|
||||||
BuiltInRayTmaxNV = 5326,
|
BuiltInRayTmaxNV = 5326,
|
||||||
|
BuiltInInstanceCustomIndexKHR = 5327,
|
||||||
BuiltInInstanceCustomIndexNV = 5327,
|
BuiltInInstanceCustomIndexNV = 5327,
|
||||||
|
BuiltInObjectToWorldKHR = 5330,
|
||||||
BuiltInObjectToWorldNV = 5330,
|
BuiltInObjectToWorldNV = 5330,
|
||||||
|
BuiltInWorldToObjectKHR = 5331,
|
||||||
BuiltInWorldToObjectNV = 5331,
|
BuiltInWorldToObjectNV = 5331,
|
||||||
|
BuiltInHitTKHR = 5332,
|
||||||
BuiltInHitTNV = 5332,
|
BuiltInHitTNV = 5332,
|
||||||
|
BuiltInHitKindKHR = 5333,
|
||||||
BuiltInHitKindNV = 5333,
|
BuiltInHitKindNV = 5333,
|
||||||
|
BuiltInIncomingRayFlagsKHR = 5351,
|
||||||
BuiltInIncomingRayFlagsNV = 5351,
|
BuiltInIncomingRayFlagsNV = 5351,
|
||||||
|
BuiltInRayGeometryIndexKHR = 5352,
|
||||||
BuiltInWarpsPerSMNV = 5374,
|
BuiltInWarpsPerSMNV = 5374,
|
||||||
BuiltInSMCountNV = 5375,
|
BuiltInSMCountNV = 5375,
|
||||||
BuiltInWarpIDNV = 5376,
|
BuiltInWarpIDNV = 5376,
|
||||||
@@ -601,6 +646,13 @@ enum LoopControlShift {
|
|||||||
LoopControlIterationMultipleShift = 6,
|
LoopControlIterationMultipleShift = 6,
|
||||||
LoopControlPeelCountShift = 7,
|
LoopControlPeelCountShift = 7,
|
||||||
LoopControlPartialCountShift = 8,
|
LoopControlPartialCountShift = 8,
|
||||||
|
LoopControlInitiationIntervalINTELShift = 16,
|
||||||
|
LoopControlMaxConcurrencyINTELShift = 17,
|
||||||
|
LoopControlDependencyArrayINTELShift = 18,
|
||||||
|
LoopControlPipelineEnableINTELShift = 19,
|
||||||
|
LoopControlLoopCoalesceINTELShift = 20,
|
||||||
|
LoopControlMaxInterleavingINTELShift = 21,
|
||||||
|
LoopControlSpeculatedIterationsINTELShift = 22,
|
||||||
LoopControlMax = 0x7fffffff,
|
LoopControlMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -615,6 +667,13 @@ enum LoopControlMask {
|
|||||||
LoopControlIterationMultipleMask = 0x00000040,
|
LoopControlIterationMultipleMask = 0x00000040,
|
||||||
LoopControlPeelCountMask = 0x00000080,
|
LoopControlPeelCountMask = 0x00000080,
|
||||||
LoopControlPartialCountMask = 0x00000100,
|
LoopControlPartialCountMask = 0x00000100,
|
||||||
|
LoopControlInitiationIntervalINTELMask = 0x00010000,
|
||||||
|
LoopControlMaxConcurrencyINTELMask = 0x00020000,
|
||||||
|
LoopControlDependencyArrayINTELMask = 0x00040000,
|
||||||
|
LoopControlPipelineEnableINTELMask = 0x00080000,
|
||||||
|
LoopControlLoopCoalesceINTELMask = 0x00100000,
|
||||||
|
LoopControlMaxInterleavingINTELMask = 0x00200000,
|
||||||
|
LoopControlSpeculatedIterationsINTELMask = 0x00400000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FunctionControlShift {
|
enum FunctionControlShift {
|
||||||
@@ -709,6 +768,7 @@ enum Scope {
|
|||||||
ScopeInvocation = 4,
|
ScopeInvocation = 4,
|
||||||
ScopeQueueFamily = 5,
|
ScopeQueueFamily = 5,
|
||||||
ScopeQueueFamilyKHR = 5,
|
ScopeQueueFamilyKHR = 5,
|
||||||
|
ScopeShaderCallKHR = 6,
|
||||||
ScopeMax = 0x7fffffff,
|
ScopeMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -833,6 +893,8 @@ enum Capability {
|
|||||||
CapabilitySignedZeroInfNanPreserve = 4466,
|
CapabilitySignedZeroInfNanPreserve = 4466,
|
||||||
CapabilityRoundingModeRTE = 4467,
|
CapabilityRoundingModeRTE = 4467,
|
||||||
CapabilityRoundingModeRTZ = 4468,
|
CapabilityRoundingModeRTZ = 4468,
|
||||||
|
CapabilityRayQueryProvisionalKHR = 4471,
|
||||||
|
CapabilityRayTraversalPrimitiveCullingProvisionalKHR = 4478,
|
||||||
CapabilityFloat16ImageAMD = 5008,
|
CapabilityFloat16ImageAMD = 5008,
|
||||||
CapabilityImageGatherBiasLodAMD = 5009,
|
CapabilityImageGatherBiasLodAMD = 5009,
|
||||||
CapabilityFragmentMaskAMD = 5010,
|
CapabilityFragmentMaskAMD = 5010,
|
||||||
@@ -886,6 +948,7 @@ enum Capability {
|
|||||||
CapabilityPhysicalStorageBufferAddresses = 5347,
|
CapabilityPhysicalStorageBufferAddresses = 5347,
|
||||||
CapabilityPhysicalStorageBufferAddressesEXT = 5347,
|
CapabilityPhysicalStorageBufferAddressesEXT = 5347,
|
||||||
CapabilityComputeDerivativeGroupLinearNV = 5350,
|
CapabilityComputeDerivativeGroupLinearNV = 5350,
|
||||||
|
CapabilityRayTracingProvisionalKHR = 5353,
|
||||||
CapabilityCooperativeMatrixNV = 5357,
|
CapabilityCooperativeMatrixNV = 5357,
|
||||||
CapabilityFragmentShaderSampleInterlockEXT = 5363,
|
CapabilityFragmentShaderSampleInterlockEXT = 5363,
|
||||||
CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
|
CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
|
||||||
@@ -897,12 +960,70 @@ enum Capability {
|
|||||||
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
||||||
CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
|
CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
|
||||||
CapabilityIntegerFunctions2INTEL = 5584,
|
CapabilityIntegerFunctions2INTEL = 5584,
|
||||||
|
CapabilityFunctionPointersINTEL = 5603,
|
||||||
|
CapabilityIndirectReferencesINTEL = 5604,
|
||||||
CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
|
CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
|
||||||
CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
|
CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
|
||||||
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
|
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
|
||||||
|
CapabilityFPGAMemoryAttributesINTEL = 5824,
|
||||||
|
CapabilityUnstructuredLoopControlsINTEL = 5886,
|
||||||
|
CapabilityFPGALoopControlsINTEL = 5888,
|
||||||
|
CapabilityKernelAttributesINTEL = 5892,
|
||||||
|
CapabilityFPGAKernelAttributesINTEL = 5897,
|
||||||
|
CapabilityBlockingPipesINTEL = 5945,
|
||||||
|
CapabilityFPGARegINTEL = 5948,
|
||||||
|
CapabilityAtomicFloat32AddEXT = 6033,
|
||||||
|
CapabilityAtomicFloat64AddEXT = 6034,
|
||||||
CapabilityMax = 0x7fffffff,
|
CapabilityMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum RayFlagsShift {
|
||||||
|
RayFlagsOpaqueKHRShift = 0,
|
||||||
|
RayFlagsNoOpaqueKHRShift = 1,
|
||||||
|
RayFlagsTerminateOnFirstHitKHRShift = 2,
|
||||||
|
RayFlagsSkipClosestHitShaderKHRShift = 3,
|
||||||
|
RayFlagsCullBackFacingTrianglesKHRShift = 4,
|
||||||
|
RayFlagsCullFrontFacingTrianglesKHRShift = 5,
|
||||||
|
RayFlagsCullOpaqueKHRShift = 6,
|
||||||
|
RayFlagsCullNoOpaqueKHRShift = 7,
|
||||||
|
RayFlagsSkipTrianglesKHRShift = 8,
|
||||||
|
RayFlagsSkipAABBsKHRShift = 9,
|
||||||
|
RayFlagsMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RayFlagsMask {
|
||||||
|
RayFlagsMaskNone = 0,
|
||||||
|
RayFlagsOpaqueKHRMask = 0x00000001,
|
||||||
|
RayFlagsNoOpaqueKHRMask = 0x00000002,
|
||||||
|
RayFlagsTerminateOnFirstHitKHRMask = 0x00000004,
|
||||||
|
RayFlagsSkipClosestHitShaderKHRMask = 0x00000008,
|
||||||
|
RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010,
|
||||||
|
RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020,
|
||||||
|
RayFlagsCullOpaqueKHRMask = 0x00000040,
|
||||||
|
RayFlagsCullNoOpaqueKHRMask = 0x00000080,
|
||||||
|
RayFlagsSkipTrianglesKHRMask = 0x00000100,
|
||||||
|
RayFlagsSkipAABBsKHRMask = 0x00000200,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RayQueryIntersection {
|
||||||
|
RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0,
|
||||||
|
RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1,
|
||||||
|
RayQueryIntersectionMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RayQueryCommittedIntersectionType {
|
||||||
|
RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0,
|
||||||
|
RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1,
|
||||||
|
RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2,
|
||||||
|
RayQueryCommittedIntersectionTypeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RayQueryCandidateIntersectionType {
|
||||||
|
RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0,
|
||||||
|
RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1,
|
||||||
|
RayQueryCandidateIntersectionTypeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
enum Op {
|
enum Op {
|
||||||
OpNop = 0,
|
OpNop = 0,
|
||||||
OpUndef = 1,
|
OpUndef = 1,
|
||||||
@@ -1254,6 +1375,13 @@ enum Op {
|
|||||||
OpSubgroupAnyKHR = 4429,
|
OpSubgroupAnyKHR = 4429,
|
||||||
OpSubgroupAllEqualKHR = 4430,
|
OpSubgroupAllEqualKHR = 4430,
|
||||||
OpSubgroupReadInvocationKHR = 4432,
|
OpSubgroupReadInvocationKHR = 4432,
|
||||||
|
OpTypeRayQueryProvisionalKHR = 4472,
|
||||||
|
OpRayQueryInitializeKHR = 4473,
|
||||||
|
OpRayQueryTerminateKHR = 4474,
|
||||||
|
OpRayQueryGenerateIntersectionKHR = 4475,
|
||||||
|
OpRayQueryConfirmIntersectionKHR = 4476,
|
||||||
|
OpRayQueryProceedKHR = 4477,
|
||||||
|
OpRayQueryGetIntersectionTypeKHR = 4479,
|
||||||
OpGroupIAddNonUniformAMD = 5000,
|
OpGroupIAddNonUniformAMD = 5000,
|
||||||
OpGroupFAddNonUniformAMD = 5001,
|
OpGroupFAddNonUniformAMD = 5001,
|
||||||
OpGroupFMinNonUniformAMD = 5002,
|
OpGroupFMinNonUniformAMD = 5002,
|
||||||
@@ -1268,11 +1396,17 @@ enum Op {
|
|||||||
OpImageSampleFootprintNV = 5283,
|
OpImageSampleFootprintNV = 5283,
|
||||||
OpGroupNonUniformPartitionNV = 5296,
|
OpGroupNonUniformPartitionNV = 5296,
|
||||||
OpWritePackedPrimitiveIndices4x8NV = 5299,
|
OpWritePackedPrimitiveIndices4x8NV = 5299,
|
||||||
|
OpReportIntersectionKHR = 5334,
|
||||||
OpReportIntersectionNV = 5334,
|
OpReportIntersectionNV = 5334,
|
||||||
|
OpIgnoreIntersectionKHR = 5335,
|
||||||
OpIgnoreIntersectionNV = 5335,
|
OpIgnoreIntersectionNV = 5335,
|
||||||
|
OpTerminateRayKHR = 5336,
|
||||||
OpTerminateRayNV = 5336,
|
OpTerminateRayNV = 5336,
|
||||||
OpTraceNV = 5337,
|
OpTraceNV = 5337,
|
||||||
|
OpTraceRayKHR = 5337,
|
||||||
|
OpTypeAccelerationStructureKHR = 5341,
|
||||||
OpTypeAccelerationStructureNV = 5341,
|
OpTypeAccelerationStructureNV = 5341,
|
||||||
|
OpExecuteCallableKHR = 5344,
|
||||||
OpExecuteCallableNV = 5344,
|
OpExecuteCallableNV = 5344,
|
||||||
OpTypeCooperativeMatrixNV = 5358,
|
OpTypeCooperativeMatrixNV = 5358,
|
||||||
OpCooperativeMatrixLoadNV = 5359,
|
OpCooperativeMatrixLoadNV = 5359,
|
||||||
@@ -1307,6 +1441,8 @@ enum Op {
|
|||||||
OpUSubSatINTEL = 5596,
|
OpUSubSatINTEL = 5596,
|
||||||
OpIMul32x16INTEL = 5597,
|
OpIMul32x16INTEL = 5597,
|
||||||
OpUMul32x16INTEL = 5598,
|
OpUMul32x16INTEL = 5598,
|
||||||
|
OpFunctionPointerINTEL = 5600,
|
||||||
|
OpFunctionPointerCallINTEL = 5601,
|
||||||
OpDecorateString = 5632,
|
OpDecorateString = 5632,
|
||||||
OpDecorateStringGOOGLE = 5632,
|
OpDecorateStringGOOGLE = 5632,
|
||||||
OpMemberDecorateString = 5633,
|
OpMemberDecorateString = 5633,
|
||||||
@@ -1429,6 +1565,28 @@ enum Op {
|
|||||||
OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
|
OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
|
||||||
OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
|
OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
|
||||||
OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
|
OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
|
||||||
|
OpLoopControlINTEL = 5887,
|
||||||
|
OpReadPipeBlockingINTEL = 5946,
|
||||||
|
OpWritePipeBlockingINTEL = 5947,
|
||||||
|
OpFPGARegINTEL = 5949,
|
||||||
|
OpRayQueryGetRayTMinKHR = 6016,
|
||||||
|
OpRayQueryGetRayFlagsKHR = 6017,
|
||||||
|
OpRayQueryGetIntersectionTKHR = 6018,
|
||||||
|
OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019,
|
||||||
|
OpRayQueryGetIntersectionInstanceIdKHR = 6020,
|
||||||
|
OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021,
|
||||||
|
OpRayQueryGetIntersectionGeometryIndexKHR = 6022,
|
||||||
|
OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023,
|
||||||
|
OpRayQueryGetIntersectionBarycentricsKHR = 6024,
|
||||||
|
OpRayQueryGetIntersectionFrontFaceKHR = 6025,
|
||||||
|
OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026,
|
||||||
|
OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027,
|
||||||
|
OpRayQueryGetIntersectionObjectRayOriginKHR = 6028,
|
||||||
|
OpRayQueryGetWorldRayDirectionKHR = 6029,
|
||||||
|
OpRayQueryGetWorldRayOriginKHR = 6030,
|
||||||
|
OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
|
||||||
|
OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
|
||||||
|
OpAtomicFAddEXT = 6035,
|
||||||
OpMax = 0x7fffffff,
|
OpMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1787,6 +1945,13 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
|||||||
case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpTypeRayQueryProvisionalKHR: *hasResult = true; *hasResultType = false; break;
|
||||||
|
case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
|
case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
|
case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
|
case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
|
||||||
@@ -1840,6 +2005,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
|||||||
case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
|
case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
|
case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpDecorateString: *hasResult = false; *hasResultType = false; break;
|
case OpDecorateString: *hasResult = false; *hasResultType = false; break;
|
||||||
case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
|
case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
|
||||||
case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
@@ -1960,6 +2127,28 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
|||||||
case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
|
case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
|
||||||
|
case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;
|
||||||
|
case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* SPV_ENABLE_UTILITY_CODE */
|
#endif /* SPV_ENABLE_UTILITY_CODE */
|
||||||
@@ -1974,6 +2163,7 @@ inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask
|
|||||||
inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); }
|
inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); }
|
||||||
inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); }
|
inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); }
|
||||||
inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); }
|
inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); }
|
||||||
|
inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); }
|
||||||
|
|
||||||
} // end namespace spv
|
} // end namespace spv
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+24
-3
@@ -55,6 +55,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
|
|
||||||
@@ -235,8 +236,7 @@ public:
|
|||||||
assert(instructions.size() > 0);
|
assert(instructions.size() > 0);
|
||||||
instructions.resize(1);
|
instructions.resize(1);
|
||||||
successors.clear();
|
successors.clear();
|
||||||
Instruction* unreachable = new Instruction(OpUnreachable);
|
addInstruction(std::unique_ptr<Instruction>(new Instruction(OpUnreachable)));
|
||||||
addInstruction(std::unique_ptr<Instruction>(unreachable));
|
|
||||||
}
|
}
|
||||||
// Change this block into a canonical dead continue target branching to the
|
// Change this block into a canonical dead continue target branching to the
|
||||||
// given header ID. Delete instructions as necessary. A canonical dead continue
|
// given header ID. Delete instructions as necessary. A canonical dead continue
|
||||||
@@ -352,10 +352,28 @@ public:
|
|||||||
const std::vector<Block*>& getBlocks() const { return blocks; }
|
const std::vector<Block*>& getBlocks() const { return blocks; }
|
||||||
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
||||||
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
||||||
|
void setReturnPrecision(Decoration precision)
|
||||||
|
{
|
||||||
|
if (precision == DecorationRelaxedPrecision)
|
||||||
|
reducedPrecisionReturn = true;
|
||||||
|
}
|
||||||
|
Decoration getReturnPrecision() const
|
||||||
|
{ return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; }
|
||||||
|
|
||||||
void setImplicitThis() { implicitThis = true; }
|
void setImplicitThis() { implicitThis = true; }
|
||||||
bool hasImplicitThis() const { return implicitThis; }
|
bool hasImplicitThis() const { return implicitThis; }
|
||||||
|
|
||||||
|
void addParamPrecision(unsigned param, Decoration precision)
|
||||||
|
{
|
||||||
|
if (precision == DecorationRelaxedPrecision)
|
||||||
|
reducedPrecisionParams.insert(param);
|
||||||
|
}
|
||||||
|
Decoration getParamPrecision(unsigned param) const
|
||||||
|
{
|
||||||
|
return reducedPrecisionParams.find(param) != reducedPrecisionParams.end() ?
|
||||||
|
DecorationRelaxedPrecision : NoPrecision;
|
||||||
|
}
|
||||||
|
|
||||||
void dump(std::vector<unsigned int>& out) const
|
void dump(std::vector<unsigned int>& out) const
|
||||||
{
|
{
|
||||||
// OpFunction
|
// OpFunction
|
||||||
@@ -380,6 +398,8 @@ protected:
|
|||||||
std::vector<Instruction*> parameterInstructions;
|
std::vector<Instruction*> parameterInstructions;
|
||||||
std::vector<Block*> blocks;
|
std::vector<Block*> blocks;
|
||||||
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
|
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
|
||||||
|
bool reducedPrecisionReturn;
|
||||||
|
std::set<int> reducedPrecisionParams; // list of parameter indexes that need a relaxed precision arg
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -440,7 +460,8 @@ protected:
|
|||||||
// - the OpFunction instruction
|
// - the OpFunction instruction
|
||||||
// - all the OpFunctionParameter instructions
|
// - all the OpFunctionParameter instructions
|
||||||
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
|
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
|
||||||
: parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false)
|
: parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false),
|
||||||
|
reducedPrecisionReturn(false)
|
||||||
{
|
{
|
||||||
// OpFunction
|
// OpFunction
|
||||||
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
|
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -61,8 +62,9 @@ enum TBasicType {
|
|||||||
EbtSampler,
|
EbtSampler,
|
||||||
EbtStruct,
|
EbtStruct,
|
||||||
EbtBlock,
|
EbtBlock,
|
||||||
EbtAccStructNV,
|
EbtAccStruct,
|
||||||
EbtReference,
|
EbtReference,
|
||||||
|
EbtRayQuery,
|
||||||
|
|
||||||
// HLSL types that live only temporarily.
|
// HLSL types that live only temporarily.
|
||||||
EbtString,
|
EbtString,
|
||||||
@@ -90,11 +92,11 @@ enum TStorageQualifier {
|
|||||||
EvqBuffer, // read/write, shared with app
|
EvqBuffer, // read/write, shared with app
|
||||||
EvqShared, // compute shader's read/write 'shared' qualifier
|
EvqShared, // compute shader's read/write 'shared' qualifier
|
||||||
|
|
||||||
EvqPayloadNV,
|
EvqPayload,
|
||||||
EvqPayloadInNV,
|
EvqPayloadIn,
|
||||||
EvqHitAttrNV,
|
EvqHitAttr,
|
||||||
EvqCallableDataNV,
|
EvqCallableData,
|
||||||
EvqCallableDataInNV,
|
EvqCallableDataIn,
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
|
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
|
||||||
@@ -229,6 +231,9 @@ enum TBuiltInVariable {
|
|||||||
EbvFragSizeEXT,
|
EbvFragSizeEXT,
|
||||||
EbvFragInvocationCountEXT,
|
EbvFragInvocationCountEXT,
|
||||||
|
|
||||||
|
EbvSecondaryFragDataEXT,
|
||||||
|
EbvSecondaryFragColorEXT,
|
||||||
|
|
||||||
EbvViewportMaskNV,
|
EbvViewportMaskNV,
|
||||||
EbvSecondaryPositionNV,
|
EbvSecondaryPositionNV,
|
||||||
EbvSecondaryViewportMaskNV,
|
EbvSecondaryViewportMaskNV,
|
||||||
@@ -238,20 +243,23 @@ enum TBuiltInVariable {
|
|||||||
EbvFragmentSizeNV,
|
EbvFragmentSizeNV,
|
||||||
EbvInvocationsPerPixelNV,
|
EbvInvocationsPerPixelNV,
|
||||||
// ray tracing
|
// ray tracing
|
||||||
EbvLaunchIdNV,
|
EbvLaunchId,
|
||||||
EbvLaunchSizeNV,
|
EbvLaunchSize,
|
||||||
EbvInstanceCustomIndexNV,
|
EbvInstanceCustomIndex,
|
||||||
EbvWorldRayOriginNV,
|
EbvGeometryIndex,
|
||||||
EbvWorldRayDirectionNV,
|
EbvWorldRayOrigin,
|
||||||
EbvObjectRayOriginNV,
|
EbvWorldRayDirection,
|
||||||
EbvObjectRayDirectionNV,
|
EbvObjectRayOrigin,
|
||||||
EbvRayTminNV,
|
EbvObjectRayDirection,
|
||||||
EbvRayTmaxNV,
|
EbvRayTmin,
|
||||||
EbvHitTNV,
|
EbvRayTmax,
|
||||||
EbvHitKindNV,
|
EbvHitT,
|
||||||
EbvObjectToWorldNV,
|
EbvHitKind,
|
||||||
EbvWorldToObjectNV,
|
EbvObjectToWorld,
|
||||||
EbvIncomingRayFlagsNV,
|
EbvObjectToWorld3x4,
|
||||||
|
EbvWorldToObject,
|
||||||
|
EbvWorldToObject3x4,
|
||||||
|
EbvIncomingRayFlags,
|
||||||
// barycentrics
|
// barycentrics
|
||||||
EbvBaryCoordNV,
|
EbvBaryCoordNV,
|
||||||
EbvBaryCoordNoPerspNV,
|
EbvBaryCoordNoPerspNV,
|
||||||
@@ -328,11 +336,11 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
|
|||||||
case EvqPointCoord: return "gl_PointCoord"; break;
|
case EvqPointCoord: return "gl_PointCoord"; break;
|
||||||
case EvqFragColor: return "fragColor"; break;
|
case EvqFragColor: return "fragColor"; break;
|
||||||
case EvqFragDepth: return "gl_FragDepth"; break;
|
case EvqFragDepth: return "gl_FragDepth"; break;
|
||||||
case EvqPayloadNV: return "rayPayloadNV"; break;
|
case EvqPayload: return "rayPayloadNV"; break;
|
||||||
case EvqPayloadInNV: return "rayPayloadInNV"; break;
|
case EvqPayloadIn: return "rayPayloadInNV"; break;
|
||||||
case EvqHitAttrNV: return "hitAttributeNV"; break;
|
case EvqHitAttr: return "hitAttributeNV"; break;
|
||||||
case EvqCallableDataNV: return "callableDataNV"; break;
|
case EvqCallableData: return "callableDataNV"; break;
|
||||||
case EvqCallableDataInNV: return "callableDataInNV"; break;
|
case EvqCallableDataIn: return "callableDataInNV"; break;
|
||||||
default: return "unknown qualifier";
|
default: return "unknown qualifier";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -428,6 +436,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||||||
case EbvFragSizeEXT: return "FragSizeEXT";
|
case EbvFragSizeEXT: return "FragSizeEXT";
|
||||||
case EbvFragInvocationCountEXT: return "FragInvocationCountEXT";
|
case EbvFragInvocationCountEXT: return "FragInvocationCountEXT";
|
||||||
|
|
||||||
|
case EbvSecondaryFragDataEXT: return "SecondaryFragDataEXT";
|
||||||
|
case EbvSecondaryFragColorEXT: return "SecondaryFragColorEXT";
|
||||||
|
|
||||||
case EbvViewportMaskNV: return "ViewportMaskNV";
|
case EbvViewportMaskNV: return "ViewportMaskNV";
|
||||||
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
@@ -436,20 +447,21 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||||||
case EbvFragFullyCoveredNV: return "FragFullyCoveredNV";
|
case EbvFragFullyCoveredNV: return "FragFullyCoveredNV";
|
||||||
case EbvFragmentSizeNV: return "FragmentSizeNV";
|
case EbvFragmentSizeNV: return "FragmentSizeNV";
|
||||||
case EbvInvocationsPerPixelNV: return "InvocationsPerPixelNV";
|
case EbvInvocationsPerPixelNV: return "InvocationsPerPixelNV";
|
||||||
case EbvLaunchIdNV: return "LaunchIdNV";
|
case EbvLaunchId: return "LaunchIdNV";
|
||||||
case EbvLaunchSizeNV: return "LaunchSizeNV";
|
case EbvLaunchSize: return "LaunchSizeNV";
|
||||||
case EbvInstanceCustomIndexNV: return "InstanceCustomIndexNV";
|
case EbvInstanceCustomIndex: return "InstanceCustomIndexNV";
|
||||||
case EbvWorldRayOriginNV: return "WorldRayOriginNV";
|
case EbvGeometryIndex: return "GeometryIndexEXT";
|
||||||
case EbvWorldRayDirectionNV: return "WorldRayDirectionNV";
|
case EbvWorldRayOrigin: return "WorldRayOriginNV";
|
||||||
case EbvObjectRayOriginNV: return "ObjectRayOriginNV";
|
case EbvWorldRayDirection: return "WorldRayDirectionNV";
|
||||||
case EbvObjectRayDirectionNV: return "ObjectRayDirectionNV";
|
case EbvObjectRayOrigin: return "ObjectRayOriginNV";
|
||||||
case EbvRayTminNV: return "ObjectRayTminNV";
|
case EbvObjectRayDirection: return "ObjectRayDirectionNV";
|
||||||
case EbvRayTmaxNV: return "ObjectRayTmaxNV";
|
case EbvRayTmin: return "ObjectRayTminNV";
|
||||||
case EbvHitTNV: return "HitTNV";
|
case EbvRayTmax: return "ObjectRayTmaxNV";
|
||||||
case EbvHitKindNV: return "HitKindNV";
|
case EbvHitT: return "HitTNV";
|
||||||
case EbvIncomingRayFlagsNV: return "IncomingRayFlagsNV";
|
case EbvHitKind: return "HitKindNV";
|
||||||
case EbvObjectToWorldNV: return "ObjectToWorldNV";
|
case EbvIncomingRayFlags: return "IncomingRayFlagsNV";
|
||||||
case EbvWorldToObjectNV: return "WorldToObjectNV";
|
case EbvObjectToWorld: return "ObjectToWorldNV";
|
||||||
|
case EbvWorldToObject: return "WorldToObjectNV";
|
||||||
|
|
||||||
case EbvBaryCoordNV: return "BaryCoordNV";
|
case EbvBaryCoordNV: return "BaryCoordNV";
|
||||||
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||||
|
|||||||
@@ -37,6 +37,17 @@
|
|||||||
#ifndef _COMMON_INCLUDED_
|
#ifndef _COMMON_INCLUDED_
|
||||||
#define _COMMON_INCLUDED_
|
#define _COMMON_INCLUDED_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#if defined(__ANDROID__) || (defined(_MSC_VER) && _MSC_VER < 1700)
|
#if defined(__ANDROID__) || (defined(_MSC_VER) && _MSC_VER < 1700)
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -93,18 +104,6 @@ std::string to_string(const T& val) {
|
|||||||
#pragma warning(disable : 4201) // nameless union
|
#pragma warning(disable : 4201) // nameless union
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <list>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <string>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "PoolAlloc.h"
|
#include "PoolAlloc.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -921,7 +921,7 @@ public:
|
|||||||
else
|
else
|
||||||
unionArray = new TConstUnionVector(size);
|
unionArray = new TConstUnionVector(size);
|
||||||
}
|
}
|
||||||
TConstUnionArray(const TConstUnionArray& a) : unionArray(a.unionArray) { }
|
TConstUnionArray(const TConstUnionArray& a) = default;
|
||||||
TConstUnionArray(const TConstUnionArray& a, int start, int size)
|
TConstUnionArray(const TConstUnionArray& a, int start, int size)
|
||||||
{
|
{
|
||||||
unionArray = new TConstUnionVector(size);
|
unionArray = new TConstUnionVector(size);
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ struct TBuiltInResource {
|
|||||||
int maxTaskWorkGroupSizeY_NV;
|
int maxTaskWorkGroupSizeY_NV;
|
||||||
int maxTaskWorkGroupSizeZ_NV;
|
int maxTaskWorkGroupSizeZ_NV;
|
||||||
int maxMeshViewCountNV;
|
int maxMeshViewCountNV;
|
||||||
|
int maxDualSourceDrawBuffersEXT;
|
||||||
|
|
||||||
TLimits limits;
|
TLimits limits;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Copyright (C) 2012-2016 LunarG, Inc.
|
// Copyright (C) 2012-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2016 Google, Inc.
|
// Copyright (C) 2015-2016 Google, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -472,6 +473,18 @@ enum TInterlockOrdering {
|
|||||||
EioCount,
|
EioCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TShaderInterface
|
||||||
|
{
|
||||||
|
// Includes both uniform blocks and buffer blocks
|
||||||
|
EsiUniform = 0,
|
||||||
|
EsiInput,
|
||||||
|
EsiOutput,
|
||||||
|
EsiNone,
|
||||||
|
|
||||||
|
EsiCount
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class TQualifier {
|
class TQualifier {
|
||||||
public:
|
public:
|
||||||
static const int layoutNotSet = -1;
|
static const int layoutNotSet = -1;
|
||||||
@@ -532,6 +545,7 @@ public:
|
|||||||
queuefamilycoherent = false;
|
queuefamilycoherent = false;
|
||||||
workgroupcoherent = false;
|
workgroupcoherent = false;
|
||||||
subgroupcoherent = false;
|
subgroupcoherent = false;
|
||||||
|
shadercallcoherent = false;
|
||||||
nonprivate = false;
|
nonprivate = false;
|
||||||
volatil = false;
|
volatil = false;
|
||||||
restrict = false;
|
restrict = false;
|
||||||
@@ -553,6 +567,7 @@ public:
|
|||||||
// having a constant_id is not sufficient: expressions have no id, but are still specConstant
|
// having a constant_id is not sufficient: expressions have no id, but are still specConstant
|
||||||
bool specConstant : 1;
|
bool specConstant : 1;
|
||||||
bool nonUniform : 1;
|
bool nonUniform : 1;
|
||||||
|
bool explicitOffset : 1;
|
||||||
|
|
||||||
#ifdef GLSLANG_WEB
|
#ifdef GLSLANG_WEB
|
||||||
bool isWriteOnly() const { return false; }
|
bool isWriteOnly() const { return false; }
|
||||||
@@ -590,6 +605,7 @@ public:
|
|||||||
bool queuefamilycoherent : 1;
|
bool queuefamilycoherent : 1;
|
||||||
bool workgroupcoherent : 1;
|
bool workgroupcoherent : 1;
|
||||||
bool subgroupcoherent : 1;
|
bool subgroupcoherent : 1;
|
||||||
|
bool shadercallcoherent : 1;
|
||||||
bool nonprivate : 1;
|
bool nonprivate : 1;
|
||||||
bool isWriteOnly() const { return writeonly; }
|
bool isWriteOnly() const { return writeonly; }
|
||||||
bool isReadOnly() const { return readonly; }
|
bool isReadOnly() const { return readonly; }
|
||||||
@@ -599,11 +615,11 @@ public:
|
|||||||
bool isSample() const { return sample; }
|
bool isSample() const { return sample; }
|
||||||
bool isMemory() const
|
bool isMemory() const
|
||||||
{
|
{
|
||||||
return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate;
|
return shadercallcoherent || subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate;
|
||||||
}
|
}
|
||||||
bool isMemoryQualifierImageAndSSBOOnly() const
|
bool isMemoryQualifierImageAndSSBOOnly() const
|
||||||
{
|
{
|
||||||
return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly;
|
return shadercallcoherent || subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly;
|
||||||
}
|
}
|
||||||
bool bufferReferenceNeedsVulkanMemoryModel() const
|
bool bufferReferenceNeedsVulkanMemoryModel() const
|
||||||
{
|
{
|
||||||
@@ -773,7 +789,7 @@ public:
|
|||||||
layoutViewportRelative = false;
|
layoutViewportRelative = false;
|
||||||
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
|
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
|
||||||
layoutSecondaryViewportRelativeOffset = -2048;
|
layoutSecondaryViewportRelativeOffset = -2048;
|
||||||
layoutShaderRecordNV = false;
|
layoutShaderRecord = false;
|
||||||
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
|
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
|
||||||
layoutFormat = ElfNone;
|
layoutFormat = ElfNone;
|
||||||
#endif
|
#endif
|
||||||
@@ -812,7 +828,7 @@ public:
|
|||||||
hasAnyLocation() ||
|
hasAnyLocation() ||
|
||||||
hasStream() ||
|
hasStream() ||
|
||||||
hasFormat() ||
|
hasFormat() ||
|
||||||
isShaderRecordNV() ||
|
isShaderRecord() ||
|
||||||
isPushConstant() ||
|
isPushConstant() ||
|
||||||
hasBufferReference();
|
hasBufferReference();
|
||||||
}
|
}
|
||||||
@@ -871,7 +887,7 @@ public:
|
|||||||
bool layoutPassthrough;
|
bool layoutPassthrough;
|
||||||
bool layoutViewportRelative;
|
bool layoutViewportRelative;
|
||||||
int layoutSecondaryViewportRelativeOffset;
|
int layoutSecondaryViewportRelativeOffset;
|
||||||
bool layoutShaderRecordNV;
|
bool layoutShaderRecord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool hasUniformLayout() const
|
bool hasUniformLayout() const
|
||||||
@@ -942,7 +958,7 @@ public:
|
|||||||
bool hasAttachment() const { return false; }
|
bool hasAttachment() const { return false; }
|
||||||
TLayoutFormat getFormat() const { return ElfNone; }
|
TLayoutFormat getFormat() const { return ElfNone; }
|
||||||
bool isPushConstant() const { return false; }
|
bool isPushConstant() const { return false; }
|
||||||
bool isShaderRecordNV() const { return false; }
|
bool isShaderRecord() const { return false; }
|
||||||
bool hasBufferReference() const { return false; }
|
bool hasBufferReference() const { return false; }
|
||||||
bool hasBufferReferenceAlign() const { return false; }
|
bool hasBufferReferenceAlign() const { return false; }
|
||||||
bool isNonUniform() const { return false; }
|
bool isNonUniform() const { return false; }
|
||||||
@@ -993,7 +1009,7 @@ public:
|
|||||||
}
|
}
|
||||||
TLayoutFormat getFormat() const { return layoutFormat; }
|
TLayoutFormat getFormat() const { return layoutFormat; }
|
||||||
bool isPushConstant() const { return layoutPushConstant; }
|
bool isPushConstant() const { return layoutPushConstant; }
|
||||||
bool isShaderRecordNV() const { return layoutShaderRecordNV; }
|
bool isShaderRecord() const { return layoutShaderRecord; }
|
||||||
bool hasBufferReference() const { return layoutBufferReference; }
|
bool hasBufferReference() const { return layoutBufferReference; }
|
||||||
bool hasBufferReferenceAlign() const
|
bool hasBufferReferenceAlign() const
|
||||||
{
|
{
|
||||||
@@ -1219,6 +1235,7 @@ struct TShaderQualifiers {
|
|||||||
bool layoutDerivativeGroupQuads; // true if layout derivative_group_quadsNV set
|
bool layoutDerivativeGroupQuads; // true if layout derivative_group_quadsNV set
|
||||||
bool layoutDerivativeGroupLinear; // true if layout derivative_group_linearNV set
|
bool layoutDerivativeGroupLinear; // true if layout derivative_group_linearNV set
|
||||||
int primitives; // mesh shader "max_primitives"DerivativeGroupLinear; // 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
|
||||||
TLayoutDepth getDepth() const { return layoutDepth; }
|
TLayoutDepth getDepth() const { return layoutDepth; }
|
||||||
#else
|
#else
|
||||||
TLayoutDepth getDepth() const { return EldNone; }
|
TLayoutDepth getDepth() const { return EldNone; }
|
||||||
@@ -1252,6 +1269,7 @@ struct TShaderQualifiers {
|
|||||||
layoutOverrideCoverage = false;
|
layoutOverrideCoverage = false;
|
||||||
layoutDerivativeGroupQuads = false;
|
layoutDerivativeGroupQuads = false;
|
||||||
layoutDerivativeGroupLinear = false;
|
layoutDerivativeGroupLinear = false;
|
||||||
|
layoutPrimitiveCulling = false;
|
||||||
primitives = TQualifier::layoutNotSet;
|
primitives = TQualifier::layoutNotSet;
|
||||||
interlockOrdering = EioNone;
|
interlockOrdering = EioNone;
|
||||||
#endif
|
#endif
|
||||||
@@ -1315,6 +1333,8 @@ struct TShaderQualifiers {
|
|||||||
primitives = src.primitives;
|
primitives = src.primitives;
|
||||||
if (src.interlockOrdering != EioNone)
|
if (src.interlockOrdering != EioNone)
|
||||||
interlockOrdering = src.interlockOrdering;
|
interlockOrdering = src.interlockOrdering;
|
||||||
|
if (src.layoutPrimitiveCulling)
|
||||||
|
layoutPrimitiveCulling = src.layoutPrimitiveCulling;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1612,6 +1632,23 @@ public:
|
|||||||
assert(fieldName);
|
assert(fieldName);
|
||||||
return *fieldName;
|
return *fieldName;
|
||||||
}
|
}
|
||||||
|
TShaderInterface getShaderInterface() const
|
||||||
|
{
|
||||||
|
if (basicType != EbtBlock)
|
||||||
|
return EsiNone;
|
||||||
|
|
||||||
|
switch (qualifier.storage) {
|
||||||
|
default:
|
||||||
|
return EsiNone;
|
||||||
|
case EvqVaryingIn:
|
||||||
|
return EsiInput;
|
||||||
|
case EvqVaryingOut:
|
||||||
|
return EsiOutput;
|
||||||
|
case EvqUniform:
|
||||||
|
case EvqBuffer:
|
||||||
|
return EsiUniform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual TBasicType getBasicType() const { return basicType; }
|
virtual TBasicType getBasicType() const { return basicType; }
|
||||||
virtual const TSampler& getSampler() const { return sampler; }
|
virtual const TSampler& getSampler() const { return sampler; }
|
||||||
@@ -1670,7 +1707,7 @@ public:
|
|||||||
}
|
}
|
||||||
virtual bool isOpaque() const { return basicType == EbtSampler
|
virtual bool isOpaque() const { return basicType == EbtSampler
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
|| basicType == EbtAtomicUint || basicType == EbtAccStructNV
|
|| basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
|
||||||
#endif
|
#endif
|
||||||
; }
|
; }
|
||||||
virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
|
virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
|
||||||
@@ -1946,7 +1983,8 @@ public:
|
|||||||
case EbtAtomicUint: return "atomic_uint";
|
case EbtAtomicUint: return "atomic_uint";
|
||||||
case EbtStruct: return "structure";
|
case EbtStruct: return "structure";
|
||||||
case EbtBlock: return "block";
|
case EbtBlock: return "block";
|
||||||
case EbtAccStructNV: return "accelerationStructureNV";
|
case EbtAccStruct: return "accelerationStructureNV";
|
||||||
|
case EbtRayQuery: return "rayQueryEXT";
|
||||||
case EbtReference: return "reference";
|
case EbtReference: return "reference";
|
||||||
#endif
|
#endif
|
||||||
default: return "unknown type";
|
default: return "unknown type";
|
||||||
@@ -2056,7 +2094,7 @@ public:
|
|||||||
appendStr(" layoutSecondaryViewportRelativeOffset=");
|
appendStr(" layoutSecondaryViewportRelativeOffset=");
|
||||||
appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
|
appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
|
||||||
}
|
}
|
||||||
if (qualifier.layoutShaderRecordNV)
|
if (qualifier.layoutShaderRecord)
|
||||||
appendStr(" shaderRecordNV");
|
appendStr(" shaderRecordNV");
|
||||||
|
|
||||||
appendStr(")");
|
appendStr(")");
|
||||||
@@ -2099,6 +2137,8 @@ public:
|
|||||||
appendStr(" workgroupcoherent");
|
appendStr(" workgroupcoherent");
|
||||||
if (qualifier.subgroupcoherent)
|
if (qualifier.subgroupcoherent)
|
||||||
appendStr(" subgroupcoherent");
|
appendStr(" subgroupcoherent");
|
||||||
|
if (qualifier.shadercallcoherent)
|
||||||
|
appendStr(" shadercallcoherent");
|
||||||
if (qualifier.nonprivate)
|
if (qualifier.nonprivate)
|
||||||
appendStr(" nonprivate");
|
appendStr(" nonprivate");
|
||||||
if (qualifier.volatil)
|
if (qualifier.volatil)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2016 LunarG, Inc.
|
// Copyright (C) 2012-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -621,6 +622,8 @@ enum TOperator {
|
|||||||
|
|
||||||
EOpIsHelperInvocation,
|
EOpIsHelperInvocation,
|
||||||
|
|
||||||
|
EOpDebugPrintf,
|
||||||
|
|
||||||
//
|
//
|
||||||
// Branch
|
// Branch
|
||||||
//
|
//
|
||||||
@@ -908,12 +911,41 @@ enum TOperator {
|
|||||||
EOpAverageRounded,
|
EOpAverageRounded,
|
||||||
EOpMul32x16,
|
EOpMul32x16,
|
||||||
|
|
||||||
EOpTraceNV,
|
EOpTrace,
|
||||||
EOpReportIntersectionNV,
|
EOpReportIntersection,
|
||||||
EOpIgnoreIntersectionNV,
|
EOpIgnoreIntersection,
|
||||||
EOpTerminateRayNV,
|
EOpTerminateRay,
|
||||||
EOpExecuteCallableNV,
|
EOpExecuteCallable,
|
||||||
EOpWritePackedPrimitiveIndices4x8NV,
|
EOpWritePackedPrimitiveIndices4x8NV,
|
||||||
|
|
||||||
|
//
|
||||||
|
// GL_EXT_ray_query operations
|
||||||
|
//
|
||||||
|
|
||||||
|
EOpRayQueryInitialize,
|
||||||
|
EOpRayQueryTerminate,
|
||||||
|
EOpRayQueryGenerateIntersection,
|
||||||
|
EOpRayQueryConfirmIntersection,
|
||||||
|
EOpRayQueryProceed,
|
||||||
|
EOpRayQueryGetIntersectionType,
|
||||||
|
EOpRayQueryGetRayTMin,
|
||||||
|
EOpRayQueryGetRayFlags,
|
||||||
|
EOpRayQueryGetIntersectionT,
|
||||||
|
EOpRayQueryGetIntersectionInstanceCustomIndex,
|
||||||
|
EOpRayQueryGetIntersectionInstanceId,
|
||||||
|
EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset,
|
||||||
|
EOpRayQueryGetIntersectionGeometryIndex,
|
||||||
|
EOpRayQueryGetIntersectionPrimitiveIndex,
|
||||||
|
EOpRayQueryGetIntersectionBarycentrics,
|
||||||
|
EOpRayQueryGetIntersectionFrontFace,
|
||||||
|
EOpRayQueryGetIntersectionCandidateAABBOpaque,
|
||||||
|
EOpRayQueryGetIntersectionObjectRayDirection,
|
||||||
|
EOpRayQueryGetIntersectionObjectRayOrigin,
|
||||||
|
EOpRayQueryGetWorldRayDirection,
|
||||||
|
EOpRayQueryGetWorldRayOrigin,
|
||||||
|
EOpRayQueryGetIntersectionObjectToWorld,
|
||||||
|
EOpRayQueryGetIntersectionWorldToObject,
|
||||||
|
|
||||||
//
|
//
|
||||||
// HLSL operations
|
// HLSL operations
|
||||||
//
|
//
|
||||||
@@ -1199,6 +1231,7 @@ public:
|
|||||||
TOperator getFlowOp() const { return flowOp; }
|
TOperator getFlowOp() const { return flowOp; }
|
||||||
TIntermTyped* getExpression() const { return expression; }
|
TIntermTyped* getExpression() const { return expression; }
|
||||||
void setExpression(TIntermTyped* pExpression) { expression = pExpression; }
|
void setExpression(TIntermTyped* pExpression) { expression = pExpression; }
|
||||||
|
void updatePrecision(TPrecisionQualifier parentPrecision);
|
||||||
protected:
|
protected:
|
||||||
TOperator flowOp;
|
TOperator flowOp;
|
||||||
TIntermTyped* expression;
|
TIntermTyped* expression;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
// Copyright (C) 2018 Google, Inc.
|
// Copyright (C) 2018-2020 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -1012,6 +1012,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
case EOpMin:
|
case EOpMin:
|
||||||
case EOpMax:
|
case EOpMax:
|
||||||
case EOpMix:
|
case EOpMix:
|
||||||
|
case EOpMod:
|
||||||
case EOpClamp:
|
case EOpClamp:
|
||||||
case EOpLessThan:
|
case EOpLessThan:
|
||||||
case EOpGreaterThan:
|
case EOpGreaterThan:
|
||||||
@@ -1074,6 +1075,14 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
case EOpPow:
|
case EOpPow:
|
||||||
newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
||||||
break;
|
break;
|
||||||
|
case EOpMod:
|
||||||
|
{
|
||||||
|
double arg0 = childConstUnions[0][arg0comp].getDConst();
|
||||||
|
double arg1 = childConstUnions[1][arg1comp].getDConst();
|
||||||
|
double result = arg0 - arg1 * floor(arg0 / arg1);
|
||||||
|
newConstArray[comp].setDConst(result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case EOpMin:
|
case EOpMin:
|
||||||
switch(children[0]->getAsTyped()->getBasicType()) {
|
switch(children[0]->getAsTyped()->getBasicType()) {
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Executable → Regular
+214
-185
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2015 LunarG, Inc.
|
// Copyright (C) 2012-2015 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2020 Google, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
@@ -113,14 +113,14 @@ TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc
|
|||||||
//
|
//
|
||||||
// Returns nullptr if the working conversions and promotions could not be found.
|
// Returns nullptr if the working conversions and promotions could not be found.
|
||||||
//
|
//
|
||||||
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
|
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc)
|
||||||
{
|
{
|
||||||
// No operations work on blocks
|
// No operations work on blocks
|
||||||
if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
|
if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Convert "reference +/- int" and "reference - reference" to integer math
|
// Convert "reference +/- int" and "reference - reference" to integer math
|
||||||
if ((op == EOpAdd || op == EOpSub) && extensionRequested(E_GL_EXT_buffer_reference2)) {
|
if (op == EOpAdd || op == EOpSub) {
|
||||||
|
|
||||||
// No addressing math on struct with unsized array.
|
// No addressing math on struct with unsized array.
|
||||||
if ((left->isReference() && left->getType().getReferentType()->containsUnsizedArray()) ||
|
if ((left->isReference() && left->getType().getReferentType()->containsUnsizedArray()) ||
|
||||||
@@ -140,43 +140,44 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||||||
node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
|
node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == EOpAdd && right->isReference() && isTypeInt(left->getBasicType())) {
|
|
||||||
const TType& referenceType = right->getType();
|
|
||||||
TIntermConstantUnion* size = addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(right->getType()), loc, true);
|
|
||||||
right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));
|
|
||||||
|
|
||||||
left = createConversion(EbtInt64, left);
|
|
||||||
left = addBinaryMath(EOpMul, left, size, loc);
|
|
||||||
|
|
||||||
TIntermTyped *node = addBinaryMath(op, left, right, loc);
|
|
||||||
node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op == EOpSub && left->isReference() && right->isReference()) {
|
|
||||||
TIntermConstantUnion* size = addConstantUnion((long long)computeBufferReferenceTypeSize(left->getType()), loc, true);
|
|
||||||
|
|
||||||
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 = addBinaryMath(EOpSub, left, right, loc);
|
|
||||||
|
|
||||||
TIntermTyped *node = addBinaryMath(EOpDiv, left, size, loc);
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No other math operators supported on references
|
|
||||||
if (left->isReference() || right->isReference()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (op == EOpAdd && right->isReference() && isTypeInt(left->getBasicType())) {
|
||||||
|
const TType& referenceType = right->getType();
|
||||||
|
TIntermConstantUnion* size =
|
||||||
|
addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(right->getType()), loc, true);
|
||||||
|
right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));
|
||||||
|
|
||||||
|
left = createConversion(EbtInt64, left);
|
||||||
|
left = addBinaryMath(EOpMul, left, size, loc);
|
||||||
|
|
||||||
|
TIntermTyped *node = addBinaryMath(op, left, right, loc);
|
||||||
|
node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op == EOpSub && left->isReference() && right->isReference()) {
|
||||||
|
TIntermConstantUnion* size =
|
||||||
|
addConstantUnion((long long)computeBufferReferenceTypeSize(left->getType()), loc, true);
|
||||||
|
|
||||||
|
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 = addBinaryMath(EOpSub, left, right, loc);
|
||||||
|
|
||||||
|
TIntermTyped *node = addBinaryMath(EOpDiv, left, size, loc);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No other math operators supported on references
|
||||||
|
if (left->isReference() || right->isReference())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
// Try converting the children's base types to compatible types.
|
// Try converting the children's base types to compatible types.
|
||||||
auto children = addConversion(op, left, right);
|
auto children = addPairConversion(op, left, right);
|
||||||
left = std::get<0>(children);
|
left = std::get<0>(children);
|
||||||
right = std::get<1>(children);
|
right = std::get<1>(children);
|
||||||
|
|
||||||
@@ -226,13 +227,12 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||||||
//
|
//
|
||||||
// Low level: add binary node (no promotions or other argument modifications)
|
// Low level: add binary node (no promotions or other argument modifications)
|
||||||
//
|
//
|
||||||
TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) const
|
TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right,
|
||||||
|
const TSourceLoc& loc) const
|
||||||
{
|
{
|
||||||
// build the node
|
// build the node
|
||||||
TIntermBinary* node = new TIntermBinary(op);
|
TIntermBinary* node = new TIntermBinary(op);
|
||||||
if (loc.line == 0)
|
node->setLoc(loc.line != 0 ? loc : left->getLoc());
|
||||||
loc = left->getLoc();
|
|
||||||
node->setLoc(loc);
|
|
||||||
node->setLeft(left);
|
node->setLeft(left);
|
||||||
node->setRight(right);
|
node->setRight(right);
|
||||||
|
|
||||||
@@ -242,7 +242,8 @@ TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TI
|
|||||||
//
|
//
|
||||||
// like non-type form, but sets node's type.
|
// like non-type form, but sets node's type.
|
||||||
//
|
//
|
||||||
TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc, const TType& type) const
|
TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right,
|
||||||
|
const TSourceLoc& loc, const TType& type) const
|
||||||
{
|
{
|
||||||
TIntermBinary* node = addBinaryNode(op, left, right, loc);
|
TIntermBinary* node = addBinaryNode(op, left, right, loc);
|
||||||
node->setType(type);
|
node->setType(type);
|
||||||
@@ -252,12 +253,10 @@ TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TI
|
|||||||
//
|
//
|
||||||
// Low level: add unary node (no promotions or other argument modifications)
|
// Low level: add unary node (no promotions or other argument modifications)
|
||||||
//
|
//
|
||||||
TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc) const
|
TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc& loc) const
|
||||||
{
|
{
|
||||||
TIntermUnary* node = new TIntermUnary(op);
|
TIntermUnary* node = new TIntermUnary(op);
|
||||||
if (loc.line == 0)
|
node->setLoc(loc.line != 0 ? loc : child->getLoc());
|
||||||
loc = child->getLoc();
|
|
||||||
node->setLoc(loc);
|
|
||||||
node->setOperand(child);
|
node->setOperand(child);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
@@ -266,7 +265,8 @@ TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSo
|
|||||||
//
|
//
|
||||||
// like non-type form, but sets node's type.
|
// like non-type form, but sets node's type.
|
||||||
//
|
//
|
||||||
TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc, const TType& type) const
|
TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc& loc, const TType& type)
|
||||||
|
const
|
||||||
{
|
{
|
||||||
TIntermUnary* node = addUnaryNode(op, child, loc);
|
TIntermUnary* node = addUnaryNode(op, child, loc);
|
||||||
node->setType(type);
|
node->setType(type);
|
||||||
@@ -281,7 +281,8 @@ TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSo
|
|||||||
// Returns nullptr if the 'right' type could not be converted to match the 'left' type,
|
// Returns nullptr if the 'right' type could not be converted to match the 'left' type,
|
||||||
// or the resulting operation cannot be properly promoted.
|
// or the resulting operation cannot be properly promoted.
|
||||||
//
|
//
|
||||||
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
|
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right,
|
||||||
|
const TSourceLoc& loc)
|
||||||
{
|
{
|
||||||
// No block assignment
|
// No block assignment
|
||||||
if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
|
if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
|
||||||
@@ -290,9 +291,7 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
|
|||||||
// Convert "reference += int" to "reference = reference + int". We need this because the
|
// Convert "reference += int" to "reference = reference + int". We need this because the
|
||||||
// "reference + int" calculation involves a cast back to the original type, which makes it
|
// "reference + int" calculation involves a cast back to the original type, which makes it
|
||||||
// not an lvalue.
|
// not an lvalue.
|
||||||
if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference() &&
|
if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference()) {
|
||||||
extensionRequested(E_GL_EXT_buffer_reference2)) {
|
|
||||||
|
|
||||||
if (!(right->getType().isScalar() && right->getType().isIntegerDomain()))
|
if (!(right->getType().isScalar() && right->getType().isIntegerDomain()))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -338,7 +337,8 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
|
|||||||
// Returns the added node.
|
// Returns the added node.
|
||||||
// The caller should set the type of the returned node.
|
// The caller should set the type of the returned node.
|
||||||
//
|
//
|
||||||
TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc)
|
TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index,
|
||||||
|
const TSourceLoc& loc)
|
||||||
{
|
{
|
||||||
// caller should set the type
|
// caller should set the type
|
||||||
return addBinaryNode(op, base, index, loc);
|
return addBinaryNode(op, base, index, loc);
|
||||||
@@ -349,7 +349,8 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT
|
|||||||
//
|
//
|
||||||
// Returns the added node.
|
// Returns the added node.
|
||||||
//
|
//
|
||||||
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc)
|
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
|
||||||
|
const TSourceLoc& loc)
|
||||||
{
|
{
|
||||||
if (child == 0)
|
if (child == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -495,7 +496,8 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOper
|
|||||||
// Returns an aggregate node, which could be the one passed in if
|
// Returns an aggregate node, which could be the one passed in if
|
||||||
// it was already an aggregate.
|
// it was already an aggregate.
|
||||||
//
|
//
|
||||||
TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc)
|
TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type,
|
||||||
|
const TSourceLoc& loc)
|
||||||
{
|
{
|
||||||
TIntermAggregate* aggNode;
|
TIntermAggregate* aggNode;
|
||||||
|
|
||||||
@@ -510,8 +512,6 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o
|
|||||||
//
|
//
|
||||||
aggNode = new TIntermAggregate();
|
aggNode = new TIntermAggregate();
|
||||||
aggNode->getSequence().push_back(node);
|
aggNode->getSequence().push_back(node);
|
||||||
if (loc.line == 0)
|
|
||||||
loc = node->getLoc();
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
aggNode = new TIntermAggregate();
|
aggNode = new TIntermAggregate();
|
||||||
@@ -520,8 +520,8 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o
|
|||||||
// Set the operator.
|
// Set the operator.
|
||||||
//
|
//
|
||||||
aggNode->setOperator(op);
|
aggNode->setOperator(op);
|
||||||
if (loc.line != 0)
|
if (loc.line != 0 || node != nullptr)
|
||||||
aggNode->setLoc(loc);
|
aggNode->setLoc(loc.line != 0 ? loc : node->getLoc());
|
||||||
|
|
||||||
aggNode->setType(type);
|
aggNode->setType(type);
|
||||||
|
|
||||||
@@ -538,7 +538,7 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const
|
|||||||
return false;
|
return false;
|
||||||
case EbtAtomicUint:
|
case EbtAtomicUint:
|
||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
case EbtAccStructNV:
|
case EbtAccStruct:
|
||||||
// opaque types can be passed to functions
|
// opaque types can be passed to functions
|
||||||
if (op == EOpFunction)
|
if (op == EOpFunction)
|
||||||
break;
|
break;
|
||||||
@@ -819,22 +819,25 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped
|
|||||||
node->getBasicType() == EbtFloat ||
|
node->getBasicType() == EbtFloat ||
|
||||||
node->getBasicType() == EbtDouble);
|
node->getBasicType() == EbtDouble);
|
||||||
|
|
||||||
if (! getArithemeticInt8Enabled()) {
|
if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) ||
|
||||||
if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) ||
|
((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes)) {
|
||||||
((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes))
|
if (! getArithemeticInt8Enabled()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! getArithemeticInt16Enabled()) {
|
if (((convertTo == EbtInt16 || convertTo == EbtUint16) && ! convertFromIntTypes) ||
|
||||||
if (((convertTo == EbtInt16 || convertTo == EbtUint16) && ! convertFromIntTypes) ||
|
((node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16) && ! convertToIntTypes)) {
|
||||||
((node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16) && ! convertToIntTypes))
|
if (! getArithemeticInt16Enabled()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! getArithemeticFloat16Enabled()) {
|
if ((convertTo == EbtFloat16 && ! convertFromFloatTypes) ||
|
||||||
if ((convertTo == EbtFloat16 && ! convertFromFloatTypes) ||
|
(node->getBasicType() == EbtFloat16 && ! convertToFloatTypes)) {
|
||||||
(node->getBasicType() == EbtFloat16 && ! convertToFloatTypes))
|
if (! getArithemeticFloat16Enabled()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -887,7 +890,7 @@ TIntermTyped* TIntermediate::addConversion(TBasicType convertTo, TIntermTyped* n
|
|||||||
// Returns the converted pair of nodes.
|
// Returns the converted pair of nodes.
|
||||||
// Returns <nullptr, nullptr> when there is no conversion.
|
// Returns <nullptr, nullptr> when there is no conversion.
|
||||||
std::tuple<TIntermTyped*, TIntermTyped*>
|
std::tuple<TIntermTyped*, TIntermTyped*>
|
||||||
TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1)
|
TIntermediate::addPairConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1)
|
||||||
{
|
{
|
||||||
if (!isConversionAllowed(op, node0) || !isConversionAllowed(op, node1))
|
if (!isConversionAllowed(op, node0) || !isConversionAllowed(op, node1))
|
||||||
return std::make_tuple(nullptr, nullptr);
|
return std::make_tuple(nullptr, nullptr);
|
||||||
@@ -940,7 +943,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no
|
|||||||
if (node0->getBasicType() == node1->getBasicType())
|
if (node0->getBasicType() == node1->getBasicType())
|
||||||
return std::make_tuple(node0, node1);
|
return std::make_tuple(node0, node1);
|
||||||
|
|
||||||
promoteTo = getConversionDestinatonType(node0->getBasicType(), node1->getBasicType(), op);
|
promoteTo = getConversionDestinationType(node0->getBasicType(), node1->getBasicType(), op);
|
||||||
if (std::get<0>(promoteTo) == EbtNumTypes || std::get<1>(promoteTo) == EbtNumTypes)
|
if (std::get<0>(promoteTo) == EbtNumTypes || std::get<1>(promoteTo) == EbtNumTypes)
|
||||||
return std::make_tuple(nullptr, nullptr);
|
return std::make_tuple(nullptr, nullptr);
|
||||||
|
|
||||||
@@ -1040,64 +1043,30 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
// Note: callers are responsible for other aspects of shape,
|
// Note: callers are responsible for other aspects of shape,
|
||||||
// like vector and matrix sizes.
|
// like vector and matrix sizes.
|
||||||
|
|
||||||
TBasicType promoteTo;
|
|
||||||
// GL_EXT_shader_16bit_storage can't do OpConstantComposite with
|
|
||||||
// 16-bit types, so disable promotion for those types.
|
|
||||||
bool canPromoteConstant = true;
|
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
//
|
//
|
||||||
// Explicit conversions (unary operations)
|
// Explicit conversions (unary operations)
|
||||||
//
|
//
|
||||||
case EOpConstructBool:
|
case EOpConstructBool:
|
||||||
promoteTo = EbtBool;
|
|
||||||
break;
|
|
||||||
case EOpConstructFloat:
|
case EOpConstructFloat:
|
||||||
promoteTo = EbtFloat;
|
|
||||||
break;
|
|
||||||
case EOpConstructInt:
|
case EOpConstructInt:
|
||||||
promoteTo = EbtInt;
|
|
||||||
break;
|
|
||||||
case EOpConstructUint:
|
case EOpConstructUint:
|
||||||
promoteTo = EbtUint;
|
|
||||||
break;
|
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
case EOpConstructDouble:
|
case EOpConstructDouble:
|
||||||
promoteTo = EbtDouble;
|
|
||||||
break;
|
|
||||||
case EOpConstructFloat16:
|
case EOpConstructFloat16:
|
||||||
promoteTo = EbtFloat16;
|
|
||||||
canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16);
|
|
||||||
break;
|
|
||||||
case EOpConstructInt8:
|
case EOpConstructInt8:
|
||||||
promoteTo = EbtInt8;
|
|
||||||
canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8);
|
|
||||||
break;
|
|
||||||
case EOpConstructUint8:
|
case EOpConstructUint8:
|
||||||
promoteTo = EbtUint8;
|
|
||||||
canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8);
|
|
||||||
break;
|
|
||||||
case EOpConstructInt16:
|
case EOpConstructInt16:
|
||||||
promoteTo = EbtInt16;
|
|
||||||
canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16);
|
|
||||||
break;
|
|
||||||
case EOpConstructUint16:
|
case EOpConstructUint16:
|
||||||
promoteTo = EbtUint16;
|
|
||||||
canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16);
|
|
||||||
break;
|
|
||||||
case EOpConstructInt64:
|
case EOpConstructInt64:
|
||||||
promoteTo = EbtInt64;
|
|
||||||
break;
|
|
||||||
case EOpConstructUint64:
|
case EOpConstructUint64:
|
||||||
promoteTo = EbtUint64;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implicit conversions
|
||||||
|
//
|
||||||
case EOpLogicalNot:
|
case EOpLogicalNot:
|
||||||
|
|
||||||
case EOpFunctionCall:
|
case EOpFunctionCall:
|
||||||
@@ -1152,9 +1121,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
if (type.getBasicType() == node->getType().getBasicType())
|
if (type.getBasicType() == node->getType().getBasicType())
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
if (canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op))
|
if (! canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op))
|
||||||
promoteTo = type.getBasicType();
|
|
||||||
else
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1164,9 +1131,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
case EOpLeftShiftAssign:
|
case EOpLeftShiftAssign:
|
||||||
case EOpRightShiftAssign:
|
case EOpRightShiftAssign:
|
||||||
{
|
{
|
||||||
if (getSource() == EShSourceHlsl && node->getType().getBasicType() == EbtBool)
|
if (!(getSource() == EShSourceHlsl && node->getType().getBasicType() == EbtBool)) {
|
||||||
promoteTo = type.getBasicType();
|
|
||||||
else {
|
|
||||||
if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType()))
|
if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType()))
|
||||||
return node;
|
return node;
|
||||||
else
|
else
|
||||||
@@ -1184,13 +1149,44 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool canPromoteConstant = true;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
// GL_EXT_shader_16bit_storage can't do OpConstantComposite with
|
||||||
|
// 16-bit types, so disable promotion for those types.
|
||||||
|
// Many issues with this, from JohnK:
|
||||||
|
// - this isn't really right to discuss SPIR-V here
|
||||||
|
// - this could easily be entirely about scalars, so is overstepping
|
||||||
|
// - we should be looking at what the shader asked for, and saying whether or
|
||||||
|
// not it can be done, in the parser, by calling requireExtensions(), not
|
||||||
|
// 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 EOpConstructFloat16:
|
||||||
|
canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
|
||||||
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16);
|
||||||
|
break;
|
||||||
|
case EOpConstructInt8:
|
||||||
|
case EOpConstructUint8:
|
||||||
|
canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
|
||||||
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8);
|
||||||
|
break;
|
||||||
|
case EOpConstructInt16:
|
||||||
|
case EOpConstructUint16:
|
||||||
|
canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
|
||||||
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (canPromoteConstant && node->getAsConstantUnion())
|
if (canPromoteConstant && node->getAsConstantUnion())
|
||||||
return promoteConstantUnion(promoteTo, node->getAsConstantUnion());
|
return promoteConstantUnion(type.getBasicType(), node->getAsConstantUnion());
|
||||||
|
|
||||||
//
|
//
|
||||||
// Add a new newNode for the conversion.
|
// Add a new newNode for the conversion.
|
||||||
//
|
//
|
||||||
TIntermTyped* newNode = createConversion(promoteTo, node);
|
TIntermTyped* newNode = createConversion(type.getBasicType(), node);
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
@@ -1620,7 +1616,7 @@ bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const
|
|||||||
//
|
//
|
||||||
bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const
|
bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const
|
||||||
{
|
{
|
||||||
if (isEsProfile() || version == 110)
|
if ((isEsProfile() && version < 310 ) || version == 110)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (from == to)
|
if (from == to)
|
||||||
@@ -1659,46 +1655,51 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool explicitTypesEnabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
if (getSource() == EShSourceHlsl) {
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8) ||
|
// HLSL
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16) ||
|
if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat))
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int32) ||
|
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int64) ||
|
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16) ||
|
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float32) ||
|
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float64);
|
|
||||||
|
|
||||||
if (explicitTypesEnabled) {
|
|
||||||
// integral promotions
|
|
||||||
if (isIntegralPromotion(from, to)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
|
// GLSL
|
||||||
|
if (isIntegralPromotion(from, to) ||
|
||||||
|
isFPPromotion(from, to) ||
|
||||||
|
isIntegralConversion(from, to) ||
|
||||||
|
isFPConversion(from, to) ||
|
||||||
|
isFPIntegralConversion(from, to)) {
|
||||||
|
|
||||||
// floating-point promotions
|
if (numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
|
||||||
if (isFPPromotion(from, to)) {
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8) ||
|
||||||
return true;
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16) ||
|
||||||
}
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int32) ||
|
||||||
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int64) ||
|
||||||
// integral conversions
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16) ||
|
||||||
if (isIntegralConversion(from, to)) {
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float32) ||
|
||||||
return true;
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float64)) {
|
||||||
}
|
|
||||||
|
|
||||||
// floating-point conversions
|
|
||||||
if (isFPConversion(from, to)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// floating-integral conversions
|
|
||||||
if (isFPIntegralConversion(from, to)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// hlsl supported conversions
|
|
||||||
if (getSource() == EShSourceHlsl) {
|
|
||||||
if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat))
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEsProfile()) {
|
||||||
|
switch (to) {
|
||||||
|
case EbtFloat:
|
||||||
|
switch (from) {
|
||||||
|
case EbtInt:
|
||||||
|
case EbtUint:
|
||||||
|
return numericFeatures.contains(TNumericFeatures::shader_implicit_conversions);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case EbtUint:
|
||||||
|
switch (from) {
|
||||||
|
case EbtInt:
|
||||||
|
return numericFeatures.contains(TNumericFeatures::shader_implicit_conversions);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (to) {
|
switch (to) {
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
@@ -1708,13 +1709,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
case EbtFloat:
|
case EbtFloat:
|
||||||
case EbtDouble:
|
return version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64);
|
||||||
return true;
|
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) &&
|
||||||
|
numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_half_float);
|
return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) &&
|
||||||
|
numericFeatures.contains(TNumericFeatures::gpu_shader_half_float);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1722,16 +1724,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
switch (from) {
|
switch (from) {
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
case EbtFloat:
|
|
||||||
return true;
|
return true;
|
||||||
case EbtBool:
|
case EbtBool:
|
||||||
return getSource() == EShSourceHlsl;
|
return getSource() == EShSourceHlsl;
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
return
|
return numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) ||
|
||||||
extensionRequested(E_GL_AMD_gpu_shader_half_float) ||
|
|
||||||
getSource() == EShSourceHlsl;
|
getSource() == EShSourceHlsl;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -1739,25 +1739,21 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
case EbtUint:
|
case EbtUint:
|
||||||
switch (from) {
|
switch (from) {
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
return version >= 400 || getSource() == EShSourceHlsl;
|
return version >= 400 || getSource() == EShSourceHlsl;
|
||||||
case EbtUint:
|
|
||||||
return true;
|
|
||||||
case EbtBool:
|
case EbtBool:
|
||||||
return getSource() == EShSourceHlsl;
|
return getSource() == EShSourceHlsl;
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch (from) {
|
switch (from) {
|
||||||
case EbtInt:
|
|
||||||
return true;
|
|
||||||
case EbtBool:
|
case EbtBool:
|
||||||
return getSource() == EShSourceHlsl;
|
return getSource() == EShSourceHlsl;
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1766,21 +1762,19 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
case EbtInt:
|
case EbtInt:
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
case EbtUint64:
|
|
||||||
return true;
|
return true;
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
switch (from) {
|
switch (from) {
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
case EbtInt64:
|
|
||||||
return true;
|
return true;
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1788,9 +1782,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
switch (from) {
|
switch (from) {
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
|
||||||
case EbtFloat16:
|
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_half_float);
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1798,8 +1790,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
switch (from) {
|
switch (from) {
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16:
|
return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
|
||||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1926,12 +1917,14 @@ static TBasicType getCorrespondingUnsignedType(TBasicType type)
|
|||||||
// integer type corresponding to the type of the operand with signed
|
// integer type corresponding to the type of the operand with signed
|
||||||
// integer type.
|
// integer type.
|
||||||
|
|
||||||
std::tuple<TBasicType, TBasicType> TIntermediate::getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const
|
std::tuple<TBasicType, TBasicType> TIntermediate::getConversionDestinationType(TBasicType type0, TBasicType type1, TOperator op) const
|
||||||
{
|
{
|
||||||
TBasicType res0 = EbtNumTypes;
|
TBasicType res0 = EbtNumTypes;
|
||||||
TBasicType res1 = EbtNumTypes;
|
TBasicType res1 = EbtNumTypes;
|
||||||
|
|
||||||
if (isEsProfile() || version == 110)
|
if ((isEsProfile() &&
|
||||||
|
(version < 310 || !numericFeatures.contains(TNumericFeatures::shader_implicit_conversions))) ||
|
||||||
|
version == 110)
|
||||||
return std::make_tuple(res0, res1);
|
return std::make_tuple(res0, res1);
|
||||||
|
|
||||||
if (getSource() == EShSourceHlsl) {
|
if (getSource() == EShSourceHlsl) {
|
||||||
@@ -2463,7 +2456,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
|
|||||||
//
|
//
|
||||||
// Get compatible types.
|
// Get compatible types.
|
||||||
//
|
//
|
||||||
auto children = addConversion(EOpSequence, trueBlock, falseBlock);
|
auto children = addPairConversion(EOpSequence, trueBlock, falseBlock);
|
||||||
trueBlock = std::get<0>(children);
|
trueBlock = std::get<0>(children);
|
||||||
falseBlock = std::get<1>(children);
|
falseBlock = std::get<1>(children);
|
||||||
|
|
||||||
@@ -2750,6 +2743,22 @@ TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expres
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Propagate precision from formal function return type to actual return type,
|
||||||
|
// and on to its subtree.
|
||||||
|
void TIntermBranch::updatePrecision(TPrecisionQualifier parentPrecision)
|
||||||
|
{
|
||||||
|
TIntermTyped* exp = getExpression();
|
||||||
|
if (exp == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (exp->getBasicType() == EbtInt || exp->getBasicType() == EbtUint ||
|
||||||
|
exp->getBasicType() == EbtFloat || exp->getBasicType() == EbtFloat16) {
|
||||||
|
if (parentPrecision != EpqNone && exp->getQualifier().precision == EpqNone) {
|
||||||
|
exp->propagatePrecision(parentPrecision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// This is to be executed after the final root is put on top by the parsing
|
// This is to be executed after the final root is put on top by the parsing
|
||||||
// process.
|
// process.
|
||||||
@@ -2774,6 +2783,9 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
|
|||||||
case EShTexSampTransUpgradeTextureRemoveSampler:
|
case EShTexSampTransUpgradeTextureRemoveSampler:
|
||||||
performTextureUpgradeAndSamplerRemovalTransformation(root);
|
performTextureUpgradeAndSamplerRemovalTransformation(root);
|
||||||
break;
|
break;
|
||||||
|
case EShTexSampTransCount:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3234,10 +3246,17 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (operand->getBasicType() != EbtFloat)
|
// HLSL uses this path for initial function signature finding for built-ins
|
||||||
|
// taking a single argument, which generally don't participate in
|
||||||
|
// operator-based type promotion (type conversion will occur later).
|
||||||
|
// For now, scalar argument cases are relying on the setType() call below.
|
||||||
|
if (getSource() == EShSourceHlsl)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// GLSL only allows integer arguments for the cases identified above in the
|
||||||
|
// case statements.
|
||||||
|
if (operand->getBasicType() != EbtFloat)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3247,9 +3266,11 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Propagate precision qualifiers *up* from children to parent.
|
||||||
void TIntermUnary::updatePrecision()
|
void TIntermUnary::updatePrecision()
|
||||||
{
|
{
|
||||||
if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
|
||||||
|
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
||||||
if (operand->getQualifier().precision > getQualifier().precision)
|
if (operand->getQualifier().precision > getQualifier().precision)
|
||||||
getQualifier().precision = operand->getQualifier().precision;
|
getQualifier().precision = operand->getQualifier().precision;
|
||||||
}
|
}
|
||||||
@@ -3745,9 +3766,12 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Propagate precision qualifiers *up* from children to parent, and then
|
||||||
|
// back *down* again to the children's subtrees.
|
||||||
void TIntermBinary::updatePrecision()
|
void TIntermBinary::updatePrecision()
|
||||||
{
|
{
|
||||||
if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
|
||||||
|
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
||||||
getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
|
getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
|
||||||
if (getQualifier().precision != EpqNone) {
|
if (getQualifier().precision != EpqNone) {
|
||||||
left->propagatePrecision(getQualifier().precision);
|
left->propagatePrecision(getQualifier().precision);
|
||||||
@@ -3756,9 +3780,14 @@ void TIntermBinary::updatePrecision()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recursively propagate precision qualifiers *down* the subtree of the current node,
|
||||||
|
// until reaching a node that already has a precision qualifier or otherwise does
|
||||||
|
// not participate in precision propagation.
|
||||||
void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
|
void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
|
||||||
{
|
{
|
||||||
if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat && getBasicType() != EbtFloat16))
|
if (getQualifier().precision != EpqNone ||
|
||||||
|
(getBasicType() != EbtInt && getBasicType() != EbtUint &&
|
||||||
|
getBasicType() != EbtFloat && getBasicType() != EbtFloat16))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
getQualifier().precision = newPrecision;
|
getQualifier().precision = newPrecision;
|
||||||
|
|||||||
@@ -74,14 +74,33 @@ public:
|
|||||||
for (unsigned int f = 0; f < globals.size(); ++f) {
|
for (unsigned int f = 0; f < globals.size(); ++f) {
|
||||||
TIntermAggregate* candidate = globals[f]->getAsAggregate();
|
TIntermAggregate* candidate = globals[f]->getAsAggregate();
|
||||||
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
|
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
|
||||||
functions.push_back(candidate);
|
destinations.push_back(candidate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::list<TIntermAggregate*> TFunctionStack;
|
void pushGlobalReference(const TString& name)
|
||||||
TFunctionStack functions;
|
{
|
||||||
|
TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence();
|
||||||
|
for (unsigned int f = 0; f < globals.size(); ++f) {
|
||||||
|
TIntermAggregate* candidate = globals[f]->getAsAggregate();
|
||||||
|
if (candidate && candidate->getOp() == EOpSequence &&
|
||||||
|
candidate->getSequence().size() == 1 &&
|
||||||
|
candidate->getSequence()[0]->getAsBinaryNode()) {
|
||||||
|
TIntermBinary* binary = candidate->getSequence()[0]->getAsBinaryNode();
|
||||||
|
TIntermSymbol* symbol = binary->getLeft()->getAsSymbolNode();
|
||||||
|
if (symbol && symbol->getQualifier().storage == EvqGlobal &&
|
||||||
|
symbol->getName() == name) {
|
||||||
|
destinations.push_back(candidate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::list<TIntermAggregate*> TDestinationStack;
|
||||||
|
TDestinationStack destinations;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// To catch which function calls are not dead, and hence which functions must be visited.
|
// To catch which function calls are not dead, and hence which functions must be visited.
|
||||||
@@ -117,16 +136,27 @@ protected:
|
|||||||
// and only visit each function once.
|
// and only visit each function once.
|
||||||
void addFunctionCall(TIntermAggregate* call)
|
void addFunctionCall(TIntermAggregate* call)
|
||||||
{
|
{
|
||||||
// // just use the map to ensure we process each function at most once
|
// just use the map to ensure we process each function at most once
|
||||||
if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
|
if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
|
||||||
liveFunctions.insert(call->getName());
|
liveFunctions.insert(call->getName());
|
||||||
pushFunction(call->getName());
|
pushFunction(call->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addGlobalReference(const TString& name)
|
||||||
|
{
|
||||||
|
// just use the map to ensure we process each global at most once
|
||||||
|
if (liveGlobals.find(name) == liveGlobals.end()) {
|
||||||
|
liveGlobals.insert(name);
|
||||||
|
pushGlobalReference(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const TIntermediate& intermediate;
|
const TIntermediate& intermediate;
|
||||||
typedef std::unordered_set<TString> TLiveFunctions;
|
typedef std::unordered_set<TString> TLiveFunctions;
|
||||||
TLiveFunctions liveFunctions;
|
TLiveFunctions liveFunctions;
|
||||||
|
typedef std::unordered_set<TString> TLiveGlobals;
|
||||||
|
TLiveGlobals liveGlobals;
|
||||||
bool traverseAll;
|
bool traverseAll;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -157,11 +157,11 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
|||||||
case EvqBuffer:
|
case EvqBuffer:
|
||||||
if (node->getQualifier().isReadOnly())
|
if (node->getQualifier().isReadOnly())
|
||||||
message = "can't modify a readonly buffer";
|
message = "can't modify a readonly buffer";
|
||||||
if (node->getQualifier().isShaderRecordNV())
|
if (node->getQualifier().isShaderRecord())
|
||||||
message = "can't modify a shaderrecordnv qualified buffer";
|
message = "can't modify a shaderrecordnv qualified buffer";
|
||||||
break;
|
break;
|
||||||
case EvqHitAttrNV:
|
case EvqHitAttr:
|
||||||
if (language != EShLangIntersectNV)
|
if (language != EShLangIntersect)
|
||||||
message = "cannot modify hitAttributeNV in this stage";
|
message = "cannot modify hitAttributeNV in this stage";
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -181,9 +181,12 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
|||||||
case EbtAtomicUint:
|
case EbtAtomicUint:
|
||||||
message = "can't modify an atomic_uint";
|
message = "can't modify an atomic_uint";
|
||||||
break;
|
break;
|
||||||
case EbtAccStructNV:
|
case EbtAccStruct:
|
||||||
message = "can't modify accelerationStructureNV";
|
message = "can't modify accelerationStructureNV";
|
||||||
break;
|
break;
|
||||||
|
case EbtRayQuery:
|
||||||
|
message = "can't modify rayQueryEXT";
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Copyright (C) 2012-2015 LunarG, Inc.
|
// Copyright (C) 2012-2015 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
// Copyright (C) 2017, 2019 ARM Limited.
|
// Copyright (C) 2017, 2019 ARM Limited.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -245,7 +246,9 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
|
|||||||
else if (tokens[2].compare("off") == 0)
|
else if (tokens[2].compare("off") == 0)
|
||||||
contextPragma.optimize = false;
|
contextPragma.optimize = false;
|
||||||
else {
|
else {
|
||||||
error(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", "");
|
if(relaxedErrors())
|
||||||
|
// If an implementation does not recognize the tokens following #pragma, then it will ignore that pragma.
|
||||||
|
warn(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,7 +272,9 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
|
|||||||
else if (tokens[2].compare("off") == 0)
|
else if (tokens[2].compare("off") == 0)
|
||||||
contextPragma.debug = false;
|
contextPragma.debug = false;
|
||||||
else {
|
else {
|
||||||
error(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", "");
|
if(relaxedErrors())
|
||||||
|
// If an implementation does not recognize the tokens following #pragma, then it will ignore that pragma.
|
||||||
|
warn(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,8 +432,18 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
|
|||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
if (base->isReference() && ! base->isArray()) {
|
if (base->isReference() && ! base->isArray()) {
|
||||||
requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference indexing");
|
requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference indexing");
|
||||||
result = intermediate.addBinaryMath(EOpAdd, base, index, loc);
|
if (base->getType().getReferentType()->containsUnsizedArray()) {
|
||||||
result->setType(base->getType());
|
error(loc, "cannot index reference to buffer containing an unsized array", "", "");
|
||||||
|
result = nullptr;
|
||||||
|
} else {
|
||||||
|
result = intermediate.addBinaryMath(EOpAdd, base, index, loc);
|
||||||
|
if (result != nullptr)
|
||||||
|
result->setType(base->getType());
|
||||||
|
}
|
||||||
|
if (result == nullptr) {
|
||||||
|
error(loc, "cannot index buffer reference", "", "");
|
||||||
|
result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
|
if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
|
||||||
@@ -740,8 +755,11 @@ TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char*
|
|||||||
}
|
}
|
||||||
|
|
||||||
TIntermTyped* result = nullptr;
|
TIntermTyped* result = nullptr;
|
||||||
if (allowed)
|
if (allowed) {
|
||||||
|
if ((left->isReference() || right->isReference()))
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference math");
|
||||||
result = intermediate.addBinaryMath(op, left, right, loc);
|
result = intermediate.addBinaryMath(op, left, right, loc);
|
||||||
|
}
|
||||||
|
|
||||||
if (result == nullptr)
|
if (result == nullptr)
|
||||||
binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
|
binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
|
||||||
@@ -821,50 +839,7 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
|||||||
TIntermTyped* result = base;
|
TIntermTyped* result = base;
|
||||||
if ((base->isVector() || base->isScalar()) &&
|
if ((base->isVector() || base->isScalar()) &&
|
||||||
(base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) {
|
(base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) {
|
||||||
if (base->isScalar()) {
|
result = handleDotSwizzle(loc, base, field);
|
||||||
const char* dotFeature = "scalar swizzle";
|
|
||||||
requireProfile(loc, ~EEsProfile, dotFeature);
|
|
||||||
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature);
|
|
||||||
}
|
|
||||||
|
|
||||||
TSwizzleSelectors<TVectorSelector> selectors;
|
|
||||||
parseSwizzleSelector(loc, field, base->getVectorSize(), selectors);
|
|
||||||
|
|
||||||
if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitFloat())
|
|
||||||
requireFloat16Arithmetic(loc, ".", "can't swizzle types containing float16");
|
|
||||||
if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitInt())
|
|
||||||
requireInt16Arithmetic(loc, ".", "can't swizzle types containing (u)int16");
|
|
||||||
if (base->isVector() && selectors.size() != 1 && base->getType().contains8BitInt())
|
|
||||||
requireInt8Arithmetic(loc, ".", "can't swizzle types containing (u)int8");
|
|
||||||
|
|
||||||
if (base->isScalar()) {
|
|
||||||
if (selectors.size() == 1)
|
|
||||||
return result;
|
|
||||||
else {
|
|
||||||
TType type(base->getBasicType(), EvqTemporary, selectors.size());
|
|
||||||
// Swizzle operations propagate specialization-constantness
|
|
||||||
if (base->getQualifier().isSpecConstant())
|
|
||||||
type.getQualifier().makeSpecConstant();
|
|
||||||
return addConstructor(loc, base, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (base->getType().getQualifier().isFrontEndConstant())
|
|
||||||
result = intermediate.foldSwizzle(base, selectors, loc);
|
|
||||||
else {
|
|
||||||
if (selectors.size() == 1) {
|
|
||||||
TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc);
|
|
||||||
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
|
|
||||||
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision));
|
|
||||||
} else {
|
|
||||||
TIntermTyped* index = intermediate.addSwizzle(selectors, loc);
|
|
||||||
result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc);
|
|
||||||
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size()));
|
|
||||||
}
|
|
||||||
// Swizzle operations propagate specialization-constantness
|
|
||||||
if (base->getType().getQualifier().isSpecConstant())
|
|
||||||
result->getWritableType().getQualifier().makeSpecConstant();
|
|
||||||
}
|
|
||||||
} else if (base->isStruct() || base->isReference()) {
|
} else if (base->isStruct() || base->isReference()) {
|
||||||
const TTypeList* fields = base->isReference() ?
|
const TTypeList* fields = base->isReference() ?
|
||||||
base->getType().getReferentType()->getStruct() :
|
base->getType().getReferentType()->getStruct() :
|
||||||
@@ -905,6 +880,60 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle seeing a base.swizzle, a subset of base.identifier in the grammar.
|
||||||
|
//
|
||||||
|
TIntermTyped* TParseContext::handleDotSwizzle(const TSourceLoc& loc, TIntermTyped* base, const TString& field)
|
||||||
|
{
|
||||||
|
TIntermTyped* result = base;
|
||||||
|
if (base->isScalar()) {
|
||||||
|
const char* dotFeature = "scalar swizzle";
|
||||||
|
requireProfile(loc, ~EEsProfile, dotFeature);
|
||||||
|
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature);
|
||||||
|
}
|
||||||
|
|
||||||
|
TSwizzleSelectors<TVectorSelector> selectors;
|
||||||
|
parseSwizzleSelector(loc, field, base->getVectorSize(), selectors);
|
||||||
|
|
||||||
|
if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitFloat())
|
||||||
|
requireFloat16Arithmetic(loc, ".", "can't swizzle types containing float16");
|
||||||
|
if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitInt())
|
||||||
|
requireInt16Arithmetic(loc, ".", "can't swizzle types containing (u)int16");
|
||||||
|
if (base->isVector() && selectors.size() != 1 && base->getType().contains8BitInt())
|
||||||
|
requireInt8Arithmetic(loc, ".", "can't swizzle types containing (u)int8");
|
||||||
|
|
||||||
|
if (base->isScalar()) {
|
||||||
|
if (selectors.size() == 1)
|
||||||
|
return result;
|
||||||
|
else {
|
||||||
|
TType type(base->getBasicType(), EvqTemporary, selectors.size());
|
||||||
|
// Swizzle operations propagate specialization-constantness
|
||||||
|
if (base->getQualifier().isSpecConstant())
|
||||||
|
type.getQualifier().makeSpecConstant();
|
||||||
|
return addConstructor(loc, base, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base->getType().getQualifier().isFrontEndConstant())
|
||||||
|
result = intermediate.foldSwizzle(base, selectors, loc);
|
||||||
|
else {
|
||||||
|
if (selectors.size() == 1) {
|
||||||
|
TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc);
|
||||||
|
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
|
||||||
|
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision));
|
||||||
|
} else {
|
||||||
|
TIntermTyped* index = intermediate.addSwizzle(selectors, loc);
|
||||||
|
result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc);
|
||||||
|
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size()));
|
||||||
|
}
|
||||||
|
// Swizzle operations propagate specialization-constantness
|
||||||
|
if (base->getType().getQualifier().isSpecConstant())
|
||||||
|
result->getWritableType().getQualifier().makeSpecConstant();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* base, int member, const TString& memberName)
|
void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* base, int member, const TString& memberName)
|
||||||
{
|
{
|
||||||
// a block that needs extension checking is either 'base', or if arrayed,
|
// a block that needs extension checking is either 'base', or if arrayed,
|
||||||
@@ -1273,7 +1302,7 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo
|
|||||||
TIntermTyped *result = intermediate.addBuiltInFunctionCall(loc, function.getBuiltInOp(),
|
TIntermTyped *result = intermediate.addBuiltInFunctionCall(loc, function.getBuiltInOp(),
|
||||||
function.getParamCount() == 1,
|
function.getParamCount() == 1,
|
||||||
arguments, function.getType());
|
arguments, function.getType());
|
||||||
if (obeyPrecisionQualifiers())
|
if (result != nullptr && obeyPrecisionQualifiers())
|
||||||
computeBuiltinPrecisions(*result, function);
|
computeBuiltinPrecisions(*result, function);
|
||||||
|
|
||||||
if (result == nullptr) {
|
if (result == nullptr) {
|
||||||
@@ -1353,6 +1382,9 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction
|
|||||||
case EOpInterpolateAtSample:
|
case EOpInterpolateAtSample:
|
||||||
numArgs = 1;
|
numArgs = 1;
|
||||||
break;
|
break;
|
||||||
|
case EOpDebugPrintf:
|
||||||
|
numArgs = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1390,23 +1422,28 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
functionReturnsValue = true;
|
functionReturnsValue = true;
|
||||||
|
TIntermBranch* branch = nullptr;
|
||||||
if (currentFunctionType->getBasicType() == EbtVoid) {
|
if (currentFunctionType->getBasicType() == EbtVoid) {
|
||||||
error(loc, "void function cannot return a value", "return", "");
|
error(loc, "void function cannot return a value", "return", "");
|
||||||
return intermediate.addBranch(EOpReturn, loc);
|
branch = intermediate.addBranch(EOpReturn, loc);
|
||||||
} else if (*currentFunctionType != value->getType()) {
|
} else if (*currentFunctionType != value->getType()) {
|
||||||
TIntermTyped* converted = intermediate.addConversion(EOpReturn, *currentFunctionType, value);
|
TIntermTyped* converted = intermediate.addConversion(EOpReturn, *currentFunctionType, value);
|
||||||
if (converted) {
|
if (converted) {
|
||||||
if (*currentFunctionType != converted->getType())
|
if (*currentFunctionType != converted->getType())
|
||||||
error(loc, "cannot convert return value to function return type", "return", "");
|
error(loc, "cannot convert return value to function return type", "return", "");
|
||||||
if (version < 420)
|
if (version < 420)
|
||||||
warn(loc, "type conversion on return values was not explicitly allowed until version 420", "return", "");
|
warn(loc, "type conversion on return values was not explicitly allowed until version 420",
|
||||||
return intermediate.addBranch(EOpReturn, converted, loc);
|
"return", "");
|
||||||
|
branch = intermediate.addBranch(EOpReturn, converted, loc);
|
||||||
} else {
|
} else {
|
||||||
error(loc, "type does not match, or is not convertible to, the function's return type", "return", "");
|
error(loc, "type does not match, or is not convertible to, the function's return type", "return", "");
|
||||||
return intermediate.addBranch(EOpReturn, value, loc);
|
branch = intermediate.addBranch(EOpReturn, value, loc);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
return intermediate.addBranch(EOpReturn, value, loc);
|
branch = intermediate.addBranch(EOpReturn, value, loc);
|
||||||
|
|
||||||
|
branch->updatePrecision(currentFunctionType->getQualifier().precision);
|
||||||
|
return branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if the operation is being done in an illegal location.
|
// See if the operation is being done in an illegal location.
|
||||||
@@ -1650,6 +1687,14 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TIntermTyped* TParseContext::addAssign(const TSourceLoc& loc, TOperator op, TIntermTyped* left, TIntermTyped* right)
|
||||||
|
{
|
||||||
|
if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference())
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "+= and -= on a buffer reference");
|
||||||
|
|
||||||
|
return intermediate.addAssign(op, left, right, loc);
|
||||||
|
}
|
||||||
|
|
||||||
void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& fnCandidate, const TIntermOperator& callNode)
|
void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& fnCandidate, const TIntermOperator& callNode)
|
||||||
{
|
{
|
||||||
const TIntermSequence* argp = &callNode.getAsAggregate()->getSequence();
|
const TIntermSequence* argp = &callNode.getAsAggregate()->getSequence();
|
||||||
@@ -1672,6 +1717,9 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction&
|
|||||||
unsigned int semantics = 0, storageClassSemantics = 0;
|
unsigned int semantics = 0, storageClassSemantics = 0;
|
||||||
unsigned int semantics2 = 0, storageClassSemantics2 = 0;
|
unsigned int semantics2 = 0, storageClassSemantics2 = 0;
|
||||||
|
|
||||||
|
const TIntermTyped* arg0 = (*argp)[0]->getAsTyped();
|
||||||
|
const bool isMS = arg0->getBasicType() == EbtSampler && arg0->getType().getSampler().isMultiSample();
|
||||||
|
|
||||||
// Grab the semantics and storage class semantics from the operands, based on opcode
|
// Grab the semantics and storage class semantics from the operands, based on opcode
|
||||||
switch (callNode.getOp()) {
|
switch (callNode.getOp()) {
|
||||||
case EOpAtomicAdd:
|
case EOpAtomicAdd:
|
||||||
@@ -1704,18 +1752,18 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction&
|
|||||||
case EOpImageAtomicXor:
|
case EOpImageAtomicXor:
|
||||||
case EOpImageAtomicExchange:
|
case EOpImageAtomicExchange:
|
||||||
case EOpImageAtomicStore:
|
case EOpImageAtomicStore:
|
||||||
storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
storageClassSemantics = (*argp)[isMS ? 5 : 4]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
semantics = (*argp)[isMS ? 6 : 5]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
break;
|
break;
|
||||||
case EOpImageAtomicLoad:
|
case EOpImageAtomicLoad:
|
||||||
storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
storageClassSemantics = (*argp)[isMS ? 4 : 3]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
semantics = (*argp)[isMS ? 5 : 4]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
break;
|
break;
|
||||||
case EOpImageAtomicCompSwap:
|
case EOpImageAtomicCompSwap:
|
||||||
storageClassSemantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
storageClassSemantics = (*argp)[isMS ? 6 : 5]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
semantics = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
semantics = (*argp)[isMS ? 7 : 6]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
storageClassSemantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
storageClassSemantics2 = (*argp)[isMS ? 8 : 7]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
semantics2 = (*argp)[8]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
semantics2 = (*argp)[isMS ? 9 : 8]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpBarrier:
|
case EOpBarrier:
|
||||||
@@ -2006,18 +2054,20 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
if (arg > 0) {
|
if (arg > 0) {
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 && arg0->getType().getSampler().shadow;
|
bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 &&
|
||||||
|
arg0->getType().getSampler().shadow;
|
||||||
if (f16ShadowCompare)
|
if (f16ShadowCompare)
|
||||||
++arg;
|
++arg;
|
||||||
#endif
|
#endif
|
||||||
if (! (*argp)[arg]->getAsConstantUnion())
|
if (! (*argp)[arg]->getAsTyped()->getQualifier().isConstant())
|
||||||
error(loc, "argument must be compile-time constant", "texel offset", "");
|
error(loc, "argument must be compile-time constant", "texel offset", "");
|
||||||
else {
|
else if ((*argp)[arg]->getAsConstantUnion()) {
|
||||||
const TType& type = (*argp)[arg]->getAsTyped()->getType();
|
const TType& type = (*argp)[arg]->getAsTyped()->getType();
|
||||||
for (int c = 0; c < type.getVectorSize(); ++c) {
|
for (int c = 0; c < type.getVectorSize(); ++c) {
|
||||||
int offset = (*argp)[arg]->getAsConstantUnion()->getConstArray()[c].getIConst();
|
int offset = (*argp)[arg]->getAsConstantUnion()->getConstArray()[c].getIConst();
|
||||||
if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset)
|
if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset)
|
||||||
error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]");
|
error(loc, "value is out of range:", "texel offset",
|
||||||
|
"[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2026,15 +2076,32 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
case EOpTraceNV:
|
case EOpTrace:
|
||||||
if (!(*argp)[10]->getAsConstantUnion())
|
if (!(*argp)[10]->getAsConstantUnion())
|
||||||
error(loc, "argument must be compile-time constant", "payload number", "");
|
error(loc, "argument must be compile-time constant", "payload number", "");
|
||||||
break;
|
break;
|
||||||
case EOpExecuteCallableNV:
|
case EOpExecuteCallable:
|
||||||
if (!(*argp)[1]->getAsConstantUnion())
|
if (!(*argp)[1]->getAsConstantUnion())
|
||||||
error(loc, "argument must be compile-time constant", "callable data number", "");
|
error(loc, "argument must be compile-time constant", "callable data number", "");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EOpRayQueryGetIntersectionType:
|
||||||
|
case EOpRayQueryGetIntersectionT:
|
||||||
|
case EOpRayQueryGetIntersectionInstanceCustomIndex:
|
||||||
|
case EOpRayQueryGetIntersectionInstanceId:
|
||||||
|
case EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
|
||||||
|
case EOpRayQueryGetIntersectionGeometryIndex:
|
||||||
|
case EOpRayQueryGetIntersectionPrimitiveIndex:
|
||||||
|
case EOpRayQueryGetIntersectionBarycentrics:
|
||||||
|
case EOpRayQueryGetIntersectionFrontFace:
|
||||||
|
case EOpRayQueryGetIntersectionObjectRayDirection:
|
||||||
|
case EOpRayQueryGetIntersectionObjectRayOrigin:
|
||||||
|
case EOpRayQueryGetIntersectionObjectToWorld:
|
||||||
|
case EOpRayQueryGetIntersectionWorldToObject:
|
||||||
|
if (!(*argp)[1]->getAsConstantUnion())
|
||||||
|
error(loc, "argument must be compile-time constant", "committed", "");
|
||||||
|
break;
|
||||||
|
|
||||||
case EOpTextureQuerySamples:
|
case EOpTextureQuerySamples:
|
||||||
case EOpImageQuerySamples:
|
case EOpImageQuerySamples:
|
||||||
// GL_ARB_shader_texture_image_samples
|
// GL_ARB_shader_texture_image_samples
|
||||||
@@ -2058,7 +2125,14 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui)
|
if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui)
|
||||||
error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
|
error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
|
||||||
} else {
|
} else {
|
||||||
if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)
|
bool isImageAtomicOnFloatAllowed = ((fnCandidate.getName().compare(0, 14, "imageAtomicAdd") == 0) ||
|
||||||
|
(fnCandidate.getName().compare(0, 15, "imageAtomicLoad") == 0) ||
|
||||||
|
(fnCandidate.getName().compare(0, 16, "imageAtomicStore") == 0) ||
|
||||||
|
(fnCandidate.getName().compare(0, 19, "imageAtomicExchange") == 0));
|
||||||
|
if (imageType.getSampler().type == EbtFloat && isImageAtomicOnFloatAllowed &&
|
||||||
|
(fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)) // imageAtomicExchange doesn't require GL_EXT_shader_atomic_float
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
|
||||||
|
if (!isImageAtomicOnFloatAllowed)
|
||||||
error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
|
error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
|
||||||
else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile())
|
else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile())
|
||||||
error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
|
error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
|
||||||
@@ -2087,10 +2161,18 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
if (argp->size() > 3) {
|
if (argp->size() > 3) {
|
||||||
requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
|
requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
|
||||||
memorySemanticsCheck(loc, fnCandidate, callNode);
|
memorySemanticsCheck(loc, fnCandidate, callNode);
|
||||||
|
if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange ||
|
||||||
|
callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpAtomicStore) &&
|
||||||
|
(arg0->getType().isFloatingDomain())) {
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
|
||||||
|
}
|
||||||
} else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) {
|
} else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) {
|
||||||
const char* const extensions[2] = { E_GL_NV_shader_atomic_int64,
|
const char* const extensions[2] = { E_GL_NV_shader_atomic_int64,
|
||||||
E_GL_EXT_shader_atomic_int64 };
|
E_GL_EXT_shader_atomic_int64 };
|
||||||
requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str());
|
requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str());
|
||||||
|
} else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange) &&
|
||||||
|
(arg0->getType().isFloatingDomain())) {
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2172,6 +2254,28 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
memorySemanticsCheck(loc, fnCandidate, callNode);
|
memorySemanticsCheck(loc, fnCandidate, callNode);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EOpMix:
|
||||||
|
if (profile == EEsProfile && version < 310) {
|
||||||
|
// Look for specific signatures
|
||||||
|
if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat &&
|
||||||
|
(*argp)[1]->getAsTyped()->getBasicType() != EbtFloat &&
|
||||||
|
(*argp)[2]->getAsTyped()->getBasicType() == EbtBool) {
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_shader_integer_mix, "specific signature of builtin mix");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile != EEsProfile && version < 450) {
|
||||||
|
if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat &&
|
||||||
|
(*argp)[0]->getAsTyped()->getBasicType() != EbtDouble &&
|
||||||
|
(*argp)[1]->getAsTyped()->getBasicType() != EbtFloat &&
|
||||||
|
(*argp)[1]->getAsTyped()->getBasicType() != EbtDouble &&
|
||||||
|
(*argp)[2]->getAsTyped()->getBasicType() == EbtBool) {
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_shader_integer_mix, fnCandidate.getName().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -2698,7 +2802,10 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden
|
|||||||
if (strncmp(identifier, "GL_", 3) == 0)
|
if (strncmp(identifier, "GL_", 3) == 0)
|
||||||
ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op, identifier);
|
ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op, identifier);
|
||||||
else if (strncmp(identifier, "defined", 8) == 0)
|
else if (strncmp(identifier, "defined", 8) == 0)
|
||||||
ppError(loc, "\"defined\" can't be (un)defined:", op, identifier);
|
if (relaxedErrors())
|
||||||
|
ppWarn(loc, "\"defined\" is (un)defined:", op, identifier);
|
||||||
|
else
|
||||||
|
ppError(loc, "\"defined\" can't be (un)defined:", op, identifier);
|
||||||
else if (strstr(identifier, "__") != 0) {
|
else if (strstr(identifier, "__") != 0) {
|
||||||
if (isEsProfile() && version >= 300 &&
|
if (isEsProfile() && version >= 300 &&
|
||||||
(strcmp(identifier, "__LINE__") == 0 ||
|
(strcmp(identifier, "__LINE__") == 0 ||
|
||||||
@@ -2706,7 +2813,7 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden
|
|||||||
strcmp(identifier, "__VERSION__") == 0))
|
strcmp(identifier, "__VERSION__") == 0))
|
||||||
ppError(loc, "predefined names can't be (un)defined:", op, identifier);
|
ppError(loc, "predefined names can't be (un)defined:", op, identifier);
|
||||||
else {
|
else {
|
||||||
if (isEsProfile() && version < 300)
|
if (isEsProfile() && version < 300 && !relaxedErrors())
|
||||||
ppError(loc, "names containing consecutive underscores are reserved, and an error if version < 300:", op, identifier);
|
ppError(loc, "names containing consecutive underscores are reserved, and an error if version < 300:", op, identifier);
|
||||||
else
|
else
|
||||||
ppWarn(loc, "names containing consecutive underscores are reserved:", op, identifier);
|
ppWarn(loc, "names containing consecutive underscores are reserved:", op, identifier);
|
||||||
@@ -3083,7 +3190,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
|||||||
error(loc, "constructor argument does not have a type", "constructor", "");
|
error(loc, "constructor argument does not have a type", "constructor", "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (op != EOpConstructStruct && typed->getBasicType() == EbtSampler) {
|
if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) {
|
||||||
error(loc, "cannot convert a sampler", "constructor", "");
|
error(loc, "cannot convert a sampler", "constructor", "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3128,7 +3235,7 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const
|
|||||||
if (function[0].type->getBasicType() != EbtSampler ||
|
if (function[0].type->getBasicType() != EbtSampler ||
|
||||||
! function[0].type->getSampler().isTexture() ||
|
! function[0].type->getSampler().isTexture() ||
|
||||||
function[0].type->isArray()) {
|
function[0].type->isArray()) {
|
||||||
error(loc, "sampler-constructor first argument must be a scalar textureXXX type", token, "");
|
error(loc, "sampler-constructor first argument must be a scalar *texture* type", token, "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=()
|
// simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=()
|
||||||
@@ -3136,7 +3243,8 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const
|
|||||||
texture.setCombined(false);
|
texture.setCombined(false);
|
||||||
texture.shadow = false;
|
texture.shadow = false;
|
||||||
if (texture != function[0].type->getSampler()) {
|
if (texture != function[0].type->getSampler()) {
|
||||||
error(loc, "sampler-constructor first argument must match type and dimensionality of constructor type", token, "");
|
error(loc, "sampler-constructor first argument must be a *texture* type"
|
||||||
|
" matching the dimensionality and sampled type of the constructor", token, "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3146,7 +3254,7 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const
|
|||||||
if ( function[1].type->getBasicType() != EbtSampler ||
|
if ( function[1].type->getBasicType() != EbtSampler ||
|
||||||
! function[1].type->getSampler().isPureSampler() ||
|
! function[1].type->getSampler().isPureSampler() ||
|
||||||
function[1].type->isArray()) {
|
function[1].type->isArray()) {
|
||||||
error(loc, "sampler-constructor second argument must be a scalar type 'sampler'", token, "");
|
error(loc, "sampler-constructor second argument must be a scalar sampler or samplerShadow", token, "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3222,14 +3330,14 @@ void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, co
|
|||||||
error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
|
error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseContext::accStructNVCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
|
void TParseContext::accStructCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
|
||||||
{
|
{
|
||||||
if (type.getQualifier().storage == EvqUniform)
|
if (type.getQualifier().storage == EvqUniform)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStructNV))
|
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStruct))
|
||||||
error(loc, "non-uniform struct contains an accelerationStructureNV:", type.getBasicTypeString().c_str(), identifier.c_str());
|
error(loc, "non-uniform struct contains an accelerationStructureNV:", type.getBasicTypeString().c_str(), identifier.c_str());
|
||||||
else if (type.getBasicType() == EbtAccStructNV && type.getQualifier().storage != EvqUniform)
|
else if (type.getBasicType() == EbtAccStruct && type.getQualifier().storage != EvqUniform)
|
||||||
error(loc, "accelerationStructureNV can only be used in uniform variables or function parameters:",
|
error(loc, "accelerationStructureNV can only be used in uniform variables or function parameters:",
|
||||||
type.getBasicTypeString().c_str(), identifier.c_str());
|
type.getBasicTypeString().c_str(), identifier.c_str());
|
||||||
|
|
||||||
@@ -3327,6 +3435,11 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
|
|||||||
!qualifier.hasBufferReference())
|
!qualifier.hasBufferReference())
|
||||||
error(loc, "buffers can be declared only as blocks", "buffer", "");
|
error(loc, "buffers can be declared only as blocks", "buffer", "");
|
||||||
|
|
||||||
|
if (qualifier.storage != EvqVaryingIn && publicType.basicType == EbtDouble &&
|
||||||
|
extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit) && language == EShLangVertex &&
|
||||||
|
version < 400) {
|
||||||
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 410, E_GL_ARB_gpu_shader_fp64, "vertex-shader `double` type");
|
||||||
|
}
|
||||||
if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
|
if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -3377,7 +3490,7 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
|
|||||||
profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays");
|
profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays");
|
||||||
}
|
}
|
||||||
if (publicType.basicType == EbtDouble)
|
if (publicType.basicType == EbtDouble)
|
||||||
profileRequires(loc, ~EEsProfile, 410, nullptr, "vertex-shader `double` type input");
|
profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_vertex_attrib_64bit, "vertex-shader `double` type input");
|
||||||
if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)
|
if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)
|
||||||
error(loc, "vertex input cannot be further qualified", "", "");
|
error(loc, "vertex input cannot be further qualified", "", "");
|
||||||
break;
|
break;
|
||||||
@@ -3513,12 +3626,14 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
|
|||||||
dst.precision = src.precision;
|
dst.precision = src.precision;
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
|
if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
|
||||||
(src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
|
(src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
|
||||||
(src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
|
(src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
|
||||||
(src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent)) ||
|
(src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
|
||||||
(src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent)))) {
|
(src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.shadercallcoherent)) ||
|
||||||
error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent qualifier allowed", GetPrecisionQualifierString(src.precision), "");
|
(src.shadercallcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)))) {
|
||||||
|
error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed",
|
||||||
|
GetPrecisionQualifierString(src.precision), "");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Layout qualifiers
|
// Layout qualifiers
|
||||||
@@ -3546,6 +3661,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
|
|||||||
MERGE_SINGLETON(queuefamilycoherent);
|
MERGE_SINGLETON(queuefamilycoherent);
|
||||||
MERGE_SINGLETON(workgroupcoherent);
|
MERGE_SINGLETON(workgroupcoherent);
|
||||||
MERGE_SINGLETON(subgroupcoherent);
|
MERGE_SINGLETON(subgroupcoherent);
|
||||||
|
MERGE_SINGLETON(shadercallcoherent);
|
||||||
MERGE_SINGLETON(nonprivate);
|
MERGE_SINGLETON(nonprivate);
|
||||||
MERGE_SINGLETON(volatil);
|
MERGE_SINGLETON(volatil);
|
||||||
MERGE_SINGLETON(restrict);
|
MERGE_SINGLETON(restrict);
|
||||||
@@ -3983,7 +4099,7 @@ void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermType
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check for additional things allowed by GL_EXT_nonuniform_qualifier
|
// check for additional things allowed by GL_EXT_nonuniform_qualifier
|
||||||
if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStructNV ||
|
if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStruct || base.getBasicType() == EbtRayQuery ||
|
||||||
(base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer()))
|
(base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer()))
|
||||||
requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index");
|
requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index");
|
||||||
else
|
else
|
||||||
@@ -4487,6 +4603,7 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
|
|||||||
type.getQualifier().queuefamilycoherent = qualifier.queuefamilycoherent;
|
type.getQualifier().queuefamilycoherent = qualifier.queuefamilycoherent;
|
||||||
type.getQualifier().workgroupcoherent = qualifier.workgroupcoherent;
|
type.getQualifier().workgroupcoherent = qualifier.workgroupcoherent;
|
||||||
type.getQualifier().subgroupcoherent = qualifier.subgroupcoherent;
|
type.getQualifier().subgroupcoherent = qualifier.subgroupcoherent;
|
||||||
|
type.getQualifier().shadercallcoherent = qualifier.shadercallcoherent;
|
||||||
type.getQualifier().nonprivate = qualifier.nonprivate;
|
type.getQualifier().nonprivate = qualifier.nonprivate;
|
||||||
type.getQualifier().readonly = qualifier.readonly;
|
type.getQualifier().readonly = qualifier.readonly;
|
||||||
type.getQualifier().writeonly = qualifier.writeonly;
|
type.getQualifier().writeonly = qualifier.writeonly;
|
||||||
@@ -4868,7 +4985,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
|
if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
|
||||||
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430");
|
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430");
|
||||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "std430");
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "std430");
|
||||||
profileRequires(loc, EEsProfile, 310, nullptr, "std430");
|
profileRequires(loc, EEsProfile, 310, nullptr, "std430");
|
||||||
publicType.qualifier.layoutPacking = ElpStd430;
|
publicType.qualifier.layoutPacking = ElpStd430;
|
||||||
return;
|
return;
|
||||||
@@ -5067,13 +5184,19 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (language == EShLangRayGenNV || language == EShLangIntersectNV ||
|
if (language == EShLangRayGen || language == EShLangIntersect ||
|
||||||
language == EShLangAnyHitNV || language == EShLangClosestHitNV ||
|
language == EShLangAnyHit || language == EShLangClosestHit ||
|
||||||
language == EShLangMissNV || language == EShLangCallableNV) {
|
language == EShLangMiss || language == EShLangCallable) {
|
||||||
if (id == "shaderrecordnv") {
|
if (id == "shaderrecordnv" || id == "shaderrecordext") {
|
||||||
publicType.qualifier.layoutShaderRecordNV = true;
|
if (id == "shaderrecordnv") {
|
||||||
|
requireExtensions(loc, 1, &E_GL_NV_ray_tracing, "shader record NV");
|
||||||
|
} else {
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "shader record EXT");
|
||||||
|
}
|
||||||
|
publicType.qualifier.layoutShaderRecord = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (language == EShLangCompute) {
|
if (language == EShLangCompute) {
|
||||||
@@ -5088,6 +5211,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id == "primitive_culling") {
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_ray_flags_primitive_culling, "primitive culling");
|
||||||
|
publicType.shaderQualifiers.layoutPrimitiveCulling = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
|
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
|
||||||
@@ -5135,6 +5264,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
profileRequires(loc, EEsProfile, 310, nullptr, feature);
|
profileRequires(loc, EEsProfile, 310, nullptr, feature);
|
||||||
}
|
}
|
||||||
publicType.qualifier.layoutOffset = value;
|
publicType.qualifier.layoutOffset = value;
|
||||||
|
publicType.qualifier.explicitOffset = true;
|
||||||
if (nonLiteral)
|
if (nonLiteral)
|
||||||
error(loc, "needs a literal integer", "offset", "");
|
error(loc, "needs a literal integer", "offset", "");
|
||||||
return;
|
return;
|
||||||
@@ -5347,10 +5477,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
|
|
||||||
case EShLangFragment:
|
case EShLangFragment:
|
||||||
if (id == "index") {
|
if (id == "index") {
|
||||||
requireProfile(loc, ECompatibilityProfile | ECoreProfile, "index layout qualifier on fragment output");
|
requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, "index layout qualifier on fragment output");
|
||||||
const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
|
const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
|
||||||
profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output");
|
profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output");
|
||||||
|
profileRequires(loc, EEsProfile ,310, E_GL_EXT_blend_func_extended, "index layout qualifier on fragment output");
|
||||||
// "It is also a compile-time error if a fragment shader sets a layout index to less than 0 or greater than 1."
|
// "It is also a compile-time error if a fragment shader sets a layout index to less than 0 or greater than 1."
|
||||||
if (value < 0 || value > 1) {
|
if (value < 0 || value > 1) {
|
||||||
value = 0;
|
value = 0;
|
||||||
@@ -5514,8 +5644,8 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
|
|||||||
dst.layoutViewportRelative = true;
|
dst.layoutViewportRelative = true;
|
||||||
if (src.layoutSecondaryViewportRelativeOffset != -2048)
|
if (src.layoutSecondaryViewportRelativeOffset != -2048)
|
||||||
dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
|
dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
|
||||||
if (src.layoutShaderRecordNV)
|
if (src.layoutShaderRecord)
|
||||||
dst.layoutShaderRecordNV = true;
|
dst.layoutShaderRecord = true;
|
||||||
if (src.pervertexNV)
|
if (src.pervertexNV)
|
||||||
dst.pervertexNV = true;
|
dst.pervertexNV = true;
|
||||||
#endif
|
#endif
|
||||||
@@ -5583,7 +5713,7 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
|
|||||||
error(loc, "cannot specify on a variable declaration", "align", "");
|
error(loc, "cannot specify on a variable declaration", "align", "");
|
||||||
if (qualifier.isPushConstant())
|
if (qualifier.isPushConstant())
|
||||||
error(loc, "can only specify on a uniform block", "push_constant", "");
|
error(loc, "can only specify on a uniform block", "push_constant", "");
|
||||||
if (qualifier.isShaderRecordNV())
|
if (qualifier.isShaderRecord())
|
||||||
error(loc, "can only specify on a buffer block", "shaderRecordNV", "");
|
error(loc, "can only specify on a buffer block", "shaderRecordNV", "");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -5657,11 +5787,11 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
|||||||
error(loc, "cannot apply to uniform or buffer block", "location", "");
|
error(loc, "cannot apply to uniform or buffer block", "location", "");
|
||||||
break;
|
break;
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
case EvqPayloadNV:
|
case EvqPayload:
|
||||||
case EvqPayloadInNV:
|
case EvqPayloadIn:
|
||||||
case EvqHitAttrNV:
|
case EvqHitAttr:
|
||||||
case EvqCallableDataNV:
|
case EvqCallableData:
|
||||||
case EvqCallableDataInNV:
|
case EvqCallableDataIn:
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
@@ -5684,6 +5814,8 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
|||||||
int repeated = intermediate.addXfbBufferOffset(type);
|
int repeated = intermediate.addXfbBufferOffset(type);
|
||||||
if (repeated >= 0)
|
if (repeated >= 0)
|
||||||
error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
|
error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
|
||||||
|
if (type.isUnsizedArray())
|
||||||
|
error(loc, "unsized array", "xfb_offset", "in buffer %d", qualifier.layoutXfbBuffer);
|
||||||
|
|
||||||
// "The offset must be a multiple of the size of the first component of the first
|
// "The offset must be a multiple of the size of the first component of the first
|
||||||
// qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
|
// qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
|
||||||
@@ -5756,7 +5888,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
|||||||
if (spvVersion.spv > 0) {
|
if (spvVersion.spv > 0) {
|
||||||
if (qualifier.isUniformOrBuffer()) {
|
if (qualifier.isUniformOrBuffer()) {
|
||||||
if (type.getBasicType() == EbtBlock && !qualifier.isPushConstant() &&
|
if (type.getBasicType() == EbtBlock && !qualifier.isPushConstant() &&
|
||||||
!qualifier.isShaderRecordNV() &&
|
!qualifier.isShaderRecord() &&
|
||||||
!qualifier.hasAttachment() &&
|
!qualifier.hasAttachment() &&
|
||||||
!qualifier.hasBufferReference())
|
!qualifier.hasBufferReference())
|
||||||
error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", "");
|
error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", "");
|
||||||
@@ -5813,7 +5945,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
|||||||
if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock)
|
if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock)
|
||||||
error(loc, "can only be used with a block", "buffer_reference", "");
|
error(loc, "can only be used with a block", "buffer_reference", "");
|
||||||
|
|
||||||
if (qualifier.isShaderRecordNV() && type.getBasicType() != EbtBlock)
|
if (qualifier.isShaderRecord() && type.getBasicType() != EbtBlock)
|
||||||
error(loc, "can only be used with a block", "shaderRecordNV", "");
|
error(loc, "can only be used with a block", "shaderRecordNV", "");
|
||||||
|
|
||||||
// input attachment
|
// input attachment
|
||||||
@@ -5958,7 +6090,7 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
|
|||||||
if (qualifier.storage != EvqBuffer)
|
if (qualifier.storage != EvqBuffer)
|
||||||
error(loc, "can only be used with buffer", "buffer_reference", "");
|
error(loc, "can only be used with buffer", "buffer_reference", "");
|
||||||
}
|
}
|
||||||
if (qualifier.isShaderRecordNV()) {
|
if (qualifier.isShaderRecord()) {
|
||||||
if (qualifier.storage != EvqBuffer)
|
if (qualifier.storage != EvqBuffer)
|
||||||
error(loc, "can only be used with a buffer", "shaderRecordNV", "");
|
error(loc, "can only be used with a buffer", "shaderRecordNV", "");
|
||||||
if (qualifier.hasBinding())
|
if (qualifier.hasBinding())
|
||||||
@@ -5967,7 +6099,7 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
|
|||||||
error(loc, "cannot be used with shaderRecordNV", "set", "");
|
error(loc, "cannot be used with shaderRecordNV", "set", "");
|
||||||
|
|
||||||
}
|
}
|
||||||
if (qualifier.storage == EvqHitAttrNV && qualifier.hasLayout()) {
|
if (qualifier.storage == EvqHitAttr && qualifier.hasLayout()) {
|
||||||
error(loc, "cannot apply layout qualifiers to hitAttributeNV variable", "hitAttributeNV", "");
|
error(loc, "cannot apply layout qualifiers to hitAttributeNV variable", "hitAttributeNV", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6018,6 +6150,8 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua
|
|||||||
error(loc, message, "num_views", "");
|
error(loc, message, "num_views", "");
|
||||||
if (shaderQualifiers.interlockOrdering != EioNone)
|
if (shaderQualifiers.interlockOrdering != EioNone)
|
||||||
error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), "");
|
error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), "");
|
||||||
|
if (shaderQualifiers.layoutPrimitiveCulling)
|
||||||
|
error(loc, "can only be applied as standalone", "primitive_culling", "");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6079,6 +6213,15 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
const TFunction* function = nullptr;
|
const TFunction* function = nullptr;
|
||||||
|
|
||||||
|
// debugPrintfEXT has var args and is in the symbol table as "debugPrintfEXT()",
|
||||||
|
// mangled to "debugPrintfEXT("
|
||||||
|
if (call.getName() == "debugPrintfEXT") {
|
||||||
|
TSymbol* symbol = symbolTable.find("debugPrintfEXT(", &builtIn);
|
||||||
|
if (symbol)
|
||||||
|
return symbol->getAsFunction();
|
||||||
|
}
|
||||||
|
|
||||||
bool explicitTypesEnabled = extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
bool explicitTypesEnabled = extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8) ||
|
extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8) ||
|
||||||
extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16) ||
|
extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16) ||
|
||||||
@@ -6088,7 +6231,10 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct
|
|||||||
extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32) ||
|
extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32) ||
|
||||||
extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64);
|
extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64);
|
||||||
|
|
||||||
if (isEsProfile() || version < 120)
|
if (isEsProfile())
|
||||||
|
function = (extensionTurnedOn(E_GL_EXT_shader_implicit_conversions) && version >= 310) ?
|
||||||
|
findFunction120(loc, call, builtIn) : findFunctionExact(loc, call, builtIn);
|
||||||
|
else if (version < 120)
|
||||||
function = findFunctionExact(loc, call, builtIn);
|
function = findFunctionExact(loc, call, builtIn);
|
||||||
else if (version < 400)
|
else if (version < 400)
|
||||||
function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
|
function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
|
||||||
@@ -6422,6 +6568,12 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
|
|||||||
type.copyArrayInnerSizes(publicType.arraySizes);
|
type.copyArrayInnerSizes(publicType.arraySizes);
|
||||||
arrayOfArrayVersionCheck(loc, type.getArraySizes());
|
arrayOfArrayVersionCheck(loc, type.getArraySizes());
|
||||||
|
|
||||||
|
if (initializer) {
|
||||||
|
if (type.getBasicType() == EbtRayQuery) {
|
||||||
|
error(loc, "ray queries can only be initialized by using the rayQueryInitializeEXT intrinsic:", "=", identifier.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (type.isCoopMat()) {
|
if (type.isCoopMat()) {
|
||||||
intermediate.setUseVulkanMemoryModel();
|
intermediate.setUseVulkanMemoryModel();
|
||||||
intermediate.setUseStorageBuffer();
|
intermediate.setUseStorageBuffer();
|
||||||
@@ -6461,7 +6613,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
|
|||||||
transparentOpaqueCheck(loc, type, identifier);
|
transparentOpaqueCheck(loc, type, identifier);
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
atomicUintCheck(loc, type, identifier);
|
atomicUintCheck(loc, type, identifier);
|
||||||
accStructNVCheck(loc, type, identifier);
|
accStructCheck(loc, type, identifier);
|
||||||
checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false);
|
checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false);
|
||||||
#endif
|
#endif
|
||||||
if (type.getQualifier().storage == EvqConst && type.containsReference()) {
|
if (type.getQualifier().storage == EvqConst && type.containsReference()) {
|
||||||
@@ -7177,6 +7329,8 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
|
|||||||
if (!node->getType().isCoopMat()) {
|
if (!node->getType().isCoopMat()) {
|
||||||
if (type.getBasicType() != node->getType().getBasicType()) {
|
if (type.getBasicType() != node->getType().getBasicType()) {
|
||||||
node = intermediate.addConversion(type.getBasicType(), node);
|
node = intermediate.addConversion(type.getBasicType(), node);
|
||||||
|
if (node == nullptr)
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
node = intermediate.setAggregateOperator(node, EOpConstructCooperativeMatrix, type, node->getLoc());
|
node = intermediate.setAggregateOperator(node, EOpConstructCooperativeMatrix, type, node->getLoc());
|
||||||
} else {
|
} else {
|
||||||
@@ -7355,8 +7509,8 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
arraySizesCheck(memberLoc, currentBlockQualifier, memberType.getArraySizes(), nullptr, member == typeList.size() - 1);
|
arraySizesCheck(memberLoc, currentBlockQualifier, memberType.getArraySizes(), nullptr, member == typeList.size() - 1);
|
||||||
if (memberQualifier.hasOffset()) {
|
if (memberQualifier.hasOffset()) {
|
||||||
if (spvVersion.spv == 0) {
|
if (spvVersion.spv == 0) {
|
||||||
requireProfile(memberLoc, ~EEsProfile, "offset on block member");
|
profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "\"offset\" on block member");
|
||||||
profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "offset on block member");
|
profileRequires(memberLoc, EEsProfile, 300, E_GL_ARB_enhanced_layouts, "\"offset\" on block member");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7395,7 +7549,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
// Special case for "push_constant uniform", which has a default of std430,
|
// Special case for "push_constant uniform", which has a default of std430,
|
||||||
// contrary to normal uniform defaults, and can't have a default tracked for it.
|
// contrary to normal uniform defaults, and can't have a default tracked for it.
|
||||||
if ((currentBlockQualifier.isPushConstant() && !currentBlockQualifier.hasPacking()) ||
|
if ((currentBlockQualifier.isPushConstant() && !currentBlockQualifier.hasPacking()) ||
|
||||||
(currentBlockQualifier.isShaderRecordNV() && !currentBlockQualifier.hasPacking()))
|
(currentBlockQualifier.isShaderRecord() && !currentBlockQualifier.hasPacking()))
|
||||||
currentBlockQualifier.layoutPacking = ElpStd430;
|
currentBlockQualifier.layoutPacking = ElpStd430;
|
||||||
|
|
||||||
// Special case for "taskNV in/out", which has a default of std430,
|
// Special case for "taskNV in/out", which has a default of std430,
|
||||||
@@ -7495,6 +7649,8 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
|
fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
|
||||||
fixXfbOffsets(currentBlockQualifier, typeList);
|
fixXfbOffsets(currentBlockQualifier, typeList);
|
||||||
fixBlockUniformOffsets(currentBlockQualifier, typeList);
|
fixBlockUniformOffsets(currentBlockQualifier, typeList);
|
||||||
|
fixBlockUniformLayoutMatrix(currentBlockQualifier, &typeList, nullptr);
|
||||||
|
fixBlockUniformLayoutPacking(currentBlockQualifier, &typeList, nullptr);
|
||||||
for (unsigned int member = 0; member < typeList.size(); ++member)
|
for (unsigned int member = 0; member < typeList.size(); ++member)
|
||||||
layoutTypeCheck(typeList[member].loc, *typeList[member].type);
|
layoutTypeCheck(typeList[member].loc, *typeList[member].type);
|
||||||
|
|
||||||
@@ -7612,6 +7768,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
// with a particular stage.
|
// with a particular stage.
|
||||||
void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier)
|
void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier)
|
||||||
{
|
{
|
||||||
|
const char *extsrt[2] = { E_GL_NV_ray_tracing, E_GL_EXT_ray_tracing };
|
||||||
switch (qualifier.storage) {
|
switch (qualifier.storage) {
|
||||||
case EvqUniform:
|
case EvqUniform:
|
||||||
profileRequires(loc, EEsProfile, 300, nullptr, "uniform block");
|
profileRequires(loc, EEsProfile, 300, nullptr, "uniform block");
|
||||||
@@ -7621,7 +7778,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
|
|||||||
break;
|
break;
|
||||||
case EvqBuffer:
|
case EvqBuffer:
|
||||||
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
|
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
|
||||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block");
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "buffer block");
|
||||||
profileRequires(loc, EEsProfile, 310, nullptr, "buffer block");
|
profileRequires(loc, EEsProfile, 310, nullptr, "buffer block");
|
||||||
break;
|
break;
|
||||||
case EvqVaryingIn:
|
case EvqVaryingIn:
|
||||||
@@ -7650,28 +7807,28 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
case EvqPayloadNV:
|
case EvqPayload:
|
||||||
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV block");
|
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadNV block");
|
||||||
requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask),
|
requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask),
|
||||||
"rayPayloadNV block");
|
"rayPayloadNV block");
|
||||||
break;
|
break;
|
||||||
case EvqPayloadInNV:
|
case EvqPayloadIn:
|
||||||
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV block");
|
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadInNV block");
|
||||||
requireStage(loc, (EShLanguageMask)(EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask),
|
requireStage(loc, (EShLanguageMask)(EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask),
|
||||||
"rayPayloadInNV block");
|
"rayPayloadInNV block");
|
||||||
break;
|
break;
|
||||||
case EvqHitAttrNV:
|
case EvqHitAttr:
|
||||||
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV block");
|
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "hitAttributeNV block");
|
||||||
requireStage(loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask), "hitAttributeNV block");
|
requireStage(loc, (EShLanguageMask)(EShLangIntersectMask | EShLangAnyHitMask | EShLangClosestHitMask), "hitAttributeNV block");
|
||||||
break;
|
break;
|
||||||
case EvqCallableDataNV:
|
case EvqCallableData:
|
||||||
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "callableDataNV block");
|
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataNV block");
|
||||||
requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask),
|
requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask),
|
||||||
"callableDataNV block");
|
"callableDataNV block");
|
||||||
break;
|
break;
|
||||||
case EvqCallableDataInNV:
|
case EvqCallableDataIn:
|
||||||
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV block");
|
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataInNV block");
|
||||||
requireStage(loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV block");
|
requireStage(loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV block");
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
@@ -7710,8 +7867,8 @@ void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier&
|
|||||||
error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
|
error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
|
||||||
if (qualifier.isPushConstant())
|
if (qualifier.isPushConstant())
|
||||||
intermediate.addPushConstantCount();
|
intermediate.addPushConstantCount();
|
||||||
if (qualifier.isShaderRecordNV())
|
if (qualifier.isShaderRecord())
|
||||||
intermediate.addShaderRecordNVCount();
|
intermediate.addShaderRecordCount();
|
||||||
if (qualifier.isTaskMemory())
|
if (qualifier.isTaskMemory())
|
||||||
intermediate.addTaskNVCount();
|
intermediate.addTaskNVCount();
|
||||||
}
|
}
|
||||||
@@ -7864,6 +8021,101 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Spread LayoutMatrix to uniform block member, if a uniform block member is a struct,
|
||||||
|
// we need spread LayoutMatrix to this struct member too. and keep this rule for recursive.
|
||||||
|
//
|
||||||
|
void TParseContext::fixBlockUniformLayoutMatrix(TQualifier& qualifier, TTypeList* originTypeList,
|
||||||
|
TTypeList* tmpTypeList)
|
||||||
|
{
|
||||||
|
assert(tmpTypeList == nullptr || originTypeList->size() == tmpTypeList->size());
|
||||||
|
for (unsigned int member = 0; member < originTypeList->size(); ++member) {
|
||||||
|
if (qualifier.layoutPacking != ElpNone) {
|
||||||
|
if (tmpTypeList == nullptr) {
|
||||||
|
if (((*originTypeList)[member].type->isMatrix() ||
|
||||||
|
(*originTypeList)[member].type->getBasicType() == EbtStruct) &&
|
||||||
|
(*originTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) {
|
||||||
|
(*originTypeList)[member].type->getQualifier().layoutMatrix = qualifier.layoutMatrix;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (((*tmpTypeList)[member].type->isMatrix() ||
|
||||||
|
(*tmpTypeList)[member].type->getBasicType() == EbtStruct) &&
|
||||||
|
(*tmpTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) {
|
||||||
|
(*tmpTypeList)[member].type->getQualifier().layoutMatrix = qualifier.layoutMatrix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*originTypeList)[member].type->getBasicType() == EbtStruct) {
|
||||||
|
TQualifier* memberQualifier = nullptr;
|
||||||
|
// block member can be declare a matrix style, so it should be update to the member's style
|
||||||
|
if ((*originTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) {
|
||||||
|
memberQualifier = &qualifier;
|
||||||
|
} else {
|
||||||
|
memberQualifier = &((*originTypeList)[member].type->getQualifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
const TType* tmpType = tmpTypeList == nullptr ?
|
||||||
|
(*originTypeList)[member].type->clone() : (*tmpTypeList)[member].type;
|
||||||
|
|
||||||
|
fixBlockUniformLayoutMatrix(*memberQualifier, (*originTypeList)[member].type->getWritableStruct(),
|
||||||
|
tmpType->getWritableStruct());
|
||||||
|
|
||||||
|
const TTypeList* structure = recordStructCopy(matrixFixRecord, (*originTypeList)[member].type, tmpType);
|
||||||
|
|
||||||
|
if (tmpTypeList == nullptr) {
|
||||||
|
(*originTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
|
||||||
|
}
|
||||||
|
if (tmpTypeList != nullptr) {
|
||||||
|
(*tmpTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Spread LayoutPacking to block member, if a block member is a struct, we need spread LayoutPacking to
|
||||||
|
// this struct member too. and keep this rule for recursive.
|
||||||
|
//
|
||||||
|
void TParseContext::fixBlockUniformLayoutPacking(TQualifier& qualifier, TTypeList* originTypeList,
|
||||||
|
TTypeList* tmpTypeList)
|
||||||
|
{
|
||||||
|
assert(tmpTypeList == nullptr || originTypeList->size() == tmpTypeList->size());
|
||||||
|
for (unsigned int member = 0; member < originTypeList->size(); ++member) {
|
||||||
|
if (qualifier.layoutPacking != ElpNone) {
|
||||||
|
if (tmpTypeList == nullptr) {
|
||||||
|
if ((*originTypeList)[member].type->getQualifier().layoutPacking == ElpNone) {
|
||||||
|
(*originTypeList)[member].type->getQualifier().layoutPacking = qualifier.layoutPacking;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((*tmpTypeList)[member].type->getQualifier().layoutPacking == ElpNone) {
|
||||||
|
(*tmpTypeList)[member].type->getQualifier().layoutPacking = qualifier.layoutPacking;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*originTypeList)[member].type->getBasicType() == EbtStruct) {
|
||||||
|
// Deep copy the type in pool.
|
||||||
|
// Because, struct use in different block may have different layout qualifier.
|
||||||
|
// We have to new a object to distinguish between them.
|
||||||
|
const TType* tmpType = tmpTypeList == nullptr ?
|
||||||
|
(*originTypeList)[member].type->clone() : (*tmpTypeList)[member].type;
|
||||||
|
|
||||||
|
fixBlockUniformLayoutPacking(qualifier, (*originTypeList)[member].type->getWritableStruct(),
|
||||||
|
tmpType->getWritableStruct());
|
||||||
|
|
||||||
|
const TTypeList* structure = recordStructCopy(packingFixRecord, (*originTypeList)[member].type, tmpType);
|
||||||
|
|
||||||
|
if (tmpTypeList == nullptr) {
|
||||||
|
(*originTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
|
||||||
|
}
|
||||||
|
if (tmpTypeList != nullptr) {
|
||||||
|
(*tmpTypeList)[member].type->setStruct(const_cast<TTypeList*>(structure));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For an identifier that is already declared, add more qualification to it.
|
// For an identifier that is already declared, add more qualification to it.
|
||||||
void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier)
|
void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier)
|
||||||
{
|
{
|
||||||
@@ -8172,6 +8424,16 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
|
|||||||
{
|
{
|
||||||
checkIoArraysConsistency(loc);
|
checkIoArraysConsistency(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (publicType.shaderQualifiers.layoutPrimitiveCulling) {
|
||||||
|
if (publicType.qualifier.storage != EvqTemporary)
|
||||||
|
error(loc, "layout qualifier can not have storage qualifiers", "primitive_culling","", "");
|
||||||
|
else {
|
||||||
|
intermediate.setLayoutPrimitiveCulling();
|
||||||
|
}
|
||||||
|
// Exit early as further checks are not valid
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
const TQualifier& qualifier = publicType.qualifier;
|
const TQualifier& qualifier = publicType.qualifier;
|
||||||
|
|
||||||
@@ -8233,7 +8495,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
|
|||||||
error(loc, "cannot declare a default, can only be used on a block", "buffer_reference", "");
|
error(loc, "cannot declare a default, can only be used on a block", "buffer_reference", "");
|
||||||
if (qualifier.hasSpecConstantId())
|
if (qualifier.hasSpecConstantId())
|
||||||
error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", "");
|
error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", "");
|
||||||
if (qualifier.isShaderRecordNV())
|
if (qualifier.isShaderRecord())
|
||||||
error(loc, "cannot declare a default, can only be used on a block", "shaderRecordNV", "");
|
error(loc, "cannot declare a default, can only be used on a block", "shaderRecordNV", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8322,5 +8584,43 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre
|
|||||||
return switchNode;
|
return switchNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// When a struct used in block, and has it's own layout packing, layout matrix,
|
||||||
|
// record the origin structure of a struct to map, and Record the structure copy to the copy table,
|
||||||
|
//
|
||||||
|
const TTypeList* TParseContext::recordStructCopy(TStructRecord& record, const TType* originType, const TType* tmpType)
|
||||||
|
{
|
||||||
|
size_t memberCount = tmpType->getStruct()->size();
|
||||||
|
size_t originHash = 0, tmpHash = 0;
|
||||||
|
std::hash<size_t> hasher;
|
||||||
|
for (size_t i = 0; i < memberCount; i++) {
|
||||||
|
size_t originMemberHash = hasher(originType->getStruct()->at(i).type->getQualifier().layoutPacking +
|
||||||
|
originType->getStruct()->at(i).type->getQualifier().layoutMatrix);
|
||||||
|
size_t tmpMemberHash = hasher(tmpType->getStruct()->at(i).type->getQualifier().layoutPacking +
|
||||||
|
tmpType->getStruct()->at(i).type->getQualifier().layoutMatrix);
|
||||||
|
originHash = hasher((originHash ^ originMemberHash) << 1);
|
||||||
|
tmpHash = hasher((tmpHash ^ tmpMemberHash) << 1);
|
||||||
|
}
|
||||||
|
const TTypeList* originStruct = originType->getStruct();
|
||||||
|
const TTypeList* tmpStruct = tmpType->getStruct();
|
||||||
|
if (originHash != tmpHash) {
|
||||||
|
auto fixRecords = record.find(originStruct);
|
||||||
|
if (fixRecords != record.end()) {
|
||||||
|
auto fixRecord = fixRecords->second.find(tmpHash);
|
||||||
|
if (fixRecord != fixRecords->second.end()) {
|
||||||
|
return fixRecord->second;
|
||||||
|
} else {
|
||||||
|
record[originStruct][tmpHash] = tmpStruct;
|
||||||
|
return tmpStruct;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
record[originStruct] = std::map<size_t, const TTypeList*>();
|
||||||
|
record[originStruct][tmpHash] = tmpStruct;
|
||||||
|
return tmpStruct;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return originStruct;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ class TScanContext;
|
|||||||
class TPpContext;
|
class TPpContext;
|
||||||
|
|
||||||
typedef std::set<int> TIdSetType;
|
typedef std::set<int> TIdSetType;
|
||||||
|
typedef std::map<const TTypeList*, std::map<size_t, const TTypeList*>> TStructRecord;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sharable code (as well as what's in TParseVersions) across
|
// Sharable code (as well as what's in TParseVersions) across
|
||||||
@@ -83,6 +84,7 @@ public:
|
|||||||
scopeMangler("::"),
|
scopeMangler("::"),
|
||||||
symbolTable(symbolTable),
|
symbolTable(symbolTable),
|
||||||
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
||||||
|
currentFunctionType(nullptr),
|
||||||
postEntryPointReturn(false),
|
postEntryPointReturn(false),
|
||||||
contextPragma(true, false),
|
contextPragma(true, false),
|
||||||
beginInvocationInterlockCount(0), endInvocationInterlockCount(0),
|
beginInvocationInterlockCount(0), endInvocationInterlockCount(0),
|
||||||
@@ -315,6 +317,7 @@ public:
|
|||||||
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
|
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
|
||||||
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
|
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
|
||||||
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
||||||
|
TIntermTyped* handleDotSwizzle(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
||||||
void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName);
|
void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName);
|
||||||
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
||||||
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
||||||
@@ -326,6 +329,7 @@ public:
|
|||||||
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||||
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
|
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
|
||||||
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
|
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
|
||||||
|
TIntermTyped* addAssign(const TSourceLoc&, TOperator op, TIntermTyped* left, TIntermTyped* right);
|
||||||
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
||||||
void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
|
void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
|
||||||
void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&);
|
void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&);
|
||||||
@@ -358,7 +362,7 @@ public:
|
|||||||
void boolCheck(const TSourceLoc&, const TPublicType&);
|
void boolCheck(const TSourceLoc&, const TPublicType&);
|
||||||
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
|
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
|
||||||
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
void accStructNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
|
void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
|
||||||
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
void memberQualifierCheck(glslang::TPublicType&);
|
void memberQualifierCheck(glslang::TPublicType&);
|
||||||
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&);
|
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&);
|
||||||
@@ -417,12 +421,15 @@ public:
|
|||||||
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
|
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
|
||||||
void fixXfbOffsets(TQualifier&, TTypeList&);
|
void fixXfbOffsets(TQualifier&, TTypeList&);
|
||||||
void fixBlockUniformOffsets(TQualifier&, TTypeList&);
|
void fixBlockUniformOffsets(TQualifier&, TTypeList&);
|
||||||
|
void fixBlockUniformLayoutMatrix(TQualifier&, TTypeList*, TTypeList*);
|
||||||
|
void fixBlockUniformLayoutPacking(TQualifier&, TTypeList*, TTypeList*);
|
||||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
|
void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
|
||||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
||||||
void invariantCheck(const TSourceLoc&, const TQualifier&);
|
void invariantCheck(const TSourceLoc&, const TQualifier&);
|
||||||
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
||||||
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||||
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
||||||
|
const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*);
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
TAttributeType attributeFromName(const TString& name) const;
|
TAttributeType attributeFromName(const TString& name) const;
|
||||||
@@ -483,6 +490,8 @@ protected:
|
|||||||
bool anyIndexLimits;
|
bool anyIndexLimits;
|
||||||
TIdSetType inductiveLoopIds;
|
TIdSetType inductiveLoopIds;
|
||||||
TVector<TIntermTyped*> needsIndexLimitationChecking;
|
TVector<TIntermTyped*> needsIndexLimitationChecking;
|
||||||
|
TStructRecord matrixFixRecord;
|
||||||
|
TStructRecord packingFixRecord;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Geometry shader input arrays:
|
// Geometry shader input arrays:
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Copyright (C) 2020 Google, Inc.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -187,17 +189,15 @@ bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstT
|
|||||||
if (lookingInMiddle) {
|
if (lookingInMiddle) {
|
||||||
notFirstToken = true;
|
notFirstToken = true;
|
||||||
// make forward progress by finishing off the current line plus extra new lines
|
// make forward progress by finishing off the current line plus extra new lines
|
||||||
if (peek() == '\n' || peek() == '\r') {
|
if (peek() != '\n' && peek() != '\r') {
|
||||||
while (peek() == '\n' || peek() == '\r')
|
|
||||||
get();
|
|
||||||
} else
|
|
||||||
do {
|
do {
|
||||||
c = get();
|
c = get();
|
||||||
} while (c != EndOfInput && c != '\n' && c != '\r');
|
} while (c != EndOfInput && c != '\n' && c != '\r');
|
||||||
while (peek() == '\n' || peek() == '\r')
|
}
|
||||||
get();
|
while (peek() == '\n' || peek() == '\r')
|
||||||
if (peek() == EndOfInput)
|
get();
|
||||||
return true;
|
if (peek() == EndOfInput)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
lookingInMiddle = true;
|
lookingInMiddle = true;
|
||||||
|
|
||||||
@@ -416,6 +416,7 @@ void TScanContext::fillInKeywordMap()
|
|||||||
(*KeywordMap)["queuefamilycoherent"] = QUEUEFAMILYCOHERENT;
|
(*KeywordMap)["queuefamilycoherent"] = QUEUEFAMILYCOHERENT;
|
||||||
(*KeywordMap)["workgroupcoherent"] = WORKGROUPCOHERENT;
|
(*KeywordMap)["workgroupcoherent"] = WORKGROUPCOHERENT;
|
||||||
(*KeywordMap)["subgroupcoherent"] = SUBGROUPCOHERENT;
|
(*KeywordMap)["subgroupcoherent"] = SUBGROUPCOHERENT;
|
||||||
|
(*KeywordMap)["shadercallcoherent"] = SHADERCALLCOHERENT;
|
||||||
(*KeywordMap)["nonprivate"] = NONPRIVATE;
|
(*KeywordMap)["nonprivate"] = NONPRIVATE;
|
||||||
(*KeywordMap)["restrict"] = RESTRICT;
|
(*KeywordMap)["restrict"] = RESTRICT;
|
||||||
(*KeywordMap)["readonly"] = READONLY;
|
(*KeywordMap)["readonly"] = READONLY;
|
||||||
@@ -704,11 +705,18 @@ void TScanContext::fillInKeywordMap()
|
|||||||
(*KeywordMap)["precise"] = PRECISE;
|
(*KeywordMap)["precise"] = PRECISE;
|
||||||
|
|
||||||
(*KeywordMap)["rayPayloadNV"] = PAYLOADNV;
|
(*KeywordMap)["rayPayloadNV"] = PAYLOADNV;
|
||||||
|
(*KeywordMap)["rayPayloadEXT"] = PAYLOADEXT;
|
||||||
(*KeywordMap)["rayPayloadInNV"] = PAYLOADINNV;
|
(*KeywordMap)["rayPayloadInNV"] = PAYLOADINNV;
|
||||||
|
(*KeywordMap)["rayPayloadInEXT"] = PAYLOADINEXT;
|
||||||
(*KeywordMap)["hitAttributeNV"] = HITATTRNV;
|
(*KeywordMap)["hitAttributeNV"] = HITATTRNV;
|
||||||
|
(*KeywordMap)["hitAttributeEXT"] = HITATTREXT;
|
||||||
(*KeywordMap)["callableDataNV"] = CALLDATANV;
|
(*KeywordMap)["callableDataNV"] = CALLDATANV;
|
||||||
|
(*KeywordMap)["callableDataEXT"] = CALLDATAEXT;
|
||||||
(*KeywordMap)["callableDataInNV"] = CALLDATAINNV;
|
(*KeywordMap)["callableDataInNV"] = CALLDATAINNV;
|
||||||
|
(*KeywordMap)["callableDataInEXT"] = CALLDATAINEXT;
|
||||||
(*KeywordMap)["accelerationStructureNV"] = ACCSTRUCTNV;
|
(*KeywordMap)["accelerationStructureNV"] = ACCSTRUCTNV;
|
||||||
|
(*KeywordMap)["accelerationStructureEXT"] = ACCSTRUCTEXT;
|
||||||
|
(*KeywordMap)["rayQueryEXT"] = RAYQUERYEXT;
|
||||||
(*KeywordMap)["perprimitiveNV"] = PERPRIMITIVENV;
|
(*KeywordMap)["perprimitiveNV"] = PERPRIMITIVENV;
|
||||||
(*KeywordMap)["perviewNV"] = PERVIEWNV;
|
(*KeywordMap)["perviewNV"] = PERVIEWNV;
|
||||||
(*KeywordMap)["taskNV"] = PERTASKNV;
|
(*KeywordMap)["taskNV"] = PERTASKNV;
|
||||||
@@ -843,6 +851,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
|||||||
parseContext.error(loc, "not supported", "::", "");
|
parseContext.error(loc, "not supported", "::", "");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PpAtomConstString: parserToken->sType.lex.string = NewPoolTString(tokenText); return STRING_LITERAL;
|
||||||
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
|
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
|
||||||
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
|
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
|
||||||
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
|
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
|
||||||
@@ -908,7 +917,8 @@ int TScanContext::tokenizeIdentifier()
|
|||||||
case BUFFER:
|
case BUFFER:
|
||||||
afterBuffer = true;
|
afterBuffer = true;
|
||||||
if ((parseContext.isEsProfile() && parseContext.version < 310) ||
|
if ((parseContext.isEsProfile() && parseContext.version < 310) ||
|
||||||
(!parseContext.isEsProfile() && parseContext.version < 430))
|
(!parseContext.isEsProfile() && (parseContext.version < 430 &&
|
||||||
|
!parseContext.extensionTurnedOn(E_GL_ARB_shader_storage_buffer_object))))
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
@@ -1014,6 +1024,23 @@ int TScanContext::tokenizeIdentifier()
|
|||||||
parseContext.extensionTurnedOn(E_GL_NV_ray_tracing))
|
parseContext.extensionTurnedOn(E_GL_NV_ray_tracing))
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
case PAYLOADEXT:
|
||||||
|
case PAYLOADINEXT:
|
||||||
|
case HITATTREXT:
|
||||||
|
case CALLDATAEXT:
|
||||||
|
case CALLDATAINEXT:
|
||||||
|
case ACCSTRUCTEXT:
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_EXT_ray_tracing) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_EXT_ray_query))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
case RAYQUERYEXT:
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
(!parseContext.isEsProfile() && parseContext.version >= 460
|
||||||
|
&& parseContext.extensionTurnedOn(E_GL_EXT_ray_query)))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
case ATOMIC_UINT:
|
case ATOMIC_UINT:
|
||||||
if ((parseContext.isEsProfile() && parseContext.version >= 310) ||
|
if ((parseContext.isEsProfile() && parseContext.version >= 310) ||
|
||||||
parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters))
|
parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters))
|
||||||
@@ -1025,6 +1052,7 @@ int TScanContext::tokenizeIdentifier()
|
|||||||
case QUEUEFAMILYCOHERENT:
|
case QUEUEFAMILYCOHERENT:
|
||||||
case WORKGROUPCOHERENT:
|
case WORKGROUPCOHERENT:
|
||||||
case SUBGROUPCOHERENT:
|
case SUBGROUPCOHERENT:
|
||||||
|
case SHADERCALLCOHERENT:
|
||||||
case NONPRIVATE:
|
case NONPRIVATE:
|
||||||
case RESTRICT:
|
case RESTRICT:
|
||||||
case READONLY:
|
case READONLY:
|
||||||
@@ -1168,8 +1196,8 @@ int TScanContext::tokenizeIdentifier()
|
|||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.isEsProfile() || parseContext.version < 150 ||
|
if (parseContext.isEsProfile() || parseContext.version < 150 ||
|
||||||
(!parseContext.symbolTable.atBuiltInLevel() &&
|
(!parseContext.symbolTable.atBuiltInLevel() &&
|
||||||
parseContext.version < 400 &&
|
(parseContext.version < 400 && !parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) &&
|
||||||
!parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64)))
|
(parseContext.version < 410 && !parseContext.extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit)))))
|
||||||
reservedWord();
|
reservedWord();
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
@@ -1764,7 +1792,9 @@ int TScanContext::dMat()
|
|||||||
|
|
||||||
if (!parseContext.isEsProfile() && (parseContext.version >= 400 ||
|
if (!parseContext.isEsProfile() && (parseContext.version >= 400 ||
|
||||||
parseContext.symbolTable.atBuiltInLevel() ||
|
parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
(parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64))))
|
(parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64)) ||
|
||||||
|
(parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit)
|
||||||
|
&& parseContext.language == EShLangVertex)))
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
if (parseContext.isForwardCompatible())
|
if (parseContext.isForwardCompatible())
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2013-2016 LunarG, Inc.
|
// Copyright (C) 2013-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2020 Google, Inc.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -51,9 +51,9 @@
|
|||||||
#include "ScanContext.h"
|
#include "ScanContext.h"
|
||||||
|
|
||||||
#ifdef ENABLE_HLSL
|
#ifdef ENABLE_HLSL
|
||||||
#include "../../hlsl/hlslParseHelper.h"
|
#include "../HLSL/hlslParseHelper.h"
|
||||||
#include "../../hlsl/hlslParseables.h"
|
#include "../HLSL/hlslParseables.h"
|
||||||
#include "../../hlsl/hlslScanContext.h"
|
#include "../HLSL/hlslScanContext.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../Include/ShHandle.h"
|
#include "../Include/ShHandle.h"
|
||||||
@@ -72,6 +72,9 @@
|
|||||||
// token to print ", but none of that seems appropriate for this file.
|
// token to print ", but none of that seems appropriate for this file.
|
||||||
#include "preprocessor/PpTokens.h"
|
#include "preprocessor/PpTokens.h"
|
||||||
|
|
||||||
|
// Build-time generated includes
|
||||||
|
#include "../../glslang/build_info.h"
|
||||||
|
|
||||||
namespace { // anonymous namespace for file-local functions and symbols
|
namespace { // anonymous namespace for file-local functions and symbols
|
||||||
|
|
||||||
// Total number of successful initializers of glslang: a refcount
|
// Total number of successful initializers of glslang: a refcount
|
||||||
@@ -291,6 +294,9 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi
|
|||||||
#ifdef GLSLANG_WEB
|
#ifdef GLSLANG_WEB
|
||||||
profile = EEsProfile;
|
profile = EEsProfile;
|
||||||
version = 310;
|
version = 310;
|
||||||
|
#elif defined(GLSLANG_ANGLE)
|
||||||
|
profile = ECoreProfile;
|
||||||
|
version = 450;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
(*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]);
|
(*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]);
|
||||||
@@ -312,6 +318,9 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
|||||||
#ifdef GLSLANG_WEB
|
#ifdef GLSLANG_WEB
|
||||||
profile = EEsProfile;
|
profile = EEsProfile;
|
||||||
version = 310;
|
version = 310;
|
||||||
|
#elif defined(GLSLANG_ANGLE)
|
||||||
|
profile = ECoreProfile;
|
||||||
|
version = 450;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
|
std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
|
||||||
@@ -351,7 +360,6 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
|||||||
(profile == EEsProfile && version >= 310))
|
(profile == EEsProfile && version >= 310))
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
#endif
|
|
||||||
|
|
||||||
// check for compute
|
// check for compute
|
||||||
if ((profile != EEsProfile && version >= 420) ||
|
if ((profile != EEsProfile && version >= 420) ||
|
||||||
@@ -359,19 +367,20 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
|||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
|
|
||||||
|
#ifndef GLSLANG_ANGLE
|
||||||
// check for ray tracing stages
|
// check for ray tracing stages
|
||||||
if (profile != EEsProfile && version >= 450) {
|
if (profile != EEsProfile && version >= 450) {
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGen, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersectNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersect, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHitNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHit, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHitNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHit, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMissNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMiss, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallableNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallable, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,6 +395,8 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
|||||||
(profile == EEsProfile && version >= 320))
|
(profile == EEsProfile && version >= 320))
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
|
#endif // !GLSLANG_ANGLE
|
||||||
|
#endif // !GLSLANG_WEB
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -487,7 +498,7 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
|
|||||||
// Function to Print all builtins
|
// Function to Print all builtins
|
||||||
void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable)
|
void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable)
|
||||||
{
|
{
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
infoSink.debug << "BuiltinSymbolTable {\n";
|
infoSink.debug << "BuiltinSymbolTable {\n";
|
||||||
|
|
||||||
symbolTable.dump(infoSink, true);
|
symbolTable.dump(infoSink, true);
|
||||||
@@ -591,7 +602,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
// Correct for stage type...
|
// Correct for stage type...
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case EShLangGeometry:
|
case EShLangGeometry:
|
||||||
@@ -623,12 +634,12 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||||||
version = profile == EEsProfile ? 310 : 420;
|
version = profile == EEsProfile ? 310 : 420;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EShLangRayGenNV:
|
case EShLangRayGen:
|
||||||
case EShLangIntersectNV:
|
case EShLangIntersect:
|
||||||
case EShLangAnyHitNV:
|
case EShLangAnyHit:
|
||||||
case EShLangClosestHitNV:
|
case EShLangClosestHit:
|
||||||
case EShLangMissNV:
|
case EShLangMiss:
|
||||||
case EShLangCallableNV:
|
case EShLangCallable:
|
||||||
if (profile == EEsProfile || version < 460) {
|
if (profile == EEsProfile || version < 460) {
|
||||||
correct = false;
|
correct = false;
|
||||||
infoSink.info.message(EPrefixError, "#version: ray tracing shaders require non-es profile with version 460 or above");
|
infoSink.info.message(EPrefixError, "#version: ray tracing shaders require non-es profile with version 460 or above");
|
||||||
@@ -716,6 +727,9 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages
|
|||||||
case EShClientOpenGL:
|
case EShClientOpenGL:
|
||||||
spvVersion.openGl = environment->input.dialectVersion;
|
spvVersion.openGl = environment->input.dialectVersion;
|
||||||
break;
|
break;
|
||||||
|
case EShClientCount:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
switch (environment->input.languageFamily) {
|
switch (environment->input.languageFamily) {
|
||||||
case EShSourceNone:
|
case EShSourceNone:
|
||||||
@@ -728,6 +742,9 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages
|
|||||||
source = EShSourceHlsl;
|
source = EShSourceHlsl;
|
||||||
messages = static_cast<EShMessages>(messages | EShMsgReadHlsl);
|
messages = static_cast<EShMessages>(messages | EShMsgReadHlsl);
|
||||||
break;
|
break;
|
||||||
|
case EShSourceCount:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,7 +878,7 @@ bool ProcessDeferred(
|
|||||||
: userInput.scanVersion(version, profile, versionNotFirstToken);
|
: userInput.scanVersion(version, profile, versionNotFirstToken);
|
||||||
bool versionNotFound = version == 0;
|
bool versionNotFound = version == 0;
|
||||||
if (forceDefaultVersionAndProfile && source == EShSourceGlsl) {
|
if (forceDefaultVersionAndProfile && source == EShSourceGlsl) {
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
|
if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
|
||||||
(version != defaultVersion || profile != defaultProfile)) {
|
(version != defaultVersion || profile != defaultProfile)) {
|
||||||
compiler->infoSink.info << "Warning, (version, profile) forced to be ("
|
compiler->infoSink.info << "Warning, (version, profile) forced to be ("
|
||||||
@@ -884,10 +901,13 @@ bool ProcessDeferred(
|
|||||||
#ifdef GLSLANG_WEB
|
#ifdef GLSLANG_WEB
|
||||||
profile = EEsProfile;
|
profile = EEsProfile;
|
||||||
version = 310;
|
version = 310;
|
||||||
|
#elif defined(GLSLANG_ANGLE)
|
||||||
|
profile = ECoreProfile;
|
||||||
|
version = 450;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
|
bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
bool warnVersionNotFirst = false;
|
bool warnVersionNotFirst = false;
|
||||||
if (! versionWillBeError && versionNotFirstToken) {
|
if (! versionWillBeError && versionNotFirstToken) {
|
||||||
if (messages & EShMsgRelaxedErrors)
|
if (messages & EShMsgRelaxedErrors)
|
||||||
@@ -957,7 +977,7 @@ bool ProcessDeferred(
|
|||||||
parseContext->setLimits(*resources);
|
parseContext->setLimits(*resources);
|
||||||
if (! goodVersion)
|
if (! goodVersion)
|
||||||
parseContext->addError();
|
parseContext->addError();
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
if (warnVersionNotFirst) {
|
if (warnVersionNotFirst) {
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
loc.init();
|
loc.init();
|
||||||
@@ -994,7 +1014,7 @@ bool ProcessDeferred(
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
// Responsible for keeping track of the most recent source string and line in
|
// Responsible for keeping track of the most recent source string and line in
|
||||||
// the preprocessor and outputting newlines appropriately if the source string
|
// the preprocessor and outputting newlines appropriately if the source string
|
||||||
@@ -1217,14 +1237,16 @@ struct DoFullParse{
|
|||||||
parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n";
|
parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_ANGLE
|
||||||
if (messages & EShMsgAST)
|
if (messages & EShMsgAST)
|
||||||
intermediate.output(parseContext.infoSink, true);
|
intermediate.output(parseContext.infoSink, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
// Take a single compilation unit, and run the preprocessor on it.
|
// Take a single compilation unit, and run the preprocessor on it.
|
||||||
// Return: True if there were no issues found in preprocessing,
|
// Return: True if there were no issues found in preprocessing,
|
||||||
// False if during preprocessing any unknown version, pragmas or
|
// False if during preprocessing any unknown version, pragmas or
|
||||||
@@ -1678,19 +1700,29 @@ int ShGetUniformLocation(const ShHandle handle, const char* name)
|
|||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
#include "../Include/revision.h"
|
Version GetVersion()
|
||||||
|
{
|
||||||
|
Version version;
|
||||||
|
version.major = GLSLANG_VERSION_MAJOR;
|
||||||
|
version.minor = GLSLANG_VERSION_MINOR;
|
||||||
|
version.patch = GLSLANG_VERSION_PATCH;
|
||||||
|
version.flavor = GLSLANG_VERSION_FLAVOR;
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
#define QUOTE(s) #s
|
#define QUOTE(s) #s
|
||||||
#define STR(n) QUOTE(n)
|
#define STR(n) QUOTE(n)
|
||||||
|
|
||||||
const char* GetEsslVersionString()
|
const char* GetEsslVersionString()
|
||||||
{
|
{
|
||||||
return "OpenGL ES GLSL 3.20 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL);
|
return "OpenGL ES GLSL 3.20 glslang Khronos. " STR(GLSLANG_VERSION_MAJOR) "." STR(GLSLANG_VERSION_MINOR) "." STR(
|
||||||
|
GLSLANG_VERSION_PATCH) GLSLANG_VERSION_FLAVOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* GetGlslVersionString()
|
const char* GetGlslVersionString()
|
||||||
{
|
{
|
||||||
return "4.60 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL);
|
return "4.60 glslang Khronos. " STR(GLSLANG_VERSION_MAJOR) "." STR(GLSLANG_VERSION_MINOR) "." STR(
|
||||||
|
GLSLANG_VERSION_PATCH) GLSLANG_VERSION_FLAVOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetKhronosToolId()
|
int GetKhronosToolId()
|
||||||
@@ -1771,6 +1803,8 @@ void TShader::setSourceEntryPoint(const char* name)
|
|||||||
sourceEntryPointName = name;
|
sourceEntryPointName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log initial settings and transforms.
|
||||||
|
// See comment for class TProcesses.
|
||||||
void TShader::addProcesses(const std::vector<std::string>& p)
|
void TShader::addProcesses(const std::vector<std::string>& p)
|
||||||
{
|
{
|
||||||
intermediate->addProcesses(p);
|
intermediate->addProcesses(p);
|
||||||
@@ -1852,7 +1886,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
|
|||||||
&environment);
|
&environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
// Fill in a string with the result of preprocessing ShaderStrings
|
// Fill in a string with the result of preprocessing ShaderStrings
|
||||||
// Returns true if all extensions, pragmas and version strings were valid.
|
// Returns true if all extensions, pragmas and version strings were valid.
|
||||||
//
|
//
|
||||||
@@ -1890,7 +1924,7 @@ const char* TShader::getInfoDebugLog()
|
|||||||
}
|
}
|
||||||
|
|
||||||
TProgram::TProgram() :
|
TProgram::TProgram() :
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
reflection(0),
|
reflection(0),
|
||||||
#endif
|
#endif
|
||||||
linked(false)
|
linked(false)
|
||||||
@@ -1906,7 +1940,7 @@ TProgram::TProgram() :
|
|||||||
TProgram::~TProgram()
|
TProgram::~TProgram()
|
||||||
{
|
{
|
||||||
delete infoSink;
|
delete infoSink;
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
delete reflection;
|
delete reflection;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1953,7 +1987,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
|
|||||||
if (stages[stage].size() == 0)
|
if (stages[stage].size() == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
int numEsShaders = 0, numNonEsShaders = 0;
|
int numEsShaders = 0, numNonEsShaders = 0;
|
||||||
for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) {
|
for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) {
|
||||||
if ((*it)->intermediate->getProfile() == EEsProfile) {
|
if ((*it)->intermediate->getProfile() == EEsProfile) {
|
||||||
@@ -2007,8 +2041,10 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
|
|||||||
#endif
|
#endif
|
||||||
intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0);
|
intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0);
|
||||||
|
|
||||||
|
#ifndef GLSLANG_ANGLE
|
||||||
if (messages & EShMsgAST)
|
if (messages & EShMsgAST)
|
||||||
intermediate[stage]->output(*infoSink, true);
|
intermediate[stage]->output(*infoSink, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
return intermediate[stage]->getNumErrors() == 0;
|
return intermediate[stage]->getNumErrors() == 0;
|
||||||
}
|
}
|
||||||
@@ -2023,7 +2059,7 @@ const char* TProgram::getInfoDebugLog()
|
|||||||
return infoSink->debug.c_str();
|
return infoSink->debug.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reflection implementation.
|
// Reflection implementation.
|
||||||
@@ -2105,6 +2141,6 @@ bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper)
|
|||||||
return ioMapper->doMap(pResolver, *infoSink);
|
return ioMapper->doMap(pResolver, *infoSink);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GLSLANG_WEB
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -74,7 +75,8 @@ void TType::buildMangledName(TString& mangledName) const
|
|||||||
case EbtInt64: mangledName += "i64"; break;
|
case EbtInt64: mangledName += "i64"; break;
|
||||||
case EbtUint64: mangledName += "u64"; break;
|
case EbtUint64: mangledName += "u64"; break;
|
||||||
case EbtAtomicUint: mangledName += "au"; break;
|
case EbtAtomicUint: mangledName += "au"; break;
|
||||||
case EbtAccStructNV: mangledName += "asnv"; break;
|
case EbtAccStruct: mangledName += "as"; break;
|
||||||
|
case EbtRayQuery: mangledName += "rq"; break;
|
||||||
#endif
|
#endif
|
||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
switch (sampler.type) {
|
switch (sampler.type) {
|
||||||
@@ -120,7 +122,7 @@ void TType::buildMangledName(TString& mangledName) const
|
|||||||
mangledName += "-tx-struct";
|
mangledName += "-tx-struct";
|
||||||
|
|
||||||
char text[16]; // plenty enough space for the small integers.
|
char text[16]; // plenty enough space for the small integers.
|
||||||
snprintf(text, sizeof(text), "%d-", sampler.getStructReturnIndex());
|
snprintf(text, sizeof(text), "%u-", sampler.getStructReturnIndex());
|
||||||
mangledName += text;
|
mangledName += text;
|
||||||
} else {
|
} else {
|
||||||
switch (sampler.getVectorSize()) {
|
switch (sampler.getVectorSize()) {
|
||||||
@@ -176,7 +178,7 @@ void TType::buildMangledName(TString& mangledName) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Dump functions.
|
// Dump functions.
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ public:
|
|||||||
virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
|
virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
|
||||||
virtual const char** getExtensions() const { return extensions->data(); }
|
virtual const char** getExtensions() const { return extensions->data(); }
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0;
|
virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0;
|
||||||
void dumpExtensions(TInfoSink& infoSink) const;
|
void dumpExtensions(TInfoSink& infoSink) const;
|
||||||
#endif
|
#endif
|
||||||
@@ -196,7 +196,7 @@ public:
|
|||||||
}
|
}
|
||||||
virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); }
|
virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); }
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
virtual void dump(TInfoSink& infoSink, bool complete = false) const;
|
virtual void dump(TInfoSink& infoSink, bool complete = false) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -319,7 +319,7 @@ public:
|
|||||||
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
||||||
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
|
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -381,7 +381,7 @@ public:
|
|||||||
virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }
|
virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }
|
||||||
|
|
||||||
virtual int getAnonId() const { return anonId; }
|
virtual int getAnonId() const { return anonId; }
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
|
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -551,7 +551,7 @@ public:
|
|||||||
|
|
||||||
void relateToOperator(const char* name, TOperator op);
|
void relateToOperator(const char* name, TOperator op);
|
||||||
void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
|
void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
void dump(TInfoSink& infoSink, bool complete = false) const;
|
void dump(TInfoSink& infoSink, bool complete = false) const;
|
||||||
#endif
|
#endif
|
||||||
TSymbolTableLevel* clone() const;
|
TSymbolTableLevel* clone() const;
|
||||||
@@ -854,7 +854,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int getMaxSymbolId() { return uniqueId; }
|
int getMaxSymbolId() { return uniqueId; }
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
void dump(TInfoSink& infoSink, bool complete = false) const;
|
void dump(TInfoSink& infoSink, bool complete = false) const;
|
||||||
#endif
|
#endif
|
||||||
void copyTable(const TSymbolTable& copyOf);
|
void copyTable(const TSymbolTable& copyOf);
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2020 Google, Inc.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -63,6 +64,7 @@
|
|||||||
// checkDeprecated()
|
// checkDeprecated()
|
||||||
// requireNotRemoved()
|
// requireNotRemoved()
|
||||||
// requireExtensions()
|
// requireExtensions()
|
||||||
|
// extensionRequires()
|
||||||
//
|
//
|
||||||
// Typically, only the first two calls are needed. They go into a code path that
|
// Typically, only the first two calls are needed. They go into a code path that
|
||||||
// implements Feature F, and will log the proper error/warning messages. Parsing
|
// implements Feature F, and will log the proper error/warning messages. Parsing
|
||||||
@@ -77,9 +79,11 @@
|
|||||||
// const char* const XXX_extension_X = "XXX_extension_X";
|
// const char* const XXX_extension_X = "XXX_extension_X";
|
||||||
//
|
//
|
||||||
// 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(),
|
// 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(),
|
||||||
// the first function below:
|
// the first function below and optionally a entry to extensionData for additional
|
||||||
|
// error checks:
|
||||||
//
|
//
|
||||||
// extensionBehavior[XXX_extension_X] = EBhDisable;
|
// extensionBehavior[XXX_extension_X] = EBhDisable;
|
||||||
|
// (Optional) exts[] = {XXX_extension_X, EShTargetSpv_1_4}
|
||||||
//
|
//
|
||||||
// 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble():
|
// 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble():
|
||||||
//
|
//
|
||||||
@@ -139,6 +143,8 @@
|
|||||||
// set of extensions that both enable them and are necessary, given the version of the symbol
|
// set of extensions that both enable them and are necessary, given the version of the symbol
|
||||||
// table. (There is a different symbol table for each version.)
|
// table. (There is a different symbol table for each version.)
|
||||||
//
|
//
|
||||||
|
// 7) If the extension has additional requirements like minimum SPIR-V version required, add them
|
||||||
|
// to extensionRequires()
|
||||||
|
|
||||||
#include "parseVersions.h"
|
#include "parseVersions.h"
|
||||||
#include "localintermediate.h"
|
#include "localintermediate.h"
|
||||||
@@ -154,6 +160,20 @@ namespace glslang {
|
|||||||
//
|
//
|
||||||
void TParseVersions::initializeExtensionBehavior()
|
void TParseVersions::initializeExtensionBehavior()
|
||||||
{
|
{
|
||||||
|
typedef struct {
|
||||||
|
const char *const extensionName;
|
||||||
|
EShTargetLanguageVersion minSpvVersion;
|
||||||
|
} extensionData;
|
||||||
|
|
||||||
|
const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4} };
|
||||||
|
|
||||||
|
for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) {
|
||||||
|
// Add only extensions which require > spv1.0 to save space in map
|
||||||
|
if (exts[ii].minSpvVersion > EShTargetSpv_1_0) {
|
||||||
|
extensionMinSpv[E_GL_EXT_ray_tracing] = exts[ii].minSpvVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extensionBehavior[E_GL_OES_texture_3D] = EBhDisable;
|
extensionBehavior[E_GL_OES_texture_3D] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable;
|
extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable;
|
extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable;
|
||||||
@@ -197,6 +217,12 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_ARB_shader_clock] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_clock] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_uniform_buffer_object] = EBhDisable;
|
extensionBehavior[E_GL_ARB_uniform_buffer_object] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_sample_shading] = EBhDisable;
|
extensionBehavior[E_GL_ARB_sample_shading] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_shader_bit_encoding] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_shader_image_size] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_shader_storage_buffer_object] = EBhDisable;
|
||||||
|
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_KHR_shader_subgroup_basic] = EBhDisable;
|
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
|
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
|
||||||
@@ -222,6 +248,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_EXT_buffer_reference2] = EBhDisable;
|
extensionBehavior[E_GL_EXT_buffer_reference2] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_buffer_reference_uvec2] = EBhDisable;
|
extensionBehavior[E_GL_EXT_buffer_reference_uvec2] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_demote_to_helper_invocation] = EBhDisable;
|
extensionBehavior[E_GL_EXT_demote_to_helper_invocation] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_debug_printf] = EBhDisable;
|
||||||
|
|
||||||
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
||||||
@@ -290,11 +317,17 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_OES_tessellation_point_size] = EBhDisable;
|
extensionBehavior[E_GL_OES_tessellation_point_size] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable;
|
extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable;
|
extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shader_integer_mix] = EBhDisable;
|
||||||
|
|
||||||
// EXT extensions
|
// EXT extensions
|
||||||
extensionBehavior[E_GL_EXT_device_group] = EBhDisable;
|
extensionBehavior[E_GL_EXT_device_group] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_multiview] = EBhDisable;
|
extensionBehavior[E_GL_EXT_multiview] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_realtime_clock] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_realtime_clock] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_ray_tracing] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_ray_query] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_ray_flags_primitive_culling] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_blend_func_extended] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shader_implicit_conversions] = EBhDisable;
|
||||||
|
|
||||||
// OVR extensions
|
// OVR extensions
|
||||||
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
|
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
|
||||||
@@ -315,7 +348,9 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int16] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int16] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int64] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int64] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GLSLANG_WEB
|
#endif // GLSLANG_WEB
|
||||||
|
|
||||||
// Get code that is not part of a shared symbol table, is specific to this shader,
|
// Get code that is not part of a shared symbol table, is specific to this shader,
|
||||||
@@ -354,6 +389,9 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_EXT_tessellation_point_size 1\n"
|
"#define GL_EXT_tessellation_point_size 1\n"
|
||||||
"#define GL_EXT_texture_buffer 1\n"
|
"#define GL_EXT_texture_buffer 1\n"
|
||||||
"#define GL_EXT_texture_cube_map_array 1\n"
|
"#define GL_EXT_texture_cube_map_array 1\n"
|
||||||
|
"#define GL_EXT_shader_implicit_conversions 1\n"
|
||||||
|
"#define GL_EXT_shader_integer_mix 1\n"
|
||||||
|
"#define GL_EXT_blend_func_extended 1\n"
|
||||||
|
|
||||||
// OES matching AEP
|
// OES matching AEP
|
||||||
"#define GL_OES_geometry_shader 1\n"
|
"#define GL_OES_geometry_shader 1\n"
|
||||||
@@ -403,10 +441,16 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_ARB_sparse_texture_clamp 1\n"
|
"#define GL_ARB_sparse_texture_clamp 1\n"
|
||||||
"#define GL_ARB_shader_stencil_export 1\n"
|
"#define GL_ARB_shader_stencil_export 1\n"
|
||||||
"#define GL_ARB_sample_shading 1\n"
|
"#define GL_ARB_sample_shading 1\n"
|
||||||
|
"#define GL_ARB_shader_image_size 1\n"
|
||||||
|
"#define GL_ARB_shading_language_packing 1\n"
|
||||||
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
|
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
|
||||||
"#define GL_ARB_post_depth_coverage 1\n"
|
"#define GL_ARB_post_depth_coverage 1\n"
|
||||||
"#define GL_ARB_fragment_shader_interlock 1\n"
|
"#define GL_ARB_fragment_shader_interlock 1\n"
|
||||||
"#define GL_ARB_uniform_buffer_object 1\n"
|
"#define GL_ARB_uniform_buffer_object 1\n"
|
||||||
|
"#define GL_ARB_shader_bit_encoding 1\n"
|
||||||
|
"#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_EXT_shader_non_constant_global_initializers 1\n"
|
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||||
"#define GL_EXT_shader_image_load_formatted 1\n"
|
"#define GL_EXT_shader_image_load_formatted 1\n"
|
||||||
"#define GL_EXT_post_depth_coverage 1\n"
|
"#define GL_EXT_post_depth_coverage 1\n"
|
||||||
@@ -421,6 +465,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_EXT_buffer_reference2 1\n"
|
"#define GL_EXT_buffer_reference2 1\n"
|
||||||
"#define GL_EXT_buffer_reference_uvec2 1\n"
|
"#define GL_EXT_buffer_reference_uvec2 1\n"
|
||||||
"#define GL_EXT_demote_to_helper_invocation 1\n"
|
"#define GL_EXT_demote_to_helper_invocation 1\n"
|
||||||
|
"#define GL_EXT_debug_printf 1\n"
|
||||||
|
|
||||||
// GL_KHR_shader_subgroup
|
// GL_KHR_shader_subgroup
|
||||||
"#define GL_KHR_shader_subgroup_basic 1\n"
|
"#define GL_KHR_shader_subgroup_basic 1\n"
|
||||||
@@ -432,8 +477,11 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_KHR_shader_subgroup_clustered 1\n"
|
"#define GL_KHR_shader_subgroup_clustered 1\n"
|
||||||
"#define GL_KHR_shader_subgroup_quad 1\n"
|
"#define GL_KHR_shader_subgroup_quad 1\n"
|
||||||
|
|
||||||
"#define E_GL_EXT_shader_atomic_int64 1\n"
|
"#define GL_EXT_shader_atomic_int64 1\n"
|
||||||
"#define E_GL_EXT_shader_realtime_clock 1\n"
|
"#define GL_EXT_shader_realtime_clock 1\n"
|
||||||
|
"#define GL_EXT_ray_tracing 1\n"
|
||||||
|
"#define GL_EXT_ray_query 1\n"
|
||||||
|
"#define GL_EXT_ray_flags_primitive_culling 1\n"
|
||||||
|
|
||||||
"#define GL_AMD_shader_ballot 1\n"
|
"#define GL_AMD_shader_ballot 1\n"
|
||||||
"#define GL_AMD_shader_trinary_minmax 1\n"
|
"#define GL_AMD_shader_trinary_minmax 1\n"
|
||||||
@@ -476,6 +524,8 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_EXT_shader_subgroup_extended_types_int16 1\n"
|
"#define GL_EXT_shader_subgroup_extended_types_int16 1\n"
|
||||||
"#define GL_EXT_shader_subgroup_extended_types_int64 1\n"
|
"#define GL_EXT_shader_subgroup_extended_types_int64 1\n"
|
||||||
"#define GL_EXT_shader_subgroup_extended_types_float16 1\n"
|
"#define GL_EXT_shader_subgroup_extended_types_float16 1\n"
|
||||||
|
|
||||||
|
"#define GL_EXT_shader_atomic_float 1\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
if (version >= 150) {
|
if (version >= 150) {
|
||||||
@@ -547,12 +597,12 @@ const char* StageName(EShLanguage stage)
|
|||||||
case EShLangTessControl: return "tessellation control";
|
case EShLangTessControl: return "tessellation control";
|
||||||
case EShLangTessEvaluation: return "tessellation evaluation";
|
case EShLangTessEvaluation: return "tessellation evaluation";
|
||||||
case EShLangGeometry: return "geometry";
|
case EShLangGeometry: return "geometry";
|
||||||
case EShLangRayGenNV: return "ray-generation";
|
case EShLangRayGen: return "ray-generation";
|
||||||
case EShLangIntersectNV: return "intersection";
|
case EShLangIntersect: return "intersection";
|
||||||
case EShLangAnyHitNV: return "any-hit";
|
case EShLangAnyHit: return "any-hit";
|
||||||
case EShLangClosestHitNV: return "closest-hit";
|
case EShLangClosestHit: return "closest-hit";
|
||||||
case EShLangMissNV: return "miss";
|
case EShLangMiss: return "miss";
|
||||||
case EShLangCallableNV: return "callable";
|
case EShLangCallable: return "callable";
|
||||||
case EShLangMeshNV: return "mesh";
|
case EShLangMeshNV: return "mesh";
|
||||||
case EShLangTaskNV: return "task";
|
case EShLangTaskNV: return "task";
|
||||||
#endif
|
#endif
|
||||||
@@ -715,7 +765,8 @@ bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExte
|
|||||||
// Use when there are no profile/version to check, it's just an error if one of the
|
// Use when there are no profile/version to check, it's just an error if one of the
|
||||||
// extensions is not present.
|
// extensions is not present.
|
||||||
//
|
//
|
||||||
void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[],
|
||||||
|
const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc))
|
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc))
|
||||||
return;
|
return;
|
||||||
@@ -734,7 +785,8 @@ void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions,
|
|||||||
// Use by preprocessor when there are no profile/version to check, it's just an error if one of the
|
// Use by preprocessor when there are no profile/version to check, it's just an error if one of the
|
||||||
// extensions is not present.
|
// extensions is not present.
|
||||||
//
|
//
|
||||||
void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[],
|
||||||
|
const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc))
|
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc))
|
||||||
return;
|
return;
|
||||||
@@ -800,10 +852,14 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
|
|||||||
error(getCurrentLoc(), "behavior not supported:", "#extension", behaviorString);
|
error(getCurrentLoc(), "behavior not supported:", "#extension", behaviorString);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool on = behavior != EBhDisable;
|
||||||
|
|
||||||
// check if extension is used with correct shader stage
|
// check if extension is used with correct shader stage
|
||||||
checkExtensionStage(getCurrentLoc(), extension);
|
checkExtensionStage(getCurrentLoc(), extension);
|
||||||
|
|
||||||
|
// check if extension has additional requirements
|
||||||
|
extensionRequires(getCurrentLoc(), extension ,behaviorString);
|
||||||
|
|
||||||
// update the requested extension
|
// update the requested extension
|
||||||
updateExtensionBehavior(extension, behavior);
|
updateExtensionBehavior(extension, behavior);
|
||||||
|
|
||||||
@@ -866,6 +922,32 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
|
|||||||
updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int64", behaviorString);
|
updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int64", behaviorString);
|
||||||
else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_float16") == 0)
|
else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_float16") == 0)
|
||||||
updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_float16", behaviorString);
|
updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_float16", behaviorString);
|
||||||
|
|
||||||
|
// see if we need to update the numeric features
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types") == 0)
|
||||||
|
intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types, on);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int8") == 0)
|
||||||
|
intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int8, on);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int16") == 0)
|
||||||
|
intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int16, on);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int32") == 0)
|
||||||
|
intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int32, on);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int64") == 0)
|
||||||
|
intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int64, on);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_float16") == 0)
|
||||||
|
intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_float16, on);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_float32") == 0)
|
||||||
|
intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_float32, on);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_float64") == 0)
|
||||||
|
intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_float64, on);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_implicit_conversions") == 0)
|
||||||
|
intermediate.updateNumericFeature(TNumericFeatures::shader_implicit_conversions, on);
|
||||||
|
else if (strcmp(extension, "GL_ARB_gpu_shader_fp64") == 0)
|
||||||
|
intermediate.updateNumericFeature(TNumericFeatures::gpu_shader_fp64, on);
|
||||||
|
else if (strcmp(extension, "GL_AMD_gpu_shader_int16") == 0)
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
||||||
@@ -901,7 +983,7 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe
|
|||||||
} else {
|
} else {
|
||||||
if (iter->second == EBhDisablePartial)
|
if (iter->second == EBhDisablePartial)
|
||||||
warn(getCurrentLoc(), "extension is only partially supported:", "#extension", extension);
|
warn(getCurrentLoc(), "extension is only partially supported:", "#extension", extension);
|
||||||
if (behavior == EBhEnable || behavior == EBhRequire)
|
if (behavior != EBhDisable)
|
||||||
intermediate.addRequestedExtension(extension);
|
intermediate.addRequestedExtension(extension);
|
||||||
iter->second = behavior;
|
iter->second = behavior;
|
||||||
}
|
}
|
||||||
@@ -920,6 +1002,24 @@ void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if extension has additional requirements
|
||||||
|
void TParseVersions::extensionRequires(const TSourceLoc &loc, const char * const extension, const char *behaviorString)
|
||||||
|
{
|
||||||
|
bool isEnabled = false;
|
||||||
|
if (!strcmp("require", behaviorString))
|
||||||
|
isEnabled = true;
|
||||||
|
else if (!strcmp("enable", behaviorString))
|
||||||
|
isEnabled = true;
|
||||||
|
|
||||||
|
if (isEnabled) {
|
||||||
|
unsigned int minSpvVersion = 0;
|
||||||
|
auto iter = extensionMinSpv.find(TString(extension));
|
||||||
|
if (iter != extensionMinSpv.end())
|
||||||
|
minSpvVersion = iter->second;
|
||||||
|
requireSpv(loc, extension, minSpvVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Call for any operation needing full GLSL integer data-type support.
|
// Call for any operation needing full GLSL integer data-type support.
|
||||||
void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
|
void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
@@ -930,8 +1030,13 @@ void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
|
|||||||
// Call for any operation needing GLSL double data-type support.
|
// Call for any operation needing GLSL double data-type support.
|
||||||
void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
|
void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
|
|
||||||
//requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
//requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader_fp64, op);
|
if (language == EShLangVertex) {
|
||||||
|
const char* const f64_Extensions[] = {E_GL_ARB_gpu_shader_fp64, E_GL_ARB_vertex_attrib_64bit};
|
||||||
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, 2, f64_Extensions, op);
|
||||||
|
} else
|
||||||
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader_fp64, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation needing GLSL float16 data-type support.
|
// Call for any operation needing GLSL float16 data-type support.
|
||||||
@@ -1172,5 +1277,12 @@ void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op)
|
|||||||
error(loc, "only allowed when generating SPIR-V", op, "");
|
error(loc, "only allowed when generating SPIR-V", op, "");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
void TParseVersions::requireSpv(const TSourceLoc& loc, const char *op, unsigned int version)
|
||||||
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
if (spvVersion.spv < version)
|
||||||
|
error(loc, "not supported for current targeted SPIR-V version", op, "");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
// Copyright (C) 2015-2018 Google, Inc.
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -35,9 +36,12 @@
|
|||||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _VERSIONS_INCLUDED_
|
#ifndef _VERSIONS_INCLUDED_
|
||||||
#define _VERSIONS_INCLUDED_
|
#define _VERSIONS_INCLUDED_
|
||||||
|
|
||||||
|
#define LAST_ELEMENT_MARKER(x) x
|
||||||
|
|
||||||
//
|
//
|
||||||
// Help manage multiple profiles, versions, extensions etc.
|
// Help manage multiple profiles, versions, extensions etc.
|
||||||
//
|
//
|
||||||
@@ -49,12 +53,13 @@
|
|||||||
// Don't maintain an ordinal set of enums (0,1,2,3...) to avoid all possible
|
// Don't maintain an ordinal set of enums (0,1,2,3...) to avoid all possible
|
||||||
// defects from mixing the two different forms.
|
// defects from mixing the two different forms.
|
||||||
//
|
//
|
||||||
typedef enum {
|
typedef enum : unsigned {
|
||||||
EBadProfile = 0,
|
EBadProfile = 0,
|
||||||
ENoProfile = (1 << 0), // only for desktop, before profiles showed up
|
ENoProfile = (1 << 0), // only for desktop, before profiles showed up
|
||||||
ECoreProfile = (1 << 1),
|
ECoreProfile = (1 << 1),
|
||||||
ECompatibilityProfile = (1 << 2),
|
ECompatibilityProfile = (1 << 2),
|
||||||
EEsProfile = (1 << 3)
|
EEsProfile = (1 << 3),
|
||||||
|
LAST_ELEMENT_MARKER(EProfileCount),
|
||||||
} EProfile;
|
} EProfile;
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
@@ -149,6 +154,12 @@ const char* const E_GL_ARB_fragment_shader_interlock = "GL_ARB_fragment_shade
|
|||||||
const char* const E_GL_ARB_shader_clock = "GL_ARB_shader_clock";
|
const char* const E_GL_ARB_shader_clock = "GL_ARB_shader_clock";
|
||||||
const char* const E_GL_ARB_uniform_buffer_object = "GL_ARB_uniform_buffer_object";
|
const char* const E_GL_ARB_uniform_buffer_object = "GL_ARB_uniform_buffer_object";
|
||||||
const char* const E_GL_ARB_sample_shading = "GL_ARB_sample_shading";
|
const char* const E_GL_ARB_sample_shading = "GL_ARB_sample_shading";
|
||||||
|
const char* const E_GL_ARB_shader_bit_encoding = "GL_ARB_shader_bit_encoding";
|
||||||
|
const char* const E_GL_ARB_shader_image_size = "GL_ARB_shader_image_size";
|
||||||
|
const char* const E_GL_ARB_shader_storage_buffer_object = "GL_ARB_shader_storage_buffer_object";
|
||||||
|
const char* const E_GL_ARB_shading_language_packing = "GL_ARB_shading_language_packing";
|
||||||
|
const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_lod";
|
||||||
|
const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit";
|
||||||
|
|
||||||
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
|
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";
|
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
||||||
@@ -183,6 +194,12 @@ const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_ref
|
|||||||
const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2";
|
const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2";
|
||||||
const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation";
|
const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation";
|
||||||
const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock";
|
const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock";
|
||||||
|
const char* const E_GL_EXT_debug_printf = "GL_EXT_debug_printf";
|
||||||
|
const char* const E_GL_EXT_ray_tracing = "GL_EXT_ray_tracing";
|
||||||
|
const char* const E_GL_EXT_ray_query = "GL_EXT_ray_query";
|
||||||
|
const char* const E_GL_EXT_ray_flags_primitive_culling = "GL_EXT_ray_flags_primitive_culling";
|
||||||
|
const char* const E_GL_EXT_blend_func_extended = "GL_EXT_blend_func_extended";
|
||||||
|
const char* const E_GL_EXT_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions";
|
||||||
|
|
||||||
// Arrays of extensions for the above viewportEXTs duplications
|
// Arrays of extensions for the above viewportEXTs duplications
|
||||||
|
|
||||||
@@ -254,6 +271,7 @@ const char* const E_GL_EXT_tessellation_shader = "GL_EXT_tessel
|
|||||||
const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessellation_point_size";
|
const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessellation_point_size";
|
||||||
const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer";
|
const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer";
|
||||||
const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array";
|
const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array";
|
||||||
|
const char* const E_GL_EXT_shader_integer_mix = "GL_EXT_shader_integer_mix";
|
||||||
|
|
||||||
// OES matching AEP
|
// OES matching AEP
|
||||||
const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader";
|
const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader";
|
||||||
@@ -281,6 +299,8 @@ const char* const E_GL_EXT_shader_subgroup_extended_types_int16 = "GL_EXT_shad
|
|||||||
const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64";
|
const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64";
|
||||||
const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16";
|
const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16";
|
||||||
|
|
||||||
|
const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float";
|
||||||
|
|
||||||
// Arrays of extensions for the above AEP duplications
|
// Arrays of extensions for the above AEP duplications
|
||||||
|
|
||||||
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
|
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
|
||||||
|
|||||||
@@ -52,6 +52,14 @@
|
|||||||
#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FE5
|
#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FE5
|
||||||
#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FE6
|
#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FE6
|
||||||
#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FE7
|
#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FE7
|
||||||
|
#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
|
||||||
|
#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
|
||||||
|
#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
|
||||||
|
|
||||||
|
#define GL_INT16_NV 0x8FE4
|
||||||
|
#define GL_INT16_VEC2_NV 0x8FE5
|
||||||
|
#define GL_INT16_VEC3_NV 0x8FE6
|
||||||
|
#define GL_INT16_VEC4_NV 0x8FE7
|
||||||
|
|
||||||
#define GL_BOOL 0x8B56
|
#define GL_BOOL 0x8B56
|
||||||
#define GL_BOOL_VEC2 0x8B57
|
#define GL_BOOL_VEC2 0x8B57
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -203,256 +203,265 @@ extern int yydebug;
|
|||||||
F64MAT4X4 = 413,
|
F64MAT4X4 = 413,
|
||||||
ATOMIC_UINT = 414,
|
ATOMIC_UINT = 414,
|
||||||
ACCSTRUCTNV = 415,
|
ACCSTRUCTNV = 415,
|
||||||
FCOOPMATNV = 416,
|
ACCSTRUCTEXT = 416,
|
||||||
ICOOPMATNV = 417,
|
RAYQUERYEXT = 417,
|
||||||
UCOOPMATNV = 418,
|
FCOOPMATNV = 418,
|
||||||
SAMPLERCUBEARRAY = 419,
|
ICOOPMATNV = 419,
|
||||||
SAMPLERCUBEARRAYSHADOW = 420,
|
UCOOPMATNV = 420,
|
||||||
ISAMPLERCUBEARRAY = 421,
|
SAMPLERCUBEARRAY = 421,
|
||||||
USAMPLERCUBEARRAY = 422,
|
SAMPLERCUBEARRAYSHADOW = 422,
|
||||||
SAMPLER1D = 423,
|
ISAMPLERCUBEARRAY = 423,
|
||||||
SAMPLER1DARRAY = 424,
|
USAMPLERCUBEARRAY = 424,
|
||||||
SAMPLER1DARRAYSHADOW = 425,
|
SAMPLER1D = 425,
|
||||||
ISAMPLER1D = 426,
|
SAMPLER1DARRAY = 426,
|
||||||
SAMPLER1DSHADOW = 427,
|
SAMPLER1DARRAYSHADOW = 427,
|
||||||
SAMPLER2DRECT = 428,
|
ISAMPLER1D = 428,
|
||||||
SAMPLER2DRECTSHADOW = 429,
|
SAMPLER1DSHADOW = 429,
|
||||||
ISAMPLER2DRECT = 430,
|
SAMPLER2DRECT = 430,
|
||||||
USAMPLER2DRECT = 431,
|
SAMPLER2DRECTSHADOW = 431,
|
||||||
SAMPLERBUFFER = 432,
|
ISAMPLER2DRECT = 432,
|
||||||
ISAMPLERBUFFER = 433,
|
USAMPLER2DRECT = 433,
|
||||||
USAMPLERBUFFER = 434,
|
SAMPLERBUFFER = 434,
|
||||||
SAMPLER2DMS = 435,
|
ISAMPLERBUFFER = 435,
|
||||||
ISAMPLER2DMS = 436,
|
USAMPLERBUFFER = 436,
|
||||||
USAMPLER2DMS = 437,
|
SAMPLER2DMS = 437,
|
||||||
SAMPLER2DMSARRAY = 438,
|
ISAMPLER2DMS = 438,
|
||||||
ISAMPLER2DMSARRAY = 439,
|
USAMPLER2DMS = 439,
|
||||||
USAMPLER2DMSARRAY = 440,
|
SAMPLER2DMSARRAY = 440,
|
||||||
SAMPLEREXTERNALOES = 441,
|
ISAMPLER2DMSARRAY = 441,
|
||||||
SAMPLEREXTERNAL2DY2YEXT = 442,
|
USAMPLER2DMSARRAY = 442,
|
||||||
ISAMPLER1DARRAY = 443,
|
SAMPLEREXTERNALOES = 443,
|
||||||
USAMPLER1D = 444,
|
SAMPLEREXTERNAL2DY2YEXT = 444,
|
||||||
USAMPLER1DARRAY = 445,
|
ISAMPLER1DARRAY = 445,
|
||||||
F16SAMPLER1D = 446,
|
USAMPLER1D = 446,
|
||||||
F16SAMPLER2D = 447,
|
USAMPLER1DARRAY = 447,
|
||||||
F16SAMPLER3D = 448,
|
F16SAMPLER1D = 448,
|
||||||
F16SAMPLER2DRECT = 449,
|
F16SAMPLER2D = 449,
|
||||||
F16SAMPLERCUBE = 450,
|
F16SAMPLER3D = 450,
|
||||||
F16SAMPLER1DARRAY = 451,
|
F16SAMPLER2DRECT = 451,
|
||||||
F16SAMPLER2DARRAY = 452,
|
F16SAMPLERCUBE = 452,
|
||||||
F16SAMPLERCUBEARRAY = 453,
|
F16SAMPLER1DARRAY = 453,
|
||||||
F16SAMPLERBUFFER = 454,
|
F16SAMPLER2DARRAY = 454,
|
||||||
F16SAMPLER2DMS = 455,
|
F16SAMPLERCUBEARRAY = 455,
|
||||||
F16SAMPLER2DMSARRAY = 456,
|
F16SAMPLERBUFFER = 456,
|
||||||
F16SAMPLER1DSHADOW = 457,
|
F16SAMPLER2DMS = 457,
|
||||||
F16SAMPLER2DSHADOW = 458,
|
F16SAMPLER2DMSARRAY = 458,
|
||||||
F16SAMPLER1DARRAYSHADOW = 459,
|
F16SAMPLER1DSHADOW = 459,
|
||||||
F16SAMPLER2DARRAYSHADOW = 460,
|
F16SAMPLER2DSHADOW = 460,
|
||||||
F16SAMPLER2DRECTSHADOW = 461,
|
F16SAMPLER1DARRAYSHADOW = 461,
|
||||||
F16SAMPLERCUBESHADOW = 462,
|
F16SAMPLER2DARRAYSHADOW = 462,
|
||||||
F16SAMPLERCUBEARRAYSHADOW = 463,
|
F16SAMPLER2DRECTSHADOW = 463,
|
||||||
IMAGE1D = 464,
|
F16SAMPLERCUBESHADOW = 464,
|
||||||
IIMAGE1D = 465,
|
F16SAMPLERCUBEARRAYSHADOW = 465,
|
||||||
UIMAGE1D = 466,
|
IMAGE1D = 466,
|
||||||
IMAGE2D = 467,
|
IIMAGE1D = 467,
|
||||||
IIMAGE2D = 468,
|
UIMAGE1D = 468,
|
||||||
UIMAGE2D = 469,
|
IMAGE2D = 469,
|
||||||
IMAGE3D = 470,
|
IIMAGE2D = 470,
|
||||||
IIMAGE3D = 471,
|
UIMAGE2D = 471,
|
||||||
UIMAGE3D = 472,
|
IMAGE3D = 472,
|
||||||
IMAGE2DRECT = 473,
|
IIMAGE3D = 473,
|
||||||
IIMAGE2DRECT = 474,
|
UIMAGE3D = 474,
|
||||||
UIMAGE2DRECT = 475,
|
IMAGE2DRECT = 475,
|
||||||
IMAGECUBE = 476,
|
IIMAGE2DRECT = 476,
|
||||||
IIMAGECUBE = 477,
|
UIMAGE2DRECT = 477,
|
||||||
UIMAGECUBE = 478,
|
IMAGECUBE = 478,
|
||||||
IMAGEBUFFER = 479,
|
IIMAGECUBE = 479,
|
||||||
IIMAGEBUFFER = 480,
|
UIMAGECUBE = 480,
|
||||||
UIMAGEBUFFER = 481,
|
IMAGEBUFFER = 481,
|
||||||
IMAGE1DARRAY = 482,
|
IIMAGEBUFFER = 482,
|
||||||
IIMAGE1DARRAY = 483,
|
UIMAGEBUFFER = 483,
|
||||||
UIMAGE1DARRAY = 484,
|
IMAGE1DARRAY = 484,
|
||||||
IMAGE2DARRAY = 485,
|
IIMAGE1DARRAY = 485,
|
||||||
IIMAGE2DARRAY = 486,
|
UIMAGE1DARRAY = 486,
|
||||||
UIMAGE2DARRAY = 487,
|
IMAGE2DARRAY = 487,
|
||||||
IMAGECUBEARRAY = 488,
|
IIMAGE2DARRAY = 488,
|
||||||
IIMAGECUBEARRAY = 489,
|
UIMAGE2DARRAY = 489,
|
||||||
UIMAGECUBEARRAY = 490,
|
IMAGECUBEARRAY = 490,
|
||||||
IMAGE2DMS = 491,
|
IIMAGECUBEARRAY = 491,
|
||||||
IIMAGE2DMS = 492,
|
UIMAGECUBEARRAY = 492,
|
||||||
UIMAGE2DMS = 493,
|
IMAGE2DMS = 493,
|
||||||
IMAGE2DMSARRAY = 494,
|
IIMAGE2DMS = 494,
|
||||||
IIMAGE2DMSARRAY = 495,
|
UIMAGE2DMS = 495,
|
||||||
UIMAGE2DMSARRAY = 496,
|
IMAGE2DMSARRAY = 496,
|
||||||
F16IMAGE1D = 497,
|
IIMAGE2DMSARRAY = 497,
|
||||||
F16IMAGE2D = 498,
|
UIMAGE2DMSARRAY = 498,
|
||||||
F16IMAGE3D = 499,
|
F16IMAGE1D = 499,
|
||||||
F16IMAGE2DRECT = 500,
|
F16IMAGE2D = 500,
|
||||||
F16IMAGECUBE = 501,
|
F16IMAGE3D = 501,
|
||||||
F16IMAGE1DARRAY = 502,
|
F16IMAGE2DRECT = 502,
|
||||||
F16IMAGE2DARRAY = 503,
|
F16IMAGECUBE = 503,
|
||||||
F16IMAGECUBEARRAY = 504,
|
F16IMAGE1DARRAY = 504,
|
||||||
F16IMAGEBUFFER = 505,
|
F16IMAGE2DARRAY = 505,
|
||||||
F16IMAGE2DMS = 506,
|
F16IMAGECUBEARRAY = 506,
|
||||||
F16IMAGE2DMSARRAY = 507,
|
F16IMAGEBUFFER = 507,
|
||||||
TEXTURECUBEARRAY = 508,
|
F16IMAGE2DMS = 508,
|
||||||
ITEXTURECUBEARRAY = 509,
|
F16IMAGE2DMSARRAY = 509,
|
||||||
UTEXTURECUBEARRAY = 510,
|
TEXTURECUBEARRAY = 510,
|
||||||
TEXTURE1D = 511,
|
ITEXTURECUBEARRAY = 511,
|
||||||
ITEXTURE1D = 512,
|
UTEXTURECUBEARRAY = 512,
|
||||||
UTEXTURE1D = 513,
|
TEXTURE1D = 513,
|
||||||
TEXTURE1DARRAY = 514,
|
ITEXTURE1D = 514,
|
||||||
ITEXTURE1DARRAY = 515,
|
UTEXTURE1D = 515,
|
||||||
UTEXTURE1DARRAY = 516,
|
TEXTURE1DARRAY = 516,
|
||||||
TEXTURE2DRECT = 517,
|
ITEXTURE1DARRAY = 517,
|
||||||
ITEXTURE2DRECT = 518,
|
UTEXTURE1DARRAY = 518,
|
||||||
UTEXTURE2DRECT = 519,
|
TEXTURE2DRECT = 519,
|
||||||
TEXTUREBUFFER = 520,
|
ITEXTURE2DRECT = 520,
|
||||||
ITEXTUREBUFFER = 521,
|
UTEXTURE2DRECT = 521,
|
||||||
UTEXTUREBUFFER = 522,
|
TEXTUREBUFFER = 522,
|
||||||
TEXTURE2DMS = 523,
|
ITEXTUREBUFFER = 523,
|
||||||
ITEXTURE2DMS = 524,
|
UTEXTUREBUFFER = 524,
|
||||||
UTEXTURE2DMS = 525,
|
TEXTURE2DMS = 525,
|
||||||
TEXTURE2DMSARRAY = 526,
|
ITEXTURE2DMS = 526,
|
||||||
ITEXTURE2DMSARRAY = 527,
|
UTEXTURE2DMS = 527,
|
||||||
UTEXTURE2DMSARRAY = 528,
|
TEXTURE2DMSARRAY = 528,
|
||||||
F16TEXTURE1D = 529,
|
ITEXTURE2DMSARRAY = 529,
|
||||||
F16TEXTURE2D = 530,
|
UTEXTURE2DMSARRAY = 530,
|
||||||
F16TEXTURE3D = 531,
|
F16TEXTURE1D = 531,
|
||||||
F16TEXTURE2DRECT = 532,
|
F16TEXTURE2D = 532,
|
||||||
F16TEXTURECUBE = 533,
|
F16TEXTURE3D = 533,
|
||||||
F16TEXTURE1DARRAY = 534,
|
F16TEXTURE2DRECT = 534,
|
||||||
F16TEXTURE2DARRAY = 535,
|
F16TEXTURECUBE = 535,
|
||||||
F16TEXTURECUBEARRAY = 536,
|
F16TEXTURE1DARRAY = 536,
|
||||||
F16TEXTUREBUFFER = 537,
|
F16TEXTURE2DARRAY = 537,
|
||||||
F16TEXTURE2DMS = 538,
|
F16TEXTURECUBEARRAY = 538,
|
||||||
F16TEXTURE2DMSARRAY = 539,
|
F16TEXTUREBUFFER = 539,
|
||||||
SUBPASSINPUT = 540,
|
F16TEXTURE2DMS = 540,
|
||||||
SUBPASSINPUTMS = 541,
|
F16TEXTURE2DMSARRAY = 541,
|
||||||
ISUBPASSINPUT = 542,
|
SUBPASSINPUT = 542,
|
||||||
ISUBPASSINPUTMS = 543,
|
SUBPASSINPUTMS = 543,
|
||||||
USUBPASSINPUT = 544,
|
ISUBPASSINPUT = 544,
|
||||||
USUBPASSINPUTMS = 545,
|
ISUBPASSINPUTMS = 545,
|
||||||
F16SUBPASSINPUT = 546,
|
USUBPASSINPUT = 546,
|
||||||
F16SUBPASSINPUTMS = 547,
|
USUBPASSINPUTMS = 547,
|
||||||
LEFT_OP = 548,
|
F16SUBPASSINPUT = 548,
|
||||||
RIGHT_OP = 549,
|
F16SUBPASSINPUTMS = 549,
|
||||||
INC_OP = 550,
|
LEFT_OP = 550,
|
||||||
DEC_OP = 551,
|
RIGHT_OP = 551,
|
||||||
LE_OP = 552,
|
INC_OP = 552,
|
||||||
GE_OP = 553,
|
DEC_OP = 553,
|
||||||
EQ_OP = 554,
|
LE_OP = 554,
|
||||||
NE_OP = 555,
|
GE_OP = 555,
|
||||||
AND_OP = 556,
|
EQ_OP = 556,
|
||||||
OR_OP = 557,
|
NE_OP = 557,
|
||||||
XOR_OP = 558,
|
AND_OP = 558,
|
||||||
MUL_ASSIGN = 559,
|
OR_OP = 559,
|
||||||
DIV_ASSIGN = 560,
|
XOR_OP = 560,
|
||||||
ADD_ASSIGN = 561,
|
MUL_ASSIGN = 561,
|
||||||
MOD_ASSIGN = 562,
|
DIV_ASSIGN = 562,
|
||||||
LEFT_ASSIGN = 563,
|
ADD_ASSIGN = 563,
|
||||||
RIGHT_ASSIGN = 564,
|
MOD_ASSIGN = 564,
|
||||||
AND_ASSIGN = 565,
|
LEFT_ASSIGN = 565,
|
||||||
XOR_ASSIGN = 566,
|
RIGHT_ASSIGN = 566,
|
||||||
OR_ASSIGN = 567,
|
AND_ASSIGN = 567,
|
||||||
SUB_ASSIGN = 568,
|
XOR_ASSIGN = 568,
|
||||||
LEFT_PAREN = 569,
|
OR_ASSIGN = 569,
|
||||||
RIGHT_PAREN = 570,
|
SUB_ASSIGN = 570,
|
||||||
LEFT_BRACKET = 571,
|
STRING_LITERAL = 571,
|
||||||
RIGHT_BRACKET = 572,
|
LEFT_PAREN = 572,
|
||||||
LEFT_BRACE = 573,
|
RIGHT_PAREN = 573,
|
||||||
RIGHT_BRACE = 574,
|
LEFT_BRACKET = 574,
|
||||||
DOT = 575,
|
RIGHT_BRACKET = 575,
|
||||||
COMMA = 576,
|
LEFT_BRACE = 576,
|
||||||
COLON = 577,
|
RIGHT_BRACE = 577,
|
||||||
EQUAL = 578,
|
DOT = 578,
|
||||||
SEMICOLON = 579,
|
COMMA = 579,
|
||||||
BANG = 580,
|
COLON = 580,
|
||||||
DASH = 581,
|
EQUAL = 581,
|
||||||
TILDE = 582,
|
SEMICOLON = 582,
|
||||||
PLUS = 583,
|
BANG = 583,
|
||||||
STAR = 584,
|
DASH = 584,
|
||||||
SLASH = 585,
|
TILDE = 585,
|
||||||
PERCENT = 586,
|
PLUS = 586,
|
||||||
LEFT_ANGLE = 587,
|
STAR = 587,
|
||||||
RIGHT_ANGLE = 588,
|
SLASH = 588,
|
||||||
VERTICAL_BAR = 589,
|
PERCENT = 589,
|
||||||
CARET = 590,
|
LEFT_ANGLE = 590,
|
||||||
AMPERSAND = 591,
|
RIGHT_ANGLE = 591,
|
||||||
QUESTION = 592,
|
VERTICAL_BAR = 592,
|
||||||
INVARIANT = 593,
|
CARET = 593,
|
||||||
HIGH_PRECISION = 594,
|
AMPERSAND = 594,
|
||||||
MEDIUM_PRECISION = 595,
|
QUESTION = 595,
|
||||||
LOW_PRECISION = 596,
|
INVARIANT = 596,
|
||||||
PRECISION = 597,
|
HIGH_PRECISION = 597,
|
||||||
PACKED = 598,
|
MEDIUM_PRECISION = 598,
|
||||||
RESOURCE = 599,
|
LOW_PRECISION = 599,
|
||||||
SUPERP = 600,
|
PRECISION = 600,
|
||||||
FLOATCONSTANT = 601,
|
PACKED = 601,
|
||||||
INTCONSTANT = 602,
|
RESOURCE = 602,
|
||||||
UINTCONSTANT = 603,
|
SUPERP = 603,
|
||||||
BOOLCONSTANT = 604,
|
FLOATCONSTANT = 604,
|
||||||
IDENTIFIER = 605,
|
INTCONSTANT = 605,
|
||||||
TYPE_NAME = 606,
|
UINTCONSTANT = 606,
|
||||||
CENTROID = 607,
|
BOOLCONSTANT = 607,
|
||||||
IN = 608,
|
IDENTIFIER = 608,
|
||||||
OUT = 609,
|
TYPE_NAME = 609,
|
||||||
INOUT = 610,
|
CENTROID = 610,
|
||||||
STRUCT = 611,
|
IN = 611,
|
||||||
VOID = 612,
|
OUT = 612,
|
||||||
WHILE = 613,
|
INOUT = 613,
|
||||||
BREAK = 614,
|
STRUCT = 614,
|
||||||
CONTINUE = 615,
|
VOID = 615,
|
||||||
DO = 616,
|
WHILE = 616,
|
||||||
ELSE = 617,
|
BREAK = 617,
|
||||||
FOR = 618,
|
CONTINUE = 618,
|
||||||
IF = 619,
|
DO = 619,
|
||||||
DISCARD = 620,
|
ELSE = 620,
|
||||||
RETURN = 621,
|
FOR = 621,
|
||||||
SWITCH = 622,
|
IF = 622,
|
||||||
CASE = 623,
|
DISCARD = 623,
|
||||||
DEFAULT = 624,
|
RETURN = 624,
|
||||||
UNIFORM = 625,
|
SWITCH = 625,
|
||||||
SHARED = 626,
|
CASE = 626,
|
||||||
BUFFER = 627,
|
DEFAULT = 627,
|
||||||
FLAT = 628,
|
UNIFORM = 628,
|
||||||
SMOOTH = 629,
|
SHARED = 629,
|
||||||
LAYOUT = 630,
|
BUFFER = 630,
|
||||||
DOUBLECONSTANT = 631,
|
FLAT = 631,
|
||||||
INT16CONSTANT = 632,
|
SMOOTH = 632,
|
||||||
UINT16CONSTANT = 633,
|
LAYOUT = 633,
|
||||||
FLOAT16CONSTANT = 634,
|
DOUBLECONSTANT = 634,
|
||||||
INT32CONSTANT = 635,
|
INT16CONSTANT = 635,
|
||||||
UINT32CONSTANT = 636,
|
UINT16CONSTANT = 636,
|
||||||
INT64CONSTANT = 637,
|
FLOAT16CONSTANT = 637,
|
||||||
UINT64CONSTANT = 638,
|
INT32CONSTANT = 638,
|
||||||
SUBROUTINE = 639,
|
UINT32CONSTANT = 639,
|
||||||
DEMOTE = 640,
|
INT64CONSTANT = 640,
|
||||||
PAYLOADNV = 641,
|
UINT64CONSTANT = 641,
|
||||||
PAYLOADINNV = 642,
|
SUBROUTINE = 642,
|
||||||
HITATTRNV = 643,
|
DEMOTE = 643,
|
||||||
CALLDATANV = 644,
|
PAYLOADNV = 644,
|
||||||
CALLDATAINNV = 645,
|
PAYLOADINNV = 645,
|
||||||
PATCH = 646,
|
HITATTRNV = 646,
|
||||||
SAMPLE = 647,
|
CALLDATANV = 647,
|
||||||
NONUNIFORM = 648,
|
CALLDATAINNV = 648,
|
||||||
COHERENT = 649,
|
PAYLOADEXT = 649,
|
||||||
VOLATILE = 650,
|
PAYLOADINEXT = 650,
|
||||||
RESTRICT = 651,
|
HITATTREXT = 651,
|
||||||
READONLY = 652,
|
CALLDATAEXT = 652,
|
||||||
WRITEONLY = 653,
|
CALLDATAINEXT = 653,
|
||||||
DEVICECOHERENT = 654,
|
PATCH = 654,
|
||||||
QUEUEFAMILYCOHERENT = 655,
|
SAMPLE = 655,
|
||||||
WORKGROUPCOHERENT = 656,
|
NONUNIFORM = 656,
|
||||||
SUBGROUPCOHERENT = 657,
|
COHERENT = 657,
|
||||||
NONPRIVATE = 658,
|
VOLATILE = 658,
|
||||||
NOPERSPECTIVE = 659,
|
RESTRICT = 659,
|
||||||
EXPLICITINTERPAMD = 660,
|
READONLY = 660,
|
||||||
PERVERTEXNV = 661,
|
WRITEONLY = 661,
|
||||||
PERPRIMITIVENV = 662,
|
DEVICECOHERENT = 662,
|
||||||
PERVIEWNV = 663,
|
QUEUEFAMILYCOHERENT = 663,
|
||||||
PERTASKNV = 664,
|
WORKGROUPCOHERENT = 664,
|
||||||
PRECISE = 665
|
SUBGROUPCOHERENT = 665,
|
||||||
|
NONPRIVATE = 666,
|
||||||
|
SHADERCALLCOHERENT = 667,
|
||||||
|
NOPERSPECTIVE = 668,
|
||||||
|
EXPLICITINTERPAMD = 669,
|
||||||
|
PERVERTEXNV = 670,
|
||||||
|
PERPRIMITIVENV = 671,
|
||||||
|
PERVIEWNV = 672,
|
||||||
|
PERTASKNV = 673,
|
||||||
|
PRECISE = 674
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -461,7 +470,7 @@ extern int yydebug;
|
|||||||
|
|
||||||
union YYSTYPE
|
union YYSTYPE
|
||||||
{
|
{
|
||||||
#line 96 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
#line 97 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
glslang::TSourceLoc loc;
|
glslang::TSourceLoc loc;
|
||||||
@@ -497,7 +506,7 @@ union YYSTYPE
|
|||||||
glslang::TArraySizes* typeParameters;
|
glslang::TArraySizes* typeParameters;
|
||||||
} interm;
|
} interm;
|
||||||
|
|
||||||
#line 501 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
#line 510 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union YYSTYPE YYSTYPE;
|
typedef union YYSTYPE YYSTYPE;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
// Copyright (C) 2012-2016 LunarG, Inc.
|
// Copyright (C) 2012-2016 LunarG, Inc.
|
||||||
// Copyright (C) 2017 ARM Limited.
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -35,7 +36,7 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
#include "localintermediate.h"
|
#include "localintermediate.h"
|
||||||
#include "../Include/InfoSink.h"
|
#include "../Include/InfoSink.h"
|
||||||
@@ -1078,18 +1079,43 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
||||||
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||||
|
|
||||||
case EOpTraceNV: out.debug << "traceNV"; break;
|
case EOpTrace: out.debug << "traceNV"; break;
|
||||||
case EOpReportIntersectionNV: out.debug << "reportIntersectionNV"; break;
|
case EOpReportIntersection: out.debug << "reportIntersectionNV"; break;
|
||||||
case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break;
|
case EOpIgnoreIntersection: out.debug << "ignoreIntersectionNV"; break;
|
||||||
case EOpTerminateRayNV: out.debug << "terminateRayNV"; break;
|
case EOpTerminateRay: out.debug << "terminateRayNV"; break;
|
||||||
case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break;
|
case EOpExecuteCallable: out.debug << "executeCallableNV"; break;
|
||||||
case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break;
|
case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break;
|
||||||
|
|
||||||
|
case EOpRayQueryInitialize: out.debug << "rayQueryInitializeEXT"; break;
|
||||||
|
case EOpRayQueryTerminate: out.debug << "rayQueryTerminateEXT"; break;
|
||||||
|
case EOpRayQueryGenerateIntersection: out.debug << "rayQueryGenerateIntersectionEXT"; break;
|
||||||
|
case EOpRayQueryConfirmIntersection: out.debug << "rayQueryConfirmIntersectionEXT"; break;
|
||||||
|
case EOpRayQueryProceed: out.debug << "rayQueryProceedEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionType: out.debug << "rayQueryGetIntersectionTypeEXT"; break;
|
||||||
|
case EOpRayQueryGetRayTMin: out.debug << "rayQueryGetRayTMinEXT"; break;
|
||||||
|
case EOpRayQueryGetRayFlags: out.debug << "rayQueryGetRayFlagsEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionT: out.debug << "rayQueryGetIntersectionTEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionInstanceCustomIndex: out.debug << "rayQueryGetIntersectionInstanceCustomIndexEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionInstanceId: out.debug << "rayQueryGetIntersectionInstanceIdEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: out.debug << "rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionGeometryIndex: out.debug << "rayQueryGetIntersectionGeometryIndexEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionPrimitiveIndex: out.debug << "rayQueryGetIntersectionPrimitiveIndexEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionBarycentrics: out.debug << "rayQueryGetIntersectionBarycentricsEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionFrontFace: out.debug << "rayQueryGetIntersectionFrontFaceEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionCandidateAABBOpaque: out.debug << "rayQueryGetIntersectionCandidateAABBOpaqueEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionObjectRayDirection: out.debug << "rayQueryGetIntersectionObjectRayDirectionEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionObjectRayOrigin: out.debug << "rayQueryGetIntersectionObjectRayOriginEXT"; break;
|
||||||
|
case EOpRayQueryGetWorldRayDirection: out.debug << "rayQueryGetWorldRayDirectionEXT"; break;
|
||||||
|
case EOpRayQueryGetWorldRayOrigin: out.debug << "rayQueryGetWorldRayOriginEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionObjectToWorld: out.debug << "rayQueryGetIntersectionObjectToWorldEXT"; break;
|
||||||
|
case EOpRayQueryGetIntersectionWorldToObject: out.debug << "rayQueryGetIntersectionWorldToObjectEXT"; break;
|
||||||
|
|
||||||
case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix"; break;
|
case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix"; break;
|
||||||
case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break;
|
case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break;
|
||||||
case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break;
|
case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break;
|
||||||
|
|
||||||
case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break;
|
case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break;
|
||||||
|
case EOpDebugPrintf: out.debug << "Debug printf"; break;
|
||||||
|
|
||||||
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
||||||
}
|
}
|
||||||
@@ -1536,4 +1562,4 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
|||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // not GLSLANG_WEB
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
#include "../Include/Common.h"
|
#include "../Include/Common.h"
|
||||||
#include "../Include/InfoSink.h"
|
#include "../Include/InfoSink.h"
|
||||||
@@ -79,6 +79,11 @@ public:
|
|||||||
target = &outputList;
|
target = &outputList;
|
||||||
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
|
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
|
||||||
target = &uniformList;
|
target = &uniformList;
|
||||||
|
// If a global is being visited, then we should also traverse it incase it's evaluation
|
||||||
|
// ends up visiting inputs we want to tag as live
|
||||||
|
else if (base->getQualifier().storage == EvqGlobal)
|
||||||
|
addGlobalReference(base->getName());
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
TVarEntryInfo ent = {base->getId(), base, ! traverseAll};
|
TVarEntryInfo ent = {base->getId(), base, ! traverseAll};
|
||||||
ent.stage = intermediate.getStage();
|
ent.stage = intermediate.getStage();
|
||||||
@@ -161,7 +166,7 @@ struct TNotifyUniformAdaptor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&);
|
TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TNotifyInOutAdaptor
|
struct TNotifyInOutAdaptor
|
||||||
@@ -180,7 +185,7 @@ struct TNotifyInOutAdaptor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&);
|
TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TResolverUniformAdaptor {
|
struct TResolverUniformAdaptor {
|
||||||
@@ -236,7 +241,7 @@ struct TResolverUniformAdaptor {
|
|||||||
bool& error;
|
bool& error;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&);
|
TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TResolverInOutAdaptor {
|
struct TResolverInOutAdaptor {
|
||||||
@@ -283,7 +288,7 @@ struct TResolverInOutAdaptor {
|
|||||||
bool& error;
|
bool& error;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&);
|
TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The class is used for reserving explicit uniform locations and ubo/ssbo/opaque bindings
|
// The class is used for reserving explicit uniform locations and ubo/ssbo/opaque bindings
|
||||||
@@ -309,26 +314,43 @@ struct TSymbolValidater
|
|||||||
TIntermSymbol* base = ent1.symbol;
|
TIntermSymbol* base = ent1.symbol;
|
||||||
const TType& type = ent1.symbol->getType();
|
const TType& type = ent1.symbol->getType();
|
||||||
const TString& name = entKey.first;
|
const TString& name = entKey.first;
|
||||||
TString mangleName1, mangleName2;
|
|
||||||
type.appendMangledName(mangleName1);
|
|
||||||
EShLanguage stage = ent1.stage;
|
EShLanguage stage = ent1.stage;
|
||||||
|
TString mangleName1, mangleName2;
|
||||||
if (currentStage != stage) {
|
if (currentStage != stage) {
|
||||||
preStage = currentStage;
|
preStage = currentStage;
|
||||||
currentStage = stage;
|
currentStage = stage;
|
||||||
nextStage = EShLangCount;
|
nextStage = EShLangCount;
|
||||||
for (int i = currentStage + 1; i < EShLangCount; i++) {
|
for (int i = currentStage + 1; i < EShLangCount; i++) {
|
||||||
if (inVarMaps[i] != nullptr)
|
if (inVarMaps[i] != nullptr) {
|
||||||
nextStage = static_cast<EShLanguage>(i);
|
nextStage = static_cast<EShLanguage>(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type.getQualifier().isArrayedIo(stage)) {
|
||||||
|
TType subType(type, 0);
|
||||||
|
subType.appendMangledName(mangleName1);
|
||||||
|
} else {
|
||||||
|
type.appendMangledName(mangleName1);
|
||||||
|
}
|
||||||
|
|
||||||
if (base->getQualifier().storage == EvqVaryingIn) {
|
if (base->getQualifier().storage == EvqVaryingIn) {
|
||||||
// validate stage in;
|
// validate stage in;
|
||||||
if (preStage == EShLangCount)
|
if (preStage == EShLangCount)
|
||||||
return;
|
return;
|
||||||
|
if (name == "gl_PerVertex")
|
||||||
|
return;
|
||||||
if (outVarMaps[preStage] != nullptr) {
|
if (outVarMaps[preStage] != nullptr) {
|
||||||
auto ent2 = outVarMaps[preStage]->find(name);
|
auto ent2 = outVarMaps[preStage]->find(name);
|
||||||
if (ent2 != outVarMaps[preStage]->end()) {
|
if (ent2 != outVarMaps[preStage]->end()) {
|
||||||
ent2->second.symbol->getType().appendMangledName(mangleName2);
|
if (ent2->second.symbol->getType().getQualifier().isArrayedIo(preStage)) {
|
||||||
|
TType subType(ent2->second.symbol->getType(), 0);
|
||||||
|
subType.appendMangledName(mangleName2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ent2->second.symbol->getType().appendMangledName(mangleName2);
|
||||||
|
}
|
||||||
if (mangleName1 == mangleName2)
|
if (mangleName1 == mangleName2)
|
||||||
return;
|
return;
|
||||||
else {
|
else {
|
||||||
@@ -343,10 +365,18 @@ struct TSymbolValidater
|
|||||||
// validate stage out;
|
// validate stage out;
|
||||||
if (nextStage == EShLangCount)
|
if (nextStage == EShLangCount)
|
||||||
return;
|
return;
|
||||||
|
if (name == "gl_PerVertex")
|
||||||
|
return;
|
||||||
if (outVarMaps[nextStage] != nullptr) {
|
if (outVarMaps[nextStage] != nullptr) {
|
||||||
auto ent2 = inVarMaps[nextStage]->find(name);
|
auto ent2 = inVarMaps[nextStage]->find(name);
|
||||||
if (ent2 != inVarMaps[nextStage]->end()) {
|
if (ent2 != inVarMaps[nextStage]->end()) {
|
||||||
ent2->second.symbol->getType().appendMangledName(mangleName2);
|
if (ent2->second.symbol->getType().getQualifier().isArrayedIo(nextStage)) {
|
||||||
|
TType subType(ent2->second.symbol->getType(), 0);
|
||||||
|
subType.appendMangledName(mangleName2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ent2->second.symbol->getType().appendMangledName(mangleName2);
|
||||||
|
}
|
||||||
if (mangleName1 == mangleName2)
|
if (mangleName1 == mangleName2)
|
||||||
return;
|
return;
|
||||||
else {
|
else {
|
||||||
@@ -384,7 +414,7 @@ struct TSymbolValidater
|
|||||||
bool& hadError;
|
bool& hadError;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TSymbolValidater& operator=(TSymbolValidater&);
|
TSymbolValidater& operator=(TSymbolValidater&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TSlotCollector {
|
struct TSlotCollector {
|
||||||
@@ -398,7 +428,7 @@ struct TSlotCollector {
|
|||||||
TInfoSink& infoSink;
|
TInfoSink& infoSink;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TSlotCollector& operator=(TSlotCollector&);
|
TSlotCollector& operator=(TSlotCollector&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate)
|
TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate)
|
||||||
@@ -579,7 +609,7 @@ TDefaultGlslIoResolver::TDefaultGlslIoResolver(const TIntermediate& intermediate
|
|||||||
|
|
||||||
int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) {
|
int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) {
|
||||||
const TType& type = ent.symbol->getType();
|
const TType& type = ent.symbol->getType();
|
||||||
const TString& name = ent.symbol->getName();
|
const TString& name = getAccessName(ent.symbol);
|
||||||
if (currentStage != stage) {
|
if (currentStage != stage) {
|
||||||
preStage = currentStage;
|
preStage = currentStage;
|
||||||
currentStage = stage;
|
currentStage = stage;
|
||||||
@@ -627,7 +657,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
|
|||||||
TVarSlotMap::iterator iter = storageSlotMap[resourceKey].find(name);
|
TVarSlotMap::iterator iter = storageSlotMap[resourceKey].find(name);
|
||||||
if (iter != storageSlotMap[resourceKey].end()) {
|
if (iter != storageSlotMap[resourceKey].end()) {
|
||||||
// If interface resource be found, set it has location and this symbol's new location
|
// If interface resource be found, set it has location and this symbol's new location
|
||||||
// equal the symbol's explicit location declarated in pre or next stage.
|
// equal the symbol's explicit location declaration in pre or next stage.
|
||||||
//
|
//
|
||||||
// vs: out vec4 a;
|
// vs: out vec4 a;
|
||||||
// fs: layout(..., location = 3,...) in vec4 a;
|
// fs: layout(..., location = 3,...) in vec4 a;
|
||||||
@@ -663,7 +693,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
|
|||||||
|
|
||||||
int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) {
|
int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) {
|
||||||
const TType& type = ent.symbol->getType();
|
const TType& type = ent.symbol->getType();
|
||||||
const TString& name = ent.symbol->getName();
|
const TString& name = getAccessName(ent.symbol);
|
||||||
// kick out of not doing this
|
// kick out of not doing this
|
||||||
if (! doAutoLocationMapping()) {
|
if (! doAutoLocationMapping()) {
|
||||||
return ent.newLocation = -1;
|
return ent.newLocation = -1;
|
||||||
@@ -706,7 +736,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
|||||||
TVarSlotMap::iterator iter = slotMap.find(name);
|
TVarSlotMap::iterator iter = slotMap.find(name);
|
||||||
if (iter != slotMap.end()) {
|
if (iter != slotMap.end()) {
|
||||||
// If uniform resource be found, set it has location and this symbol's new location
|
// If uniform resource be found, set it has location and this symbol's new location
|
||||||
// equal the uniform's explicit location declarated in other stage.
|
// equal the uniform's explicit location declaration in other stage.
|
||||||
//
|
//
|
||||||
// vs: uniform vec4 a;
|
// vs: uniform vec4 a;
|
||||||
// fs: layout(..., location = 3,...) uniform vec4 a;
|
// fs: layout(..., location = 3,...) uniform vec4 a;
|
||||||
@@ -714,7 +744,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
|||||||
location = iter->second;
|
location = iter->second;
|
||||||
}
|
}
|
||||||
if (! hasLocation) {
|
if (! hasLocation) {
|
||||||
// No explicit location declaraten in other stage.
|
// No explicit location declaration in other stage.
|
||||||
// So we should find a new slot for this uniform.
|
// So we should find a new slot for this uniform.
|
||||||
//
|
//
|
||||||
// vs: uniform vec4 a;
|
// vs: uniform vec4 a;
|
||||||
@@ -723,7 +753,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
|||||||
storageSlotMap[resourceKey][name] = location;
|
storageSlotMap[resourceKey][name] = location;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// the first uniform declarated in a program.
|
// the first uniform declaration in a program.
|
||||||
TVarSlotMap varSlotMap;
|
TVarSlotMap varSlotMap;
|
||||||
location = getFreeSlot(resourceKey, 0, size);
|
location = getFreeSlot(resourceKey, 0, size);
|
||||||
varSlotMap[name] = location;
|
varSlotMap[name] = location;
|
||||||
@@ -734,8 +764,8 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
|||||||
|
|
||||||
int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) {
|
int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) {
|
||||||
const TType& type = ent.symbol->getType();
|
const TType& type = ent.symbol->getType();
|
||||||
const TString& name = ent.symbol->getName();
|
const TString& name = getAccessName(ent.symbol);
|
||||||
// On OpenGL arrays of opaque types take a seperate binding for each element
|
// On OpenGL arrays of opaque types take a separate binding for each element
|
||||||
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
|
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
|
||||||
TResourceType resource = getResourceType(type);
|
TResourceType resource = getResourceType(type);
|
||||||
// don't need to handle uniform symbol, it will be handled in resolveUniformLocation
|
// don't need to handle uniform symbol, it will be handled in resolveUniformLocation
|
||||||
@@ -809,7 +839,7 @@ void TDefaultGlslIoResolver::endCollect(EShLanguage /*stage*/) {
|
|||||||
|
|
||||||
void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
|
void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
|
||||||
const TType& type = ent.symbol->getType();
|
const TType& type = ent.symbol->getType();
|
||||||
const TString& name = ent.symbol->getName();
|
const TString& name = getAccessName(ent.symbol);
|
||||||
TStorageQualifier storage = type.getQualifier().storage;
|
TStorageQualifier storage = type.getQualifier().storage;
|
||||||
EShLanguage stage(EShLangCount);
|
EShLanguage stage(EShLangCount);
|
||||||
switch (storage) {
|
switch (storage) {
|
||||||
@@ -831,6 +861,7 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink&
|
|||||||
if (iter->second != location) {
|
if (iter->second != location) {
|
||||||
TString errorMsg = "Invalid location: " + name;
|
TString errorMsg = "Invalid location: " + name;
|
||||||
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
||||||
|
hasError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -856,6 +887,7 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink&
|
|||||||
if (iter->second != location) {
|
if (iter->second != location) {
|
||||||
TString errorMsg = "Invalid location: " + name;
|
TString errorMsg = "Invalid location: " + name;
|
||||||
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
||||||
|
hasError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -867,7 +899,7 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink&
|
|||||||
|
|
||||||
void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
|
void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
|
||||||
const TType& type = ent.symbol->getType();
|
const TType& type = ent.symbol->getType();
|
||||||
const TString& name = ent.symbol->getName();
|
const TString& name = getAccessName(ent.symbol);
|
||||||
int resource = getResourceType(type);
|
int resource = getResourceType(type);
|
||||||
if (type.getQualifier().hasBinding()) {
|
if (type.getQualifier().hasBinding()) {
|
||||||
TVarSlotMap& varSlotMap = resourceSlotMap[resource];
|
TVarSlotMap& varSlotMap = resourceSlotMap[resource];
|
||||||
@@ -884,11 +916,19 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
|
|||||||
if (iter->second != binding) {
|
if (iter->second != binding) {
|
||||||
TString errorMsg = "Invalid binding: " + name;
|
TString errorMsg = "Invalid binding: " + name;
|
||||||
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
||||||
|
hasError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TString& TDefaultGlslIoResolver::getAccessName(const TIntermSymbol* symbol)
|
||||||
|
{
|
||||||
|
return symbol->getBasicType() == EbtBlock ?
|
||||||
|
symbol->getType().getTypeName() :
|
||||||
|
symbol->getName();
|
||||||
|
}
|
||||||
|
|
||||||
//TDefaultGlslIoResolver end
|
//TDefaultGlslIoResolver end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1070,11 +1110,12 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
|
|||||||
TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
|
TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
|
||||||
root->traverse(&iter_binding_all);
|
root->traverse(&iter_binding_all);
|
||||||
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
||||||
while (! iter_binding_live.functions.empty()) {
|
while (! iter_binding_live.destinations.empty()) {
|
||||||
TIntermNode* function = iter_binding_live.functions.back();
|
TIntermNode* destination = iter_binding_live.destinations.back();
|
||||||
iter_binding_live.functions.pop_back();
|
iter_binding_live.destinations.pop_back();
|
||||||
function->traverse(&iter_binding_live);
|
destination->traverse(&iter_binding_live);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
|
// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
|
||||||
std::for_each(inVarMap.begin(), inVarMap.end(),
|
std::for_each(inVarMap.begin(), inVarMap.end(),
|
||||||
[&inVector](TVarLivePair p) { inVector.push_back(p); });
|
[&inVector](TVarLivePair p) { inVector.push_back(p); });
|
||||||
@@ -1158,18 +1199,19 @@ bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TIn
|
|||||||
resolver = &defaultResolver;
|
resolver = &defaultResolver;
|
||||||
}
|
}
|
||||||
resolver->addStage(stage);
|
resolver->addStage(stage);
|
||||||
inVarMaps[stage] = new TVarLiveMap, outVarMaps[stage] = new TVarLiveMap(), uniformVarMap[stage] = new TVarLiveMap();
|
inVarMaps[stage] = new TVarLiveMap(); outVarMaps[stage] = new TVarLiveMap(); uniformVarMap[stage] = new TVarLiveMap();
|
||||||
TVarGatherTraverser iter_binding_all(intermediate, true, *inVarMaps[stage], *outVarMaps[stage],
|
TVarGatherTraverser iter_binding_all(intermediate, true, *inVarMaps[stage], *outVarMaps[stage],
|
||||||
*uniformVarMap[stage]);
|
*uniformVarMap[stage]);
|
||||||
TVarGatherTraverser iter_binding_live(intermediate, false, *inVarMaps[stage], *outVarMaps[stage],
|
TVarGatherTraverser iter_binding_live(intermediate, false, *inVarMaps[stage], *outVarMaps[stage],
|
||||||
*uniformVarMap[stage]);
|
*uniformVarMap[stage]);
|
||||||
root->traverse(&iter_binding_all);
|
root->traverse(&iter_binding_all);
|
||||||
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
||||||
while (! iter_binding_live.functions.empty()) {
|
while (! iter_binding_live.destinations.empty()) {
|
||||||
TIntermNode* function = iter_binding_live.functions.back();
|
TIntermNode* destination = iter_binding_live.destinations.back();
|
||||||
iter_binding_live.functions.pop_back();
|
iter_binding_live.destinations.pop_back();
|
||||||
function->traverse(&iter_binding_live);
|
destination->traverse(&iter_binding_live);
|
||||||
}
|
}
|
||||||
|
|
||||||
TNotifyInOutAdaptor inOutNotify(stage, *resolver);
|
TNotifyInOutAdaptor inOutNotify(stage, *resolver);
|
||||||
TNotifyUniformAdaptor uniformNotify(stage, *resolver);
|
TNotifyUniformAdaptor uniformNotify(stage, *resolver);
|
||||||
// Resolve current stage input symbol location with previous stage output here,
|
// Resolve current stage input symbol location with previous stage output here,
|
||||||
@@ -1246,4 +1288,4 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
|
|||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // GLSLANG_WEB
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
#ifndef _IOMAPPER_INCLUDED
|
#ifndef _IOMAPPER_INCLUDED
|
||||||
#define _IOMAPPER_INCLUDED
|
#define _IOMAPPER_INCLUDED
|
||||||
@@ -129,6 +129,7 @@ public:
|
|||||||
uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage);
|
uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage);
|
||||||
|
|
||||||
TSlotSetMap slots;
|
TSlotSetMap slots;
|
||||||
|
bool hasError = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TDefaultIoResolverBase(TDefaultIoResolverBase&);
|
TDefaultIoResolverBase(TDefaultIoResolverBase&);
|
||||||
@@ -185,7 +186,7 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Defaulf I/O resolver for OpenGL
|
// Default I/O resolver for OpenGL
|
||||||
struct TDefaultGlslIoResolver : public TDefaultIoResolverBase {
|
struct TDefaultGlslIoResolver : public TDefaultIoResolverBase {
|
||||||
public:
|
public:
|
||||||
typedef std::map<TString, int> TVarSlotMap; // <resourceName, location/binding>
|
typedef std::map<TString, int> TVarSlotMap; // <resourceName, location/binding>
|
||||||
@@ -202,6 +203,7 @@ public:
|
|||||||
void endCollect(EShLanguage) override;
|
void endCollect(EShLanguage) override;
|
||||||
void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
|
void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
|
||||||
void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
|
void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
|
||||||
|
const TString& getAccessName(const TIntermSymbol*);
|
||||||
// in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol.
|
// in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol.
|
||||||
// We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage.
|
// We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage.
|
||||||
// if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key.
|
// if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key.
|
||||||
@@ -237,12 +239,13 @@ typedef std::map<TString, TVarEntryInfo> TVarLiveMap;
|
|||||||
// In the future, if the vc++ compiler can handle such a situation,
|
// In the future, if the vc++ compiler can handle such a situation,
|
||||||
// this part of the code will be removed.
|
// this part of the code will be removed.
|
||||||
struct TVarLivePair : std::pair<const TString, TVarEntryInfo> {
|
struct TVarLivePair : std::pair<const TString, TVarEntryInfo> {
|
||||||
TVarLivePair(std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {}
|
TVarLivePair(const std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {}
|
||||||
TVarLivePair& operator=(const TVarLivePair& _Right) {
|
TVarLivePair& operator=(const TVarLivePair& _Right) {
|
||||||
const_cast<TString&>(first) = _Right.first;
|
const_cast<TString&>(first) = _Right.first;
|
||||||
second = _Right.second;
|
second = _Right.second;
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
TVarLivePair(const TVarLivePair& src) : pair(src) { }
|
||||||
};
|
};
|
||||||
typedef std::vector<TVarLivePair> TVarLiveVector;
|
typedef std::vector<TVarLivePair> TVarLiveVector;
|
||||||
|
|
||||||
@@ -260,10 +263,10 @@ public:
|
|||||||
class TGlslIoMapper : public TIoMapper {
|
class TGlslIoMapper : public TIoMapper {
|
||||||
public:
|
public:
|
||||||
TGlslIoMapper() {
|
TGlslIoMapper() {
|
||||||
memset(inVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
|
memset(inVarMaps, 0, sizeof(TVarLiveMap*) * EShLangCount);
|
||||||
memset(outVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
|
memset(outVarMaps, 0, sizeof(TVarLiveMap*) * EShLangCount);
|
||||||
memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
|
memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * EShLangCount);
|
||||||
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
|
memset(intermediates, 0, sizeof(TIntermediate*) * EShLangCount);
|
||||||
}
|
}
|
||||||
virtual ~TGlslIoMapper() {
|
virtual ~TGlslIoMapper() {
|
||||||
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||||
@@ -296,4 +299,4 @@ public:
|
|||||||
|
|
||||||
#endif // _IOMAPPER_INCLUDED
|
#endif // _IOMAPPER_INCLUDED
|
||||||
|
|
||||||
#endif // GLSLANG_WEB
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ void TIntermediate::warn(TInfoSink& infoSink, const char* message)
|
|||||||
//
|
//
|
||||||
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
{
|
{
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
mergeCallGraphs(infoSink, unit);
|
mergeCallGraphs(infoSink, unit);
|
||||||
mergeModes(infoSink, unit);
|
mergeModes(infoSink, unit);
|
||||||
mergeTrees(infoSink, unit);
|
mergeTrees(infoSink, unit);
|
||||||
@@ -104,7 +104,7 @@ void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
|
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
#define MERGE_MAX(member) member = std::max(member, unit.member)
|
#define MERGE_MAX(member) member = std::max(member, unit.member)
|
||||||
#define MERGE_TRUE(member) if (unit.member) member = unit.member;
|
#define MERGE_TRUE(member) if (unit.member) member = unit.member;
|
||||||
@@ -138,7 +138,11 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
MERGE_MAX(spvVersion.openGl);
|
MERGE_MAX(spvVersion.openGl);
|
||||||
|
|
||||||
numErrors += unit.getNumErrors();
|
numErrors += unit.getNumErrors();
|
||||||
numPushConstants += unit.numPushConstants;
|
// Only one push_constant is allowed, mergeLinkerObjects() will ensure the push_constant
|
||||||
|
// is the same for all units.
|
||||||
|
if (numPushConstants > 1 || unit.numPushConstants > 1)
|
||||||
|
error(infoSink, "Only one push_constant block is allowed per stage");
|
||||||
|
numPushConstants = std::min(numPushConstants + unit.numPushConstants, 1);
|
||||||
|
|
||||||
if (unit.invocations != TQualifier::layoutNotSet) {
|
if (unit.invocations != TQualifier::layoutNotSet) {
|
||||||
if (invocations == TQualifier::layoutNotSet)
|
if (invocations == TQualifier::layoutNotSet)
|
||||||
@@ -149,7 +153,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
|
|
||||||
if (vertices == TQualifier::layoutNotSet)
|
if (vertices == TQualifier::layoutNotSet)
|
||||||
vertices = unit.vertices;
|
vertices = unit.vertices;
|
||||||
else if (vertices != unit.vertices) {
|
else if (unit.vertices != TQualifier::layoutNotSet && vertices != unit.vertices) {
|
||||||
if (language == EShLangGeometry || language == EShLangMeshNV)
|
if (language == EShLangGeometry || language == EShLangMeshNV)
|
||||||
error(infoSink, "Contradictory layout max_vertices values");
|
error(infoSink, "Contradictory layout max_vertices values");
|
||||||
else if (language == EShLangTessControl)
|
else if (language == EShLangTessControl)
|
||||||
@@ -168,12 +172,12 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
|
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
inputPrimitive = unit.inputPrimitive;
|
inputPrimitive = unit.inputPrimitive;
|
||||||
else if (inputPrimitive != unit.inputPrimitive)
|
else if (unit.inputPrimitive != ElgNone && inputPrimitive != unit.inputPrimitive)
|
||||||
error(infoSink, "Contradictory input layout primitives");
|
error(infoSink, "Contradictory input layout primitives");
|
||||||
|
|
||||||
if (outputPrimitive == ElgNone)
|
if (outputPrimitive == ElgNone)
|
||||||
outputPrimitive = unit.outputPrimitive;
|
outputPrimitive = unit.outputPrimitive;
|
||||||
else if (outputPrimitive != unit.outputPrimitive)
|
else if (unit.outputPrimitive != ElgNone && outputPrimitive != unit.outputPrimitive)
|
||||||
error(infoSink, "Contradictory output layout primitives");
|
error(infoSink, "Contradictory output layout primitives");
|
||||||
|
|
||||||
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
|
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
|
||||||
@@ -286,7 +290,7 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getting this far means we have two existing trees to merge...
|
// Getting this far means we have two existing trees to merge...
|
||||||
numShaderRecordNVBlocks += unit.numShaderRecordNVBlocks;
|
numShaderRecordBlocks += unit.numShaderRecordBlocks;
|
||||||
numTaskNVBlocks += unit.numTaskNVBlocks;
|
numTaskNVBlocks += unit.numTaskNVBlocks;
|
||||||
|
|
||||||
// Get the top-level globals of each unit
|
// Get the top-level globals of each unit
|
||||||
@@ -299,10 +303,10 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
|
|
||||||
// Map by global name to unique ID to rationalize the same object having
|
// Map by global name to unique ID to rationalize the same object having
|
||||||
// differing IDs in different trees.
|
// differing IDs in different trees.
|
||||||
TMap<TString, int> idMap;
|
TIdMaps idMaps;
|
||||||
int maxId;
|
int maxId;
|
||||||
seedIdMap(idMap, maxId);
|
seedIdMap(idMaps, maxId);
|
||||||
remapIds(idMap, maxId + 1, unit);
|
remapIds(idMaps, maxId + 1, unit);
|
||||||
|
|
||||||
mergeBodies(infoSink, globals, unitGlobals);
|
mergeBodies(infoSink, globals, unitGlobals);
|
||||||
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
|
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
|
||||||
@@ -311,27 +315,40 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const TString& getNameForIdMap(TIntermSymbol* symbol)
|
||||||
|
{
|
||||||
|
TShaderInterface si = symbol->getType().getShaderInterface();
|
||||||
|
if (si == EsiNone)
|
||||||
|
return symbol->getName();
|
||||||
|
else
|
||||||
|
return symbol->getType().getTypeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Traverser that seeds an ID map with all built-ins, and tracks the
|
// Traverser that seeds an ID map with all built-ins, and tracks the
|
||||||
// maximum ID used.
|
// maximum ID used.
|
||||||
// (It would be nice to put this in a function, but that causes warnings
|
// (It would be nice to put this in a function, but that causes warnings
|
||||||
// on having no bodies for the copy-constructor/operator=.)
|
// on having no bodies for the copy-constructor/operator=.)
|
||||||
class TBuiltInIdTraverser : public TIntermTraverser {
|
class TBuiltInIdTraverser : public TIntermTraverser {
|
||||||
public:
|
public:
|
||||||
TBuiltInIdTraverser(TMap<TString, int>& idMap) : idMap(idMap), maxId(0) { }
|
TBuiltInIdTraverser(TIdMaps& idMaps) : idMaps(idMaps), maxId(0) { }
|
||||||
// If it's a built in, add it to the map.
|
// If it's a built in, add it to the map.
|
||||||
// Track the max ID.
|
// Track the max ID.
|
||||||
virtual void visitSymbol(TIntermSymbol* symbol)
|
virtual void visitSymbol(TIntermSymbol* symbol)
|
||||||
{
|
{
|
||||||
const TQualifier& qualifier = symbol->getType().getQualifier();
|
const TQualifier& qualifier = symbol->getType().getQualifier();
|
||||||
if (qualifier.builtIn != EbvNone)
|
if (qualifier.builtIn != EbvNone) {
|
||||||
idMap[symbol->getName()] = symbol->getId();
|
TShaderInterface si = symbol->getType().getShaderInterface();
|
||||||
|
idMaps[si][getNameForIdMap(symbol)] = symbol->getId();
|
||||||
|
}
|
||||||
maxId = std::max(maxId, symbol->getId());
|
maxId = std::max(maxId, symbol->getId());
|
||||||
}
|
}
|
||||||
int getMaxId() const { return maxId; }
|
int getMaxId() const { return maxId; }
|
||||||
protected:
|
protected:
|
||||||
TBuiltInIdTraverser(TBuiltInIdTraverser&);
|
TBuiltInIdTraverser(TBuiltInIdTraverser&);
|
||||||
TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&);
|
TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&);
|
||||||
TMap<TString, int>& idMap;
|
TIdMaps& idMaps;
|
||||||
int maxId;
|
int maxId;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -340,31 +357,33 @@ protected:
|
|||||||
// on having no bodies for the copy-constructor/operator=.)
|
// on having no bodies for the copy-constructor/operator=.)
|
||||||
class TUserIdTraverser : public TIntermTraverser {
|
class TUserIdTraverser : public TIntermTraverser {
|
||||||
public:
|
public:
|
||||||
TUserIdTraverser(TMap<TString, int>& idMap) : idMap(idMap) { }
|
TUserIdTraverser(TIdMaps& idMaps) : idMaps(idMaps) { }
|
||||||
// If its a non-built-in global, add it to the map.
|
// If its a non-built-in global, add it to the map.
|
||||||
virtual void visitSymbol(TIntermSymbol* symbol)
|
virtual void visitSymbol(TIntermSymbol* symbol)
|
||||||
{
|
{
|
||||||
const TQualifier& qualifier = symbol->getType().getQualifier();
|
const TQualifier& qualifier = symbol->getType().getQualifier();
|
||||||
if (qualifier.builtIn == EbvNone)
|
if (qualifier.builtIn == EbvNone) {
|
||||||
idMap[symbol->getName()] = symbol->getId();
|
TShaderInterface si = symbol->getType().getShaderInterface();
|
||||||
|
idMaps[si][getNameForIdMap(symbol)] = symbol->getId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TUserIdTraverser(TUserIdTraverser&);
|
TUserIdTraverser(TUserIdTraverser&);
|
||||||
TUserIdTraverser& operator=(TUserIdTraverser&);
|
TUserIdTraverser& operator=(TUserIdTraverser&);
|
||||||
TMap<TString, int>& idMap; // over biggest id
|
TIdMaps& idMaps; // over biggest id
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize the the ID map with what we know of 'this' AST.
|
// Initialize the the ID map with what we know of 'this' AST.
|
||||||
void TIntermediate::seedIdMap(TMap<TString, int>& idMap, int& maxId)
|
void TIntermediate::seedIdMap(TIdMaps& idMaps, int& maxId)
|
||||||
{
|
{
|
||||||
// all built-ins everywhere need to align on IDs and contribute to the max ID
|
// all built-ins everywhere need to align on IDs and contribute to the max ID
|
||||||
TBuiltInIdTraverser builtInIdTraverser(idMap);
|
TBuiltInIdTraverser builtInIdTraverser(idMaps);
|
||||||
treeRoot->traverse(&builtInIdTraverser);
|
treeRoot->traverse(&builtInIdTraverser);
|
||||||
maxId = builtInIdTraverser.getMaxId();
|
maxId = builtInIdTraverser.getMaxId();
|
||||||
|
|
||||||
// user variables in the linker object list need to align on ids
|
// user variables in the linker object list need to align on ids
|
||||||
TUserIdTraverser userIdTraverser(idMap);
|
TUserIdTraverser userIdTraverser(idMaps);
|
||||||
findLinkerObjects()->traverse(&userIdTraverser);
|
findLinkerObjects()->traverse(&userIdTraverser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,7 +392,7 @@ void TIntermediate::seedIdMap(TMap<TString, int>& idMap, int& maxId)
|
|||||||
// on having no bodies for the copy-constructor/operator=.)
|
// on having no bodies for the copy-constructor/operator=.)
|
||||||
class TRemapIdTraverser : public TIntermTraverser {
|
class TRemapIdTraverser : public TIntermTraverser {
|
||||||
public:
|
public:
|
||||||
TRemapIdTraverser(const TMap<TString, int>& idMap, int idShift) : idMap(idMap), idShift(idShift) { }
|
TRemapIdTraverser(const TIdMaps& idMaps, int idShift) : idMaps(idMaps), idShift(idShift) { }
|
||||||
// Do the mapping:
|
// Do the mapping:
|
||||||
// - if the same symbol, adopt the 'this' ID
|
// - if the same symbol, adopt the 'this' ID
|
||||||
// - otherwise, ensure a unique ID by shifting to a new space
|
// - otherwise, ensure a unique ID by shifting to a new space
|
||||||
@@ -382,8 +401,9 @@ public:
|
|||||||
const TQualifier& qualifier = symbol->getType().getQualifier();
|
const TQualifier& qualifier = symbol->getType().getQualifier();
|
||||||
bool remapped = false;
|
bool remapped = false;
|
||||||
if (qualifier.isLinkable() || qualifier.builtIn != EbvNone) {
|
if (qualifier.isLinkable() || qualifier.builtIn != EbvNone) {
|
||||||
auto it = idMap.find(symbol->getName());
|
TShaderInterface si = symbol->getType().getShaderInterface();
|
||||||
if (it != idMap.end()) {
|
auto it = idMaps[si].find(getNameForIdMap(symbol));
|
||||||
|
if (it != idMaps[si].end()) {
|
||||||
symbol->changeId(it->second);
|
symbol->changeId(it->second);
|
||||||
remapped = true;
|
remapped = true;
|
||||||
}
|
}
|
||||||
@@ -394,14 +414,14 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
TRemapIdTraverser(TRemapIdTraverser&);
|
TRemapIdTraverser(TRemapIdTraverser&);
|
||||||
TRemapIdTraverser& operator=(TRemapIdTraverser&);
|
TRemapIdTraverser& operator=(TRemapIdTraverser&);
|
||||||
const TMap<TString, int>& idMap;
|
const TIdMaps& idMaps;
|
||||||
int idShift;
|
int idShift;
|
||||||
};
|
};
|
||||||
|
|
||||||
void TIntermediate::remapIds(const TMap<TString, int>& idMap, int idShift, TIntermediate& unit)
|
void TIntermediate::remapIds(const TIdMaps& idMaps, int idShift, TIntermediate& unit)
|
||||||
{
|
{
|
||||||
// Remap all IDs to either share or be unique, as dictated by the idMap and idShift.
|
// Remap all IDs to either share or be unique, as dictated by the idMap and idShift.
|
||||||
TRemapIdTraverser idTraverser(idMap, idShift);
|
TRemapIdTraverser idTraverser(idMaps, idShift);
|
||||||
unit.getTreeRoot()->traverse(&idTraverser);
|
unit.getTreeRoot()->traverse(&idTraverser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +463,19 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
|
|||||||
TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
|
TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
|
||||||
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
|
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
|
||||||
assert(symbol && unitSymbol);
|
assert(symbol && unitSymbol);
|
||||||
if (symbol->getName() == unitSymbol->getName()) {
|
|
||||||
|
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 (symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) {
|
||||||
|
isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (symbol->getName() == unitSymbol->getName())
|
||||||
|
isSameSymbol = true;
|
||||||
|
|
||||||
|
if (isSameSymbol) {
|
||||||
// filter out copy
|
// filter out copy
|
||||||
merge = false;
|
merge = false;
|
||||||
|
|
||||||
@@ -462,6 +494,9 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
|
|||||||
// Check for consistent types/qualification/initializers etc.
|
// Check for consistent types/qualification/initializers etc.
|
||||||
mergeErrorCheck(infoSink, *symbol, *unitSymbol, false);
|
mergeErrorCheck(infoSink, *symbol, *unitSymbol, false);
|
||||||
}
|
}
|
||||||
|
// 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())
|
||||||
|
error(infoSink, "Only one push_constant block is allowed per stage");
|
||||||
}
|
}
|
||||||
if (merge)
|
if (merge)
|
||||||
linkerObjects.push_back(unitLinkerObjects[unitLinkObj]);
|
linkerObjects.push_back(unitLinkerObjects[unitLinkObj]);
|
||||||
@@ -498,7 +533,7 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
|
|||||||
//
|
//
|
||||||
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage)
|
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage)
|
||||||
{
|
{
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
bool writeTypeComparison = false;
|
bool writeTypeComparison = false;
|
||||||
|
|
||||||
// Types have to match
|
// Types have to match
|
||||||
@@ -520,6 +555,22 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
|||||||
writeTypeComparison = true;
|
writeTypeComparison = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uniform and buffer blocks must either both have an instance name, or
|
||||||
|
// must both be anonymous. The names don't need to match though.
|
||||||
|
if (symbol.getQualifier().isUniformOrBuffer() &&
|
||||||
|
(IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()))) {
|
||||||
|
error(infoSink, "Matched Uniform or Storage blocks must all be anonymous,"
|
||||||
|
" or all be named:");
|
||||||
|
writeTypeComparison = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (symbol.getQualifier().storage == unitSymbol.getQualifier().storage &&
|
||||||
|
(IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()) ||
|
||||||
|
(!IsAnonymous(symbol.getName()) && symbol.getName() != unitSymbol.getName()))) {
|
||||||
|
warn(infoSink, "Matched shader interfaces are using different instance names.");
|
||||||
|
writeTypeComparison = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Precision...
|
// Precision...
|
||||||
if (symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
|
if (symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
|
||||||
error(infoSink, "Precision qualifiers must match:");
|
error(infoSink, "Precision qualifiers must match:");
|
||||||
@@ -555,6 +606,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
|||||||
symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent ||
|
symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent ||
|
||||||
symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent ||
|
symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent ||
|
||||||
symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent ||
|
symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent ||
|
||||||
|
symbol.getQualifier().shadercallcoherent!= unitSymbol.getQualifier().shadercallcoherent ||
|
||||||
symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate ||
|
symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate ||
|
||||||
symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
|
symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
|
||||||
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
|
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
|
||||||
@@ -589,9 +641,13 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeTypeComparison)
|
if (writeTypeComparison) {
|
||||||
infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus \"" <<
|
infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus ";
|
||||||
unitSymbol.getType().getCompleteString() << "\"\n";
|
if (symbol.getName() != unitSymbol.getName())
|
||||||
|
infoSink.info << unitSymbol.getName() << ": ";
|
||||||
|
|
||||||
|
infoSink.info << "\"" << unitSymbol.getType().getCompleteString() << "\"\n";
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,13 +777,13 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
break;
|
break;
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
break;
|
break;
|
||||||
case EShLangRayGenNV:
|
case EShLangRayGen:
|
||||||
case EShLangIntersectNV:
|
case EShLangIntersect:
|
||||||
case EShLangAnyHitNV:
|
case EShLangAnyHit:
|
||||||
case EShLangClosestHitNV:
|
case EShLangClosestHit:
|
||||||
case EShLangMissNV:
|
case EShLangMiss:
|
||||||
case EShLangCallableNV:
|
case EShLangCallable:
|
||||||
if (numShaderRecordNVBlocks > 1)
|
if (numShaderRecordBlocks > 1)
|
||||||
error(infoSink, "Only one shaderRecordNV buffer block is allowed per stage");
|
error(infoSink, "Only one shaderRecordNV buffer block is allowed per stage");
|
||||||
break;
|
break;
|
||||||
case EShLangMeshNV:
|
case EShLangMeshNV:
|
||||||
@@ -1306,9 +1362,9 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
|||||||
// that component's size. Aggregate types are flattened down to the component
|
// that component's size. Aggregate types are flattened down to the component
|
||||||
// level to get this sequence of components."
|
// level to get this sequence of components."
|
||||||
|
|
||||||
if (type.isArray()) {
|
if (type.isSizedArray()) {
|
||||||
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
assert(type.isSizedArray());
|
// Unsized array use to xfb should be a compile error.
|
||||||
TType elementType(type, 0);
|
TType elementType(type, 0);
|
||||||
return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType, contains16BitType, contains16BitType);
|
return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType, contains16BitType, contains16BitType);
|
||||||
}
|
}
|
||||||
@@ -1494,7 +1550,9 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
|
|||||||
RoundToPow2(size, alignment);
|
RoundToPow2(size, alignment);
|
||||||
stride = size; // uses full matrix size for stride of an array of matrices (not quite what rule 6/8, but what's expected)
|
stride = size; // uses full matrix size for stride of an array of matrices (not quite what rule 6/8, but what's expected)
|
||||||
// uses the assumption for rule 10 in the comment above
|
// uses the assumption for rule 10 in the comment above
|
||||||
size = stride * type.getOuterArraySize();
|
// use one element to represent the last member of SSBO which is unsized array
|
||||||
|
int arraySize = (type.isUnsizedArray() && (type.getOuterArraySize() == 0)) ? 1 : type.getOuterArraySize();
|
||||||
|
size = stride * arraySize;
|
||||||
return alignment;
|
return alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,10 @@ struct TXfbBuffer {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Track a set of strings describing how the module was processed.
|
// Track a set of strings describing how the module was processed.
|
||||||
// Using the form:
|
// This includes command line options, transforms, etc., ideally inclusive enough
|
||||||
|
// to reproduce the steps used to transform the input source to the output.
|
||||||
|
// E.g., see SPIR-V OpModuleProcessed.
|
||||||
|
// Each "process" or "transform" uses is expressed in the form:
|
||||||
// process arg0 arg1 arg2 ...
|
// process arg0 arg1 arg2 ...
|
||||||
// process arg0 arg1 arg2 ...
|
// process arg0 arg1 arg2 ...
|
||||||
// where everything is textual, and there can be zero or more arguments
|
// where everything is textual, and there can be zero or more arguments
|
||||||
@@ -222,6 +225,40 @@ enum ComputeDerivativeMode {
|
|||||||
LayoutDerivativeGroupLinear, // derivative_group_linearNV
|
LayoutDerivativeGroupLinear, // derivative_group_linearNV
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TIdMaps {
|
||||||
|
public:
|
||||||
|
TMap<TString, int>& operator[](int i) { return maps[i]; }
|
||||||
|
const TMap<TString, int>& operator[](int i) const { return maps[i]; }
|
||||||
|
private:
|
||||||
|
TMap<TString, int> maps[EsiCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
class TNumericFeatures {
|
||||||
|
public:
|
||||||
|
TNumericFeatures() : features(0) { }
|
||||||
|
TNumericFeatures(const TNumericFeatures&) = delete;
|
||||||
|
TNumericFeatures& operator=(const TNumericFeatures&) = delete;
|
||||||
|
typedef enum : unsigned int {
|
||||||
|
shader_explicit_arithmetic_types = 1 << 0,
|
||||||
|
shader_explicit_arithmetic_types_int8 = 1 << 1,
|
||||||
|
shader_explicit_arithmetic_types_int16 = 1 << 2,
|
||||||
|
shader_explicit_arithmetic_types_int32 = 1 << 3,
|
||||||
|
shader_explicit_arithmetic_types_int64 = 1 << 4,
|
||||||
|
shader_explicit_arithmetic_types_float16 = 1 << 5,
|
||||||
|
shader_explicit_arithmetic_types_float32 = 1 << 6,
|
||||||
|
shader_explicit_arithmetic_types_float64 = 1 << 7,
|
||||||
|
shader_implicit_conversions = 1 << 8,
|
||||||
|
gpu_shader_fp64 = 1 << 9,
|
||||||
|
gpu_shader_int16 = 1 << 10,
|
||||||
|
gpu_shader_half_float = 1 << 11,
|
||||||
|
} feature;
|
||||||
|
void insert(feature f) { features |= f; }
|
||||||
|
void erase(feature f) { features &= ~f; }
|
||||||
|
bool contains(feature f) const { return (features & f) != 0; }
|
||||||
|
private:
|
||||||
|
unsigned int features;
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set of helper functions to help parse and build the tree.
|
// Set of helper functions to help parse and build the tree.
|
||||||
//
|
//
|
||||||
@@ -229,7 +266,10 @@ class TIntermediate {
|
|||||||
public:
|
public:
|
||||||
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
|
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
|
||||||
language(l),
|
language(l),
|
||||||
profile(p), version(v), treeRoot(0),
|
#ifndef GLSLANG_ANGLE
|
||||||
|
profile(p), version(v),
|
||||||
|
#endif
|
||||||
|
treeRoot(0),
|
||||||
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
||||||
invertY(false),
|
invertY(false),
|
||||||
useStorageBuffer(false),
|
useStorageBuffer(false),
|
||||||
@@ -244,15 +284,16 @@ public:
|
|||||||
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
|
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
|
||||||
pixelCenterInteger(false), originUpperLeft(false),
|
pixelCenterInteger(false), originUpperLeft(false),
|
||||||
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
|
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
|
||||||
postDepthCoverage(false), depthLayout(EldNone),
|
postDepthCoverage(false), depthLayout(EldNone),
|
||||||
hlslFunctionality1(false),
|
hlslFunctionality1(false),
|
||||||
blendEquations(0), xfbMode(false), multiStream(false),
|
blendEquations(0), xfbMode(false), multiStream(false),
|
||||||
layoutOverrideCoverage(false),
|
layoutOverrideCoverage(false),
|
||||||
geoPassthroughEXT(false),
|
geoPassthroughEXT(false),
|
||||||
numShaderRecordNVBlocks(0),
|
numShaderRecordBlocks(0),
|
||||||
computeDerivativeMode(LayoutDerivativeNone),
|
computeDerivativeMode(LayoutDerivativeNone),
|
||||||
primitives(TQualifier::layoutNotSet),
|
primitives(TQualifier::layoutNotSet),
|
||||||
numTaskNVBlocks(0),
|
numTaskNVBlocks(0),
|
||||||
|
layoutPrimitiveCulling(false),
|
||||||
autoMapBindings(false),
|
autoMapBindings(false),
|
||||||
autoMapLocations(false),
|
autoMapLocations(false),
|
||||||
flattenUniformArrays(false),
|
flattenUniformArrays(false),
|
||||||
@@ -282,9 +323,20 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void setVersion(int v) { version = v; }
|
void setVersion(int v)
|
||||||
|
{
|
||||||
|
#ifndef GLSLANG_ANGLE
|
||||||
|
version = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void setProfile(EProfile p)
|
||||||
|
{
|
||||||
|
#ifndef GLSLANG_ANGLE
|
||||||
|
profile = p;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int getVersion() const { return version; }
|
int getVersion() const { return version; }
|
||||||
void setProfile(EProfile p) { profile = p; }
|
|
||||||
EProfile getProfile() const { return profile; }
|
EProfile getProfile() const { return profile; }
|
||||||
void setSpv(const SpvVersion& s)
|
void setSpv(const SpvVersion& s)
|
||||||
{
|
{
|
||||||
@@ -332,6 +384,9 @@ public:
|
|||||||
case EShTargetVulkan_1_1:
|
case EShTargetVulkan_1_1:
|
||||||
processes.addProcess("target-env vulkan1.1");
|
processes.addProcess("target-env vulkan1.1");
|
||||||
break;
|
break;
|
||||||
|
case EShTargetVulkan_1_2:
|
||||||
|
processes.addProcess("target-env vulkan1.2");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
processes.addProcess("target-env vulkanUnknown");
|
processes.addProcess("target-env vulkanUnknown");
|
||||||
break;
|
break;
|
||||||
@@ -377,7 +432,7 @@ public:
|
|||||||
void setSource(EShSource s) { source = s; }
|
void setSource(EShSource s) { source = s; }
|
||||||
EShSource getSource() const { return source; }
|
EShSource getSource() const { return source; }
|
||||||
#else
|
#else
|
||||||
void setSource(EShSource s) { assert(s == EShSourceGlsl); }
|
void setSource(EShSource s) { assert(s == EShSourceGlsl); (void)s; }
|
||||||
EShSource getSource() const { return EShSourceGlsl; }
|
EShSource getSource() const { return EShSourceGlsl; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -388,15 +443,15 @@ public:
|
|||||||
TIntermSymbol* addSymbol(const TType&, const TSourceLoc&);
|
TIntermSymbol* addSymbol(const TType&, const TSourceLoc&);
|
||||||
TIntermSymbol* addSymbol(const TIntermSymbol&);
|
TIntermSymbol* addSymbol(const TIntermSymbol&);
|
||||||
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
|
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
|
||||||
std::tuple<TIntermTyped*, TIntermTyped*> addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1);
|
std::tuple<TIntermTyped*, TIntermTyped*> addPairConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1);
|
||||||
TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*);
|
TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*);
|
||||||
TIntermTyped* addConversion(TBasicType convertTo, TIntermTyped* node) const;
|
TIntermTyped* addConversion(TBasicType convertTo, TIntermTyped* node) const;
|
||||||
void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode);
|
void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode);
|
||||||
TIntermTyped* addShapeConversion(const TType&, TIntermTyped*);
|
TIntermTyped* addShapeConversion(const TType&, TIntermTyped*);
|
||||||
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
|
||||||
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
|
||||||
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
|
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&);
|
||||||
TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc);
|
TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, const TSourceLoc&);
|
||||||
TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType);
|
TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType);
|
||||||
bool canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op = EOpNull) const;
|
bool canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op = EOpNull) const;
|
||||||
bool isIntegralPromotion(TBasicType from, TBasicType to) const;
|
bool isIntegralPromotion(TBasicType from, TBasicType to) const;
|
||||||
@@ -410,7 +465,7 @@ public:
|
|||||||
TIntermAggregate* makeAggregate(TIntermNode* node);
|
TIntermAggregate* makeAggregate(TIntermNode* node);
|
||||||
TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
|
TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
|
||||||
TIntermAggregate* makeAggregate(const TSourceLoc&);
|
TIntermAggregate* makeAggregate(const TSourceLoc&);
|
||||||
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
|
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, const TSourceLoc&);
|
||||||
bool areAllChildConst(TIntermAggregate* aggrNode);
|
bool areAllChildConst(TIntermAggregate* aggrNode);
|
||||||
TIntermSelection* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
|
TIntermSelection* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
|
||||||
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
|
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
|
||||||
@@ -439,10 +494,11 @@ public:
|
|||||||
|
|
||||||
// Low level functions to add nodes (no conversions or other higher level transformations)
|
// Low level functions to add nodes (no conversions or other higher level transformations)
|
||||||
// If a type is provided, the node's type will be set to it.
|
// If a type is provided, the node's type will be set to it.
|
||||||
TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc) const;
|
TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&) const;
|
||||||
TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, const TType&) const;
|
TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&,
|
||||||
TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc) const;
|
const TType&) const;
|
||||||
TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc, const TType&) const;
|
TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc&) const;
|
||||||
|
TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc&, const TType&) const;
|
||||||
|
|
||||||
// Constant folding (in Constant.cpp)
|
// Constant folding (in Constant.cpp)
|
||||||
TIntermTyped* fold(TIntermAggregate* aggrNode);
|
TIntermTyped* fold(TIntermAggregate* aggrNode);
|
||||||
@@ -457,11 +513,7 @@ public:
|
|||||||
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
||||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
|
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
|
||||||
|
|
||||||
void setUseStorageBuffer()
|
void setUseStorageBuffer() { useStorageBuffer = true; }
|
||||||
{
|
|
||||||
useStorageBuffer = true;
|
|
||||||
processes.addProcess("use-storage-buffer");
|
|
||||||
}
|
|
||||||
bool usingStorageBuffer() const { return useStorageBuffer; }
|
bool usingStorageBuffer() const { return useStorageBuffer; }
|
||||||
void setDepthReplacing() { depthReplacing = true; }
|
void setDepthReplacing() { depthReplacing = true; }
|
||||||
bool isDepthReplacing() const { return depthReplacing; }
|
bool isDepthReplacing() const { return depthReplacing; }
|
||||||
@@ -500,7 +552,7 @@ public:
|
|||||||
bool getAutoMapBindings() const { return false; }
|
bool getAutoMapBindings() const { return false; }
|
||||||
bool getAutoMapLocations() const { return false; }
|
bool getAutoMapLocations() const { return false; }
|
||||||
int getNumPushConstants() const { return 0; }
|
int getNumPushConstants() const { return 0; }
|
||||||
void addShaderRecordNVCount() { }
|
void addShaderRecordCount() { }
|
||||||
void addTaskNVCount() { }
|
void addTaskNVCount() { }
|
||||||
void setUseVulkanMemoryModel() { }
|
void setUseVulkanMemoryModel() { }
|
||||||
bool usingVulkanMemoryModel() const { return false; }
|
bool usingVulkanMemoryModel() const { return false; }
|
||||||
@@ -580,7 +632,7 @@ public:
|
|||||||
processes.addProcess("flatten-uniform-arrays");
|
processes.addProcess("flatten-uniform-arrays");
|
||||||
}
|
}
|
||||||
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
|
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
|
||||||
#endif
|
#endif
|
||||||
void setNoStorageFormat(bool b)
|
void setNoStorageFormat(bool b)
|
||||||
{
|
{
|
||||||
useUnknownFormat = b;
|
useUnknownFormat = b;
|
||||||
@@ -617,7 +669,7 @@ public:
|
|||||||
|
|
||||||
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
||||||
int getNumPushConstants() const { return numPushConstants; }
|
int getNumPushConstants() const { return numPushConstants; }
|
||||||
void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; }
|
void addShaderRecordCount() { ++numShaderRecordBlocks; }
|
||||||
void addTaskNVCount() { ++numTaskNVBlocks; }
|
void addTaskNVCount() { ++numTaskNVBlocks; }
|
||||||
|
|
||||||
bool setInvocations(int i)
|
bool setInvocations(int i)
|
||||||
@@ -720,6 +772,8 @@ public:
|
|||||||
void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
|
void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
|
||||||
bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; }
|
bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; }
|
||||||
ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
|
ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
|
||||||
|
void setLayoutPrimitiveCulling() { layoutPrimitiveCulling = true; }
|
||||||
|
bool getLayoutPrimitiveCulling() const { return layoutPrimitiveCulling; }
|
||||||
bool setPrimitives(int m)
|
bool setPrimitives(int m)
|
||||||
{
|
{
|
||||||
if (primitives != TQualifier::layoutNotSet)
|
if (primitives != TQualifier::layoutNotSet)
|
||||||
@@ -831,22 +885,25 @@ public:
|
|||||||
bool getArithemeticInt8Enabled() const { return false; }
|
bool getArithemeticInt8Enabled() const { return false; }
|
||||||
bool getArithemeticInt16Enabled() const { return false; }
|
bool getArithemeticInt16Enabled() const { return false; }
|
||||||
bool getArithemeticFloat16Enabled() const { return false; }
|
bool getArithemeticFloat16Enabled() const { return false; }
|
||||||
|
void updateNumericFeature(TNumericFeatures::feature f, bool on) { }
|
||||||
#else
|
#else
|
||||||
bool getArithemeticInt8Enabled() const {
|
bool getArithemeticInt8Enabled() const {
|
||||||
return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8);
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8);
|
||||||
}
|
}
|
||||||
bool getArithemeticInt16Enabled() const {
|
bool getArithemeticInt16Enabled() const {
|
||||||
return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
|
||||||
extensionRequested(E_GL_AMD_gpu_shader_int16) ||
|
numericFeatures.contains(TNumericFeatures::gpu_shader_int16) ||
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16);
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getArithemeticFloat16Enabled() const {
|
bool getArithemeticFloat16Enabled() const {
|
||||||
return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
|
||||||
extensionRequested(E_GL_AMD_gpu_shader_half_float) ||
|
numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) ||
|
||||||
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16);
|
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16);
|
||||||
}
|
}
|
||||||
|
void updateNumericFeature(TNumericFeatures::feature f, bool on)
|
||||||
|
{ on ? numericFeatures.insert(f) : numericFeatures.erase(f); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -856,8 +913,8 @@ protected:
|
|||||||
void mergeCallGraphs(TInfoSink&, TIntermediate&);
|
void mergeCallGraphs(TInfoSink&, TIntermediate&);
|
||||||
void mergeModes(TInfoSink&, TIntermediate&);
|
void mergeModes(TInfoSink&, TIntermediate&);
|
||||||
void mergeTrees(TInfoSink&, TIntermediate&);
|
void mergeTrees(TInfoSink&, TIntermediate&);
|
||||||
void seedIdMap(TMap<TString, int>& idMap, int& maxId);
|
void seedIdMap(TIdMaps& idMaps, int& maxId);
|
||||||
void remapIds(const TMap<TString, int>& idMap, int idShift, TIntermediate&);
|
void remapIds(const TIdMaps& idMaps, int idShift, TIntermediate&);
|
||||||
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
|
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
|
||||||
void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
|
void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
|
||||||
void mergeImplicitArraySizes(TType&, const TType&);
|
void mergeImplicitArraySizes(TType&, const TType&);
|
||||||
@@ -878,17 +935,7 @@ protected:
|
|||||||
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
||||||
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
||||||
bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
|
bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
|
||||||
std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
|
std::tuple<TBasicType, TBasicType> getConversionDestinationType(TBasicType type0, TBasicType type1, TOperator op) const;
|
||||||
|
|
||||||
// JohnK: I think this function should go away.
|
|
||||||
// This data structure is just a log to pass on to back ends.
|
|
||||||
// Versioning and extensions are handled in Version.cpp, with a rich
|
|
||||||
// set of functions for querying stages, versions, extension enable/disabled, etc.
|
|
||||||
#ifdef GLSLANG_WEB
|
|
||||||
bool extensionRequested(const char *extension) const { return false; }
|
|
||||||
#else
|
|
||||||
bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char* getResourceName(TResourceType);
|
static const char* getResourceName(TResourceType);
|
||||||
|
|
||||||
@@ -898,8 +945,13 @@ protected:
|
|||||||
typedef std::list<TCall> TGraph;
|
typedef std::list<TCall> TGraph;
|
||||||
TGraph callGraph;
|
TGraph callGraph;
|
||||||
|
|
||||||
|
#ifdef GLSLANG_ANGLE
|
||||||
|
const EProfile profile = ECoreProfile;
|
||||||
|
const int version = 450;
|
||||||
|
#else
|
||||||
EProfile profile; // source profile
|
EProfile profile; // source profile
|
||||||
int version; // source version
|
int version; // source version
|
||||||
|
#endif
|
||||||
SpvVersion spvVersion;
|
SpvVersion spvVersion;
|
||||||
TIntermNode* treeRoot;
|
TIntermNode* treeRoot;
|
||||||
std::set<std::string> requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them
|
std::set<std::string> requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them
|
||||||
@@ -942,10 +994,11 @@ protected:
|
|||||||
bool multiStream;
|
bool multiStream;
|
||||||
bool layoutOverrideCoverage;
|
bool layoutOverrideCoverage;
|
||||||
bool geoPassthroughEXT;
|
bool geoPassthroughEXT;
|
||||||
int numShaderRecordNVBlocks;
|
int numShaderRecordBlocks;
|
||||||
ComputeDerivativeMode computeDerivativeMode;
|
ComputeDerivativeMode computeDerivativeMode;
|
||||||
int primitives;
|
int primitives;
|
||||||
int numTaskNVBlocks;
|
int numTaskNVBlocks;
|
||||||
|
bool layoutPrimitiveCulling;
|
||||||
|
|
||||||
// Base shift values
|
// Base shift values
|
||||||
std::array<unsigned int, EResCount> shiftBinding;
|
std::array<unsigned int, EResCount> shiftBinding;
|
||||||
@@ -972,6 +1025,7 @@ protected:
|
|||||||
|
|
||||||
std::unordered_map<std::string, int> uniformLocationOverrides;
|
std::unordered_map<std::string, int> uniformLocationOverrides;
|
||||||
int uniformLocationBase;
|
int uniformLocationBase;
|
||||||
|
TNumericFeatures numericFeatures;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
||||||
|
|||||||
@@ -165,17 +165,27 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// matrix from vector
|
// matrix from vector or scalar
|
||||||
int count = 0;
|
int count = 0;
|
||||||
const int startIndex = index;
|
const int startIndex = index;
|
||||||
int nodeComps = node->getType().computeNumComponents();
|
int nodeComps = node->getType().computeNumComponents();
|
||||||
for (int i = startIndex; i < endIndex; i++) {
|
for (int i = startIndex; i < endIndex; i++) {
|
||||||
if (i >= instanceSize)
|
if (i >= instanceSize)
|
||||||
return;
|
return;
|
||||||
if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
|
if (nodeComps == 1) {
|
||||||
|
// If there is a single scalar parameter to a matrix
|
||||||
|
// constructor, it is used to initialize all the
|
||||||
|
// components on the matrix's diagonal, with the
|
||||||
|
// remaining components initialized to 0.0.
|
||||||
|
if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
|
||||||
|
leftUnionArray[i] = rightUnionArray[count];
|
||||||
|
else
|
||||||
|
leftUnionArray[i].setDConst(0.0);
|
||||||
|
} else {
|
||||||
|
// construct the matrix in column-major order, from
|
||||||
|
// the components provided, in order
|
||||||
leftUnionArray[i] = rightUnionArray[count];
|
leftUnionArray[i] = rightUnionArray[count];
|
||||||
else
|
}
|
||||||
leftUnionArray[i].setDConst(0.0);
|
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink,
|
const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink,
|
||||||
bool forwardCompatible, EShMessages messages)
|
bool forwardCompatible, EShMessages messages)
|
||||||
:
|
:
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
forwardCompatible(forwardCompatible),
|
forwardCompatible(forwardCompatible),
|
||||||
profile(profile),
|
profile(profile),
|
||||||
#endif
|
#endif
|
||||||
@@ -101,6 +101,7 @@ public:
|
|||||||
void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { }
|
void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { }
|
||||||
void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { }
|
void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { }
|
||||||
void checkExtensionStage(const TSourceLoc&, const char* const extension) { }
|
void checkExtensionStage(const TSourceLoc&, const char* const extension) { }
|
||||||
|
void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior) { }
|
||||||
void fullIntegerCheck(const TSourceLoc&, const char* op) { }
|
void fullIntegerCheck(const TSourceLoc&, const char* op) { }
|
||||||
void doubleCheck(const TSourceLoc&, const char* op) { }
|
void doubleCheck(const TSourceLoc&, const char* op) { }
|
||||||
bool float16Arithmetic() { return false; }
|
bool float16Arithmetic() { return false; }
|
||||||
@@ -115,9 +116,14 @@ public:
|
|||||||
bool relaxedErrors() const { return false; }
|
bool relaxedErrors() const { return false; }
|
||||||
bool suppressWarnings() const { return true; }
|
bool suppressWarnings() const { return true; }
|
||||||
bool isForwardCompatible() const { return false; }
|
bool isForwardCompatible() const { return false; }
|
||||||
|
#else
|
||||||
|
#ifdef GLSLANG_ANGLE
|
||||||
|
const bool forwardCompatible = true;
|
||||||
|
const EProfile profile = ECoreProfile;
|
||||||
#else
|
#else
|
||||||
bool forwardCompatible; // true if errors are to be given for use of deprecated features
|
bool forwardCompatible; // true if errors are to be given for use of deprecated features
|
||||||
EProfile profile; // the declared profile in the shader (core by default)
|
EProfile profile; // the declared profile in the shader (core by default)
|
||||||
|
#endif
|
||||||
bool isEsProfile() const { return profile == EEsProfile; }
|
bool isEsProfile() const { return profile == EEsProfile; }
|
||||||
void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc);
|
void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc);
|
||||||
void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions,
|
void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions,
|
||||||
@@ -139,6 +145,7 @@ public:
|
|||||||
virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[],
|
virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[],
|
||||||
const char* featureDesc);
|
const char* featureDesc);
|
||||||
virtual void checkExtensionStage(const TSourceLoc&, const char* const extension);
|
virtual void checkExtensionStage(const TSourceLoc&, const char* const extension);
|
||||||
|
virtual void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior);
|
||||||
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
|
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
|
||||||
|
|
||||||
virtual void unimplemented(const TSourceLoc&, const char* featureDesc);
|
virtual void unimplemented(const TSourceLoc&, const char* featureDesc);
|
||||||
@@ -170,6 +177,7 @@ public:
|
|||||||
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
|
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
|
||||||
virtual void requireVulkan(const TSourceLoc&, const char* op);
|
virtual void requireVulkan(const TSourceLoc&, const char* op);
|
||||||
virtual void requireSpv(const TSourceLoc&, const char* op);
|
virtual void requireSpv(const TSourceLoc&, const char* op);
|
||||||
|
virtual void requireSpv(const TSourceLoc&, const char *op, unsigned int version);
|
||||||
|
|
||||||
|
|
||||||
#if defined(GLSLANG_WEB) && !defined(GLSLANG_WEB_DEVEL)
|
#if defined(GLSLANG_WEB) && !defined(GLSLANG_WEB_DEVEL)
|
||||||
@@ -221,7 +229,8 @@ public:
|
|||||||
TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree
|
TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is set to
|
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is
|
||||||
|
TMap<TString, unsigned int> extensionMinSpv; // for each extension string, store minimum spirv required
|
||||||
EShMessages messages; // errors/warnings/rule-sets
|
EShMessages messages; // errors/warnings/rule-sets
|
||||||
int numErrors; // number of compile-time errors encountered
|
int numErrors; // number of compile-time errors encountered
|
||||||
TInputScanner* currentScanner;
|
TInputScanner* currentScanner;
|
||||||
|
|||||||
@@ -422,10 +422,10 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
|
|||||||
if (! parseContext.isReadingHLSL() && isMacroInput()) {
|
if (! parseContext.isReadingHLSL() && isMacroInput()) {
|
||||||
if (parseContext.relaxedErrors())
|
if (parseContext.relaxedErrors())
|
||||||
parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression",
|
parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression",
|
||||||
"defined", "");
|
"defined", "");
|
||||||
else
|
else
|
||||||
parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros",
|
parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros",
|
||||||
"defined", "");
|
"defined", "");
|
||||||
}
|
}
|
||||||
bool needclose = 0;
|
bool needclose = 0;
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
@@ -621,14 +621,25 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
|
|||||||
{
|
{
|
||||||
const TSourceLoc directiveLoc = ppToken->loc;
|
const TSourceLoc directiveLoc = ppToken->loc;
|
||||||
bool startWithLocalSearch = true; // to additionally include the extra "" paths
|
bool startWithLocalSearch = true; // to additionally include the extra "" paths
|
||||||
int token = scanToken(ppToken);
|
int token;
|
||||||
|
|
||||||
// handle <header-name>-style #include
|
// Find the first non-whitespace char after #include
|
||||||
if (token == '<') {
|
int ch = getChar();
|
||||||
|
while (ch == ' ' || ch == '\t') {
|
||||||
|
ch = getChar();
|
||||||
|
}
|
||||||
|
if (ch == '<') {
|
||||||
|
// <header-name> style
|
||||||
startWithLocalSearch = false;
|
startWithLocalSearch = false;
|
||||||
token = scanHeaderName(ppToken, '>');
|
token = scanHeaderName(ppToken, '>');
|
||||||
|
} else if (ch == '"') {
|
||||||
|
// "header-name" style
|
||||||
|
token = scanHeaderName(ppToken, '"');
|
||||||
|
} else {
|
||||||
|
// unexpected, get the full token to generate the error
|
||||||
|
ungetChar();
|
||||||
|
token = scanToken(ppToken);
|
||||||
}
|
}
|
||||||
// otherwise ppToken already has the header name and it was "header-name" style
|
|
||||||
|
|
||||||
if (token != PpAtomConstString) {
|
if (token != PpAtomConstString) {
|
||||||
parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", "");
|
parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", "");
|
||||||
@@ -711,7 +722,9 @@ int TPpContext::CPPline(TPpToken* ppToken)
|
|||||||
const char* sourceName = nullptr; // Optional source file name.
|
const char* sourceName = nullptr; // Optional source file name.
|
||||||
bool lineErr = false;
|
bool lineErr = false;
|
||||||
bool fileErr = false;
|
bool fileErr = false;
|
||||||
|
disableEscapeSequences = true;
|
||||||
token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken);
|
token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken);
|
||||||
|
disableEscapeSequences = false;
|
||||||
if (! lineErr) {
|
if (! lineErr) {
|
||||||
lineToken = lineRes;
|
lineToken = lineRes;
|
||||||
if (token == '\n')
|
if (token == '\n')
|
||||||
@@ -754,7 +767,9 @@ int TPpContext::CPPline(TPpToken* ppToken)
|
|||||||
// Handle #error
|
// Handle #error
|
||||||
int TPpContext::CPPerror(TPpToken* ppToken)
|
int TPpContext::CPPerror(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
|
disableEscapeSequences = true;
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
|
disableEscapeSequences = false;
|
||||||
std::string message;
|
std::string message;
|
||||||
TSourceLoc loc = ppToken->loc;
|
TSourceLoc loc = ppToken->loc;
|
||||||
|
|
||||||
@@ -1169,7 +1184,9 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b
|
|||||||
int macroAtom = atomStrings.getAtom(ppToken->name);
|
int macroAtom = atomStrings.getAtom(ppToken->name);
|
||||||
switch (macroAtom) {
|
switch (macroAtom) {
|
||||||
case PpAtomLineMacro:
|
case PpAtomLineMacro:
|
||||||
ppToken->ival = parseContext.getCurrentLoc().line;
|
// Arguments which are macro have been replaced in the first stage.
|
||||||
|
if (ppToken->ival == 0)
|
||||||
|
ppToken->ival = parseContext.getCurrentLoc().line;
|
||||||
snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
|
snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
|
||||||
UngetToken(PpAtomConstInt, ppToken);
|
UngetToken(PpAtomConstInt, ppToken);
|
||||||
return MacroExpandStarted;
|
return MacroExpandStarted;
|
||||||
@@ -1270,6 +1287,11 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b
|
|||||||
nestStack.push_back('}');
|
nestStack.push_back('}');
|
||||||
else if (nestStack.size() > 0 && token == nestStack.back())
|
else if (nestStack.size() > 0 && token == nestStack.back())
|
||||||
nestStack.pop_back();
|
nestStack.pop_back();
|
||||||
|
|
||||||
|
//Macro replacement list is expanded in the last stage.
|
||||||
|
if (atomStrings.getAtom(ppToken->name) == PpAtomLineMacro)
|
||||||
|
ppToken->ival = parseContext.getCurrentLoc().line;
|
||||||
|
|
||||||
in->args[arg]->putToken(token, ppToken);
|
in->args[arg]->putToken(token, ppToken);
|
||||||
tokenRecorded = true;
|
tokenRecorded = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ namespace glslang {
|
|||||||
TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
|
TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
|
||||||
preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
|
preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
|
||||||
rootFileName(rootFileName),
|
rootFileName(rootFileName),
|
||||||
currentSourceFile(rootFileName)
|
currentSourceFile(rootFileName),
|
||||||
|
disableEscapeSequences(false)
|
||||||
{
|
{
|
||||||
ifdepth = 0;
|
ifdepth = 0;
|
||||||
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
|
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
|
||||||
|
|||||||
@@ -105,13 +105,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Used for comparing macro definitions, so checks what is relevant for that.
|
// Used for comparing macro definitions, so checks what is relevant for that.
|
||||||
bool operator==(const TPpToken& right)
|
bool operator==(const TPpToken& right) const
|
||||||
{
|
{
|
||||||
return space == right.space &&
|
return space == right.space &&
|
||||||
ival == right.ival && dval == right.dval && i64val == right.i64val &&
|
ival == right.ival && dval == right.dval && i64val == right.i64val &&
|
||||||
strncmp(name, right.name, MaxTokenLength) == 0;
|
strncmp(name, right.name, MaxTokenLength) == 0;
|
||||||
}
|
}
|
||||||
bool operator!=(const TPpToken& right) { return ! operator==(right); }
|
bool operator!=(const TPpToken& right) const { return ! operator==(right); }
|
||||||
|
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
// True if a space (for white space or a removed comment) should also be
|
// True if a space (for white space or a removed comment) should also be
|
||||||
@@ -695,6 +695,7 @@ protected:
|
|||||||
std::string currentSourceFile;
|
std::string currentSourceFile;
|
||||||
|
|
||||||
std::istringstream strtodStream;
|
std::istringstream strtodStream;
|
||||||
|
bool disableEscapeSequences;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@@ -1026,12 +1026,80 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
case '\'':
|
case '\'':
|
||||||
return pp->characterLiteral(ppToken);
|
return pp->characterLiteral(ppToken);
|
||||||
case '"':
|
case '"':
|
||||||
// TODO: If this gets enhanced to handle escape sequences, or
|
// #include uses scanHeaderName() to ignore these escape sequences.
|
||||||
// anything that is different than what #include needs, then
|
|
||||||
// #include needs to use scanHeaderName() for this.
|
|
||||||
ch = getch();
|
ch = getch();
|
||||||
while (ch != '"' && ch != '\n' && ch != EndOfInput) {
|
while (ch != '"' && ch != '\n' && ch != EndOfInput) {
|
||||||
if (len < MaxTokenLength) {
|
if (len < MaxTokenLength) {
|
||||||
|
if (ch == '\\' && !pp->disableEscapeSequences) {
|
||||||
|
int nextCh = getch();
|
||||||
|
switch (nextCh) {
|
||||||
|
case '\'': ch = 0x27; break;
|
||||||
|
case '"': ch = 0x22; break;
|
||||||
|
case '?': ch = 0x3f; break;
|
||||||
|
case '\\': ch = 0x5c; break;
|
||||||
|
case 'a': ch = 0x07; break;
|
||||||
|
case 'b': ch = 0x08; break;
|
||||||
|
case 'f': ch = 0x0c; break;
|
||||||
|
case 'n': ch = 0x0a; break;
|
||||||
|
case 'r': ch = 0x0d; break;
|
||||||
|
case 't': ch = 0x09; break;
|
||||||
|
case 'v': ch = 0x0b; break;
|
||||||
|
case 'x':
|
||||||
|
// Hex value, arbitrary number of characters. Terminated by the first
|
||||||
|
// non-hex digit
|
||||||
|
{
|
||||||
|
int numDigits = 0;
|
||||||
|
ch = 0;
|
||||||
|
while (true) {
|
||||||
|
nextCh = getch();
|
||||||
|
if (nextCh >= '0' && nextCh <= '9')
|
||||||
|
nextCh -= '0';
|
||||||
|
else if (nextCh >= 'A' && nextCh <= 'F')
|
||||||
|
nextCh -= 'A' - 10;
|
||||||
|
else if (nextCh >= 'a' && nextCh <= 'f')
|
||||||
|
nextCh -= 'a' - 10;
|
||||||
|
else {
|
||||||
|
ungetch();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
numDigits++;
|
||||||
|
ch = ch * 0x10 + nextCh;
|
||||||
|
}
|
||||||
|
if (numDigits == 0) {
|
||||||
|
pp->parseContext.ppError(ppToken->loc, "Expected hex value in escape sequence", "string", "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
// Octal value, up to three octal digits
|
||||||
|
{
|
||||||
|
int numDigits = 1;
|
||||||
|
ch = nextCh - '0';
|
||||||
|
while (numDigits < 3) {
|
||||||
|
nextCh = getch();
|
||||||
|
if (nextCh >= '0' && nextCh <= '7')
|
||||||
|
nextCh -= '0';
|
||||||
|
else {
|
||||||
|
ungetch();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
numDigits++;
|
||||||
|
ch = ch * 8 + nextCh;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
pp->parseContext.ppError(ppToken->loc, "Invalid escape sequence", "string", "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
ppToken->name[len] = (char)ch;
|
ppToken->name[len] = (char)ch;
|
||||||
len++;
|
len++;
|
||||||
ch = getch();
|
ch = getch();
|
||||||
@@ -1120,10 +1188,12 @@ int TPpContext::tokenize(TPpToken& ppToken)
|
|||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
case PpAtomConstString:
|
case PpAtomConstString:
|
||||||
|
// HLSL allows string literals.
|
||||||
|
// GLSL allows string literals with GL_EXT_debug_printf.
|
||||||
if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) {
|
if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) {
|
||||||
// HLSL allows string literals.
|
parseContext.requireExtensions(ppToken.loc, 1, &E_GL_EXT_debug_printf, "string literal");
|
||||||
parseContext.ppError(ppToken.loc, "string literals not supported", "\"\"", "");
|
if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\'':
|
case '\'':
|
||||||
|
|||||||
@@ -867,4 +867,4 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GLSLANG_WEB
|
#endif // GLSLANG_WEB
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
#include "../Include/Common.h"
|
#include "../Include/Common.h"
|
||||||
#include "reflection.h"
|
#include "reflection.h"
|
||||||
@@ -77,10 +77,10 @@ namespace glslang {
|
|||||||
// This is in the glslang namespace directly so it can be a friend of TReflection.
|
// This is in the glslang namespace directly so it can be a friend of TReflection.
|
||||||
//
|
//
|
||||||
|
|
||||||
class TReflectionTraverser : public TLiveTraverser {
|
class TReflectionTraverser : public TIntermTraverser {
|
||||||
public:
|
public:
|
||||||
TReflectionTraverser(const TIntermediate& i, TReflection& r) :
|
TReflectionTraverser(const TIntermediate& i, TReflection& r) :
|
||||||
TLiveTraverser(i), reflection(r) { }
|
TIntermTraverser(), intermediate(i), reflection(r), updateStageMasks(true) { }
|
||||||
|
|
||||||
virtual bool visitBinary(TVisit, TIntermBinary* node);
|
virtual bool visitBinary(TVisit, TIntermBinary* node);
|
||||||
virtual void visitSymbol(TIntermSymbol* base);
|
virtual void visitSymbol(TIntermSymbol* base);
|
||||||
@@ -92,11 +92,28 @@ public:
|
|||||||
if (processedDerefs.find(&base) == processedDerefs.end()) {
|
if (processedDerefs.find(&base) == processedDerefs.end()) {
|
||||||
processedDerefs.insert(&base);
|
processedDerefs.insert(&base);
|
||||||
|
|
||||||
|
int blockIndex = -1;
|
||||||
|
int offset = -1;
|
||||||
|
TList<TIntermBinary*> derefs;
|
||||||
|
TString baseName = base.getName();
|
||||||
|
|
||||||
|
if (base.getType().getBasicType() == EbtBlock) {
|
||||||
|
offset = 0;
|
||||||
|
bool anonymous = IsAnonymous(baseName);
|
||||||
|
const TString& blockName = base.getType().getTypeName();
|
||||||
|
|
||||||
|
if (!anonymous)
|
||||||
|
baseName = blockName;
|
||||||
|
else
|
||||||
|
baseName = "";
|
||||||
|
|
||||||
|
blockIndex = addBlockName(blockName, base.getType(), intermediate.getBlockSize(base.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
// Use a degenerate (empty) set of dereferences to immediately put as at the end of
|
// Use a degenerate (empty) set of dereferences to immediately put as at the end of
|
||||||
// the dereference change expected by blowUpActiveAggregate.
|
// the dereference change expected by blowUpActiveAggregate.
|
||||||
TList<TIntermBinary*> derefs;
|
blowUpActiveAggregate(base.getType(), baseName, derefs, derefs.end(), offset, blockIndex, 0, -1, 0,
|
||||||
blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0, 0,
|
base.getQualifier().storage, updateStageMasks);
|
||||||
base.getQualifier().storage, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,9 +172,9 @@ public:
|
|||||||
void getOffsets(const TType& type, TVector<int>& offsets)
|
void getOffsets(const TType& type, TVector<int>& offsets)
|
||||||
{
|
{
|
||||||
const TTypeList& memberList = *type.getStruct();
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
|
||||||
int memberSize = 0;
|
int memberSize = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
for (size_t m = 0; m < offsets.size(); ++m) {
|
for (size_t m = 0; m < offsets.size(); ++m) {
|
||||||
// if the user supplied an offset, snap to it now
|
// if the user supplied an offset, snap to it now
|
||||||
if (memberList[m].type->getQualifier().hasOffset())
|
if (memberList[m].type->getQualifier().hasOffset())
|
||||||
@@ -233,7 +250,7 @@ public:
|
|||||||
// A value of 0 for arraySize will mean to use the full array's size.
|
// A value of 0 for arraySize will mean to use the full array's size.
|
||||||
void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList<TIntermBinary*>& derefs,
|
void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList<TIntermBinary*>& derefs,
|
||||||
TList<TIntermBinary*>::const_iterator deref, int offset, int blockIndex, int arraySize,
|
TList<TIntermBinary*>::const_iterator deref, int offset, int blockIndex, int arraySize,
|
||||||
int topLevelArrayStride, TStorageQualifier baseStorage, bool active)
|
int topLevelArraySize, int topLevelArrayStride, TStorageQualifier baseStorage, bool active)
|
||||||
{
|
{
|
||||||
// when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query.
|
// when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query.
|
||||||
// Broadly:
|
// Broadly:
|
||||||
@@ -262,14 +279,15 @@ public:
|
|||||||
// Visit all the indices of this array, and for each one add on the remaining dereferencing
|
// Visit all the indices of this array, and for each one add on the remaining dereferencing
|
||||||
for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
|
for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
|
||||||
TString newBaseName = name;
|
TString newBaseName = name;
|
||||||
if (strictArraySuffix && blockParent)
|
if (terminalType->getBasicType() == EbtBlock) {}
|
||||||
|
else if (strictArraySuffix && blockParent)
|
||||||
newBaseName.append(TString("[0]"));
|
newBaseName.append(TString("[0]"));
|
||||||
else if (strictArraySuffix || baseType.getBasicType() != EbtBlock)
|
else if (strictArraySuffix || baseType.getBasicType() != EbtBlock)
|
||||||
newBaseName.append(TString("[") + String(i) + "]");
|
newBaseName.append(TString("[") + String(i) + "]");
|
||||||
TList<TIntermBinary*>::const_iterator nextDeref = deref;
|
TList<TIntermBinary*>::const_iterator nextDeref = deref;
|
||||||
++nextDeref;
|
++nextDeref;
|
||||||
blowUpActiveAggregate(*terminalType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize,
|
blowUpActiveAggregate(*terminalType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize,
|
||||||
topLevelArrayStride, baseStorage, active);
|
topLevelArraySize, topLevelArrayStride, baseStorage, active);
|
||||||
|
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
offset += stride;
|
offset += stride;
|
||||||
@@ -282,9 +300,10 @@ public:
|
|||||||
int stride = getArrayStride(baseType, visitNode->getLeft()->getType());
|
int stride = getArrayStride(baseType, visitNode->getLeft()->getType());
|
||||||
|
|
||||||
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
if (strictArraySuffix && blockParent) {
|
if (terminalType->getBasicType() == EbtBlock) {}
|
||||||
|
else if (strictArraySuffix && blockParent)
|
||||||
name.append(TString("[0]"));
|
name.append(TString("[0]"));
|
||||||
} else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) {
|
else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) {
|
||||||
name.append(TString("[") + String(index) + "]");
|
name.append(TString("[") + String(index) + "]");
|
||||||
|
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
@@ -294,7 +313,10 @@ public:
|
|||||||
if (topLevelArrayStride == 0)
|
if (topLevelArrayStride == 0)
|
||||||
topLevelArrayStride = stride;
|
topLevelArrayStride = stride;
|
||||||
|
|
||||||
blockParent = false;
|
// expand top-level arrays in blocks with [0] suffix
|
||||||
|
if (topLevelArrayStride != 0 && visitNode->getLeft()->getType().isArray()) {
|
||||||
|
blockParent = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EOpIndexDirectStruct:
|
case EOpIndexDirectStruct:
|
||||||
@@ -304,6 +326,12 @@ public:
|
|||||||
if (name.size() > 0)
|
if (name.size() > 0)
|
||||||
name.append(".");
|
name.append(".");
|
||||||
name.append((*visitNode->getLeft()->getType().getStruct())[index].type->getFieldName());
|
name.append((*visitNode->getLeft()->getType().getStruct())[index].type->getFieldName());
|
||||||
|
|
||||||
|
// expand non top-level arrays with [x] suffix
|
||||||
|
if (visitNode->getLeft()->getType().getBasicType() != EbtBlock && terminalType->isArray())
|
||||||
|
{
|
||||||
|
blockParent = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -323,24 +351,27 @@ public:
|
|||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
stride = getArrayStride(baseType, *terminalType);
|
stride = getArrayStride(baseType, *terminalType);
|
||||||
|
|
||||||
if (topLevelArrayStride == 0)
|
|
||||||
topLevelArrayStride = stride;
|
|
||||||
|
|
||||||
int arrayIterateSize = std::max(terminalType->getOuterArraySize(), 1);
|
int arrayIterateSize = std::max(terminalType->getOuterArraySize(), 1);
|
||||||
|
|
||||||
// for top-level arrays in blocks, only expand [0] to avoid explosion of items
|
// for top-level arrays in blocks, only expand [0] to avoid explosion of items
|
||||||
if (strictArraySuffix && blockParent)
|
if ((strictArraySuffix && blockParent) ||
|
||||||
|
((topLevelArraySize == arrayIterateSize) && (topLevelArrayStride == 0))) {
|
||||||
arrayIterateSize = 1;
|
arrayIterateSize = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (topLevelArrayStride == 0)
|
||||||
|
topLevelArrayStride = stride;
|
||||||
|
|
||||||
for (int i = 0; i < arrayIterateSize; ++i) {
|
for (int i = 0; i < arrayIterateSize; ++i) {
|
||||||
TString newBaseName = name;
|
TString newBaseName = name;
|
||||||
newBaseName.append(TString("[") + String(i) + "]");
|
if (terminalType->getBasicType() != EbtBlock)
|
||||||
|
newBaseName.append(TString("[") + String(i) + "]");
|
||||||
TType derefType(*terminalType, 0);
|
TType derefType(*terminalType, 0);
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
offset = baseOffset + stride * i;
|
offset = baseOffset + stride * i;
|
||||||
|
|
||||||
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
|
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
|
||||||
topLevelArrayStride, baseStorage, active);
|
topLevelArraySize, topLevelArrayStride, baseStorage, active);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Visit all members of this aggregate, and for each one,
|
// Visit all members of this aggregate, and for each one,
|
||||||
@@ -369,8 +400,31 @@ public:
|
|||||||
arrayStride = getArrayStride(baseType, derefType);
|
arrayStride = getArrayStride(baseType, derefType);
|
||||||
}
|
}
|
||||||
|
|
||||||
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
|
if (topLevelArraySize == -1 && arrayStride == 0 && blockParent)
|
||||||
arrayStride, baseStorage, active);
|
topLevelArraySize = 1;
|
||||||
|
|
||||||
|
if (strictArraySuffix && blockParent) {
|
||||||
|
// if this member is an array, store the top-level array stride but start the explosion from
|
||||||
|
// the inner struct type.
|
||||||
|
if (derefType.isArray() && derefType.isStruct()) {
|
||||||
|
newBaseName.append("[0]");
|
||||||
|
auto dimSize = derefType.isUnsizedArray() ? 0 : derefType.getArraySizes()->getDimSize(0);
|
||||||
|
blowUpActiveAggregate(TType(derefType, 0), newBaseName, derefs, derefs.end(), memberOffsets[i],
|
||||||
|
blockIndex, 0, dimSize, arrayStride, terminalType->getQualifier().storage, false);
|
||||||
|
}
|
||||||
|
else if (derefType.isArray()) {
|
||||||
|
auto dimSize = derefType.isUnsizedArray() ? 0 : derefType.getArraySizes()->getDimSize(0);
|
||||||
|
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), memberOffsets[i], blockIndex,
|
||||||
|
0, dimSize, 0, terminalType->getQualifier().storage, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), memberOffsets[i], blockIndex,
|
||||||
|
0, 1, 0, terminalType->getQualifier().storage, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
|
||||||
|
topLevelArraySize, arrayStride, baseStorage, active);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +460,7 @@ public:
|
|||||||
if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->isAtomic())
|
if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->isAtomic())
|
||||||
reflection.atomicCounterUniformIndices.push_back(uniformIndex);
|
reflection.atomicCounterUniformIndices.push_back(uniformIndex);
|
||||||
|
|
||||||
|
variables.back().topLevelArraySize = topLevelArraySize;
|
||||||
variables.back().topLevelArrayStride = topLevelArrayStride;
|
variables.back().topLevelArrayStride = topLevelArrayStride;
|
||||||
|
|
||||||
if ((reflection.options & EShReflectionAllBlockVariables) && active) {
|
if ((reflection.options & EShReflectionAllBlockVariables) && active) {
|
||||||
@@ -537,65 +592,17 @@ public:
|
|||||||
if (! anonymous)
|
if (! anonymous)
|
||||||
baseName = blockName;
|
baseName = blockName;
|
||||||
|
|
||||||
if (base->getType().isArray()) {
|
blockIndex = addBlockName(blockName, base->getType(), intermediate.getBlockSize(base->getType()));
|
||||||
TType derefType(base->getType(), 0);
|
|
||||||
|
|
||||||
assert(! anonymous);
|
|
||||||
for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e)
|
|
||||||
blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType,
|
|
||||||
intermediate.getBlockSize(base->getType()));
|
|
||||||
baseName.append(TString("[0]"));
|
|
||||||
} else
|
|
||||||
blockIndex = addBlockName(blockName, base->getType(), intermediate.getBlockSize(base->getType()));
|
|
||||||
|
|
||||||
if (reflection.options & EShReflectionAllBlockVariables) {
|
if (reflection.options & EShReflectionAllBlockVariables) {
|
||||||
// Use a degenerate (empty) set of dereferences to immediately put as at the end of
|
// Use a degenerate (empty) set of dereferences to immediately put as at the end of
|
||||||
// the dereference change expected by blowUpActiveAggregate.
|
// the dereference change expected by blowUpActiveAggregate.
|
||||||
TList<TIntermBinary*> derefs;
|
TList<TIntermBinary*> derefs;
|
||||||
|
|
||||||
// because we don't have any derefs, the first thing blowUpActiveAggregate will do is iterate over each
|
// otherwise - if we're not using strict array suffix rules, or this isn't a block so we are
|
||||||
// member in the struct definition. This will lose any information about whether the parent was a buffer
|
// expanding root arrays anyway, just start the iteration from the base block type.
|
||||||
// block. So if we're using strict array rules which don't expand the first child of a buffer block we
|
blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.end(), 0, blockIndex, 0, -1, 0,
|
||||||
// instead iterate over the children here.
|
|
||||||
const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix);
|
|
||||||
bool blockParent = (base->getType().getBasicType() == EbtBlock && base->getQualifier().storage == EvqBuffer);
|
|
||||||
|
|
||||||
if (strictArraySuffix && blockParent) {
|
|
||||||
TType structDerefType(base->getType(), 0);
|
|
||||||
|
|
||||||
const TType &structType = base->getType().isArray() ? structDerefType : base->getType();
|
|
||||||
const TTypeList& typeList = *structType.getStruct();
|
|
||||||
|
|
||||||
TVector<int> memberOffsets;
|
|
||||||
|
|
||||||
memberOffsets.resize(typeList.size());
|
|
||||||
getOffsets(structType, memberOffsets);
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)typeList.size(); ++i) {
|
|
||||||
TType derefType(structType, i);
|
|
||||||
TString name = baseName;
|
|
||||||
if (name.size() > 0)
|
|
||||||
name.append(".");
|
|
||||||
name.append(typeList[i].type->getFieldName());
|
|
||||||
|
|
||||||
// if this member is an array, store the top-level array stride but start the explosion from
|
|
||||||
// the inner struct type.
|
|
||||||
if (derefType.isArray() && derefType.isStruct()) {
|
|
||||||
name.append("[0]");
|
|
||||||
blowUpActiveAggregate(TType(derefType, 0), name, derefs, derefs.end(), memberOffsets[i],
|
|
||||||
blockIndex, 0, getArrayStride(structType, derefType),
|
|
||||||
base->getQualifier().storage, false);
|
|
||||||
} else {
|
|
||||||
blowUpActiveAggregate(derefType, name, derefs, derefs.end(), memberOffsets[i], blockIndex,
|
|
||||||
0, 0, base->getQualifier().storage, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// otherwise - if we're not using strict array suffix rules, or this isn't a block so we are
|
|
||||||
// expanding root arrays anyway, just start the iteration from the base block type.
|
|
||||||
blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.end(), 0, blockIndex, 0, 0,
|
|
||||||
base->getQualifier().storage, false);
|
base->getQualifier().storage, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,30 +633,40 @@ public:
|
|||||||
else
|
else
|
||||||
baseName = base->getName();
|
baseName = base->getName();
|
||||||
}
|
}
|
||||||
blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, 0,
|
blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, -1, 0,
|
||||||
base->getQualifier().storage, true);
|
base->getQualifier().storage, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int addBlockName(const TString& name, const TType& type, int size)
|
int addBlockName(const TString& name, const TType& type, int size)
|
||||||
{
|
{
|
||||||
TReflection::TMapIndexToReflection& blocks = reflection.GetBlockMapForStorage(type.getQualifier().storage);
|
int blockIndex = 0;
|
||||||
|
if (type.isArray()) {
|
||||||
int blockIndex;
|
TType derefType(type, 0);
|
||||||
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
|
for (int e = 0; e < type.getOuterArraySize(); ++e) {
|
||||||
if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) {
|
int memberBlockIndex = addBlockName(name + "[" + String(e) + "]", derefType, size);
|
||||||
blockIndex = (int)blocks.size();
|
if (e == 0)
|
||||||
reflection.nameToIndex[name.c_str()] = blockIndex;
|
blockIndex = memberBlockIndex;
|
||||||
blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1));
|
}
|
||||||
|
|
||||||
blocks.back().numMembers = countAggregateMembers(type);
|
|
||||||
|
|
||||||
EShLanguageMask& stages = blocks.back().stages;
|
|
||||||
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
|
||||||
} else {
|
} else {
|
||||||
blockIndex = it->second;
|
TReflection::TMapIndexToReflection& blocks = reflection.GetBlockMapForStorage(type.getQualifier().storage);
|
||||||
|
|
||||||
EShLanguageMask& stages = blocks[blockIndex].stages;
|
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
|
||||||
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) {
|
||||||
|
blockIndex = (int)blocks.size();
|
||||||
|
reflection.nameToIndex[name.c_str()] = blockIndex;
|
||||||
|
blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, blockIndex));
|
||||||
|
|
||||||
|
blocks.back().numMembers = countAggregateMembers(type);
|
||||||
|
|
||||||
|
EShLanguageMask& stages = blocks.back().stages;
|
||||||
|
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
blockIndex = it->second;
|
||||||
|
|
||||||
|
EShLanguageMask& stages = blocks[blockIndex].stages;
|
||||||
|
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return blockIndex;
|
return blockIndex;
|
||||||
@@ -995,8 +1012,10 @@ public:
|
|||||||
return type.isArray() ? type.getOuterArraySize() : 1;
|
return type.isArray() ? type.getOuterArraySize() : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TIntermediate& intermediate;
|
||||||
TReflection& reflection;
|
TReflection& reflection;
|
||||||
std::set<const TIntermNode*> processedDerefs;
|
std::set<const TIntermNode*> processedDerefs;
|
||||||
|
bool updateStageMasks;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TReflectionTraverser(TReflectionTraverser&);
|
TReflectionTraverser(TReflectionTraverser&);
|
||||||
@@ -1029,7 +1048,21 @@ bool TReflectionTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
|||||||
// To reflect non-dereferenced objects.
|
// To reflect non-dereferenced objects.
|
||||||
void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
|
void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
|
||||||
{
|
{
|
||||||
if (base->getQualifier().storage == EvqUniform)
|
if (base->getQualifier().storage == EvqUniform) {
|
||||||
|
if (base->getBasicType() == EbtBlock) {
|
||||||
|
if (reflection.options & EShReflectionSharedStd140UBO) {
|
||||||
|
addUniform(*base);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addUniform(*base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #TODO add std140/layout active rules for ssbo, same with ubo.
|
||||||
|
// Storage buffer blocks will be collected and expanding in this part.
|
||||||
|
if((reflection.options & EShReflectionSharedStd140SSBO) &&
|
||||||
|
(base->getQualifier().storage == EvqBuffer && base->getBasicType() == EbtBlock &&
|
||||||
|
(base->getQualifier().layoutPacking == ElpStd140 || base->getQualifier().layoutPacking == ElpShared)))
|
||||||
addUniform(*base);
|
addUniform(*base);
|
||||||
|
|
||||||
if ((intermediate.getStage() == reflection.firstStage && base->getQualifier().isPipeInput()) ||
|
if ((intermediate.getStage() == reflection.firstStage && base->getQualifier().isPipeInput()) ||
|
||||||
@@ -1135,15 +1168,47 @@ bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate)
|
|||||||
|
|
||||||
TReflectionTraverser it(intermediate, *this);
|
TReflectionTraverser it(intermediate, *this);
|
||||||
|
|
||||||
// put the entry point on the list of functions to process
|
for (auto& sequnence : intermediate.getTreeRoot()->getAsAggregate()->getSequence()) {
|
||||||
it.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
if (sequnence->getAsAggregate() != nullptr) {
|
||||||
|
if (sequnence->getAsAggregate()->getOp() == glslang::EOpLinkerObjects) {
|
||||||
// process all the functions
|
it.updateStageMasks = false;
|
||||||
while (! it.functions.empty()) {
|
TIntermAggregate* linkerObjects = sequnence->getAsAggregate();
|
||||||
TIntermNode* function = it.functions.back();
|
for (auto& sequnence : linkerObjects->getSequence()) {
|
||||||
it.functions.pop_back();
|
auto pNode = sequnence->getAsSymbolNode();
|
||||||
function->traverse(&it);
|
if (pNode != nullptr) {
|
||||||
|
if ((pNode->getQualifier().storage == EvqUniform &&
|
||||||
|
(options & EShReflectionSharedStd140UBO)) ||
|
||||||
|
(pNode->getQualifier().storage == EvqBuffer &&
|
||||||
|
(options & EShReflectionSharedStd140SSBO))) {
|
||||||
|
// collect std140 and shared uniform block form AST
|
||||||
|
if ((pNode->getBasicType() == EbtBlock) &&
|
||||||
|
((pNode->getQualifier().layoutPacking == ElpStd140) ||
|
||||||
|
(pNode->getQualifier().layoutPacking == ElpShared))) {
|
||||||
|
pNode->traverse(&it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((options & EShReflectionAllIOVariables) &&
|
||||||
|
(pNode->getQualifier().isPipeInput() || pNode->getQualifier().isPipeOutput()))
|
||||||
|
{
|
||||||
|
pNode->traverse(&it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// This traverser will travers all function in AST.
|
||||||
|
// If we want reflect uncalled function, we need set linke message EShMsgKeepUncalled.
|
||||||
|
// When EShMsgKeepUncalled been set to true, all function will be keep in AST, even it is a uncalled function.
|
||||||
|
// This will keep some uniform variables in reflection, if those uniform variables is used in these uncalled function.
|
||||||
|
//
|
||||||
|
// If we just want reflect only live node, we can use a default link message or set EShMsgKeepUncalled false.
|
||||||
|
// When linke message not been set EShMsgKeepUncalled, linker won't keep uncalled function in AST.
|
||||||
|
// So, travers all function node can equivalent to travers live function.
|
||||||
|
it.updateStageMasks = true;
|
||||||
|
sequnence->getAsAggregate()->traverse(&it);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
it.updateStageMasks = true;
|
||||||
|
|
||||||
buildCounterIndices(intermediate);
|
buildCounterIndices(intermediate);
|
||||||
buildUniformStageMask(intermediate);
|
buildUniformStageMask(intermediate);
|
||||||
@@ -1188,7 +1253,7 @@ void TReflection::dump()
|
|||||||
|
|
||||||
for (int dim=0; dim<3; ++dim)
|
for (int dim=0; dim<3; ++dim)
|
||||||
if (getLocalSize(dim) > 1)
|
if (getLocalSize(dim) > 1)
|
||||||
printf("Local size %s: %d\n", axis[dim], getLocalSize(dim));
|
printf("Local size %s: %u\n", axis[dim], getLocalSize(dim));
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
@@ -1201,4 +1266,4 @@ void TReflection::dump()
|
|||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // GLSLANG_WEB
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
#ifndef _REFLECTION_INCLUDED
|
#ifndef _REFLECTION_INCLUDED
|
||||||
#define _REFLECTION_INCLUDED
|
#define _REFLECTION_INCLUDED
|
||||||
@@ -220,4 +220,4 @@ protected:
|
|||||||
|
|
||||||
#endif // _REFLECTION_INCLUDED
|
#endif // _REFLECTION_INCLUDED
|
||||||
|
|
||||||
#endif // GLSLANG_WEB
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ const TBuiltInResource DefaultTBuiltInResource = {
|
|||||||
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
||||||
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
||||||
/* .maxMeshViewCountNV = */ 4,
|
/* .maxMeshViewCountNV = */ 4,
|
||||||
|
/* .maxDualSourceDrawBuffersEXT = */ 1,
|
||||||
|
|
||||||
/* .limits = */ {
|
/* .limits = */ {
|
||||||
/* .nonInductiveForLoops = */ 1,
|
/* .nonInductiveForLoops = */ 1,
|
||||||
@@ -176,7 +177,12 @@ extern "C" {
|
|||||||
* If null, the compilation failed.
|
* If null, the compilation failed.
|
||||||
*/
|
*/
|
||||||
EMSCRIPTEN_KEEPALIVE
|
EMSCRIPTEN_KEEPALIVE
|
||||||
void* convert_glsl_to_spirv(const char* glsl, int stage_int, bool gen_debug, uint32_t** spirv, size_t* spirv_len)
|
void* convert_glsl_to_spirv(const char* glsl,
|
||||||
|
int stage_int,
|
||||||
|
bool gen_debug,
|
||||||
|
glslang::EShTargetLanguageVersion spirv_version,
|
||||||
|
uint32_t** spirv,
|
||||||
|
size_t* spirv_len)
|
||||||
{
|
{
|
||||||
if (glsl == nullptr) {
|
if (glsl == nullptr) {
|
||||||
fprintf(stderr, "Input pointer null\n");
|
fprintf(stderr, "Input pointer null\n");
|
||||||
@@ -194,6 +200,18 @@ void* convert_glsl_to_spirv(const char* glsl, int stage_int, bool gen_debug, uin
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
EShLanguage stage = static_cast<EShLanguage>(stage_int);
|
EShLanguage stage = static_cast<EShLanguage>(stage_int);
|
||||||
|
switch (spirv_version) {
|
||||||
|
case glslang::EShTargetSpv_1_0:
|
||||||
|
case glslang::EShTargetSpv_1_1:
|
||||||
|
case glslang::EShTargetSpv_1_2:
|
||||||
|
case glslang::EShTargetSpv_1_3:
|
||||||
|
case glslang::EShTargetSpv_1_4:
|
||||||
|
case glslang::EShTargetSpv_1_5:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Invalid SPIR-V version number\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
glslang::InitializeProcess();
|
glslang::InitializeProcess();
|
||||||
@@ -203,8 +221,8 @@ void* convert_glsl_to_spirv(const char* glsl, int stage_int, bool gen_debug, uin
|
|||||||
glslang::TShader shader(stage);
|
glslang::TShader shader(stage);
|
||||||
shader.setStrings(&glsl, 1);
|
shader.setStrings(&glsl, 1);
|
||||||
shader.setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, 100);
|
shader.setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, 100);
|
||||||
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1);
|
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0);
|
||||||
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3);
|
shader.setEnvTarget(glslang::EShTargetSpv, spirv_version);
|
||||||
if (!shader.parse(&DefaultTBuiltInResource, 100, true, EShMsgDefault)) {
|
if (!shader.parse(&DefaultTBuiltInResource, 100, true, EShMsgDefault)) {
|
||||||
fprintf(stderr, "Parse failed\n");
|
fprintf(stderr, "Parse failed\n");
|
||||||
fprintf(stderr, "%s\n", shader.getInfoLog());
|
fprintf(stderr, "%s\n", shader.getInfoLog());
|
||||||
@@ -260,7 +278,7 @@ void main() { })";
|
|||||||
uint32_t* output;
|
uint32_t* output;
|
||||||
size_t output_len;
|
size_t output_len;
|
||||||
|
|
||||||
void* id = convert_glsl_to_spirv(input, 4, false, &output, &output_len);
|
void* id = convert_glsl_to_spirv(input, 4, false, glslang::EShTargetSpv_1_0, &output, &output_len);
|
||||||
assert(output != nullptr);
|
assert(output != nullptr);
|
||||||
assert(output_len != 0);
|
assert(output_len != 0);
|
||||||
destroy_output_buffer(id);
|
destroy_output_buffer(id);
|
||||||
|
|||||||
@@ -1,23 +1,34 @@
|
|||||||
Module['compileGLSLZeroCopy'] = function(glsl, shader_stage, gen_debug) {
|
Module['compileGLSLZeroCopy'] = function(glsl, shader_stage, gen_debug, spirv_version) {
|
||||||
gen_debug = !!gen_debug;
|
gen_debug = !!gen_debug;
|
||||||
|
|
||||||
var shader_stage_int;
|
var shader_stage_int; // EShLanguage
|
||||||
if (shader_stage === 'vertex') {
|
switch (shader_stage) {
|
||||||
shader_stage_int = 0;
|
case 'vertex': shader_stage_int = 0; break;
|
||||||
} else if (shader_stage === 'fragment') {
|
case 'fragment': shader_stage_int = 4; break;
|
||||||
shader_stage_int = 4;
|
case 'compute': shader_stage_int = 5; break;
|
||||||
} else if (shader_stage === 'compute') {
|
default:
|
||||||
shader_stage_int = 5;
|
throw new Error("shader_stage must be 'vertex', 'fragment', or 'compute'.");
|
||||||
} else {
|
}
|
||||||
throw new Error("shader_stage must be 'vertex', 'fragment', or 'compute'");
|
|
||||||
|
spirv_version = spirv_version || '1.0';
|
||||||
|
var spirv_version_int; // EShTargetLanguageVersion
|
||||||
|
switch (spirv_version) {
|
||||||
|
case '1.0': spirv_version_int = (1 << 16) | (0 << 8); break;
|
||||||
|
case '1.1': spirv_version_int = (1 << 16) | (1 << 8); break;
|
||||||
|
case '1.2': spirv_version_int = (1 << 16) | (2 << 8); break;
|
||||||
|
case '1.3': spirv_version_int = (1 << 16) | (3 << 8); break;
|
||||||
|
case '1.4': spirv_version_int = (1 << 16) | (4 << 8); break;
|
||||||
|
case '1.5': spirv_version_int = (1 << 16) | (5 << 8); break;
|
||||||
|
default:
|
||||||
|
throw new Error("spirv_version must be '1.0' ~ '1.5'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var p_output = Module['_malloc'](4);
|
var p_output = Module['_malloc'](4);
|
||||||
var p_output_len = Module['_malloc'](4);
|
var p_output_len = Module['_malloc'](4);
|
||||||
var id = ccall('convert_glsl_to_spirv',
|
var id = ccall('convert_glsl_to_spirv',
|
||||||
'number',
|
'number',
|
||||||
['string', 'number', 'boolean', 'number', 'number'],
|
['string', 'number', 'boolean', 'number', 'number', 'number'],
|
||||||
[glsl, shader_stage_int, gen_debug, p_output, p_output_len]);
|
[glsl, shader_stage_int, gen_debug, spirv_version_int, p_output, p_output_len]);
|
||||||
var output = getValue(p_output, 'i32');
|
var output = getValue(p_output, 'i32');
|
||||||
var output_len = getValue(p_output_len, 'i32');
|
var output_len = getValue(p_output_len, 'i32');
|
||||||
Module['_free'](p_output);
|
Module['_free'](p_output);
|
||||||
@@ -37,8 +48,8 @@ Module['compileGLSLZeroCopy'] = function(glsl, shader_stage, gen_debug) {
|
|||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
Module['compileGLSL'] = function(glsl, shader_stage, gen_debug) {
|
Module['compileGLSL'] = function(glsl, shader_stage, gen_debug, spirv_version) {
|
||||||
var compiled = Module['compileGLSLZeroCopy'](glsl, shader_stage, gen_debug);
|
var compiled = Module['compileGLSLZeroCopy'](glsl, shader_stage, gen_debug, spirv_version);
|
||||||
var ret = compiled['data'].slice()
|
var ret = compiled['data'].slice()
|
||||||
compiled['free']();
|
compiled['free']();
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -44,16 +44,25 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define C_DECL __cdecl
|
#define C_DECL __cdecl
|
||||||
//#ifdef SH_EXPORTING
|
|
||||||
// #define SH_IMPORT_EXPORT __declspec(dllexport)
|
|
||||||
//#else
|
|
||||||
// #define SH_IMPORT_EXPORT __declspec(dllimport)
|
|
||||||
//#endif
|
|
||||||
#define SH_IMPORT_EXPORT
|
|
||||||
#else
|
#else
|
||||||
#define SH_IMPORT_EXPORT
|
#define C_DECL
|
||||||
#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
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -65,22 +74,17 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This should always increase, as some paths to do not consume
|
|
||||||
// a more major number.
|
|
||||||
// It should increment by one when new functionality is added.
|
|
||||||
#define GLSLANG_MINOR_VERSION 13
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Call before doing any other compiler/linker operations.
|
// Call before doing any other compiler/linker operations.
|
||||||
//
|
//
|
||||||
// (Call once per process, not once per thread.)
|
// (Call once per process, not once per thread.)
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT int ShInitialize();
|
GLSLANG_EXPORT int ShInitialize();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Call this at process shutdown to clean up memory.
|
// Call this at process shutdown to clean up memory.
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT int ShFinalize();
|
GLSLANG_EXPORT int ShFinalize();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Types of languages the compiler can consume.
|
// Types of languages the compiler can consume.
|
||||||
@@ -92,32 +96,45 @@ typedef enum {
|
|||||||
EShLangGeometry,
|
EShLangGeometry,
|
||||||
EShLangFragment,
|
EShLangFragment,
|
||||||
EShLangCompute,
|
EShLangCompute,
|
||||||
EShLangRayGenNV,
|
EShLangRayGen,
|
||||||
EShLangIntersectNV,
|
EShLangRayGenNV = EShLangRayGen,
|
||||||
EShLangAnyHitNV,
|
EShLangIntersect,
|
||||||
EShLangClosestHitNV,
|
EShLangIntersectNV = EShLangIntersect,
|
||||||
EShLangMissNV,
|
EShLangAnyHit,
|
||||||
EShLangCallableNV,
|
EShLangAnyHitNV = EShLangAnyHit,
|
||||||
|
EShLangClosestHit,
|
||||||
|
EShLangClosestHitNV = EShLangClosestHit,
|
||||||
|
EShLangMiss,
|
||||||
|
EShLangMissNV = EShLangMiss,
|
||||||
|
EShLangCallable,
|
||||||
|
EShLangCallableNV = EShLangCallable,
|
||||||
EShLangTaskNV,
|
EShLangTaskNV,
|
||||||
EShLangMeshNV,
|
EShLangMeshNV,
|
||||||
EShLangCount,
|
LAST_ELEMENT_MARKER(EShLangCount),
|
||||||
} EShLanguage; // would be better as stage, but this is ancient now
|
} EShLanguage; // would be better as stage, but this is ancient now
|
||||||
|
|
||||||
typedef enum {
|
typedef enum : unsigned {
|
||||||
EShLangVertexMask = (1 << EShLangVertex),
|
EShLangVertexMask = (1 << EShLangVertex),
|
||||||
EShLangTessControlMask = (1 << EShLangTessControl),
|
EShLangTessControlMask = (1 << EShLangTessControl),
|
||||||
EShLangTessEvaluationMask = (1 << EShLangTessEvaluation),
|
EShLangTessEvaluationMask = (1 << EShLangTessEvaluation),
|
||||||
EShLangGeometryMask = (1 << EShLangGeometry),
|
EShLangGeometryMask = (1 << EShLangGeometry),
|
||||||
EShLangFragmentMask = (1 << EShLangFragment),
|
EShLangFragmentMask = (1 << EShLangFragment),
|
||||||
EShLangComputeMask = (1 << EShLangCompute),
|
EShLangComputeMask = (1 << EShLangCompute),
|
||||||
EShLangRayGenNVMask = (1 << EShLangRayGenNV),
|
EShLangRayGenMask = (1 << EShLangRayGen),
|
||||||
EShLangIntersectNVMask = (1 << EShLangIntersectNV),
|
EShLangRayGenNVMask = EShLangRayGenMask,
|
||||||
EShLangAnyHitNVMask = (1 << EShLangAnyHitNV),
|
EShLangIntersectMask = (1 << EShLangIntersect),
|
||||||
EShLangClosestHitNVMask = (1 << EShLangClosestHitNV),
|
EShLangIntersectNVMask = EShLangIntersectMask,
|
||||||
EShLangMissNVMask = (1 << EShLangMissNV),
|
EShLangAnyHitMask = (1 << EShLangAnyHit),
|
||||||
EShLangCallableNVMask = (1 << EShLangCallableNV),
|
EShLangAnyHitNVMask = EShLangAnyHitMask,
|
||||||
|
EShLangClosestHitMask = (1 << EShLangClosestHit),
|
||||||
|
EShLangClosestHitNVMask = EShLangClosestHitMask,
|
||||||
|
EShLangMissMask = (1 << EShLangMiss),
|
||||||
|
EShLangMissNVMask = EShLangMissMask,
|
||||||
|
EShLangCallableMask = (1 << EShLangCallable),
|
||||||
|
EShLangCallableNVMask = EShLangCallableMask,
|
||||||
EShLangTaskNVMask = (1 << EShLangTaskNV),
|
EShLangTaskNVMask = (1 << EShLangTaskNV),
|
||||||
EShLangMeshNVMask = (1 << EShLangMeshNV),
|
EShLangMeshNVMask = (1 << EShLangMeshNV),
|
||||||
|
LAST_ELEMENT_MARKER(EShLanguageMaskCount),
|
||||||
} EShLanguageMask;
|
} EShLanguageMask;
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
@@ -128,24 +145,29 @@ typedef enum {
|
|||||||
EShSourceNone,
|
EShSourceNone,
|
||||||
EShSourceGlsl, // GLSL, includes ESSL (OpenGL ES GLSL)
|
EShSourceGlsl, // GLSL, includes ESSL (OpenGL ES GLSL)
|
||||||
EShSourceHlsl, // HLSL
|
EShSourceHlsl, // HLSL
|
||||||
|
LAST_ELEMENT_MARKER(EShSourceCount),
|
||||||
} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead
|
} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShClientNone, // use when there is no client, e.g. for validation
|
EShClientNone, // use when there is no client, e.g. for validation
|
||||||
EShClientVulkan,
|
EShClientVulkan,
|
||||||
EShClientOpenGL,
|
EShClientOpenGL,
|
||||||
|
LAST_ELEMENT_MARKER(EShClientCount),
|
||||||
} EShClient;
|
} EShClient;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShTargetNone,
|
EShTargetNone,
|
||||||
EShTargetSpv, // SPIR-V (preferred spelling)
|
EShTargetSpv, // SPIR-V (preferred spelling)
|
||||||
EshTargetSpv = EShTargetSpv, // legacy spelling
|
EshTargetSpv = EShTargetSpv, // legacy spelling
|
||||||
|
LAST_ELEMENT_MARKER(EShTargetCount),
|
||||||
} EShTargetLanguage;
|
} EShTargetLanguage;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0
|
EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0
|
||||||
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
|
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
|
||||||
|
EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2
|
||||||
EShTargetOpenGL_450 = 450, // OpenGL
|
EShTargetOpenGL_450 = 450, // OpenGL
|
||||||
|
LAST_ELEMENT_MARKER(EShTargetClientVersionCount),
|
||||||
} EShTargetClientVersion;
|
} EShTargetClientVersion;
|
||||||
|
|
||||||
typedef EShTargetClientVersion EshTargetClientVersion;
|
typedef EShTargetClientVersion EshTargetClientVersion;
|
||||||
@@ -157,6 +179,7 @@ typedef enum {
|
|||||||
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
|
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
|
||||||
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
|
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
|
||||||
EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5
|
EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5
|
||||||
|
LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount),
|
||||||
} EShTargetLanguageVersion;
|
} EShTargetLanguageVersion;
|
||||||
|
|
||||||
struct TInputLanguage {
|
struct TInputLanguage {
|
||||||
@@ -186,7 +209,7 @@ struct TEnvironment {
|
|||||||
TTarget target; // what to generate
|
TTarget target; // what to generate
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* StageName(EShLanguage);
|
GLSLANG_EXPORT const char* StageName(EShLanguage);
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
@@ -206,6 +229,7 @@ typedef enum {
|
|||||||
EShOptNone,
|
EShOptNone,
|
||||||
EShOptSimple, // Optimizations that can be done quickly
|
EShOptSimple, // Optimizations that can be done quickly
|
||||||
EShOptFull, // Optimizations that will take more time
|
EShOptFull, // Optimizations that will take more time
|
||||||
|
LAST_ELEMENT_MARKER(EshOptLevelCount),
|
||||||
} EShOptimizationLevel;
|
} EShOptimizationLevel;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -214,12 +238,13 @@ typedef enum {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
EShTexSampTransKeep, // keep textures and samplers as is (default)
|
EShTexSampTransKeep, // keep textures and samplers as is (default)
|
||||||
EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers
|
EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers
|
||||||
|
LAST_ELEMENT_MARKER(EShTexSampTransCount),
|
||||||
} EShTextureSamplerTransformMode;
|
} EShTextureSamplerTransformMode;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Message choices for what errors and warnings are given.
|
// Message choices for what errors and warnings are given.
|
||||||
//
|
//
|
||||||
enum EShMessages {
|
enum EShMessages : unsigned {
|
||||||
EShMsgDefault = 0, // default is to give all required errors and extra warnings
|
EShMsgDefault = 0, // default is to give all required errors and extra warnings
|
||||||
EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input
|
EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input
|
||||||
EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification
|
EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification
|
||||||
@@ -234,21 +259,26 @@ enum EShMessages {
|
|||||||
EShMsgDebugInfo = (1 << 10), // save debug information
|
EShMsgDebugInfo = (1 << 10), // save debug information
|
||||||
EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
|
EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
|
||||||
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
|
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
|
||||||
EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers)
|
EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics)
|
||||||
EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
|
EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
|
||||||
|
LAST_ELEMENT_MARKER(EShMsgCount),
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Options for building reflection
|
// Options for building reflection
|
||||||
//
|
//
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShReflectionDefault = 0, // default is original behaviour before options were added
|
EShReflectionDefault = 0, // default is original behaviour before options were added
|
||||||
EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes
|
EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes
|
||||||
EShReflectionBasicArraySuffix = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection
|
EShReflectionBasicArraySuffix = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection
|
||||||
EShReflectionIntermediateIO = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader
|
EShReflectionIntermediateIO = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader
|
||||||
EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately
|
EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately
|
||||||
EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive
|
EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive
|
||||||
EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks
|
EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks
|
||||||
|
EShReflectionAllIOVariables = (1 << 6), // reflect all input/output variables, even if they are inactive
|
||||||
|
EShReflectionSharedStd140SSBO = (1 << 7), // Apply std140/shared rules for ubo to ssbo
|
||||||
|
EShReflectionSharedStd140UBO = (1 << 8), // Apply std140/shared rules for ubo to ssbo
|
||||||
|
LAST_ELEMENT_MARKER(EShReflectionCount),
|
||||||
} EShReflectionOptions;
|
} EShReflectionOptions;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -280,10 +310,10 @@ typedef void* ShHandle;
|
|||||||
// Driver calls these to create and destroy compiler/linker
|
// Driver calls these to create and destroy compiler/linker
|
||||||
// objects.
|
// objects.
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader
|
GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader
|
||||||
SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair
|
GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair
|
||||||
SH_IMPORT_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object)
|
GLSLANG_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object)
|
||||||
SH_IMPORT_EXPORT void ShDestruct(ShHandle);
|
GLSLANG_EXPORT void ShDestruct(ShHandle);
|
||||||
|
|
||||||
//
|
//
|
||||||
// The return value of ShCompile is boolean, non-zero indicating
|
// The return value of ShCompile is boolean, non-zero indicating
|
||||||
@@ -292,7 +322,7 @@ SH_IMPORT_EXPORT void ShDestruct(ShHandle);
|
|||||||
// The info-log should be written by ShCompile into
|
// The info-log should be written by ShCompile into
|
||||||
// ShHandle, so it can answer future queries.
|
// ShHandle, so it can answer future queries.
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT int ShCompile(
|
GLSLANG_EXPORT int ShCompile(
|
||||||
const ShHandle,
|
const ShHandle,
|
||||||
const char* const shaderStrings[],
|
const char* const shaderStrings[],
|
||||||
const int numStrings,
|
const int numStrings,
|
||||||
@@ -305,7 +335,7 @@ SH_IMPORT_EXPORT int ShCompile(
|
|||||||
EShMessages messages = EShMsgDefault // warnings and errors
|
EShMessages messages = EShMsgDefault // warnings and errors
|
||||||
);
|
);
|
||||||
|
|
||||||
SH_IMPORT_EXPORT int ShLinkExt(
|
GLSLANG_EXPORT int ShLinkExt(
|
||||||
const ShHandle, // linker object
|
const ShHandle, // linker object
|
||||||
const ShHandle h[], // compiler objects to link together
|
const ShHandle h[], // compiler objects to link together
|
||||||
const int numHandles);
|
const int numHandles);
|
||||||
@@ -314,26 +344,26 @@ SH_IMPORT_EXPORT int ShLinkExt(
|
|||||||
// ShSetEncrpytionMethod is a place-holder for specifying
|
// ShSetEncrpytionMethod is a place-holder for specifying
|
||||||
// how source code is encrypted.
|
// how source code is encrypted.
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT void ShSetEncryptionMethod(ShHandle);
|
GLSLANG_EXPORT void ShSetEncryptionMethod(ShHandle);
|
||||||
|
|
||||||
//
|
//
|
||||||
// All the following return 0 if the information is not
|
// All the following return 0 if the information is not
|
||||||
// available in the object passed down, or the object is bad.
|
// available in the object passed down, or the object is bad.
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle);
|
GLSLANG_EXPORT const char* ShGetInfoLog(const ShHandle);
|
||||||
SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle);
|
GLSLANG_EXPORT const void* ShGetExecutable(const ShHandle);
|
||||||
SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing
|
GLSLANG_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing
|
||||||
SH_IMPORT_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings
|
GLSLANG_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings
|
||||||
//
|
//
|
||||||
// Tell the linker to never assign a vertex attribute to this list of physical attributes
|
// Tell the linker to never assign a vertex attribute to this list of physical attributes
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count);
|
GLSLANG_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Returns the location ID of the named uniform.
|
// Returns the location ID of the named uniform.
|
||||||
// Returns -1 if error.
|
// Returns -1 if error.
|
||||||
//
|
//
|
||||||
SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
|
GLSLANG_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // end extern "C"
|
} // end extern "C"
|
||||||
@@ -364,19 +394,27 @@ class TInfoSink;
|
|||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
const char* GetEsslVersionString();
|
struct Version {
|
||||||
const char* GetGlslVersionString();
|
int major;
|
||||||
int GetKhronosToolId();
|
int minor;
|
||||||
|
int patch;
|
||||||
|
const char* flavor;
|
||||||
|
};
|
||||||
|
|
||||||
|
GLSLANG_EXPORT Version GetVersion();
|
||||||
|
GLSLANG_EXPORT const char* GetEsslVersionString();
|
||||||
|
GLSLANG_EXPORT const char* GetGlslVersionString();
|
||||||
|
GLSLANG_EXPORT int GetKhronosToolId();
|
||||||
|
|
||||||
class TIntermediate;
|
class TIntermediate;
|
||||||
class TProgram;
|
class TProgram;
|
||||||
class TPoolAllocator;
|
class TPoolAllocator;
|
||||||
|
|
||||||
// Call this exactly once per process before using anything else
|
// Call this exactly once per process before using anything else
|
||||||
bool InitializeProcess();
|
GLSLANG_EXPORT bool InitializeProcess();
|
||||||
|
|
||||||
// Call once per process to tear down everything
|
// Call once per process to tear down everything
|
||||||
void FinalizeProcess();
|
GLSLANG_EXPORT void FinalizeProcess();
|
||||||
|
|
||||||
// Resource type for IO resolver
|
// Resource type for IO resolver
|
||||||
enum TResourceType {
|
enum TResourceType {
|
||||||
@@ -389,11 +427,14 @@ enum TResourceType {
|
|||||||
EResCount
|
EResCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Make one TShader per shader that you will link into a program. Then
|
// Make one TShader per shader that you will link into a program. Then
|
||||||
// - provide the shader through setStrings() or setStringsWithLengths()
|
// - provide the shader through setStrings() or setStringsWithLengths()
|
||||||
// - optionally call setEnv*(), see below for more detail
|
// - optionally call setEnv*(), see below for more detail
|
||||||
// - optionally use setPreamble() to set a special shader string that will be
|
// - optionally use setPreamble() to set a special shader string that will be
|
||||||
// processed before all others but won't affect the validity of #version
|
// processed before all others but won't affect the validity of #version
|
||||||
|
// - optionally call addProcesses() for each setting/transform,
|
||||||
|
// see comment for class TProcesses
|
||||||
// - call parse(): source language and target environment must be selected
|
// - call parse(): source language and target environment must be selected
|
||||||
// either by correct setting of EShMessages sent to parse(), or by
|
// either by correct setting of EShMessages sent to parse(), or by
|
||||||
// explicitly calling setEnv*()
|
// explicitly calling setEnv*()
|
||||||
@@ -406,40 +447,41 @@ enum TResourceType {
|
|||||||
//
|
//
|
||||||
class TShader {
|
class TShader {
|
||||||
public:
|
public:
|
||||||
explicit TShader(EShLanguage);
|
GLSLANG_EXPORT explicit TShader(EShLanguage);
|
||||||
virtual ~TShader();
|
GLSLANG_EXPORT virtual ~TShader();
|
||||||
void setStrings(const char* const* s, int n);
|
GLSLANG_EXPORT void setStrings(const char* const* s, int n);
|
||||||
void setStringsWithLengths(const char* const* s, const int* l, int n);
|
GLSLANG_EXPORT void setStringsWithLengths(
|
||||||
void setStringsWithLengthsAndNames(
|
const char* const* s, const int* l, int n);
|
||||||
|
GLSLANG_EXPORT void setStringsWithLengthsAndNames(
|
||||||
const char* const* s, const int* l, const char* const* names, int n);
|
const char* const* s, const int* l, const char* const* names, int n);
|
||||||
void setPreamble(const char* s) { preamble = s; }
|
void setPreamble(const char* s) { preamble = s; }
|
||||||
void setEntryPoint(const char* entryPoint);
|
GLSLANG_EXPORT void setEntryPoint(const char* entryPoint);
|
||||||
void setSourceEntryPoint(const char* sourceEntryPointName);
|
GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
|
||||||
void addProcesses(const std::vector<std::string>&);
|
GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
|
||||||
|
|
||||||
// IO resolver binding data: see comments in ShaderLang.cpp
|
// IO resolver binding data: see comments in ShaderLang.cpp
|
||||||
void setShiftBinding(TResourceType res, unsigned int base);
|
GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);
|
||||||
void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
|
GLSLANG_EXPORT void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
|
||||||
void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
GLSLANG_EXPORT void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
|
GLSLANG_EXPORT void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
|
||||||
void setResourceSetBinding(const std::vector<std::string>& base);
|
GLSLANG_EXPORT void setResourceSetBinding(const std::vector<std::string>& base);
|
||||||
void setAutoMapBindings(bool map);
|
GLSLANG_EXPORT void setAutoMapBindings(bool map);
|
||||||
void setAutoMapLocations(bool map);
|
GLSLANG_EXPORT void setAutoMapLocations(bool map);
|
||||||
void addUniformLocationOverride(const char* name, int loc);
|
GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc);
|
||||||
void setUniformLocationBase(int base);
|
GLSLANG_EXPORT void setUniformLocationBase(int base);
|
||||||
void setInvertY(bool invert);
|
GLSLANG_EXPORT void setInvertY(bool invert);
|
||||||
#ifdef ENABLE_HLSL
|
#ifdef ENABLE_HLSL
|
||||||
void setHlslIoMapping(bool hlslIoMap);
|
GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
|
||||||
void setFlattenUniformArrays(bool flatten);
|
GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);
|
||||||
#endif
|
#endif
|
||||||
void setNoStorageFormat(bool useUnknownFormat);
|
GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat);
|
||||||
void setNanMinMaxClamp(bool nanMinMaxClamp);
|
GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp);
|
||||||
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
|
GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
|
||||||
|
|
||||||
// For setting up the environment (cleared to nothingness in the constructor).
|
// 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
|
// These must be called so that parsing is done for the right source language and
|
||||||
@@ -579,8 +621,10 @@ public:
|
|||||||
virtual void releaseInclude(IncludeResult*) override { }
|
virtual void releaseInclude(IncludeResult*) override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
GLSLANG_EXPORT bool parse(
|
||||||
bool forwardCompatible, EShMessages, Includer&);
|
const TBuiltInResource*, int defaultVersion, EProfile defaultProfile,
|
||||||
|
bool forceDefaultVersionAndProfile, bool forwardCompatible,
|
||||||
|
EShMessages, Includer&);
|
||||||
|
|
||||||
bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||||
bool forwardCompatible, EShMessages messages)
|
bool forwardCompatible, EShMessages messages)
|
||||||
@@ -603,13 +647,14 @@ public:
|
|||||||
|
|
||||||
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
|
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
|
||||||
// is not an officially supported or fully working path.
|
// is not an officially supported or fully working path.
|
||||||
bool preprocess(const TBuiltInResource* builtInResources,
|
GLSLANG_EXPORT bool preprocess(
|
||||||
int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
const TBuiltInResource* builtInResources, int defaultVersion,
|
||||||
bool forwardCompatible, EShMessages message, std::string* outputString,
|
EProfile defaultProfile, bool forceDefaultVersionAndProfile,
|
||||||
Includer& includer);
|
bool forwardCompatible, EShMessages message, std::string* outputString,
|
||||||
|
Includer& includer);
|
||||||
|
|
||||||
const char* getInfoLog();
|
GLSLANG_EXPORT const char* getInfoLog();
|
||||||
const char* getInfoDebugLog();
|
GLSLANG_EXPORT const char* getInfoDebugLog();
|
||||||
EShLanguage getStage() const { return stage; }
|
EShLanguage getStage() const { return stage; }
|
||||||
TIntermediate* getIntermediate() const { return intermediate; }
|
TIntermediate* getIntermediate() const { return intermediate; }
|
||||||
|
|
||||||
@@ -628,11 +673,11 @@ protected:
|
|||||||
// stringNames is the optional names for all the strings. If stringNames
|
// stringNames is the optional names for all the strings. If stringNames
|
||||||
// is null, then none of the strings has name. If a certain element in
|
// is null, then none of the strings has name. If a certain element in
|
||||||
// stringNames is null, then the corresponding string does not have name.
|
// stringNames is null, then the corresponding string does not have name.
|
||||||
const char* const* strings;
|
const char* const* strings; // explicit code to compile, see previous comment
|
||||||
const int* lengths;
|
const int* lengths;
|
||||||
const char* const* stringNames;
|
const char* const* stringNames;
|
||||||
const char* preamble;
|
int numStrings; // size of the above arrays
|
||||||
int numStrings;
|
const char* preamble; // string of implicit code to compile before the explicitly provided code
|
||||||
|
|
||||||
// a function in the source string can be renamed FROM this TO the name given in setEntryPoint.
|
// a function in the source string can be renamed FROM this TO the name given in setEntryPoint.
|
||||||
std::string sourceEntryPointName;
|
std::string sourceEntryPointName;
|
||||||
@@ -645,7 +690,7 @@ private:
|
|||||||
TShader& operator=(TShader&);
|
TShader& operator=(TShader&);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
//
|
//
|
||||||
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
|
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
|
||||||
@@ -654,11 +699,11 @@ private:
|
|||||||
// Data needed for just a single object at the granularity exchanged by the reflection API
|
// Data needed for just a single object at the granularity exchanged by the reflection API
|
||||||
class TObjectReflection {
|
class TObjectReflection {
|
||||||
public:
|
public:
|
||||||
TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
|
GLSLANG_EXPORT TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
|
||||||
|
|
||||||
const TType* getType() const { return type; }
|
GLSLANG_EXPORT const TType* getType() const { return type; }
|
||||||
int getBinding() const;
|
GLSLANG_EXPORT int getBinding() const;
|
||||||
void dump() const;
|
GLSLANG_EXPORT void dump() const;
|
||||||
static TObjectReflection badReflection() { return TObjectReflection(); }
|
static TObjectReflection badReflection() { return TObjectReflection(); }
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -669,6 +714,7 @@ public:
|
|||||||
int counterIndex;
|
int counterIndex;
|
||||||
int numMembers;
|
int numMembers;
|
||||||
int arrayStride; // stride of an array variable
|
int arrayStride; // stride of an array variable
|
||||||
|
int topLevelArraySize; // size of the top-level variable in a storage buffer member
|
||||||
int topLevelArrayStride; // stride of the top-level variable in a storage buffer member
|
int topLevelArrayStride; // stride of the top-level variable in a storage buffer member
|
||||||
EShLanguageMask stages;
|
EShLanguageMask stages;
|
||||||
|
|
||||||
@@ -762,7 +808,7 @@ public:
|
|||||||
virtual void addStage(EShLanguage stage) = 0;
|
virtual void addStage(EShLanguage stage) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GLSLANG_WEB
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|
||||||
// Make one TProgram per set of shaders that will get linked together. Add all
|
// 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()
|
// the shaders that are to be linked together. After calling shader.parse()
|
||||||
@@ -772,40 +818,40 @@ public:
|
|||||||
//
|
//
|
||||||
class TProgram {
|
class TProgram {
|
||||||
public:
|
public:
|
||||||
TProgram();
|
GLSLANG_EXPORT TProgram();
|
||||||
virtual ~TProgram();
|
GLSLANG_EXPORT virtual ~TProgram();
|
||||||
void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
|
void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
|
||||||
std::list<TShader*>& getShaders(EShLanguage stage) { return stages[stage]; }
|
std::list<TShader*>& getShaders(EShLanguage stage) { return stages[stage]; }
|
||||||
// Link Validation interface
|
// Link Validation interface
|
||||||
bool link(EShMessages);
|
GLSLANG_EXPORT bool link(EShMessages);
|
||||||
const char* getInfoLog();
|
GLSLANG_EXPORT const char* getInfoLog();
|
||||||
const char* getInfoDebugLog();
|
GLSLANG_EXPORT const char* getInfoDebugLog();
|
||||||
|
|
||||||
TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
|
TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
|
|
||||||
// Reflection Interface
|
// Reflection Interface
|
||||||
|
|
||||||
// call first, to do liveness analysis, index mapping, etc.; returns false on failure
|
// call first, to do liveness analysis, index mapping, etc.; returns false on failure
|
||||||
bool buildReflection(int opts = EShReflectionDefault);
|
GLSLANG_EXPORT bool buildReflection(int opts = EShReflectionDefault);
|
||||||
unsigned getLocalSize(int dim) const; // return dim'th local size
|
GLSLANG_EXPORT unsigned getLocalSize(int dim) const; // return dim'th local size
|
||||||
int getReflectionIndex(const char *name) const;
|
GLSLANG_EXPORT int getReflectionIndex(const char *name) const;
|
||||||
int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const;
|
GLSLANG_EXPORT int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const;
|
||||||
int getNumUniformVariables() const;
|
GLSLANG_EXPORT int getNumUniformVariables() const;
|
||||||
const TObjectReflection& getUniform(int index) const;
|
GLSLANG_EXPORT const TObjectReflection& getUniform(int index) const;
|
||||||
int getNumUniformBlocks() const;
|
GLSLANG_EXPORT int getNumUniformBlocks() const;
|
||||||
const TObjectReflection& getUniformBlock(int index) const;
|
GLSLANG_EXPORT const TObjectReflection& getUniformBlock(int index) const;
|
||||||
int getNumPipeInputs() const;
|
GLSLANG_EXPORT int getNumPipeInputs() const;
|
||||||
const TObjectReflection& getPipeInput(int index) const;
|
GLSLANG_EXPORT const TObjectReflection& getPipeInput(int index) const;
|
||||||
int getNumPipeOutputs() const;
|
GLSLANG_EXPORT int getNumPipeOutputs() const;
|
||||||
const TObjectReflection& getPipeOutput(int index) const;
|
GLSLANG_EXPORT const TObjectReflection& getPipeOutput(int index) const;
|
||||||
int getNumBufferVariables() const;
|
GLSLANG_EXPORT int getNumBufferVariables() const;
|
||||||
const TObjectReflection& getBufferVariable(int index) const;
|
GLSLANG_EXPORT const TObjectReflection& getBufferVariable(int index) const;
|
||||||
int getNumBufferBlocks() const;
|
GLSLANG_EXPORT int getNumBufferBlocks() const;
|
||||||
const TObjectReflection& getBufferBlock(int index) const;
|
GLSLANG_EXPORT const TObjectReflection& getBufferBlock(int index) const;
|
||||||
int getNumAtomicCounters() const;
|
GLSLANG_EXPORT int getNumAtomicCounters() const;
|
||||||
const TObjectReflection& getAtomicCounter(int index) const;
|
GLSLANG_EXPORT const TObjectReflection& getAtomicCounter(int index) const;
|
||||||
|
|
||||||
// Legacy Reflection Interface - expressed in terms of above interface
|
// Legacy Reflection Interface - expressed in terms of above interface
|
||||||
|
|
||||||
@@ -872,22 +918,22 @@ public:
|
|||||||
// returns a TType*
|
// returns a TType*
|
||||||
const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); }
|
const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); }
|
||||||
|
|
||||||
void dumpReflection();
|
GLSLANG_EXPORT void dumpReflection();
|
||||||
// I/O mapping: apply base offsets and map live unbound variables
|
// I/O mapping: apply base offsets and map live unbound variables
|
||||||
// If resolver is not provided it uses the previous approach
|
// If resolver is not provided it uses the previous approach
|
||||||
// and respects auto assignment and offsets.
|
// and respects auto assignment and offsets.
|
||||||
bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr);
|
GLSLANG_EXPORT bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr);
|
||||||
#endif
|
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool linkStage(EShLanguage, EShMessages);
|
GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages);
|
||||||
|
|
||||||
TPoolAllocator* pool;
|
TPoolAllocator* pool;
|
||||||
std::list<TShader*> stages[EShLangCount];
|
std::list<TShader*> stages[EShLangCount];
|
||||||
TIntermediate* intermediate[EShLangCount];
|
TIntermediate* intermediate[EShLangCount];
|
||||||
bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage
|
bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage
|
||||||
TInfoSink* infoSink;
|
TInfoSink* infoSink;
|
||||||
#ifndef GLSLANG_WEB
|
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||||
TReflection* reflection;
|
TReflection* reflection;
|
||||||
#endif
|
#endif
|
||||||
bool linked;
|
bool linked;
|
||||||
|
|||||||
+31
-4
@@ -1,5 +1,5 @@
|
|||||||
|
// Copyright (C) 2020 The Khronos Group Inc.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2018 The Khronos Group Inc.
|
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
// disclaimer in the documentation and/or other materials provided
|
// disclaimer in the documentation and/or other materials provided
|
||||||
// with the distribution.
|
// with the distribution.
|
||||||
//
|
//
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
// Neither the name of The Khronos Group Inc. nor the names of its
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
@@ -30,6 +30,33 @@
|
|||||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
|
||||||
|
|
||||||
#include "pch.h"
|
#ifndef GLSLANG_BUILD_INFO
|
||||||
|
#define GLSLANG_BUILD_INFO
|
||||||
|
|
||||||
|
#define GLSLANG_VERSION_MAJOR 11
|
||||||
|
#define GLSLANG_VERSION_MINOR 0
|
||||||
|
#define GLSLANG_VERSION_PATCH 0
|
||||||
|
#define GLSLANG_VERSION_FLAVOR ""
|
||||||
|
|
||||||
|
#define GLSLANG_VERSION_GREATER_THAN(major, minor, patch) \
|
||||||
|
(((major) > GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \
|
||||||
|
(((minor) > GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \
|
||||||
|
((patch) > GLSLANG_VERSION_PATCH)))))
|
||||||
|
|
||||||
|
#define GLSLANG_VERSION_GREATER_OR_EQUAL_TO(major, minor, patch) \
|
||||||
|
(((major) > GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \
|
||||||
|
(((minor) > GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \
|
||||||
|
((patch) >= GLSLANG_VERSION_PATCH)))))
|
||||||
|
|
||||||
|
#define GLSLANG_VERSION_LESS_THAN(major, minor, patch) \
|
||||||
|
(((major) < GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \
|
||||||
|
(((minor) < GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \
|
||||||
|
((patch) < GLSLANG_VERSION_PATCH)))))
|
||||||
|
|
||||||
|
#define GLSLANG_VERSION_LESS_OR_EQUAL_TO(major, minor, patch) \
|
||||||
|
(((major) < GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \
|
||||||
|
(((minor) < GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \
|
||||||
|
((patch) <= GLSLANG_VERSION_PATCH)))))
|
||||||
|
|
||||||
|
#endif // GLSLANG_BUILD_INFO
|
||||||
@@ -118,6 +118,7 @@ static const TBuiltInResource defaultTBuiltInResource = {
|
|||||||
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
||||||
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
||||||
/* .maxMeshViewCountNV = */ 4,
|
/* .maxMeshViewCountNV = */ 4,
|
||||||
|
/* .maxDualSourceDrawBuffersEXT = */ 1,
|
||||||
/* .limits = */ {
|
/* .limits = */ {
|
||||||
/* .nonInductiveForLoops = */ 1,
|
/* .nonInductiveForLoops = */ 1,
|
||||||
/* .whileLoops = */ 1,
|
/* .whileLoops = */ 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user