Merge pull request #52933 from akien-mga/vulkan-1.2.190

This commit is contained in:
Rémi Verschelde 2021-09-22 13:47:52 +02:00 committed by GitHub
commit b7ad29d574
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 25415 additions and 13361 deletions

View file

@ -13,46 +13,47 @@ if env["builtin_glslang"]:
thirdparty_dir = "#thirdparty/glslang/" thirdparty_dir = "#thirdparty/glslang/"
thirdparty_sources = [ thirdparty_sources = [
"glslang/CInterface/glslang_c_interface.cpp", "glslang/CInterface/glslang_c_interface.cpp",
"glslang/MachineIndependent/RemoveTree.cpp",
"glslang/MachineIndependent/ParseHelper.cpp",
"glslang/MachineIndependent/iomapper.cpp",
"glslang/MachineIndependent/propagateNoContraction.cpp",
"glslang/MachineIndependent/Intermediate.cpp",
"glslang/MachineIndependent/linkValidate.cpp",
"glslang/MachineIndependent/attribute.cpp", "glslang/MachineIndependent/attribute.cpp",
"glslang/MachineIndependent/Scan.cpp",
"glslang/MachineIndependent/Initialize.cpp",
"glslang/MachineIndependent/Constant.cpp", "glslang/MachineIndependent/Constant.cpp",
"glslang/MachineIndependent/reflection.cpp", "glslang/MachineIndependent/glslang_tab.cpp",
"glslang/MachineIndependent/InfoSink.cpp",
"glslang/MachineIndependent/Initialize.cpp",
"glslang/MachineIndependent/Intermediate.cpp",
"glslang/MachineIndependent/intermOut.cpp",
"glslang/MachineIndependent/IntermTraverse.cpp",
"glslang/MachineIndependent/iomapper.cpp",
"glslang/MachineIndependent/limits.cpp", "glslang/MachineIndependent/limits.cpp",
"glslang/MachineIndependent/preprocessor/PpScanner.cpp", "glslang/MachineIndependent/linkValidate.cpp",
"glslang/MachineIndependent/preprocessor/PpTokens.cpp", "glslang/MachineIndependent/parseConst.cpp",
"glslang/MachineIndependent/ParseContextBase.cpp",
"glslang/MachineIndependent/ParseHelper.cpp",
"glslang/MachineIndependent/PoolAlloc.cpp",
"glslang/MachineIndependent/preprocessor/PpAtom.cpp", "glslang/MachineIndependent/preprocessor/PpAtom.cpp",
"glslang/MachineIndependent/preprocessor/PpContext.cpp", "glslang/MachineIndependent/preprocessor/PpContext.cpp",
"glslang/MachineIndependent/preprocessor/Pp.cpp", "glslang/MachineIndependent/preprocessor/Pp.cpp",
"glslang/MachineIndependent/InfoSink.cpp", "glslang/MachineIndependent/preprocessor/PpScanner.cpp",
"glslang/MachineIndependent/intermOut.cpp", "glslang/MachineIndependent/preprocessor/PpTokens.cpp",
"glslang/MachineIndependent/SymbolTable.cpp", "glslang/MachineIndependent/propagateNoContraction.cpp",
"glslang/MachineIndependent/glslang_tab.cpp", "glslang/MachineIndependent/reflection.cpp",
"glslang/MachineIndependent/Versions.cpp", "glslang/MachineIndependent/RemoveTree.cpp",
"glslang/MachineIndependent/Scan.cpp",
"glslang/MachineIndependent/ShaderLang.cpp", "glslang/MachineIndependent/ShaderLang.cpp",
"glslang/MachineIndependent/parseConst.cpp", "glslang/MachineIndependent/SpirvIntrinsics.cpp",
"glslang/MachineIndependent/PoolAlloc.cpp", "glslang/MachineIndependent/SymbolTable.cpp",
"glslang/MachineIndependent/ParseContextBase.cpp", "glslang/MachineIndependent/Versions.cpp",
"glslang/MachineIndependent/IntermTraverse.cpp",
"glslang/GenericCodeGen/Link.cpp",
"glslang/GenericCodeGen/CodeGen.cpp", "glslang/GenericCodeGen/CodeGen.cpp",
"glslang/GenericCodeGen/Link.cpp",
"OGLCompilersDLL/InitializeDll.cpp", "OGLCompilersDLL/InitializeDll.cpp",
"SPIRV/CInterface/spirv_c_interface.cpp", "SPIRV/CInterface/spirv_c_interface.cpp",
"SPIRV/InReadableOrder.cpp",
"SPIRV/GlslangToSpv.cpp",
"SPIRV/SpvBuilder.cpp",
"SPIRV/SpvTools.cpp",
"SPIRV/disassemble.cpp", "SPIRV/disassemble.cpp",
"SPIRV/doc.cpp", "SPIRV/doc.cpp",
"SPIRV/SPVRemapper.cpp", "SPIRV/GlslangToSpv.cpp",
"SPIRV/SpvPostProcess.cpp", "SPIRV/InReadableOrder.cpp",
"SPIRV/Logger.cpp", "SPIRV/Logger.cpp",
"SPIRV/SpvBuilder.cpp",
"SPIRV/SpvPostProcess.cpp",
"SPIRV/SPVRemapper.cpp",
"SPIRV/SpvTools.cpp",
"StandAlone/ResourceLimits.cpp", "StandAlone/ResourceLimits.cpp",
] ]

26
thirdparty/README.md vendored
View file

@ -159,7 +159,7 @@ Files extracted from upstream source:
## glslang ## glslang
- Upstream: https://github.com/KhronosGroup/glslang - Upstream: https://github.com/KhronosGroup/glslang
- Version: git (dd69df7f3dac26362e10b0f38efb9e47990f7537, 2020) - Version: 11.6.0 (2fb89a0072ae7316af1c856f22663fde4928128a, 2021)
- License: glslang - License: glslang
Version should be kept in sync with the one of the used Vulkan SDK (see `vulkan` Version should be kept in sync with the one of the used Vulkan SDK (see `vulkan`
@ -173,7 +173,7 @@ Files extracted from upstream source:
- Run `cmake . && make` and copy generated `include/glslang/build_info.h` - Run `cmake . && make` and copy generated `include/glslang/build_info.h`
to `glslang/build_info.h` to `glslang/build_info.h`
- `LICENSE.txt` - `LICENSE.txt`
- Unnecessary files like `CMakeLists.txt` and `updateGrammar` removed. - Unnecessary files like `CMakeLists.txt`, `*.m4` and `updateGrammar` removed.
## graphite ## graphite
@ -611,9 +611,12 @@ Godot. Please check the file to know what's new.
## spirv-reflect ## spirv-reflect
- Upstream: https://github.com/KhronosGroup/SPIRV-Reflect - Upstream: https://github.com/KhronosGroup/SPIRV-Reflect
- Version: git (272e050728de8d4a4ce9e7101c1244e6ff56e5b0, 2021) - Version: git (cc937caab141d889c9c9dff572c5a6854d5cf9b4, 2021)
- License: Apache 2.0 - License: Apache 2.0
Does not track Vulkan SDK releases closely, but try to package a commit newer
than the matching glslang and Vulkan headers, just in case.
Files extracted from upstream source: Files extracted from upstream source:
- `spirv_reflect.{c,h}` - `spirv_reflect.{c,h}`
@ -672,10 +675,16 @@ folder.
## volk ## volk
- Upstream: https://github.com/zeux/volk - Upstream: https://github.com/zeux/volk
- Version: git (d75c007f375f35612dba3de512ac73f10bf9aa0e, 2021) - Version: 1.2.190 (760a782f295a66de7391d6ed573d65e3fb1c8450, 2021)
- License: MIT - License: MIT
The volk commit should match the version of the Vulkan headers defined below. Unless there is a specific reason to package a more recent version, please stick
to tagged releases. All Vulkan libraries and headers should be kept in sync so:
- Update Vulkan SDK components to the matching tag (see "vulkan").
- Update glslang (see "glslang").
- Update spirv-reflect (see "spirv-reflect").
Files extracted from upstream source: Files extracted from upstream source:
@ -686,11 +695,10 @@ Files extracted from upstream source:
## vulkan ## vulkan
- Upstream: https://github.com/KhronosGroup/Vulkan-Headers - Upstream: https://github.com/KhronosGroup/Vulkan-Headers
- Version: sdk-1.2.182.0 (37164a5726f7e6113810f9557903a117498421cf, 2021) - Version: 1.2.190 (9e62d027636cd7210f60d934f56107ed6e1579b8, 2021)
- License: Apache 2.0 - License: Apache 2.0
Unless there is a specific reason to package a more recent version, please stick The vendored version should be kept in sync with volk, see above.
to Vulkan SDK releases (prefixed by `sdk-`) for all components.
Files extracted from upstream source: Files extracted from upstream source:
@ -701,7 +709,7 @@ Files extracted from upstream source:
SDK release: https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/layers/generated/vk_enum_string_helper.h SDK release: https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/layers/generated/vk_enum_string_helper.h
`vk_mem_alloc.h` is taken from https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator `vk_mem_alloc.h` is taken from https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
Version: 3.0.0-development (2021-06-21), branch `feature-small-buffers`, commit `cfea2f72851f9ee4a399769f18865047b83711f1` Version: 3.0.0-development (2021-07-07), branch `feature-small-buffers`, commit `cfea2f72851f9ee4a399769f18865047b83711f1`
`vk_mem_alloc.cpp` is a Godot file and should be preserved on updates. `vk_mem_alloc.cpp` is a Godot file and should be preserved on updates.
Patches in the `patches` directory should be re-applied after updates. Patches in the `patches` directory should be re-applied after updates.

View file

@ -36,6 +36,8 @@ static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fu
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"; static const char* const E_SPV_EXT_shader_atomic_float_add = "SPV_EXT_shader_atomic_float_add";
static const char* const E_SPV_EXT_shader_atomic_float16_add = "SPV_EXT_shader_atomic_float16_add";
static const char* const E_SPV_EXT_shader_atomic_float_min_max = "SPV_EXT_shader_atomic_float_min_max";
static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64"; static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64";
#endif // #ifndef GLSLextEXT_H #endif // #ifndef GLSLextEXT_H

View file

@ -50,5 +50,7 @@ static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_t
static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query"; static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query";
static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragment_shading_rate"; static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragment_shading_rate";
static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation"; static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation";
static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
#endif // #ifndef GLSLextKHR_H #endif // #ifndef GLSLextKHR_H

View file

@ -69,6 +69,9 @@ const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
//SPV_NV_raytracing //SPV_NV_raytracing
const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing"; const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
//SPV_NV_ray_tracing_motion_blur
const char* const E_SPV_NV_ray_tracing_motion_blur = "SPV_NV_ray_tracing_motion_blur";
//SPV_NV_shading_rate //SPV_NV_shading_rate
const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate"; const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate";

View file

@ -160,6 +160,7 @@ protected:
spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const; spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const;
spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, std::vector<unsigned int>& operands) const; spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, std::vector<unsigned int>& operands) const;
spv::StorageClass TranslateStorageClass(const glslang::TType&); spv::StorageClass TranslateStorageClass(const glslang::TType&);
void TranslateLiterals(const glslang::TVector<const glslang::TIntermConstantUnion*>&, std::vector<unsigned>&) const;
void addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType); void addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType);
spv::Id createSpvVariable(const glslang::TIntermSymbol*, spv::Id forcedType); spv::Id createSpvVariable(const glslang::TIntermSymbol*, spv::Id forcedType);
spv::Id getSampledType(const glslang::TSampler&); spv::Id getSampledType(const glslang::TSampler&);
@ -178,6 +179,7 @@ protected:
spv::Id accessChainLoad(const glslang::TType& type); spv::Id accessChainLoad(const glslang::TType& type);
void accessChainStore(const glslang::TType& type, spv::Id rvalue); void accessChainStore(const glslang::TType& type, spv::Id rvalue);
void multiTypeStore(const glslang::TType&, spv::Id rValue); void multiTypeStore(const glslang::TType&, spv::Id rValue);
spv::Id convertLoadedBoolInUniformToUint(const glslang::TType& type, spv::Id nominalTypeId, spv::Id loadedId);
glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const; glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix); int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix); int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
@ -255,17 +257,17 @@ protected:
bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp
spv::Id stdBuiltins; spv::Id stdBuiltins;
spv::Id nonSemanticDebugPrintf; spv::Id nonSemanticDebugPrintf;
std::unordered_map<const char*, spv::Id> extBuiltinMap; std::unordered_map<std::string, spv::Id> extBuiltinMap;
std::unordered_map<int, spv::Id> symbolValues; std::unordered_map<long long, spv::Id> symbolValues;
std::unordered_set<int> rValueParameters; // set of formal function parameters passed as rValues, std::unordered_set<long long> rValueParameters; // set of formal function parameters passed as rValues,
// rather than a pointer // rather than a pointer
std::unordered_map<std::string, spv::Function*> functionMap; std::unordered_map<std::string, spv::Function*> functionMap;
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount]; std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
// for mapping glslang block indices to spv indices (e.g., due to hidden members): // for mapping glslang block indices to spv indices (e.g., due to hidden members):
std::unordered_map<int, std::vector<int>> memberRemapper; std::unordered_map<long long, std::vector<int>> memberRemapper;
// for mapping glslang symbol struct to symbol Id // for mapping glslang symbol struct to symbol Id
std::unordered_map<const glslang::TTypeList*, int> glslangTypeToIdMap; std::unordered_map<const glslang::TTypeList*, long long> glslangTypeToIdMap;
std::stack<bool> breakForLoop; // false means break for switch std::stack<bool> breakForLoop; // false means break for switch
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator; std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
// Map pointee types for EbtReference to their forward pointers // Map pointee types for EbtReference to their forward pointers
@ -380,6 +382,7 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock; case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock;
case glslang::EvqVaryingIn: return spv::DecorationBlock; case glslang::EvqVaryingIn: return spv::DecorationBlock;
case glslang::EvqVaryingOut: return spv::DecorationBlock; case glslang::EvqVaryingOut: return spv::DecorationBlock;
case glslang::EvqShared: return spv::DecorationBlock;
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
case glslang::EvqPayload: return spv::DecorationBlock; case glslang::EvqPayload: return spv::DecorationBlock;
case glslang::EvqPayloadIn: return spv::DecorationBlock; case glslang::EvqPayloadIn: return spv::DecorationBlock;
@ -436,6 +439,7 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T
break; break;
case glslang::EbtBlock: case glslang::EbtBlock:
switch (type.getQualifier().storage) { switch (type.getQualifier().storage) {
case glslang::EvqShared:
case glslang::EvqUniform: case glslang::EvqUniform:
case glslang::EvqBuffer: case glslang::EvqBuffer:
switch (type.getQualifier().layoutPacking) { switch (type.getQualifier().layoutPacking) {
@ -1029,6 +1033,10 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
return spv::BuiltInIncomingRayFlagsKHR; return spv::BuiltInIncomingRayFlagsKHR;
case glslang::EbvGeometryIndex: case glslang::EbvGeometryIndex:
return spv::BuiltInRayGeometryIndexKHR; return spv::BuiltInRayGeometryIndexKHR;
case glslang::EbvCurrentRayTimeNV:
builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
return spv::BuiltInCurrentRayTimeNV;
// barycentrics // barycentrics
case glslang::EbvBaryCoordNV: case glslang::EbvBaryCoordNV:
@ -1247,6 +1255,10 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
{ {
if (type.getBasicType() == glslang::EbtRayQuery) if (type.getBasicType() == glslang::EbtRayQuery)
return spv::StorageClassPrivate; return spv::StorageClassPrivate;
#ifndef GLSLANG_WEB
if (type.getQualifier().isSpirvByReference())
return spv::StorageClassFunction;
#endif
if (type.getQualifier().isPipeInput()) if (type.getQualifier().isPipeInput())
return spv::StorageClassInput; return spv::StorageClassInput;
if (type.getQualifier().isPipeOutput()) if (type.getQualifier().isPipeOutput())
@ -1278,6 +1290,12 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
return spv::StorageClassUniformConstant; return spv::StorageClassUniformConstant;
} }
if (type.getQualifier().storage == glslang::EvqShared && type.getBasicType() == glslang::EbtBlock) {
builder.addExtension(spv::E_SPV_KHR_workgroup_memory_explicit_layout);
builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR);
return spv::StorageClassWorkgroup;
}
switch (type.getQualifier().storage) { switch (type.getQualifier().storage) {
case glslang::EvqGlobal: return spv::StorageClassPrivate; case glslang::EvqGlobal: return spv::StorageClassPrivate;
case glslang::EvqConstReadOnly: return spv::StorageClassFunction; case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
@ -1289,6 +1307,7 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
case glslang::EvqHitAttr: return spv::StorageClassHitAttributeKHR; case glslang::EvqHitAttr: return spv::StorageClassHitAttributeKHR;
case glslang::EvqCallableData: return spv::StorageClassCallableDataKHR; case glslang::EvqCallableData: return spv::StorageClassCallableDataKHR;
case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR; case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR;
case glslang::EvqSpirvStorageClass: return static_cast<spv::StorageClass>(type.getQualifier().spirvStorageClass);
#endif #endif
default: default:
assert(0); assert(0);
@ -1298,6 +1317,52 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
return spv::StorageClassFunction; return spv::StorageClassFunction;
} }
// Translate glslang constants to SPIR-V literals
void TGlslangToSpvTraverser::TranslateLiterals(const glslang::TVector<const glslang::TIntermConstantUnion*>& constants,
std::vector<unsigned>& literals) const
{
for (auto constant : constants) {
if (constant->getBasicType() == glslang::EbtFloat) {
float floatValue = static_cast<float>(constant->getConstArray()[0].getDConst());
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
literals.push_back(literal);
} else if (constant->getBasicType() == glslang::EbtInt) {
unsigned literal = constant->getConstArray()[0].getIConst();
literals.push_back(literal);
} else if (constant->getBasicType() == glslang::EbtUint) {
unsigned literal = constant->getConstArray()[0].getUConst();
literals.push_back(literal);
} else if (constant->getBasicType() == glslang::EbtBool) {
unsigned literal = constant->getConstArray()[0].getBConst();
literals.push_back(literal);
} else if (constant->getBasicType() == glslang::EbtString) {
auto str = constant->getConstArray()[0].getSConst()->c_str();
unsigned literal = 0;
char* literalPtr = reinterpret_cast<char*>(&literal);
unsigned charCount = 0;
char ch = 0;
do {
ch = *(str++);
*(literalPtr++) = ch;
++charCount;
if (charCount == 4) {
literals.push_back(literal);
literalPtr = reinterpret_cast<char*>(&literal);
charCount = 0;
}
} while (ch != 0);
// Partial literal is padded with 0
if (charCount > 0) {
for (; charCount < 4; ++charCount)
*(literalPtr++) = 0;
literals.push_back(literal);
}
} else
assert(0); // Unexpected type
}
}
// Add capabilities pertaining to how an array is indexed. // Add capabilities pertaining to how an array is indexed.
void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType, void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType,
const glslang::TType& indexType) const glslang::TType& indexType)
@ -1485,7 +1550,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
if (glslangIntermediate->usingPhysicalStorageBuffer()) { if (glslangIntermediate->usingPhysicalStorageBuffer()) {
addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT; addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT;
builder.addIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer, spv::Spv_1_5); builder.addIncorporatedExtension(spv::E_SPV_KHR_physical_storage_buffer, spv::Spv_1_5);
builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT); builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT);
} }
if (glslangIntermediate->usingVulkanMemoryModel()) { if (glslangIntermediate->usingVulkanMemoryModel()) {
@ -1518,6 +1583,13 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR); builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR);
} }
#ifndef GLSLANG_WEB
if (glslangIntermediate->getSubgroupUniformControlFlow()) {
builder.addExtension(spv::E_SPV_KHR_subgroup_uniform_control_flow);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeSubgroupUniformControlFlowKHR);
}
#endif
unsigned int mode; unsigned int mode;
switch (glslangIntermediate->getStage()) { switch (glslangIntermediate->getStage()) {
case EShLangVertex: case EShLangVertex:
@ -1543,15 +1615,16 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
builder.addExtension(spv::E_SPV_KHR_post_depth_coverage); builder.addExtension(spv::E_SPV_KHR_post_depth_coverage);
} }
if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing()) if (glslangIntermediate->isDepthReplacing())
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing); builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
switch(glslangIntermediate->getDepth()) { switch(glslangIntermediate->getDepth()) {
case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break; case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break;
case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break; case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break;
default: mode = spv::ExecutionModeMax; break; case glslang::EldUnchanged: mode = spv::ExecutionModeDepthUnchanged; break;
default: mode = spv::ExecutionModeMax; break;
} }
if (mode != spv::ExecutionModeMax) if (mode != spv::ExecutionModeMax)
builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
@ -1719,6 +1792,53 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
default: default:
break; break;
} }
#ifndef GLSLANG_WEB
//
// Add SPIR-V requirements (GL_EXT_spirv_intrinsics)
//
if (glslangIntermediate->hasSpirvRequirement()) {
const glslang::TSpirvRequirement& spirvRequirement = glslangIntermediate->getSpirvRequirement();
// Add SPIR-V extension requirement
for (auto& extension : spirvRequirement.extensions)
builder.addExtension(extension.c_str());
// Add SPIR-V capability requirement
for (auto capability : spirvRequirement.capabilities)
builder.addCapability(static_cast<spv::Capability>(capability));
}
//
// Add SPIR-V execution mode qualifiers (GL_EXT_spirv_intrinsics)
//
if (glslangIntermediate->hasSpirvExecutionMode()) {
const glslang::TSpirvExecutionMode spirvExecutionMode = glslangIntermediate->getSpirvExecutionMode();
// Add spirv_execution_mode
for (auto& mode : spirvExecutionMode.modes) {
if (!mode.second.empty()) {
std::vector<unsigned> literals;
TranslateLiterals(mode.second, literals);
builder.addExecutionMode(shaderEntry, static_cast<spv::ExecutionMode>(mode.first), literals);
} else
builder.addExecutionMode(shaderEntry, static_cast<spv::ExecutionMode>(mode.first));
}
// Add spirv_execution_mode_id
for (auto& modeId : spirvExecutionMode.modeIds) {
std::vector<spv::Id> operandIds;
assert(!modeId.second.empty());
for (auto extraOperand : modeId.second) {
int nextConst = 0;
spv::Id operandId = createSpvConstantFromConstUnionArray(
extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
operandIds.push_back(operandId);
}
builder.addExecutionModeId(shaderEntry, static_cast<spv::ExecutionMode>(modeId.first), operandIds);
}
}
#endif
} }
// Finish creating SPV, after the traversal is complete. // Finish creating SPV, after the traversal is complete.
@ -1986,7 +2106,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
{ {
// This may be, e.g., an anonymous block-member selection, which generally need // This may be, e.g., an anonymous block-member selection, which generally need
// index remapping due to hidden members in anonymous blocks. // index remapping due to hidden members in anonymous blocks.
int glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()]; long long glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()];
if (memberRemapper.find(glslangId) != memberRemapper.end()) { if (memberRemapper.find(glslangId) != memberRemapper.end()) {
std::vector<int>& remapper = memberRemapper[glslangId]; std::vector<int>& remapper = memberRemapper[glslangId];
assert(remapper.size() > 0); assert(remapper.size() > 0);
@ -2116,6 +2236,49 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
} }
} }
spv::Id TGlslangToSpvTraverser::convertLoadedBoolInUniformToUint(const glslang::TType& type,
spv::Id nominalTypeId,
spv::Id loadedId)
{
if (builder.isScalarType(nominalTypeId)) {
// Conversion for bool
spv::Id boolType = builder.makeBoolType();
if (nominalTypeId != boolType)
return builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0));
} else if (builder.isVectorType(nominalTypeId)) {
// Conversion for bvec
int vecSize = builder.getNumTypeComponents(nominalTypeId);
spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
if (nominalTypeId != bvecType)
loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
makeSmearedConstant(builder.makeUintConstant(0), vecSize));
} else if (builder.isArrayType(nominalTypeId)) {
// Conversion for bool array
spv::Id boolArrayTypeId = convertGlslangToSpvType(type);
if (nominalTypeId != boolArrayTypeId)
{
// Use OpCopyLogical from SPIR-V 1.4 if available.
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4)
return builder.createUnaryOp(spv::OpCopyLogical, boolArrayTypeId, loadedId);
glslang::TType glslangElementType(type, 0);
spv::Id elementNominalTypeId = builder.getContainedTypeId(nominalTypeId);
std::vector<spv::Id> constituents;
for (int index = 0; index < type.getOuterArraySize(); ++index) {
// get the element
spv::Id elementValue = builder.createCompositeExtract(loadedId, elementNominalTypeId, index);
// recursively convert it
spv::Id elementConvertedValue = convertLoadedBoolInUniformToUint(glslangElementType, elementNominalTypeId, elementValue);
constituents.push_back(elementConvertedValue);
}
return builder.createCompositeConstruct(boolArrayTypeId, constituents);
}
}
return loadedId;
}
// Figure out what, if any, type changes are needed when accessing a specific built-in. // Figure out what, if any, type changes are needed when accessing a specific built-in.
// Returns <the type SPIR-V requires for declarion, the type to translate to on use>. // Returns <the type SPIR-V requires for declarion, the type to translate to on use>.
// Also see comment for 'forceType', regarding tracking SPIR-V-required types. // Also see comment for 'forceType', regarding tracking SPIR-V-required types.
@ -2292,7 +2455,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
if (node->getOp() == glslang::EOpAtomicCounterIncrement || if (node->getOp() == glslang::EOpAtomicCounterIncrement ||
node->getOp() == glslang::EOpAtomicCounterDecrement || node->getOp() == glslang::EOpAtomicCounterDecrement ||
node->getOp() == glslang::EOpAtomicCounter || node->getOp() == glslang::EOpAtomicCounter ||
node->getOp() == glslang::EOpInterpolateAtCentroid || (node->getOp() == glslang::EOpInterpolateAtCentroid &&
glslangIntermediate->getSource() != glslang::EShSourceHlsl) ||
node->getOp() == glslang::EOpRayQueryProceed || node->getOp() == glslang::EOpRayQueryProceed ||
node->getOp() == glslang::EOpRayQueryGetRayTMin || node->getOp() == glslang::EOpRayQueryGetRayTMin ||
node->getOp() == glslang::EOpRayQueryGetRayFlags || node->getOp() == glslang::EOpRayQueryGetRayFlags ||
@ -2300,10 +2464,14 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
node->getOp() == glslang::EOpRayQueryGetWorldRayDirection || node->getOp() == glslang::EOpRayQueryGetWorldRayDirection ||
node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque || node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque ||
node->getOp() == glslang::EOpRayQueryTerminate || node->getOp() == glslang::EOpRayQueryTerminate ||
node->getOp() == glslang::EOpRayQueryConfirmIntersection) { node->getOp() == glslang::EOpRayQueryConfirmIntersection ||
(node->getOp() == glslang::EOpSpirvInst && operandNode->getAsTyped()->getQualifier().isSpirvByReference())) {
operand = builder.accessChainGetLValue(); // Special case l-value operands operand = builder.accessChainGetLValue(); // Special case l-value operands
lvalueCoherentFlags = builder.getAccessChain().coherentFlags; lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType()); lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType());
} else if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
// Will be translated to a literal value, make a placeholder here
operand = spv::NoResult;
} else } else
#endif #endif
{ {
@ -2324,6 +2492,38 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, result = createUnaryOperation(node->getOp(), decorations, resultType(), operand,
node->getOperand()->getBasicType(), lvalueCoherentFlags); node->getOperand()->getBasicType(), lvalueCoherentFlags);
#ifndef GLSLANG_WEB
// it could be attached to a SPIR-V intruction
if (!result) {
if (node->getOp() == glslang::EOpSpirvInst) {
const auto& spirvInst = node->getSpirvInstruction();
if (spirvInst.set == "") {
spv::IdImmediate idImmOp = {true, operand};
if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
// Translate the constant to a literal value
std::vector<unsigned> literals;
glslang::TVector<const glslang::TIntermConstantUnion*> constants;
constants.push_back(operandNode->getAsConstantUnion());
TranslateLiterals(constants, literals);
idImmOp = {false, literals[0]};
}
if (node->getBasicType() == glslang::EbtVoid)
builder.createNoResultOp(static_cast<spv::Op>(spirvInst.id), {idImmOp});
else
result = builder.createOp(static_cast<spv::Op>(spirvInst.id), resultType(), {idImmOp});
} else {
result = builder.createBuiltinCall(
resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()),
spirvInst.id, {operand});
}
if (node->getBasicType() == glslang::EbtVoid)
return false; // done with this node
}
}
#endif
if (result) { if (result) {
if (invertedType) { if (invertedType) {
result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result); result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result);
@ -2775,6 +2975,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
break; break;
case glslang::EOpAtomicAdd: case glslang::EOpAtomicAdd:
case glslang::EOpAtomicSubtract:
case glslang::EOpAtomicMin: case glslang::EOpAtomicMin:
case glslang::EOpAtomicMax: case glslang::EOpAtomicMax:
case glslang::EOpAtomicAnd: case glslang::EOpAtomicAnd:
@ -2821,6 +3022,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
case glslang::EOpIgnoreIntersectionNV: case glslang::EOpIgnoreIntersectionNV:
case glslang::EOpTerminateRayNV: case glslang::EOpTerminateRayNV:
case glslang::EOpTraceNV: case glslang::EOpTraceNV:
case glslang::EOpTraceRayMotionNV:
case glslang::EOpTraceKHR: case glslang::EOpTraceKHR:
case glslang::EOpExecuteCallableNV: case glslang::EOpExecuteCallableNV:
case glslang::EOpExecuteCallableKHR: case glslang::EOpExecuteCallableKHR:
@ -2946,6 +3148,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
break; break;
case glslang::EOpAtomicAdd: case glslang::EOpAtomicAdd:
case glslang::EOpAtomicSubtract:
case glslang::EOpAtomicMin: case glslang::EOpAtomicMin:
case glslang::EOpAtomicMax: case glslang::EOpAtomicMax:
case glslang::EOpAtomicAnd: case glslang::EOpAtomicAnd:
@ -2966,7 +3169,13 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
case glslang::EOpInterpolateAtOffset: case glslang::EOpInterpolateAtOffset:
case glslang::EOpInterpolateAtVertex: case glslang::EOpInterpolateAtVertex:
if (arg == 0) { if (arg == 0) {
lvalue = true; // If GLSL, use the address of the interpolant argument.
// If HLSL, use an internal version of OpInterolates that takes
// the rvalue of the interpolant. A fixup pass in spirv-opt
// legalization will remove the OpLoad and convert to an lvalue.
// Had to do this because legalization will only propagate a
// builtin into an rvalue.
lvalue = glslangIntermediate->getSource() != glslang::EShSourceHlsl;
// Does it need a swizzle inversion? If so, evaluation is inverted; // Does it need a swizzle inversion? If so, evaluation is inverted;
// operate first on the swizzle base, then apply the swizzle. // operate first on the swizzle base, then apply the swizzle.
@ -3012,6 +3221,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
if (arg == 1) if (arg == 1)
lvalue = true; lvalue = true;
break; break;
case glslang::EOpSpirvInst:
if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvByReference())
lvalue = true;
break;
#endif #endif
default: default:
break; break;
@ -3109,15 +3322,22 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst(); bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst();
operands.push_back(builder.makeIntConstant(cond ? 1 : 0)); operands.push_back(builder.makeIntConstant(cond ? 1 : 0));
} else if ((arg == 10 && glslangOp == glslang::EOpTraceKHR) || } else if ((arg == 10 && glslangOp == glslang::EOpTraceKHR) ||
(arg == 11 && glslangOp == glslang::EOpTraceRayMotionNV) ||
(arg == 1 && glslangOp == glslang::EOpExecuteCallableKHR)) { (arg == 1 && glslangOp == glslang::EOpExecuteCallableKHR)) {
const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : 1; const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : (glslangOp == glslang::EOpTraceRayMotionNV ? 11 : 1);
const int set = glslangOp == glslang::EOpTraceKHR ? 0 : 1; const int set = glslangOp == glslang::EOpExecuteCallableKHR ? 1 : 0;
const int location = glslangOperands[opdNum]->getAsConstantUnion()->getConstArray()[0].getUConst(); const int location = glslangOperands[opdNum]->getAsConstantUnion()->getConstArray()[0].getUConst();
auto itNode = locationToSymbol[set].find(location); auto itNode = locationToSymbol[set].find(location);
visitSymbol(itNode->second); visitSymbol(itNode->second);
spv::Id symId = getSymbolId(itNode->second); spv::Id symId = getSymbolId(itNode->second);
operands.push_back(symId); operands.push_back(symId);
} else { #ifndef GLSLANG_WEB
} else if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvLiteral()) {
// Will be translated to a literal value, make a placeholder here
operands.push_back(spv::NoResult);
#endif
} else {
operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType())); operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
} }
} }
@ -3155,8 +3375,38 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
#endif #endif
if (atomic) { if (atomic) {
// Handle all atomics // Handle all atomics
result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), glslang::TBasicType typeProxy = (node->getOp() == glslang::EOpAtomicStore)
? node->getSequence()[0]->getAsTyped()->getBasicType() : node->getBasicType();
result = createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy,
lvalueCoherentFlags); lvalueCoherentFlags);
#ifndef GLSLANG_WEB
} else if (node->getOp() == glslang::EOpSpirvInst) {
const auto& spirvInst = node->getSpirvInstruction();
if (spirvInst.set == "") {
std::vector<spv::IdImmediate> idImmOps;
for (int i = 0; i < glslangOperands.size(); ++i) {
if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) {
// Translate the constant to a literal value
std::vector<unsigned> literals;
glslang::TVector<const glslang::TIntermConstantUnion*> constants;
constants.push_back(glslangOperands[i]->getAsConstantUnion());
TranslateLiterals(constants, literals);
idImmOps.push_back({false, literals[0]});
} else
idImmOps.push_back({true, operands[i]});
}
if (node->getBasicType() == glslang::EbtVoid)
builder.createNoResultOp(static_cast<spv::Op>(spirvInst.id), idImmOps);
else
result = builder.createOp(static_cast<spv::Op>(spirvInst.id), resultType(), idImmOps);
} else {
result = builder.createBuiltinCall(
resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()),
spirvInst.id, operands);
}
noReturnValue = node->getBasicType() == glslang::EbtVoid;
#endif
} else if (node->getOp() == glslang::EOpDebugPrintf) { } else if (node->getOp() == glslang::EOpDebugPrintf) {
if (!nonSemanticDebugPrintf) { if (!nonSemanticDebugPrintf) {
nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf"); nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf");
@ -3437,6 +3687,11 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node) void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node)
{ {
#ifndef GLSLANG_WEB
if (node->getQualifier().isSpirvLiteral())
return; // Translated to a literal value, skip further processing
#endif
int nextConst = 0; int nextConst = 0;
spv::Id constant = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(), nextConst, false); spv::Id constant = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(), nextConst, false);
@ -3623,6 +3878,11 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
break; break;
#endif #endif
default: default:
if (storageClass == spv::StorageClassWorkgroup &&
node->getType().getBasicType() == glslang::EbtBlock) {
builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR);
break;
}
if (node->getType().contains16BitFloat()) if (node->getType().contains16BitFloat())
builder.addCapability(spv::CapabilityFloat16); builder.addCapability(spv::CapabilityFloat16);
if (node->getType().contains16BitInt()) if (node->getType().contains16BitInt())
@ -3641,6 +3901,9 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
} else if (storageClass == spv::StorageClassStorageBuffer) { } else if (storageClass == spv::StorageClassStorageBuffer) {
builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5); builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
builder.addCapability(spv::CapabilityStorageBuffer8BitAccess); builder.addCapability(spv::CapabilityStorageBuffer8BitAccess);
} else if (storageClass == spv::StorageClassWorkgroup &&
node->getType().getBasicType() == glslang::EbtBlock) {
builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR);
} else { } else {
builder.addCapability(spv::CapabilityInt8); builder.addCapability(spv::CapabilityInt8);
} }
@ -3652,13 +3915,14 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
spv::Id initializer = spv::NoResult; spv::Id initializer = spv::NoResult;
if (node->getType().getQualifier().storage == glslang::EvqUniform && if (node->getType().getQualifier().storage == glslang::EvqUniform && !node->getConstArray().empty()) {
!node->getConstArray().empty()) { int nextConst = 0;
int nextConst = 0; initializer = createSpvConstantFromConstUnionArray(node->getType(),
initializer = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(),
node->getConstArray(), nextConst,
nextConst, false /* specConst */);
false /* specConst */); } else if (node->getType().getQualifier().isNullInit()) {
initializer = builder.makeNullConstant(spvType);
} }
return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer); return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer);
@ -3876,6 +4140,77 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
case glslang::EbtString: case glslang::EbtString:
// no type used for OpString // no type used for OpString
return 0; return 0;
#ifndef GLSLANG_WEB
case glslang::EbtSpirvType: {
// GL_EXT_spirv_intrinsics
const auto& spirvType = type.getSpirvType();
const auto& spirvInst = spirvType.spirvInst;
std::vector<spv::Id> operands;
for (const auto& typeParam : spirvType.typeParams) {
if (typeParam.isConstant) {
// Constant expression
if (typeParam.constant->isLiteral()) {
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
unsigned literal = 0;
char* literalPtr = reinterpret_cast<char*>(&literal);
unsigned charCount = 0;
char ch = 0;
do {
ch = *(str++);
*(literalPtr++) = ch;
++charCount;
if (charCount == 4) {
operands.push_back(literal);
literalPtr = reinterpret_cast<char*>(&literal);
charCount = 0;
}
} while (ch != 0);
// Partial literal is padded with 0
if (charCount > 0) {
for (; charCount < 4; ++charCount)
*(literalPtr++) = 0;
operands.push_back(literal);
}
} else
assert(0); // Unexpected type
} else {
int nextConst = 0;
spv::Id constant = createSpvConstantFromConstUnionArray(
typeParam.constant->getType(), typeParam.constant->getConstArray(), nextConst, false);
operands.push_back(constant);
}
} else {
// Type specifier
spv::Id typeId = convertGlslangToSpvType(*typeParam.type);
operands.push_back(typeId);
}
}
if (spirvInst.set == "")
spvType = builder.createOp(static_cast<spv::Op>(spirvInst.id), spv::NoType, operands);
else {
spvType = builder.createBuiltinCall(
spv::NoType, getExtBuiltins(spirvInst.set.c_str()), spirvInst.id, operands);
}
break;
}
#endif
default: default:
assert(0); assert(0);
break; break;
@ -4072,7 +4407,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
{ {
// Name and decorate the non-hidden members // Name and decorate the non-hidden members
int offset = -1; int offset = -1;
int locationOffset = 0; // for use within the members of this struct
bool memberLocationInvalid = type.isArrayOfArrays() || bool memberLocationInvalid = type.isArrayOfArrays() ||
(type.isArray() && (type.getQualifier().isArrayedIo(glslangIntermediate->getStage()) == false)); (type.isArray() && (type.getQualifier().isArrayedIo(glslangIntermediate->getStage()) == false));
for (int i = 0; i < (int)glslangMembers->size(); i++) { for (int i = 0; i < (int)glslangMembers->size(); i++) {
@ -4130,10 +4464,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
if (!memberLocationInvalid && memberQualifier.hasLocation()) if (!memberLocationInvalid && memberQualifier.hasLocation())
builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation); builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
if (qualifier.hasLocation()) // track for upcoming inheritance
locationOffset += glslangIntermediate->computeTypeLocationSize(
glslangMember, glslangIntermediate->getStage());
// component, XFB, others // component, XFB, others
if (glslangMember.getQualifier().hasComponent()) if (glslangMember.getQualifier().hasComponent())
builder.addMemberDecoration(spvType, member, spv::DecorationComponent, builder.addMemberDecoration(spvType, member, spv::DecorationComponent,
@ -4189,6 +4519,38 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV); builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough); builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
} }
//
// Add SPIR-V decorations for members (GL_EXT_spirv_intrinsics)
//
if (glslangMember.getQualifier().hasSprivDecorate()) {
const glslang::TSpirvDecorate& spirvDecorate = glslangMember.getQualifier().getSpirvDecorate();
// Add spirv_decorate
for (auto& decorate : spirvDecorate.decorates) {
if (!decorate.second.empty()) {
std::vector<unsigned> literals;
TranslateLiterals(decorate.second, literals);
builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first), literals);
}
else
builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first));
}
// spirv_decorate_id not applied to members
assert(spirvDecorate.decorateIds.empty());
// Add spirv_decorate_string
for (auto& decorateString : spirvDecorate.decorateStrings) {
std::vector<const char*> strings;
assert(!decorateString.second.empty());
for (auto extraOperand : decorateString.second) {
const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
strings.push_back(string);
}
builder.addDecoration(spvType, static_cast<spv::Decoration>(decorateString.first), strings);
}
}
#endif #endif
} }
@ -4207,6 +4569,8 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra
glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim); glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim);
if (specNode != nullptr) { if (specNode != nullptr) {
builder.clearAccessChain(); builder.clearAccessChain();
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
specNode->traverse(this); specNode->traverse(this);
return accessChainLoad(specNode->getAsTyped()->getType()); return accessChainLoad(specNode->getAsTyped()->getType());
} }
@ -4242,19 +4606,7 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
// Need to convert to abstract types when necessary // Need to convert to abstract types when necessary
if (type.getBasicType() == glslang::EbtBool) { if (type.getBasicType() == glslang::EbtBool) {
if (builder.isScalarType(nominalTypeId)) { loadedId = convertLoadedBoolInUniformToUint(type, nominalTypeId, loadedId);
// Conversion for bool
spv::Id boolType = builder.makeBoolType();
if (nominalTypeId != boolType)
loadedId = builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0));
} else if (builder.isVectorType(nominalTypeId)) {
// Conversion for bvec
int vecSize = builder.getNumTypeComponents(nominalTypeId);
spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
if (nominalTypeId != bvecType)
loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
makeSmearedConstant(builder.makeUintConstant(0), vecSize));
}
} }
return loadedId; return loadedId;
@ -4406,6 +4758,7 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang:
// has to be a uniform or buffer block or task in/out blocks // has to be a uniform or buffer block or task in/out blocks
if (type.getQualifier().storage != glslang::EvqUniform && if (type.getQualifier().storage != glslang::EvqUniform &&
type.getQualifier().storage != glslang::EvqBuffer && type.getQualifier().storage != glslang::EvqBuffer &&
type.getQualifier().storage != glslang::EvqShared &&
!type.getQualifier().isTaskMemory()) !type.getQualifier().isTaskMemory())
return glslang::ElpNone; return glslang::ElpNone;
@ -4575,6 +4928,9 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
if (glslangIntermediate->getSource() == glslang::EShSourceHlsl) if (glslangIntermediate->getSource() == glslang::EShSourceHlsl)
return paramType.getBasicType() == glslang::EbtBlock; return paramType.getBasicType() == glslang::EbtBlock;
return paramType.containsOpaque() || // sampler, etc. return paramType.containsOpaque() || // sampler, etc.
#ifndef GLSLANG_WEB
paramType.getQualifier().isSpirvByReference() || // spirv_by_reference
#endif
(paramType.getBasicType() == glslang::EbtBlock && qualifier == glslang::EvqBuffer); // SSBO (paramType.getBasicType() == glslang::EbtBlock && qualifier == glslang::EvqBuffer); // SSBO
} }
@ -4968,7 +5324,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
int components = node->getType().getVectorSize(); int components = node->getType().getVectorSize();
if (node->getOp() == glslang::EOpTextureFetch) { if (node->getOp() == glslang::EOpImageLoad ||
node->getOp() == glslang::EOpImageLoadLod ||
node->getOp() == glslang::EOpTextureFetch ||
node->getOp() == glslang::EOpTextureFetchOffset) {
// These must produce 4 components, per SPIR-V spec. We'll add a conversion constructor if needed. // These must produce 4 components, per SPIR-V spec. We'll add a conversion constructor if needed.
// This will only happen through the HLSL path for operator[], so we do not have to handle e.g. // This will only happen through the HLSL path for operator[], so we do not have to handle e.g.
// the EOpTexture/Proj/Lod/etc family. It would be harmless to do so, but would need more logic // the EOpTexture/Proj/Lod/etc family. It would be harmless to do so, but would need more logic
@ -5530,7 +5889,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
++lValueCount; ++lValueCount;
} else { } else {
// process r-value, which involves a copy for a type mismatch // process r-value, which involves a copy for a type mismatch
if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a]) || if (function->getParamType(a) != builder.getTypeId(rValues[rValueCount]) ||
TranslatePrecisionDecoration(*argTypes[a]) != function->getParamPrecision(a)) TranslatePrecisionDecoration(*argTypes[a]) != function->getParamPrecision(a))
{ {
spv::Id argCopy = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, function->getParamType(a), "arg"); spv::Id argCopy = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, function->getParamType(a), "arg");
@ -6813,9 +7172,6 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
break; break;
case glslang::EOpConvPtrToUvec2: case glslang::EOpConvPtrToUvec2:
case glslang::EOpConvUvec2ToPtr: case glslang::EOpConvUvec2ToPtr:
if (builder.isVector(operand))
builder.promoteIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer,
spv::E_SPV_KHR_physical_storage_buffer, spv::Spv_1_5);
convOp = spv::OpBitcast; convOp = spv::OpBitcast;
break; break;
#endif #endif
@ -6864,29 +7220,58 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
case glslang::EOpImageAtomicAdd: case glslang::EOpImageAtomicAdd:
case glslang::EOpAtomicCounterAdd: case glslang::EOpAtomicCounterAdd:
opCode = spv::OpAtomicIAdd; opCode = spv::OpAtomicIAdd;
if (typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) { if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
opCode = spv::OpAtomicFAddEXT; opCode = spv::OpAtomicFAddEXT;
builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add); builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add);
if (typeProxy == glslang::EbtFloat) if (typeProxy == glslang::EbtFloat16) {
builder.addExtension(spv::E_SPV_EXT_shader_atomic_float16_add);
builder.addCapability(spv::CapabilityAtomicFloat16AddEXT);
} else if (typeProxy == glslang::EbtFloat) {
builder.addCapability(spv::CapabilityAtomicFloat32AddEXT); builder.addCapability(spv::CapabilityAtomicFloat32AddEXT);
else } else {
builder.addCapability(spv::CapabilityAtomicFloat64AddEXT); builder.addCapability(spv::CapabilityAtomicFloat64AddEXT);
}
} }
break; break;
case glslang::EOpAtomicSubtract:
case glslang::EOpAtomicCounterSubtract: case glslang::EOpAtomicCounterSubtract:
opCode = spv::OpAtomicISub; opCode = spv::OpAtomicISub;
break; break;
case glslang::EOpAtomicMin: case glslang::EOpAtomicMin:
case glslang::EOpImageAtomicMin: case glslang::EOpImageAtomicMin:
case glslang::EOpAtomicCounterMin: case glslang::EOpAtomicCounterMin:
opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
spv::OpAtomicUMin : spv::OpAtomicSMin; opCode = spv::OpAtomicFMinEXT;
builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
if (typeProxy == glslang::EbtFloat16)
builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
else if (typeProxy == glslang::EbtFloat)
builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
else
builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
} else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) {
opCode = spv::OpAtomicUMin;
} else {
opCode = spv::OpAtomicSMin;
}
break; break;
case glslang::EOpAtomicMax: case glslang::EOpAtomicMax:
case glslang::EOpImageAtomicMax: case glslang::EOpImageAtomicMax:
case glslang::EOpAtomicCounterMax: case glslang::EOpAtomicCounterMax:
opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
spv::OpAtomicUMax : spv::OpAtomicSMax; opCode = spv::OpAtomicFMaxEXT;
builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
if (typeProxy == glslang::EbtFloat16)
builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
else if (typeProxy == glslang::EbtFloat)
builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
else
builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
} else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) {
opCode = spv::OpAtomicUMax;
} else {
opCode = spv::OpAtomicSMax;
}
break; break;
case glslang::EOpAtomicAnd: case glslang::EOpAtomicAnd:
case glslang::EOpImageAtomicAnd: case glslang::EOpImageAtomicAnd:
@ -6995,6 +7380,10 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
} }
if (builder.getConstantScalar(scopeId) == spv::ScopeQueueFamily) {
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
}
if (glslangIntermediate->usingVulkanMemoryModel() && builder.getConstantScalar(scopeId) == spv::ScopeDevice) { if (glslangIntermediate->usingVulkanMemoryModel() && builder.getConstantScalar(scopeId) == spv::ScopeDevice) {
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
} }
@ -7940,6 +8329,11 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
case glslang::EOpTraceNV: case glslang::EOpTraceNV:
builder.createNoResultOp(spv::OpTraceNV, operands); builder.createNoResultOp(spv::OpTraceNV, operands);
return 0; return 0;
case glslang::EOpTraceRayMotionNV:
builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
builder.createNoResultOp(spv::OpTraceRayMotionNV, operands);
return 0;
case glslang::EOpTraceKHR: case glslang::EOpTraceKHR:
builder.createNoResultOp(spv::OpTraceRayKHR, operands); builder.createNoResultOp(spv::OpTraceRayKHR, operands);
return 0; return 0;
@ -7991,7 +8385,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
opCode = spv::OpRayQueryGetIntersectionInstanceIdKHR; opCode = spv::OpRayQueryGetIntersectionInstanceIdKHR;
break; break;
case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
typeId = builder.makeIntType(32); typeId = builder.makeUintType(32);
opCode = spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR; opCode = spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR;
break; break;
case glslang::EOpRayQueryGetIntersectionGeometryIndex: case glslang::EOpRayQueryGetIntersectionGeometryIndex:
@ -8424,6 +8818,48 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addDecoration(id, symbol->getType().getQualifier().restrict ? builder.addDecoration(id, symbol->getType().getQualifier().restrict ?
spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
} }
//
// Add SPIR-V decorations for structure (GL_EXT_spirv_intrinsics)
//
if (symbol->getType().getQualifier().hasSprivDecorate()) {
const glslang::TSpirvDecorate& spirvDecorate = symbol->getType().getQualifier().getSpirvDecorate();
// Add spirv_decorate
for (auto& decorate : spirvDecorate.decorates) {
if (!decorate.second.empty()) {
std::vector<unsigned> literals;
TranslateLiterals(decorate.second, literals);
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
}
else
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first));
}
// Add spirv_decorate_id
for (auto& decorateId : spirvDecorate.decorateIds) {
std::vector<spv::Id> operandIds;
assert(!decorateId.second.empty());
for (auto extraOperand : decorateId.second) {
int nextConst = 0;
spv::Id operandId = createSpvConstantFromConstUnionArray(
extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
operandIds.push_back(operandId);
}
builder.addDecoration(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
}
// Add spirv_decorate_string
for (auto& decorateString : spirvDecorate.decorateStrings) {
std::vector<const char*> strings;
assert(!decorateString.second.empty());
for (auto extraOperand : decorateString.second) {
const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
strings.push_back(string);
}
builder.addDecoration(id, static_cast<spv::Decoration>(decorateString.first), strings);
}
}
#endif #endif
return id; return id;

View file

@ -544,6 +544,9 @@ namespace spv {
// Extended instructions: currently, assume everything is an ID. // Extended instructions: currently, assume everything is an ID.
// TODO: add whatever data we need for exceptions to that // TODO: add whatever data we need for exceptions to that
if (opCode == spv::OpExtInst) { if (opCode == spv::OpExtInst) {
idFn(asId(word)); // Instruction set is an ID that also needs to be mapped
word += 2; // instruction set, and instruction from set word += 2; // instruction set, and instruction from set
numOperands -= 2; numOperands -= 2;

View file

@ -743,6 +743,26 @@ Id Builder::getContainedTypeId(Id typeId, int member) const
} }
} }
// Figure out the final resulting type of the access chain.
Id Builder::getResultingAccessChainType() const
{
assert(accessChain.base != NoResult);
Id typeId = getTypeId(accessChain.base);
assert(isPointerType(typeId));
typeId = getContainedTypeId(typeId);
for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) {
if (isStructType(typeId)) {
assert(isConstantScalar(accessChain.indexChain[i]));
typeId = getContainedTypeId(typeId, getConstantScalar(accessChain.indexChain[i]));
} else
typeId = getContainedTypeId(typeId, accessChain.indexChain[i]);
}
return typeId;
}
// Return the immediately contained type of a given composite type. // Return the immediately contained type of a given composite type.
Id Builder::getContainedTypeId(Id typeId) const Id Builder::getContainedTypeId(Id typeId) const
{ {
@ -869,6 +889,30 @@ bool Builder::isSpecConstantOpCode(Op opcode) const
} }
} }
Id Builder::makeNullConstant(Id typeId)
{
Instruction* constant;
// See if we already made it.
Id existing = NoResult;
for (int i = 0; i < (int)nullConstants.size(); ++i) {
constant = nullConstants[i];
if (constant->getTypeId() == typeId)
existing = constant->getResultId();
}
if (existing != NoResult)
return existing;
// Make it
Instruction* c = new Instruction(getUniqueId(), typeId, OpConstantNull);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
nullConstants.push_back(c);
module.mapInstruction(c);
return c->getResultId();
}
Id Builder::makeBoolConstant(bool b, bool specConstant) Id Builder::makeBoolConstant(bool b, bool specConstant)
{ {
Id typeId = makeBoolType(); Id typeId = makeBoolType();
@ -1561,16 +1605,7 @@ Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMa
Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vector<Id>& offsets) Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vector<Id>& offsets)
{ {
// Figure out the final resulting type. // Figure out the final resulting type.
spv::Id typeId = getTypeId(base); Id typeId = getResultingAccessChainType();
assert(isPointerType(typeId) && offsets.size() > 0);
typeId = getContainedTypeId(typeId);
for (int i = 0; i < (int)offsets.size(); ++i) {
if (isStructType(typeId)) {
assert(isConstantScalar(offsets[i]));
typeId = getContainedTypeId(typeId, getConstantScalar(offsets[i]));
} else
typeId = getContainedTypeId(typeId, offsets[i]);
}
typeId = makePointer(storageClass, typeId); typeId = makePointer(storageClass, typeId);
// Make the instruction // Make the instruction
@ -2519,7 +2554,7 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
int row = 0; int row = 0;
int col = 0; int col = 0;
for (int arg = 0; arg < (int)sources.size(); ++arg) { for (int arg = 0; arg < (int)sources.size() && col < numCols; ++arg) {
Id argComp = sources[arg]; Id argComp = sources[arg];
for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) { for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) {
if (getNumComponents(sources[arg]) > 1) { if (getNumComponents(sources[arg]) > 1) {
@ -2531,6 +2566,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
row = 0; row = 0;
col++; col++;
} }
if (col == numCols) {
// If more components are provided than fit the matrix, discard the rest.
break;
}
} }
} }
} }
@ -2766,28 +2805,59 @@ void Builder::accessChainStore(Id rvalue, Decoration nonUniform, spv::MemoryAcce
assert(accessChain.isRValue == false); assert(accessChain.isRValue == false);
transferAccessChainSwizzle(true); transferAccessChainSwizzle(true);
Id base = collapseAccessChain();
addDecoration(base, nonUniform);
Id source = rvalue; // If a swizzle exists and is not full and is not dynamic, then the swizzle will be broken into individual stores.
if (accessChain.swizzle.size() > 0 &&
getNumTypeComponents(getResultingAccessChainType()) != (int)accessChain.swizzle.size() &&
accessChain.component == NoResult) {
for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) {
accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle[i]));
accessChain.instr = NoResult;
// dynamic component should be gone Id base = collapseAccessChain();
assert(accessChain.component == NoResult); addDecoration(base, nonUniform);
// If swizzle still exists, it is out-of-order or not full, we must load the target vector, accessChain.indexChain.pop_back();
// extract and insert elements to perform writeMask and/or swizzle. accessChain.instr = NoResult;
if (accessChain.swizzle.size() > 0) {
Id tempBaseId = createLoad(base, spv::NoPrecision); // dynamic component should be gone
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle); assert(accessChain.component == NoResult);
Id source = createCompositeExtract(rvalue, getContainedTypeId(getTypeId(rvalue)), i);
// take LSB of alignment
alignment = alignment & ~(alignment & (alignment-1));
if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
}
createStore(source, base, memoryAccess, scope, alignment);
}
} }
else {
Id base = collapseAccessChain();
addDecoration(base, nonUniform);
// take LSB of alignment Id source = rvalue;
alignment = alignment & ~(alignment & (alignment-1));
if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) { // dynamic component should be gone
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask); assert(accessChain.component == NoResult);
// If swizzle still exists, it may be out-of-order, we must load the target vector,
// extract and insert elements to perform writeMask and/or swizzle.
if (accessChain.swizzle.size() > 0) {
Id tempBaseId = createLoad(base, spv::NoPrecision);
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
}
// take LSB of alignment
alignment = alignment & ~(alignment & (alignment-1));
if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
}
createStore(source, base, memoryAccess, scope, alignment);
} }
createStore(source, base, memoryAccess, scope, alignment);
} }
// Comments in header // Comments in header

View file

@ -202,6 +202,7 @@ public:
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); } StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
ImageFormat getImageTypeFormat(Id typeId) const ImageFormat getImageTypeFormat(Id typeId) const
{ return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); } { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
Id getResultingAccessChainType() const;
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)); }
@ -293,6 +294,7 @@ 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 makeNullConstant(Id typeId);
Id makeBoolConstant(bool b, bool specConstant = false); Id makeBoolConstant(bool b, bool specConstant = false);
Id makeInt8Constant(int i, bool specConstant = false) Id makeInt8Constant(int i, bool specConstant = false)
{ return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); } { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
@ -838,6 +840,8 @@ public:
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants; std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
// map type opcodes to type instructions // map type opcodes to type instructions
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes; std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;
// list of OpConstantNull instructions
std::vector<Instruction*> nullConstants;
// stack of switches // stack of switches
std::stack<Block*> switchMerges; std::stack<Block*> switchMerges;

View file

@ -436,6 +436,38 @@ void Builder::postProcessFeatures() {
} }
} }
} }
// If any Vulkan memory model-specific functionality is used, update the
// OpMemoryModel to match.
if (capabilities.find(spv::CapabilityVulkanMemoryModelKHR) != capabilities.end()) {
memoryModel = spv::MemoryModelVulkanKHR;
addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
}
// Add Aliased decoration if there's more than one Workgroup Block variable.
if (capabilities.find(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
assert(entryPoints.size() == 1);
auto &ep = entryPoints[0];
std::vector<Id> workgroup_variables;
for (int i = 0; i < (int)ep->getNumOperands(); i++) {
if (!ep->isIdOperand(i))
continue;
const Id id = ep->getIdOperand(i);
const Instruction *instr = module.getInstruction(id);
if (instr->getOpCode() != spv::OpVariable)
continue;
if (instr->getImmediateOperand(0) == spv::StorageClassWorkgroup)
workgroup_variables.push_back(id);
}
if (workgroup_variables.size() > 1) {
for (size_t i = 0; i < workgroup_variables.size(); i++)
addDecoration(workgroup_variables[i], spv::DecorationAliased);
}
}
} }
#endif #endif

View file

@ -153,6 +153,8 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<
spv_validator_options options = spvValidatorOptionsCreate(); spv_validator_options options = spvValidatorOptionsCreate();
spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets()); spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization); spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
spvValidateWithOptions(context, options, &binary, &diagnostic); spvValidateWithOptions(context, options, &binary, &diagnostic);
// report // report
@ -205,6 +207,7 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
optimizer.RegisterPass(spvtools::CreateVectorDCEPass()); optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass()); optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass());
if (options->optimizeSize) { if (options->optimizeSize) {
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass()); optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
} }

View file

@ -188,6 +188,7 @@ const char* ExecutionModeString(int mode)
case ExecutionModeRoundingModeRTE: return "RoundingModeRTE"; case ExecutionModeRoundingModeRTE: return "RoundingModeRTE";
case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ"; case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ";
case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT"; case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT";
case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlow";
case ExecutionModeOutputLinesNV: return "OutputLinesNV"; case ExecutionModeOutputLinesNV: return "OutputLinesNV";
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV"; case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
@ -425,6 +426,7 @@ const char* BuiltInString(int builtIn)
case BuiltInSMCountNV: return "SMCountNV"; case BuiltInSMCountNV: return "SMCountNV";
case BuiltInWarpIDNV: return "WarpIDNV"; case BuiltInWarpIDNV: return "WarpIDNV";
case BuiltInSMIDNV: return "SMIDNV"; case BuiltInSMIDNV: return "SMIDNV";
case BuiltInCurrentRayTimeNV: return "CurrentRayTimeNV";
default: return "Bad"; default: return "Bad";
} }
@ -915,8 +917,10 @@ 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 CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV";
case CapabilityRayTracingKHR: return "RayTracingKHR"; case CapabilityRayTracingKHR: return "RayTracingKHR";
case CapabilityRayQueryKHR: return "RayQueryKHR"; case CapabilityRayQueryKHR: return "RayQueryKHR";
case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR"; case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR";
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
@ -964,8 +968,16 @@ const char* CapabilityString(int info)
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL"; case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
case CapabilityAtomicFloat16AddEXT: return "AtomicFloat16AddEXT";
case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
case CapabilityAtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT";
case CapabilityAtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT";
case CapabilityAtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT";
case CapabilityWorkgroupMemoryExplicitLayoutKHR: return "CapabilityWorkgroupMemoryExplicitLayoutKHR";
case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR";
case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR";
default: return "Bad"; default: return "Bad";
} }
@ -1346,6 +1358,8 @@ const char* OpcodeString(int op)
case 4432: return "OpSubgroupReadInvocationKHR"; case 4432: return "OpSubgroupReadInvocationKHR";
case OpAtomicFAddEXT: return "OpAtomicFAddEXT"; case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
case OpAtomicFMinEXT: return "OpAtomicFMinEXT";
case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT";
case 5000: return "OpGroupIAddNonUniformAMD"; case 5000: return "OpGroupIAddNonUniformAMD";
case 5001: return "OpGroupFAddNonUniformAMD"; case 5001: return "OpGroupFAddNonUniformAMD";
@ -1370,6 +1384,7 @@ const char* OpcodeString(int op)
case OpTerminateRayNV: return "OpTerminateRayNV"; case OpTerminateRayNV: return "OpTerminateRayNV";
case OpTerminateRayKHR: return "OpTerminateRayKHR"; case OpTerminateRayKHR: return "OpTerminateRayKHR";
case OpTraceNV: return "OpTraceNV"; case OpTraceNV: return "OpTraceNV";
case OpTraceRayMotionNV: return "OpTraceRayMotionNV";
case OpTraceRayKHR: return "OpTraceRayKHR"; case OpTraceRayKHR: return "OpTraceRayKHR";
case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR"; case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR";
case OpExecuteCallableNV: return "OpExecuteCallableNV"; case OpExecuteCallableNV: return "OpExecuteCallableNV";
@ -2336,6 +2351,16 @@ void Parameterize()
InstructionDesc[OpAtomicSMax].operands.push(OperandMemorySemantics, "'Semantics'"); InstructionDesc[OpAtomicSMax].operands.push(OperandMemorySemantics, "'Semantics'");
InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Value'"); InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Value'");
InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpAtomicFMinEXT].operands.push(OperandScope, "'Scope'");
InstructionDesc[OpAtomicFMinEXT].operands.push(OperandMemorySemantics, "'Semantics'");
InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Value'");
InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandScope, "'Scope'");
InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandMemorySemantics, "'Semantics'");
InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Value'");
InstructionDesc[OpAtomicAnd].operands.push(OperandId, "'Pointer'"); InstructionDesc[OpAtomicAnd].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpAtomicAnd].operands.push(OperandScope, "'Scope'"); InstructionDesc[OpAtomicAnd].operands.push(OperandScope, "'Scope'");
InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics, "'Semantics'"); InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics, "'Semantics'");
@ -2714,7 +2739,7 @@ void Parameterize()
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandScope, "'Execution'"); InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandScope, "'Execution'");
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "X"); InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "X");
InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandLiteralNumber, "'Direction'"); InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "'Direction'");
InstructionDesc[OpSubgroupBallotKHR].operands.push(OperandId, "'Predicate'"); InstructionDesc[OpSubgroupBallotKHR].operands.push(OperandId, "'Predicate'");
@ -2790,6 +2815,20 @@ void Parameterize()
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'"); InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
InstructionDesc[OpTraceNV].setResultAndType(false, false); InstructionDesc[OpTraceNV].setResultAndType(false, false);
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Acceleration Structure'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Flags'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Cull Mask'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Offset'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Stride'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Miss Index'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Origin'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMin'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Direction'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMax'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Time'");
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Payload'");
InstructionDesc[OpTraceRayMotionNV].setResultAndType(false, false);
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Acceleration Structure'"); InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Acceleration Structure'");
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'"); InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'");
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'"); InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'");

View file

@ -150,6 +150,7 @@ enum ExecutionMode {
ExecutionModeSubgroupsPerWorkgroupId = 37, ExecutionModeSubgroupsPerWorkgroupId = 37,
ExecutionModeLocalSizeId = 38, ExecutionModeLocalSizeId = 38,
ExecutionModeLocalSizeHintId = 39, ExecutionModeLocalSizeHintId = 39,
ExecutionModeSubgroupUniformControlFlowKHR = 4421,
ExecutionModePostDepthCoverage = 4446, ExecutionModePostDepthCoverage = 4446,
ExecutionModeDenormPreserve = 4459, ExecutionModeDenormPreserve = 4459,
ExecutionModeDenormFlushToZero = 4460, ExecutionModeDenormFlushToZero = 4460,
@ -168,10 +169,16 @@ enum ExecutionMode {
ExecutionModeSampleInterlockUnorderedEXT = 5369, ExecutionModeSampleInterlockUnorderedEXT = 5369,
ExecutionModeShadingRateInterlockOrderedEXT = 5370, ExecutionModeShadingRateInterlockOrderedEXT = 5370,
ExecutionModeShadingRateInterlockUnorderedEXT = 5371, ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
ExecutionModeSharedLocalMemorySizeINTEL = 5618,
ExecutionModeRoundingModeRTPINTEL = 5620,
ExecutionModeRoundingModeRTNINTEL = 5621,
ExecutionModeFloatingPointModeALTINTEL = 5622,
ExecutionModeFloatingPointModeIEEEINTEL = 5623,
ExecutionModeMaxWorkgroupSizeINTEL = 5893, ExecutionModeMaxWorkgroupSizeINTEL = 5893,
ExecutionModeMaxWorkDimINTEL = 5894, ExecutionModeMaxWorkDimINTEL = 5894,
ExecutionModeNoGlobalOffsetINTEL = 5895, ExecutionModeNoGlobalOffsetINTEL = 5895,
ExecutionModeNumSIMDWorkitemsINTEL = 5896, ExecutionModeNumSIMDWorkitemsINTEL = 5896,
ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
ExecutionModeMax = 0x7fffffff, ExecutionModeMax = 0x7fffffff,
}; };
@ -204,6 +211,8 @@ enum StorageClass {
StorageClassPhysicalStorageBuffer = 5349, StorageClassPhysicalStorageBuffer = 5349,
StorageClassPhysicalStorageBufferEXT = 5349, StorageClassPhysicalStorageBufferEXT = 5349,
StorageClassCodeSectionINTEL = 5605, StorageClassCodeSectionINTEL = 5605,
StorageClassDeviceOnlyINTEL = 5936,
StorageClassHostOnlyINTEL = 5937,
StorageClassMax = 0x7fffffff, StorageClassMax = 0x7fffffff,
}; };
@ -374,6 +383,8 @@ enum FPFastMathModeShift {
FPFastMathModeNSZShift = 2, FPFastMathModeNSZShift = 2,
FPFastMathModeAllowRecipShift = 3, FPFastMathModeAllowRecipShift = 3,
FPFastMathModeFastShift = 4, FPFastMathModeFastShift = 4,
FPFastMathModeAllowContractFastINTELShift = 16,
FPFastMathModeAllowReassocINTELShift = 17,
FPFastMathModeMax = 0x7fffffff, FPFastMathModeMax = 0x7fffffff,
}; };
@ -384,6 +395,8 @@ enum FPFastMathModeMask {
FPFastMathModeNSZMask = 0x00000004, FPFastMathModeNSZMask = 0x00000004,
FPFastMathModeAllowRecipMask = 0x00000008, FPFastMathModeAllowRecipMask = 0x00000008,
FPFastMathModeFastMask = 0x00000010, FPFastMathModeFastMask = 0x00000010,
FPFastMathModeAllowContractFastINTELMask = 0x00010000,
FPFastMathModeAllowReassocINTELMask = 0x00020000,
}; };
enum FPRoundingMode { enum FPRoundingMode {
@ -397,6 +410,7 @@ enum FPRoundingMode {
enum LinkageType { enum LinkageType {
LinkageTypeExport = 0, LinkageTypeExport = 0,
LinkageTypeImport = 1, LinkageTypeImport = 1,
LinkageTypeLinkOnceODR = 2,
LinkageTypeMax = 0x7fffffff, LinkageTypeMax = 0x7fffffff,
}; };
@ -484,12 +498,22 @@ enum Decoration {
DecorationRestrictPointerEXT = 5355, DecorationRestrictPointerEXT = 5355,
DecorationAliasedPointer = 5356, DecorationAliasedPointer = 5356,
DecorationAliasedPointerEXT = 5356, DecorationAliasedPointerEXT = 5356,
DecorationSIMTCallINTEL = 5599,
DecorationReferencedIndirectlyINTEL = 5602, DecorationReferencedIndirectlyINTEL = 5602,
DecorationClobberINTEL = 5607,
DecorationSideEffectsINTEL = 5608,
DecorationVectorComputeVariableINTEL = 5624,
DecorationFuncParamIOKindINTEL = 5625,
DecorationVectorComputeFunctionINTEL = 5626,
DecorationStackCallINTEL = 5627,
DecorationGlobalVariableOffsetINTEL = 5628,
DecorationCounterBuffer = 5634, DecorationCounterBuffer = 5634,
DecorationHlslCounterBufferGOOGLE = 5634, DecorationHlslCounterBufferGOOGLE = 5634,
DecorationHlslSemanticGOOGLE = 5635, DecorationHlslSemanticGOOGLE = 5635,
DecorationUserSemantic = 5635, DecorationUserSemantic = 5635,
DecorationUserTypeGOOGLE = 5636, DecorationUserTypeGOOGLE = 5636,
DecorationFunctionRoundingModeINTEL = 5822,
DecorationFunctionDenormModeINTEL = 5823,
DecorationRegisterINTEL = 5825, DecorationRegisterINTEL = 5825,
DecorationMemoryINTEL = 5826, DecorationMemoryINTEL = 5826,
DecorationNumbanksINTEL = 5827, DecorationNumbanksINTEL = 5827,
@ -502,6 +526,17 @@ enum Decoration {
DecorationMergeINTEL = 5834, DecorationMergeINTEL = 5834,
DecorationBankBitsINTEL = 5835, DecorationBankBitsINTEL = 5835,
DecorationForcePow2DepthINTEL = 5836, DecorationForcePow2DepthINTEL = 5836,
DecorationBurstCoalesceINTEL = 5899,
DecorationCacheSizeINTEL = 5900,
DecorationDontStaticallyCoalesceINTEL = 5901,
DecorationPrefetchINTEL = 5902,
DecorationStallEnableINTEL = 5905,
DecorationFuseLoopsInFunctionINTEL = 5907,
DecorationBufferLocationINTEL = 5921,
DecorationIOPipeStorageINTEL = 5944,
DecorationFunctionFloatingPointModeINTEL = 6080,
DecorationSingleElementVectorINTEL = 6085,
DecorationVectorComputeCallableFunctionINTEL = 6087,
DecorationMax = 0x7fffffff, DecorationMax = 0x7fffffff,
}; };
@ -617,6 +652,7 @@ enum BuiltIn {
BuiltInHitTNV = 5332, BuiltInHitTNV = 5332,
BuiltInHitKindKHR = 5333, BuiltInHitKindKHR = 5333,
BuiltInHitKindNV = 5333, BuiltInHitKindNV = 5333,
BuiltInCurrentRayTimeNV = 5334,
BuiltInIncomingRayFlagsKHR = 5351, BuiltInIncomingRayFlagsKHR = 5351,
BuiltInIncomingRayFlagsNV = 5351, BuiltInIncomingRayFlagsNV = 5351,
BuiltInRayGeometryIndexKHR = 5352, BuiltInRayGeometryIndexKHR = 5352,
@ -656,6 +692,7 @@ enum LoopControlShift {
LoopControlLoopCoalesceINTELShift = 20, LoopControlLoopCoalesceINTELShift = 20,
LoopControlMaxInterleavingINTELShift = 21, LoopControlMaxInterleavingINTELShift = 21,
LoopControlSpeculatedIterationsINTELShift = 22, LoopControlSpeculatedIterationsINTELShift = 22,
LoopControlNoFusionINTELShift = 23,
LoopControlMax = 0x7fffffff, LoopControlMax = 0x7fffffff,
}; };
@ -677,6 +714,7 @@ enum LoopControlMask {
LoopControlLoopCoalesceINTELMask = 0x00100000, LoopControlLoopCoalesceINTELMask = 0x00100000,
LoopControlMaxInterleavingINTELMask = 0x00200000, LoopControlMaxInterleavingINTELMask = 0x00200000,
LoopControlSpeculatedIterationsINTELMask = 0x00400000, LoopControlSpeculatedIterationsINTELMask = 0x00400000,
LoopControlNoFusionINTELMask = 0x00800000,
}; };
enum FunctionControlShift { enum FunctionControlShift {
@ -876,6 +914,9 @@ enum Capability {
CapabilityFragmentShadingRateKHR = 4422, CapabilityFragmentShadingRateKHR = 4422,
CapabilitySubgroupBallotKHR = 4423, CapabilitySubgroupBallotKHR = 4423,
CapabilityDrawParameters = 4427, CapabilityDrawParameters = 4427,
CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428,
CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429,
CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430,
CapabilitySubgroupVoteKHR = 4431, CapabilitySubgroupVoteKHR = 4431,
CapabilityStorageBuffer16BitAccess = 4433, CapabilityStorageBuffer16BitAccess = 4433,
CapabilityStorageUniformBufferBlock16 = 4433, CapabilityStorageUniformBufferBlock16 = 4433,
@ -948,6 +989,7 @@ enum Capability {
CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
CapabilityRayTracingNV = 5340, CapabilityRayTracingNV = 5340,
CapabilityRayTracingMotionBlurNV = 5341,
CapabilityVulkanMemoryModel = 5345, CapabilityVulkanMemoryModel = 5345,
CapabilityVulkanMemoryModelKHR = 5345, CapabilityVulkanMemoryModelKHR = 5345,
CapabilityVulkanMemoryModelDeviceScope = 5346, CapabilityVulkanMemoryModelDeviceScope = 5346,
@ -966,21 +1008,42 @@ enum Capability {
CapabilitySubgroupBufferBlockIOINTEL = 5569, CapabilitySubgroupBufferBlockIOINTEL = 5569,
CapabilitySubgroupImageBlockIOINTEL = 5570, CapabilitySubgroupImageBlockIOINTEL = 5570,
CapabilitySubgroupImageMediaBlockIOINTEL = 5579, CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
CapabilityRoundToInfinityINTEL = 5582,
CapabilityFloatingPointModeINTEL = 5583,
CapabilityIntegerFunctions2INTEL = 5584, CapabilityIntegerFunctions2INTEL = 5584,
CapabilityFunctionPointersINTEL = 5603, CapabilityFunctionPointersINTEL = 5603,
CapabilityIndirectReferencesINTEL = 5604, CapabilityIndirectReferencesINTEL = 5604,
CapabilityAsmINTEL = 5606,
CapabilityAtomicFloat32MinMaxEXT = 5612,
CapabilityAtomicFloat64MinMaxEXT = 5613,
CapabilityAtomicFloat16MinMaxEXT = 5616,
CapabilityVectorComputeINTEL = 5617,
CapabilityVectorAnyINTEL = 5619,
CapabilityExpectAssumeKHR = 5629,
CapabilitySubgroupAvcMotionEstimationINTEL = 5696, CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
CapabilityVariableLengthArrayINTEL = 5817,
CapabilityFunctionFloatControlINTEL = 5821,
CapabilityFPGAMemoryAttributesINTEL = 5824, CapabilityFPGAMemoryAttributesINTEL = 5824,
CapabilityFPFastMathModeINTEL = 5837,
CapabilityArbitraryPrecisionIntegersINTEL = 5844,
CapabilityUnstructuredLoopControlsINTEL = 5886, CapabilityUnstructuredLoopControlsINTEL = 5886,
CapabilityFPGALoopControlsINTEL = 5888, CapabilityFPGALoopControlsINTEL = 5888,
CapabilityKernelAttributesINTEL = 5892, CapabilityKernelAttributesINTEL = 5892,
CapabilityFPGAKernelAttributesINTEL = 5897, CapabilityFPGAKernelAttributesINTEL = 5897,
CapabilityFPGAMemoryAccessesINTEL = 5898,
CapabilityFPGAClusterAttributesINTEL = 5904,
CapabilityLoopFuseINTEL = 5906,
CapabilityFPGABufferLocationINTEL = 5920,
CapabilityUSMStorageClassesINTEL = 5935,
CapabilityIOPipesINTEL = 5943,
CapabilityBlockingPipesINTEL = 5945, CapabilityBlockingPipesINTEL = 5945,
CapabilityFPGARegINTEL = 5948, CapabilityFPGARegINTEL = 5948,
CapabilityAtomicFloat32AddEXT = 6033, CapabilityAtomicFloat32AddEXT = 6033,
CapabilityAtomicFloat64AddEXT = 6034, CapabilityAtomicFloat64AddEXT = 6034,
CapabilityLongConstantCompositeINTEL = 6089,
CapabilityAtomicFloat16AddEXT = 6095,
CapabilityMax = 0x7fffffff, CapabilityMax = 0x7fffffff,
}; };
@ -1047,6 +1110,18 @@ enum FragmentShadingRateMask {
FragmentShadingRateHorizontal4PixelsMask = 0x00000008, FragmentShadingRateHorizontal4PixelsMask = 0x00000008,
}; };
enum FPDenormMode {
FPDenormModePreserve = 0,
FPDenormModeFlushToZero = 1,
FPDenormModeMax = 0x7fffffff,
};
enum FPOperationMode {
FPOperationModeIEEE = 0,
FPOperationModeALT = 1,
FPOperationModeMax = 0x7fffffff,
};
enum Op { enum Op {
OpNop = 0, OpNop = 0,
OpUndef = 1, OpUndef = 1,
@ -1430,6 +1505,8 @@ enum Op {
OpIgnoreIntersectionNV = 5335, OpIgnoreIntersectionNV = 5335,
OpTerminateRayNV = 5336, OpTerminateRayNV = 5336,
OpTraceNV = 5337, OpTraceNV = 5337,
OpTraceMotionNV = 5338,
OpTraceRayMotionNV = 5339,
OpTypeAccelerationStructureKHR = 5341, OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341, OpTypeAccelerationStructureNV = 5341,
OpExecuteCallableNV = 5344, OpExecuteCallableNV = 5344,
@ -1466,8 +1543,15 @@ enum Op {
OpUSubSatINTEL = 5596, OpUSubSatINTEL = 5596,
OpIMul32x16INTEL = 5597, OpIMul32x16INTEL = 5597,
OpUMul32x16INTEL = 5598, OpUMul32x16INTEL = 5598,
OpFunctionPointerINTEL = 5600, OpConstFunctionPointerINTEL = 5600,
OpFunctionPointerCallINTEL = 5601, OpFunctionPointerCallINTEL = 5601,
OpAsmTargetINTEL = 5609,
OpAsmINTEL = 5610,
OpAsmCallINTEL = 5611,
OpAtomicFMinEXT = 5614,
OpAtomicFMaxEXT = 5615,
OpAssumeTrueKHR = 5630,
OpExpectKHR = 5631,
OpDecorateString = 5632, OpDecorateString = 5632,
OpDecorateStringGOOGLE = 5632, OpDecorateStringGOOGLE = 5632,
OpMemberDecorateString = 5633, OpMemberDecorateString = 5633,
@ -1590,7 +1674,12 @@ enum Op {
OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
OpVariableLengthArrayINTEL = 5818,
OpSaveMemoryINTEL = 5819,
OpRestoreMemoryINTEL = 5820,
OpLoopControlINTEL = 5887, OpLoopControlINTEL = 5887,
OpPtrCastToCrossWorkgroupINTEL = 5934,
OpCrossWorkgroupCastToPtrINTEL = 5938,
OpReadPipeBlockingINTEL = 5946, OpReadPipeBlockingINTEL = 5946,
OpWritePipeBlockingINTEL = 5947, OpWritePipeBlockingINTEL = 5947,
OpFPGARegINTEL = 5949, OpFPGARegINTEL = 5949,
@ -1612,6 +1701,10 @@ enum Op {
OpRayQueryGetIntersectionObjectToWorldKHR = 6031, OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
OpRayQueryGetIntersectionWorldToObjectKHR = 6032, OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
OpAtomicFAddEXT = 6035, OpAtomicFAddEXT = 6035,
OpTypeBufferSurfaceINTEL = 6086,
OpTypeStructContinuedINTEL = 6090,
OpConstantCompositeContinuedINTEL = 6091,
OpSpecConstantCompositeContinuedINTEL = 6092,
OpMax = 0x7fffffff, OpMax = 0x7fffffff,
}; };
@ -2001,6 +2094,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
case OpTraceNV: *hasResult = false; *hasResultType = false; break; case OpTraceNV: *hasResult = false; *hasResultType = false; break;
case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break;
case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break;
case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
@ -2036,8 +2131,15 @@ 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 OpConstFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break;
case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break;
case OpAsmINTEL: *hasResult = true; *hasResultType = true; break;
case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break;
case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break;
case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break;
case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break;
case OpExpectKHR: *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;
@ -2158,7 +2260,12 @@ 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 OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break;
case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break;
case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break;
case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break;
case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break;
case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
@ -2180,6 +2287,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;
case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;
case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break;
case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
} }
} }
#endif /* SPV_ENABLE_UTILITY_CODE */ #endif /* SPV_ENABLE_UTILITY_CODE */

View file

@ -40,6 +40,7 @@
#include <string> #include <string>
#include <fstream> #include <fstream>
#include <algorithm> #include <algorithm>
#include <set>
#include "./../glslang/Public/ShaderLang.h" #include "./../glslang/Public/ShaderLang.h"
@ -84,12 +85,18 @@ public:
} }
} }
virtual std::set<std::string> getIncludedFiles()
{
return includedFiles;
}
virtual ~DirStackFileIncluder() override { } virtual ~DirStackFileIncluder() override { }
protected: protected:
typedef char tUserDataElement; typedef char tUserDataElement;
std::vector<std::string> directoryStack; std::vector<std::string> directoryStack;
int externalLocalDirectoryCount; int externalLocalDirectoryCount;
std::set<std::string> includedFiles;
// Search for a valid "local" path based on combining the stack of include // Search for a valid "local" path based on combining the stack of include
// directories and the nominal name of the header. // directories and the nominal name of the header.
@ -108,6 +115,7 @@ protected:
std::ifstream file(path, std::ios_base::binary | std::ios_base::ate); std::ifstream file(path, std::ios_base::binary | std::ios_base::ate);
if (file) { if (file) {
directoryStack.push_back(getDirectory(path)); directoryStack.push_back(getDirectory(path));
includedFiles.insert(path);
return newIncludeResult(path, file, (int)file.tellg()); return newIncludeResult(path, file, (int)file.tellg());
} }
} }

View file

@ -65,6 +65,10 @@ enum TBasicType {
EbtAccStruct, EbtAccStruct,
EbtReference, EbtReference,
EbtRayQuery, EbtRayQuery,
#ifndef GLSLANG_WEB
// SPIR-V type defined by spirv_type
EbtSpirvType,
#endif
// HLSL types that live only temporarily. // HLSL types that live only temporarily.
EbtString, EbtString,
@ -91,6 +95,9 @@ enum TStorageQualifier {
EvqUniform, // read only, shared with app EvqUniform, // read only, shared with app
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
#ifndef GLSLANG_WEB
EvqSpirvStorageClass, // spirv_storage_class
#endif
EvqPayload, EvqPayload,
EvqPayloadIn, EvqPayloadIn,
@ -263,6 +270,7 @@ enum TBuiltInVariable {
EbvWorldToObject, EbvWorldToObject,
EbvWorldToObject3x4, EbvWorldToObject3x4,
EbvIncomingRayFlags, EbvIncomingRayFlags,
EbvCurrentRayTimeNV,
// barycentrics // barycentrics
EbvBaryCoordNV, EbvBaryCoordNV,
EbvBaryCoordNoPerspNV, EbvBaryCoordNoPerspNV,
@ -321,6 +329,9 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
case EvqGlobal: return "global"; break; case EvqGlobal: return "global"; break;
case EvqConst: return "const"; break; case EvqConst: return "const"; break;
case EvqConstReadOnly: return "const (read only)"; break; case EvqConstReadOnly: return "const (read only)"; break;
#ifndef GLSLANG_WEB
case EvqSpirvStorageClass: return "spirv_storage_class"; break;
#endif
case EvqVaryingIn: return "in"; break; case EvqVaryingIn: return "in"; break;
case EvqVaryingOut: return "out"; break; case EvqVaryingOut: return "out"; break;
case EvqUniform: return "uniform"; break; case EvqUniform: return "uniform"; break;
@ -465,6 +476,7 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
case EbvIncomingRayFlags: return "IncomingRayFlagsNV"; case EbvIncomingRayFlags: return "IncomingRayFlagsNV";
case EbvObjectToWorld: return "ObjectToWorldNV"; case EbvObjectToWorld: return "ObjectToWorldNV";
case EbvWorldToObject: return "WorldToObjectNV"; case EbvWorldToObject: return "WorldToObjectNV";
case EbvCurrentRayTimeNV: return "CurrentRayTimeNV";
case EbvBaryCoordNV: return "BaryCoordNV"; case EbvBaryCoordNV: return "BaryCoordNV";
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";

View file

@ -194,6 +194,10 @@ template <class K, class D, class HASH = std::hash<K>, class PRED = std::equal_t
class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > { class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > {
}; };
template <class K, class CMP = std::less<K> >
class TSet : public std::set<K, CMP, pool_allocator<K> > {
};
// //
// Persistent string memory. Should only be used for strings that survive // Persistent string memory. Should only be used for strings that survive
// across compiles/links. // across compiles/links.
@ -286,6 +290,18 @@ template <class T> bool IsMultipleOfPow2(T number, int powerOf2)
return ! (number & (powerOf2 - 1)); return ! (number & (powerOf2 - 1));
} }
// Returns log2 of an integer power of 2.
// T should be integral.
template <class T> int IntLog2(T n)
{
assert(IsPow2(n));
int result = 0;
while ((T(1) << result) != n) {
result++;
}
return result;
}
} // end namespace glslang } // end namespace glslang
#endif // _COMMON_INCLUDED_ #endif // _COMMON_INCLUDED_

View file

@ -0,0 +1,136 @@
//
// Copyright(C) 2021 Advanced Micro Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#ifndef GLSLANG_WEB
//
// GL_EXT_spirv_intrinsics
//
#include "Common.h"
namespace glslang {
class TIntermTyped;
class TIntermConstantUnion;
class TType;
// SPIR-V requirements
struct TSpirvRequirement {
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
// capability = [..]
TSet<TString> extensions;
// extension = [..]
TSet<int> capabilities;
};
// SPIR-V execution modes
struct TSpirvExecutionMode {
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
// spirv_execution_mode
TMap<int, TVector<const TIntermConstantUnion*>> modes;
// spirv_execution_mode_id
TMap<int, TVector<const TIntermConstantUnion*> > modeIds;
};
// SPIR-V decorations
struct TSpirvDecorate {
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
// spirv_decorate
TMap<int, TVector<const TIntermConstantUnion*> > decorates;
// spirv_decorate_id
TMap<int, TVector<const TIntermConstantUnion*> > decorateIds;
// spirv_decorate_string
TMap<int, TVector<const TIntermConstantUnion*> > decorateStrings;
};
// SPIR-V instruction
struct TSpirvInstruction {
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TSpirvInstruction() { set = ""; id = -1; }
bool operator==(const TSpirvInstruction& rhs) const { return set == rhs.set && id == rhs.id; }
bool operator!=(const TSpirvInstruction& rhs) const { return !operator==(rhs); }
// spirv_instruction
TString set;
int id;
};
// SPIR-V type parameter
struct TSpirvTypeParameter {
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TSpirvTypeParameter(const TIntermConstantUnion* arg) { isConstant = true; constant = arg; }
TSpirvTypeParameter(const TType* arg) { isConstant = false; type = arg; }
bool operator==(const TSpirvTypeParameter& rhs) const
{
return isConstant == rhs.isConstant && ((isConstant && constant == rhs.constant) || (!isConstant && type == rhs.type));
}
bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }
bool isConstant;
union {
const TIntermConstantUnion* constant;
const TType* type;
};
};
typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;
// SPIR-V type
struct TSpirvType {
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
bool operator==(const TSpirvType& rhs) const
{
return spirvInst == rhs.spirvInst && typeParams == rhs.typeParams;
}
bool operator!=(const TSpirvType& rhs) const { return !operator==(rhs); }
// spirv_type
TSpirvInstruction spirvInst;
TSpirvTypeParameters typeParams;
};
} // end namespace glslang
#endif // GLSLANG_WEB

View file

@ -44,11 +44,14 @@
#include "../Include/BaseTypes.h" #include "../Include/BaseTypes.h"
#include "../Public/ShaderLang.h" #include "../Public/ShaderLang.h"
#include "arrays.h" #include "arrays.h"
#include "SpirvIntrinsics.h"
#include <algorithm> #include <algorithm>
namespace glslang { namespace glslang {
class TIntermAggregate;
const int GlslangMaxTypeLength = 200; // TODO: need to print block/struct one member per line, so this can stay bounded const int GlslangMaxTypeLength = 200; // TODO: need to print block/struct one member per line, so this can stay bounded
const char* const AnonymousPrefix = "anon@"; // for something like a block whose members can be directly accessed const char* const AnonymousPrefix = "anon@"; // for something like a block whose members can be directly accessed
@ -115,6 +118,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
#endif #endif
bool is1D() const { return dim == Esd1D; } bool is1D() const { return dim == Esd1D; }
bool is2D() const { return dim == Esd2D; }
bool isBuffer() const { return dim == EsdBuffer; } bool isBuffer() const { return dim == EsdBuffer; }
bool isRect() const { return dim == EsdRect; } bool isRect() const { return dim == EsdRect; }
bool isSubpass() const { return dim == EsdSubpass; } bool isSubpass() const { return dim == EsdSubpass; }
@ -486,7 +490,6 @@ enum TShaderInterface
EsiCount EsiCount
}; };
class TQualifier { class TQualifier {
public: public:
static const int layoutNotSet = -1; static const int layoutNotSet = -1;
@ -499,7 +502,11 @@ public:
declaredBuiltIn = EbvNone; declaredBuiltIn = EbvNone;
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
noContraction = false; noContraction = false;
nullInit = false;
spirvByReference = false;
spirvLiteral = false;
#endif #endif
defaultBlock = false;
} }
// drop qualifiers that don't belong in a temporary variable // drop qualifiers that don't belong in a temporary variable
@ -512,7 +519,15 @@ public:
clearMemory(); clearMemory();
specConstant = false; specConstant = false;
nonUniform = false; nonUniform = false;
nullInit = false;
defaultBlock = false;
clearLayout(); clearLayout();
#ifndef GLSLANG_WEB
spirvStorageClass = -1;
spirvDecorate = nullptr;
spirvByReference = false;
spirvLiteral = false;
#endif
} }
void clearInterstage() void clearInterstage()
@ -570,6 +585,7 @@ public:
bool specConstant : 1; bool specConstant : 1;
bool nonUniform : 1; bool nonUniform : 1;
bool explicitOffset : 1; bool explicitOffset : 1;
bool defaultBlock : 1; // default blocks with matching names have structures merged when linking
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
bool isWriteOnly() const { return false; } bool isWriteOnly() const { return false; }
@ -588,6 +604,12 @@ public:
bool isNoContraction() const { return false; } bool isNoContraction() const { return false; }
void setNoContraction() { } void setNoContraction() { }
bool isPervertexNV() const { return false; } bool isPervertexNV() const { return false; }
void setNullInit() { }
bool isNullInit() const { return false; }
void setSpirvByReference() { }
bool isSpirvByReference() { return false; }
void setSpirvLiteral() { }
bool isSpirvLiteral() { return false; }
#else #else
bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
bool nopersp : 1; bool nopersp : 1;
@ -609,6 +631,9 @@ public:
bool subgroupcoherent : 1; bool subgroupcoherent : 1;
bool shadercallcoherent : 1; bool shadercallcoherent : 1;
bool nonprivate : 1; bool nonprivate : 1;
bool nullInit : 1;
bool spirvByReference : 1;
bool spirvLiteral : 1;
bool isWriteOnly() const { return writeonly; } bool isWriteOnly() const { return writeonly; }
bool isReadOnly() const { return readonly; } bool isReadOnly() const { return readonly; }
bool isRestrict() const { return restrict; } bool isRestrict() const { return restrict; }
@ -644,6 +669,12 @@ public:
bool isNoContraction() const { return noContraction; } bool isNoContraction() const { return noContraction; }
void setNoContraction() { noContraction = true; } void setNoContraction() { noContraction = true; }
bool isPervertexNV() const { return pervertexNV; } bool isPervertexNV() const { return pervertexNV; }
void setNullInit() { nullInit = true; }
bool isNullInit() const { return nullInit; }
void setSpirvByReference() { spirvByReference = true; }
bool isSpirvByReference() const { return spirvByReference; }
void setSpirvLiteral() { spirvLiteral = true; }
bool isSpirvLiteral() const { return spirvLiteral; }
#endif #endif
bool isPipeInput() const bool isPipeInput() const
@ -749,6 +780,46 @@ public:
} }
} }
TBlockStorageClass getBlockStorage() const {
if (storage == EvqUniform && !isPushConstant()) {
return EbsUniform;
}
else if (storage == EvqUniform) {
return EbsPushConstant;
}
else if (storage == EvqBuffer) {
return EbsStorageBuffer;
}
return EbsNone;
}
void setBlockStorage(TBlockStorageClass newBacking) {
#ifndef GLSLANG_WEB
layoutPushConstant = (newBacking == EbsPushConstant);
#endif
switch (newBacking) {
case EbsUniform :
if (layoutPacking == ElpStd430) {
// std430 would not be valid
layoutPacking = ElpStd140;
}
storage = EvqUniform;
break;
case EbsStorageBuffer :
storage = EvqBuffer;
break;
#ifndef GLSLANG_WEB
case EbsPushConstant :
storage = EvqUniform;
layoutSet = TQualifier::layoutSetEnd;
layoutBinding = TQualifier::layoutBindingEnd;
break;
#endif
default:
break;
}
}
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
bool isPerView() const { return false; } bool isPerView() const { return false; }
bool isTaskMemory() const { return false; } bool isTaskMemory() const { return false; }
@ -845,6 +916,7 @@ public:
return hasNonXfbLayout() || return hasNonXfbLayout() ||
hasXfb(); hasXfb();
} }
TLayoutMatrix layoutMatrix : 3; TLayoutMatrix layoutMatrix : 3;
TLayoutPacking layoutPacking : 4; TLayoutPacking layoutPacking : 4;
int layoutOffset; int layoutOffset;
@ -896,6 +968,10 @@ public:
bool layoutViewportRelative; bool layoutViewportRelative;
int layoutSecondaryViewportRelativeOffset; int layoutSecondaryViewportRelativeOffset;
bool layoutShaderRecord; bool layoutShaderRecord;
// GL_EXT_spirv_intrinsics
int spirvStorageClass;
TSpirvDecorate* spirvDecorate;
#endif #endif
bool hasUniformLayout() const bool hasUniformLayout() const
@ -1027,6 +1103,15 @@ public:
{ {
return nonUniform; return nonUniform;
} }
// GL_EXT_spirv_intrinsics
bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
void setSpirvDecorate(int decoration, const TIntermAggregate* args = nullptr);
void setSpirvDecorateId(int decoration, const TIntermAggregate* args);
void setSpirvDecorateString(int decoration, const TIntermAggregate* args);
const TSpirvDecorate& getSpirvDecorate() const { assert(spirvDecorate); return *spirvDecorate; }
TSpirvDecorate& getSpirvDecorate() { assert(spirvDecorate); return *spirvDecorate; }
TString getSpirvDecorateQualifierString() const;
#endif #endif
bool hasSpecConstantId() const bool hasSpecConstantId() const
{ {
@ -1371,6 +1456,10 @@ public:
const TType* userDef; const TType* userDef;
TSourceLoc loc; TSourceLoc loc;
TArraySizes* typeParameters; TArraySizes* typeParameters;
#ifndef GLSLANG_WEB
// SPIR-V type defined by spirv_type directive
TSpirvType* spirvType;
#endif
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
bool isCoopmat() const { return false; } bool isCoopmat() const { return false; }
@ -1389,6 +1478,9 @@ public:
loc = l; loc = l;
typeParameters = nullptr; typeParameters = nullptr;
coopmat = false; coopmat = false;
#ifndef GLSLANG_WEB
spirvType = nullptr;
#endif
} }
void initQualifiers(bool global = false) void initQualifiers(bool global = false)
@ -1425,6 +1517,11 @@ public:
return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr; return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr;
} }
#ifndef GLSLANG_WEB
// GL_EXT_spirv_intrinsics
void setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams = nullptr);
#endif
// "Image" is a superset of "Subpass" // "Image" is a superset of "Subpass"
bool isImage() const { return basicType == EbtSampler && sampler.isImage(); } bool isImage() const { return basicType == EbtSampler && sampler.isImage(); }
bool isSubpass() const { return basicType == EbtSampler && sampler.isSubpass(); } bool isSubpass() const { return basicType == EbtSampler && sampler.isSubpass(); }
@ -1442,6 +1539,9 @@ public:
bool isVector = false) : bool isVector = false) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false), basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr) arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
#ifndef GLSLANG_WEB
, spirvType(nullptr)
#endif
{ {
sampler.clear(); sampler.clear();
qualifier.clear(); qualifier.clear();
@ -1453,6 +1553,9 @@ public:
bool isVector = false) : bool isVector = false) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false), basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr) arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
#ifndef GLSLANG_WEB
, spirvType(nullptr)
#endif
{ {
sampler.clear(); sampler.clear();
qualifier.clear(); qualifier.clear();
@ -1466,6 +1569,9 @@ public:
basicType(p.basicType), basicType(p.basicType),
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmat(p.coopmat), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmat(p.coopmat),
arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters) arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters)
#ifndef GLSLANG_WEB
, spirvType(p.spirvType)
#endif
{ {
if (basicType == EbtSampler) if (basicType == EbtSampler)
sampler = p.sampler; sampler = p.sampler;
@ -1500,6 +1606,9 @@ public:
basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr), arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
sampler(sampler), typeParameters(nullptr) sampler(sampler), typeParameters(nullptr)
#ifndef GLSLANG_WEB
, spirvType(nullptr)
#endif
{ {
qualifier.clear(); qualifier.clear();
qualifier.storage = q; qualifier.storage = q;
@ -1550,6 +1659,9 @@ public:
TType(TTypeList* userDef, const TString& n) : TType(TTypeList* userDef, const TString& n) :
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr) arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
#ifndef GLSLANG_WEB
, spirvType(nullptr)
#endif
{ {
sampler.clear(); sampler.clear();
qualifier.clear(); qualifier.clear();
@ -1559,6 +1671,9 @@ public:
TType(TTypeList* userDef, const TString& n, const TQualifier& q) : TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr) qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
#ifndef GLSLANG_WEB
, spirvType(nullptr)
#endif
{ {
sampler.clear(); sampler.clear();
typeName = NewPoolTString(n.c_str()); typeName = NewPoolTString(n.c_str());
@ -1567,6 +1682,9 @@ public:
explicit TType(TBasicType t, const TType &p, const TString& n) : explicit TType(TBasicType t, const TType &p, const TString& n) :
basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
#ifndef GLSLANG_WEB
, spirvType(nullptr)
#endif
{ {
assert(t == EbtReference); assert(t == EbtReference);
typeName = NewPoolTString(n.c_str()); typeName = NewPoolTString(n.c_str());
@ -1597,6 +1715,9 @@ public:
referentType = copyOf.referentType; referentType = copyOf.referentType;
} }
typeParameters = copyOf.typeParameters; typeParameters = copyOf.typeParameters;
#ifndef GLSLANG_WEB
spirvType = copyOf.spirvType;
#endif
coopmat = copyOf.isCoopMat(); coopmat = copyOf.isCoopMat();
} }
@ -1687,6 +1808,7 @@ public:
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); } virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
virtual bool isScalarOrVec1() const { return isScalar() || vector1; } virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
virtual bool isScalarOrVector() const { return !isMatrix() && !isStruct() && !isArray(); }
virtual bool isVector() const { return vectorSize > 1 || vector1; } virtual bool isVector() const { return vectorSize > 1 || vector1; }
virtual bool isMatrix() const { return matrixCols ? true : false; } virtual bool isMatrix() const { return matrixCols ? true : false; }
virtual bool isArray() const { return arraySizes != nullptr; } virtual bool isArray() const { return arraySizes != nullptr; }
@ -1717,7 +1839,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 == EbtAccStruct || basicType == EbtRayQuery || basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
#endif #endif
; } ; }
virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; } virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
@ -1965,8 +2087,6 @@ public:
} }
} }
const char* getBasicString() const const char* getBasicString() const
{ {
return TType::getBasicString(basicType); return TType::getBasicString(basicType);
@ -1997,6 +2117,7 @@ public:
case EbtRayQuery: return "rayQueryEXT"; case EbtRayQuery: return "rayQueryEXT";
case EbtReference: return "reference"; case EbtReference: return "reference";
case EbtString: return "string"; case EbtString: return "string";
case EbtSpirvType: return "spirv_type";
#endif #endif
default: return "unknown type"; default: return "unknown type";
} }
@ -2017,6 +2138,9 @@ public:
const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); }; const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); };
const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); }; const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); };
if (qualifier.hasSprivDecorate())
appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
if (qualifier.hasLayout()) { if (qualifier.hasLayout()) {
// To reduce noise, skip this if the only layout is an xfb_buffer // To reduce noise, skip this if the only layout is an xfb_buffer
// with no triggering xfb_offset. // with no triggering xfb_offset.
@ -2164,6 +2288,12 @@ public:
appendStr(" specialization-constant"); appendStr(" specialization-constant");
if (qualifier.nonUniform) if (qualifier.nonUniform)
appendStr(" nonuniform"); appendStr(" nonuniform");
if (qualifier.isNullInit())
appendStr(" null-init");
if (qualifier.isSpirvByReference())
appendStr(" spirv_by_reference");
if (qualifier.isSpirvLiteral())
appendStr(" spirv_literal");
appendStr(" "); appendStr(" ");
appendStr(getStorageQualifierString()); appendStr(getStorageQualifierString());
if (isArray()) { if (isArray()) {
@ -2283,6 +2413,17 @@ public:
name += ';' ; name += ';' ;
} }
// These variables are inconsistently declared inside and outside of gl_PerVertex in glslang right now.
// They are declared inside of 'in gl_PerVertex', but sitting as standalone when they are 'out'puts.
bool isInconsistentGLPerVertexMember(const TString& name) const
{
if (name == "gl_SecondaryPositionNV" ||
name == "gl_PositionPerViewNV")
return true;
return false;
}
// Do two structure types match? They could be declared independently, // Do two structure types match? They could be declared independently,
// in different places, but still might satisfy the definition of matching. // in different places, but still might satisfy the definition of matching.
// From the spec: // From the spec:
@ -2298,22 +2439,48 @@ public:
(isStruct() && right.isStruct() && structure == right.structure)) (isStruct() && right.isStruct() && structure == right.structure))
return true; return true;
// Both being nullptr was caught above, now they both have to be structures of the same number of elements
if (!isStruct() || !right.isStruct() ||
structure->size() != right.structure->size())
return false;
// Structure names have to match // Structure names have to match
if (*typeName != *right.typeName) if (*typeName != *right.typeName)
return false; return false;
// Compare the names and types of all the members, which have to match // There are inconsistencies with how gl_PerVertex is setup. For now ignore those as errors if they
for (unsigned int i = 0; i < structure->size(); ++i) { // are known inconsistencies.
if ((*structure)[i].type->getFieldName() != (*right.structure)[i].type->getFieldName()) bool isGLPerVertex = *typeName == "gl_PerVertex";
return false;
if (*(*structure)[i].type != *(*right.structure)[i].type) // Both being nullptr was caught above, now they both have to be structures of the same number of elements
return false; if (!isStruct() || !right.isStruct() ||
(structure->size() != right.structure->size() && !isGLPerVertex))
return false;
// Compare the names and types of all the members, which have to match
for (size_t li = 0, ri = 0; li < structure->size() || ri < right.structure->size(); ++li, ++ri) {
if (li < structure->size() && ri < right.structure->size()) {
if ((*structure)[li].type->getFieldName() == (*right.structure)[ri].type->getFieldName()) {
if (*(*structure)[li].type != *(*right.structure)[ri].type)
return false;
} else {
// If one of the members is something that's inconsistently declared, skip over it
// for now.
if (isGLPerVertex) {
if (isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName())) {
ri--;
continue;
} else if (isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName())) {
li--;
continue;
}
} else {
return false;
}
}
// If we get here, then there should only be inconsistently declared members left
} else if (li < structure->size()) {
if (!isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName()))
return false;
} else {
if (!isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName()))
return false;
}
} }
return true; return true;
@ -2363,6 +2530,15 @@ public:
(typeParameters != nullptr && right.typeParameters != nullptr && *typeParameters == *right.typeParameters)); (typeParameters != nullptr && right.typeParameters != nullptr && *typeParameters == *right.typeParameters));
} }
#ifndef GLSLANG_WEB
// See if two type's SPIR-V type contents match
bool sameSpirvType(const TType& right) const
{
return ((spirvType == nullptr && right.spirvType == nullptr) ||
(spirvType != nullptr && right.spirvType != nullptr && *spirvType == *right.spirvType));
}
#endif
// See if two type's elements match in all ways except basic type // See if two type's elements match in all ways except basic type
bool sameElementShape(const TType& right) const bool sameElementShape(const TType& right) const
{ {
@ -2401,7 +2577,11 @@ public:
// See if two types match in all ways (just the actual type, not qualification) // See if two types match in all ways (just the actual type, not qualification)
bool operator==(const TType& right) const bool operator==(const TType& right) const
{ {
#ifndef GLSLANG_WEB
return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right) && sameSpirvType(right);
#else
return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right); return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right);
#endif
} }
bool operator!=(const TType& right) const bool operator!=(const TType& right) const
@ -2420,6 +2600,10 @@ public:
return 0; return 0;
} }
#ifndef GLSLANG_WEB
const TSpirvType& getSpirvType() const { assert(spirvType); return *spirvType; }
#endif
protected: protected:
// Require consumer to pick between deep copy and shallow copy. // Require consumer to pick between deep copy and shallow copy.
TType(const TType& type); TType(const TType& type);
@ -2432,6 +2616,19 @@ protected:
{ {
shallowCopy(copyOf); shallowCopy(copyOf);
#ifndef GLSLANG_WEB
// GL_EXT_spirv_intrinsics
if (copyOf.qualifier.spirvDecorate) {
qualifier.spirvDecorate = new TSpirvDecorate;
*qualifier.spirvDecorate = *copyOf.qualifier.spirvDecorate;
}
if (copyOf.spirvType) {
spirvType = new TSpirvType;
*spirvType = *copyOf.spirvType;
}
#endif
if (copyOf.arraySizes) { if (copyOf.arraySizes) {
arraySizes = new TArraySizes; arraySizes = new TArraySizes;
*arraySizes = *copyOf.arraySizes; *arraySizes = *copyOf.arraySizes;
@ -2491,6 +2688,9 @@ protected:
TString *typeName; // for structure type name TString *typeName; // for structure type name
TSampler sampler; TSampler sampler;
TArraySizes* typeParameters;// nullptr unless a parameterized type; can be shared across types TArraySizes* typeParameters;// nullptr unless a parameterized type; can be shared across types
#ifndef GLSLANG_WEB
TSpirvType* spirvType; // SPIR-V type defined by spirv_type directive
#endif
}; };
} // end namespace glslang } // end namespace glslang

View file

@ -100,8 +100,9 @@ typedef enum {
typedef enum { typedef enum {
GLSLANG_TARGET_VULKAN_1_0 = (1 << 22), GLSLANG_TARGET_VULKAN_1_0 = (1 << 22),
GLSLANG_TARGET_VULKAN_1_1 = (1 << 22) | (1 << 12), GLSLANG_TARGET_VULKAN_1_1 = (1 << 22) | (1 << 12),
GLSLANG_TARGET_VULKAN_1_2 = (1 << 22) | (2 << 12),
GLSLANG_TARGET_OPENGL_450 = 450, GLSLANG_TARGET_OPENGL_450 = 450,
LAST_ELEMENT_MARKER(GLSLANG_TARGET_CLIENT_VERSION_COUNT), LAST_ELEMENT_MARKER(GLSLANG_TARGET_CLIENT_VERSION_COUNT = 4),
} glslang_target_client_version_t; } glslang_target_client_version_t;
/* SH_TARGET_LanguageVersion counterpart */ /* SH_TARGET_LanguageVersion counterpart */
@ -112,7 +113,7 @@ typedef enum {
GLSLANG_TARGET_SPV_1_3 = (1 << 16) | (3 << 8), GLSLANG_TARGET_SPV_1_3 = (1 << 16) | (3 << 8),
GLSLANG_TARGET_SPV_1_4 = (1 << 16) | (4 << 8), GLSLANG_TARGET_SPV_1_4 = (1 << 16) | (4 << 8),
GLSLANG_TARGET_SPV_1_5 = (1 << 16) | (5 << 8), GLSLANG_TARGET_SPV_1_5 = (1 << 16) | (5 << 8),
LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT), LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT = 6),
} glslang_target_language_version_t; } glslang_target_language_version_t;
/* EShExecutable counterpart */ /* EShExecutable counterpart */

View file

@ -71,6 +71,9 @@ enum TOperator {
EOpFunctionCall, EOpFunctionCall,
EOpFunction, // For function definition EOpFunction, // For function definition
EOpParameters, // an aggregate listing the parameters to a function EOpParameters, // an aggregate listing the parameters to a function
#ifndef GLSLANG_WEB
EOpSpirvInst,
#endif
// //
// Unary operators // Unary operators
@ -593,6 +596,7 @@ enum TOperator {
EOpTime, EOpTime,
EOpAtomicAdd, EOpAtomicAdd,
EOpAtomicSubtract,
EOpAtomicMin, EOpAtomicMin,
EOpAtomicMax, EOpAtomicMax,
EOpAtomicAnd, EOpAtomicAnd,
@ -922,6 +926,7 @@ enum TOperator {
EOpMul32x16, EOpMul32x16,
EOpTraceNV, EOpTraceNV,
EOpTraceRayMotionNV,
EOpTraceKHR, EOpTraceKHR,
EOpReportIntersection, EOpReportIntersection,
EOpIgnoreIntersectionNV, EOpIgnoreIntersectionNV,
@ -1135,6 +1140,8 @@ public:
virtual TBasicType getBasicType() const { return type.getBasicType(); } virtual TBasicType getBasicType() const { return type.getBasicType(); }
virtual TQualifier& getQualifier() { return type.getQualifier(); } virtual TQualifier& getQualifier() { return type.getQualifier(); }
virtual const TQualifier& getQualifier() const { return type.getQualifier(); } virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
virtual TArraySizes* getArraySizes() { return type.getArraySizes(); }
virtual const TArraySizes* getArraySizes() const { return type.getArraySizes(); }
virtual void propagatePrecision(TPrecisionQualifier); virtual void propagatePrecision(TPrecisionQualifier);
virtual int getVectorSize() const { return type.getVectorSize(); } virtual int getVectorSize() const { return type.getVectorSize(); }
virtual int getMatrixCols() const { return type.getMatrixCols(); } virtual int getMatrixCols() const { return type.getMatrixCols(); }
@ -1275,15 +1282,15 @@ public:
// if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from
// per process threadPoolAllocator, then it causes increased memory usage per compile // per process threadPoolAllocator, then it causes increased memory usage per compile
// it is essential to use "symbol = sym" to assign to symbol // it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(int i, const TString& n, const TType& t) TIntermSymbol(long long i, const TString& n, const TType& t)
: TIntermTyped(t), id(i), : TIntermTyped(t), id(i),
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
flattenSubset(-1), flattenSubset(-1),
#endif #endif
constSubtree(nullptr) constSubtree(nullptr)
{ name = n; } { name = n; }
virtual int getId() const { return id; } virtual long long getId() const { return id; }
virtual void changeId(int i) { id = i; } virtual void changeId(long long i) { id = i; }
virtual const TString& getName() const { return name; } virtual const TString& getName() const { return name; }
virtual void traverse(TIntermTraverser*); virtual void traverse(TIntermTraverser*);
virtual TIntermSymbol* getAsSymbolNode() { return this; } virtual TIntermSymbol* getAsSymbolNode() { return this; }
@ -1301,10 +1308,10 @@ public:
// This is meant for cases where a node has already been constructed, and // This is meant for cases where a node has already been constructed, and
// later on, it becomes necessary to switch to a different symbol. // later on, it becomes necessary to switch to a different symbol.
virtual void switchId(int newId) { id = newId; } virtual void switchId(long long newId) { id = newId; }
protected: protected:
int id; // the unique id of the symbol this node represents long long id; // the unique id of the symbol this node represents
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
#endif #endif
@ -1613,8 +1620,15 @@ public:
virtual TIntermUnary* getAsUnaryNode() { return this; } virtual TIntermUnary* getAsUnaryNode() { return this; }
virtual const TIntermUnary* getAsUnaryNode() const { return this; } virtual const TIntermUnary* getAsUnaryNode() const { return this; }
virtual void updatePrecision(); virtual void updatePrecision();
#ifndef GLSLANG_WEB
void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
#endif
protected: protected:
TIntermTyped* operand; TIntermTyped* operand;
#ifndef GLSLANG_WEB
TSpirvInstruction spirvInst;
#endif
}; };
typedef TVector<TIntermNode*> TIntermSequence; typedef TVector<TIntermNode*> TIntermSequence;
@ -1645,6 +1659,10 @@ public:
bool getDebug() const { return debug; } bool getDebug() const { return debug; }
void setPragmaTable(const TPragmaTable& pTable); void setPragmaTable(const TPragmaTable& pTable);
const TPragmaTable& getPragmaTable() const { return *pragmaTable; } const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
#ifndef GLSLANG_WEB
void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
#endif
protected: protected:
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
@ -1655,6 +1673,9 @@ protected:
bool optimize; bool optimize;
bool debug; bool debug;
TPragmaTable* pragmaTable; TPragmaTable* pragmaTable;
#ifndef GLSLANG_WEB
TSpirvInstruction spirvInst;
#endif
}; };
// //
@ -1672,8 +1693,11 @@ public:
flatten(false), dontFlatten(false) {} flatten(false), dontFlatten(false) {}
virtual void traverse(TIntermTraverser*); virtual void traverse(TIntermTraverser*);
virtual TIntermTyped* getCondition() const { return condition; } virtual TIntermTyped* getCondition() const { return condition; }
virtual void setCondition(TIntermTyped* c) { condition = c; }
virtual TIntermNode* getTrueBlock() const { return trueBlock; } virtual TIntermNode* getTrueBlock() const { return trueBlock; }
virtual void setTrueBlock(TIntermTyped* tb) { trueBlock = tb; }
virtual TIntermNode* getFalseBlock() const { return falseBlock; } virtual TIntermNode* getFalseBlock() const { return falseBlock; }
virtual void setFalseBlock(TIntermTyped* fb) { falseBlock = fb; }
virtual TIntermSelection* getAsSelectionNode() { return this; } virtual TIntermSelection* getAsSelectionNode() { return this; }
virtual const TIntermSelection* getAsSelectionNode() const { return this; } virtual const TIntermSelection* getAsSelectionNode() const { return this; }

View file

@ -529,7 +529,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EbtDouble: case EbtDouble:
case EbtFloat16: case EbtFloat16:
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break; case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break; // Note: avoid UBSAN error regarding negating 0x80000000
case EbtInt: newConstArray[i].setIConst(
unionArray[i].getIConst() == 0x80000000
? -0x7FFFFFFF - 1
: -unionArray[i].getIConst());
break;
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break; case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break; case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break;
@ -599,17 +604,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
newConstArray[i].setDConst(log(unionArray[i].getDConst())); newConstArray[i].setDConst(log(unionArray[i].getDConst()));
break; break;
case EOpExp2: case EOpExp2:
{ newConstArray[i].setDConst(exp2(unionArray[i].getDConst()));
const double inv_log2_e = 0.69314718055994530941723212145818; break;
newConstArray[i].setDConst(exp(unionArray[i].getDConst() * inv_log2_e));
break;
}
case EOpLog2: case EOpLog2:
{ newConstArray[i].setDConst(log2(unionArray[i].getDConst()));
const double log2_e = 1.4426950408889634073599246810019; break;
newConstArray[i].setDConst(log2_e * log(unionArray[i].getDConst()));
break;
}
case EOpSqrt: case EOpSqrt:
newConstArray[i].setDConst(sqrt(unionArray[i].getDConst())); newConstArray[i].setDConst(sqrt(unionArray[i].getDConst()));
break; break;

View file

@ -483,7 +483,8 @@ void TBuiltIns::relateTabledBuiltins(int /* version */, EProfile /* profile */,
inline bool IncludeLegacy(int version, EProfile profile, const SpvVersion& spvVersion) inline bool IncludeLegacy(int version, EProfile profile, const SpvVersion& spvVersion)
{ {
return profile != EEsProfile && (version <= 130 || (spvVersion.spv == 0 && ARBCompatibility) || profile == ECompatibilityProfile); return profile != EEsProfile && (version <= 130 || (spvVersion.spv == 0 && version == 140 && ARBCompatibility) ||
profile == ECompatibilityProfile);
} }
// Construct TBuiltInParseables base class. This can be used for language-common constructs. // Construct TBuiltInParseables base class. This can be used for language-common constructs.
@ -931,7 +932,203 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n"); "\n");
} }
if (profile != EEsProfile && version >= 450) { if (profile == EEsProfile && version >= 310) { // Explicit Types
commonBuiltins.append(
"float64_t sqrt(float64_t);"
"f64vec2 sqrt(f64vec2);"
"f64vec3 sqrt(f64vec3);"
"f64vec4 sqrt(f64vec4);"
"float64_t inversesqrt(float64_t);"
"f64vec2 inversesqrt(f64vec2);"
"f64vec3 inversesqrt(f64vec3);"
"f64vec4 inversesqrt(f64vec4);"
"float64_t abs(float64_t);"
"f64vec2 abs(f64vec2);"
"f64vec3 abs(f64vec3);"
"f64vec4 abs(f64vec4);"
"float64_t sign(float64_t);"
"f64vec2 sign(f64vec2);"
"f64vec3 sign(f64vec3);"
"f64vec4 sign(f64vec4);"
"float64_t floor(float64_t);"
"f64vec2 floor(f64vec2);"
"f64vec3 floor(f64vec3);"
"f64vec4 floor(f64vec4);"
"float64_t trunc(float64_t);"
"f64vec2 trunc(f64vec2);"
"f64vec3 trunc(f64vec3);"
"f64vec4 trunc(f64vec4);"
"float64_t round(float64_t);"
"f64vec2 round(f64vec2);"
"f64vec3 round(f64vec3);"
"f64vec4 round(f64vec4);"
"float64_t roundEven(float64_t);"
"f64vec2 roundEven(f64vec2);"
"f64vec3 roundEven(f64vec3);"
"f64vec4 roundEven(f64vec4);"
"float64_t ceil(float64_t);"
"f64vec2 ceil(f64vec2);"
"f64vec3 ceil(f64vec3);"
"f64vec4 ceil(f64vec4);"
"float64_t fract(float64_t);"
"f64vec2 fract(f64vec2);"
"f64vec3 fract(f64vec3);"
"f64vec4 fract(f64vec4);"
"float64_t mod(float64_t, float64_t);"
"f64vec2 mod(f64vec2 , float64_t);"
"f64vec3 mod(f64vec3 , float64_t);"
"f64vec4 mod(f64vec4 , float64_t);"
"f64vec2 mod(f64vec2 , f64vec2);"
"f64vec3 mod(f64vec3 , f64vec3);"
"f64vec4 mod(f64vec4 , f64vec4);"
"float64_t modf(float64_t, out float64_t);"
"f64vec2 modf(f64vec2, out f64vec2);"
"f64vec3 modf(f64vec3, out f64vec3);"
"f64vec4 modf(f64vec4, out f64vec4);"
"float64_t min(float64_t, float64_t);"
"f64vec2 min(f64vec2, float64_t);"
"f64vec3 min(f64vec3, float64_t);"
"f64vec4 min(f64vec4, float64_t);"
"f64vec2 min(f64vec2, f64vec2);"
"f64vec3 min(f64vec3, f64vec3);"
"f64vec4 min(f64vec4, f64vec4);"
"float64_t max(float64_t, float64_t);"
"f64vec2 max(f64vec2 , float64_t);"
"f64vec3 max(f64vec3 , float64_t);"
"f64vec4 max(f64vec4 , float64_t);"
"f64vec2 max(f64vec2 , f64vec2);"
"f64vec3 max(f64vec3 , f64vec3);"
"f64vec4 max(f64vec4 , f64vec4);"
"float64_t clamp(float64_t, float64_t, float64_t);"
"f64vec2 clamp(f64vec2 , float64_t, float64_t);"
"f64vec3 clamp(f64vec3 , float64_t, float64_t);"
"f64vec4 clamp(f64vec4 , float64_t, float64_t);"
"f64vec2 clamp(f64vec2 , f64vec2 , f64vec2);"
"f64vec3 clamp(f64vec3 , f64vec3 , f64vec3);"
"f64vec4 clamp(f64vec4 , f64vec4 , f64vec4);"
"float64_t mix(float64_t, float64_t, float64_t);"
"f64vec2 mix(f64vec2, f64vec2, float64_t);"
"f64vec3 mix(f64vec3, f64vec3, float64_t);"
"f64vec4 mix(f64vec4, f64vec4, float64_t);"
"f64vec2 mix(f64vec2, f64vec2, f64vec2);"
"f64vec3 mix(f64vec3, f64vec3, f64vec3);"
"f64vec4 mix(f64vec4, f64vec4, f64vec4);"
"float64_t mix(float64_t, float64_t, bool);"
"f64vec2 mix(f64vec2, f64vec2, bvec2);"
"f64vec3 mix(f64vec3, f64vec3, bvec3);"
"f64vec4 mix(f64vec4, f64vec4, bvec4);"
"float64_t step(float64_t, float64_t);"
"f64vec2 step(f64vec2 , f64vec2);"
"f64vec3 step(f64vec3 , f64vec3);"
"f64vec4 step(f64vec4 , f64vec4);"
"f64vec2 step(float64_t, f64vec2);"
"f64vec3 step(float64_t, f64vec3);"
"f64vec4 step(float64_t, f64vec4);"
"float64_t smoothstep(float64_t, float64_t, float64_t);"
"f64vec2 smoothstep(f64vec2 , f64vec2 , f64vec2);"
"f64vec3 smoothstep(f64vec3 , f64vec3 , f64vec3);"
"f64vec4 smoothstep(f64vec4 , f64vec4 , f64vec4);"
"f64vec2 smoothstep(float64_t, float64_t, f64vec2);"
"f64vec3 smoothstep(float64_t, float64_t, f64vec3);"
"f64vec4 smoothstep(float64_t, float64_t, f64vec4);"
"float64_t length(float64_t);"
"float64_t length(f64vec2);"
"float64_t length(f64vec3);"
"float64_t length(f64vec4);"
"float64_t distance(float64_t, float64_t);"
"float64_t distance(f64vec2 , f64vec2);"
"float64_t distance(f64vec3 , f64vec3);"
"float64_t distance(f64vec4 , f64vec4);"
"float64_t dot(float64_t, float64_t);"
"float64_t dot(f64vec2 , f64vec2);"
"float64_t dot(f64vec3 , f64vec3);"
"float64_t dot(f64vec4 , f64vec4);"
"f64vec3 cross(f64vec3, f64vec3);"
"float64_t normalize(float64_t);"
"f64vec2 normalize(f64vec2);"
"f64vec3 normalize(f64vec3);"
"f64vec4 normalize(f64vec4);"
"float64_t faceforward(float64_t, float64_t, float64_t);"
"f64vec2 faceforward(f64vec2, f64vec2, f64vec2);"
"f64vec3 faceforward(f64vec3, f64vec3, f64vec3);"
"f64vec4 faceforward(f64vec4, f64vec4, f64vec4);"
"float64_t reflect(float64_t, float64_t);"
"f64vec2 reflect(f64vec2 , f64vec2 );"
"f64vec3 reflect(f64vec3 , f64vec3 );"
"f64vec4 reflect(f64vec4 , f64vec4 );"
"float64_t refract(float64_t, float64_t, float64_t);"
"f64vec2 refract(f64vec2 , f64vec2 , float64_t);"
"f64vec3 refract(f64vec3 , f64vec3 , float64_t);"
"f64vec4 refract(f64vec4 , f64vec4 , float64_t);"
"f64mat2 matrixCompMult(f64mat2, f64mat2);"
"f64mat3 matrixCompMult(f64mat3, f64mat3);"
"f64mat4 matrixCompMult(f64mat4, f64mat4);"
"f64mat2x3 matrixCompMult(f64mat2x3, f64mat2x3);"
"f64mat2x4 matrixCompMult(f64mat2x4, f64mat2x4);"
"f64mat3x2 matrixCompMult(f64mat3x2, f64mat3x2);"
"f64mat3x4 matrixCompMult(f64mat3x4, f64mat3x4);"
"f64mat4x2 matrixCompMult(f64mat4x2, f64mat4x2);"
"f64mat4x3 matrixCompMult(f64mat4x3, f64mat4x3);"
"f64mat2 outerProduct(f64vec2, f64vec2);"
"f64mat3 outerProduct(f64vec3, f64vec3);"
"f64mat4 outerProduct(f64vec4, f64vec4);"
"f64mat2x3 outerProduct(f64vec3, f64vec2);"
"f64mat3x2 outerProduct(f64vec2, f64vec3);"
"f64mat2x4 outerProduct(f64vec4, f64vec2);"
"f64mat4x2 outerProduct(f64vec2, f64vec4);"
"f64mat3x4 outerProduct(f64vec4, f64vec3);"
"f64mat4x3 outerProduct(f64vec3, f64vec4);"
"f64mat2 transpose(f64mat2);"
"f64mat3 transpose(f64mat3);"
"f64mat4 transpose(f64mat4);"
"f64mat2x3 transpose(f64mat3x2);"
"f64mat3x2 transpose(f64mat2x3);"
"f64mat2x4 transpose(f64mat4x2);"
"f64mat4x2 transpose(f64mat2x4);"
"f64mat3x4 transpose(f64mat4x3);"
"f64mat4x3 transpose(f64mat3x4);"
"float64_t determinant(f64mat2);"
"float64_t determinant(f64mat3);"
"float64_t determinant(f64mat4);"
"f64mat2 inverse(f64mat2);"
"f64mat3 inverse(f64mat3);"
"f64mat4 inverse(f64mat4);"
"\n");
}
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) {
commonBuiltins.append( commonBuiltins.append(
"int64_t abs(int64_t);" "int64_t abs(int64_t);"
@ -998,25 +1195,25 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"u64vec3 mix(u64vec3, u64vec3, bvec3);" "u64vec3 mix(u64vec3, u64vec3, bvec3);"
"u64vec4 mix(u64vec4, u64vec4, bvec4);" "u64vec4 mix(u64vec4, u64vec4, bvec4);"
"int64_t doubleBitsToInt64(double);" "int64_t doubleBitsToInt64(float64_t);"
"i64vec2 doubleBitsToInt64(dvec2);" "i64vec2 doubleBitsToInt64(f64vec2);"
"i64vec3 doubleBitsToInt64(dvec3);" "i64vec3 doubleBitsToInt64(f64vec3);"
"i64vec4 doubleBitsToInt64(dvec4);" "i64vec4 doubleBitsToInt64(f64vec4);"
"uint64_t doubleBitsToUint64(double);" "uint64_t doubleBitsToUint64(float64_t);"
"u64vec2 doubleBitsToUint64(dvec2);" "u64vec2 doubleBitsToUint64(f64vec2);"
"u64vec3 doubleBitsToUint64(dvec3);" "u64vec3 doubleBitsToUint64(f64vec3);"
"u64vec4 doubleBitsToUint64(dvec4);" "u64vec4 doubleBitsToUint64(f64vec4);"
"double int64BitsToDouble(int64_t);" "float64_t int64BitsToDouble(int64_t);"
"dvec2 int64BitsToDouble(i64vec2);" "f64vec2 int64BitsToDouble(i64vec2);"
"dvec3 int64BitsToDouble(i64vec3);" "f64vec3 int64BitsToDouble(i64vec3);"
"dvec4 int64BitsToDouble(i64vec4);" "f64vec4 int64BitsToDouble(i64vec4);"
"double uint64BitsToDouble(uint64_t);" "float64_t uint64BitsToDouble(uint64_t);"
"dvec2 uint64BitsToDouble(u64vec2);" "f64vec2 uint64BitsToDouble(u64vec2);"
"dvec3 uint64BitsToDouble(u64vec3);" "f64vec3 uint64BitsToDouble(u64vec3);"
"dvec4 uint64BitsToDouble(u64vec4);" "f64vec4 uint64BitsToDouble(u64vec4);"
"int64_t packInt2x32(ivec2);" "int64_t packInt2x32(ivec2);"
"uint64_t packUint2x32(uvec2);" "uint64_t packUint2x32(uvec2);"
@ -1065,6 +1262,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"bvec3 notEqual(u64vec3, u64vec3);" "bvec3 notEqual(u64vec3, u64vec3);"
"bvec4 notEqual(u64vec4, u64vec4);" "bvec4 notEqual(u64vec4, u64vec4);"
"int64_t bitCount(int64_t);"
"i64vec2 bitCount(i64vec2);"
"i64vec3 bitCount(i64vec3);"
"i64vec4 bitCount(i64vec4);"
"int64_t bitCount(uint64_t);"
"i64vec2 bitCount(u64vec2);"
"i64vec3 bitCount(u64vec3);"
"i64vec4 bitCount(u64vec4);"
"int64_t findLSB(int64_t);" "int64_t findLSB(int64_t);"
"i64vec2 findLSB(i64vec2);" "i64vec2 findLSB(i64vec2);"
"i64vec3 findLSB(i64vec3);" "i64vec3 findLSB(i64vec3);"
@ -1230,11 +1437,23 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
" int64_t atomicMin(coherent volatile inout int64_t, int64_t);" " int64_t atomicMin(coherent volatile inout int64_t, int64_t);"
"uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t, int, int, int);" "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t, int, int, int);"
" int64_t atomicMin(coherent volatile inout int64_t, int64_t, int, int, int);" " int64_t atomicMin(coherent volatile inout int64_t, int64_t, int, int, int);"
"float16_t atomicMin(coherent volatile inout float16_t, float16_t);"
"float16_t atomicMin(coherent volatile inout float16_t, float16_t, int, int, int);"
" float atomicMin(coherent volatile inout float, float);"
" float atomicMin(coherent volatile inout float, float, int, int, int);"
" double atomicMin(coherent volatile inout double, double);"
" double atomicMin(coherent volatile inout double, double, int, int, int);"
"uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);" "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);"
" int64_t atomicMax(coherent volatile inout int64_t, int64_t);" " int64_t atomicMax(coherent volatile inout int64_t, int64_t);"
"uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t, int, int, int);" "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t, int, int, int);"
" int64_t atomicMax(coherent volatile inout int64_t, int64_t, int, int, int);" " int64_t atomicMax(coherent volatile inout int64_t, int64_t, int, int, int);"
"float16_t atomicMax(coherent volatile inout float16_t, float16_t);"
"float16_t atomicMax(coherent volatile inout float16_t, float16_t, int, int, int);"
" float atomicMax(coherent volatile inout float, float);"
" float atomicMax(coherent volatile inout float, float, int, int, int);"
" double atomicMax(coherent volatile inout double, double);"
" double atomicMax(coherent volatile inout double, double, int, int, int);"
"uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);" "uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);"
" int64_t atomicAnd(coherent volatile inout int64_t, int64_t);" " int64_t atomicAnd(coherent volatile inout int64_t, int64_t);"
@ -1255,6 +1474,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
" int64_t atomicAdd(coherent volatile inout int64_t, int64_t);" " int64_t atomicAdd(coherent volatile inout int64_t, int64_t);"
"uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);" "uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);"
" int64_t atomicAdd(coherent volatile inout int64_t, int64_t, int, int, int);" " int64_t atomicAdd(coherent volatile inout int64_t, int64_t, int, int, int);"
"float16_t atomicAdd(coherent volatile inout float16_t, float16_t);"
"float16_t atomicAdd(coherent volatile inout float16_t, float16_t, int, int, int);"
" float atomicAdd(coherent volatile inout float, float);" " float atomicAdd(coherent volatile inout float, float);"
" float atomicAdd(coherent volatile inout float, float, int, int, int);" " float atomicAdd(coherent volatile inout float, float, int, int, int);"
" double atomicAdd(coherent volatile inout double, double);" " double atomicAdd(coherent volatile inout double, double);"
@ -1264,6 +1485,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
" int64_t atomicExchange(coherent volatile inout int64_t, int64_t);" " int64_t atomicExchange(coherent volatile inout int64_t, int64_t);"
"uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);" "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);"
" int64_t atomicExchange(coherent volatile inout int64_t, int64_t, int, int, int);" " int64_t atomicExchange(coherent volatile inout int64_t, int64_t, int, int, int);"
"float16_t atomicExchange(coherent volatile inout float16_t, float16_t);"
"float16_t atomicExchange(coherent volatile inout float16_t, float16_t, int, int, int);"
" float atomicExchange(coherent volatile inout float, float);" " float atomicExchange(coherent volatile inout float, float);"
" float atomicExchange(coherent volatile inout float, float, int, int, int);" " float atomicExchange(coherent volatile inout float, float, int, int, int);"
" double atomicExchange(coherent volatile inout double, double);" " double atomicExchange(coherent volatile inout double, double);"
@ -1276,11 +1499,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);" "uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);"
" int64_t atomicLoad(coherent volatile in int64_t, int, int, int);" " int64_t atomicLoad(coherent volatile in int64_t, int, int, int);"
"float16_t atomicLoad(coherent volatile in float16_t, int, int, int);"
" float atomicLoad(coherent volatile in float, int, int, int);" " float atomicLoad(coherent volatile in float, int, int, int);"
" double atomicLoad(coherent volatile in double, int, int, int);" " double atomicLoad(coherent volatile in double, int, int, int);"
"void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);" "void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);"
"void atomicStore(coherent volatile out int64_t, int64_t, int, int, int);" "void atomicStore(coherent volatile out int64_t, int64_t, int, int, int);"
"void atomicStore(coherent volatile out float16_t, float16_t, int, int, int);"
"void atomicStore(coherent volatile out float, float, int, int, int);" "void atomicStore(coherent volatile out float, float, int, int, int);"
"void atomicStore(coherent volatile out double, double, int, int, int);" "void atomicStore(coherent volatile out double, double, int, int, int);"
"\n"); "\n");
@ -1335,6 +1560,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"dvec4 fma(dvec4, dvec4, dvec4 );" "dvec4 fma(dvec4, dvec4, dvec4 );"
"\n"); "\n");
} }
if (profile == EEsProfile && version >= 310) { // ARB_gpu_shader_fp64
commonBuiltins.append(
"float64_t fma(float64_t, float64_t, float64_t);"
"f64vec2 fma(f64vec2, f64vec2, f64vec2 );"
"f64vec3 fma(f64vec3, f64vec3, f64vec3 );"
"f64vec4 fma(f64vec4, f64vec4, f64vec4 );"
"\n");
}
#endif #endif
if ((profile == EEsProfile && version >= 310) || if ((profile == EEsProfile && version >= 310) ||
@ -1371,6 +1605,21 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n"); "\n");
} }
if (profile == EEsProfile && version >= 310) { // ARB_gpu_shader_fp64
commonBuiltins.append(
"float64_t frexp(float64_t, out int);"
"f64vec2 frexp( f64vec2, out ivec2);"
"f64vec3 frexp( f64vec3, out ivec3);"
"f64vec4 frexp( f64vec4, out ivec4);"
"float64_t ldexp(float64_t, int);"
"f64vec2 ldexp( f64vec2, ivec2);"
"f64vec3 ldexp( f64vec3, ivec3);"
"f64vec4 ldexp( f64vec4, ivec4);"
"\n");
}
#endif #endif
#endif #endif
@ -1615,6 +1864,22 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n"); "\n");
} }
if (profile != EEsProfile && version == 450) {
commonBuiltins.append(
"uint atomicCounterAddARB(atomic_uint, uint);"
"uint atomicCounterSubtractARB(atomic_uint, uint);"
"uint atomicCounterMinARB(atomic_uint, uint);"
"uint atomicCounterMaxARB(atomic_uint, uint);"
"uint atomicCounterAndARB(atomic_uint, uint);"
"uint atomicCounterOrARB(atomic_uint, uint);"
"uint atomicCounterXorARB(atomic_uint, uint);"
"uint atomicCounterExchangeARB(atomic_uint, uint);"
"uint atomicCounterCompSwapARB(atomic_uint, uint, uint);"
"\n");
}
if (profile != EEsProfile && version >= 460) { if (profile != EEsProfile && version >= 460) {
commonBuiltins.append( commonBuiltins.append(
"uint atomicCounterAdd(atomic_uint, uint);" "uint atomicCounterAdd(atomic_uint, uint);"
@ -1627,6 +1892,36 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"uint atomicCounterExchange(atomic_uint, uint);" "uint atomicCounterExchange(atomic_uint, uint);"
"uint atomicCounterCompSwap(atomic_uint, uint, uint);" "uint atomicCounterCompSwap(atomic_uint, uint, uint);"
"\n");
}
}
else if (spvVersion.vulkanRelaxed) {
//
// Atomic counter functions act as aliases to normal atomic functions.
// replace definitions to take 'volatile coherent uint' instead of 'atomic_uint'
// and map to equivalent non-counter atomic op
//
if ((profile != EEsProfile && version >= 300) ||
(profile == EEsProfile && version >= 310)) {
commonBuiltins.append(
"uint atomicCounterIncrement(volatile coherent uint);"
"uint atomicCounterDecrement(volatile coherent uint);"
"uint atomicCounter(volatile coherent uint);"
"\n");
}
if (profile != EEsProfile && version >= 460) {
commonBuiltins.append(
"uint atomicCounterAdd(volatile coherent uint, uint);"
"uint atomicCounterSubtract(volatile coherent uint, uint);"
"uint atomicCounterMin(volatile coherent uint, uint);"
"uint atomicCounterMax(volatile coherent uint, uint);"
"uint atomicCounterAnd(volatile coherent uint, uint);"
"uint atomicCounterOr(volatile coherent uint, uint);"
"uint atomicCounterXor(volatile coherent uint, uint);"
"uint atomicCounterExchange(volatile coherent uint, uint);"
"uint atomicCounterCompSwap(volatile coherent uint, uint, uint);"
"\n"); "\n");
} }
} }
@ -3116,7 +3411,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
#ifndef GLSLANG_ANGLE #ifndef GLSLANG_ANGLE
// GL_AMD_gpu_shader_half_float/Explicit types // GL_AMD_gpu_shader_half_float/Explicit types
if (profile != EEsProfile && version >= 450) { if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) {
commonBuiltins.append( commonBuiltins.append(
"float16_t radians(float16_t);" "float16_t radians(float16_t);"
"f16vec2 radians(f16vec2);" "f16vec2 radians(f16vec2);"
@ -3464,7 +3759,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
} }
// Explicit types // Explicit types
if (profile != EEsProfile && version >= 450) { if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) {
commonBuiltins.append( commonBuiltins.append(
"int8_t abs(int8_t);" "int8_t abs(int8_t);"
"i8vec2 abs(i8vec2);" "i8vec2 abs(i8vec2);"
@ -4124,7 +4419,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
} }
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
if ((profile != EEsProfile && version >= 420) || esBarrier) { if ((profile != EEsProfile && version >= 420) || esBarrier) {
if (spvVersion.vulkan == 0) { if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed) {
commonBuiltins.append("void memoryBarrierAtomicCounter();"); commonBuiltins.append("void memoryBarrierAtomicCounter();");
} }
commonBuiltins.append("void memoryBarrierImage();"); commonBuiltins.append("void memoryBarrierImage();");
@ -4382,7 +4677,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n"); "\n");
} }
// Builtins for GL_NV_ray_tracing/GL_EXT_ray_tracing/GL_EXT_ray_query // Builtins for GL_NV_ray_tracing/GL_NV_ray_tracing_motion_blur/GL_EXT_ray_tracing/GL_EXT_ray_query
if (profile != EEsProfile && version >= 460) { if (profile != EEsProfile && version >= 460) {
commonBuiltins.append("void rayQueryInitializeEXT(rayQueryEXT, accelerationStructureEXT, uint, uint, vec3, float, vec3, float);" commonBuiltins.append("void rayQueryInitializeEXT(rayQueryEXT, accelerationStructureEXT, uint, uint, vec3, float, vec3, float);"
"void rayQueryTerminateEXT(rayQueryEXT);" "void rayQueryTerminateEXT(rayQueryEXT);"
@ -4411,6 +4706,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangRayGen].append( stageBuiltins[EShLangRayGen].append(
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void executeCallableNV(uint, int);" "void executeCallableNV(uint, int);"
"void executeCallableEXT(uint, int);" "void executeCallableEXT(uint, int);"
@ -4425,12 +4721,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n"); "\n");
stageBuiltins[EShLangClosestHit].append( stageBuiltins[EShLangClosestHit].append(
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void executeCallableNV(uint, int);" "void executeCallableNV(uint, int);"
"void executeCallableEXT(uint, int);" "void executeCallableEXT(uint, int);"
"\n"); "\n");
stageBuiltins[EShLangMiss].append( stageBuiltins[EShLangMiss].append(
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void executeCallableNV(uint, int);" "void executeCallableNV(uint, int);"
"void executeCallableEXT(uint, int);" "void executeCallableEXT(uint, int);"
@ -4848,6 +5146,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in int gl_VertexIndex;" "in int gl_VertexIndex;"
"in int gl_InstanceIndex;" "in int gl_InstanceIndex;"
); );
if (spvVersion.vulkan > 0 && version >= 140 && spvVersion.vulkanRelaxed)
stageBuiltins[EShLangVertex].append(
"in int gl_VertexID;" // declare with 'in' qualifier
"in int gl_InstanceID;"
);
if (version >= 440) { if (version >= 440) {
stageBuiltins[EShLangVertex].append( stageBuiltins[EShLangVertex].append(
"in int gl_BaseVertexARB;" "in int gl_BaseVertexARB;"
@ -4885,7 +5190,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"mediump float gl_PointSize;" // needs qualifier fixed later "mediump float gl_PointSize;" // needs qualifier fixed later
); );
} else { } else {
if (spvVersion.vulkan == 0) if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed)
stageBuiltins[EShLangVertex].append( stageBuiltins[EShLangVertex].append(
"in highp int gl_VertexID;" // needs qualifier fixed later "in highp int gl_VertexID;" // needs qualifier fixed later
"in highp int gl_InstanceID;" // needs qualifier fixed later "in highp int gl_InstanceID;" // needs qualifier fixed later
@ -5632,6 +5937,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in mat3x4 gl_WorldToObject3x4EXT;" "in mat3x4 gl_WorldToObject3x4EXT;"
"in uint gl_IncomingRayFlagsNV;" "in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;" "in uint gl_IncomingRayFlagsEXT;"
"in float gl_CurrentRayTimeNV;"
"\n"; "\n";
const char *hitDecls = const char *hitDecls =
"in uvec3 gl_LaunchIDNV;" "in uvec3 gl_LaunchIDNV;"
@ -5667,6 +5973,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in mat3x4 gl_WorldToObject3x4EXT;" "in mat3x4 gl_WorldToObject3x4EXT;"
"in uint gl_IncomingRayFlagsNV;" "in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;" "in uint gl_IncomingRayFlagsEXT;"
"in float gl_CurrentRayTimeNV;"
"\n"; "\n";
const char *missDecls = const char *missDecls =
"in uvec3 gl_LaunchIDNV;" "in uvec3 gl_LaunchIDNV;"
@ -5685,6 +5992,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in float gl_RayTmaxEXT;" "in float gl_RayTmaxEXT;"
"in uint gl_IncomingRayFlagsNV;" "in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;" "in uint gl_IncomingRayFlagsEXT;"
"in float gl_CurrentRayTimeNV;"
"\n"; "\n";
const char *callableDecls = const char *callableDecls =
@ -6211,6 +6519,24 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
commonBuiltins.append(imageParams); commonBuiltins.append(imageParams);
commonBuiltins.append(", float"); commonBuiltins.append(", float");
commonBuiltins.append(", int, int, int);\n"); commonBuiltins.append(", int, int, int);\n");
commonBuiltins.append("float imageAtomicMin(volatile coherent ");
commonBuiltins.append(imageParams);
commonBuiltins.append(", float);\n");
commonBuiltins.append("float imageAtomicMin(volatile coherent ");
commonBuiltins.append(imageParams);
commonBuiltins.append(", float");
commonBuiltins.append(", int, int, int);\n");
commonBuiltins.append("float imageAtomicMax(volatile coherent ");
commonBuiltins.append(imageParams);
commonBuiltins.append(", float);\n");
commonBuiltins.append("float imageAtomicMax(volatile coherent ");
commonBuiltins.append(imageParams);
commonBuiltins.append(", float");
commonBuiltins.append(", int, int, int);\n");
} }
} }
} }
@ -6538,7 +6864,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
s.append(");\n"); s.append(");\n");
// Add to the per-language set of built-ins // Add to the per-language set of built-ins
if (bias || lodClamp != 0) { if (!grad && (bias || lodClamp != 0)) {
stageBuiltins[EShLangFragment].append(s); stageBuiltins[EShLangFragment].append(s);
stageBuiltins[EShLangCompute].append(s); stageBuiltins[EShLangCompute].append(s);
} else } else
@ -6979,6 +7305,9 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentUniformVectors = %d;", resources.maxFragmentUniformVectors); snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentUniformVectors = %d;", resources.maxFragmentUniformVectors);
s.append(builtInConstant); s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingVectors = %d;", resources.maxVaryingVectors);
s.append(builtInConstant);
} }
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs); snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs);
@ -7011,7 +7340,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents); snprintf(builtInConstant, maxSize, "const int gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents);
s.append(builtInConstant); s.append(builtInConstant);
if (version < 150 || ARBCompatibility) { // Moved from just being deprecated into compatibility profile only as of 4.20
if (version < 420 || profile == ECompatibilityProfile) {
snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats); snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats);
s.append(builtInConstant); s.append(builtInConstant);
} }
@ -7436,6 +7766,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
} }
if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
// treat these built-ins as aliases of VertexIndex and InstanceIndex
BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable);
BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable);
}
if (profile != EEsProfile) { if (profile != EEsProfile) {
if (version >= 440) { if (version >= 440) {
symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters); symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters);
@ -7947,6 +8283,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("atomicCounter" , 1, &E_GL_ARB_shader_atomic_counters); symbolTable.setFunctionExtensions("atomicCounter" , 1, &E_GL_ARB_shader_atomic_counters);
} }
// E_GL_ARB_shader_atomic_counter_ops
if (profile != EEsProfile && version == 450) {
symbolTable.setFunctionExtensions("atomicCounterAddARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterSubtractARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterMinARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterMaxARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterAndARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterOrARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterXorARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterExchangeARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
symbolTable.setFunctionExtensions("atomicCounterCompSwapARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
}
// E_GL_ARB_derivative_control // E_GL_ARB_derivative_control
if (profile != EEsProfile && version < 450) { if (profile != EEsProfile && version < 450) {
symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_ARB_derivative_control); symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_ARB_derivative_control);
@ -8475,11 +8824,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setVariableExtensions("gl_WorldToObject3x4EXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_WorldToObject3x4EXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setVariableExtensions("gl_IncomingRayFlagsNV", 1, &E_GL_NV_ray_tracing); symbolTable.setVariableExtensions("gl_IncomingRayFlagsNV", 1, &E_GL_NV_ray_tracing);
symbolTable.setVariableExtensions("gl_IncomingRayFlagsEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_IncomingRayFlagsEXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setVariableExtensions("gl_CurrentRayTimeNV", 1, &E_GL_NV_ray_tracing_motion_blur);
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
symbolTable.setFunctionExtensions("traceNV", 1, &E_GL_NV_ray_tracing); symbolTable.setFunctionExtensions("traceNV", 1, &E_GL_NV_ray_tracing);
symbolTable.setFunctionExtensions("traceRayMotionNV", 1, &E_GL_NV_ray_tracing_motion_blur);
symbolTable.setFunctionExtensions("traceRayEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setFunctionExtensions("traceRayEXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setFunctionExtensions("reportIntersectionNV", 1, &E_GL_NV_ray_tracing); symbolTable.setFunctionExtensions("reportIntersectionNV", 1, &E_GL_NV_ray_tracing);
symbolTable.setFunctionExtensions("reportIntersectionEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setFunctionExtensions("reportIntersectionEXT", 1, &E_GL_EXT_ray_tracing);
@ -8523,6 +8874,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
BuiltInVariable("gl_IncomingRayFlagsNV", EbvIncomingRayFlags, symbolTable); BuiltInVariable("gl_IncomingRayFlagsNV", EbvIncomingRayFlags, symbolTable);
BuiltInVariable("gl_IncomingRayFlagsEXT", EbvIncomingRayFlags, symbolTable); BuiltInVariable("gl_IncomingRayFlagsEXT", EbvIncomingRayFlags, symbolTable);
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
BuiltInVariable("gl_CurrentRayTimeNV", EbvCurrentRayTimeNV, symbolTable);
// GL_ARB_shader_ballot // GL_ARB_shader_ballot
symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot);
@ -8912,6 +9264,14 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter); symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter);
symbolTable.relateToOperator("memoryBarrierImage", EOpMemoryBarrierImage); symbolTable.relateToOperator("memoryBarrierImage", EOpMemoryBarrierImage);
if (spvVersion.vulkanRelaxed) {
//
// functions signature have been replaced to take uint operations on buffer variables
// remap atomic counter functions to atomic operations
//
symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierBuffer);
}
symbolTable.relateToOperator("atomicLoad", EOpAtomicLoad); symbolTable.relateToOperator("atomicLoad", EOpAtomicLoad);
symbolTable.relateToOperator("atomicStore", EOpAtomicStore); symbolTable.relateToOperator("atomicStore", EOpAtomicStore);
@ -8919,12 +9279,38 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement); symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement);
symbolTable.relateToOperator("atomicCounter", EOpAtomicCounter); symbolTable.relateToOperator("atomicCounter", EOpAtomicCounter);
if (spvVersion.vulkanRelaxed) {
//
// functions signature have been replaced to take uint operations
// remap atomic counter functions to atomic operations
//
// these atomic counter functions do not match signatures of glsl
// atomic functions, so they will be remapped to semantically
// equivalent functions in the parser
//
symbolTable.relateToOperator("atomicCounterIncrement", EOpNull);
symbolTable.relateToOperator("atomicCounterDecrement", EOpNull);
symbolTable.relateToOperator("atomicCounter", EOpNull);
}
symbolTable.relateToOperator("clockARB", EOpReadClockSubgroupKHR); symbolTable.relateToOperator("clockARB", EOpReadClockSubgroupKHR);
symbolTable.relateToOperator("clock2x32ARB", EOpReadClockSubgroupKHR); symbolTable.relateToOperator("clock2x32ARB", EOpReadClockSubgroupKHR);
symbolTable.relateToOperator("clockRealtimeEXT", EOpReadClockDeviceKHR); symbolTable.relateToOperator("clockRealtimeEXT", EOpReadClockDeviceKHR);
symbolTable.relateToOperator("clockRealtime2x32EXT", EOpReadClockDeviceKHR); symbolTable.relateToOperator("clockRealtime2x32EXT", EOpReadClockDeviceKHR);
if (profile != EEsProfile && version == 450) {
symbolTable.relateToOperator("atomicCounterAddARB", EOpAtomicCounterAdd);
symbolTable.relateToOperator("atomicCounterSubtractARB", EOpAtomicCounterSubtract);
symbolTable.relateToOperator("atomicCounterMinARB", EOpAtomicCounterMin);
symbolTable.relateToOperator("atomicCounterMaxARB", EOpAtomicCounterMax);
symbolTable.relateToOperator("atomicCounterAndARB", EOpAtomicCounterAnd);
symbolTable.relateToOperator("atomicCounterOrARB", EOpAtomicCounterOr);
symbolTable.relateToOperator("atomicCounterXorARB", EOpAtomicCounterXor);
symbolTable.relateToOperator("atomicCounterExchangeARB", EOpAtomicCounterExchange);
symbolTable.relateToOperator("atomicCounterCompSwapARB", EOpAtomicCounterCompSwap);
}
if (profile != EEsProfile && version >= 460) { if (profile != EEsProfile && version >= 460) {
symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicCounterAdd); symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicCounterAdd);
symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicCounterSubtract); symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicCounterSubtract);
@ -8937,6 +9323,23 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("atomicCounterCompSwap", EOpAtomicCounterCompSwap); symbolTable.relateToOperator("atomicCounterCompSwap", EOpAtomicCounterCompSwap);
} }
if (spvVersion.vulkanRelaxed) {
//
// functions signature have been replaced to take 'uint' instead of 'atomic_uint'
// remap atomic counter functions to non-counter atomic ops so
// functions act as aliases to non-counter atomic ops
//
symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicAdd);
symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicSubtract);
symbolTable.relateToOperator("atomicCounterMin", EOpAtomicMin);
symbolTable.relateToOperator("atomicCounterMax", EOpAtomicMax);
symbolTable.relateToOperator("atomicCounterAnd", EOpAtomicAnd);
symbolTable.relateToOperator("atomicCounterOr", EOpAtomicOr);
symbolTable.relateToOperator("atomicCounterXor", EOpAtomicXor);
symbolTable.relateToOperator("atomicCounterExchange", EOpAtomicExchange);
symbolTable.relateToOperator("atomicCounterCompSwap", EOpAtomicCompSwap);
}
symbolTable.relateToOperator("fma", EOpFma); symbolTable.relateToOperator("fma", EOpFma);
symbolTable.relateToOperator("frexp", EOpFrexp); symbolTable.relateToOperator("frexp", EOpFrexp);
symbolTable.relateToOperator("ldexp", EOpLdexp); symbolTable.relateToOperator("ldexp", EOpLdexp);
@ -9315,6 +9718,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
case EShLangMiss: case EShLangMiss:
if (profile != EEsProfile && version >= 460) { if (profile != EEsProfile && version >= 460) {
symbolTable.relateToOperator("traceNV", EOpTraceNV); symbolTable.relateToOperator("traceNV", EOpTraceNV);
symbolTable.relateToOperator("traceRayMotionNV", EOpTraceRayMotionNV);
symbolTable.relateToOperator("traceRayEXT", EOpTraceKHR); symbolTable.relateToOperator("traceRayEXT", EOpTraceKHR);
symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV); symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV);
symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR); symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR);

View file

@ -65,7 +65,7 @@ namespace glslang {
// Returns the added node. // Returns the added node.
// //
TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray, TIntermSymbol* TIntermediate::addSymbol(long long id, const TString& name, const TType& type, const TConstUnionArray& constArray,
TIntermTyped* constSubtree, const TSourceLoc& loc) TIntermTyped* constSubtree, const TSourceLoc& loc)
{ {
TIntermSymbol* node = new TIntermSymbol(id, name, type); TIntermSymbol* node = new TIntermSymbol(id, name, type);
@ -1739,7 +1739,7 @@ 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 || IsRequestedExtension(E_GL_ARB_gpu_shader5);
case EbtBool: case EbtBool:
return getSource() == EShSourceHlsl; return getSource() == EShSourceHlsl;
case EbtInt16: case EbtInt16:
@ -2676,7 +2676,11 @@ TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selecto
// 'swizzleOkay' says whether or not it is okay to consider a swizzle // 'swizzleOkay' says whether or not it is okay to consider a swizzle
// a valid part of the dereference chain. // a valid part of the dereference chain.
// //
const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay) // 'BufferReferenceOk' says if type is buffer_reference, the routine stop to find the most left node.
//
//
const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay , bool bufferReferenceOk)
{ {
do { do {
const TIntermBinary* binary = node->getAsBinaryNode(); const TIntermBinary* binary = node->getAsBinaryNode();
@ -2694,6 +2698,8 @@ const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool
return nullptr; return nullptr;
} }
node = node->getAsBinaryNode()->getLeft(); node = node->getAsBinaryNode()->getLeft();
if (bufferReferenceOk && node->isReference())
return node;
} while (true); } while (true);
} }
@ -2870,7 +2876,7 @@ void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& calle
return; return;
} }
callGraph.push_front(TCall(caller, callee)); callGraph.emplace_front(caller, callee);
} }
// //
@ -3776,11 +3782,16 @@ void TIntermBinary::updatePrecision()
{ {
if (getBasicType() == EbtInt || getBasicType() == EbtUint || if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision); if (op == EOpRightShift || op == EOpLeftShift) {
if (getQualifier().precision != EpqNone) { // For shifts get precision from left side only and thus no need to propagate
left->propagatePrecision(getQualifier().precision); getQualifier().precision = left->getQualifier().precision;
right->propagatePrecision(getQualifier().precision); } else {
} getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
if (getQualifier().precision != EpqNone) {
left->propagatePrecision(getQualifier().precision);
right->propagatePrecision(getQualifier().precision);
}
}
} }
} }

View file

@ -601,7 +601,6 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin
selector.push_back(0); selector.push_back(0);
} }
#ifdef ENABLE_HLSL
// //
// Make the passed-in variable information become a member of the // Make the passed-in variable information become a member of the
// global uniform block. If this doesn't exist yet, make it. // global uniform block. If this doesn't exist yet, make it.
@ -646,7 +645,67 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
++firstNewMember; ++firstNewMember;
} }
#endif
void TParseContextBase::growAtomicCounterBlock(int binding, const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList) {
// Make the atomic counter block, if not yet made.
const auto &at = atomicCounterBuffers.find(binding);
if (at == atomicCounterBuffers.end()) {
atomicCounterBuffers.insert({binding, (TVariable*)nullptr });
atomicCounterBlockFirstNewMember.insert({binding, 0});
}
TVariable*& atomicCounterBuffer = atomicCounterBuffers[binding];
int& bufferNewMember = atomicCounterBlockFirstNewMember[binding];
if (atomicCounterBuffer == nullptr) {
TQualifier blockQualifier;
blockQualifier.clear();
blockQualifier.storage = EvqBuffer;
char charBuffer[512];
if (binding != TQualifier::layoutBindingEnd) {
snprintf(charBuffer, 512, "%s_%d", getAtomicCounterBlockName(), binding);
} else {
snprintf(charBuffer, 512, "%s_0", getAtomicCounterBlockName());
}
TType blockType(new TTypeList, *NewPoolTString(charBuffer), blockQualifier);
setUniformBlockDefaults(blockType);
blockType.getQualifier().layoutPacking = ElpStd430;
atomicCounterBuffer = new TVariable(NewPoolTString(""), blockType, true);
// If we arn't auto mapping bindings then set the block to use the same
// binding as what the atomic was set to use
if (!intermediate.getAutoMapBindings()) {
atomicCounterBuffer->getWritableType().getQualifier().layoutBinding = binding;
}
bufferNewMember = 0;
atomicCounterBuffer->getWritableType().getQualifier().layoutSet = atomicCounterBlockSet;
}
// Add the requested member as a member to the global block.
TType* type = new TType;
type->shallowCopy(memberType);
type->setFieldName(memberName);
if (typeList)
type->setStruct(typeList);
TTypeLoc typeLoc = {type, loc};
atomicCounterBuffer->getType().getWritableStruct()->push_back(typeLoc);
// Insert into the symbol table.
if (bufferNewMember == 0) {
// This is the first request; we need a normal symbol table insert
if (symbolTable.insert(*atomicCounterBuffer))
trackLinkage(*atomicCounterBuffer);
else
error(loc, "failed to insert the global constant buffer", "buffer", "");
} else {
// This is a follow-on request; we need to amend the first insert
symbolTable.amend(*atomicCounterBuffer, bufferNewMember);
}
++bufferNewMember;
}
void TParseContextBase::finish() void TParseContextBase::finish()
{ {

File diff suppressed because it is too large Load diff

View file

@ -67,7 +67,7 @@ struct TPragma {
class TScanContext; class TScanContext;
class TPpContext; class TPpContext;
typedef std::set<int> TIdSetType; typedef std::set<long long> TIdSetType;
typedef std::map<const TTypeList*, std::map<size_t, const TTypeList*>> TStructRecord; typedef std::map<const TTypeList*, std::map<size_t, const TTypeList*>> TStructRecord;
// //
@ -92,7 +92,8 @@ public:
limits(resources.limits), limits(resources.limits),
globalUniformBlock(nullptr), globalUniformBlock(nullptr),
globalUniformBinding(TQualifier::layoutBindingEnd), globalUniformBinding(TQualifier::layoutBindingEnd),
globalUniformSet(TQualifier::layoutSetEnd) globalUniformSet(TQualifier::layoutSetEnd),
atomicCounterBlockSet(TQualifier::layoutSetEnd)
{ {
if (entryPoint != nullptr) if (entryPoint != nullptr)
sourceEntryPointName = *entryPoint; sourceEntryPointName = *entryPoint;
@ -154,10 +155,11 @@ public:
extensionCallback(line, extension, behavior); extensionCallback(line, extension, behavior);
} }
#ifdef ENABLE_HLSL
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
#endif
// Manage global buffer (used for backing atomic counters in GLSL when using relaxed Vulkan semantics)
virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
// Potentially rename shader entry point function // Potentially rename shader entry point function
void renameShaderFunction(TString*& name) const void renameShaderFunction(TString*& name) const
@ -230,7 +232,25 @@ protected:
// override this to set the language-specific name // override this to set the language-specific name
virtual const char* getGlobalUniformBlockName() const { return ""; } virtual const char* getGlobalUniformBlockName() const { return ""; }
virtual void setUniformBlockDefaults(TType&) const { } virtual void setUniformBlockDefaults(TType&) const { }
virtual void finalizeGlobalUniformBlockLayout(TVariable&) { } virtual void finalizeGlobalUniformBlockLayout(TVariable&) {}
// Manage the atomic counter block (used for atomic_uints with Vulkan-Relaxed)
TMap<int, TVariable*> atomicCounterBuffers;
unsigned int atomicCounterBlockSet;
TMap<int, int> atomicCounterBlockFirstNewMember;
// override this to set the language-specific name
virtual const char* getAtomicCounterBlockName() const { return ""; }
virtual void setAtomicCounterBlockDefaults(TType&) const {}
virtual void setInvariant(const TSourceLoc& loc, const char* builtin) {}
virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
bool isAtomicCounterBlock(const TSymbol& symbol) {
const TVariable* var = symbol.getAsVariable();
if (!var)
return false;
const auto& at = atomicCounterBuffers.find(var->getType().getQualifier().layoutBinding);
return (at != atomicCounterBuffers.end() && (*at).second->getType() == var->getType());
}
virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken, virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, TPrefixType prefix, const char* szExtraInfoFormat, TPrefixType prefix,
va_list args); va_list args);
@ -293,6 +313,9 @@ public:
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override; bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
void parserError(const char* s); // for bison's yyerror void parserError(const char* s); // for bison's yyerror
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override;
virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override;
void reservedErrorCheck(const TSourceLoc&, const TString&); void reservedErrorCheck(const TSourceLoc&, const TString&);
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override; void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override;
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override; bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override;
@ -340,6 +363,10 @@ public:
void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier); void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode); void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode);
TIntermTyped* vkRelaxedRemapFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
// returns true if the variable was remapped to something else
bool vkRelaxedRemapUniformVariable(const TSourceLoc&, TString&, const TPublicType&, TArraySizes*, TIntermTyped*, TType&);
void assignError(const TSourceLoc&, const char* op, TString left, TString right); void assignError(const TSourceLoc&, const char* op, TString left, TString right);
void unaryOpError(const TSourceLoc&, const char* op, TString operand); void unaryOpError(const TSourceLoc&, const char* op, TString operand);
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right); void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
@ -392,7 +419,7 @@ public:
void arrayLimitCheck(const TSourceLoc&, const TString&, int size); void arrayLimitCheck(const TSourceLoc&, const TString&, int size);
void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature); void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature);
void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&); void inductiveLoopBodyCheck(TIntermNode*, long long loopIndexId, TSymbolTable&);
void constantIndexExpressionCheck(TIntermNode*); void constantIndexExpressionCheck(TIntermNode*);
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&); void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
@ -417,6 +444,7 @@ public:
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to); void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to);
void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0); void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
void blockStorageRemap(const TSourceLoc&, const TString*, TQualifier&);
void blockStageIoCheck(const TSourceLoc&, const TQualifier&); void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName); void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation); void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
@ -443,6 +471,22 @@ public:
void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*); void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
// Determine loop control from attributes // Determine loop control from attributes
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*); void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
// Function attributes
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
// GL_EXT_spirv_intrinsics
TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
const TIntermAggregate* extensions, const TIntermAggregate* capabilities);
TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
TSpirvRequirement* spirvReq2);
TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
TSpirvTypeParameters* makeSpirvTypeParameters(const TPublicType& type);
TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
TSpirvTypeParameters* spirvTypeParams2);
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value);
TSpirvInstruction* mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1,
TSpirvInstruction* spirvInst2);
#endif #endif
void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember); void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember);
@ -461,6 +505,15 @@ protected:
void finish() override; void finish() override;
#endif #endif
virtual const char* getGlobalUniformBlockName() const override;
virtual void finalizeGlobalUniformBlockLayout(TVariable&) override;
virtual void setUniformBlockDefaults(TType& block) const override;
virtual const char* getAtomicCounterBlockName() const override;
virtual void finalizeAtomicCounterBlockLayout(TVariable&) override;
virtual void setAtomicCounterBlockDefaults(TType& block) const override;
virtual void setInvariant(const TSourceLoc& loc, const char* builtin) override;
public: public:
// //
// Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access // Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access
@ -485,6 +538,7 @@ protected:
TQualifier globalUniformDefaults; TQualifier globalUniformDefaults;
TQualifier globalInputDefaults; TQualifier globalInputDefaults;
TQualifier globalOutputDefaults; TQualifier globalOutputDefaults;
TQualifier globalSharedDefaults;
TString currentCaller; // name of last function body entered (not valid when at global scope) TString currentCaller; // name of last function body entered (not valid when at global scope)
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point

View file

@ -586,6 +586,18 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["f64mat4x2"] = F64MAT4X2; (*KeywordMap)["f64mat4x2"] = F64MAT4X2;
(*KeywordMap)["f64mat4x3"] = F64MAT4X3; (*KeywordMap)["f64mat4x3"] = F64MAT4X3;
(*KeywordMap)["f64mat4x4"] = F64MAT4X4; (*KeywordMap)["f64mat4x4"] = F64MAT4X4;
// GL_EXT_spirv_intrinsics
(*KeywordMap)["spirv_instruction"] = SPIRV_INSTRUCTION;
(*KeywordMap)["spirv_execution_mode"] = SPIRV_EXECUTION_MODE;
(*KeywordMap)["spirv_execution_mode_id"] = SPIRV_EXECUTION_MODE_ID;
(*KeywordMap)["spirv_decorate"] = SPIRV_DECORATE;
(*KeywordMap)["spirv_decorate_id"] = SPIRV_DECORATE_ID;
(*KeywordMap)["spirv_decorate_string"] = SPIRV_DECORATE_STRING;
(*KeywordMap)["spirv_type"] = SPIRV_TYPE;
(*KeywordMap)["spirv_storage_class"] = SPIRV_STORAGE_CLASS;
(*KeywordMap)["spirv_by_reference"] = SPIRV_BY_REFERENCE;
(*KeywordMap)["spirv_literal"] = SPIRV_LITERAL;
#endif #endif
(*KeywordMap)["sampler2D"] = SAMPLER2D; (*KeywordMap)["sampler2D"] = SAMPLER2D;
@ -1747,6 +1759,21 @@ int TScanContext::tokenizeIdentifier()
return keyword; return keyword;
else else
return identifierOrType(); return identifierOrType();
case SPIRV_INSTRUCTION:
case SPIRV_EXECUTION_MODE:
case SPIRV_EXECUTION_MODE_ID:
case SPIRV_DECORATE:
case SPIRV_DECORATE_ID:
case SPIRV_DECORATE_STRING:
case SPIRV_TYPE:
case SPIRV_STORAGE_CLASS:
case SPIRV_BY_REFERENCE:
case SPIRV_LITERAL:
if (parseContext.symbolTable.atBuiltInLevel() ||
parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
return keyword;
return identifierOrType();
#endif #endif
default: default:

View file

@ -159,7 +159,7 @@ int MapVersionToIndex(int version)
return index; return index;
} }
const int SpvVersionCount = 3; // index range in MapSpvVersionToIndex const int SpvVersionCount = 4; // index range in MapSpvVersionToIndex
int MapSpvVersionToIndex(const SpvVersion& spvVersion) int MapSpvVersionToIndex(const SpvVersion& spvVersion)
{ {
@ -167,8 +167,12 @@ int MapSpvVersionToIndex(const SpvVersion& spvVersion)
if (spvVersion.openGl > 0) if (spvVersion.openGl > 0)
index = 1; index = 1;
else if (spvVersion.vulkan > 0) else if (spvVersion.vulkan > 0) {
index = 2; if (!spvVersion.vulkanRelaxed)
index = 2;
else
index = 3;
}
assert(index < SpvVersionCount); assert(index < SpvVersionCount);
@ -723,6 +727,7 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages
break; break;
case EShClientVulkan: case EShClientVulkan:
spvVersion.vulkanGlsl = environment->input.dialectVersion; spvVersion.vulkanGlsl = environment->input.dialectVersion;
spvVersion.vulkanRelaxed = environment->input.vulkanRulesRelaxed;
break; break;
case EShClientOpenGL: case EShClientOpenGL:
spvVersion.openGl = environment->input.dialectVersion; spvVersion.openGl = environment->input.dialectVersion;
@ -949,6 +954,9 @@ bool ProcessDeferred(
if (cachedTable) if (cachedTable)
symbolTable->adoptLevels(*cachedTable); symbolTable->adoptLevels(*cachedTable);
if (intermediate.getUniqueId() != 0)
symbolTable->overwriteUniqueId(intermediate.getUniqueId());
// Add built-in symbols that are potentially context dependent; // Add built-in symbols that are potentially context dependent;
// they get popped again further down. // they get popped again further down.
if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion, if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion,
@ -1011,6 +1019,7 @@ bool ProcessDeferred(
bool success = processingContext(*parseContext, ppContext, fullInput, bool success = processingContext(*parseContext, ppContext, fullInput,
versionWillBeError, *symbolTable, versionWillBeError, *symbolTable,
intermediate, optLevel, messages); intermediate, optLevel, messages);
intermediate.setUniqueId(symbolTable->getMaxSymbolId());
return success; return success;
} }
@ -1270,14 +1279,15 @@ bool PreprocessDeferred(
EShMessages messages, // warnings/errors/AST; things to print out EShMessages messages, // warnings/errors/AST; things to print out
TShader::Includer& includer, TShader::Includer& includer,
TIntermediate& intermediate, // returned tree, etc. TIntermediate& intermediate, // returned tree, etc.
std::string* outputString) std::string* outputString,
TEnvironment* environment = nullptr)
{ {
DoPreprocessing parser(outputString); DoPreprocessing parser(outputString);
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
preamble, optLevel, resources, defaultVersion, preamble, optLevel, resources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile, defaultProfile, forceDefaultVersionAndProfile,
forwardCompatible, messages, intermediate, parser, forwardCompatible, messages, intermediate, parser,
false, includer); false, includer, "", environment);
} }
#endif #endif
@ -1757,6 +1767,7 @@ TShader::TShader(EShLanguage s)
// clear environment (avoid constructors in them for use in a C interface) // clear environment (avoid constructors in them for use in a C interface)
environment.input.languageFamily = EShSourceNone; environment.input.languageFamily = EShSourceNone;
environment.input.dialect = EShClientNone; environment.input.dialect = EShClientNone;
environment.input.vulkanRulesRelaxed = false;
environment.client.client = EShClientNone; environment.client.client = EShClientNone;
environment.target.language = EShTargetNone; environment.target.language = EShTargetNone;
environment.target.hlslFunctionality1 = false; environment.target.hlslFunctionality1 = false;
@ -1810,6 +1821,11 @@ void TShader::addProcesses(const std::vector<std::string>& p)
intermediate->addProcesses(p); intermediate->addProcesses(p);
} }
void TShader::setUniqueId(unsigned long long id)
{
intermediate->setUniqueId(id);
}
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); } void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
@ -1858,6 +1874,15 @@ void TShader::setResourceSetBinding(const std::vector<std::string>& base) { in
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); } void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
#endif #endif
void TShader::addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing) { intermediate->addBlockStorageOverride(nameStr, backing); }
void TShader::setGlobalUniformBlockName(const char* name) { intermediate->setGlobalUniformBlockName(name); }
void TShader::setGlobalUniformSet(unsigned int set) { intermediate->setGlobalUniformSet(set); }
void TShader::setGlobalUniformBinding(unsigned int binding) { intermediate->setGlobalUniformBinding(binding); }
void TShader::setAtomicCounterBlockName(const char* name) { intermediate->setAtomicCounterBlockName(name); }
void TShader::setAtomicCounterBlockSet(unsigned int set) { intermediate->setAtomicCounterBlockSet(set); }
#ifdef ENABLE_HLSL #ifdef ENABLE_HLSL
// See comment above TDefaultHlslIoMapper in iomapper.cpp: // See comment above TDefaultHlslIoMapper in iomapper.cpp:
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
@ -1909,7 +1934,8 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble, return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble,
EShOptNone, builtInResources, defaultVersion, EShOptNone, builtInResources, defaultVersion,
defaultProfile, forceDefaultVersionAndProfile, defaultProfile, forceDefaultVersionAndProfile,
forwardCompatible, message, includer, *intermediate, output_string); forwardCompatible, message, includer, *intermediate, output_string,
&environment);
} }
#endif #endif
@ -1972,7 +1998,10 @@ bool TProgram::link(EShMessages messages)
error = true; error = true;
} }
// TODO: Link: cross-stage error checking if (!error) {
if (! crossStageCheck(messages))
error = true;
}
return ! error; return ! error;
} }
@ -2049,6 +2078,69 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
return intermediate[stage]->getNumErrors() == 0; return intermediate[stage]->getNumErrors() == 0;
} }
//
// Check that there are no errors in linker objects accross stages
//
// Return true if no errors.
//
bool TProgram::crossStageCheck(EShMessages) {
// make temporary intermediates to hold the linkage symbols for each linking interface
// while we do the checks
// Independent interfaces are:
// all uniform variables and blocks
// all buffer blocks
// all in/out on a stage boundary
TVector<TIntermediate*> activeStages;
for (int s = 0; s < EShLangCount; ++s) {
if (intermediate[s])
activeStages.push_back(intermediate[s]);
}
// no extra linking if there is only one stage
if (! (activeStages.size() > 1))
return true;
// setup temporary tree to hold unfirom objects from different stages
TIntermediate* firstIntermediate = activeStages.front();
TIntermediate uniforms(EShLangCount,
firstIntermediate->getVersion(),
firstIntermediate->getProfile());
uniforms.setSpv(firstIntermediate->getSpv());
TIntermAggregate uniformObjects(EOpLinkerObjects);
TIntermAggregate root(EOpSequence);
root.getSequence().push_back(&uniformObjects);
uniforms.setTreeRoot(&root);
bool error = false;
// merge uniforms from all stages into a single intermediate
for (unsigned int i = 0; i < activeStages.size(); ++i) {
uniforms.mergeUniformObjects(*infoSink, *activeStages[i]);
}
error |= uniforms.getNumErrors() != 0;
// copy final definition of global block back into each stage
for (unsigned int i = 0; i < activeStages.size(); ++i) {
// We only want to merge into already existing global uniform blocks.
// A stage that doesn't already know about the global doesn't care about it's content.
// Otherwise we end up pointing to the same object between different stages
// and that will break binding/set remappings
bool mergeExistingOnly = true;
activeStages[i]->mergeGlobalUniformBlocks(*infoSink, uniforms, mergeExistingOnly);
}
// compare cross stage symbols for each stage boundary
for (unsigned int i = 1; i < activeStages.size(); ++i) {
activeStages[i - 1]->checkStageIO(*infoSink, *activeStages[i]);
error |= (activeStages[i - 1]->getNumErrors() != 0);
}
return !error;
}
const char* TProgram::getInfoLog() const char* TProgram::getInfoLog()
{ {
return infoSink->info.c_str(); return infoSink->info.c_str();

View file

@ -0,0 +1,355 @@
//
// Copyright(C) 2021 Advanced Micro Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#ifndef GLSLANG_WEB
//
// GL_EXT_spirv_intrinsics
//
#include "../Include/intermediate.h"
#include "../Include/SpirvIntrinsics.h"
#include "../Include/Types.h"
#include "ParseHelper.h"
namespace glslang {
//
// Handle SPIR-V requirements
//
TSpirvRequirement* TParseContext::makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
const TIntermAggregate* extensions,
const TIntermAggregate* capabilities)
{
TSpirvRequirement* spirvReq = new TSpirvRequirement;
if (name == "extensions") {
assert(extensions);
for (auto extension : extensions->getSequence()) {
assert(extension->getAsConstantUnion());
spirvReq->extensions.insert(*extension->getAsConstantUnion()->getConstArray()[0].getSConst());
}
} else if (name == "capabilities") {
assert(capabilities);
for (auto capability : capabilities->getSequence()) {
assert(capability->getAsConstantUnion());
spirvReq->capabilities.insert(capability->getAsConstantUnion()->getConstArray()[0].getIConst());
}
} else
error(loc, "unknow SPIR-V requirement", name.c_str(), "");
return spirvReq;
}
TSpirvRequirement* TParseContext::mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
TSpirvRequirement* spirvReq2)
{
// Merge the second SPIR-V requirement to the first one
if (!spirvReq2->extensions.empty()) {
if (spirvReq1->extensions.empty())
spirvReq1->extensions = spirvReq2->extensions;
else
error(loc, "too many SPIR-V requirements", "extensions", "");
}
if (!spirvReq2->capabilities.empty()) {
if (spirvReq1->capabilities.empty())
spirvReq1->capabilities = spirvReq2->capabilities;
else
error(loc, "too many SPIR-V requirements", "capabilities", "");
}
return spirvReq1;
}
void TIntermediate::insertSpirvRequirement(const TSpirvRequirement* spirvReq)
{
if (!spirvRequirement)
spirvRequirement = new TSpirvRequirement;
for (auto extension : spirvReq->extensions)
spirvRequirement->extensions.insert(extension);
for (auto capability : spirvReq->capabilities)
spirvRequirement->capabilities.insert(capability);
}
//
// Handle SPIR-V execution modes
//
void TIntermediate::insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args)
{
if (!spirvExecutionMode)
spirvExecutionMode = new TSpirvExecutionMode;
TVector<const TIntermConstantUnion*> extraOperands;
if (args) {
for (auto arg : args->getSequence()) {
auto extraOperand = arg->getAsConstantUnion();
assert(extraOperand != nullptr);
extraOperands.push_back(extraOperand);
}
}
spirvExecutionMode->modes[executionMode] = extraOperands;
}
void TIntermediate::insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args)
{
if (!spirvExecutionMode)
spirvExecutionMode = new TSpirvExecutionMode;
assert(args);
TVector<const TIntermConstantUnion*> extraOperands;
for (auto arg : args->getSequence()) {
auto extraOperand = arg->getAsConstantUnion();
assert(extraOperand != nullptr);
extraOperands.push_back(extraOperand);
}
spirvExecutionMode->modeIds[executionMode] = extraOperands;
}
//
// Handle SPIR-V decorate qualifiers
//
void TQualifier::setSpirvDecorate(int decoration, const TIntermAggregate* args)
{
if (!spirvDecorate)
spirvDecorate = new TSpirvDecorate;
TVector<const TIntermConstantUnion*> extraOperands;
if (args) {
for (auto arg : args->getSequence()) {
auto extraOperand = arg->getAsConstantUnion();
assert(extraOperand != nullptr);
extraOperands.push_back(extraOperand);
}
}
spirvDecorate->decorates[decoration] = extraOperands;
}
void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args)
{
if (!spirvDecorate)
spirvDecorate = new TSpirvDecorate;
assert(args);
TVector<const TIntermConstantUnion*> extraOperands;
for (auto arg : args->getSequence()) {
auto extraOperand = arg->getAsConstantUnion();
assert(extraOperand != nullptr);
extraOperands.push_back(extraOperand);
}
spirvDecorate->decorateIds[decoration] = extraOperands;
}
void TQualifier::setSpirvDecorateString(int decoration, const TIntermAggregate* args)
{
if (!spirvDecorate)
spirvDecorate = new TSpirvDecorate;
assert(args);
TVector<const TIntermConstantUnion*> extraOperands;
for (auto arg : args->getSequence()) {
auto extraOperand = arg->getAsConstantUnion();
assert(extraOperand != nullptr);
extraOperands.push_back(extraOperand);
}
spirvDecorate->decorateStrings[decoration] = extraOperands;
}
TString TQualifier::getSpirvDecorateQualifierString() const
{
assert(spirvDecorate);
TString qualifierString;
const auto appendFloat = [&](float f) { qualifierString.append(std::to_string(f).c_str()); };
const auto appendInt = [&](int i) { qualifierString.append(std::to_string(i).c_str()); };
const auto appendUint = [&](unsigned int u) { qualifierString.append(std::to_string(u).c_str()); };
const auto appendBool = [&](bool b) { qualifierString.append(std::to_string(b).c_str()); };
const auto appendStr = [&](const char* s) { qualifierString.append(s); };
const auto appendDecorate = [&](const TIntermConstantUnion* constant) {
if (constant->getBasicType() == EbtFloat) {
float value = static_cast<float>(constant->getConstArray()[0].getDConst());
appendFloat(value);
}
else if (constant->getBasicType() == EbtInt) {
int value = constant->getConstArray()[0].getIConst();
appendInt(value);
}
else if (constant->getBasicType() == EbtUint) {
unsigned value = constant->getConstArray()[0].getUConst();
appendUint(value);
}
else if (constant->getBasicType() == EbtBool) {
bool value = constant->getConstArray()[0].getBConst();
appendBool(value);
}
else if (constant->getBasicType() == EbtString) {
const TString* value = constant->getConstArray()[0].getSConst();
appendStr(value->c_str());
}
else
assert(0);
};
for (auto& decorate : spirvDecorate->decorates) {
appendStr("spirv_decorate(");
appendInt(decorate.first);
for (auto extraOperand : decorate.second) {
appendStr(", ");
appendDecorate(extraOperand);
}
appendStr(") ");
}
for (auto& decorateId : spirvDecorate->decorateIds) {
appendStr("spirv_decorate_id(");
appendInt(decorateId.first);
for (auto extraOperand : decorateId.second) {
appendStr(", ");
appendDecorate(extraOperand);
}
appendStr(") ");
}
for (auto& decorateString : spirvDecorate->decorateStrings) {
appendStr("spirv_decorate_string(");
appendInt(decorateString.first);
for (auto extraOperand : decorateString.second) {
appendStr(", ");
appendDecorate(extraOperand);
}
appendStr(") ");
}
return qualifierString;
}
//
// Handle SPIR-V type specifiers
//
void TPublicType::setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams)
{
if (!spirvType)
spirvType = new TSpirvType;
basicType = EbtSpirvType;
spirvType->spirvInst = spirvInst;
if (typeParams)
spirvType->typeParams = *typeParams;
}
TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant)
{
TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters;
if (constant->getBasicType() != EbtFloat &&
constant->getBasicType() != EbtInt &&
constant->getBasicType() != EbtUint &&
constant->getBasicType() != EbtBool &&
constant->getBasicType() != EbtString)
error(loc, "this type not allowed", constant->getType().getBasicString(), "");
else {
assert(constant);
spirvTypeParams->push_back(TSpirvTypeParameter(constant));
}
return spirvTypeParams;
}
TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TPublicType& type)
{
TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters;
spirvTypeParams->push_back(TSpirvTypeParameter(new TType(type)));
return spirvTypeParams;
}
TSpirvTypeParameters* TParseContext::mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, TSpirvTypeParameters* spirvTypeParams2)
{
// Merge SPIR-V type parameters of the second one to the first one
for (const auto& spirvTypeParam : *spirvTypeParams2)
spirvTypeParams1->push_back(spirvTypeParam);
return spirvTypeParams1;
}
//
// Handle SPIR-V instruction qualifiers
//
TSpirvInstruction* TParseContext::makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value)
{
TSpirvInstruction* spirvInst = new TSpirvInstruction;
if (name == "set")
spirvInst->set = value;
else
error(loc, "unknown SPIR-V instruction qualifier", name.c_str(), "");
return spirvInst;
}
TSpirvInstruction* TParseContext::makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value)
{
TSpirvInstruction* spirvInstuction = new TSpirvInstruction;
if (name == "id")
spirvInstuction->id = value;
else
error(loc, "unknown SPIR-V instruction qualifier", name.c_str(), "");
return spirvInstuction;
}
TSpirvInstruction* TParseContext::mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1, TSpirvInstruction* spirvInst2)
{
// Merge qualifiers of the second SPIR-V instruction to those of the first one
if (!spirvInst2->set.empty()) {
if (spirvInst1->set.empty())
spirvInst1->set = spirvInst2->set;
else
error(loc, "too many SPIR-V instruction qualifiers", "spirv_instruction", "(set)");
}
if (spirvInst2->id != -1) {
if (spirvInst1->id == -1)
spirvInst1->id = spirvInst2->id;
else
error(loc, "too many SPIR-V instruction qualifiers", "spirv_instruction", "(id)");
}
return spirvInst1;
}
} // end namespace glslang
#endif // GLSLANG_WEB

View file

@ -77,6 +77,7 @@ void TType::buildMangledName(TString& mangledName) const
case EbtAtomicUint: mangledName += "au"; break; case EbtAtomicUint: mangledName += "au"; break;
case EbtAccStruct: mangledName += "as"; break; case EbtAccStruct: mangledName += "as"; break;
case EbtRayQuery: mangledName += "rq"; break; case EbtRayQuery: mangledName += "rq"; break;
case EbtSpirvType: mangledName += "spv-t"; break;
#endif #endif
case EbtSampler: case EbtSampler:
switch (sampler.type) { switch (sampler.type) {
@ -170,7 +171,7 @@ void TType::buildMangledName(TString& mangledName) const
for (int i = 0; i < arraySizes->getNumDims(); ++i) { for (int i = 0; i < arraySizes->getNumDims(); ++i) {
if (arraySizes->getDimNode(i)) { if (arraySizes->getDimNode(i)) {
if (arraySizes->getDimNode(i)->getAsSymbolNode()) if (arraySizes->getDimNode(i)->getAsSymbolNode())
snprintf(buf, maxSize, "s%d", arraySizes->getDimNode(i)->getAsSymbolNode()->getId()); snprintf(buf, maxSize, "s%lld", arraySizes->getDimNode(i)->getAsSymbolNode()->getId());
else else
snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i)); snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i));
} else } else
@ -390,6 +391,9 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
implicitThis = copyOf.implicitThis; implicitThis = copyOf.implicitThis;
illegalImplicitThis = copyOf.illegalImplicitThis; illegalImplicitThis = copyOf.illegalImplicitThis;
defaultParamCount = copyOf.defaultParamCount; defaultParamCount = copyOf.defaultParamCount;
#ifndef GLSLANG_WEB
spirvInst = copyOf.spirvInst;
#endif
} }
TFunction* TFunction::clone() const TFunction* TFunction::clone() const

View file

@ -104,8 +104,8 @@ public:
virtual const TAnonMember* getAsAnonMember() const { return 0; } virtual const TAnonMember* getAsAnonMember() const { return 0; }
virtual const TType& getType() const = 0; virtual const TType& getType() const = 0;
virtual TType& getWritableType() = 0; virtual TType& getWritableType() = 0;
virtual void setUniqueId(int id) { uniqueId = id; } virtual void setUniqueId(long long id) { uniqueId = id; }
virtual int getUniqueId() const { return uniqueId; } virtual long long getUniqueId() const { return uniqueId; }
virtual void setExtensions(int numExts, const char* const exts[]) virtual void setExtensions(int numExts, const char* const exts[])
{ {
assert(extensions == 0); assert(extensions == 0);
@ -130,7 +130,7 @@ protected:
TSymbol& operator=(const TSymbol&); TSymbol& operator=(const TSymbol&);
const TString *name; const TString *name;
unsigned int uniqueId; // For cross-scope comparing during code generation unsigned long long uniqueId; // For cross-scope comparing during code generation
// For tracking what extensions must be present // For tracking what extensions must be present
// (don't use if correct version/profile is present). // (don't use if correct version/profile is present).
@ -319,6 +319,15 @@ 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
virtual void setSpirvInstruction(const TSpirvInstruction& inst)
{
relateToOperator(EOpSpirvInst);
spirvInst = inst;
}
virtual const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
#endif
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) #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
@ -342,6 +351,10 @@ protected:
// This is important for a static member function that has member variables in scope, // This is important for a static member function that has member variables in scope,
// but is not allowed to use them, or see hidden symbols instead. // but is not allowed to use them, or see hidden symbols instead.
int defaultParamCount; int defaultParamCount;
#ifndef GLSLANG_WEB
TSpirvInstruction spirvInst; // SPIR-V instruction qualifiers
#endif
}; };
// //
@ -612,6 +625,7 @@ public:
// 3: user-shader globals // 3: user-shader globals
// //
protected: protected:
static const uint32_t LevelFlagBitOffset = 56;
static const int globalLevel = 3; static const int globalLevel = 3;
static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
@ -620,10 +634,12 @@ public:
bool isEmpty() { return table.size() == 0; } bool isEmpty() { return table.size() == 0; }
bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); } bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
bool atGlobalLevel() { return isGlobalLevel(currentLevel()); } bool atGlobalLevel() { return isGlobalLevel(currentLevel()); }
static bool isBuiltInSymbol(int uniqueId) { static bool isBuiltInSymbol(long long uniqueId) {
int level = uniqueId >> LevelFlagBitOffset; int level = static_cast<int>(uniqueId >> LevelFlagBitOffset);
return isBuiltInLevel(level); return isBuiltInLevel(level);
} }
static constexpr uint64_t uniqueIdMask = (1LL << LevelFlagBitOffset) - 1;
static const uint32_t MaxLevelInUniqueID = 127;
void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; } void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
void setSeparateNameSpaces() { separateNameSpaces = true; } void setSeparateNameSpaces() { separateNameSpaces = true; }
@ -691,6 +707,16 @@ public:
return table[currentLevel()]->amend(symbol, firstNewMember); return table[currentLevel()]->amend(symbol, firstNewMember);
} }
// Update the level info in symbol's unique ID to current level
void amendSymbolIdLevel(TSymbol& symbol)
{
// clamp level to avoid overflow
uint64_t level = (uint32_t)currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel();
uint64_t symbolId = symbol.getUniqueId();
symbolId &= uniqueIdMask;
symbolId |= (level << LevelFlagBitOffset);
symbol.setUniqueId(symbolId);
}
// //
// To allocate an internal temporary, which will need to be uniquely // To allocate an internal temporary, which will need to be uniquely
// identified by the consumer of the AST, but never need to // identified by the consumer of the AST, but never need to
@ -859,7 +885,7 @@ public:
} }
} }
int getMaxSymbolId() { return uniqueId; } long long getMaxSymbolId() { return uniqueId; }
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) #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
@ -876,19 +902,24 @@ public:
// Add current level in the high-bits of unique id // Add current level in the high-bits of unique id
void updateUniqueIdLevelFlag() { void updateUniqueIdLevelFlag() {
// clamp level to avoid overflow // clamp level to avoid overflow
uint32_t level = currentLevel() > 7 ? 7 : currentLevel(); uint64_t level = (uint32_t)currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel();
uniqueId &= ((1 << LevelFlagBitOffset) - 1); uniqueId &= uniqueIdMask;
uniqueId |= (level << LevelFlagBitOffset); uniqueId |= (level << LevelFlagBitOffset);
} }
void overwriteUniqueId(long long id)
{
uniqueId = id;
updateUniqueIdLevelFlag();
}
protected: protected:
TSymbolTable(TSymbolTable&); TSymbolTable(TSymbolTable&);
TSymbolTable& operator=(TSymbolTableLevel&); TSymbolTable& operator=(TSymbolTableLevel&);
int currentLevel() const { return static_cast<int>(table.size()) - 1; } int currentLevel() const { return static_cast<int>(table.size()) - 1; }
static const uint32_t LevelFlagBitOffset = 28;
std::vector<TSymbolTableLevel*> table; std::vector<TSymbolTableLevel*> table;
int uniqueId; // for unique identification in code generation long long uniqueId; // for unique identification in code generation
bool noBuiltInRedeclarations; bool noBuiltInRedeclarations;
bool separateNameSpaces; bool separateNameSpaces;
unsigned int adoptedLevels; unsigned int adoptedLevels;

View file

@ -165,12 +165,14 @@ void TParseVersions::initializeExtensionBehavior()
EShTargetLanguageVersion minSpvVersion; EShTargetLanguageVersion minSpvVersion;
} extensionData; } extensionData;
const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4} }; const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4},
{E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4}
};
for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) { for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) {
// Add only extensions which require > spv1.0 to save space in map // Add only extensions which require > spv1.0 to save space in map
if (exts[ii].minSpvVersion > EShTargetSpv_1_0) { if (exts[ii].minSpvVersion > EShTargetSpv_1_0) {
extensionMinSpv[E_GL_EXT_ray_tracing] = exts[ii].minSpvVersion; extensionMinSpv[exts[ii].extensionName] = exts[ii].minSpvVersion;
} }
} }
@ -198,6 +200,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_explicit_uniform_location] = EBhDisable; extensionBehavior[E_GL_ARB_explicit_uniform_location] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_image_load_store] = EBhDisable; extensionBehavior[E_GL_ARB_shader_image_load_store] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_atomic_counters] = EBhDisable; extensionBehavior[E_GL_ARB_shader_atomic_counters] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_atomic_counter_ops] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_draw_parameters] = EBhDisable; extensionBehavior[E_GL_ARB_shader_draw_parameters] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_group_vote] = EBhDisable; extensionBehavior[E_GL_ARB_shader_group_vote] = EBhDisable;
extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable; extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable;
@ -251,6 +254,7 @@ void TParseVersions::initializeExtensionBehavior()
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;
extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable;
// #line and #include // #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable; extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
@ -280,6 +284,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable; extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable;
extensionBehavior[E_GL_NV_shading_rate_image] = EBhDisable; extensionBehavior[E_GL_NV_shading_rate_image] = EBhDisable;
extensionBehavior[E_GL_NV_ray_tracing] = EBhDisable; extensionBehavior[E_GL_NV_ray_tracing] = EBhDisable;
extensionBehavior[E_GL_NV_ray_tracing_motion_blur] = EBhDisable;
extensionBehavior[E_GL_NV_fragment_shader_barycentric] = EBhDisable; extensionBehavior[E_GL_NV_fragment_shader_barycentric] = EBhDisable;
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable; extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable; extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
@ -305,6 +310,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_tessellation_point_size] = EBhDisable; extensionBehavior[E_GL_EXT_tessellation_point_size] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_buffer] = EBhDisable; extensionBehavior[E_GL_EXT_texture_buffer] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_cube_map_array] = EBhDisable; extensionBehavior[E_GL_EXT_texture_cube_map_array] = EBhDisable;
extensionBehavior[E_GL_EXT_null_initializer] = EBhDisable;
// OES matching AEP // OES matching AEP
extensionBehavior[E_GL_OES_geometry_shader] = EBhDisable; extensionBehavior[E_GL_OES_geometry_shader] = EBhDisable;
@ -330,6 +336,8 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_fragment_shading_rate] = EBhDisable; extensionBehavior[E_GL_EXT_fragment_shading_rate] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_image_int64] = EBhDisable; extensionBehavior[E_GL_EXT_shader_image_int64] = EBhDisable;
extensionBehavior[E_GL_EXT_terminate_invocation] = EBhDisable; extensionBehavior[E_GL_EXT_terminate_invocation] = EBhDisable;
extensionBehavior[E_GL_EXT_shared_memory_block] = EBhDisable;
extensionBehavior[E_GL_EXT_spirv_intrinsics] = EBhDisable;
// OVR extensions // OVR extensions
extensionBehavior[E_GL_OVR_multiview] = EBhDisable; extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
@ -351,6 +359,7 @@ void TParseVersions::initializeExtensionBehavior()
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; extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_atomic_float2] = EBhDisable;
} }
#endif // GLSLANG_WEB #endif // GLSLANG_WEB
@ -408,9 +417,13 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_shader_non_constant_global_initializers 1\n" "#define GL_EXT_shader_non_constant_global_initializers 1\n"
; ;
if (isEsProfile() && version >= 300) { if (version >= 300) {
preamble += "#define GL_NV_shader_noperspective_interpolation 1\n"; preamble += "#define GL_NV_shader_noperspective_interpolation 1\n";
} }
if (version >= 310) {
preamble += "#define GL_EXT_null_initializer 1\n";
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
}
} else { // !isEsProfile() } else { // !isEsProfile()
preamble = preamble =
@ -468,6 +481,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#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" "#define GL_EXT_debug_printf 1\n"
"#define GL_EXT_fragment_shading_rate 1\n" "#define GL_EXT_fragment_shading_rate 1\n"
"#define GL_EXT_shared_memory_block 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"
@ -485,6 +499,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_ray_tracing 1\n" "#define GL_EXT_ray_tracing 1\n"
"#define GL_EXT_ray_query 1\n" "#define GL_EXT_ray_query 1\n"
"#define GL_EXT_ray_flags_primitive_culling 1\n" "#define GL_EXT_ray_flags_primitive_culling 1\n"
"#define GL_EXT_spirv_intrinsics 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"
@ -507,6 +522,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_NV_shader_subgroup_partitioned 1\n" "#define GL_NV_shader_subgroup_partitioned 1\n"
"#define GL_NV_shading_rate_image 1\n" "#define GL_NV_shading_rate_image 1\n"
"#define GL_NV_ray_tracing 1\n" "#define GL_NV_ray_tracing 1\n"
"#define GL_NV_ray_tracing_motion_blur 1\n"
"#define GL_NV_fragment_shader_barycentric 1\n" "#define GL_NV_fragment_shader_barycentric 1\n"
"#define GL_NV_compute_shader_derivatives 1\n" "#define GL_NV_compute_shader_derivatives 1\n"
"#define GL_NV_shader_texture_footprint 1\n" "#define GL_NV_shader_texture_footprint 1\n"
@ -529,6 +545,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#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" "#define GL_EXT_shader_atomic_float 1\n"
"#define GL_EXT_shader_atomic_float2 1\n"
; ;
if (version >= 150) { if (version >= 150) {
@ -538,6 +555,10 @@ void TParseVersions::getPreamble(std::string& preamble)
if (profile == ECompatibilityProfile) if (profile == ECompatibilityProfile)
preamble += "#define GL_compatibility_profile 1\n"; preamble += "#define GL_compatibility_profile 1\n";
} }
if (version >= 140) {
preamble += "#define GL_EXT_null_initializer 1\n";
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
}
#endif // GLSLANG_WEB #endif // GLSLANG_WEB
} }
@ -590,6 +611,29 @@ void TParseVersions::getPreamble(std::string& preamble)
preamble += "\n"; preamble += "\n";
} }
#endif #endif
#ifndef GLSLANG_WEB
// GL_EXT_spirv_intrinsics
if (!isEsProfile()) {
switch (language) {
case EShLangVertex: preamble += "#define GL_VERTEX_SHADER 1 \n"; break;
case EShLangTessControl: preamble += "#define GL_TESSELLATION_CONTROL_SHADER 1 \n"; break;
case EShLangTessEvaluation: preamble += "#define GL_TESSELLATION_EVALUATION_SHADER 1 \n"; break;
case EShLangGeometry: preamble += "#define GL_GEOMETRY_SHADER 1 \n"; break;
case EShLangFragment: preamble += "#define GL_FRAGMENT_SHADER 1 \n"; break;
case EShLangCompute: preamble += "#define GL_COMPUTE_SHADER 1 \n"; break;
case EShLangRayGen: preamble += "#define GL_RAY_GENERATION_SHADER_EXT 1 \n"; break;
case EShLangIntersect: preamble += "#define GL_INTERSECTION_SHADER_EXT 1 \n"; break;
case EShLangAnyHit: preamble += "#define GL_ANY_HIT_SHADER_EXT 1 \n"; break;
case EShLangClosestHit: preamble += "#define GL_CLOSEST_HIT_SHADER_EXT 1 \n"; break;
case EShLangMiss: preamble += "#define GL_MISS_SHADER_EXT 1 \n"; break;
case EShLangCallable: preamble += "#define GL_CALLABLE_SHADER_EXT 1 \n"; break;
case EShLangTaskNV: preamble += "#define GL_TASK_SHADER_NV 1 \n"; break;
case EShLangMeshNV: preamble += "#define GL_MESH_SHADER_NV 1 \n"; break;
default: break;
}
}
#endif
} }
// //
@ -866,7 +910,7 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
checkExtensionStage(getCurrentLoc(), extension); checkExtensionStage(getCurrentLoc(), extension);
// check if extension has additional requirements // check if extension has additional requirements
extensionRequires(getCurrentLoc(), extension ,behaviorString); extensionRequires(getCurrentLoc(), extension, behaviorString);
// update the requested extension // update the requested extension
updateExtensionBehavior(extension, behavior); updateExtensionBehavior(extension, behavior);
@ -1264,7 +1308,7 @@ void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
// Call for any operation removed because Vulkan SPIR-V is being generated. // Call for any operation removed because Vulkan SPIR-V is being generated.
void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op) void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op)
{ {
if (spvVersion.vulkan > 0) if (spvVersion.vulkan > 0 && !spvVersion.vulkanRelaxed)
error(loc, "not allowed when using GLSL for Vulkan", op, ""); error(loc, "not allowed when using GLSL for Vulkan", op, "");
} }

View file

@ -87,11 +87,12 @@ inline const char* ProfileName(EProfile profile)
// The union of all requested rule sets will be applied. // The union of all requested rule sets will be applied.
// //
struct SpvVersion { struct SpvVersion {
SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0) {} SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0), vulkanRelaxed(false) {}
unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header
int vulkanGlsl; // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX" int vulkanGlsl; // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX"
int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use
int openGl; // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX" int openGl; // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX"
bool vulkanRelaxed; // relax changes to GLSL for Vulkan, allowing some GL-specific to be compiled to Vulkan SPIR-V target
}; };
// //
@ -135,6 +136,7 @@ const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attri
const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location"; const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location";
const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store"; const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store";
const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters"; const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters";
const char* const E_GL_ARB_shader_atomic_counter_ops = "GL_ARB_shader_atomic_counter_ops";
const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters"; const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters";
const char* const E_GL_ARB_shader_group_vote = "GL_ARB_shader_group_vote"; const char* const E_GL_ARB_shader_group_vote = "GL_ARB_shader_group_vote";
const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control"; const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control";
@ -201,6 +203,10 @@ const char* const E_GL_EXT_blend_func_extended = "GL_EXT_blend_func
const char* const E_GL_EXT_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions"; const char* const E_GL_EXT_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions";
const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_shading_rate"; const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_shading_rate";
const char* const E_GL_EXT_shader_image_int64 = "GL_EXT_shader_image_int64"; const char* const E_GL_EXT_shader_image_int64 = "GL_EXT_shader_image_int64";
const char* const E_GL_EXT_null_initializer = "GL_EXT_null_initializer";
const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_memory_block";
const char* const E_GL_EXT_subgroup_uniform_control_flow = "GL_EXT_subgroup_uniform_control_flow";
const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intrinsics";
// Arrays of extensions for the above viewportEXTs duplications // Arrays of extensions for the above viewportEXTs duplications
@ -242,6 +248,7 @@ const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_
const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned"; const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned";
const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image"; const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image";
const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing"; const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing";
const char* const E_GL_NV_ray_tracing_motion_blur = "GL_NV_ray_tracing_motion_blur";
const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric"; const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric";
const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives"; const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives";
const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint"; const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint";
@ -302,6 +309,7 @@ const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shad
const char* const E_GL_EXT_terminate_invocation = "GL_EXT_terminate_invocation"; const char* const E_GL_EXT_terminate_invocation = "GL_EXT_terminate_invocation";
const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float"; const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float";
const char* const E_GL_EXT_shader_atomic_float2 = "GL_EXT_shader_atomic_float2";
// Arrays of extensions for the above AEP duplications // Arrays of extensions for the above AEP duplications

View file

@ -123,6 +123,8 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
return EatPeelCount; return EatPeelCount;
else if (name == "partial_count") else if (name == "partial_count")
return EatPartialCount; return EatPartialCount;
else if (name == "subgroup_uniform_control_flow")
return EatSubgroupUniformControlFlow;
else else
return EatNone; return EatNone;
} }
@ -341,6 +343,29 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
} }
} }
//
// Function attributes
//
void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes, TFunction* function)
{
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
if (it->size() > 0) {
warn(loc, "attribute with arguments not recognized, skipping", "", "");
continue;
}
switch (it->name) {
case EatSubgroupUniformControlFlow:
intermediate.setSubgroupUniformControlFlow();
break;
default:
warn(loc, "attribute does not apply to a function", "", "");
break;
}
}
}
} // end namespace glslang } // end namespace glslang
#endif // GLSLANG_WEB #endif // GLSLANG_WEB

View file

@ -118,7 +118,8 @@ namespace glslang {
EatFormatR8ui, EatFormatR8ui,
EatFormatUnknown, EatFormatUnknown,
EatNonWritable, EatNonWritable,
EatNonReadable EatNonReadable,
EatSubgroupUniformControlFlow,
}; };
class TIntermAggregate; class TIntermAggregate;

View file

@ -49,9 +49,9 @@
#define GL_INT64_VEC4_ARB 0x8FEB #define GL_INT64_VEC4_ARB 0x8FEB
#define GL_UNSIGNED_INT64_ARB 0x140F #define GL_UNSIGNED_INT64_ARB 0x140F
#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FE5 #define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5
#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FE6 #define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6
#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FE7 #define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7
#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 #define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 #define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 #define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3

View file

@ -116,6 +116,9 @@ using namespace glslang;
glslang::TIntermNodePair nodePair; glslang::TIntermNodePair nodePair;
glslang::TIntermTyped* intermTypedNode; glslang::TIntermTyped* intermTypedNode;
glslang::TAttributes* attributes; glslang::TAttributes* attributes;
glslang::TSpirvRequirement* spirvReq;
glslang::TSpirvInstruction* spirvInst;
glslang::TSpirvTypeParameters* spirvTypeParams;
}; };
union { union {
glslang::TPublicType type; glslang::TPublicType type;
@ -271,6 +274,11 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS %token <lex> SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS
%token <lex> F16SUBPASSINPUT F16SUBPASSINPUTMS %token <lex> F16SUBPASSINPUT F16SUBPASSINPUTMS
// spirv intrinsics
%token <lex> SPIRV_INSTRUCTION SPIRV_EXECUTION_MODE SPIRV_EXECUTION_MODE_ID
%token <lex> SPIRV_DECORATE SPIRV_DECORATE_ID SPIRV_DECORATE_STRING
%token <lex> SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL
%token <lex> LEFT_OP RIGHT_OP %token <lex> LEFT_OP RIGHT_OP
@ -362,6 +370,19 @@ extern int yylex(YYSTYPE*, TParseContext&);
%type <interm.attributes> attribute attribute_list single_attribute %type <interm.attributes> attribute attribute_list single_attribute
%type <interm.intermNode> demote_statement %type <interm.intermNode> demote_statement
%type <interm.intermTypedNode> initializer_list %type <interm.intermTypedNode> initializer_list
%type <interm.spirvReq> spirv_requirements_list spirv_requirements_parameter
%type <interm.intermNode> spirv_extension_list spirv_capability_list
%type <interm.intermNode> spirv_execution_mode_qualifier
%type <interm.intermNode> spirv_execution_mode_parameter_list spirv_execution_mode_parameter spirv_execution_mode_id_parameter_list
%type <interm.type> spirv_storage_class_qualifier
%type <interm.type> spirv_decorate_qualifier
%type <interm.intermNode> spirv_decorate_parameter_list spirv_decorate_parameter
%type <interm.intermNode> spirv_decorate_id_parameter_list
%type <interm.intermNode> spirv_decorate_string_parameter_list
%type <interm.type> spirv_type_specifier
%type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
%type <interm.spirvInst> spirv_instruction_qualifier
%type <interm.spirvInst> spirv_instruction_qualifier_list spirv_instruction_qualifier_id
%start translation_unit %start translation_unit
@ -875,6 +896,20 @@ declaration
$$ = 0; $$ = 0;
// TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
} }
| spirv_instruction_qualifier function_prototype SEMICOLON {
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier");
$2.function->setSpirvInstruction(*$1); // Attach SPIR-V intruction qualifier
parseContext.handleFunctionDeclarator($2.loc, *$2.function, true /* prototype */);
$$ = 0;
// TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
}
| spirv_execution_mode_qualifier SEMICOLON {
parseContext.globalCheck($2.loc, "SPIR-V execution mode qualifier");
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier");
$$ = 0;
}
| init_declarator_list SEMICOLON { | init_declarator_list SEMICOLON {
if ($1.intermNode && $1.intermNode->getAsAggregate()) if ($1.intermNode && $1.intermNode->getAsAggregate())
$1.intermNode->getAsAggregate()->setOperator(EOpSequence); $1.intermNode->getAsAggregate()->setOperator(EOpSequence);
@ -944,6 +979,25 @@ function_prototype
$$.function = $1; $$.function = $1;
$$.loc = $2.loc; $$.loc = $2.loc;
} }
| function_declarator RIGHT_PAREN attribute {
$$.function = $1;
$$.loc = $2.loc;
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
}
| attribute function_declarator RIGHT_PAREN {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
}
| attribute function_declarator RIGHT_PAREN attribute {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
}
; ;
function_declarator function_declarator
@ -1347,6 +1401,25 @@ single_type_qualifier
| non_uniform_qualifier { | non_uniform_qualifier {
$$ = $1; $$ = $1;
} }
| spirv_storage_class_qualifier {
parseContext.globalCheck($1.loc, "spirv_storage_class");
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier");
$$ = $1;
}
| spirv_decorate_qualifier {
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier");
$$ = $1;
}
| SPIRV_BY_REFERENCE {
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference");
$$.init($1.loc);
$$.qualifier.setSpirvByReference();
}
| SPIRV_LITERAL {
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal");
$$.init($1.loc);
$$.qualifier.setSpirvLiteral();
}
; ;
@ -3407,6 +3480,10 @@ type_specifier_nonarray
$$.basicType = EbtUint; $$.basicType = EbtUint;
$$.coopmat = true; $$.coopmat = true;
} }
| spirv_type_specifier {
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier");
$$ = $1;
}
| struct_specifier { | struct_specifier {
$$ = $1; $$ = $1;
@ -3575,6 +3652,12 @@ initializer
parseContext.profileRequires($1.loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); parseContext.profileRequires($1.loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature);
$$ = $2; $$ = $2;
} }
| LEFT_BRACE RIGHT_BRACE {
const char* initFeature = "empty { } initializer";
parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_EXT_null_initializer, initFeature);
parseContext.profileRequires($1.loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, initFeature);
$$ = parseContext.intermediate.makeAggregate($1.loc);
}
; ;
@ -3707,6 +3790,7 @@ selection_statement
} }
| attribute selection_statement_nonattributed { | attribute selection_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSelectionAttributes(*$1, $2); parseContext.handleSelectionAttributes(*$1, $2);
$$ = $2; $$ = $2;
} }
@ -3754,6 +3838,7 @@ switch_statement
} }
| attribute switch_statement_nonattributed { | attribute switch_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSwitchAttributes(*$1, $2); parseContext.handleSwitchAttributes(*$1, $2);
$$ = $2; $$ = $2;
} }
@ -3818,6 +3903,7 @@ iteration_statement
} }
| attribute iteration_statement_nonattributed { | attribute iteration_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleLoopAttributes(*$1, $2); parseContext.handleLoopAttributes(*$1, $2);
$$ = $2; $$ = $2;
} }
@ -4021,7 +4107,6 @@ function_definition
attribute attribute
: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET { : LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET {
$$ = $3; $$ = $3;
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_control_flow_attributes, "attribute");
} }
attribute_list attribute_list
@ -4041,4 +4126,273 @@ single_attribute
} }
spirv_requirements_list
: spirv_requirements_parameter {
$$ = $1;
}
| spirv_requirements_list COMMA spirv_requirements_parameter {
$$ = parseContext.mergeSpirvRequirements($2.loc, $1, $3);
}
spirv_requirements_parameter
: IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET {
$$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, $4->getAsAggregate(), nullptr);
}
| IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET {
$$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, nullptr, $4->getAsAggregate());
}
spirv_extension_list
: STRING_LITERAL {
$$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
}
| spirv_extension_list COMMA STRING_LITERAL {
$$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
}
spirv_capability_list
: INTCONSTANT {
$$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.i, $1.loc, true));
}
| spirv_capability_list COMMA INTCONSTANT {
$$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.i, $3.loc, true));
}
spirv_execution_mode_qualifier
: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN {
parseContext.intermediate.insertSpirvExecutionMode($3.i);
$$ = 0;
}
| SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
parseContext.intermediate.insertSpirvRequirement($3);
parseContext.intermediate.insertSpirvExecutionMode($5.i);
$$ = 0;
}
| SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
parseContext.intermediate.insertSpirvExecutionMode($3.i, $5->getAsAggregate());
$$ = 0;
}
| SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
parseContext.intermediate.insertSpirvRequirement($3);
parseContext.intermediate.insertSpirvExecutionMode($5.i, $7->getAsAggregate());
$$ = 0;
}
| SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
parseContext.intermediate.insertSpirvExecutionModeId($3.i, $5->getAsAggregate());
$$ = 0;
}
| SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
parseContext.intermediate.insertSpirvRequirement($3);
parseContext.intermediate.insertSpirvExecutionModeId($5.i, $7->getAsAggregate());
$$ = 0;
}
spirv_execution_mode_parameter_list
: spirv_execution_mode_parameter {
$$ = parseContext.intermediate.makeAggregate($1);
}
| spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter {
$$ = parseContext.intermediate.growAggregate($1, $3);
}
spirv_execution_mode_parameter
: FLOATCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
}
| INTCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
}
| UINTCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
}
| BOOLCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
}
| STRING_LITERAL {
$$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true);
}
spirv_execution_mode_id_parameter_list
: constant_expression {
if ($1->getBasicType() != EbtFloat &&
$1->getBasicType() != EbtInt &&
$1->getBasicType() != EbtUint &&
$1->getBasicType() != EbtBool &&
$1->getBasicType() != EbtString)
parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
$$ = parseContext.intermediate.makeAggregate($1);
}
| spirv_execution_mode_id_parameter_list COMMA constant_expression {
if ($3->getBasicType() != EbtFloat &&
$3->getBasicType() != EbtInt &&
$3->getBasicType() != EbtUint &&
$3->getBasicType() != EbtBool &&
$3->getBasicType() != EbtString)
parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
$$ = parseContext.intermediate.growAggregate($1, $3);
}
spirv_storage_class_qualifier
: SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN {
$$.init($1.loc);
$$.qualifier.storage = EvqSpirvStorageClass;
$$.qualifier.spirvStorageClass = $3.i;
}
| SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
$$.init($1.loc);
parseContext.intermediate.insertSpirvRequirement($3);
$$.qualifier.storage = EvqSpirvStorageClass;
$$.qualifier.spirvStorageClass = $5.i;
}
spirv_decorate_qualifier
: SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN{
$$.init($1.loc);
$$.qualifier.setSpirvDecorate($3.i);
}
| SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN{
$$.init($1.loc);
parseContext.intermediate.insertSpirvRequirement($3);
$$.qualifier.setSpirvDecorate($5.i);
}
| SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
$$.init($1.loc);
$$.qualifier.setSpirvDecorate($3.i, $5->getAsAggregate());
}
| SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
$$.init($1.loc);
parseContext.intermediate.insertSpirvRequirement($3);
$$.qualifier.setSpirvDecorate($5.i, $7->getAsAggregate());
}
| SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
$$.init($1.loc);
$$.qualifier.setSpirvDecorateId($3.i, $5->getAsAggregate());
}
| SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
$$.init($1.loc);
parseContext.intermediate.insertSpirvRequirement($3);
$$.qualifier.setSpirvDecorateId($5.i, $7->getAsAggregate());
}
| SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
$$.init($1.loc);
$$.qualifier.setSpirvDecorateString($3.i, $5->getAsAggregate());
}
| SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
$$.init($1.loc);
parseContext.intermediate.insertSpirvRequirement($3);
$$.qualifier.setSpirvDecorateString($5.i, $7->getAsAggregate());
}
spirv_decorate_parameter_list
: spirv_decorate_parameter {
$$ = parseContext.intermediate.makeAggregate($1);
}
| spirv_decorate_parameter_list COMMA spirv_decorate_parameter {
$$ = parseContext.intermediate.growAggregate($1, $3);
}
spirv_decorate_parameter
: FLOATCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
}
| INTCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
}
| UINTCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
}
| BOOLCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
}
spirv_decorate_id_parameter_list
: constant_expression {
if ($1->getBasicType() != EbtFloat &&
$1->getBasicType() != EbtInt &&
$1->getBasicType() != EbtUint &&
$1->getBasicType() != EbtBool)
parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
$$ = parseContext.intermediate.makeAggregate($1);
}
| spirv_decorate_id_parameter_list COMMA constant_expression {
if ($3->getBasicType() != EbtFloat &&
$3->getBasicType() != EbtInt &&
$3->getBasicType() != EbtUint &&
$3->getBasicType() != EbtBool)
parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
$$ = parseContext.intermediate.growAggregate($1, $3);
}
spirv_decorate_string_parameter_list
: STRING_LITERAL {
$$ = parseContext.intermediate.makeAggregate(
parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
}
| spirv_decorate_string_parameter_list COMMA STRING_LITERAL {
$$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
}
spirv_type_specifier
: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.setSpirvType(*$3, $5);
}
| SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
parseContext.intermediate.insertSpirvRequirement($3);
$$.setSpirvType(*$5, $7);
}
| SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.setSpirvType(*$3);
}
| SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
parseContext.intermediate.insertSpirvRequirement($3);
$$.setSpirvType(*$5);
}
spirv_type_parameter_list
: spirv_type_parameter {
$$ = $1;
}
| spirv_type_parameter_list COMMA spirv_type_parameter {
$$ = parseContext.mergeSpirvTypeParameters($1, $3);
}
spirv_type_parameter
: constant_expression {
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
}
| type_specifier {
$$ = parseContext.makeSpirvTypeParameters($1);
}
spirv_instruction_qualifier
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
$$ = $3;
}
| SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
parseContext.intermediate.insertSpirvRequirement($3);
$$ = $5;
}
spirv_instruction_qualifier_list
: spirv_instruction_qualifier_id {
$$ = $1;
}
| spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id {
$$ = parseContext.mergeSpirvInstruction($2.loc, $1, $3);
}
spirv_instruction_qualifier_id
: IDENTIFIER EQUAL STRING_LITERAL {
$$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, *$3.string);
}
| IDENTIFIER EQUAL INTCONSTANT {
$$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, $3.i);
}
%% %%

File diff suppressed because it is too large Load diff

View file

@ -368,134 +368,144 @@ extern int yydebug;
USUBPASSINPUTMS = 569, /* USUBPASSINPUTMS */ USUBPASSINPUTMS = 569, /* USUBPASSINPUTMS */
F16SUBPASSINPUT = 570, /* F16SUBPASSINPUT */ F16SUBPASSINPUT = 570, /* F16SUBPASSINPUT */
F16SUBPASSINPUTMS = 571, /* F16SUBPASSINPUTMS */ F16SUBPASSINPUTMS = 571, /* F16SUBPASSINPUTMS */
LEFT_OP = 572, /* LEFT_OP */ SPIRV_INSTRUCTION = 572, /* SPIRV_INSTRUCTION */
RIGHT_OP = 573, /* RIGHT_OP */ SPIRV_EXECUTION_MODE = 573, /* SPIRV_EXECUTION_MODE */
INC_OP = 574, /* INC_OP */ SPIRV_EXECUTION_MODE_ID = 574, /* SPIRV_EXECUTION_MODE_ID */
DEC_OP = 575, /* DEC_OP */ SPIRV_DECORATE = 575, /* SPIRV_DECORATE */
LE_OP = 576, /* LE_OP */ SPIRV_DECORATE_ID = 576, /* SPIRV_DECORATE_ID */
GE_OP = 577, /* GE_OP */ SPIRV_DECORATE_STRING = 577, /* SPIRV_DECORATE_STRING */
EQ_OP = 578, /* EQ_OP */ SPIRV_TYPE = 578, /* SPIRV_TYPE */
NE_OP = 579, /* NE_OP */ SPIRV_STORAGE_CLASS = 579, /* SPIRV_STORAGE_CLASS */
AND_OP = 580, /* AND_OP */ SPIRV_BY_REFERENCE = 580, /* SPIRV_BY_REFERENCE */
OR_OP = 581, /* OR_OP */ SPIRV_LITERAL = 581, /* SPIRV_LITERAL */
XOR_OP = 582, /* XOR_OP */ LEFT_OP = 582, /* LEFT_OP */
MUL_ASSIGN = 583, /* MUL_ASSIGN */ RIGHT_OP = 583, /* RIGHT_OP */
DIV_ASSIGN = 584, /* DIV_ASSIGN */ INC_OP = 584, /* INC_OP */
ADD_ASSIGN = 585, /* ADD_ASSIGN */ DEC_OP = 585, /* DEC_OP */
MOD_ASSIGN = 586, /* MOD_ASSIGN */ LE_OP = 586, /* LE_OP */
LEFT_ASSIGN = 587, /* LEFT_ASSIGN */ GE_OP = 587, /* GE_OP */
RIGHT_ASSIGN = 588, /* RIGHT_ASSIGN */ EQ_OP = 588, /* EQ_OP */
AND_ASSIGN = 589, /* AND_ASSIGN */ NE_OP = 589, /* NE_OP */
XOR_ASSIGN = 590, /* XOR_ASSIGN */ AND_OP = 590, /* AND_OP */
OR_ASSIGN = 591, /* OR_ASSIGN */ OR_OP = 591, /* OR_OP */
SUB_ASSIGN = 592, /* SUB_ASSIGN */ XOR_OP = 592, /* XOR_OP */
STRING_LITERAL = 593, /* STRING_LITERAL */ MUL_ASSIGN = 593, /* MUL_ASSIGN */
LEFT_PAREN = 594, /* LEFT_PAREN */ DIV_ASSIGN = 594, /* DIV_ASSIGN */
RIGHT_PAREN = 595, /* RIGHT_PAREN */ ADD_ASSIGN = 595, /* ADD_ASSIGN */
LEFT_BRACKET = 596, /* LEFT_BRACKET */ MOD_ASSIGN = 596, /* MOD_ASSIGN */
RIGHT_BRACKET = 597, /* RIGHT_BRACKET */ LEFT_ASSIGN = 597, /* LEFT_ASSIGN */
LEFT_BRACE = 598, /* LEFT_BRACE */ RIGHT_ASSIGN = 598, /* RIGHT_ASSIGN */
RIGHT_BRACE = 599, /* RIGHT_BRACE */ AND_ASSIGN = 599, /* AND_ASSIGN */
DOT = 600, /* DOT */ XOR_ASSIGN = 600, /* XOR_ASSIGN */
COMMA = 601, /* COMMA */ OR_ASSIGN = 601, /* OR_ASSIGN */
COLON = 602, /* COLON */ SUB_ASSIGN = 602, /* SUB_ASSIGN */
EQUAL = 603, /* EQUAL */ STRING_LITERAL = 603, /* STRING_LITERAL */
SEMICOLON = 604, /* SEMICOLON */ LEFT_PAREN = 604, /* LEFT_PAREN */
BANG = 605, /* BANG */ RIGHT_PAREN = 605, /* RIGHT_PAREN */
DASH = 606, /* DASH */ LEFT_BRACKET = 606, /* LEFT_BRACKET */
TILDE = 607, /* TILDE */ RIGHT_BRACKET = 607, /* RIGHT_BRACKET */
PLUS = 608, /* PLUS */ LEFT_BRACE = 608, /* LEFT_BRACE */
STAR = 609, /* STAR */ RIGHT_BRACE = 609, /* RIGHT_BRACE */
SLASH = 610, /* SLASH */ DOT = 610, /* DOT */
PERCENT = 611, /* PERCENT */ COMMA = 611, /* COMMA */
LEFT_ANGLE = 612, /* LEFT_ANGLE */ COLON = 612, /* COLON */
RIGHT_ANGLE = 613, /* RIGHT_ANGLE */ EQUAL = 613, /* EQUAL */
VERTICAL_BAR = 614, /* VERTICAL_BAR */ SEMICOLON = 614, /* SEMICOLON */
CARET = 615, /* CARET */ BANG = 615, /* BANG */
AMPERSAND = 616, /* AMPERSAND */ DASH = 616, /* DASH */
QUESTION = 617, /* QUESTION */ TILDE = 617, /* TILDE */
INVARIANT = 618, /* INVARIANT */ PLUS = 618, /* PLUS */
HIGH_PRECISION = 619, /* HIGH_PRECISION */ STAR = 619, /* STAR */
MEDIUM_PRECISION = 620, /* MEDIUM_PRECISION */ SLASH = 620, /* SLASH */
LOW_PRECISION = 621, /* LOW_PRECISION */ PERCENT = 621, /* PERCENT */
PRECISION = 622, /* PRECISION */ LEFT_ANGLE = 622, /* LEFT_ANGLE */
PACKED = 623, /* PACKED */ RIGHT_ANGLE = 623, /* RIGHT_ANGLE */
RESOURCE = 624, /* RESOURCE */ VERTICAL_BAR = 624, /* VERTICAL_BAR */
SUPERP = 625, /* SUPERP */ CARET = 625, /* CARET */
FLOATCONSTANT = 626, /* FLOATCONSTANT */ AMPERSAND = 626, /* AMPERSAND */
INTCONSTANT = 627, /* INTCONSTANT */ QUESTION = 627, /* QUESTION */
UINTCONSTANT = 628, /* UINTCONSTANT */ INVARIANT = 628, /* INVARIANT */
BOOLCONSTANT = 629, /* BOOLCONSTANT */ HIGH_PRECISION = 629, /* HIGH_PRECISION */
IDENTIFIER = 630, /* IDENTIFIER */ MEDIUM_PRECISION = 630, /* MEDIUM_PRECISION */
TYPE_NAME = 631, /* TYPE_NAME */ LOW_PRECISION = 631, /* LOW_PRECISION */
CENTROID = 632, /* CENTROID */ PRECISION = 632, /* PRECISION */
IN = 633, /* IN */ PACKED = 633, /* PACKED */
OUT = 634, /* OUT */ RESOURCE = 634, /* RESOURCE */
INOUT = 635, /* INOUT */ SUPERP = 635, /* SUPERP */
STRUCT = 636, /* STRUCT */ FLOATCONSTANT = 636, /* FLOATCONSTANT */
VOID = 637, /* VOID */ INTCONSTANT = 637, /* INTCONSTANT */
WHILE = 638, /* WHILE */ UINTCONSTANT = 638, /* UINTCONSTANT */
BREAK = 639, /* BREAK */ BOOLCONSTANT = 639, /* BOOLCONSTANT */
CONTINUE = 640, /* CONTINUE */ IDENTIFIER = 640, /* IDENTIFIER */
DO = 641, /* DO */ TYPE_NAME = 641, /* TYPE_NAME */
ELSE = 642, /* ELSE */ CENTROID = 642, /* CENTROID */
FOR = 643, /* FOR */ IN = 643, /* IN */
IF = 644, /* IF */ OUT = 644, /* OUT */
DISCARD = 645, /* DISCARD */ INOUT = 645, /* INOUT */
RETURN = 646, /* RETURN */ STRUCT = 646, /* STRUCT */
SWITCH = 647, /* SWITCH */ VOID = 647, /* VOID */
CASE = 648, /* CASE */ WHILE = 648, /* WHILE */
DEFAULT = 649, /* DEFAULT */ BREAK = 649, /* BREAK */
TERMINATE_INVOCATION = 650, /* TERMINATE_INVOCATION */ CONTINUE = 650, /* CONTINUE */
TERMINATE_RAY = 651, /* TERMINATE_RAY */ DO = 651, /* DO */
IGNORE_INTERSECTION = 652, /* IGNORE_INTERSECTION */ ELSE = 652, /* ELSE */
UNIFORM = 653, /* UNIFORM */ FOR = 653, /* FOR */
SHARED = 654, /* SHARED */ IF = 654, /* IF */
BUFFER = 655, /* BUFFER */ DISCARD = 655, /* DISCARD */
FLAT = 656, /* FLAT */ RETURN = 656, /* RETURN */
SMOOTH = 657, /* SMOOTH */ SWITCH = 657, /* SWITCH */
LAYOUT = 658, /* LAYOUT */ CASE = 658, /* CASE */
DOUBLECONSTANT = 659, /* DOUBLECONSTANT */ DEFAULT = 659, /* DEFAULT */
INT16CONSTANT = 660, /* INT16CONSTANT */ TERMINATE_INVOCATION = 660, /* TERMINATE_INVOCATION */
UINT16CONSTANT = 661, /* UINT16CONSTANT */ TERMINATE_RAY = 661, /* TERMINATE_RAY */
FLOAT16CONSTANT = 662, /* FLOAT16CONSTANT */ IGNORE_INTERSECTION = 662, /* IGNORE_INTERSECTION */
INT32CONSTANT = 663, /* INT32CONSTANT */ UNIFORM = 663, /* UNIFORM */
UINT32CONSTANT = 664, /* UINT32CONSTANT */ SHARED = 664, /* SHARED */
INT64CONSTANT = 665, /* INT64CONSTANT */ BUFFER = 665, /* BUFFER */
UINT64CONSTANT = 666, /* UINT64CONSTANT */ FLAT = 666, /* FLAT */
SUBROUTINE = 667, /* SUBROUTINE */ SMOOTH = 667, /* SMOOTH */
DEMOTE = 668, /* DEMOTE */ LAYOUT = 668, /* LAYOUT */
PAYLOADNV = 669, /* PAYLOADNV */ DOUBLECONSTANT = 669, /* DOUBLECONSTANT */
PAYLOADINNV = 670, /* PAYLOADINNV */ INT16CONSTANT = 670, /* INT16CONSTANT */
HITATTRNV = 671, /* HITATTRNV */ UINT16CONSTANT = 671, /* UINT16CONSTANT */
CALLDATANV = 672, /* CALLDATANV */ FLOAT16CONSTANT = 672, /* FLOAT16CONSTANT */
CALLDATAINNV = 673, /* CALLDATAINNV */ INT32CONSTANT = 673, /* INT32CONSTANT */
PAYLOADEXT = 674, /* PAYLOADEXT */ UINT32CONSTANT = 674, /* UINT32CONSTANT */
PAYLOADINEXT = 675, /* PAYLOADINEXT */ INT64CONSTANT = 675, /* INT64CONSTANT */
HITATTREXT = 676, /* HITATTREXT */ UINT64CONSTANT = 676, /* UINT64CONSTANT */
CALLDATAEXT = 677, /* CALLDATAEXT */ SUBROUTINE = 677, /* SUBROUTINE */
CALLDATAINEXT = 678, /* CALLDATAINEXT */ DEMOTE = 678, /* DEMOTE */
PATCH = 679, /* PATCH */ PAYLOADNV = 679, /* PAYLOADNV */
SAMPLE = 680, /* SAMPLE */ PAYLOADINNV = 680, /* PAYLOADINNV */
NONUNIFORM = 681, /* NONUNIFORM */ HITATTRNV = 681, /* HITATTRNV */
COHERENT = 682, /* COHERENT */ CALLDATANV = 682, /* CALLDATANV */
VOLATILE = 683, /* VOLATILE */ CALLDATAINNV = 683, /* CALLDATAINNV */
RESTRICT = 684, /* RESTRICT */ PAYLOADEXT = 684, /* PAYLOADEXT */
READONLY = 685, /* READONLY */ PAYLOADINEXT = 685, /* PAYLOADINEXT */
WRITEONLY = 686, /* WRITEONLY */ HITATTREXT = 686, /* HITATTREXT */
DEVICECOHERENT = 687, /* DEVICECOHERENT */ CALLDATAEXT = 687, /* CALLDATAEXT */
QUEUEFAMILYCOHERENT = 688, /* QUEUEFAMILYCOHERENT */ CALLDATAINEXT = 688, /* CALLDATAINEXT */
WORKGROUPCOHERENT = 689, /* WORKGROUPCOHERENT */ PATCH = 689, /* PATCH */
SUBGROUPCOHERENT = 690, /* SUBGROUPCOHERENT */ SAMPLE = 690, /* SAMPLE */
NONPRIVATE = 691, /* NONPRIVATE */ NONUNIFORM = 691, /* NONUNIFORM */
SHADERCALLCOHERENT = 692, /* SHADERCALLCOHERENT */ COHERENT = 692, /* COHERENT */
NOPERSPECTIVE = 693, /* NOPERSPECTIVE */ VOLATILE = 693, /* VOLATILE */
EXPLICITINTERPAMD = 694, /* EXPLICITINTERPAMD */ RESTRICT = 694, /* RESTRICT */
PERVERTEXNV = 695, /* PERVERTEXNV */ READONLY = 695, /* READONLY */
PERPRIMITIVENV = 696, /* PERPRIMITIVENV */ WRITEONLY = 696, /* WRITEONLY */
PERVIEWNV = 697, /* PERVIEWNV */ DEVICECOHERENT = 697, /* DEVICECOHERENT */
PERTASKNV = 698, /* PERTASKNV */ QUEUEFAMILYCOHERENT = 698, /* QUEUEFAMILYCOHERENT */
PRECISE = 699 /* PRECISE */ WORKGROUPCOHERENT = 699, /* WORKGROUPCOHERENT */
SUBGROUPCOHERENT = 700, /* SUBGROUPCOHERENT */
NONPRIVATE = 701, /* NONPRIVATE */
SHADERCALLCOHERENT = 702, /* SHADERCALLCOHERENT */
NOPERSPECTIVE = 703, /* NOPERSPECTIVE */
EXPLICITINTERPAMD = 704, /* EXPLICITINTERPAMD */
PERVERTEXNV = 705, /* PERVERTEXNV */
PERPRIMITIVENV = 706, /* PERPRIMITIVENV */
PERVIEWNV = 707, /* PERVIEWNV */
PERTASKNV = 708, /* PERTASKNV */
PRECISE = 709 /* PRECISE */
}; };
typedef enum yytokentype yytoken_kind_t; typedef enum yytokentype yytoken_kind_t;
#endif #endif
@ -527,6 +537,9 @@ union YYSTYPE
glslang::TIntermNodePair nodePair; glslang::TIntermNodePair nodePair;
glslang::TIntermTyped* intermTypedNode; glslang::TIntermTyped* intermTypedNode;
glslang::TAttributes* attributes; glslang::TAttributes* attributes;
glslang::TSpirvRequirement* spirvReq;
glslang::TSpirvInstruction* spirvInst;
glslang::TSpirvTypeParameters* spirvTypeParams;
}; };
union { union {
glslang::TPublicType type; glslang::TPublicType type;
@ -540,7 +553,7 @@ union YYSTYPE
glslang::TArraySizes* typeParameters; glslang::TArraySizes* typeParameters;
} interm; } interm;
#line 544 "MachineIndependent/glslang_tab.cpp.h" #line 557 "MachineIndependent/glslang_tab.cpp.h"
}; };
typedef union YYSTYPE YYSTYPE; typedef union YYSTYPE YYSTYPE;

View file

@ -696,6 +696,10 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpConstructReference: out.debug << "Construct reference type"; break; case EOpConstructReference: out.debug << "Construct reference type"; break;
#ifndef GLSLANG_WEB
case EOpSpirvInst: out.debug << "spirv_instruction"; break;
#endif
default: out.debug.message(EPrefixError, "Bad unary op"); default: out.debug.message(EPrefixError, "Bad unary op");
} }
@ -886,6 +890,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpTime: out.debug << "time"; break; case EOpTime: out.debug << "time"; break;
case EOpAtomicAdd: out.debug << "AtomicAdd"; break; case EOpAtomicAdd: out.debug << "AtomicAdd"; break;
case EOpAtomicSubtract: out.debug << "AtomicSubtract"; break;
case EOpAtomicMin: out.debug << "AtomicMin"; break; case EOpAtomicMin: out.debug << "AtomicMin"; break;
case EOpAtomicMax: out.debug << "AtomicMax"; break; case EOpAtomicMax: out.debug << "AtomicMax"; break;
case EOpAtomicAnd: out.debug << "AtomicAnd"; break; case EOpAtomicAnd: out.debug << "AtomicAnd"; break;
@ -1084,6 +1089,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
case EOpTraceNV: out.debug << "traceNV"; break; case EOpTraceNV: out.debug << "traceNV"; break;
case EOpTraceRayMotionNV: out.debug << "traceRayMotionNV"; break;
case EOpTraceKHR: out.debug << "traceRayKHR"; break; case EOpTraceKHR: out.debug << "traceRayKHR"; break;
case EOpReportIntersection: out.debug << "reportIntersectionNV"; break; case EOpReportIntersection: out.debug << "reportIntersectionNV"; break;
case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break; case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break;
@ -1125,6 +1131,10 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break; case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break;
case EOpDebugPrintf: out.debug << "Debug printf"; break; case EOpDebugPrintf: out.debug << "Debug printf"; break;
#ifndef GLSLANG_WEB
case EOpSpirvInst: out.debug << "spirv_instruction"; break;
#endif
default: out.debug.message(EPrefixError, "Bad aggregation op"); default: out.debug.message(EPrefixError, "Bad aggregation op");
} }
@ -1486,6 +1496,9 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
if (xfbMode) if (xfbMode)
infoSink.debug << "in xfb mode\n"; infoSink.debug << "in xfb mode\n";
if (getSubgroupUniformControlFlow())
infoSink.debug << "subgroup_uniform_control_flow\n";
switch (language) { switch (language) {
case EShLangVertex: case EShLangVertex:
break; break;

View file

@ -210,8 +210,8 @@ struct TResolverUniformAdaptor {
ent.newIndex = -1; ent.newIndex = -1;
const bool isValid = resolver.validateBinding(stage, ent); const bool isValid = resolver.validateBinding(stage, ent);
if (isValid) { if (isValid) {
resolver.resolveBinding(ent.stage, ent);
resolver.resolveSet(ent.stage, ent); resolver.resolveSet(ent.stage, ent);
resolver.resolveBinding(ent.stage, ent);
resolver.resolveUniformLocation(ent.stage, ent); resolver.resolveUniformLocation(ent.stage, ent);
if (ent.newBinding != -1) { if (ent.newBinding != -1) {
@ -317,15 +317,13 @@ private:
}; };
// 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
// xxTODO: maybe this logic should be moved into the resolver's "validateInOut" and "validateUniform"
struct TSymbolValidater struct TSymbolValidater
{ {
TSymbolValidater(TIoMapResolver& r, TInfoSink& i, TVarLiveMap* in[EShLangCount], TVarLiveMap* out[EShLangCount], TSymbolValidater(TIoMapResolver& r, TInfoSink& i, TVarLiveMap* in[EShLangCount], TVarLiveMap* out[EShLangCount],
TVarLiveMap* uniform[EShLangCount], bool& hadError, EProfile profile, int version) TVarLiveMap* uniform[EShLangCount], bool& hadError, EProfile profile, int version)
: preStage(EShLangCount) : resolver(r)
, currentStage(EShLangCount)
, nextStage(EShLangCount)
, resolver(r)
, infoSink(i) , infoSink(i)
, hadError(hadError) , hadError(hadError)
, profile(profile) , profile(profile)
@ -438,17 +436,23 @@ 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;
EShLanguage stage = ent1.stage;
TString mangleName1, mangleName2; TString mangleName1, mangleName2;
if (currentStage != stage) { EShLanguage stage = ent1.stage;
preStage = currentStage; EShLanguage preStage, currentStage, nextStage;
currentStage = stage;
nextStage = EShLangCount; preStage = EShLangCount;
for (int i = currentStage + 1; i < EShLangCount; i++) { for (int i = stage - 1; i >= 0; i--) {
if (inVarMaps[i] != nullptr) { if (inVarMaps[i] != nullptr) {
nextStage = static_cast<EShLanguage>(i); preStage = static_cast<EShLanguage>(i);
break; break;
} }
}
currentStage = stage;
nextStage = EShLangCount;
for (int i = stage + 1; i < EShLangCount; i++) {
if (inVarMaps[i] != nullptr) {
nextStage = static_cast<EShLanguage>(i);
break;
} }
} }
@ -459,6 +463,9 @@ struct TSymbolValidater
type.appendMangledName(mangleName1); type.appendMangledName(mangleName1);
} }
// basic checking that symbols match
// more extensive checking in the link stage
if (base->getQualifier().storage == EvqVaryingIn) { if (base->getQualifier().storage == EvqVaryingIn) {
// validate stage in; // validate stage in;
if (preStage == EShLangCount) if (preStage == EShLangCount)
@ -484,8 +491,7 @@ struct TSymbolValidater
if (ent2->second.symbol->getType().getQualifier().isArrayedIo(preStage)) { if (ent2->second.symbol->getType().getQualifier().isArrayedIo(preStage)) {
TType subType(ent2->second.symbol->getType(), 0); TType subType(ent2->second.symbol->getType(), 0);
subType.appendMangledName(mangleName2); subType.appendMangledName(mangleName2);
} } else {
else {
ent2->second.symbol->getType().appendMangledName(mangleName2); ent2->second.symbol->getType().appendMangledName(mangleName2);
} }
@ -536,8 +542,7 @@ struct TSymbolValidater
if (ent2->second.symbol->getType().getQualifier().isArrayedIo(nextStage)) { if (ent2->second.symbol->getType().getQualifier().isArrayedIo(nextStage)) {
TType subType(ent2->second.symbol->getType(), 0); TType subType(ent2->second.symbol->getType(), 0);
subType.appendMangledName(mangleName2); subType.appendMangledName(mangleName2);
} } else {
else {
ent2->second.symbol->getType().appendMangledName(mangleName2); ent2->second.symbol->getType().appendMangledName(mangleName2);
} }
if (mangleName1 == mangleName2) if (mangleName1 == mangleName2)
@ -550,7 +555,7 @@ struct TSymbolValidater
} }
return; return;
} }
} else if (base->getQualifier().isUniformOrBuffer() && ! base->getQualifier().isPushConstant()) { } else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant()) {
// validate uniform type; // validate uniform type;
for (int i = 0; i < EShLangCount; i++) { for (int i = 0; i < EShLangCount; i++) {
if (i != currentStage && outVarMaps[i] != nullptr) { if (i != currentStage && outVarMaps[i] != nullptr) {
@ -558,6 +563,7 @@ struct TSymbolValidater
if (ent2 != uniformVarMap[i]->end()) { if (ent2 != uniformVarMap[i]->end()) {
ent2->second.symbol->getType().appendMangledName(mangleName2); ent2->second.symbol->getType().appendMangledName(mangleName2);
if (mangleName1 != mangleName2) { if (mangleName1 != mangleName2) {
ent2->second.symbol->getType().sameElementType(type);
TString err = "Invalid Uniform variable type : " + entKey.first; TString err = "Invalid Uniform variable type : " + entKey.first;
infoSink.info.message(EPrefixInternalError, err.c_str()); infoSink.info.message(EPrefixInternalError, err.c_str());
hadError = true; hadError = true;
@ -608,8 +614,7 @@ struct TSymbolValidater
} }
TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], *uniformVarMap[EShLangCount]; TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], *uniformVarMap[EShLangCount];
// Use for mark pre stage, to get more interface symbol information.
EShLanguage preStage, currentStage, nextStage;
// Use for mark current shader stage for resolver // Use for mark current shader stage for resolver
TIoMapResolver& resolver; TIoMapResolver& resolver;
TInfoSink& infoSink; TInfoSink& infoSink;
@ -749,14 +754,18 @@ TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate
, nextOutputLocation(0) , nextOutputLocation(0)
{ {
memset(stageMask, false, sizeof(bool) * (EShLangCount + 1)); memset(stageMask, false, sizeof(bool) * (EShLangCount + 1));
memset(stageIntermediates, 0, sizeof(TIntermediate*) * (EShLangCount));
stageIntermediates[intermediate.getStage()] = &intermediate;
} }
int TDefaultIoResolverBase::getBaseBinding(TResourceType res, unsigned int set) const { int TDefaultIoResolverBase::getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const {
return selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set)); return stageIntermediates[stage] ? selectBaseBinding(stageIntermediates[stage]->getShiftBinding(res), stageIntermediates[stage]->getShiftBindingForSet(res, set))
: selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set));
} }
const std::vector<std::string>& TDefaultIoResolverBase::getResourceSetBinding() const { const std::vector<std::string>& TDefaultIoResolverBase::getResourceSetBinding(EShLanguage stage) const {
return intermediate.getResourceSetBinding(); return stageIntermediates[stage] ? stageIntermediates[stage]->getResourceSetBinding()
: intermediate.getResourceSetBinding();
} }
bool TDefaultIoResolverBase::doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); } bool TDefaultIoResolverBase::doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }
@ -797,14 +806,14 @@ int TDefaultIoResolverBase::getFreeSlot(int set, int base, int size) {
return reserveSlot(set, base, size); return reserveSlot(set, base, size);
} }
int TDefaultIoResolverBase::resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) { int TDefaultIoResolverBase::resolveSet(EShLanguage stage, TVarEntryInfo& ent) {
const TType& type = ent.symbol->getType(); const TType& type = ent.symbol->getType();
if (type.getQualifier().hasSet()) { if (type.getQualifier().hasSet()) {
return ent.newSet = type.getQualifier().layoutSet; return ent.newSet = type.getQualifier().layoutSet;
} }
// If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN) // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN)
if (getResourceSetBinding().size() == 1) { if (getResourceSetBinding(stage).size() == 1) {
return ent.newSet = atoi(getResourceSetBinding()[0].c_str()); return ent.newSet = atoi(getResourceSetBinding(stage)[0].c_str());
} }
return ent.newSet = 0; return ent.newSet = 0;
} }
@ -925,7 +934,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
preStage = currentStage; preStage = currentStage;
currentStage = stage; currentStage = stage;
} }
// kick out of not doing this // kick out if not doing this
if (! doAutoLocationMapping()) { if (! doAutoLocationMapping()) {
return ent.newLocation = -1; return ent.newLocation = -1;
} }
@ -1073,7 +1082,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
return ent.newLocation = location; return ent.newLocation = location;
} }
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->getAccessName(); const TString& name = ent.symbol->getAccessName();
// On OpenGL arrays of opaque types take a separate binding for each element // On OpenGL arrays of opaque types take a separate binding for each element
@ -1086,30 +1095,32 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo&
// There is no 'set' qualifier in OpenGL shading language, each resource has its own // There is no 'set' qualifier in OpenGL shading language, each resource has its own
// binding name space, so remap the 'set' to resource type which make each resource // binding name space, so remap the 'set' to resource type which make each resource
// binding is valid from 0 to MAX_XXRESOURCE_BINDINGS // binding is valid from 0 to MAX_XXRESOURCE_BINDINGS
int set = resource; int set = intermediate.getSpv().openGl != 0 ? resource : ent.newSet;
int resourceKey = set;
if (resource < EResCount) { if (resource < EResCount) {
if (type.getQualifier().hasBinding()) { if (type.getQualifier().hasBinding()) {
ent.newBinding = reserveSlot(set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding, numBindings); int newBinding = reserveSlot(resourceKey, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings);
return ent.newBinding; return ent.newBinding = newBinding;
} else if (ent.live && doAutoBindingMapping()) {
} else {
// The resource in current stage is not declared with binding, but it is possible declared // The resource in current stage is not declared with binding, but it is possible declared
// with explicit binding in other stages, find the resourceSlotMap firstly to check whether // with explicit binding in other stages, find the resourceSlotMap firstly to check whether
// the resource has binding, don't need to allocate if it already has a binding // the resource has binding, don't need to allocate if it already has a binding
bool hasBinding = false; bool hasBinding = false;
if (! resourceSlotMap[resource].empty()) { ent.newBinding = -1; // leave as -1 if it isn't set below
TVarSlotMap::iterator iter = resourceSlotMap[resource].find(name);
if (iter != resourceSlotMap[resource].end()) { if (! resourceSlotMap[resourceKey].empty()) {
TVarSlotMap::iterator iter = resourceSlotMap[resourceKey].find(name);
if (iter != resourceSlotMap[resourceKey].end()) {
hasBinding = true; hasBinding = true;
ent.newBinding = iter->second; ent.newBinding = iter->second;
} }
} }
if (! hasBinding) { if (!hasBinding && (ent.live && doAutoBindingMapping())) {
TVarSlotMap varSlotMap;
// find free slot, the caller did make sure it passes all vars with binding // find free slot, the caller did make sure it passes all vars with binding
// first and now all are passed that do not have a binding and needs one // first and now all are passed that do not have a binding and needs one
int binding = getFreeSlot(resource, getBaseBinding(resource, set), numBindings); int binding = getFreeSlot(resourceKey, getBaseBinding(stage, resource, set), numBindings);
varSlotMap[name] = binding; resourceSlotMap[resourceKey][name] = binding;
resourceSlotMap[resource] = varSlotMap;
ent.newBinding = binding; ent.newBinding = binding;
} }
return ent.newBinding; return ent.newBinding;
@ -1211,16 +1222,20 @@ 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->getAccessName(); const TString& name = ent.symbol->getAccessName();
int resource = getResourceType(type); TResourceType resource = getResourceType(type);
int set = intermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent);
int resourceKey = set;
if (type.getQualifier().hasBinding()) { if (type.getQualifier().hasBinding()) {
TVarSlotMap& varSlotMap = resourceSlotMap[resource]; TVarSlotMap& varSlotMap = resourceSlotMap[resourceKey];
TVarSlotMap::iterator iter = varSlotMap.find(name); TVarSlotMap::iterator iter = varSlotMap.find(name);
int binding = type.getQualifier().layoutBinding; int binding = type.getQualifier().layoutBinding + getBaseBinding(ent.stage, resource, set);
if (iter == varSlotMap.end()) { if (iter == varSlotMap.end()) {
// Reserve the slots for the ubo, ssbo and opaques who has explicit binding // Reserve the slots for the ubo, ssbo and opaques who has explicit binding
int numBindings = type.isSizedArray() ? type.getCumulativeArraySize() : 1; int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
varSlotMap[name] = binding; varSlotMap[name] = binding;
reserveSlot(resource, binding, numBindings); reserveSlot(resourceKey, binding, numBindings);
} else { } else {
// Allocate binding by name for OpenGL driver, so the resource in different // Allocate binding by name for OpenGL driver, so the resource in different
// stages should be declared with the same binding // stages should be declared with the same binding
@ -1269,7 +1284,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
return EResCount; return EResCount;
} }
int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override { int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) override {
const TType& type = ent.symbol->getType(); const TType& type = ent.symbol->getType();
const int set = getLayoutSet(type); const int set = getLayoutSet(type);
// On OpenGL arrays of opaque types take a seperate binding for each element // On OpenGL arrays of opaque types take a seperate binding for each element
@ -1278,11 +1293,11 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
if (resource < EResCount) { if (resource < EResCount) {
if (type.getQualifier().hasBinding()) { if (type.getQualifier().hasBinding()) {
return ent.newBinding = reserveSlot( return ent.newBinding = reserveSlot(
set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding, numBindings); set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings);
} else if (ent.live && doAutoBindingMapping()) { } else if (ent.live && doAutoBindingMapping()) {
// find free slot, the caller did make sure it passes all vars with binding // find free slot, the caller did make sure it passes all vars with binding
// first and now all are passed that do not have a binding and needs one // first and now all are passed that do not have a binding and needs one
return ent.newBinding = getFreeSlot(set, getBaseBinding(resource, set), numBindings); return ent.newBinding = getFreeSlot(set, getBaseBinding(stage, resource, set), numBindings);
} }
} }
return ent.newBinding = -1; return ent.newBinding = -1;
@ -1354,17 +1369,17 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase {
return EResCount; return EResCount;
} }
int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override { int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) override {
const TType& type = ent.symbol->getType(); const TType& type = ent.symbol->getType();
const int set = getLayoutSet(type); const int set = getLayoutSet(type);
TResourceType resource = getResourceType(type); TResourceType resource = getResourceType(type);
if (resource < EResCount) { if (resource < EResCount) {
if (type.getQualifier().hasBinding()) { if (type.getQualifier().hasBinding()) {
return ent.newBinding = reserveSlot(set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding); return ent.newBinding = reserveSlot(set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding);
} else if (ent.live && doAutoBindingMapping()) { } else if (ent.live && doAutoBindingMapping()) {
// find free slot, the caller did make sure it passes all vars with binding // find free slot, the caller did make sure it passes all vars with binding
// first and now all are passed that do not have a binding and needs one // first and now all are passed that do not have a binding and needs one
return ent.newBinding = getFreeSlot(set, getBaseBinding(resource, set)); return ent.newBinding = getFreeSlot(set, getBaseBinding(stage, resource, set));
} }
} }
return ent.newBinding = -1; return ent.newBinding = -1;
@ -1403,10 +1418,10 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
else else
resolver = &defaultResolver; resolver = &defaultResolver;
} }
resolver->addStage(stage);
#else #else
resolver = &defaultResolver; resolver = &defaultResolver;
#endif #endif
resolver->addStage(stage, intermediate);
TVarLiveMap inVarMap, outVarMap, uniformVarMap; TVarLiveMap inVarMap, outVarMap, uniformVarMap;
TVarLiveVector inVector, outVector, uniformVector; TVarLiveVector inVector, outVector, uniformVector;
@ -1502,10 +1517,21 @@ bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TIn
} }
// if no resolver is provided, use the default resolver with the given shifts and auto map settings // if no resolver is provided, use the default resolver with the given shifts and auto map settings
TDefaultGlslIoResolver defaultResolver(intermediate); TDefaultGlslIoResolver defaultResolver(intermediate);
#ifdef ENABLE_HLSL
TDefaultHlslIoResolver defaultHlslResolver(intermediate);
if (resolver == nullptr) {
// TODO: use a passed in IO mapper for this
if (intermediate.usingHlslIoMapping())
resolver = &defaultHlslResolver;
else
resolver = &defaultResolver;
}
#else
if (resolver == nullptr) { if (resolver == nullptr) {
resolver = &defaultResolver; resolver = &defaultResolver;
} }
resolver->addStage(stage); #endif
resolver->addStage(stage, intermediate);
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]);
@ -1547,15 +1573,51 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
TResolverInOutAdaptor inOutResolve(EShLangCount, *resolver, infoSink, hadError); TResolverInOutAdaptor inOutResolve(EShLangCount, *resolver, infoSink, hadError);
TSymbolValidater symbolValidater(*resolver, infoSink, inVarMaps, TSymbolValidater symbolValidater(*resolver, infoSink, inVarMaps,
outVarMaps, uniformVarMap, hadError, profile, version); outVarMaps, uniformVarMap, hadError, profile, version);
TVarLiveVector inVectors[EShLangCount];
TVarLiveVector outVectors[EShLangCount];
TVarLiveVector uniformVector; TVarLiveVector uniformVector;
resolver->beginResolve(EShLangCount); resolver->beginResolve(EShLangCount);
for (int stage = EShLangVertex; stage < EShLangCount; stage++) { for (int stage = EShLangVertex; stage < EShLangCount; stage++) {
if (inVarMaps[stage] != nullptr) { if (inVarMaps[stage] != nullptr) {
inOutResolve.setStage(EShLanguage(stage)); inOutResolve.setStage(EShLanguage(stage));
for (auto& var : *(inVarMaps[stage])) { symbolValidater(var); }
for (auto& var : *(inVarMaps[stage])) { inOutResolve(var); } // copy vars into a sorted list
for (auto& var : *(outVarMaps[stage])) { symbolValidater(var); } std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(),
for (auto& var : *(outVarMaps[stage])) { inOutResolve(var); } [&inVectors, stage](TVarLivePair p) { inVectors[stage].push_back(p); });
std::sort(inVectors[stage].begin(), inVectors[stage].end(),
[](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
});
std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(),
[&outVectors, stage](TVarLivePair p) { outVectors[stage].push_back(p); });
std::sort(outVectors[stage].begin(), outVectors[stage].end(),
[](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
});
for (auto& var : inVectors[stage]) { symbolValidater(var); }
for (auto& var : inVectors[stage]) { inOutResolve(var); }
for (auto& var : outVectors[stage]) { symbolValidater(var); }
for (auto& var : outVectors[stage]) { inOutResolve(var); }
// copy results back into maps
std::for_each(inVectors[stage].begin(), inVectors[stage].end(),
[this, stage](TVarLivePair p) {
auto at = inVarMaps[stage]->find(p.first);
if (at != inVarMaps[stage]->end())
at->second = p.second;
});
std::for_each(outVectors[stage].begin(), outVectors[stage].end(),
[this, stage](TVarLivePair p) {
auto at = outVarMaps[stage]->find(p.first);
if (at != outVarMaps[stage]->end())
at->second = p.second;
});
} }
if (uniformVarMap[stage] != nullptr) { if (uniformVarMap[stage] != nullptr) {
uniformResolve.setStage(EShLanguage(stage)); uniformResolve.setStage(EShLanguage(stage));
@ -1563,7 +1625,7 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
} }
} }
std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); return TVarEntryInfo::TOrderByPriorityAndLive()(p1.second, p2.second);
}); });
for (auto& var : uniformVector) { symbolValidater(var); } for (auto& var : uniformVector) { symbolValidater(var); }
for (auto& var : uniformVector) { uniformResolve(var); } for (auto& var : uniformVector) { uniformResolve(var); }

View file

@ -52,7 +52,7 @@ namespace glslang {
class TIntermediate; class TIntermediate;
struct TVarEntryInfo { struct TVarEntryInfo {
int id; long long id;
TIntermSymbol* symbol; TIntermSymbol* symbol;
bool live; bool live;
int newBinding; int newBinding;
@ -87,6 +87,35 @@ struct TVarEntryInfo {
return lPoints > rPoints; return lPoints > rPoints;
} }
}; };
struct TOrderByPriorityAndLive {
// ordering:
// 1) do live variables first
// 2) has both binding and set
// 3) has binding but no set
// 4) has no binding but set
// 5) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (l.live != r.live)
return l.live > r.live;
if (lPoints != rPoints)
return lPoints > rPoints;
return l.id < r.id;
}
};
}; };
// Base class for shared TIoMapResolver services, used by several derivations. // Base class for shared TIoMapResolver services, used by several derivations.
@ -107,8 +136,8 @@ public:
void endCollect(EShLanguage) override {} void endCollect(EShLanguage) override {}
void reserverResourceSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {} void reserverResourceSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {}
void reserverStorageSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {} void reserverStorageSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {}
int getBaseBinding(TResourceType res, unsigned int set) const; int getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const;
const std::vector<std::string>& getResourceSetBinding() const; const std::vector<std::string>& getResourceSetBinding(EShLanguage stage) const;
virtual TResourceType getResourceType(const glslang::TType& type) = 0; virtual TResourceType getResourceType(const glslang::TType& type) = 0;
bool doAutoBindingMapping() const; bool doAutoBindingMapping() const;
bool doAutoLocationMapping() const; bool doAutoLocationMapping() const;
@ -122,9 +151,11 @@ public:
int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override; int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override;
int resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) override; int resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
int resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) override; int resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
void addStage(EShLanguage stage) override { void addStage(EShLanguage stage, TIntermediate& stageIntermediate) override {
if (stage < EShLangCount) if (stage < EShLangCount) {
stageMask[stage] = true; stageMask[stage] = true;
stageIntermediates[stage] = &stageIntermediate;
}
} }
uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage); uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage);
@ -139,6 +170,8 @@ protected:
int nextInputLocation; int nextInputLocation;
int nextOutputLocation; int nextOutputLocation;
bool stageMask[EShLangCount + 1]; bool stageMask[EShLangCount + 1];
const TIntermediate* stageIntermediates[EShLangCount];
// Return descriptor set specific base if there is one, and the generic base otherwise. // Return descriptor set specific base if there is one, and the generic base otherwise.
int selectBaseBinding(int base, int descriptorSetBase) const { int selectBaseBinding(int base, int descriptorSetBase) const {
return descriptorSetBase != -1 ? descriptorSetBase : base; return descriptorSetBase != -1 ? descriptorSetBase : base;

View file

@ -63,14 +63,14 @@ namespace glslang {
class TInductiveTraverser : public TIntermTraverser { class TInductiveTraverser : public TIntermTraverser {
public: public:
TInductiveTraverser(int id, TSymbolTable& st) TInductiveTraverser(long long id, TSymbolTable& st)
: loopId(id), symbolTable(st), bad(false) { } : loopId(id), symbolTable(st), bad(false) { }
virtual bool visitBinary(TVisit, TIntermBinary* node); virtual bool visitBinary(TVisit, TIntermBinary* node);
virtual bool visitUnary(TVisit, TIntermUnary* node); virtual bool visitUnary(TVisit, TIntermUnary* node);
virtual bool visitAggregate(TVisit, TIntermAggregate* node); virtual bool visitAggregate(TVisit, TIntermAggregate* node);
int loopId; // unique ID of the symbol that's the loop inductive variable long long loopId; // unique ID of the symbol that's the loop inductive variable
TSymbolTable& symbolTable; TSymbolTable& symbolTable;
bool bad; bool bad;
TSourceLoc badLoc; TSourceLoc badLoc;
@ -129,7 +129,7 @@ bool TInductiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* n
// //
// External function to call for loop check. // External function to call for loop check.
// //
void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbolTable& symbolTable) void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, long long loopId, TSymbolTable& symbolTable)
{ {
TInductiveTraverser it(loopId, symbolTable); TInductiveTraverser it(loopId, symbolTable);

View file

@ -48,6 +48,7 @@
#include "localintermediate.h" #include "localintermediate.h"
#include "../Include/InfoSink.h" #include "../Include/InfoSink.h"
#include "SymbolTable.h"
namespace glslang { namespace glslang {
@ -89,6 +90,56 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
#endif #endif
} }
//
// check that link objects between stages
//
void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit) {
if (unit.treeRoot == nullptr || treeRoot == nullptr)
return;
// Get the linker-object lists
TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
TIntermSequence unitLinkerObjects = unit.findLinkerObjects()->getSequence();
// filter unitLinkerObjects to only contain uniforms
auto end = std::remove_if(unitLinkerObjects.begin(), unitLinkerObjects.end(),
[](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqUniform &&
node->getAsSymbolNode()->getQualifier().storage != EvqBuffer; });
unitLinkerObjects.resize(end - unitLinkerObjects.begin());
// merge uniforms and do error checking
bool mergeExistingOnly = false;
mergeGlobalUniformBlocks(infoSink, unit, mergeExistingOnly);
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
}
//
// do error checking on the shader boundary in / out vars
//
void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) {
if (unit.treeRoot == nullptr || treeRoot == nullptr)
return;
// Get copies of the linker-object lists
TIntermSequence linkerObjects = findLinkerObjects()->getSequence();
TIntermSequence unitLinkerObjects = unit.findLinkerObjects()->getSequence();
// filter linkerObjects to only contain out variables
auto end = std::remove_if(linkerObjects.begin(), linkerObjects.end(),
[](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqVaryingOut; });
linkerObjects.resize(end - linkerObjects.begin());
// filter unitLinkerObjects to only contain in variables
auto unitEnd = std::remove_if(unitLinkerObjects.begin(), unitLinkerObjects.end(),
[](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqVaryingIn; });
unitLinkerObjects.resize(unitEnd - unitLinkerObjects.begin());
// do matching and error checking
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
// TODO: final check; make sure that any statically used `in` have matching `out` written to
}
void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
{ {
if (unit.getNumEntryPoints() > 0) { if (unit.getNumEntryPoints() > 0) {
@ -136,6 +187,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
MERGE_MAX(spvVersion.vulkanGlsl); MERGE_MAX(spvVersion.vulkanGlsl);
MERGE_MAX(spvVersion.vulkan); MERGE_MAX(spvVersion.vulkan);
MERGE_MAX(spvVersion.openGl); MERGE_MAX(spvVersion.openGl);
MERGE_TRUE(spvVersion.vulkanRelaxed);
numErrors += unit.getNumErrors(); numErrors += unit.getNumErrors();
// Only one push_constant is allowed, mergeLinkerObjects() will ensure the push_constant // Only one push_constant is allowed, mergeLinkerObjects() will ensure the push_constant
@ -264,6 +316,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
MERGE_TRUE(useUnknownFormat); MERGE_TRUE(useUnknownFormat);
MERGE_TRUE(hlslOffsets); MERGE_TRUE(hlslOffsets);
MERGE_TRUE(useStorageBuffer); MERGE_TRUE(useStorageBuffer);
MERGE_TRUE(invariantAll);
MERGE_TRUE(hlslIoMapping); MERGE_TRUE(hlslIoMapping);
// TODO: sourceFile // TODO: sourceFile
@ -306,12 +359,14 @@ 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.
TIdMaps idMaps; TIdMaps idMaps;
int maxId; long long idShift;
seedIdMap(idMaps, maxId); seedIdMap(idMaps, idShift);
remapIds(idMaps, maxId + 1, unit); remapIds(idMaps, idShift + 1, unit);
mergeBodies(infoSink, globals, unitGlobals); mergeBodies(infoSink, globals, unitGlobals);
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects); bool mergeExistingOnly = false;
mergeGlobalUniformBlocks(infoSink, unit, mergeExistingOnly);
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end()); ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
} }
@ -329,14 +384,14 @@ static const TString& getNameForIdMap(TIntermSymbol* symbol)
// 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, currently using (maximum ID + 1) as new symbol id shift seed.
// Level id will keep same after shifting.
// (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(TIdMaps& idMaps) : idMaps(idMaps), maxId(0) { } TBuiltInIdTraverser(TIdMaps& idMaps) : idMaps(idMaps), idShift(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.
virtual void visitSymbol(TIntermSymbol* symbol) virtual void visitSymbol(TIntermSymbol* symbol)
{ {
const TQualifier& qualifier = symbol->getType().getQualifier(); const TQualifier& qualifier = symbol->getType().getQualifier();
@ -344,14 +399,16 @@ public:
TShaderInterface si = symbol->getType().getShaderInterface(); TShaderInterface si = symbol->getType().getShaderInterface();
idMaps[si][getNameForIdMap(symbol)] = symbol->getId(); idMaps[si][getNameForIdMap(symbol)] = symbol->getId();
} }
maxId = std::max(maxId, symbol->getId()); idShift = (symbol->getId() & ~TSymbolTable::uniqueIdMask) |
std::max(idShift & TSymbolTable::uniqueIdMask,
symbol->getId() & TSymbolTable::uniqueIdMask);
} }
int getMaxId() const { return maxId; } long long getIdShift() const { return idShift; }
protected: protected:
TBuiltInIdTraverser(TBuiltInIdTraverser&); TBuiltInIdTraverser(TBuiltInIdTraverser&);
TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&); TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&);
TIdMaps& idMaps; TIdMaps& idMaps;
int maxId; long long idShift;
}; };
// Traverser that seeds an ID map with non-builtins. // Traverser that seeds an ID map with non-builtins.
@ -377,12 +434,12 @@ protected:
}; };
// 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(TIdMaps& idMaps, int& maxId) void TIntermediate::seedIdMap(TIdMaps& idMaps, long long& idShift)
{ {
// 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(idMaps); TBuiltInIdTraverser builtInIdTraverser(idMaps);
treeRoot->traverse(&builtInIdTraverser); treeRoot->traverse(&builtInIdTraverser);
maxId = builtInIdTraverser.getMaxId(); idShift = builtInIdTraverser.getIdShift() & TSymbolTable::uniqueIdMask;
// 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(idMaps); TUserIdTraverser userIdTraverser(idMaps);
@ -394,7 +451,7 @@ void TIntermediate::seedIdMap(TIdMaps& idMaps, 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 TIdMaps& idMaps, int idShift) : idMaps(idMaps), idShift(idShift) { } TRemapIdTraverser(const TIdMaps& idMaps, long long 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
@ -406,7 +463,9 @@ public:
TShaderInterface si = symbol->getType().getShaderInterface(); TShaderInterface si = symbol->getType().getShaderInterface();
auto it = idMaps[si].find(getNameForIdMap(symbol)); auto it = idMaps[si].find(getNameForIdMap(symbol));
if (it != idMaps[si].end()) { if (it != idMaps[si].end()) {
symbol->changeId(it->second); uint64_t id = (symbol->getId() & ~TSymbolTable::uniqueIdMask) |
(it->second & TSymbolTable::uniqueIdMask);
symbol->changeId(id);
remapped = true; remapped = true;
} }
} }
@ -417,10 +476,10 @@ protected:
TRemapIdTraverser(TRemapIdTraverser&); TRemapIdTraverser(TRemapIdTraverser&);
TRemapIdTraverser& operator=(TRemapIdTraverser&); TRemapIdTraverser& operator=(TRemapIdTraverser&);
const TIdMaps& idMaps; const TIdMaps& idMaps;
int idShift; long long idShift;
}; };
void TIntermediate::remapIds(const TIdMaps& idMaps, int idShift, TIntermediate& unit) void TIntermediate::remapIds(const TIdMaps& idMaps, long long 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(idMaps, idShift); TRemapIdTraverser idTraverser(idMaps, idShift);
@ -451,11 +510,193 @@ void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, c
globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1); globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1);
} }
static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) {
return // 1) same stage and same shader interface
(stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) ||
// 2) accross stages and both are uniform or buffer
(symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) ||
(symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) ||
// 3) in/out matched across stage boundary
(stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) ||
(unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut);
}
//
// Global Unfiform block stores any default uniforms (i.e. uniforms without a block)
// If two linked stages declare the same member, they are meant to be the same uniform
// and need to be in the same block
// merge the members of different stages to allow them to be linked properly
// as a single block
//
void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly)
{
TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
TIntermSequence& unitLinkerObjects = unit.findLinkerObjects()->getSequence();
// build lists of default blocks from the intermediates
TIntermSequence defaultBlocks;
TIntermSequence unitDefaultBlocks;
auto filter = [](TIntermSequence& list, TIntermNode* node) {
if (node->getAsSymbolNode()->getQualifier().defaultBlock) {
list.push_back(node);
}
};
std::for_each(linkerObjects.begin(), linkerObjects.end(),
[&defaultBlocks, &filter](TIntermNode* node) {
filter(defaultBlocks, node);
});
std::for_each(unitLinkerObjects.begin(), unitLinkerObjects.end(),
[&unitDefaultBlocks, &filter](TIntermNode* node) {
filter(unitDefaultBlocks, node);
});
auto itUnitBlock = unitDefaultBlocks.begin();
for (; itUnitBlock != unitDefaultBlocks.end(); itUnitBlock++) {
bool add = !mergeExistingOnly;
auto itBlock = defaultBlocks.begin();
for (; itBlock != defaultBlocks.end(); itBlock++) {
TIntermSymbol* block = (*itBlock)->getAsSymbolNode();
TIntermSymbol* unitBlock = (*itUnitBlock)->getAsSymbolNode();
assert(block && unitBlock);
// if the two default blocks match, then merge their definitions
if (block->getType().getTypeName() == unitBlock->getType().getTypeName() &&
block->getQualifier().storage == unitBlock->getQualifier().storage) {
add = false;
mergeBlockDefinitions(infoSink, block, unitBlock, &unit);
}
}
if (add) {
// push back on original list; won't change the size of the list we're iterating over
linkerObjects.push_back(*itUnitBlock);
}
}
}
void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unit) {
if (block->getType() == unitBlock->getType()) {
return;
}
if (block->getType().getTypeName() != unitBlock->getType().getTypeName() ||
block->getType().getBasicType() != unitBlock->getType().getBasicType() ||
block->getQualifier().storage != unitBlock->getQualifier().storage ||
block->getQualifier().layoutSet != unitBlock->getQualifier().layoutSet) {
// different block names likely means different blocks
return;
}
// merge the struct
// order of declarations doesn't matter and they matched based on member name
TTypeList* memberList = block->getType().getWritableStruct();
TTypeList* unitMemberList = unitBlock->getType().getWritableStruct();
// keep track of which members have changed position
// so we don't have to search the array again
std::map<unsigned int, unsigned int> memberIndexUpdates;
size_t memberListStartSize = memberList->size();
for (unsigned int i = 0; i < unitMemberList->size(); ++i) {
bool merge = true;
for (unsigned int j = 0; j < memberListStartSize; ++j) {
if ((*memberList)[j].type->getFieldName() == (*unitMemberList)[i].type->getFieldName()) {
merge = false;
const TType* memberType = (*memberList)[j].type;
const TType* unitMemberType = (*unitMemberList)[i].type;
// compare types
// don't need as many checks as when merging symbols, since
// initializers and most qualifiers are stripped when the member is moved into the block
if ((*memberType) != (*unitMemberType)) {
error(infoSink, "Types must match:");
infoSink.info << " " << memberType->getFieldName() << ": ";
infoSink.info << "\"" << memberType->getCompleteString() << "\" versus ";
infoSink.info << "\"" << unitMemberType->getCompleteString() << "\"\n";
}
memberIndexUpdates[i] = j;
}
}
if (merge) {
memberList->push_back((*unitMemberList)[i]);
memberIndexUpdates[i] = (unsigned int)memberList->size() - 1;
}
}
TType unitType;
unitType.shallowCopy(unitBlock->getType());
// update symbol node in unit tree,
// and other nodes that may reference it
class TMergeBlockTraverser : public TIntermTraverser {
public:
TMergeBlockTraverser(const glslang::TType &type, const glslang::TType& unitType,
glslang::TIntermediate& unit,
const std::map<unsigned int, unsigned int>& memberIdxUpdates) :
newType(type), unitType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates)
{ }
virtual ~TMergeBlockTraverser() { }
const glslang::TType& newType; // type with modifications
const glslang::TType& unitType; // copy of original type
glslang::TIntermediate& unit; // intermediate that is being updated
const std::map<unsigned int, unsigned int>& memberIndexUpdates;
virtual void visitSymbol(TIntermSymbol* symbol)
{
glslang::TType& symType = symbol->getWritableType();
if (symType == unitType) {
// each symbol node has a local copy of the unitType
// if merging involves changing properties that aren't shared objects
// they should be updated in all instances
// e.g. the struct list is a ptr to an object, so it can be updated
// once, outside the traverser
//*symType.getWritableStruct() = *newType.getStruct();
}
}
virtual bool visitBinary(TVisit, glslang::TIntermBinary* node)
{
if (node->getOp() == EOpIndexDirectStruct && node->getLeft()->getType() == unitType) {
// this is a dereference to a member of the block since the
// member list changed, need to update this to point to the
// right index
assert(node->getRight()->getAsConstantUnion());
glslang::TIntermConstantUnion* constNode = node->getRight()->getAsConstantUnion();
unsigned int memberIdx = constNode->getConstArray()[0].getUConst();
unsigned int newIdx = memberIndexUpdates.at(memberIdx);
TIntermTyped* newConstNode = unit.addConstantUnion(newIdx, node->getRight()->getLoc());
node->setRight(newConstNode);
delete constNode;
return true;
}
return true;
}
} finalLinkTraverser(block->getType(), unitType, *unit, memberIndexUpdates);
// update the tree to use the new type
unit->getTreeRoot()->traverse(&finalLinkTraverser);
// update the member list
(*unitMemberList) = (*memberList);
}
// //
// Merge the linker objects from unitLinkerObjects into linkerObjects. // Merge the linker objects from unitLinkerObjects into linkerObjects.
// Duplication is expected and filtered out, but contradictions are an error. // Duplication is expected and filtered out, but contradictions are an error.
// //
void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects) void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects, EShLanguage unitStage)
{ {
// Error check and merge the linker objects (duplicates should not be created) // Error check and merge the linker objects (duplicates should not be created)
std::size_t initialNumLinkerObjects = linkerObjects.size(); std::size_t initialNumLinkerObjects = linkerObjects.size();
@ -470,7 +711,7 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
// If they are both blocks in the same shader interface, // If they are both blocks in the same shader interface,
// match by the block-name, not the identifier name. // match by the block-name, not the identifier name.
if (symbol->getType().getBasicType() == EbtBlock && unitSymbol->getType().getBasicType() == EbtBlock) { if (symbol->getType().getBasicType() == EbtBlock && unitSymbol->getType().getBasicType() == EbtBlock) {
if (symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) { if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) {
isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName(); isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName();
} }
} }
@ -490,18 +731,54 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
if (! symbol->getQualifier().hasBinding() && unitSymbol->getQualifier().hasBinding()) if (! symbol->getQualifier().hasBinding() && unitSymbol->getQualifier().hasBinding())
symbol->getQualifier().layoutBinding = unitSymbol->getQualifier().layoutBinding; symbol->getQualifier().layoutBinding = unitSymbol->getQualifier().layoutBinding;
// Similarly for location
if (!symbol->getQualifier().hasLocation() && unitSymbol->getQualifier().hasLocation()) {
symbol->getQualifier().layoutLocation = unitSymbol->getQualifier().layoutLocation;
}
// Update implicit array sizes // Update implicit array sizes
mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType()); mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType());
// Check for consistent types/qualification/initializers etc. // Check for consistent types/qualification/initializers etc.
mergeErrorCheck(infoSink, *symbol, *unitSymbol, false); mergeErrorCheck(infoSink, *symbol, *unitSymbol, unitStage);
} }
// If different symbols, verify they arn't push_constant since there can only be one per stage // 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()) else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant() && getStage() == unitStage)
error(infoSink, "Only one push_constant block is allowed per stage"); 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]);
// for anonymous blocks, check that their members don't conflict with other names
if (unitLinkerObjects[unitLinkObj]->getAsSymbolNode()->getBasicType() == EbtBlock &&
IsAnonymous(unitLinkerObjects[unitLinkObj]->getAsSymbolNode()->getName())) {
for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) {
TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
assert(symbol && unitSymbol);
auto checkName = [this, unitSymbol, &infoSink](const TString& name) {
for (unsigned int i = 0; i < unitSymbol->getType().getStruct()->size(); ++i) {
if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()) {
error(infoSink, "Anonymous member name used for global variable or other anonymous member: ");
infoSink.info << (*unitSymbol->getType().getStruct())[i].type->getCompleteString() << "\n";
}
}
};
if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) {
checkName(symbol->getName());
// check members of other anonymous blocks
if (symbol->getBasicType() == EbtBlock && IsAnonymous(symbol->getName())) {
for (unsigned int i = 0; i < symbol->getType().getStruct()->size(); ++i) {
checkName((*symbol->getType().getStruct())[i].type->getFieldName());
}
}
}
}
}
}
} }
} }
@ -533,26 +810,75 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
// //
// This function only does one of intra- or cross-stage matching per call. // This function only does one of intra- or cross-stage matching per call.
// //
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage) void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, EShLanguage unitStage)
{ {
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
bool crossStage = getStage() != unitStage;
bool writeTypeComparison = false; bool writeTypeComparison = false;
// Types have to match // Types have to match
if (symbol.getType() != unitSymbol.getType()) { {
// but, we make an exception if one is an implicit array and the other is sized // but, we make an exception if one is an implicit array and the other is sized
if (! (symbol.getType().isArray() && unitSymbol.getType().isArray() && // or if the array sizes differ because of the extra array dimension on some in/out boundaries
symbol.getType().sameElementType(unitSymbol.getType()) && bool arraysMatch = false;
(symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()))) { if (isIoResizeArray(symbol.getType(), getStage()) || isIoResizeArray(unitSymbol.getType(), unitStage)) {
error(infoSink, "Types must match:"); // if the arrays have an extra dimension because of the stage.
// compare dimensions while ignoring the outer dimension
unsigned int firstDim = isIoResizeArray(symbol.getType(), getStage()) ? 1 : 0;
unsigned int numDim = symbol.getArraySizes()
? symbol.getArraySizes()->getNumDims() : 0;
unsigned int unitFirstDim = isIoResizeArray(unitSymbol.getType(), unitStage) ? 1 : 0;
unsigned int unitNumDim = unitSymbol.getArraySizes()
? unitSymbol.getArraySizes()->getNumDims() : 0;
arraysMatch = (numDim - firstDim) == (unitNumDim - unitFirstDim);
// check that array sizes match as well
for (unsigned int i = 0; i < (numDim - firstDim) && arraysMatch; i++) {
if (symbol.getArraySizes()->getDimSize(firstDim + i) !=
unitSymbol.getArraySizes()->getDimSize(unitFirstDim + i)) {
arraysMatch = false;
break;
}
}
}
else {
arraysMatch = symbol.getType().sameArrayness(unitSymbol.getType()) ||
(symbol.getType().isArray() && unitSymbol.getType().isArray() &&
(symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()));
}
if (!symbol.getType().sameElementType(unitSymbol.getType()) ||
!symbol.getType().sameTypeParameters(unitSymbol.getType()) ||
!arraysMatch ) {
writeTypeComparison = true; writeTypeComparison = true;
error(infoSink, "Types must match:");
} }
} }
// Qualifiers have to (almost) match // Interface block member-wise layout qualifiers have to match
if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock &&
symbol.getType().getStruct() && unitSymbol.getType().getStruct() &&
symbol.getType().sameStructType(unitSymbol.getType())) {
for (unsigned int i = 0; i < symbol.getType().getStruct()->size(); ++i) {
const TQualifier& qualifier = (*symbol.getType().getStruct())[i].type->getQualifier();
const TQualifier& unitQualifier = (*unitSymbol.getType().getStruct())[i].type->getQualifier();
if (qualifier.layoutMatrix != unitQualifier.layoutMatrix ||
qualifier.layoutOffset != unitQualifier.layoutOffset ||
qualifier.layoutAlign != unitQualifier.layoutAlign ||
qualifier.layoutLocation != unitQualifier.layoutLocation ||
qualifier.layoutComponent != unitQualifier.layoutComponent) {
error(infoSink, "Interface block member layout qualifiers must match:");
writeTypeComparison = true;
}
}
}
bool isInOut = crossStage &&
((symbol.getQualifier().storage == EvqVaryingIn && unitSymbol.getQualifier().storage == EvqVaryingOut) ||
(symbol.getQualifier().storage == EvqVaryingOut && unitSymbol.getQualifier().storage == EvqVaryingIn));
// Qualifiers have to (almost) match
// Storage... // Storage...
if (symbol.getQualifier().storage != unitSymbol.getQualifier().storage) { if (!isInOut && symbol.getQualifier().storage != unitSymbol.getQualifier().storage) {
error(infoSink, "Storage qualifiers must match:"); error(infoSink, "Storage qualifiers must match:");
writeTypeComparison = true; writeTypeComparison = true;
} }
@ -574,7 +900,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
} }
// Precision... // Precision...
if (symbol.getQualifier().precision != unitSymbol.getQualifier().precision) { if (!isInOut && symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
error(infoSink, "Precision qualifiers must match:"); error(infoSink, "Precision qualifiers must match:");
writeTypeComparison = true; writeTypeComparison = true;
} }
@ -592,12 +918,16 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
} }
// Auxiliary and interpolation... // Auxiliary and interpolation...
if (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid || // "interpolation qualification (e.g., flat) and auxiliary qualification (e.g. centroid) may differ.
// These mismatches are allowed between any pair of stages ...
// those provided in the fragment shader supersede those provided in previous stages."
if (!crossStage &&
(symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid ||
symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth || symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth ||
symbol.getQualifier().flat != unitSymbol.getQualifier().flat || symbol.getQualifier().flat != unitSymbol.getQualifier().flat ||
symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() || symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() ||
symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() || symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() ||
symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective()) { symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective())) {
error(infoSink, "Interpolation and auxiliary storage qualifiers must match:"); error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
writeTypeComparison = true; writeTypeComparison = true;
} }
@ -653,6 +983,25 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
#endif #endif
} }
void TIntermediate::sharedBlockCheck(TInfoSink& infoSink)
{
bool has_shared_block = false;
bool has_shared_non_block = false;
TIntermSequence& linkObjects = findLinkerObjects()->getSequence();
for (size_t i = 0; i < linkObjects.size(); ++i) {
const TType& type = linkObjects[i]->getAsTyped()->getType();
const TQualifier& qualifier = type.getQualifier();
if (qualifier.storage == glslang::EvqShared) {
if (type.getBasicType() == glslang::EbtBlock)
has_shared_block = true;
else
has_shared_non_block = true;
}
}
if (has_shared_block && has_shared_non_block)
error(infoSink, "cannot mix use of shared variables inside and outside blocks");
}
// //
// Do final link-time error checking of a complete (merged) intermediate representation. // Do final link-time error checking of a complete (merged) intermediate representation.
// (Much error checking was done during merging). // (Much error checking was done during merging).
@ -778,6 +1127,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
error(infoSink, "post_depth_coverage requires early_fragment_tests"); error(infoSink, "post_depth_coverage requires early_fragment_tests");
break; break;
case EShLangCompute: case EShLangCompute:
sharedBlockCheck(infoSink);
break; break;
case EShLangRayGen: case EShLangRayGen:
case EShLangIntersect: case EShLangIntersect:
@ -810,6 +1160,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
case EShLangTaskNV: case EShLangTaskNV:
if (numTaskNVBlocks > 1) if (numTaskNVBlocks > 1)
error(infoSink, "Only one taskNV interface block is allowed per shader"); error(infoSink, "Only one taskNV interface block is allowed per shader");
sharedBlockCheck(infoSink);
break; break;
default: default:
error(infoSink, "Unknown Stage."); error(infoSink, "Unknown Stage.");
@ -1804,4 +2155,17 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
return size; return size;
} }
#ifndef GLSLANG_WEB
bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
return type.isArray() &&
((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) ||
(language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
! type.getQualifier().patch) ||
(language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
type.getQualifier().pervertexNV) ||
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
!type.getQualifier().perTaskNV));
}
#endif // not GLSLANG_WEB
} // end namespace glslang } // end namespace glslang

View file

@ -227,10 +227,10 @@ enum ComputeDerivativeMode {
class TIdMaps { class TIdMaps {
public: public:
TMap<TString, int>& operator[](int i) { return maps[i]; } TMap<TString, long long>& operator[](long long i) { return maps[i]; }
const TMap<TString, int>& operator[](int i) const { return maps[i]; } const TMap<TString, long long>& operator[](long long i) const { return maps[i]; }
private: private:
TMap<TString, int> maps[EsiCount]; TMap<TString, long long> maps[EsiCount];
}; };
class TNumericFeatures { class TNumericFeatures {
@ -291,8 +291,15 @@ public:
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false), numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
invertY(false), invertY(false),
useStorageBuffer(false), useStorageBuffer(false),
invariantAll(false),
nanMinMaxClamp(false), nanMinMaxClamp(false),
depthReplacing(false) depthReplacing(false),
uniqueId(0),
globalUniformBlockName(""),
atomicCounterBlockName(""),
globalUniformBlockSet(TQualifier::layoutSetEnd),
globalUniformBlockBinding(TQualifier::layoutBindingEnd),
atomicCounterBlockSet(TQualifier::layoutSetEnd)
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
, ,
implicitThisName("@this"), implicitCounterName("@count"), implicitThisName("@this"), implicitCounterName("@count"),
@ -322,7 +329,10 @@ public:
textureSamplerTransformMode(EShTexSampTransKeep), textureSamplerTransformMode(EShTexSampTransKeep),
needToLegalize(false), needToLegalize(false),
binaryDoubleOutput(false), binaryDoubleOutput(false),
subgroupUniformControlFlow(false),
usePhysicalStorageBuffer(false), usePhysicalStorageBuffer(false),
spirvRequirement(nullptr),
spirvExecutionMode(nullptr),
uniformLocationBase(0) uniformLocationBase(0)
#endif #endif
{ {
@ -529,15 +539,30 @@ public:
TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&); TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
// Tree ops // Tree ops
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay); static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false);
// Linkage related // Linkage related
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&); void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
TIntermAggregate* findLinkerObjects() const; TIntermAggregate* findLinkerObjects() const;
void setGlobalUniformBlockName(const char* name) { globalUniformBlockName = std::string(name); }
const char* getGlobalUniformBlockName() const { return globalUniformBlockName.c_str(); }
void setGlobalUniformSet(unsigned int set) { globalUniformBlockSet = set; }
unsigned int getGlobalUniformSet() const { return globalUniformBlockSet; }
void setGlobalUniformBinding(unsigned int binding) { globalUniformBlockBinding = binding; }
unsigned int getGlobalUniformBinding() const { return globalUniformBlockBinding; }
void setAtomicCounterBlockName(const char* name) { atomicCounterBlockName = std::string(name); }
const char* getAtomicCounterBlockName() const { return atomicCounterBlockName.c_str(); }
void setAtomicCounterBlockSet(unsigned int set) { atomicCounterBlockSet = set; }
unsigned int getAtomicCounterBlockSet() const { return atomicCounterBlockSet; }
void setUseStorageBuffer() { useStorageBuffer = true; } void setUseStorageBuffer() { useStorageBuffer = true; }
bool usingStorageBuffer() const { return useStorageBuffer; } bool usingStorageBuffer() const { return useStorageBuffer; }
void setInvariantAll() { invariantAll = true; }
bool isInvariantAll() const { return invariantAll; }
void setDepthReplacing() { depthReplacing = true; } void setDepthReplacing() { depthReplacing = true; }
bool isDepthReplacing() const { return depthReplacing; } bool isDepthReplacing() const { return depthReplacing; }
bool setLocalSize(int dim, int size) bool setLocalSize(int dim, int size)
@ -549,6 +574,11 @@ public:
return true; return true;
} }
unsigned int getLocalSize(int dim) const { return localSize[dim]; } unsigned int getLocalSize(int dim) const { return localSize[dim]; }
bool isLocalSizeSet() const
{
// Return true if any component has been set (i.e. any component is not default).
return localSizeNotDefault[0] || localSizeNotDefault[1] || localSizeNotDefault[2];
}
bool setLocalSizeSpecId(int dim, int id) bool setLocalSizeSpecId(int dim, int id)
{ {
if (localSizeSpecId[dim] != TQualifier::layoutNotSet) if (localSizeSpecId[dim] != TQualifier::layoutNotSet)
@ -557,6 +587,13 @@ public:
return true; return true;
} }
int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; } int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; }
bool isLocalSizeSpecialized() const
{
// Return true if any component has been specialized.
return localSizeSpecId[0] != TQualifier::layoutNotSet ||
localSizeSpecId[1] != TQualifier::layoutNotSet ||
localSizeSpecId[2] != TQualifier::layoutNotSet;
}
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
void output(TInfoSink&, bool tree) { } void output(TInfoSink&, bool tree) { }
@ -833,8 +870,34 @@ public:
void setBinaryDoubleOutput() { binaryDoubleOutput = true; } void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
bool getBinaryDoubleOutput() { return binaryDoubleOutput; } bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
void setSubgroupUniformControlFlow() { subgroupUniformControlFlow = true; }
bool getSubgroupUniformControlFlow() const { return subgroupUniformControlFlow; }
// GL_EXT_spirv_intrinsics
void insertSpirvRequirement(const TSpirvRequirement* spirvReq);
bool hasSpirvRequirement() const { return spirvRequirement != nullptr; }
const TSpirvRequirement& getSpirvRequirement() const { return *spirvRequirement; }
void insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args = nullptr);
void insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args);
bool hasSpirvExecutionMode() const { return spirvExecutionMode != nullptr; }
const TSpirvExecutionMode& getSpirvExecutionMode() const { return *spirvExecutionMode; }
#endif // GLSLANG_WEB #endif // GLSLANG_WEB
void addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing)
{
std::string name(nameStr);
blockBackingOverrides[name] = backing;
}
TBlockStorageClass getBlockStorageOverride(const char* nameStr) const
{
std::string name = nameStr;
auto pos = blockBackingOverrides.find(name);
if (pos == blockBackingOverrides.end())
return EbsNone;
else
return pos->second;
}
#ifdef ENABLE_HLSL #ifdef ENABLE_HLSL
void setHlslFunctionality1() { hlslFunctionality1 = true; } void setHlslFunctionality1() { hlslFunctionality1 = true; }
bool getHlslFunctionality1() const { return hlslFunctionality1; } bool getHlslFunctionality1() const { return hlslFunctionality1; }
@ -858,10 +921,27 @@ public:
bool usingHlslIoMapping() { return false; } bool usingHlslIoMapping() { return false; }
#endif #endif
bool usingScalarBlockLayout() const {
for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt) {
if (*extIt == E_GL_EXT_scalar_block_layout)
return true;
}
return false;
}
bool IsRequestedExtension(const char* extension) const
{
return (requestedExtensions.find(extension) != requestedExtensions.end());
}
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee); void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
void merge(TInfoSink&, TIntermediate&); void merge(TInfoSink&, TIntermediate&);
void finalCheck(TInfoSink&, bool keepUncalled); void finalCheck(TInfoSink&, bool keepUncalled);
void mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly);
void mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit);
void checkStageIO(TInfoSink&, TIntermediate&);
bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const; bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const;
TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const; TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
@ -885,6 +965,8 @@ public:
static int getOffset(const TType& type, int index); static int getOffset(const TType& type, int index);
static int getBlockSize(const TType& blockType); static int getBlockSize(const TType& blockType);
static int computeBufferReferenceTypeSize(const TType&); static int computeBufferReferenceTypeSize(const TType&);
static bool isIoResizeArray(const TType& type, EShLanguage language);
bool promote(TIntermOperator*); bool promote(TIntermOperator*);
void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; } void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; }
bool getNanMinMaxClamp() const { return nanMinMaxClamp; } bool getNanMinMaxClamp() const { return nanMinMaxClamp; }
@ -903,6 +985,8 @@ public:
void addProcess(const std::string& process) { processes.addProcess(process); } void addProcess(const std::string& process) { processes.addProcess(process); }
void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); } const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
unsigned long long getUniqueId() const { return uniqueId; }
void setUniqueId(unsigned long long id) { uniqueId = id; }
// Certain explicit conversions are allowed conditionally // Certain explicit conversions are allowed conditionally
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
@ -931,21 +1015,23 @@ public:
#endif #endif
protected: protected:
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&); TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
void error(TInfoSink& infoSink, const char*); void error(TInfoSink& infoSink, const char*);
void warn(TInfoSink& infoSink, const char*); void warn(TInfoSink& infoSink, const char*);
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(TIdMaps& idMaps, int& maxId); void seedIdMap(TIdMaps& idMaps, long long& IdShift);
void remapIds(const TIdMaps& idMaps, int idShift, TIntermediate&); void remapIds(const TIdMaps& idMaps, long long 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, EShLanguage);
void mergeBlockDefinitions(TInfoSink&, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unitRoot);
void mergeImplicitArraySizes(TType&, const TType&); void mergeImplicitArraySizes(TType&, const TType&);
void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, bool crossStage); void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, EShLanguage);
void checkCallGraphCycles(TInfoSink&); void checkCallGraphCycles(TInfoSink&);
void checkCallGraphBodies(TInfoSink&, bool keepUncalled); void checkCallGraphBodies(TInfoSink&, bool keepUncalled);
void inOutLocationCheck(TInfoSink&); void inOutLocationCheck(TInfoSink&);
void sharedBlockCheck(TInfoSink&);
bool userOutputUsed() const; bool userOutputUsed() const;
bool isSpecializationOperation(const TIntermOperator&) const; bool isSpecializationOperation(const TIntermOperator&) const;
bool isNonuniformPropagating(TOperator) const; bool isNonuniformPropagating(TOperator) const;
@ -985,11 +1071,20 @@ protected:
bool recursive; bool recursive;
bool invertY; bool invertY;
bool useStorageBuffer; bool useStorageBuffer;
bool invariantAll;
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
bool depthReplacing; bool depthReplacing;
int localSize[3]; int localSize[3];
bool localSizeNotDefault[3]; bool localSizeNotDefault[3];
int localSizeSpecId[3]; int localSizeSpecId[3];
unsigned long long uniqueId;
std::string globalUniformBlockName;
std::string atomicCounterBlockName;
unsigned int globalUniformBlockSet;
unsigned int globalUniformBlockBinding;
unsigned int atomicCounterBlockSet;
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
public: public:
const char* const implicitThisName; const char* const implicitThisName;
@ -1044,12 +1139,17 @@ protected:
bool needToLegalize; bool needToLegalize;
bool binaryDoubleOutput; bool binaryDoubleOutput;
bool subgroupUniformControlFlow;
bool usePhysicalStorageBuffer; bool usePhysicalStorageBuffer;
TSpirvRequirement* spirvRequirement;
TSpirvExecutionMode* spirvExecutionMode;
std::unordered_map<std::string, int> uniformLocationOverrides; std::unordered_map<std::string, int> uniformLocationOverrides;
int uniformLocationBase; int uniformLocationBase;
TNumericFeatures numericFeatures; TNumericFeatures numericFeatures;
#endif #endif
std::unordered_map<std::string, TBlockStorageClass> blockBackingOverrides;
std::unordered_set<int> usedConstantId; // specialization constant ids used std::unordered_set<int> usedConstantId; // specialization constant ids used
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters

View file

@ -166,31 +166,30 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
} }
} else { } else {
// matrix from vector or scalar // matrix from vector or scalar
int count = 0;
const int startIndex = index;
int nodeComps = node->getType().computeNumComponents(); int nodeComps = node->getType().computeNumComponents();
for (int i = startIndex; i < endIndex; i++) { if (nodeComps == 1) {
if (i >= instanceSize) for (int c = 0; c < matrixCols; ++c) {
return; for (int r = 0; r < matrixRows; ++r) {
if (nodeComps == 1) { if (r == c)
// If there is a single scalar parameter to a matrix leftUnionArray[index] = rightUnionArray[0];
// constructor, it is used to initialize all the else
// components on the matrix's diagonal, with the leftUnionArray[index].setDConst(0.0);
// remaining components initialized to 0.0. index++;
if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 ) }
leftUnionArray[i] = rightUnionArray[count]; }
else } else {
leftUnionArray[i].setDConst(0.0); int count = 0;
} else { for (int i = index; i < endIndex; i++) {
if (i >= instanceSize)
return;
// construct the matrix in column-major order, from // construct the matrix in column-major order, from
// the components provided, in order // the components provided, in order
leftUnionArray[i] = rightUnionArray[count]; leftUnionArray[i] = rightUnionArray[count];
}
index++; index++;
if (nodeComps > 1)
count++; count++;
}
} }
} }
} }

View file

@ -1191,9 +1191,11 @@ int TPpContext::tokenize(TPpToken& ppToken)
// HLSL allows string literals. // HLSL allows string literals.
// GLSL allows string literals with GL_EXT_debug_printf. // GLSL allows string literals with GL_EXT_debug_printf.
if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) { if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) {
parseContext.requireExtensions(ppToken.loc, 1, &E_GL_EXT_debug_printf, "string literal"); const char* const string_literal_EXTs[] = { E_GL_EXT_debug_printf, E_GL_EXT_spirv_intrinsics };
if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf)) parseContext.requireExtensions(ppToken.loc, 2, string_literal_EXTs, "string literal");
continue; if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf) &&
!parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
continue;
} }
break; break;
case '\'': case '\'':

View file

@ -907,8 +907,8 @@ public:
case EbtFloat16: return GL_FLOAT16_VEC2_NV + offset; case EbtFloat16: return GL_FLOAT16_VEC2_NV + offset;
case EbtInt: return GL_INT_VEC2 + offset; case EbtInt: return GL_INT_VEC2 + offset;
case EbtUint: return GL_UNSIGNED_INT_VEC2 + offset; case EbtUint: return GL_UNSIGNED_INT_VEC2 + offset;
case EbtInt64: return GL_INT64_ARB + offset; case EbtInt64: return GL_INT64_VEC2_ARB + offset;
case EbtUint64: return GL_UNSIGNED_INT64_ARB + offset; case EbtUint64: return GL_UNSIGNED_INT64_VEC2_ARB + offset;
case EbtBool: return GL_BOOL_VEC2 + offset; case EbtBool: return GL_BOOL_VEC2 + offset;
case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset; case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset;
default: return 0; default: return 0;
@ -1138,6 +1138,8 @@ void TReflection::buildCounterIndices(const TIntermediate& intermediate)
if (index >= 0) if (index >= 0)
indexToUniformBlock[i].counterIndex = index; indexToUniformBlock[i].counterIndex = index;
} }
#else
(void)intermediate;
#endif #endif
} }

View file

@ -167,7 +167,7 @@ typedef enum {
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 EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2
EShTargetOpenGL_450 = 450, // OpenGL EShTargetOpenGL_450 = 450, // OpenGL
LAST_ELEMENT_MARKER(EShTargetClientVersionCount), LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 4),
} EShTargetClientVersion; } EShTargetClientVersion;
typedef EShTargetClientVersion EshTargetClientVersion; typedef EShTargetClientVersion EshTargetClientVersion;
@ -179,7 +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), LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 6),
} EShTargetLanguageVersion; } EShTargetLanguageVersion;
struct TInputLanguage { struct TInputLanguage {
@ -187,6 +187,7 @@ struct TInputLanguage {
EShLanguage stage; // redundant information with other input, this one overrides when not EShSourceNone EShLanguage stage; // redundant information with other input, this one overrides when not EShSourceNone
EShClient dialect; EShClient dialect;
int dialectVersion; // version of client's language definition, not the client (when not EShClientNone) int dialectVersion; // version of client's language definition, not the client (when not EShClientNone)
bool vulkanRulesRelaxed;
}; };
struct TClient { struct TClient {
@ -427,6 +428,14 @@ enum TResourceType {
EResCount EResCount
}; };
enum TBlockStorageClass
{
EbsUniform = 0,
EbsStorageBuffer,
EbsPushConstant,
EbsNone, // not a uniform or buffer variable
EbsCount,
};
// 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()
@ -458,6 +467,7 @@ public:
GLSLANG_EXPORT void setEntryPoint(const char* entryPoint); GLSLANG_EXPORT void setEntryPoint(const char* entryPoint);
GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName); GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&); GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
GLSLANG_EXPORT void setUniqueId(unsigned long long id);
// IO resolver binding data: see comments in ShaderLang.cpp // IO resolver binding data: see comments in ShaderLang.cpp
GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base); GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);
@ -482,6 +492,14 @@ public:
GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat); GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat);
GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp); GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp);
GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
GLSLANG_EXPORT void addBlockStorageOverride(const char* nameStr, glslang::TBlockStorageClass backing);
GLSLANG_EXPORT void setGlobalUniformBlockName(const char* name);
GLSLANG_EXPORT void setAtomicCounterBlockName(const char* name);
GLSLANG_EXPORT void setGlobalUniformSet(unsigned int set);
GLSLANG_EXPORT void setGlobalUniformBinding(unsigned int binding);
GLSLANG_EXPORT void setAtomicCounterBlockSet(unsigned int set);
GLSLANG_EXPORT void setAtomicCounterBlockBinding(unsigned int binding);
// 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
@ -490,7 +508,7 @@ public:
// //
// setEnvInput: The input source language and stage. If generating code for a // setEnvInput: The input source language and stage. If generating code for a
// specific client, the input client semantics to use and the // specific client, the input client semantics to use and the
// version of the that client's input semantics to use, otherwise // version of that client's input semantics to use, otherwise
// use EShClientNone and version of 0, e.g. for validation mode. // use EShClientNone and version of 0, e.g. for validation mode.
// Note 'version' does not describe the target environment, // Note 'version' does not describe the target environment,
// just the version of the source dialect to compile under. // just the version of the source dialect to compile under.
@ -538,6 +556,9 @@ public:
bool getEnvTargetHlslFunctionality1() const { return false; } bool getEnvTargetHlslFunctionality1() const { return false; }
#endif #endif
void setEnvInputVulkanRulesRelaxed() { environment.input.vulkanRulesRelaxed = true; }
bool getEnvInputVulkanRulesRelaxed() const { return environment.input.vulkanRulesRelaxed; }
// Interface to #include handlers. // Interface to #include handlers.
// //
// To support #include, a client of Glslang does the following: // To support #include, a client of Glslang does the following:
@ -701,7 +722,7 @@ class TObjectReflection {
public: public:
GLSLANG_EXPORT 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);
GLSLANG_EXPORT const TType* getType() const { return type; } const TType* getType() const { return type; }
GLSLANG_EXPORT int getBinding() const; GLSLANG_EXPORT int getBinding() const;
GLSLANG_EXPORT void dump() const; GLSLANG_EXPORT void dump() const;
static TObjectReflection badReflection() { return TObjectReflection(); } static TObjectReflection badReflection() { return TObjectReflection(); }
@ -805,7 +826,7 @@ public:
// Called by TSlotCollector to resolve resource locations or bindings // Called by TSlotCollector to resolve resource locations or bindings
virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0; virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0;
// Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline // Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline
virtual void addStage(EShLanguage stage) = 0; virtual void addStage(EShLanguage stage, TIntermediate& stageIntermediate) = 0;
}; };
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE #endif // !GLSLANG_WEB && !GLSLANG_ANGLE
@ -927,6 +948,7 @@ public:
protected: protected:
GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages); GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages);
GLSLANG_EXPORT bool crossStageCheck(EShMessages);
TPoolAllocator* pool; TPoolAllocator* pool;
std::list<TShader*> stages[EShLangCount]; std::list<TShader*> stages[EShLangCount];

View file

@ -35,7 +35,7 @@
#define GLSLANG_BUILD_INFO #define GLSLANG_BUILD_INFO
#define GLSLANG_VERSION_MAJOR 11 #define GLSLANG_VERSION_MAJOR 11
#define GLSLANG_VERSION_MINOR 0 #define GLSLANG_VERSION_MINOR 6
#define GLSLANG_VERSION_PATCH 0 #define GLSLANG_VERSION_PATCH 0
#define GLSLANG_VERSION_FLAVOR "" #define GLSLANG_VERSION_FLAVOR ""

View file

@ -631,9 +631,12 @@ static void volkGenLoadDevice(void* context, PFN_vkVoidFunction (*load)(void*, c
vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)load(context, "vkGetPastPresentationTimingGOOGLE"); vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)load(context, "vkGetPastPresentationTimingGOOGLE");
vkGetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)load(context, "vkGetRefreshCycleDurationGOOGLE"); vkGetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)load(context, "vkGetRefreshCycleDurationGOOGLE");
#endif /* defined(VK_GOOGLE_display_timing) */ #endif /* defined(VK_GOOGLE_display_timing) */
#if defined(VK_HUAWEI_invocation_mask)
vkCmdBindInvocationMaskHUAWEI = (PFN_vkCmdBindInvocationMaskHUAWEI)load(context, "vkCmdBindInvocationMaskHUAWEI");
#endif /* defined(VK_HUAWEI_invocation_mask) */
#if defined(VK_HUAWEI_subpass_shading) #if defined(VK_HUAWEI_subpass_shading)
vkCmdSubpassShadingHUAWEI = (PFN_vkCmdSubpassShadingHUAWEI)load(context, "vkCmdSubpassShadingHUAWEI"); vkCmdSubpassShadingHUAWEI = (PFN_vkCmdSubpassShadingHUAWEI)load(context, "vkCmdSubpassShadingHUAWEI");
vkGetSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetSubpassShadingMaxWorkgroupSizeHUAWEI"); vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
#endif /* defined(VK_HUAWEI_subpass_shading) */ #endif /* defined(VK_HUAWEI_subpass_shading) */
#if defined(VK_INTEL_performance_query) #if defined(VK_INTEL_performance_query)
vkAcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)load(context, "vkAcquirePerformanceConfigurationINTEL"); vkAcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)load(context, "vkAcquirePerformanceConfigurationINTEL");
@ -758,6 +761,9 @@ static void volkGenLoadDevice(void* context, PFN_vkVoidFunction (*load)(void*, c
vkGetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)load(context, "vkGetPipelineExecutablePropertiesKHR"); vkGetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)load(context, "vkGetPipelineExecutablePropertiesKHR");
vkGetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)load(context, "vkGetPipelineExecutableStatisticsKHR"); vkGetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)load(context, "vkGetPipelineExecutableStatisticsKHR");
#endif /* defined(VK_KHR_pipeline_executable_properties) */ #endif /* defined(VK_KHR_pipeline_executable_properties) */
#if defined(VK_KHR_present_wait)
vkWaitForPresentKHR = (PFN_vkWaitForPresentKHR)load(context, "vkWaitForPresentKHR");
#endif /* defined(VK_KHR_present_wait) */
#if defined(VK_KHR_push_descriptor) #if defined(VK_KHR_push_descriptor)
vkCmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)load(context, "vkCmdPushDescriptorSetKHR"); vkCmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)load(context, "vkCmdPushDescriptorSetKHR");
#endif /* defined(VK_KHR_push_descriptor) */ #endif /* defined(VK_KHR_push_descriptor) */
@ -847,6 +853,9 @@ static void volkGenLoadDevice(void* context, PFN_vkVoidFunction (*load)(void*, c
vkDestroyIndirectCommandsLayoutNV = (PFN_vkDestroyIndirectCommandsLayoutNV)load(context, "vkDestroyIndirectCommandsLayoutNV"); vkDestroyIndirectCommandsLayoutNV = (PFN_vkDestroyIndirectCommandsLayoutNV)load(context, "vkDestroyIndirectCommandsLayoutNV");
vkGetGeneratedCommandsMemoryRequirementsNV = (PFN_vkGetGeneratedCommandsMemoryRequirementsNV)load(context, "vkGetGeneratedCommandsMemoryRequirementsNV"); vkGetGeneratedCommandsMemoryRequirementsNV = (PFN_vkGetGeneratedCommandsMemoryRequirementsNV)load(context, "vkGetGeneratedCommandsMemoryRequirementsNV");
#endif /* defined(VK_NV_device_generated_commands) */ #endif /* defined(VK_NV_device_generated_commands) */
#if defined(VK_NV_external_memory_rdma)
vkGetMemoryRemoteAddressNV = (PFN_vkGetMemoryRemoteAddressNV)load(context, "vkGetMemoryRemoteAddressNV");
#endif /* defined(VK_NV_external_memory_rdma) */
#if defined(VK_NV_external_memory_win32) #if defined(VK_NV_external_memory_win32)
vkGetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)load(context, "vkGetMemoryWin32HandleNV"); vkGetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)load(context, "vkGetMemoryWin32HandleNV");
#endif /* defined(VK_NV_external_memory_win32) */ #endif /* defined(VK_NV_external_memory_win32) */
@ -1182,9 +1191,12 @@ static void volkGenLoadDeviceTable(struct VolkDeviceTable* table, void* context,
table->vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)load(context, "vkGetPastPresentationTimingGOOGLE"); table->vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)load(context, "vkGetPastPresentationTimingGOOGLE");
table->vkGetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)load(context, "vkGetRefreshCycleDurationGOOGLE"); table->vkGetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)load(context, "vkGetRefreshCycleDurationGOOGLE");
#endif /* defined(VK_GOOGLE_display_timing) */ #endif /* defined(VK_GOOGLE_display_timing) */
#if defined(VK_HUAWEI_invocation_mask)
table->vkCmdBindInvocationMaskHUAWEI = (PFN_vkCmdBindInvocationMaskHUAWEI)load(context, "vkCmdBindInvocationMaskHUAWEI");
#endif /* defined(VK_HUAWEI_invocation_mask) */
#if defined(VK_HUAWEI_subpass_shading) #if defined(VK_HUAWEI_subpass_shading)
table->vkCmdSubpassShadingHUAWEI = (PFN_vkCmdSubpassShadingHUAWEI)load(context, "vkCmdSubpassShadingHUAWEI"); table->vkCmdSubpassShadingHUAWEI = (PFN_vkCmdSubpassShadingHUAWEI)load(context, "vkCmdSubpassShadingHUAWEI");
table->vkGetSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetSubpassShadingMaxWorkgroupSizeHUAWEI"); table->vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
#endif /* defined(VK_HUAWEI_subpass_shading) */ #endif /* defined(VK_HUAWEI_subpass_shading) */
#if defined(VK_INTEL_performance_query) #if defined(VK_INTEL_performance_query)
table->vkAcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)load(context, "vkAcquirePerformanceConfigurationINTEL"); table->vkAcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)load(context, "vkAcquirePerformanceConfigurationINTEL");
@ -1309,6 +1321,9 @@ static void volkGenLoadDeviceTable(struct VolkDeviceTable* table, void* context,
table->vkGetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)load(context, "vkGetPipelineExecutablePropertiesKHR"); table->vkGetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)load(context, "vkGetPipelineExecutablePropertiesKHR");
table->vkGetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)load(context, "vkGetPipelineExecutableStatisticsKHR"); table->vkGetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)load(context, "vkGetPipelineExecutableStatisticsKHR");
#endif /* defined(VK_KHR_pipeline_executable_properties) */ #endif /* defined(VK_KHR_pipeline_executable_properties) */
#if defined(VK_KHR_present_wait)
table->vkWaitForPresentKHR = (PFN_vkWaitForPresentKHR)load(context, "vkWaitForPresentKHR");
#endif /* defined(VK_KHR_present_wait) */
#if defined(VK_KHR_push_descriptor) #if defined(VK_KHR_push_descriptor)
table->vkCmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)load(context, "vkCmdPushDescriptorSetKHR"); table->vkCmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)load(context, "vkCmdPushDescriptorSetKHR");
#endif /* defined(VK_KHR_push_descriptor) */ #endif /* defined(VK_KHR_push_descriptor) */
@ -1398,6 +1413,9 @@ static void volkGenLoadDeviceTable(struct VolkDeviceTable* table, void* context,
table->vkDestroyIndirectCommandsLayoutNV = (PFN_vkDestroyIndirectCommandsLayoutNV)load(context, "vkDestroyIndirectCommandsLayoutNV"); table->vkDestroyIndirectCommandsLayoutNV = (PFN_vkDestroyIndirectCommandsLayoutNV)load(context, "vkDestroyIndirectCommandsLayoutNV");
table->vkGetGeneratedCommandsMemoryRequirementsNV = (PFN_vkGetGeneratedCommandsMemoryRequirementsNV)load(context, "vkGetGeneratedCommandsMemoryRequirementsNV"); table->vkGetGeneratedCommandsMemoryRequirementsNV = (PFN_vkGetGeneratedCommandsMemoryRequirementsNV)load(context, "vkGetGeneratedCommandsMemoryRequirementsNV");
#endif /* defined(VK_NV_device_generated_commands) */ #endif /* defined(VK_NV_device_generated_commands) */
#if defined(VK_NV_external_memory_rdma)
table->vkGetMemoryRemoteAddressNV = (PFN_vkGetMemoryRemoteAddressNV)load(context, "vkGetMemoryRemoteAddressNV");
#endif /* defined(VK_NV_external_memory_rdma) */
#if defined(VK_NV_external_memory_win32) #if defined(VK_NV_external_memory_win32)
table->vkGetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)load(context, "vkGetMemoryWin32HandleNV"); table->vkGetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)load(context, "vkGetMemoryWin32HandleNV");
#endif /* defined(VK_NV_external_memory_win32) */ #endif /* defined(VK_NV_external_memory_win32) */
@ -1822,9 +1840,12 @@ PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP;
PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE; PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE; PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE;
#endif /* defined(VK_GOOGLE_display_timing) */ #endif /* defined(VK_GOOGLE_display_timing) */
#if defined(VK_HUAWEI_invocation_mask)
PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI;
#endif /* defined(VK_HUAWEI_invocation_mask) */
#if defined(VK_HUAWEI_subpass_shading) #if defined(VK_HUAWEI_subpass_shading)
PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI; PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI vkGetSubpassShadingMaxWorkgroupSizeHUAWEI; PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
#endif /* defined(VK_HUAWEI_subpass_shading) */ #endif /* defined(VK_HUAWEI_subpass_shading) */
#if defined(VK_INTEL_performance_query) #if defined(VK_INTEL_performance_query)
PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL; PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL;
@ -1995,6 +2016,9 @@ PFN_vkGetPipelineExecutableInternalRepresentationsKHR vkGetPipelineExecutableInt
PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR; PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR;
PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR; PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR;
#endif /* defined(VK_KHR_pipeline_executable_properties) */ #endif /* defined(VK_KHR_pipeline_executable_properties) */
#if defined(VK_KHR_present_wait)
PFN_vkWaitForPresentKHR vkWaitForPresentKHR;
#endif /* defined(VK_KHR_present_wait) */
#if defined(VK_KHR_push_descriptor) #if defined(VK_KHR_push_descriptor)
PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR; PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
#endif /* defined(VK_KHR_push_descriptor) */ #endif /* defined(VK_KHR_push_descriptor) */
@ -2131,6 +2155,9 @@ PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemoryRequi
#if defined(VK_NV_external_memory_capabilities) #if defined(VK_NV_external_memory_capabilities)
PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV vkGetPhysicalDeviceExternalImageFormatPropertiesNV; PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV vkGetPhysicalDeviceExternalImageFormatPropertiesNV;
#endif /* defined(VK_NV_external_memory_capabilities) */ #endif /* defined(VK_NV_external_memory_capabilities) */
#if defined(VK_NV_external_memory_rdma)
PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV;
#endif /* defined(VK_NV_external_memory_rdma) */
#if defined(VK_NV_external_memory_win32) #if defined(VK_NV_external_memory_win32)
PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV; PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV;
#endif /* defined(VK_NV_external_memory_win32) */ #endif /* defined(VK_NV_external_memory_win32) */

View file

@ -15,7 +15,7 @@
#endif #endif
/* VOLK_GENERATE_VERSION_DEFINE */ /* VOLK_GENERATE_VERSION_DEFINE */
#define VOLK_HEADER_VERSION 182 #define VOLK_HEADER_VERSION 190
/* VOLK_GENERATE_VERSION_DEFINE */ /* VOLK_GENERATE_VERSION_DEFINE */
#ifndef VK_NO_PROTOTYPES #ifndef VK_NO_PROTOTYPES
@ -51,10 +51,13 @@
# endif # endif
#endif #endif
/* Disable VK_NVX_image_view_handle because SDK 140 introduced a change that can't be used with prior versions */ /* Disable several extensions on earlier SDKs because later SDKs introduce a backwards incompatible change to function signatures */
#if VK_HEADER_VERSION < 140 #if VK_HEADER_VERSION < 140
# undef VK_NVX_image_view_handle # undef VK_NVX_image_view_handle
#endif #endif
#if VK_HEADER_VERSION < 184
# undef VK_HUAWEI_subpass_shading
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -410,9 +413,12 @@ struct VolkDeviceTable
PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE; PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE; PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE;
#endif /* defined(VK_GOOGLE_display_timing) */ #endif /* defined(VK_GOOGLE_display_timing) */
#if defined(VK_HUAWEI_invocation_mask)
PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI;
#endif /* defined(VK_HUAWEI_invocation_mask) */
#if defined(VK_HUAWEI_subpass_shading) #if defined(VK_HUAWEI_subpass_shading)
PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI; PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI vkGetSubpassShadingMaxWorkgroupSizeHUAWEI; PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
#endif /* defined(VK_HUAWEI_subpass_shading) */ #endif /* defined(VK_HUAWEI_subpass_shading) */
#if defined(VK_INTEL_performance_query) #if defined(VK_INTEL_performance_query)
PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL; PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL;
@ -537,6 +543,9 @@ struct VolkDeviceTable
PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR; PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR;
PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR; PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR;
#endif /* defined(VK_KHR_pipeline_executable_properties) */ #endif /* defined(VK_KHR_pipeline_executable_properties) */
#if defined(VK_KHR_present_wait)
PFN_vkWaitForPresentKHR vkWaitForPresentKHR;
#endif /* defined(VK_KHR_present_wait) */
#if defined(VK_KHR_push_descriptor) #if defined(VK_KHR_push_descriptor)
PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR; PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
#endif /* defined(VK_KHR_push_descriptor) */ #endif /* defined(VK_KHR_push_descriptor) */
@ -626,6 +635,9 @@ struct VolkDeviceTable
PFN_vkDestroyIndirectCommandsLayoutNV vkDestroyIndirectCommandsLayoutNV; PFN_vkDestroyIndirectCommandsLayoutNV vkDestroyIndirectCommandsLayoutNV;
PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemoryRequirementsNV; PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemoryRequirementsNV;
#endif /* defined(VK_NV_device_generated_commands) */ #endif /* defined(VK_NV_device_generated_commands) */
#if defined(VK_NV_external_memory_rdma)
PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV;
#endif /* defined(VK_NV_external_memory_rdma) */
#if defined(VK_NV_external_memory_win32) #if defined(VK_NV_external_memory_win32)
PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV; PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV;
#endif /* defined(VK_NV_external_memory_win32) */ #endif /* defined(VK_NV_external_memory_win32) */
@ -1042,9 +1054,12 @@ extern PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP
extern PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE; extern PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
extern PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE; extern PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE;
#endif /* defined(VK_GOOGLE_display_timing) */ #endif /* defined(VK_GOOGLE_display_timing) */
#if defined(VK_HUAWEI_invocation_mask)
extern PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI;
#endif /* defined(VK_HUAWEI_invocation_mask) */
#if defined(VK_HUAWEI_subpass_shading) #if defined(VK_HUAWEI_subpass_shading)
extern PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI; extern PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
extern PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI vkGetSubpassShadingMaxWorkgroupSizeHUAWEI; extern PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
#endif /* defined(VK_HUAWEI_subpass_shading) */ #endif /* defined(VK_HUAWEI_subpass_shading) */
#if defined(VK_INTEL_performance_query) #if defined(VK_INTEL_performance_query)
extern PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL; extern PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL;
@ -1215,6 +1230,9 @@ extern PFN_vkGetPipelineExecutableInternalRepresentationsKHR vkGetPipelineExecut
extern PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR; extern PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR;
extern PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR; extern PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR;
#endif /* defined(VK_KHR_pipeline_executable_properties) */ #endif /* defined(VK_KHR_pipeline_executable_properties) */
#if defined(VK_KHR_present_wait)
extern PFN_vkWaitForPresentKHR vkWaitForPresentKHR;
#endif /* defined(VK_KHR_present_wait) */
#if defined(VK_KHR_push_descriptor) #if defined(VK_KHR_push_descriptor)
extern PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR; extern PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
#endif /* defined(VK_KHR_push_descriptor) */ #endif /* defined(VK_KHR_push_descriptor) */
@ -1351,6 +1369,9 @@ extern PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemo
#if defined(VK_NV_external_memory_capabilities) #if defined(VK_NV_external_memory_capabilities)
extern PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV vkGetPhysicalDeviceExternalImageFormatPropertiesNV; extern PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV vkGetPhysicalDeviceExternalImageFormatPropertiesNV;
#endif /* defined(VK_NV_external_memory_capabilities) */ #endif /* defined(VK_NV_external_memory_capabilities) */
#if defined(VK_NV_external_memory_rdma)
extern PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV;
#endif /* defined(VK_NV_external_memory_rdma) */
#if defined(VK_NV_external_memory_win32) #if defined(VK_NV_external_memory_win32)
extern PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV; extern PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV;
#endif /* defined(VK_NV_external_memory_win32) */ #endif /* defined(VK_NV_external_memory_win32) */

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@ extern "C" {
#define VK_KHR_video_queue 1 #define VK_KHR_video_queue 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionKHR) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionKHR)
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionParametersKHR) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionParametersKHR)
#define VK_KHR_VIDEO_QUEUE_SPEC_VERSION 1 #define VK_KHR_VIDEO_QUEUE_SPEC_VERSION 2
#define VK_KHR_VIDEO_QUEUE_EXTENSION_NAME "VK_KHR_video_queue" #define VK_KHR_VIDEO_QUEUE_EXTENSION_NAME "VK_KHR_video_queue"
typedef enum VkQueryResultStatusKHR { typedef enum VkQueryResultStatusKHR {
@ -66,12 +66,12 @@ typedef enum VkVideoComponentBitDepthFlagBitsKHR {
} VkVideoComponentBitDepthFlagBitsKHR; } VkVideoComponentBitDepthFlagBitsKHR;
typedef VkFlags VkVideoComponentBitDepthFlagsKHR; typedef VkFlags VkVideoComponentBitDepthFlagsKHR;
typedef enum VkVideoCapabilitiesFlagBitsKHR { typedef enum VkVideoCapabilityFlagBitsKHR {
VK_VIDEO_CAPABILITIES_PROTECTED_CONTENT_BIT_KHR = 0x00000001, VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR = 0x00000001,
VK_VIDEO_CAPABILITIES_SEPARATE_REFERENCE_IMAGES_BIT_KHR = 0x00000002, VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR = 0x00000002,
VK_VIDEO_CAPABILITIES_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF VK_VIDEO_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoCapabilitiesFlagBitsKHR; } VkVideoCapabilityFlagBitsKHR;
typedef VkFlags VkVideoCapabilitiesFlagsKHR; typedef VkFlags VkVideoCapabilityFlagsKHR;
typedef enum VkVideoSessionCreateFlagBitsKHR { typedef enum VkVideoSessionCreateFlagBitsKHR {
VK_VIDEO_SESSION_CREATE_DEFAULT_KHR = 0, VK_VIDEO_SESSION_CREATE_DEFAULT_KHR = 0,
@ -120,21 +120,21 @@ typedef struct VkVideoProfilesKHR {
} VkVideoProfilesKHR; } VkVideoProfilesKHR;
typedef struct VkVideoCapabilitiesKHR { typedef struct VkVideoCapabilitiesKHR {
VkStructureType sType; VkStructureType sType;
void* pNext; void* pNext;
VkVideoCapabilitiesFlagsKHR capabilityFlags; VkVideoCapabilityFlagsKHR capabilityFlags;
VkDeviceSize minBitstreamBufferOffsetAlignment; VkDeviceSize minBitstreamBufferOffsetAlignment;
VkDeviceSize minBitstreamBufferSizeAlignment; VkDeviceSize minBitstreamBufferSizeAlignment;
VkExtent2D videoPictureExtentGranularity; VkExtent2D videoPictureExtentGranularity;
VkExtent2D minExtent; VkExtent2D minExtent;
VkExtent2D maxExtent; VkExtent2D maxExtent;
uint32_t maxReferencePicturesSlotsCount; uint32_t maxReferencePicturesSlotsCount;
uint32_t maxReferencePicturesActiveCount; uint32_t maxReferencePicturesActiveCount;
} VkVideoCapabilitiesKHR; } VkVideoCapabilitiesKHR;
typedef struct VkPhysicalDeviceVideoFormatInfoKHR { typedef struct VkPhysicalDeviceVideoFormatInfoKHR {
VkStructureType sType; VkStructureType sType;
const void* pNext; void* pNext;
VkImageUsageFlags imageUsage; VkImageUsageFlags imageUsage;
const VkVideoProfilesKHR* pVideoProfiles; const VkVideoProfilesKHR* pVideoProfiles;
} VkPhysicalDeviceVideoFormatInfoKHR; } VkPhysicalDeviceVideoFormatInfoKHR;
@ -433,10 +433,10 @@ VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR(
#define VK_EXT_video_encode_h264 1 #define VK_EXT_video_encode_h264 1
#include "vk_video/vulkan_video_codec_h264std.h" #include "vk_video/vulkan_video_codec_h264std.h"
#include "vk_video/vulkan_video_codec_h264std_encode.h" #include "vk_video/vulkan_video_codec_h264std_encode.h"
#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 1 #define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 2
#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264" #define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264"
typedef enum VkVideoEncodeH264CapabilitiesFlagBitsEXT { typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT {
VK_VIDEO_ENCODE_H264_CAPABILITY_CABAC_BIT_EXT = 0x00000001, VK_VIDEO_ENCODE_H264_CAPABILITY_CABAC_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H264_CAPABILITY_CAVLC_BIT_EXT = 0x00000002, VK_VIDEO_ENCODE_H264_CAPABILITY_CAVLC_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT = 0x00000004, VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT = 0x00000004,
@ -448,9 +448,9 @@ typedef enum VkVideoEncodeH264CapabilitiesFlagBitsEXT {
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_PARTIAL_BIT_EXT = 0x00000100, VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_PARTIAL_BIT_EXT = 0x00000100,
VK_VIDEO_ENCODE_H264_CAPABILITY_MULTIPLE_SLICE_PER_FRAME_BIT_EXT = 0x00000200, VK_VIDEO_ENCODE_H264_CAPABILITY_MULTIPLE_SLICE_PER_FRAME_BIT_EXT = 0x00000200,
VK_VIDEO_ENCODE_H264_CAPABILITY_EVENLY_DISTRIBUTED_SLICE_SIZE_BIT_EXT = 0x00000400, VK_VIDEO_ENCODE_H264_CAPABILITY_EVENLY_DISTRIBUTED_SLICE_SIZE_BIT_EXT = 0x00000400,
VK_VIDEO_ENCODE_H264_CAPABILITIES_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264CapabilitiesFlagBitsEXT; } VkVideoEncodeH264CapabilityFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264CapabilitiesFlagsEXT; typedef VkFlags VkVideoEncodeH264CapabilityFlagsEXT;
typedef enum VkVideoEncodeH264InputModeFlagBitsEXT { typedef enum VkVideoEncodeH264InputModeFlagBitsEXT {
VK_VIDEO_ENCODE_H264_INPUT_MODE_FRAME_BIT_EXT = 0x00000001, VK_VIDEO_ENCODE_H264_INPUT_MODE_FRAME_BIT_EXT = 0x00000001,
@ -475,19 +475,19 @@ typedef enum VkVideoEncodeH264CreateFlagBitsEXT {
} VkVideoEncodeH264CreateFlagBitsEXT; } VkVideoEncodeH264CreateFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264CreateFlagsEXT; typedef VkFlags VkVideoEncodeH264CreateFlagsEXT;
typedef struct VkVideoEncodeH264CapabilitiesEXT { typedef struct VkVideoEncodeH264CapabilitiesEXT {
VkStructureType sType; VkStructureType sType;
const void* pNext; const void* pNext;
VkVideoEncodeH264CapabilitiesFlagsEXT flags; VkVideoEncodeH264CapabilityFlagsEXT flags;
VkVideoEncodeH264InputModeFlagsEXT inputModeFlags; VkVideoEncodeH264InputModeFlagsEXT inputModeFlags;
VkVideoEncodeH264OutputModeFlagsEXT outputModeFlags; VkVideoEncodeH264OutputModeFlagsEXT outputModeFlags;
VkExtent2D minPictureSizeInMbs; VkExtent2D minPictureSizeInMbs;
VkExtent2D maxPictureSizeInMbs; VkExtent2D maxPictureSizeInMbs;
VkExtent2D inputImageDataAlignment; VkExtent2D inputImageDataAlignment;
uint8_t maxNumL0ReferenceForP; uint8_t maxNumL0ReferenceForP;
uint8_t maxNumL0ReferenceForB; uint8_t maxNumL0ReferenceForB;
uint8_t maxNumL1Reference; uint8_t maxNumL1Reference;
uint8_t qualityLevelCount; uint8_t qualityLevelCount;
VkExtensionProperties stdExtensionVersion; VkExtensionProperties stdExtensionVersion;
} VkVideoEncodeH264CapabilitiesEXT; } VkVideoEncodeH264CapabilitiesEXT;
typedef struct VkVideoEncodeH264SessionCreateInfoEXT { typedef struct VkVideoEncodeH264SessionCreateInfoEXT {
@ -567,22 +567,22 @@ typedef struct VkVideoEncodeH264ProfileEXT {
#define VK_EXT_video_decode_h264 1 #define VK_EXT_video_decode_h264 1
#include "vk_video/vulkan_video_codec_h264std_decode.h" #include "vk_video/vulkan_video_codec_h264std_decode.h"
#define VK_EXT_VIDEO_DECODE_H264_SPEC_VERSION 1 #define VK_EXT_VIDEO_DECODE_H264_SPEC_VERSION 3
#define VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME "VK_EXT_video_decode_h264" #define VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME "VK_EXT_video_decode_h264"
typedef enum VkVideoDecodeH264FieldLayoutFlagBitsEXT { typedef enum VkVideoDecodeH264PictureLayoutFlagBitsEXT {
VK_VIDEO_DECODE_H264_PROGRESSIVE_PICTURES_ONLY_EXT = 0, VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT = 0,
VK_VIDEO_DECODE_H264_FIELD_LAYOUT_LINE_INTERLACED_PLANE_BIT_EXT = 0x00000001, VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_EXT = 0x00000001,
VK_VIDEO_DECODE_H264_FIELD_LAYOUT_SEPARATE_INTERLACED_PLANE_BIT_EXT = 0x00000002, VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_EXT = 0x00000002,
VK_VIDEO_DECODE_H264_FIELD_LAYOUT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoDecodeH264FieldLayoutFlagBitsEXT; } VkVideoDecodeH264PictureLayoutFlagBitsEXT;
typedef VkFlags VkVideoDecodeH264FieldLayoutFlagsEXT; typedef VkFlags VkVideoDecodeH264PictureLayoutFlagsEXT;
typedef VkFlags VkVideoDecodeH264CreateFlagsEXT; typedef VkFlags VkVideoDecodeH264CreateFlagsEXT;
typedef struct VkVideoDecodeH264ProfileEXT { typedef struct VkVideoDecodeH264ProfileEXT {
VkStructureType sType; VkStructureType sType;
const void* pNext; const void* pNext;
StdVideoH264ProfileIdc stdProfileIdc; StdVideoH264ProfileIdc stdProfileIdc;
VkVideoDecodeH264FieldLayoutFlagsEXT fieldLayout; VkVideoDecodeH264PictureLayoutFlagsEXT pictureLayout;
} VkVideoDecodeH264ProfileEXT; } VkVideoDecodeH264ProfileEXT;
typedef struct VkVideoDecodeH264CapabilitiesEXT { typedef struct VkVideoDecodeH264CapabilitiesEXT {

View file

@ -72,7 +72,7 @@ extern "C" {
#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 #define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0
// Version of this file // Version of this file
#define VK_HEADER_VERSION 182 #define VK_HEADER_VERSION 190
// Complete version of this file // Complete version of this file
#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 2, VK_HEADER_VERSION) #define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 2, VK_HEADER_VERSION)
@ -120,6 +120,7 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet)
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool)
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer)
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)
#define VK_UUID_SIZE 16U
#define VK_ATTACHMENT_UNUSED (~0U) #define VK_ATTACHMENT_UNUSED (~0U)
#define VK_FALSE 0U #define VK_FALSE 0U
#define VK_LOD_CLAMP_NONE 1000.0F #define VK_LOD_CLAMP_NONE 1000.0F
@ -132,7 +133,6 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)
#define VK_MAX_MEMORY_TYPES 32U #define VK_MAX_MEMORY_TYPES 32U
#define VK_MAX_MEMORY_HEAPS 16U #define VK_MAX_MEMORY_HEAPS 16U
#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256U #define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256U
#define VK_UUID_SIZE 16U
#define VK_MAX_EXTENSION_NAME_SIZE 256U #define VK_MAX_EXTENSION_NAME_SIZE 256U
#define VK_MAX_DESCRIPTION_SIZE 256U #define VK_MAX_DESCRIPTION_SIZE 256U
@ -714,6 +714,7 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000,
VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000, VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000,
VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001, VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002,
@ -741,6 +742,7 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003, VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003,
VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004,
VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000,
VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001,
@ -752,6 +754,8 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = 1000280000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = 1000280001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000,
@ -765,6 +769,8 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002,
VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000,
VK_STRUCTURE_TYPE_PRESENT_ID_KHR = 1000294000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000,
VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001, VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001,
VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002, VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002,
@ -820,14 +826,18 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001,
VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000,
VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001,
VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002,
VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000, VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000,
VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001, VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001,
VK_STRUCTURE_TYPE_SUBPASSS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000, VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000,
VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000,
VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000,
@ -1058,6 +1068,11 @@ typedef enum VkObjectType {
VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkObjectType; } VkObjectType;
typedef enum VkPipelineCacheHeaderVersion {
VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1,
VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF
} VkPipelineCacheHeaderVersion;
typedef enum VkVendorId { typedef enum VkVendorId {
VK_VENDOR_ID_VIV = 0x10001, VK_VENDOR_ID_VIV = 0x10001,
VK_VENDOR_ID_VSI = 0x10002, VK_VENDOR_ID_VSI = 0x10002,
@ -1068,11 +1083,6 @@ typedef enum VkVendorId {
VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF
} VkVendorId; } VkVendorId;
typedef enum VkPipelineCacheHeaderVersion {
VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1,
VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF
} VkPipelineCacheHeaderVersion;
typedef enum VkSystemAllocationScope { typedef enum VkSystemAllocationScope {
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1,
@ -1699,13 +1709,15 @@ typedef enum VkAttachmentLoadOp {
VK_ATTACHMENT_LOAD_OP_LOAD = 0, VK_ATTACHMENT_LOAD_OP_LOAD = 0,
VK_ATTACHMENT_LOAD_OP_CLEAR = 1, VK_ATTACHMENT_LOAD_OP_CLEAR = 1,
VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2,
VK_ATTACHMENT_LOAD_OP_NONE_EXT = 1000400000,
VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF
} VkAttachmentLoadOp; } VkAttachmentLoadOp;
typedef enum VkAttachmentStoreOp { typedef enum VkAttachmentStoreOp {
VK_ATTACHMENT_STORE_OP_STORE = 0, VK_ATTACHMENT_STORE_OP_STORE = 0,
VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, VK_ATTACHMENT_STORE_OP_DONT_CARE = 1,
VK_ATTACHMENT_STORE_OP_NONE_QCOM = 1000301000, VK_ATTACHMENT_STORE_OP_NONE_EXT = 1000301000,
VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE_EXT,
VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF
} VkAttachmentStoreOp; } VkAttachmentStoreOp;
@ -1917,6 +1929,7 @@ typedef enum VkImageUsageFlagBits {
#ifdef VK_ENABLE_BETA_EXTENSIONS #ifdef VK_ENABLE_BETA_EXTENSIONS
VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR = 0x00008000, VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR = 0x00008000,
#endif #endif
VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI = 0x00040000,
VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,
VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkImageUsageFlagBits; } VkImageUsageFlagBits;
@ -1940,6 +1953,7 @@ typedef enum VkMemoryPropertyFlagBits {
VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020, VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020,
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD = 0x00000040, VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD = 0x00000040,
VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD = 0x00000080, VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD = 0x00000080,
VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV = 0x00000100,
VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkMemoryPropertyFlagBits; } VkMemoryPropertyFlagBits;
typedef VkFlags VkMemoryPropertyFlags; typedef VkFlags VkMemoryPropertyFlags;
@ -2114,10 +2128,6 @@ typedef enum VkImageViewCreateFlagBits {
VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkImageViewCreateFlagBits; } VkImageViewCreateFlagBits;
typedef VkFlags VkImageViewCreateFlags; typedef VkFlags VkImageViewCreateFlags;
typedef enum VkShaderModuleCreateFlagBits {
VK_SHADER_MODULE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkShaderModuleCreateFlagBits;
typedef VkFlags VkShaderModuleCreateFlags; typedef VkFlags VkShaderModuleCreateFlags;
typedef enum VkPipelineCacheCreateFlagBits { typedef enum VkPipelineCacheCreateFlagBits {
@ -2421,6 +2431,14 @@ typedef struct VkMemoryBarrier {
VkAccessFlags dstAccessMask; VkAccessFlags dstAccessMask;
} VkMemoryBarrier; } VkMemoryBarrier;
typedef struct VkPipelineCacheHeaderVersionOne {
uint32_t headerSize;
VkPipelineCacheHeaderVersion headerVersion;
uint32_t vendorID;
uint32_t deviceID;
uint8_t pipelineCacheUUID[VK_UUID_SIZE];
} VkPipelineCacheHeaderVersionOne;
typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)(
void* pUserData, void* pUserData,
size_t size, size_t size,
@ -4492,6 +4510,7 @@ typedef enum VkExternalMemoryHandleTypeFlagBits {
VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA = 0x00000800, VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA = 0x00000800,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV = 0x00001000,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
@ -5264,6 +5283,7 @@ typedef enum VkDriverId {
VK_DRIVER_ID_MOLTENVK = 14, VK_DRIVER_ID_MOLTENVK = 14,
VK_DRIVER_ID_COREAVI_PROPRIETARY = 15, VK_DRIVER_ID_COREAVI_PROPRIETARY = 15,
VK_DRIVER_ID_JUICE_PROPRIETARY = 16, VK_DRIVER_ID_JUICE_PROPRIETARY = 16,
VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17,
VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY, VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY,
VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE, VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE,
VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV, VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV,
@ -6177,7 +6197,7 @@ typedef struct VkAcquireNextImageInfoKHR {
typedef struct VkDeviceGroupPresentCapabilitiesKHR { typedef struct VkDeviceGroupPresentCapabilitiesKHR {
VkStructureType sType; VkStructureType sType;
const void* pNext; void* pNext;
uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE]; uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE];
VkDeviceGroupPresentModeFlagsKHR modes; VkDeviceGroupPresentModeFlagsKHR modes;
} VkDeviceGroupPresentCapabilitiesKHR; } VkDeviceGroupPresentCapabilitiesKHR;
@ -7052,7 +7072,7 @@ typedef struct VkPhysicalDevicePerformanceQueryPropertiesKHR {
typedef struct VkPerformanceCounterKHR { typedef struct VkPerformanceCounterKHR {
VkStructureType sType; VkStructureType sType;
const void* pNext; void* pNext;
VkPerformanceCounterUnitKHR unit; VkPerformanceCounterUnitKHR unit;
VkPerformanceCounterScopeKHR scope; VkPerformanceCounterScopeKHR scope;
VkPerformanceCounterStorageKHR storage; VkPerformanceCounterStorageKHR storage;
@ -7061,7 +7081,7 @@ typedef struct VkPerformanceCounterKHR {
typedef struct VkPerformanceCounterDescriptionKHR { typedef struct VkPerformanceCounterDescriptionKHR {
VkStructureType sType; VkStructureType sType;
const void* pNext; void* pNext;
VkPerformanceCounterDescriptionFlagsKHR flags; VkPerformanceCounterDescriptionFlagsKHR flags;
char name[VK_MAX_DESCRIPTION_SIZE]; char name[VK_MAX_DESCRIPTION_SIZE];
char category[VK_MAX_DESCRIPTION_SIZE]; char category[VK_MAX_DESCRIPTION_SIZE];
@ -7662,6 +7682,26 @@ typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayou
#define VK_KHR_present_wait 1
#define VK_KHR_PRESENT_WAIT_SPEC_VERSION 1
#define VK_KHR_PRESENT_WAIT_EXTENSION_NAME "VK_KHR_present_wait"
typedef struct VkPhysicalDevicePresentWaitFeaturesKHR {
VkStructureType sType;
void* pNext;
VkBool32 presentWait;
} VkPhysicalDevicePresentWaitFeaturesKHR;
typedef VkResult (VKAPI_PTR *PFN_vkWaitForPresentKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkWaitForPresentKHR(
VkDevice device,
VkSwapchainKHR swapchain,
uint64_t presentId,
uint64_t timeout);
#endif
#define VK_KHR_uniform_buffer_standard_layout 1 #define VK_KHR_uniform_buffer_standard_layout 1
#define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION 1 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION 1
#define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME "VK_KHR_uniform_buffer_standard_layout" #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME "VK_KHR_uniform_buffer_standard_layout"
@ -7826,6 +7866,52 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR
#endif #endif
#define VK_KHR_shader_integer_dot_product 1
#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION 1
#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME "VK_KHR_shader_integer_dot_product"
typedef struct VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR {
VkStructureType sType;
void* pNext;
VkBool32 shaderIntegerDotProduct;
} VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR;
typedef struct VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR {
VkStructureType sType;
void* pNext;
VkBool32 integerDotProduct8BitUnsignedAccelerated;
VkBool32 integerDotProduct8BitSignedAccelerated;
VkBool32 integerDotProduct8BitMixedSignednessAccelerated;
VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated;
VkBool32 integerDotProduct4x8BitPackedSignedAccelerated;
VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated;
VkBool32 integerDotProduct16BitUnsignedAccelerated;
VkBool32 integerDotProduct16BitSignedAccelerated;
VkBool32 integerDotProduct16BitMixedSignednessAccelerated;
VkBool32 integerDotProduct32BitUnsignedAccelerated;
VkBool32 integerDotProduct32BitSignedAccelerated;
VkBool32 integerDotProduct32BitMixedSignednessAccelerated;
VkBool32 integerDotProduct64BitUnsignedAccelerated;
VkBool32 integerDotProduct64BitSignedAccelerated;
VkBool32 integerDotProduct64BitMixedSignednessAccelerated;
VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated;
VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated;
VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated;
VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated;
VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated;
VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated;
VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated;
VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated;
VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated;
VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated;
VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated;
VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated;
VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated;
VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated;
VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated;
} VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR;
#define VK_KHR_pipeline_library 1 #define VK_KHR_pipeline_library 1
#define VK_KHR_PIPELINE_LIBRARY_SPEC_VERSION 1 #define VK_KHR_PIPELINE_LIBRARY_SPEC_VERSION 1
#define VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME "VK_KHR_pipeline_library" #define VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME "VK_KHR_pipeline_library"
@ -7843,6 +7929,24 @@ typedef struct VkPipelineLibraryCreateInfoKHR {
#define VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME "VK_KHR_shader_non_semantic_info" #define VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME "VK_KHR_shader_non_semantic_info"
#define VK_KHR_present_id 1
#define VK_KHR_PRESENT_ID_SPEC_VERSION 1
#define VK_KHR_PRESENT_ID_EXTENSION_NAME "VK_KHR_present_id"
typedef struct VkPresentIdKHR {
VkStructureType sType;
const void* pNext;
uint32_t swapchainCount;
const uint64_t* pPresentIds;
} VkPresentIdKHR;
typedef struct VkPhysicalDevicePresentIdFeaturesKHR {
VkStructureType sType;
void* pNext;
VkBool32 presentId;
} VkPhysicalDevicePresentIdFeaturesKHR;
#define VK_KHR_synchronization2 1 #define VK_KHR_synchronization2 1
typedef uint64_t VkFlags64; typedef uint64_t VkFlags64;
#define VK_KHR_SYNCHRONIZATION_2_SPEC_VERSION 1 #define VK_KHR_SYNCHRONIZATION_2_SPEC_VERSION 1
@ -7865,7 +7969,7 @@ static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL;
@ -7887,15 +7991,16 @@ static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL;
static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL;
typedef VkFlags64 VkAccessFlags2KHR; typedef VkFlags64 VkAccessFlags2KHR;
@ -7941,13 +8046,14 @@ static const VkAccessFlagBits2KHR VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT
static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL;
static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL;
static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL;
static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000; static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL;
static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL;
static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL; static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL;
static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000; static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL;
static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000; static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL;
static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL; static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL;
static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL; static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL;
static const VkAccessFlagBits2KHR VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL;
typedef enum VkSubmitFlagBitsKHR { typedef enum VkSubmitFlagBitsKHR {
@ -10075,9 +10181,10 @@ typedef VkGeometryFlagBitsKHR VkGeometryFlagBitsNV;
typedef enum VkGeometryInstanceFlagBitsKHR { typedef enum VkGeometryInstanceFlagBitsKHR {
VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR = 0x00000001, VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR = 0x00000001,
VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = 0x00000002, VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR = 0x00000002,
VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004, VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004,
VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008, VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008,
VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR,
VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR, VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR,
VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR, VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR,
VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR, VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR,
@ -11588,6 +11695,28 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOpEXT(
#endif #endif
#define VK_EXT_shader_atomic_float2 1
#define VK_EXT_SHADER_ATOMIC_FLOAT_2_SPEC_VERSION 1
#define VK_EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME "VK_EXT_shader_atomic_float2"
typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT {
VkStructureType sType;
void* pNext;
VkBool32 shaderBufferFloat16Atomics;
VkBool32 shaderBufferFloat16AtomicAdd;
VkBool32 shaderBufferFloat16AtomicMinMax;
VkBool32 shaderBufferFloat32AtomicMinMax;
VkBool32 shaderBufferFloat64AtomicMinMax;
VkBool32 shaderSharedFloat16Atomics;
VkBool32 shaderSharedFloat16AtomicAdd;
VkBool32 shaderSharedFloat16AtomicMinMax;
VkBool32 shaderSharedFloat32AtomicMinMax;
VkBool32 shaderSharedFloat64AtomicMinMax;
VkBool32 shaderImageFloat32AtomicMinMax;
VkBool32 sparseImageFloat32AtomicMinMax;
} VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT;
#define VK_EXT_shader_demote_to_helper_invocation 1 #define VK_EXT_shader_demote_to_helper_invocation 1
#define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION 1 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION 1
#define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation" #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation"
@ -11867,7 +11996,7 @@ typedef struct VkPhysicalDeviceDeviceMemoryReportFeaturesEXT {
typedef struct VkDeviceMemoryReportCallbackDataEXT { typedef struct VkDeviceMemoryReportCallbackDataEXT {
VkStructureType sType; VkStructureType sType;
const void* pNext; void* pNext;
VkDeviceMemoryReportFlagsEXT flags; VkDeviceMemoryReportFlagsEXT flags;
VkDeviceMemoryReportEventTypeEXT type; VkDeviceMemoryReportEventTypeEXT type;
uint64_t memoryObjectId; uint64_t memoryObjectId;
@ -12202,7 +12331,7 @@ typedef struct VkAccelerationStructureMotionInstanceNV {
typedef struct VkPhysicalDeviceRayTracingMotionBlurFeaturesNV { typedef struct VkPhysicalDeviceRayTracingMotionBlurFeaturesNV {
VkStructureType sType; VkStructureType sType;
const void* pNext; void* pNext;
VkBool32 rayTracingMotionBlur; VkBool32 rayTracingMotionBlur;
VkBool32 rayTracingMotionBlurPipelineTraceRaysIndirect; VkBool32 rayTracingMotionBlurPipelineTraceRaysIndirect;
} VkPhysicalDeviceRayTracingMotionBlurFeaturesNV; } VkPhysicalDeviceRayTracingMotionBlurFeaturesNV;
@ -12370,8 +12499,20 @@ typedef struct VkPhysicalDeviceDrmPropertiesEXT {
#define VK_EXT_primitive_topology_list_restart 1
#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION 1
#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME "VK_EXT_primitive_topology_list_restart"
typedef struct VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {
VkStructureType sType;
void* pNext;
VkBool32 primitiveTopologyListRestart;
VkBool32 primitiveTopologyPatchListRestart;
} VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT;
#define VK_HUAWEI_subpass_shading 1 #define VK_HUAWEI_subpass_shading 1
#define VK_HUAWEI_SUBPASS_SHADING_SPEC_VERSION 0 #define VK_HUAWEI_SUBPASS_SHADING_SPEC_VERSION 2
#define VK_HUAWEI_SUBPASS_SHADING_EXTENSION_NAME "VK_HUAWEI_subpass_shading" #define VK_HUAWEI_SUBPASS_SHADING_EXTENSION_NAME "VK_HUAWEI_subpass_shading"
typedef struct VkSubpassShadingPipelineCreateInfoHUAWEI { typedef struct VkSubpassShadingPipelineCreateInfoHUAWEI {
VkStructureType sType; VkStructureType sType;
@ -12392,11 +12533,12 @@ typedef struct VkPhysicalDeviceSubpassShadingPropertiesHUAWEI {
uint32_t maxSubpassShadingWorkgroupSizeAspectRatio; uint32_t maxSubpassShadingWorkgroupSizeAspectRatio;
} VkPhysicalDeviceSubpassShadingPropertiesHUAWEI; } VkPhysicalDeviceSubpassShadingPropertiesHUAWEI;
typedef VkResult (VKAPI_PTR *PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI)(VkRenderPass renderpass, VkExtent2D* pMaxWorkgroupSize); typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)(VkDevice device, VkRenderPass renderpass, VkExtent2D* pMaxWorkgroupSize);
typedef void (VKAPI_PTR *PFN_vkCmdSubpassShadingHUAWEI)(VkCommandBuffer commandBuffer); typedef void (VKAPI_PTR *PFN_vkCmdSubpassShadingHUAWEI)(VkCommandBuffer commandBuffer);
#ifndef VK_NO_PROTOTYPES #ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetSubpassShadingMaxWorkgroupSizeHUAWEI( VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI(
VkDevice device,
VkRenderPass renderpass, VkRenderPass renderpass,
VkExtent2D* pMaxWorkgroupSize); VkExtent2D* pMaxWorkgroupSize);
@ -12405,6 +12547,52 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSubpassShadingHUAWEI(
#endif #endif
#define VK_HUAWEI_invocation_mask 1
#define VK_HUAWEI_INVOCATION_MASK_SPEC_VERSION 1
#define VK_HUAWEI_INVOCATION_MASK_EXTENSION_NAME "VK_HUAWEI_invocation_mask"
typedef struct VkPhysicalDeviceInvocationMaskFeaturesHUAWEI {
VkStructureType sType;
void* pNext;
VkBool32 invocationMask;
} VkPhysicalDeviceInvocationMaskFeaturesHUAWEI;
typedef void (VKAPI_PTR *PFN_vkCmdBindInvocationMaskHUAWEI)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkCmdBindInvocationMaskHUAWEI(
VkCommandBuffer commandBuffer,
VkImageView imageView,
VkImageLayout imageLayout);
#endif
#define VK_NV_external_memory_rdma 1
typedef void* VkRemoteAddressNV;
#define VK_NV_EXTERNAL_MEMORY_RDMA_SPEC_VERSION 1
#define VK_NV_EXTERNAL_MEMORY_RDMA_EXTENSION_NAME "VK_NV_external_memory_rdma"
typedef struct VkMemoryGetRemoteAddressInfoNV {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetRemoteAddressInfoNV;
typedef struct VkPhysicalDeviceExternalMemoryRDMAFeaturesNV {
VkStructureType sType;
void* pNext;
VkBool32 externalMemoryRDMA;
} VkPhysicalDeviceExternalMemoryRDMAFeaturesNV;
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryRemoteAddressNV)(VkDevice device, const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, VkRemoteAddressNV* pAddress);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryRemoteAddressNV(
VkDevice device,
const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo,
VkRemoteAddressNV* pAddress);
#endif
#define VK_EXT_extended_dynamic_state2 1 #define VK_EXT_extended_dynamic_state2 1
#define VK_EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION 1 #define VK_EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION 1
#define VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME "VK_EXT_extended_dynamic_state2" #define VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME "VK_EXT_extended_dynamic_state2"
@ -12539,9 +12727,14 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT(
#endif #endif
#define VK_EXT_load_store_op_none 1
#define VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION 1
#define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none"
#define VK_KHR_acceleration_structure 1 #define VK_KHR_acceleration_structure 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR)
#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 11 #define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 12
#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure" #define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure"
typedef enum VkBuildAccelerationStructureModeKHR { typedef enum VkBuildAccelerationStructureModeKHR {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
diff --git a/thirdparty/vulkan/vk_enum_string_helper.h b/thirdparty/vulkan/vk_enum_string_helper.h diff --git a/thirdparty/vulkan/vk_enum_string_helper.h b/thirdparty/vulkan/vk_enum_string_helper.h
index 4c36430341..004a861774 100755 index 4c36430341..004a861774 100644
--- a/thirdparty/vulkan/vk_enum_string_helper.h --- a/thirdparty/vulkan/vk_enum_string_helper.h
+++ b/thirdparty/vulkan/vk_enum_string_helper.h +++ b/thirdparty/vulkan/vk_enum_string_helper.h
@@ -36,7 +36,11 @@ @@ -36,7 +36,11 @@

View file

@ -1,9 +1,9 @@
diff --git a/thirdparty/vulkan/vk_mem_alloc.h b/thirdparty/vulkan/vk_mem_alloc.h diff --git a/thirdparty/vulkan/vk_mem_alloc.h b/thirdparty/vulkan/vk_mem_alloc.h
index 8a42699e7f..510fa4d3ef 100644 index 65d6243419..9890f20f7c 100644
--- a/thirdparty/vulkan/vk_mem_alloc.h --- a/thirdparty/vulkan/vk_mem_alloc.h
+++ b/thirdparty/vulkan/vk_mem_alloc.h +++ b/thirdparty/vulkan/vk_mem_alloc.h
@@ -1771,7 +1771,11 @@ available through VmaAllocatorCreateInfo::pRecordSettings. @@ -2063,7 +2063,11 @@ available through VmaAllocatorCreateInfo::pRecordSettings.
#endif #endif // #if defined(__ANDROID__) && VMA_STATIC_VULKAN_FUNCTIONS && VK_NO_PROTOTYPES
#ifndef VULKAN_H_ #ifndef VULKAN_H_
- #include <vulkan/vulkan.h> - #include <vulkan/vulkan.h>
@ -14,4 +14,4 @@ index 8a42699e7f..510fa4d3ef 100644
+ #endif + #endif
#endif #endif
#if VMA_RECORDING_ENABLED // Define this macro to declare maximum supported Vulkan version in format AAABBBCCC,

View file

@ -558,6 +558,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
return "VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID"; return "VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID";
case VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR: case VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR:
return "VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR"; return "VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR";
case VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV:
return "VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV";
case VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR: case VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR:
return "VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR"; return "VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR";
case VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA: case VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA:
@ -674,6 +676,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2:
@ -728,6 +732,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT:
@ -776,6 +782,12 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR";
#endif // VK_ENABLE_BETA_EXTENSIONS #endif // VK_ENABLE_BETA_EXTENSIONS
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2:
@ -816,6 +828,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES:
@ -836,6 +850,10 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL:
return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL"; return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL";
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV:
@ -1006,6 +1024,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
return "VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV"; return "VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV";
case VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP: case VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP:
return "VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP"; return "VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP";
case VK_STRUCTURE_TYPE_PRESENT_ID_KHR:
return "VK_STRUCTURE_TYPE_PRESENT_ID_KHR";
case VK_STRUCTURE_TYPE_PRESENT_INFO_KHR: case VK_STRUCTURE_TYPE_PRESENT_INFO_KHR:
return "VK_STRUCTURE_TYPE_PRESENT_INFO_KHR"; return "VK_STRUCTURE_TYPE_PRESENT_INFO_KHR";
case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR: case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR:
@ -1108,8 +1128,6 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
return "VK_STRUCTURE_TYPE_SUBMIT_INFO"; return "VK_STRUCTURE_TYPE_SUBMIT_INFO";
case VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR: case VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR:
return "VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR"; return "VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR";
case VK_STRUCTURE_TYPE_SUBPASSS_SHADING_PIPELINE_CREATE_INFO_HUAWEI:
return "VK_STRUCTURE_TYPE_SUBPASSS_SHADING_PIPELINE_CREATE_INFO_HUAWEI";
case VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO: case VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO:
return "VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO"; return "VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO";
case VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2: case VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2:
@ -1120,6 +1138,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
return "VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE"; return "VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE";
case VK_STRUCTURE_TYPE_SUBPASS_END_INFO: case VK_STRUCTURE_TYPE_SUBPASS_END_INFO:
return "VK_STRUCTURE_TYPE_SUBPASS_END_INFO"; return "VK_STRUCTURE_TYPE_SUBPASS_END_INFO";
case VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI:
return "VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI";
case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT: case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT:
return "VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT"; return "VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT";
case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR: case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR:
@ -1657,6 +1677,17 @@ static inline const char* string_VkObjectType(VkObjectType input_value)
} }
} }
static inline const char* string_VkPipelineCacheHeaderVersion(VkPipelineCacheHeaderVersion input_value)
{
switch (input_value)
{
case VK_PIPELINE_CACHE_HEADER_VERSION_ONE:
return "VK_PIPELINE_CACHE_HEADER_VERSION_ONE";
default:
return "Unhandled VkPipelineCacheHeaderVersion";
}
}
static inline const char* string_VkVendorId(VkVendorId input_value) static inline const char* string_VkVendorId(VkVendorId input_value)
{ {
switch (input_value) switch (input_value)
@ -1678,17 +1709,6 @@ static inline const char* string_VkVendorId(VkVendorId input_value)
} }
} }
static inline const char* string_VkPipelineCacheHeaderVersion(VkPipelineCacheHeaderVersion input_value)
{
switch (input_value)
{
case VK_PIPELINE_CACHE_HEADER_VERSION_ONE:
return "VK_PIPELINE_CACHE_HEADER_VERSION_ONE";
default:
return "Unhandled VkPipelineCacheHeaderVersion";
}
}
static inline const char* string_VkSystemAllocationScope(VkSystemAllocationScope input_value) static inline const char* string_VkSystemAllocationScope(VkSystemAllocationScope input_value)
{ {
switch (input_value) switch (input_value)
@ -2455,6 +2475,8 @@ static inline const char* string_VkImageUsageFlagBits(VkImageUsageFlagBits input
return "VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR"; return "VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR";
case VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT: case VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT:
return "VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT"; return "VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT";
case VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI:
return "VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI";
case VK_IMAGE_USAGE_SAMPLED_BIT: case VK_IMAGE_USAGE_SAMPLED_BIT:
return "VK_IMAGE_USAGE_SAMPLED_BIT"; return "VK_IMAGE_USAGE_SAMPLED_BIT";
case VK_IMAGE_USAGE_STORAGE_BIT: case VK_IMAGE_USAGE_STORAGE_BIT:
@ -2559,6 +2581,8 @@ static inline const char* string_VkMemoryPropertyFlagBits(VkMemoryPropertyFlagBi
return "VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT"; return "VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT";
case VK_MEMORY_PROPERTY_PROTECTED_BIT: case VK_MEMORY_PROPERTY_PROTECTED_BIT:
return "VK_MEMORY_PROPERTY_PROTECTED_BIT"; return "VK_MEMORY_PROPERTY_PROTECTED_BIT";
case VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV:
return "VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV";
default: default:
return "Unhandled VkMemoryPropertyFlagBits"; return "Unhandled VkMemoryPropertyFlagBits";
} }
@ -4066,6 +4090,8 @@ static inline const char* string_VkAttachmentLoadOp(VkAttachmentLoadOp input_val
return "VK_ATTACHMENT_LOAD_OP_DONT_CARE"; return "VK_ATTACHMENT_LOAD_OP_DONT_CARE";
case VK_ATTACHMENT_LOAD_OP_LOAD: case VK_ATTACHMENT_LOAD_OP_LOAD:
return "VK_ATTACHMENT_LOAD_OP_LOAD"; return "VK_ATTACHMENT_LOAD_OP_LOAD";
case VK_ATTACHMENT_LOAD_OP_NONE_EXT:
return "VK_ATTACHMENT_LOAD_OP_NONE_EXT";
default: default:
return "Unhandled VkAttachmentLoadOp"; return "Unhandled VkAttachmentLoadOp";
} }
@ -4077,8 +4103,8 @@ static inline const char* string_VkAttachmentStoreOp(VkAttachmentStoreOp input_v
{ {
case VK_ATTACHMENT_STORE_OP_DONT_CARE: case VK_ATTACHMENT_STORE_OP_DONT_CARE:
return "VK_ATTACHMENT_STORE_OP_DONT_CARE"; return "VK_ATTACHMENT_STORE_OP_DONT_CARE";
case VK_ATTACHMENT_STORE_OP_NONE_QCOM: case VK_ATTACHMENT_STORE_OP_NONE_EXT:
return "VK_ATTACHMENT_STORE_OP_NONE_QCOM"; return "VK_ATTACHMENT_STORE_OP_NONE_EXT";
case VK_ATTACHMENT_STORE_OP_STORE: case VK_ATTACHMENT_STORE_OP_STORE:
return "VK_ATTACHMENT_STORE_OP_STORE"; return "VK_ATTACHMENT_STORE_OP_STORE";
default: default:
@ -4655,6 +4681,8 @@ static inline const char* string_VkExternalMemoryHandleTypeFlagBits(VkExternalMe
return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT"; return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT";
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT"; return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT";
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV:
return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV";
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA: case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA:
return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA"; return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA";
default: default:
@ -4927,6 +4955,8 @@ static inline const char* string_VkDriverId(VkDriverId input_value)
return "VK_DRIVER_ID_NVIDIA_PROPRIETARY"; return "VK_DRIVER_ID_NVIDIA_PROPRIETARY";
case VK_DRIVER_ID_QUALCOMM_PROPRIETARY: case VK_DRIVER_ID_QUALCOMM_PROPRIETARY:
return "VK_DRIVER_ID_QUALCOMM_PROPRIETARY"; return "VK_DRIVER_ID_QUALCOMM_PROPRIETARY";
case VK_DRIVER_ID_VERISILICON_PROPRIETARY:
return "VK_DRIVER_ID_VERISILICON_PROPRIETARY";
default: default:
return "Unhandled VkDriverId"; return "Unhandled VkDriverId";
} }
@ -5427,32 +5457,32 @@ static inline std::string string_VkVideoComponentBitDepthFlagsKHR(VkVideoCompone
#ifdef VK_ENABLE_BETA_EXTENSIONS #ifdef VK_ENABLE_BETA_EXTENSIONS
static inline const char* string_VkVideoCapabilitiesFlagBitsKHR(VkVideoCapabilitiesFlagBitsKHR input_value) static inline const char* string_VkVideoCapabilityFlagBitsKHR(VkVideoCapabilityFlagBitsKHR input_value)
{ {
switch (input_value) switch (input_value)
{ {
case VK_VIDEO_CAPABILITIES_PROTECTED_CONTENT_BIT_KHR: case VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR:
return "VK_VIDEO_CAPABILITIES_PROTECTED_CONTENT_BIT_KHR"; return "VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR";
case VK_VIDEO_CAPABILITIES_SEPARATE_REFERENCE_IMAGES_BIT_KHR: case VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR:
return "VK_VIDEO_CAPABILITIES_SEPARATE_REFERENCE_IMAGES_BIT_KHR"; return "VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR";
default: default:
return "Unhandled VkVideoCapabilitiesFlagBitsKHR"; return "Unhandled VkVideoCapabilityFlagBitsKHR";
} }
} }
static inline std::string string_VkVideoCapabilitiesFlagsKHR(VkVideoCapabilitiesFlagsKHR input_value) static inline std::string string_VkVideoCapabilityFlagsKHR(VkVideoCapabilityFlagsKHR input_value)
{ {
std::string ret; std::string ret;
int index = 0; int index = 0;
while(input_value) { while(input_value) {
if (input_value & 1) { if (input_value & 1) {
if( !ret.empty()) ret.append("|"); if( !ret.empty()) ret.append("|");
ret.append(string_VkVideoCapabilitiesFlagBitsKHR(static_cast<VkVideoCapabilitiesFlagBitsKHR>(1U << index))); ret.append(string_VkVideoCapabilityFlagBitsKHR(static_cast<VkVideoCapabilityFlagBitsKHR>(1U << index)));
} }
++index; ++index;
input_value >>= 1; input_value >>= 1;
} }
if( ret.empty()) ret.append(string_VkVideoCapabilitiesFlagBitsKHR(static_cast<VkVideoCapabilitiesFlagBitsKHR>(0))); if( ret.empty()) ret.append(string_VkVideoCapabilityFlagBitsKHR(static_cast<VkVideoCapabilityFlagBitsKHR>(0)));
return ret; return ret;
} }
#endif // VK_ENABLE_BETA_EXTENSIONS #endif // VK_ENABLE_BETA_EXTENSIONS
@ -5702,6 +5732,8 @@ static inline const char* string_VkExternalMemoryHandleTypeFlagBitsKHR(VkExterna
return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT"; return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT";
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT"; return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT";
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV:
return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV";
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA: case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA:
return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA"; return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA";
default: default:
@ -6154,6 +6186,8 @@ static inline const char* string_VkDriverIdKHR(VkDriverIdKHR input_value)
return "VK_DRIVER_ID_NVIDIA_PROPRIETARY"; return "VK_DRIVER_ID_NVIDIA_PROPRIETARY";
case VK_DRIVER_ID_QUALCOMM_PROPRIETARY: case VK_DRIVER_ID_QUALCOMM_PROPRIETARY:
return "VK_DRIVER_ID_QUALCOMM_PROPRIETARY"; return "VK_DRIVER_ID_QUALCOMM_PROPRIETARY";
case VK_DRIVER_ID_VERISILICON_PROPRIETARY:
return "VK_DRIVER_ID_VERISILICON_PROPRIETARY";
default: default:
return "Unhandled VkDriverIdKHR"; return "Unhandled VkDriverIdKHR";
} }
@ -6430,6 +6464,8 @@ static inline const char* string_VkPipelineStageFlagBits2KHR(uint64_t input_valu
return "VK_PIPELINE_STAGE_2_HOST_BIT_KHR"; return "VK_PIPELINE_STAGE_2_HOST_BIT_KHR";
case VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR: case VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR:
return "VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR"; return "VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR";
case VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI:
return "VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI";
case VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR: case VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR:
return "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR"; return "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR";
case VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV: case VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV:
@ -6527,6 +6563,8 @@ static inline const char* string_VkAccessFlagBits2KHR(uint64_t input_value)
return "VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR"; return "VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR";
case VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR: case VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR:
return "VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR"; return "VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR";
case VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI:
return "VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI";
case VK_ACCESS_2_MEMORY_READ_BIT_KHR: case VK_ACCESS_2_MEMORY_READ_BIT_KHR:
return "VK_ACCESS_2_MEMORY_READ_BIT_KHR"; return "VK_ACCESS_2_MEMORY_READ_BIT_KHR";
case VK_ACCESS_2_MEMORY_WRITE_BIT_KHR: case VK_ACCESS_2_MEMORY_WRITE_BIT_KHR:
@ -6757,7 +6795,7 @@ static inline const char* string_VkRasterizationOrderAMD(VkRasterizationOrderAMD
#ifdef VK_ENABLE_BETA_EXTENSIONS #ifdef VK_ENABLE_BETA_EXTENSIONS
static inline const char* string_VkVideoEncodeH264CapabilitiesFlagBitsEXT(VkVideoEncodeH264CapabilitiesFlagBitsEXT input_value) static inline const char* string_VkVideoEncodeH264CapabilityFlagBitsEXT(VkVideoEncodeH264CapabilityFlagBitsEXT input_value)
{ {
switch (input_value) switch (input_value)
{ {
@ -6784,23 +6822,23 @@ static inline const char* string_VkVideoEncodeH264CapabilitiesFlagBitsEXT(VkVide
case VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT: case VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT:
return "VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT"; return "VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT";
default: default:
return "Unhandled VkVideoEncodeH264CapabilitiesFlagBitsEXT"; return "Unhandled VkVideoEncodeH264CapabilityFlagBitsEXT";
} }
} }
static inline std::string string_VkVideoEncodeH264CapabilitiesFlagsEXT(VkVideoEncodeH264CapabilitiesFlagsEXT input_value) static inline std::string string_VkVideoEncodeH264CapabilityFlagsEXT(VkVideoEncodeH264CapabilityFlagsEXT input_value)
{ {
std::string ret; std::string ret;
int index = 0; int index = 0;
while(input_value) { while(input_value) {
if (input_value & 1) { if (input_value & 1) {
if( !ret.empty()) ret.append("|"); if( !ret.empty()) ret.append("|");
ret.append(string_VkVideoEncodeH264CapabilitiesFlagBitsEXT(static_cast<VkVideoEncodeH264CapabilitiesFlagBitsEXT>(1U << index))); ret.append(string_VkVideoEncodeH264CapabilityFlagBitsEXT(static_cast<VkVideoEncodeH264CapabilityFlagBitsEXT>(1U << index)));
} }
++index; ++index;
input_value >>= 1; input_value >>= 1;
} }
if( ret.empty()) ret.append(string_VkVideoEncodeH264CapabilitiesFlagBitsEXT(static_cast<VkVideoEncodeH264CapabilitiesFlagBitsEXT>(0))); if( ret.empty()) ret.append(string_VkVideoEncodeH264CapabilityFlagBitsEXT(static_cast<VkVideoEncodeH264CapabilityFlagBitsEXT>(0)));
return ret; return ret;
} }
#endif // VK_ENABLE_BETA_EXTENSIONS #endif // VK_ENABLE_BETA_EXTENSIONS
@ -6911,34 +6949,34 @@ static inline std::string string_VkVideoEncodeH264CreateFlagsEXT(VkVideoEncodeH2
#ifdef VK_ENABLE_BETA_EXTENSIONS #ifdef VK_ENABLE_BETA_EXTENSIONS
static inline const char* string_VkVideoDecodeH264FieldLayoutFlagBitsEXT(VkVideoDecodeH264FieldLayoutFlagBitsEXT input_value) static inline const char* string_VkVideoDecodeH264PictureLayoutFlagBitsEXT(VkVideoDecodeH264PictureLayoutFlagBitsEXT input_value)
{ {
switch (input_value) switch (input_value)
{ {
case VK_VIDEO_DECODE_H264_FIELD_LAYOUT_LINE_INTERLACED_PLANE_BIT_EXT: case VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_EXT:
return "VK_VIDEO_DECODE_H264_FIELD_LAYOUT_LINE_INTERLACED_PLANE_BIT_EXT"; return "VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_EXT";
case VK_VIDEO_DECODE_H264_FIELD_LAYOUT_SEPARATE_INTERLACED_PLANE_BIT_EXT: case VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_EXT:
return "VK_VIDEO_DECODE_H264_FIELD_LAYOUT_SEPARATE_INTERLACED_PLANE_BIT_EXT"; return "VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_EXT";
case VK_VIDEO_DECODE_H264_PROGRESSIVE_PICTURES_ONLY_EXT: case VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT:
return "VK_VIDEO_DECODE_H264_PROGRESSIVE_PICTURES_ONLY_EXT"; return "VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT";
default: default:
return "Unhandled VkVideoDecodeH264FieldLayoutFlagBitsEXT"; return "Unhandled VkVideoDecodeH264PictureLayoutFlagBitsEXT";
} }
} }
static inline std::string string_VkVideoDecodeH264FieldLayoutFlagsEXT(VkVideoDecodeH264FieldLayoutFlagsEXT input_value) static inline std::string string_VkVideoDecodeH264PictureLayoutFlagsEXT(VkVideoDecodeH264PictureLayoutFlagsEXT input_value)
{ {
std::string ret; std::string ret;
int index = 0; int index = 0;
while(input_value) { while(input_value) {
if (input_value & 1) { if (input_value & 1) {
if( !ret.empty()) ret.append("|"); if( !ret.empty()) ret.append("|");
ret.append(string_VkVideoDecodeH264FieldLayoutFlagBitsEXT(static_cast<VkVideoDecodeH264FieldLayoutFlagBitsEXT>(1U << index))); ret.append(string_VkVideoDecodeH264PictureLayoutFlagBitsEXT(static_cast<VkVideoDecodeH264PictureLayoutFlagBitsEXT>(1U << index)));
} }
++index; ++index;
input_value >>= 1; input_value >>= 1;
} }
if( ret.empty()) ret.append(string_VkVideoDecodeH264FieldLayoutFlagBitsEXT(static_cast<VkVideoDecodeH264FieldLayoutFlagBitsEXT>(0))); if( ret.empty()) ret.append(string_VkVideoDecodeH264PictureLayoutFlagBitsEXT(static_cast<VkVideoDecodeH264PictureLayoutFlagBitsEXT>(0)));
return ret; return ret;
} }
#endif // VK_ENABLE_BETA_EXTENSIONS #endif // VK_ENABLE_BETA_EXTENSIONS
@ -7542,8 +7580,8 @@ static inline const char* string_VkGeometryInstanceFlagBitsKHR(VkGeometryInstanc
return "VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR"; return "VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR";
case VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR: case VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR:
return "VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR"; return "VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR";
case VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR: case VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR:
return "VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR"; return "VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR";
default: default:
return "Unhandled VkGeometryInstanceFlagBitsKHR"; return "Unhandled VkGeometryInstanceFlagBitsKHR";
} }
@ -7575,8 +7613,8 @@ static inline const char* string_VkGeometryInstanceFlagBitsNV(VkGeometryInstance
return "VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR"; return "VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR";
case VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR: case VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR:
return "VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR"; return "VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR";
case VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR: case VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR:
return "VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR"; return "VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR";
default: default:
return "Unhandled VkGeometryInstanceFlagBitsNV"; return "Unhandled VkGeometryInstanceFlagBitsNV";
} }