summaryrefslogtreecommitdiff
path: root/thirdparty/glslang/SPIRV
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2020-10-15 12:04:10 +0200
committerRémi Verschelde <rverschelde@gmail.com>2020-10-15 12:29:42 +0200
commit148ad49c939f2413532ebecf92b60ce8dbc8cb8b (patch)
tree304312bd872998f9f65ed86d416440bb0c01f378 /thirdparty/glslang/SPIRV
parentb84f9b00681526afe39484129672e21917659084 (diff)
vulkan: Sync loader, headers and glslang to sdk-1.2.154.0
Actually sdk-1.2.154.1 for Vulkan-Loader. glslang is updated to bacaef3237c515e40d1a24722be48c0a0b30f75f which is the known-good version for Vulkan-ValidationLayers 1.2.154.0. COPYRIGHT.txt was synced with the current version of the glslang LICENSE.txt, and `glslang/register_types.cpp` now uses the upstream definition for its default builtin resource instead of hardcoding it.
Diffstat (limited to 'thirdparty/glslang/SPIRV')
-rw-r--r--thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp110
-rw-r--r--thirdparty/glslang/SPIRV/GLSL.ext.EXT.h1
-rw-r--r--thirdparty/glslang/SPIRV/GLSL.ext.KHR.h7
-rw-r--r--[-rwxr-xr-x]thirdparty/glslang/SPIRV/GlslangToSpv.cpp953
-rw-r--r--[-rwxr-xr-x]thirdparty/glslang/SPIRV/GlslangToSpv.h0
-rw-r--r--thirdparty/glslang/SPIRV/Logger.cpp2
-rw-r--r--thirdparty/glslang/SPIRV/NonSemanticDebugPrintf.h50
-rw-r--r--thirdparty/glslang/SPIRV/SPVRemapper.cpp3
-rw-r--r--thirdparty/glslang/SPIRV/SpvBuilder.cpp194
-rw-r--r--thirdparty/glslang/SPIRV/SpvBuilder.h138
-rw-r--r--thirdparty/glslang/SPIRV/SpvTools.cpp101
-rw-r--r--thirdparty/glslang/SPIRV/SpvTools.h16
-rw-r--r--thirdparty/glslang/SPIRV/disassemble.cpp13
-rw-r--r--thirdparty/glslang/SPIRV/doc.cpp289
-rw-r--r--thirdparty/glslang/SPIRV/doc.h1
-rw-r--r--thirdparty/glslang/SPIRV/hex_float.h4
-rw-r--r--thirdparty/glslang/SPIRV/spirv.hpp200
-rw-r--r--[-rwxr-xr-x]thirdparty/glslang/SPIRV/spvIR.h27
18 files changed, 1655 insertions, 454 deletions
diff --git a/thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp b/thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp
new file mode 100644
index 0000000000..a0790f48f1
--- /dev/null
+++ b/thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp
@@ -0,0 +1,110 @@
+/**
+ This code is based on the glslang_c_interface implementation by Viktor Latypov
+**/
+
+/**
+BSD 2-Clause License
+
+Copyright (c) 2019, Viktor Latypov
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. 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.
+
+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 HOLDER 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.
+**/
+
+#include "glslang/Include/glslang_c_interface.h"
+
+#include "SPIRV/GlslangToSpv.h"
+#include "SPIRV/Logger.h"
+#include "SPIRV/SpvTools.h"
+
+typedef struct glslang_program_s {
+ glslang::TProgram* program;
+ std::vector<unsigned int> spirv;
+ std::string loggerMessages;
+} glslang_program_t;
+
+static EShLanguage c_shader_stage(glslang_stage_t stage)
+{
+ switch (stage) {
+ case GLSLANG_STAGE_VERTEX:
+ return EShLangVertex;
+ case GLSLANG_STAGE_TESSCONTROL:
+ return EShLangTessControl;
+ case GLSLANG_STAGE_TESSEVALUATION:
+ return EShLangTessEvaluation;
+ case GLSLANG_STAGE_GEOMETRY:
+ return EShLangGeometry;
+ case GLSLANG_STAGE_FRAGMENT:
+ return EShLangFragment;
+ case GLSLANG_STAGE_COMPUTE:
+ return EShLangCompute;
+ case GLSLANG_STAGE_RAYGEN_NV:
+ return EShLangRayGen;
+ case GLSLANG_STAGE_INTERSECT_NV:
+ return EShLangIntersect;
+ case GLSLANG_STAGE_ANYHIT_NV:
+ return EShLangAnyHit;
+ case GLSLANG_STAGE_CLOSESTHIT_NV:
+ return EShLangClosestHit;
+ case GLSLANG_STAGE_MISS_NV:
+ return EShLangMiss;
+ case GLSLANG_STAGE_CALLABLE_NV:
+ return EShLangCallable;
+ case GLSLANG_STAGE_TASK_NV:
+ return EShLangTaskNV;
+ case GLSLANG_STAGE_MESH_NV:
+ return EShLangMeshNV;
+ default:
+ break;
+ }
+ return EShLangCount;
+}
+
+GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage)
+{
+ spv::SpvBuildLogger logger;
+ glslang::SpvOptions spvOptions;
+ spvOptions.validate = true;
+
+ const glslang::TIntermediate* intermediate = program->program->getIntermediate(c_shader_stage(stage));
+
+ glslang::GlslangToSpv(*intermediate, program->spirv, &logger, &spvOptions);
+
+ program->loggerMessages = logger.getAllMessages();
+}
+
+GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program) { return program->spirv.size(); }
+
+GLSLANG_EXPORT void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int* out)
+{
+ memcpy(out, program->spirv.data(), program->spirv.size() * sizeof(unsigned int));
+}
+
+GLSLANG_EXPORT unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program)
+{
+ return program->spirv.data();
+}
+
+GLSLANG_EXPORT const char* glslang_program_SPIRV_get_messages(glslang_program_t* program)
+{
+ return program->loggerMessages.empty() ? nullptr : program->loggerMessages.c_str();
+}
diff --git a/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h b/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
index 40164b6187..6eb0eeeada 100644
--- a/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
+++ b/thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
@@ -35,5 +35,6 @@ static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shade
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
static const char* const E_SPV_EXT_fragment_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_shader_atomic_float_add = "SPV_EXT_shader_atomic_float_add";
#endif // #ifndef GLSLextEXT_H
diff --git a/thirdparty/glslang/SPIRV/GLSL.ext.KHR.h b/thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
index e58e836a8d..d783a8f299 100644
--- a/thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
+++ b/thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
@@ -1,5 +1,6 @@
/*
-** Copyright (c) 2014-2016 The Khronos Group Inc.
+** Copyright (c) 2014-2020 The Khronos Group Inc.
+** Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
@@ -44,5 +45,7 @@ static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physi
static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer";
static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock";
static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock";
-
+static const char* const E_SPV_KHR_non_semantic_info = "SPV_KHR_non_semantic_info";
+static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_tracing";
+static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query";
#endif // #ifndef GLSLextKHR_H
diff --git a/thirdparty/glslang/SPIRV/GlslangToSpv.cpp b/thirdparty/glslang/SPIRV/GlslangToSpv.cpp
index 0c8a87e3ce..c85541603f 100755..100644
--- a/thirdparty/glslang/SPIRV/GlslangToSpv.cpp
+++ b/thirdparty/glslang/SPIRV/GlslangToSpv.cpp
@@ -1,7 +1,8 @@
//
// Copyright (C) 2014-2016 LunarG, Inc.
-// Copyright (C) 2015-2018 Google, Inc.
+// Copyright (C) 2015-2020 Google, Inc.
// Copyright (C) 2017 ARM Limited.
+// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
@@ -48,13 +49,16 @@ namespace spv {
#include "GLSL.ext.EXT.h"
#include "GLSL.ext.AMD.h"
#include "GLSL.ext.NV.h"
+ #include "NonSemanticDebugPrintf.h"
}
// Glslang includes
#include "../glslang/MachineIndependent/localintermediate.h"
#include "../glslang/MachineIndependent/SymbolTable.h"
#include "../glslang/Include/Common.h"
-#include "../glslang/Include/revision.h"
+
+// Build-time generated includes
+#include "glslang/build_info.h"
#include <fstream>
#include <iomanip>
@@ -187,7 +191,8 @@ protected:
void makeGlobalInitializers(const glslang::TIntermSequence&);
void visitFunctions(const glslang::TIntermSequence&);
void handleFunctionEntry(const glslang::TIntermAggregate* node);
- void translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments, spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
+ void translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments,
+ spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
void translateArguments(glslang::TIntermUnary& node, std::vector<spv::Id>& arguments);
spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node);
spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*);
@@ -196,28 +201,36 @@ protected:
glslang::TBasicType typeProxy, bool reduceComparison = true);
spv::Id createBinaryMatrixOperation(spv::Op, OpDecorations&, spv::Id typeId, spv::Id left, spv::Id right);
spv::Id createUnaryOperation(glslang::TOperator op, OpDecorations&, spv::Id typeId, spv::Id operand,
- glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
+ glslang::TBasicType typeProxy,
+ const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
spv::Id createUnaryMatrixOperation(spv::Op op, OpDecorations&, spv::Id typeId, spv::Id operand,
glslang::TBasicType typeProxy);
spv::Id createConversion(glslang::TOperator op, OpDecorations&, spv::Id destTypeId, spv::Id operand,
glslang::TBasicType typeProxy);
spv::Id createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize);
spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
- spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
- spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
- spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector<spv::Id>& operands);
- spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
- spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
+ spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId,
+ std::vector<spv::Id>& operands, glslang::TBasicType typeProxy,
+ const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
+ spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands,
+ glslang::TBasicType typeProxy);
+ spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation,
+ spv::Id typeId, std::vector<spv::Id>& operands);
+ spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands,
+ glslang::TBasicType typeProxy);
+ spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId,
+ std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId);
spv::Id getSymbolId(const glslang::TIntermSymbol* node);
void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier);
spv::Id createSpvConstant(const glslang::TIntermTyped&);
- spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant);
+ spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&,
+ int& nextConst, bool specConstant);
bool isTrivialLeaf(const glslang::TIntermTyped* node);
bool isTrivial(const glslang::TIntermTyped* node);
spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right);
spv::Id getExtBuiltins(const char* name);
- std::pair<spv::Id, spv::Id> getForcedType(spv::BuiltIn, const glslang::TType&);
+ std::pair<spv::Id, spv::Id> getForcedType(glslang::TBuiltInVariable builtIn, const glslang::TType&);
spv::Id translateForcedType(spv::Id object);
spv::Id createCompositeConstruct(spv::Id typeId, std::vector<spv::Id> constituents);
@@ -233,15 +246,18 @@ protected:
spv::Builder builder;
bool inEntryPoint;
bool entryPointTerminated;
- bool linkageOnly; // true when visiting the set of objects in the AST present only for establishing interface, whether or not they were statically used
+ bool linkageOnly; // true when visiting the set of objects in the AST present only for
+ // establishing interface, whether or not they were statically used
std::set<spv::Id> iOSet; // all input/output variables from either static use or declaration of interface
const glslang::TIntermediate* glslangIntermediate;
bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp
spv::Id stdBuiltins;
+ spv::Id nonSemanticDebugPrintf;
std::unordered_map<const char*, spv::Id> extBuiltinMap;
std::unordered_map<int, spv::Id> symbolValues;
- std::unordered_set<int> rValueParameters; // set of formal function parameters passed as rValues, rather than a pointer
+ std::unordered_set<int> rValueParameters; // set of formal function parameters passed as rValues,
+ // rather than a pointer
std::unordered_map<std::string, spv::Function*> functionMap;
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):
@@ -267,6 +283,8 @@ spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile
{
#ifdef GLSLANG_WEB
return spv::SourceLanguageESSL;
+#elif defined(GLSLANG_ANGLE)
+ return spv::SourceLanguageGLSL;
#endif
switch (source) {
@@ -299,12 +317,12 @@ spv::ExecutionModel TranslateExecutionModel(EShLanguage stage)
case EShLangTessControl: return spv::ExecutionModelTessellationControl;
case EShLangTessEvaluation: return spv::ExecutionModelTessellationEvaluation;
case EShLangGeometry: return spv::ExecutionModelGeometry;
- case EShLangRayGenNV: return spv::ExecutionModelRayGenerationNV;
- case EShLangIntersectNV: return spv::ExecutionModelIntersectionNV;
- case EShLangAnyHitNV: return spv::ExecutionModelAnyHitNV;
- case EShLangClosestHitNV: return spv::ExecutionModelClosestHitNV;
- case EShLangMissNV: return spv::ExecutionModelMissNV;
- case EShLangCallableNV: return spv::ExecutionModelCallableNV;
+ case EShLangRayGen: return spv::ExecutionModelRayGenerationKHR;
+ case EShLangIntersect: return spv::ExecutionModelIntersectionKHR;
+ case EShLangAnyHit: return spv::ExecutionModelAnyHitKHR;
+ case EShLangClosestHit: return spv::ExecutionModelClosestHitKHR;
+ case EShLangMiss: return spv::ExecutionModelMissKHR;
+ case EShLangCallable: return spv::ExecutionModelCallableKHR;
case EShLangTaskNV: return spv::ExecutionModelTaskNV;
case EShLangMeshNV: return spv::ExecutionModelMeshNV;
#endif
@@ -358,11 +376,11 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
case glslang::EvqVaryingIn: return spv::DecorationBlock;
case glslang::EvqVaryingOut: return spv::DecorationBlock;
#ifndef GLSLANG_WEB
- case glslang::EvqPayloadNV: return spv::DecorationBlock;
- case glslang::EvqPayloadInNV: return spv::DecorationBlock;
- case glslang::EvqHitAttrNV: return spv::DecorationBlock;
- case glslang::EvqCallableDataNV: return spv::DecorationBlock;
- case glslang::EvqCallableDataInNV: return spv::DecorationBlock;
+ case glslang::EvqPayload: return spv::DecorationBlock;
+ case glslang::EvqPayloadIn: return spv::DecorationBlock;
+ case glslang::EvqHitAttr: return spv::DecorationBlock;
+ case glslang::EvqCallableData: return spv::DecorationBlock;
+ case glslang::EvqCallableDataIn: return spv::DecorationBlock;
#endif
default:
assert(0);
@@ -374,7 +392,8 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
}
// Translate glslang type to SPIR-V memory decorations.
-void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector<spv::Decoration>& memory, bool useVulkanMemoryModel)
+void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector<spv::Decoration>& memory,
+ bool useVulkanMemoryModel)
{
if (!useVulkanMemoryModel) {
if (qualifier.isCoherent())
@@ -433,11 +452,11 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T
}
return spv::DecorationMax;
#ifndef GLSLANG_WEB
- case glslang::EvqPayloadNV:
- case glslang::EvqPayloadInNV:
- case glslang::EvqHitAttrNV:
- case glslang::EvqCallableDataNV:
- case glslang::EvqCallableDataInNV:
+ case glslang::EvqPayload:
+ case glslang::EvqPayloadIn:
+ case glslang::EvqHitAttr:
+ case glslang::EvqCallableData:
+ case glslang::EvqCallableDataIn:
return spv::DecorationMax;
#endif
default:
@@ -529,15 +548,11 @@ spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(
if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage)
return mask;
- if (coherentFlags.volatil ||
- coherentFlags.coherent ||
- coherentFlags.devicecoherent ||
- coherentFlags.queuefamilycoherent ||
- coherentFlags.workgroupcoherent ||
- coherentFlags.subgroupcoherent) {
+ if (coherentFlags.isVolatile() || coherentFlags.anyCoherent()) {
mask = mask | spv::MemoryAccessMakePointerAvailableKHRMask |
spv::MemoryAccessMakePointerVisibleKHRMask;
}
+
if (coherentFlags.nonprivate) {
mask = mask | spv::MemoryAccessNonPrivatePointerKHRMask;
}
@@ -562,11 +577,7 @@ spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(
return mask;
if (coherentFlags.volatil ||
- coherentFlags.coherent ||
- coherentFlags.devicecoherent ||
- coherentFlags.queuefamilycoherent ||
- coherentFlags.workgroupcoherent ||
- coherentFlags.subgroupcoherent) {
+ coherentFlags.anyCoherent()) {
mask = mask | spv::ImageOperandsMakeTexelAvailableKHRMask |
spv::ImageOperandsMakeTexelVisibleKHRMask;
}
@@ -595,14 +606,11 @@ spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCohere
flags.workgroupcoherent = type.getQualifier().workgroupcoherent ||
type.getQualifier().storage == glslang::EvqShared;
flags.subgroupcoherent = type.getQualifier().subgroupcoherent;
+ flags.shadercallcoherent = type.getQualifier().shadercallcoherent;
flags.volatil = type.getQualifier().volatil;
// *coherent variables are implicitly nonprivate in GLSL
flags.nonprivate = type.getQualifier().nonprivate ||
- flags.subgroupcoherent ||
- flags.workgroupcoherent ||
- flags.queuefamilycoherent ||
- flags.devicecoherent ||
- flags.coherent ||
+ flags.anyCoherent() ||
flags.volatil;
flags.isImage = type.getBasicType() == glslang::EbtSampler;
#endif
@@ -626,6 +634,8 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(
scope = spv::ScopeWorkgroup;
} else if (coherentFlags.subgroupcoherent) {
scope = spv::ScopeSubgroup;
+ } else if (coherentFlags.shadercallcoherent) {
+ scope = spv::ScopeShaderCallKHR;
}
if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) {
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
@@ -640,7 +650,8 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(
// is generated only when using the variable in an executable instruction, but not when
// just declaring a struct member variable with it. This is true for PointSize,
// ClipDistance, and CullDistance.
-spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn, bool memberDeclaration)
+spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn,
+ bool memberDeclaration)
{
switch (builtIn) {
case glslang::EbvPointSize:
@@ -933,34 +944,38 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
return spv::BuiltInInvocationsPerPixelNV;
// ray tracing
- case glslang::EbvLaunchIdNV:
- return spv::BuiltInLaunchIdNV;
- case glslang::EbvLaunchSizeNV:
- return spv::BuiltInLaunchSizeNV;
- case glslang::EbvWorldRayOriginNV:
- return spv::BuiltInWorldRayOriginNV;
- case glslang::EbvWorldRayDirectionNV:
- return spv::BuiltInWorldRayDirectionNV;
- case glslang::EbvObjectRayOriginNV:
- return spv::BuiltInObjectRayOriginNV;
- case glslang::EbvObjectRayDirectionNV:
- return spv::BuiltInObjectRayDirectionNV;
- case glslang::EbvRayTminNV:
- return spv::BuiltInRayTminNV;
- case glslang::EbvRayTmaxNV:
- return spv::BuiltInRayTmaxNV;
- case glslang::EbvInstanceCustomIndexNV:
- return spv::BuiltInInstanceCustomIndexNV;
- case glslang::EbvHitTNV:
- return spv::BuiltInHitTNV;
- case glslang::EbvHitKindNV:
- return spv::BuiltInHitKindNV;
- case glslang::EbvObjectToWorldNV:
- return spv::BuiltInObjectToWorldNV;
- case glslang::EbvWorldToObjectNV:
- return spv::BuiltInWorldToObjectNV;
- case glslang::EbvIncomingRayFlagsNV:
- return spv::BuiltInIncomingRayFlagsNV;
+ case glslang::EbvLaunchId:
+ return spv::BuiltInLaunchIdKHR;
+ case glslang::EbvLaunchSize:
+ return spv::BuiltInLaunchSizeKHR;
+ case glslang::EbvWorldRayOrigin:
+ return spv::BuiltInWorldRayOriginKHR;
+ case glslang::EbvWorldRayDirection:
+ return spv::BuiltInWorldRayDirectionKHR;
+ case glslang::EbvObjectRayOrigin:
+ return spv::BuiltInObjectRayOriginKHR;
+ case glslang::EbvObjectRayDirection:
+ return spv::BuiltInObjectRayDirectionKHR;
+ case glslang::EbvRayTmin:
+ return spv::BuiltInRayTminKHR;
+ case glslang::EbvRayTmax:
+ return spv::BuiltInRayTmaxKHR;
+ case glslang::EbvInstanceCustomIndex:
+ return spv::BuiltInInstanceCustomIndexKHR;
+ case glslang::EbvHitT:
+ return spv::BuiltInHitTKHR;
+ case glslang::EbvHitKind:
+ return spv::BuiltInHitKindKHR;
+ case glslang::EbvObjectToWorld:
+ case glslang::EbvObjectToWorld3x4:
+ return spv::BuiltInObjectToWorldKHR;
+ case glslang::EbvWorldToObject:
+ case glslang::EbvWorldToObject3x4:
+ return spv::BuiltInWorldToObjectKHR;
+ case glslang::EbvIncomingRayFlags:
+ return spv::BuiltInIncomingRayFlagsKHR;
+ case glslang::EbvGeometryIndex:
+ return spv::BuiltInRayGeometryIndexKHR;
// barycentrics
case glslang::EbvBaryCoordNV:
@@ -1106,7 +1121,8 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
}
}
-spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(const glslang::TIntermSelection& selectionNode) const
+spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(
+ const glslang::TIntermSelection& selectionNode) const
{
if (selectionNode.getFlatten())
return spv::SelectionControlFlattenMask;
@@ -1115,7 +1131,8 @@ spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(cons
return spv::SelectionControlMaskNone;
}
-spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const glslang::TIntermSwitch& switchNode) const
+spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const glslang::TIntermSwitch& switchNode)
+ const
{
if (switchNode.getFlatten())
return spv::SelectionControlFlattenMask;
@@ -1169,6 +1186,8 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang:
// Translate glslang type to SPIR-V storage class.
spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::TType& type)
{
+ if (type.getBasicType() == glslang::EbtRayQuery)
+ return spv::StorageClassFunction;
if (type.getQualifier().isPipeInput())
return spv::StorageClassInput;
if (type.getQualifier().isPipeOutput())
@@ -1183,8 +1202,8 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
}
if (type.getQualifier().isUniformOrBuffer() &&
- type.getQualifier().isShaderRecordNV()) {
- return spv::StorageClassShaderRecordBufferNV;
+ type.getQualifier().isShaderRecord()) {
+ return spv::StorageClassShaderRecordBufferKHR;
}
if (glslangIntermediate->usingStorageBuffer() && type.getQualifier().storage == glslang::EvqBuffer) {
@@ -1206,11 +1225,11 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
case glslang::EvqTemporary: return spv::StorageClassFunction;
case glslang::EvqShared: return spv::StorageClassWorkgroup;
#ifndef GLSLANG_WEB
- case glslang::EvqPayloadNV: return spv::StorageClassRayPayloadNV;
- case glslang::EvqPayloadInNV: return spv::StorageClassIncomingRayPayloadNV;
- case glslang::EvqHitAttrNV: return spv::StorageClassHitAttributeNV;
- case glslang::EvqCallableDataNV: return spv::StorageClassCallableDataNV;
- case glslang::EvqCallableDataInNV: return spv::StorageClassIncomingCallableDataNV;
+ case glslang::EvqPayload: return spv::StorageClassRayPayloadKHR;
+ case glslang::EvqPayloadIn: return spv::StorageClassIncomingRayPayloadKHR;
+ case glslang::EvqHitAttr: return spv::StorageClassHitAttributeKHR;
+ case glslang::EvqCallableData: return spv::StorageClassCallableDataKHR;
+ case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR;
#endif
default:
assert(0);
@@ -1270,14 +1289,15 @@ bool IsDescriptorResource(const glslang::TType& type)
// uniform and buffer blocks are included, unless it is a push_constant
if (type.getBasicType() == glslang::EbtBlock)
return type.getQualifier().isUniformOrBuffer() &&
- ! type.getQualifier().isShaderRecordNV() &&
+ ! type.getQualifier().isShaderRecord() &&
! type.getQualifier().isPushConstant();
// non block...
// basically samplerXXX/subpass/sampler/texture are all included
// if they are the global-scope-class, not the function parameter
// (or local, if they ever exist) class.
- if (type.getBasicType() == glslang::EbtSampler)
+ if (type.getBasicType() == glslang::EbtSampler ||
+ type.getBasicType() == glslang::EbtAccStruct)
return type.getQualifier().isUniformOrBuffer();
// None of the above.
@@ -1320,6 +1340,8 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa
child.workgroupcoherent = true;
if (parent.subgroupcoherent)
child.subgroupcoherent = true;
+ if (parent.shadercallcoherent)
+ child.shadercallcoherent = true;
if (parent.nonprivate)
child.nonprivate = true;
if (parent.volatil)
@@ -1350,16 +1372,18 @@ bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifie
// Implement the TGlslangToSpvTraverser class.
//
-TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const glslang::TIntermediate* glslangIntermediate,
- spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options)
- : TIntermTraverser(true, false, true),
- options(options),
- shaderEntry(nullptr), currentFunction(nullptr),
- sequenceDepth(0), logger(buildLogger),
- builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger),
- inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
- glslangIntermediate(glslangIntermediate),
- nanMinMaxClamp(glslangIntermediate->getNanMinMaxClamp())
+TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
+ const glslang::TIntermediate* glslangIntermediate,
+ spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options) :
+ TIntermTraverser(true, false, true),
+ options(options),
+ shaderEntry(nullptr), currentFunction(nullptr),
+ sequenceDepth(0), logger(buildLogger),
+ builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger),
+ inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
+ glslangIntermediate(glslangIntermediate),
+ nanMinMaxClamp(glslangIntermediate->getNanMinMaxClamp()),
+ nonSemanticDebugPrintf(0)
{
spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage());
@@ -1402,7 +1426,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT;
builder.addIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer, spv::Spv_1_5);
builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT);
- };
+ }
if (glslangIntermediate->usingVulkanMemoryModel()) {
memoryModel = spv::MemoryModelVulkanKHR;
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
@@ -1429,6 +1453,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb);
}
+ if (glslangIntermediate->getLayoutPrimitiveCulling()) {
+ builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR);
+ }
+
unsigned int mode;
switch (glslangIntermediate->getStage()) {
case EShLangVertex:
@@ -1458,6 +1486,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
#ifndef GLSLANG_WEB
+
switch(glslangIntermediate->getDepth()) {
case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break;
case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break;
@@ -1495,7 +1524,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock);
}
#endif
- break;
+ break;
case EShLangCompute:
builder.addCapability(spv::CapabilityShader);
@@ -1520,7 +1549,8 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
glslang::TLayoutGeometry primitive;
if (glslangIntermediate->getStage() == EShLangTessControl) {
- builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
+ builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices,
+ glslangIntermediate->getVertices());
primitive = glslangIntermediate->getOutputPrimitive();
} else {
primitive = glslangIntermediate->getInputPrimitive();
@@ -1582,15 +1612,24 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
break;
- case EShLangRayGenNV:
- case EShLangIntersectNV:
- case EShLangAnyHitNV:
- case EShLangClosestHitNV:
- case EShLangMissNV:
- case EShLangCallableNV:
- builder.addCapability(spv::CapabilityRayTracingNV);
- builder.addExtension("SPV_NV_ray_tracing");
+ case EShLangRayGen:
+ case EShLangIntersect:
+ case EShLangAnyHit:
+ case EShLangClosestHit:
+ case EShLangMiss:
+ case EShLangCallable:
+ {
+ auto& extensions = glslangIntermediate->getRequestedExtensions();
+ if (extensions.find("GL_NV_ray_tracing") == extensions.end()) {
+ builder.addCapability(spv::CapabilityRayTracingProvisionalKHR);
+ builder.addExtension("SPV_KHR_ray_tracing");
+ }
+ else {
+ builder.addCapability(spv::CapabilityRayTracingNV);
+ builder.addExtension("SPV_NV_ray_tracing");
+ }
break;
+ }
case EShLangTaskNV:
case EShLangMeshNV:
builder.addCapability(spv::CapabilityMeshShadingNV);
@@ -1599,8 +1638,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
if (glslangIntermediate->getStage() == EShLangMeshNV) {
- builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
- builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV, glslangIntermediate->getPrimitives());
+ builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices,
+ glslangIntermediate->getVertices());
+ builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV,
+ glslangIntermediate->getPrimitives());
switch (glslangIntermediate->getOutputPrimitive()) {
case glslang::ElgPoints: mode = spv::ExecutionModeOutputPoints; break;
@@ -1674,20 +1715,24 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
spv::Id id = getSymbolId(symbol);
if (builder.isPointer(id)) {
- // Include all "static use" and "linkage only" interface variables on the OpEntryPoint instruction
- // Consider adding to the OpEntryPoint interface list.
- // Only looking at structures if they have at least one member.
- if (!symbol->getType().isStruct() || symbol->getType().getStruct()->size() > 0) {
- spv::StorageClass sc = builder.getStorageClass(id);
- // Before SPIR-V 1.4, we only want to include Input and Output.
- // Starting with SPIR-V 1.4, we want all globals.
- if ((glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4 && sc != spv::StorageClassFunction) ||
- (sc == spv::StorageClassInput || sc == spv::StorageClassOutput)) {
- iOSet.insert(id);
+ if (!symbol->getType().getQualifier().isParamInput() &&
+ !symbol->getType().getQualifier().isParamOutput()) {
+ // Include all "static use" and "linkage only" interface variables on the OpEntryPoint instruction
+ // Consider adding to the OpEntryPoint interface list.
+ // Only looking at structures if they have at least one member.
+ if (!symbol->getType().isStruct() || symbol->getType().getStruct()->size() > 0) {
+ spv::StorageClass sc = builder.getStorageClass(id);
+ // Before SPIR-V 1.4, we only want to include Input and Output.
+ // Starting with SPIR-V 1.4, we want all globals.
+ if ((glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4 && builder.isGlobalStorage(id)) ||
+ (sc == spv::StorageClassInput || sc == spv::StorageClassOutput)) {
+ iOSet.insert(id);
+ }
}
}
- // If the SPIR-V type is required to be different than the AST type,
+ // If the SPIR-V type is required to be different than the AST type
+ // (for ex SubgroupMasks or 3x4 ObjectToWorld/WorldToObject matrices),
// translate now from the SPIR-V type to the AST type, for the consuming
// operation.
// Note this turns it from an l-value to an r-value.
@@ -1847,7 +1892,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
int dummySize;
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
TranslateCoherent(node->getLeft()->getType()),
- glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
+ glslangIntermediate->getBaseAlignmentScalar(
+ node->getLeft()->getType(), dummySize));
} else {
// Load through a block reference is performed with a dot operator that
@@ -1877,7 +1923,9 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
}
// normal case for indexing array or structure or block
- builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(node->getLeft()->getType()), node->getLeft()->getType().getBufferReferenceAlignment());
+ builder.accessChainPush(builder.makeIntConstant(spvIndex),
+ TranslateCoherent(node->getLeft()->getType()),
+ node->getLeft()->getType().getBufferReferenceAlignment());
// Add capabilities here for accessing PointSize and clip/cull distance.
// We have deferred generation of associated capabilities until now.
@@ -1914,9 +1962,11 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
int dummySize;
builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()),
TranslateCoherent(node->getLeft()->getType()),
- glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
+ glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(),
+ dummySize));
} else
- builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()), node->getLeft()->getType().getBufferReferenceAlignment());
+ builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()),
+ node->getLeft()->getType().getBufferReferenceAlignment());
}
return false;
case glslang::EOpVectorSwizzle:
@@ -1927,7 +1977,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
int dummySize;
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
TranslateCoherent(node->getLeft()->getType()),
- glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
+ glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(),
+ dummySize));
}
return false;
case glslang::EOpMatrixSwizzle:
@@ -1943,7 +1994,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
if (isTrivial(node->getRight()->getAsTyped()))
break; // handle below as a normal binary operation
// otherwise, we need to do dynamic short circuiting on the right operand
- spv::Id result = createShortCircuit(node->getOp(), *node->getLeft()->getAsTyped(), *node->getRight()->getAsTyped());
+ spv::Id result = createShortCircuit(node->getOp(), *node->getLeft()->getAsTyped(),
+ *node->getRight()->getAsTyped());
builder.clearAccessChain();
builder.setAccessChainRValue(result);
}
@@ -1985,16 +2037,16 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
// 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>.
// Also see comment for 'forceType', regarding tracking SPIR-V-required types.
-std::pair<spv::Id, spv::Id> TGlslangToSpvTraverser::getForcedType(spv::BuiltIn builtIn,
+std::pair<spv::Id, spv::Id> TGlslangToSpvTraverser::getForcedType(glslang::TBuiltInVariable glslangBuiltIn,
const glslang::TType& glslangType)
{
- switch(builtIn)
+ switch(glslangBuiltIn)
{
- case spv::BuiltInSubgroupEqMask:
- case spv::BuiltInSubgroupGeMask:
- case spv::BuiltInSubgroupGtMask:
- case spv::BuiltInSubgroupLeMask:
- case spv::BuiltInSubgroupLtMask: {
+ case glslang::EbvSubGroupEqMask:
+ case glslang::EbvSubGroupGeMask:
+ case glslang::EbvSubGroupGtMask:
+ case glslang::EbvSubGroupLeMask:
+ case glslang::EbvSubGroupLtMask: {
// these require changing a 64-bit scaler -> a vector of 32-bit components
if (glslangType.isVector())
break;
@@ -2002,6 +2054,15 @@ std::pair<spv::Id, spv::Id> TGlslangToSpvTraverser::getForcedType(spv::BuiltIn b
builder.makeUintType(64));
return ret;
}
+ // There are no SPIR-V builtins defined for these and map onto original non-transposed
+ // builtins. During visitBinary we insert a transpose
+ case glslang::EbvWorldToObject3x4:
+ case glslang::EbvObjectToWorld3x4: {
+ spv::Id mat43 = builder.makeMatrixType(builder.makeFloatType(32), 4, 3);
+ spv::Id mat34 = builder.makeMatrixType(builder.makeFloatType(32), 3, 4);
+ std::pair<spv::Id, spv::Id> ret(mat43, mat34);
+ return ret;
+ }
default:
break;
}
@@ -2040,7 +2101,15 @@ spv::Id TGlslangToSpvTraverser::translateForcedType(spv::Id object)
} else {
logger->missingFunctionality("forcing 32-bit vector type to non 64-bit scalar");
}
- } else {
+ } else if (builder.isMatrixType(objectTypeId)) {
+ // There are no SPIR-V builtins defined for 3x4 variants of ObjectToWorld/WorldToObject
+ // and we insert a transpose after loading the original non-transposed builtins
+ builder.clearAccessChain();
+ builder.setAccessChainLValue(object);
+ object = builder.accessChainLoad(spv::NoPrecision, spv::DecorationMax, objectTypeId);
+ return builder.createUnaryOp(spv::OpTranspose, desiredTypeId, object);
+
+ } else {
logger->missingFunctionality("forcing non 32-bit vector type");
}
@@ -2091,7 +2160,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
} else {
glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft();
block->traverse(this);
- unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()->getConstArray()[0].getUConst();
+ unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()
+ ->getConstArray()[0].getUConst();
length = builder.createArrayLength(builder.accessChainGetLValue(), member);
}
@@ -2117,7 +2187,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
// Does it need a swizzle inversion? If so, evaluation is inverted;
// operate first on the swizzle base, then apply the swizzle.
spv::Id invertedType = spv::NoType;
- auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? invertedType : convertGlslangToSpvType(node->getType()); };
+ auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ?
+ invertedType : convertGlslangToSpvType(node->getType()); };
if (node->getOp() == glslang::EOpInterpolateAtCentroid)
invertedType = getInvertedSwizzleType(*node->getOperand());
@@ -2138,7 +2209,15 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
if (node->getOp() == glslang::EOpAtomicCounterIncrement ||
node->getOp() == glslang::EOpAtomicCounterDecrement ||
node->getOp() == glslang::EOpAtomicCounter ||
- node->getOp() == glslang::EOpInterpolateAtCentroid) {
+ node->getOp() == glslang::EOpInterpolateAtCentroid ||
+ node->getOp() == glslang::EOpRayQueryProceed ||
+ node->getOp() == glslang::EOpRayQueryGetRayTMin ||
+ node->getOp() == glslang::EOpRayQueryGetRayFlags ||
+ node->getOp() == glslang::EOpRayQueryGetWorldRayOrigin ||
+ node->getOp() == glslang::EOpRayQueryGetWorldRayDirection ||
+ node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque ||
+ node->getOp() == glslang::EOpRayQueryTerminate ||
+ node->getOp() == glslang::EOpRayQueryConfirmIntersection) {
operand = builder.accessChainGetLValue(); // Special case l-value operands
lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType());
@@ -2154,11 +2233,13 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
// it could be a conversion
if (! result)
- result = createConversion(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType());
+ result = createConversion(node->getOp(), decorations, resultType(), operand,
+ node->getOperand()->getBasicType());
// if not, then possibly an operation
if (! result)
- result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType(), lvalueCoherentFlags);
+ result = createUnaryOperation(node->getOp(), decorations, resultType(), operand,
+ node->getOperand()->getBasicType(), lvalueCoherentFlags);
if (result) {
if (invertedType) {
@@ -2229,6 +2310,12 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
case glslang::EOpEndStreamPrimitive:
builder.createNoResultOp(spv::OpEndStreamPrimitive, operand);
return false;
+ case glslang::EOpRayQueryTerminate:
+ builder.createNoResultOp(spv::OpRayQueryTerminateKHR, operand);
+ return false;
+ case glslang::EOpRayQueryConfirmIntersection:
+ builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR, operand);
+ return false;
#endif
default:
@@ -2251,7 +2338,8 @@ spv::Id TGlslangToSpvTraverser::createCompositeConstruct(spv::Id resultTypeId, s
std::vector<spv::Id> rTypeConstituents;
int numrTypeConstituents = builder.getNumTypeConstituents(rType);
for (int i = 0; i < numrTypeConstituents; ++i) {
- rTypeConstituents.push_back(builder.createCompositeExtract(constituent, builder.getContainedTypeId(rType, i), i));
+ rTypeConstituents.push_back(builder.createCompositeExtract(constituent,
+ builder.getContainedTypeId(rType, i), i));
}
constituents[c] = createCompositeConstruct(lType, rTypeConstituents);
} else {
@@ -2277,8 +2365,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
spv::Id result = spv::NoResult;
- spv::Id invertedType = spv::NoType; // to use to override the natural type of the node
- auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? invertedType : convertGlslangToSpvType(node->getType()); };
+ spv::Id invertedType = spv::NoType; // to use to override the natural type of the node
+ std::vector<spv::Builder::AccessChain> complexLvalues; // for holding swizzling l-values too complex for
+ // SPIR-V, for an out parameter
+ std::vector<spv::Id> temporaryLvalues; // temporaries to pass, as proxies for complexLValues
+
+ auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ?
+ invertedType :
+ convertGlslangToSpvType(node->getType()); };
// try texturing
result = createImageTextureFunctionCall(node);
@@ -2382,7 +2476,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
if (node->isUserDefined())
result = handleUserFunctionCall(node);
- // assert(result); // this can happen for bad shaders because the call graph completeness checking is not yet done
if (result) {
builder.clearAccessChain();
builder.setAccessChainRValue(result);
@@ -2633,13 +2726,43 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
binOp = node->getOp();
break;
- case glslang::EOpIgnoreIntersectionNV:
- case glslang::EOpTerminateRayNV:
- case glslang::EOpTraceNV:
- case glslang::EOpExecuteCallableNV:
+ case glslang::EOpIgnoreIntersection:
+ case glslang::EOpTerminateRay:
+ case glslang::EOpTrace:
+ case glslang::EOpExecuteCallable:
case glslang::EOpWritePackedPrimitiveIndices4x8NV:
noReturnValue = true;
break;
+ case glslang::EOpRayQueryInitialize:
+ case glslang::EOpRayQueryTerminate:
+ case glslang::EOpRayQueryGenerateIntersection:
+ case glslang::EOpRayQueryConfirmIntersection:
+ builder.addExtension("SPV_KHR_ray_query");
+ builder.addCapability(spv::CapabilityRayQueryProvisionalKHR);
+ noReturnValue = true;
+ break;
+ case glslang::EOpRayQueryProceed:
+ case glslang::EOpRayQueryGetIntersectionType:
+ case glslang::EOpRayQueryGetRayTMin:
+ case glslang::EOpRayQueryGetRayFlags:
+ case glslang::EOpRayQueryGetIntersectionT:
+ case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex:
+ case glslang::EOpRayQueryGetIntersectionInstanceId:
+ case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
+ case glslang::EOpRayQueryGetIntersectionGeometryIndex:
+ case glslang::EOpRayQueryGetIntersectionPrimitiveIndex:
+ case glslang::EOpRayQueryGetIntersectionBarycentrics:
+ case glslang::EOpRayQueryGetIntersectionFrontFace:
+ case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque:
+ case glslang::EOpRayQueryGetIntersectionObjectRayDirection:
+ case glslang::EOpRayQueryGetIntersectionObjectRayOrigin:
+ case glslang::EOpRayQueryGetWorldRayDirection:
+ case glslang::EOpRayQueryGetWorldRayOrigin:
+ case glslang::EOpRayQueryGetIntersectionObjectToWorld:
+ case glslang::EOpRayQueryGetIntersectionWorldToObject:
+ builder.addExtension("SPV_KHR_ray_query");
+ builder.addCapability(spv::CapabilityRayQueryProvisionalKHR);
+ break;
case glslang::EOpCooperativeMatrixLoad:
case glslang::EOpCooperativeMatrixStore:
noReturnValue = true;
@@ -2651,6 +2774,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
break;
#endif
+ case glslang::EOpDebugPrintf:
+ noReturnValue = true;
+ break;
+
default:
break;
}
@@ -2702,6 +2829,28 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
lvalue = true;
break;
+ case glslang::EOpRayQueryInitialize:
+ case glslang::EOpRayQueryTerminate:
+ case glslang::EOpRayQueryConfirmIntersection:
+ case glslang::EOpRayQueryProceed:
+ case glslang::EOpRayQueryGenerateIntersection:
+ case glslang::EOpRayQueryGetIntersectionType:
+ case glslang::EOpRayQueryGetIntersectionT:
+ case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex:
+ case glslang::EOpRayQueryGetIntersectionInstanceId:
+ case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
+ case glslang::EOpRayQueryGetIntersectionGeometryIndex:
+ case glslang::EOpRayQueryGetIntersectionPrimitiveIndex:
+ case glslang::EOpRayQueryGetIntersectionBarycentrics:
+ case glslang::EOpRayQueryGetIntersectionFrontFace:
+ case glslang::EOpRayQueryGetIntersectionObjectRayDirection:
+ case glslang::EOpRayQueryGetIntersectionObjectRayOrigin:
+ case glslang::EOpRayQueryGetIntersectionObjectToWorld:
+ case glslang::EOpRayQueryGetIntersectionWorldToObject:
+ if (arg == 0)
+ lvalue = true;
+ break;
+
case glslang::EOpAtomicAdd:
case glslang::EOpAtomicMin:
case glslang::EOpAtomicMax:
@@ -2727,9 +2876,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
// Does it need a swizzle inversion? If so, evaluation is inverted;
// operate first on the swizzle base, then apply the swizzle.
+ // That is, we transform
+ //
+ // interpolate(v.zy) -> interpolate(v).zy
+ //
if (glslangOperands[0]->getAsOperator() &&
glslangOperands[0]->getAsOperator()->getOp() == glslang::EOpVectorSwizzle)
- invertedType = convertGlslangToSpvType(glslangOperands[0]->getAsBinaryNode()->getLeft()->getType());
+ invertedType = convertGlslangToSpvType(
+ glslangOperands[0]->getAsBinaryNode()->getLeft()->getType());
}
break;
case glslang::EOpAtomicLoad:
@@ -2789,8 +2943,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
builder.setAccessChain(save);
// Point to the first element of the array.
- builder.accessChainPush(elementId, TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()),
- glslangOperands[arg]->getAsTyped()->getType().getBufferReferenceAlignment());
+ builder.accessChainPush(elementId,
+ TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()),
+ glslangOperands[arg]->getAsTyped()->getType().getBufferReferenceAlignment());
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
unsigned int alignment = builder.getAccessChain().alignment;
@@ -2800,7 +2955,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
memoryAccess &= ~spv::MemoryAccessMakePointerAvailableKHRMask;
if (node->getOp() == glslang::EOpCooperativeMatrixStore)
memoryAccess &= ~spv::MemoryAccessMakePointerVisibleKHRMask;
- if (builder.getStorageClass(builder.getAccessChain().base) == spv::StorageClassPhysicalStorageBufferEXT) {
+ if (builder.getStorageClass(builder.getAccessChain().base) ==
+ spv::StorageClassPhysicalStorageBufferEXT) {
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
}
@@ -2810,8 +2966,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
memoryAccessOperands.push_back(spv::IdImmediate(false, alignment));
}
- if (memoryAccess & (spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask)) {
- memoryAccessOperands.push_back(spv::IdImmediate(true, builder.makeUintConstant(TranslateMemoryScope(coherentFlags))));
+ if (memoryAccess &
+ (spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask)) {
+ memoryAccessOperands.push_back(spv::IdImmediate(true,
+ builder.makeUintConstant(TranslateMemoryScope(coherentFlags))));
}
} else if (arg == 2) {
continue;
@@ -2819,13 +2977,48 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
}
#endif
+ // for l-values, pass the address, for r-values, pass the value
if (lvalue) {
- operands.push_back(builder.accessChainGetLValue());
+ if (invertedType == spv::NoType && !builder.isSpvLvalue()) {
+ // SPIR-V cannot represent an l-value containing a swizzle that doesn't
+ // reduce to a simple access chain. So, we need a temporary vector to
+ // receive the result, and must later swizzle that into the original
+ // l-value.
+ complexLvalues.push_back(builder.getAccessChain());
+ temporaryLvalues.push_back(builder.createVariable(
+ spv::NoPrecision, spv::StorageClassFunction,
+ builder.accessChainGetInferredType(), "swizzleTemp"));
+ operands.push_back(temporaryLvalues.back());
+ } else {
+ operands.push_back(builder.accessChainGetLValue());
+ }
lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
lvalueCoherentFlags |= TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType());
} else {
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
- operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
+ glslang::TOperator glslangOp = node->getOp();
+ if (arg == 1 &&
+ (glslangOp == glslang::EOpRayQueryGetIntersectionType ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionT ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionInstanceCustomIndex ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionInstanceId ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionGeometryIndex ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionPrimitiveIndex ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionBarycentrics ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionFrontFace ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionObjectRayDirection ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionObjectRayOrigin ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionObjectToWorld ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionWorldToObject
+ )) {
+ bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst();
+ operands.push_back(builder.makeIntConstant(cond ? 1 : 0));
+ }
+ else {
+ operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
+ }
+
}
}
@@ -2861,7 +3054,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
#endif
if (atomic) {
// Handle all atomics
- result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags);
+ result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(),
+ lvalueCoherentFlags);
+ } else if (node->getOp() == glslang::EOpDebugPrintf) {
+ if (!nonSemanticDebugPrintf) {
+ nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf");
+ }
+ result = builder.createBuiltinCall(builder.makeVoidType(), nonSemanticDebugPrintf, spv::NonSemanticDebugPrintfDebugPrintf, operands);
+ builder.addExtension(spv::E_SPV_KHR_non_semantic_info);
} else {
// Pass through to generic operations.
switch (glslangOperands.size()) {
@@ -2883,8 +3083,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
result = createMiscOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
break;
}
- if (invertedType)
+
+ if (invertedType != spv::NoResult)
result = createInvertedSwizzle(precision, *glslangOperands[0]->getAsBinaryNode(), result);
+
+ for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) {
+ builder.setAccessChain(complexLvalues[i]);
+ builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision));
+ }
}
if (noReturnValue)
@@ -3000,7 +3206,8 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
} else {
// We need control flow to select the result.
// TODO: Once SPIR-V OpSelect allows arbitrary types, eliminate this path.
- result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
+ result = builder.createVariable(TranslatePrecisionDecoration(node->getType()),
+ spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
// Selection control:
const spv::SelectionControlMask control = TranslateSelectionControl(*node);
@@ -3025,8 +3232,10 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
// Execute the one side needed, as per the condition
const auto executeOneSide = [&]() {
// Always emit control flow.
- if (node->getBasicType() != glslang::EbtVoid)
- result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
+ if (node->getBasicType() != glslang::EbtVoid) {
+ result = builder.createVariable(TranslatePrecisionDecoration(node->getType()), spv::StorageClassFunction,
+ convertGlslangToSpvType(node->getType()));
+ }
// Selection control:
const spv::SelectionControlMask control = TranslateSelectionControl(*node);
@@ -3091,7 +3300,8 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
defaultSegment = (int)codeSegments.size();
else if (child->getAsBranchNode() && child->getAsBranchNode()->getFlowOp() == glslang::EOpCase) {
valueIndexToSegment[caseValues.size()] = (int)codeSegments.size();
- caseValues.push_back(child->getAsBranchNode()->getExpression()->getAsConstantUnion()->getConstArray()[0].getIConst());
+ caseValues.push_back(child->getAsBranchNode()->getExpression()->getAsConstantUnion()
+ ->getConstArray()[0].getIConst());
} else
codeSegments.push_back(child);
}
@@ -3104,7 +3314,8 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
// make the switch statement
std::vector<spv::Block*> segmentBlocks; // returned, as the blocks allocated in the call
- builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, segmentBlocks);
+ builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment,
+ segmentBlocks);
// emit all the code in the segments
breakForLoop.push(false);
@@ -3221,15 +3432,17 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
builder.createLoopContinue();
break;
case glslang::EOpReturn:
- if (node->getExpression()) {
+ if (node->getExpression() != nullptr) {
const glslang::TType& glslangReturnType = node->getExpression()->getType();
spv::Id returnId = accessChainLoad(glslangReturnType);
- if (builder.getTypeId(returnId) != currentFunction->getReturnType()) {
+ if (builder.getTypeId(returnId) != currentFunction->getReturnType() ||
+ TranslatePrecisionDecoration(glslangReturnType) != currentFunction->getReturnPrecision()) {
builder.clearAccessChain();
- spv::Id copyId = builder.createVariable(spv::StorageClassFunction, currentFunction->getReturnType());
+ spv::Id copyId = builder.createVariable(currentFunction->getReturnPrecision(),
+ spv::StorageClassFunction, currentFunction->getReturnType());
builder.setAccessChainLValue(copyId);
multiTypeStore(glslangReturnType, returnId);
- returnId = builder.createLoad(copyId);
+ returnId = builder.createLoad(copyId, currentFunction->getReturnPrecision());
}
builder.makeReturn(false, returnId);
} else
@@ -3325,7 +3538,18 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
if (glslang::IsAnonymous(name))
name = "";
- return builder.createVariable(storageClass, spvType, name);
+ spv::Id initializer = spv::NoResult;
+
+ if (node->getType().getQualifier().storage == glslang::EvqUniform &&
+ !node->getConstArray().empty()) {
+ int nextConst = 0;
+ initializer = createSpvConstantFromConstUnionArray(node->getType(),
+ node->getConstArray(),
+ nextConst,
+ false /* specConst */);
+ }
+
+ return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer);
}
// Return type Id of the sampled type.
@@ -3361,7 +3585,8 @@ spv::Id TGlslangToSpvTraverser::getInvertedSwizzleType(const glslang::TIntermTyp
// When inverting a swizzle with a parent op, this function
// will apply the swizzle operation to a completed parent operation.
-spv::Id TGlslangToSpvTraverser::createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped& node, spv::Id parentResult)
+spv::Id TGlslangToSpvTraverser::createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped& node,
+ spv::Id parentResult)
{
std::vector<unsigned> swizzle;
convertSwizzle(*node.getAsBinaryNode()->getRight()->getAsAggregate(), swizzle);
@@ -3444,8 +3669,11 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
builder.addCapability(spv::CapabilityAtomicStorage);
spvType = builder.makeUintType(32);
break;
- case glslang::EbtAccStructNV:
- spvType = builder.makeAccelerationStructureNVType();
+ case glslang::EbtAccStruct:
+ spvType = builder.makeAccelerationStructureType();
+ break;
+ case glslang::EbtRayQuery:
+ spvType = builder.makeRayQueryType();
break;
case glslang::EbtReference:
{
@@ -3501,6 +3729,9 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier);
}
break;
+ case glslang::EbtString:
+ // no type used for OpString
+ return 0;
default:
assert(0);
break;
@@ -3626,7 +3857,8 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
{
// Create a vector of struct types for SPIR-V to consume
std::vector<spv::Id> spvMembers;
- int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
+ int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0,
+ // except sometimes for blocks
std::vector<std::pair<glslang::TType*, glslang::TQualifier> > deferredForwardPointers;
for (int i = 0; i < (int)glslangMembers->size(); i++) {
glslang::TType& glslangMember = *(*glslangMembers)[i].type;
@@ -3662,10 +3894,12 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
deferredForwardPointers.push_back(std::make_pair(&glslangMember, memberQualifier));
}
spvMembers.push_back(
- convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, true));
+ convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember,
+ true));
} else {
spvMembers.push_back(
- convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, false));
+ convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember,
+ false));
}
}
}
@@ -3853,11 +4087,11 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
alignment |= type.getBufferReferenceAlignment();
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
- TranslateNonUniformDecoration(type.getQualifier()),
- nominalTypeId,
- spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
- TranslateMemoryScope(coherentFlags),
- alignment);
+ TranslateNonUniformDecoration(type.getQualifier()),
+ nominalTypeId,
+ spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
+ TranslateMemoryScope(coherentFlags),
+ alignment);
// Need to convert to abstract types when necessary
if (type.getBasicType() == glslang::EbtBool) {
@@ -3871,7 +4105,8 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
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));
+ loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
+ makeSmearedConstant(builder.makeUintConstant(0), vecSize));
}
}
@@ -3920,7 +4155,8 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I
alignment |= type.getBufferReferenceAlignment();
builder.accessChainStore(rvalue,
- spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask),
+ spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) &
+ ~spv::MemoryAccessMakePointerVisibleKHRMask),
TranslateMemoryScope(coherentFlags), alignment);
}
@@ -3981,7 +4217,8 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
// set up the target storage
builder.clearAccessChain();
builder.setAccessChainLValue(lValue);
- builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), type.getBufferReferenceAlignment());
+ builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type),
+ type.getBufferReferenceAlignment());
// store the member
multiTypeStore(glslangElementType, elementRValue);
@@ -4001,7 +4238,8 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
// set up the target storage
builder.clearAccessChain();
builder.setAccessChainLValue(lValue);
- builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), type.getBufferReferenceAlignment());
+ builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type),
+ type.getBufferReferenceAlignment());
// store the member
multiTypeStore(glslangMemberType, memberRValue);
@@ -4036,18 +4274,21 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang:
}
// Given an array type, returns the integer stride required for that array
-int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
+int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout,
+ glslang::TLayoutMatrix matrixLayout)
{
int size;
int stride;
- glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor);
+ glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout,
+ matrixLayout == glslang::ElmRowMajor);
return stride;
}
// Given a matrix type, or array (of array) of matrixes type, returns the integer stride required for that matrix
// when used as a member of an interface block
-int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
+int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout,
+ glslang::TLayoutMatrix matrixLayout)
{
glslang::TType elementType;
elementType.shallowCopy(matrixType);
@@ -4055,7 +4296,8 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, gl
int size;
int stride;
- glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor);
+ glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout,
+ matrixLayout == glslang::ElmRowMajor);
return stride;
}
@@ -4066,8 +4308,8 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, gl
// 'currentOffset' should be passed in already initialized, ready to modify, and reflecting
// the migration of data from nextOffset -> currentOffset. It should be -1 on the first call.
// -1 means a non-forced member offset (no decoration needed).
-void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset,
- glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
+void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType,
+ int& currentOffset, int& nextOffset, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
{
// this will get a positive value when deemed necessary
nextOffset = -1;
@@ -4097,7 +4339,8 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
int memberSize;
int dummyStride;
- int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout, matrixLayout == glslang::ElmRowMajor);
+ int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout,
+ matrixLayout == glslang::ElmRowMajor);
// Adjust alignment for HLSL rules
// TODO: make this consistent in early phases of code:
@@ -4116,7 +4359,8 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
glslang::RoundToPow2(currentOffset, memberAlignment);
// Bump up to vec4 if there is a bad straddle
- if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize, currentOffset))
+ if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize,
+ currentOffset))
glslang::RoundToPow2(currentOffset, 16);
nextOffset = currentOffset + memberSize;
@@ -4169,8 +4413,10 @@ bool TGlslangToSpvTraverser::writableParam(glslang::TStorageQualifier qualifier)
assert(qualifier == glslang::EvqIn ||
qualifier == glslang::EvqOut ||
qualifier == glslang::EvqInOut ||
+ qualifier == glslang::EvqUniform ||
qualifier == glslang::EvqConstReadOnly);
- return qualifier != glslang::EvqConstReadOnly;
+ return qualifier != glslang::EvqConstReadOnly &&
+ qualifier != glslang::EvqUniform;
}
// Is parameter pass-by-original?
@@ -4188,7 +4434,8 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
// Make all the functions, skeletally, without actually visiting their bodies.
void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
{
- const auto getParamDecorations = [&](std::vector<spv::Decoration>& decorations, const glslang::TType& type, bool useVulkanMemoryModel) {
+ const auto getParamDecorations = [&](std::vector<spv::Decoration>& decorations, const glslang::TType& type,
+ bool useVulkanMemoryModel) {
spv::Decoration paramPrecision = TranslatePrecisionDecoration(type);
if (paramPrecision != spv::NoPrecision)
decorations.push_back(paramPrecision);
@@ -4286,7 +4533,8 @@ void TGlslangToSpvTraverser::makeGlobalInitializers(const glslang::TIntermSequen
builder.setBuildPoint(shaderEntry->getLastBlock());
for (int i = 0; i < (int)initializers.size(); ++i) {
glslang::TIntermAggregate* initializer = initializers[i]->getAsAggregate();
- if (initializer && initializer->getOp() != glslang::EOpFunction && initializer->getOp() != glslang::EOpLinkerObjects) {
+ if (initializer && initializer->getOp() != glslang::EOpFunction && initializer->getOp() !=
+ glslang::EOpLinkerObjects) {
// We're on a top-level node that's not a function. Treat as an initializer, whose
// code goes into the beginning of the entry point.
@@ -4314,7 +4562,8 @@ void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate
builder.setBuildPoint(functionBlock);
}
-void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments, spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
+void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments,
+ spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
{
const glslang::TIntermSequence& glslangArguments = node.getSequence();
@@ -4327,7 +4576,8 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate&
sampler = glslangArguments[0]->getAsTyped()->getType().getSampler();
cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
#ifndef GLSLANG_WEB
- f16ShadowCompare = sampler.shadow && glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16;
+ f16ShadowCompare = sampler.shadow &&
+ glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16;
#endif
}
@@ -4490,7 +4740,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
translateArguments(*node->getAsAggregate(), arguments, lvalueCoherentFlags);
else
translateArguments(*node->getAsUnaryNode(), arguments);
- spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision());
+ spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
spv::Builder::TextureParameters params = { };
params.sampler = arguments[0];
@@ -4703,7 +4953,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
operands.push_back(imageOperand);
}
if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) {
- spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
+ spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(
+ TranslateCoherent(imageType))) };
operands.push_back(imageOperand);
}
@@ -4731,18 +4982,22 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
// imageAtomicStore has a void return type so base the pointer type on
// the type of the value operand.
if (node->getOp() == glslang::EOpImageAtomicStore) {
- resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(operands[2].word));
+ resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(*opIt));
} else {
resultTypeId = builder.makePointer(spv::StorageClassImage, resultType());
}
spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands);
+ if (imageType.getQualifier().nonUniform) {
+ builder.addDecoration(pointer, spv::DecorationNonUniformEXT);
+ }
std::vector<spv::Id> operands;
operands.push_back(pointer);
for (; opIt != arguments.end(); ++opIt)
operands.push_back(*opIt);
- return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags);
+ return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(),
+ lvalueCoherentFlags);
}
}
@@ -4767,7 +5022,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
std::vector<spv::Id> comps;
comps.push_back(zero);
comps.push_back(zero);
- operands.push_back(builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps));
+ operands.push_back(builder.makeCompositeConstant(
+ builder.makeVectorType(builder.makeIntType(32), 2), comps));
}
for (; opIt != arguments.end(); ++opIt)
@@ -4856,7 +5112,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
else
dRefComp = builder.getNumComponents(params.coords) - 1;
indexes.push_back(dRefComp);
- params.Dref = builder.createCompositeExtract(params.coords, builder.getScalarTypeId(builder.getTypeId(params.coords)), indexes);
+ params.Dref = builder.createCompositeExtract(params.coords,
+ builder.getScalarTypeId(builder.getTypeId(params.coords)), indexes);
}
// lod
@@ -4981,7 +5238,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
flags.clear();
builder.accessChainPush(builder.makeIntConstant(i), flags, 0);
- builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), i+1));
+ builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1),
+ i+1));
}
return builder.createCompositeExtract(res, resultType(), 0);
}
@@ -5004,10 +5262,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
// copy the projective coordinate if we have to
if (projTargetComp != projSourceComp) {
spv::Id projComp = builder.createCompositeExtract(params.coords,
- builder.getScalarTypeId(builder.getTypeId(params.coords)),
- projSourceComp);
+ builder.getScalarTypeId(builder.getTypeId(params.coords)), projSourceComp);
params.coords = builder.createCompositeInsert(projComp, params.coords,
- builder.getTypeId(params.coords), projTargetComp);
+ builder.getTypeId(params.coords), projTargetComp);
}
}
@@ -5087,7 +5344,8 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
++lValueCount;
} else if (writableParam(qualifiers[a])) {
// need space to hold the copy
- arg = builder.createVariable(spv::StorageClassFunction, builder.getContainedTypeId(function->getParamType(a)), "param");
+ arg = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction,
+ builder.getContainedTypeId(function->getParamType(a)), "param");
if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) {
// need to copy the input into output space
builder.setAccessChain(lValues[lValueCount]);
@@ -5099,12 +5357,14 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
++lValueCount;
} else {
// process r-value, which involves a copy for a type mismatch
- if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a])) {
- spv::Id argCopy = builder.createVariable(spv::StorageClassFunction, function->getParamType(a), "arg");
+ if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a]) ||
+ TranslatePrecisionDecoration(*argTypes[a]) != function->getParamPrecision(a))
+ {
+ spv::Id argCopy = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, function->getParamType(a), "arg");
builder.clearAccessChain();
builder.setAccessChainLValue(argCopy);
multiTypeStore(*argTypes[a], rValues[rValueCount]);
- arg = builder.createLoad(argCopy);
+ arg = builder.createLoad(argCopy, function->getParamPrecision(a));
} else
arg = rValues[rValueCount];
++rValueCount;
@@ -5123,7 +5383,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
++lValueCount;
else if (writableParam(qualifiers[a])) {
if (qualifiers[a] == glslang::EvqOut || qualifiers[a] == glslang::EvqInOut) {
- spv::Id copy = builder.createLoad(spvArgs[a]);
+ spv::Id copy = builder.createLoad(spvArgs[a], spv::NoPrecision);
builder.setAccessChain(lValues[lValueCount]);
multiTypeStore(*argTypes[a], copy);
}
@@ -5368,7 +5628,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD
case glslang::EOpNotEqual:
case glslang::EOpVectorNotEqual:
if (isFloat)
- binOp = spv::OpFOrdNotEqual;
+ binOp = spv::OpFUnordNotEqual;
else if (isBool)
binOp = spv::OpLogicalNotEqual;
else
@@ -5502,7 +5762,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora
}
spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId,
- spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
+ spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
{
spv::Op unaryOp = spv::OpNop;
int extBuiltins = -1;
@@ -5763,6 +6023,24 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
case glslang::EOpFwidthCoarse:
unaryOp = spv::OpFwidthCoarse;
break;
+ case glslang::EOpRayQueryProceed:
+ unaryOp = spv::OpRayQueryProceedKHR;
+ break;
+ case glslang::EOpRayQueryGetRayTMin:
+ unaryOp = spv::OpRayQueryGetRayTMinKHR;
+ break;
+ case glslang::EOpRayQueryGetRayFlags:
+ unaryOp = spv::OpRayQueryGetRayFlagsKHR;
+ break;
+ case glslang::EOpRayQueryGetWorldRayOrigin:
+ unaryOp = spv::OpRayQueryGetWorldRayOriginKHR;
+ break;
+ case glslang::EOpRayQueryGetWorldRayDirection:
+ unaryOp = spv::OpRayQueryGetWorldRayDirectionKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque:
+ unaryOp = spv::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR;
+ break;
case glslang::EOpInterpolateAtCentroid:
if (typeProxy == glslang::EbtFloat16)
builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
@@ -6048,7 +6326,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
case glslang::EOpConvFloatToBool:
zero = builder.makeFloatConstant(0.0F);
zero = makeSmearedConstant(zero, vectorSize);
- return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
+ return builder.createBinOp(spv::OpFUnordNotEqual, destType, operand, zero);
case glslang::EOpConvBoolToFloat:
convOp = spv::OpSelect;
zero = builder.makeFloatConstant(0.0F);
@@ -6197,11 +6475,11 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
case glslang::EOpConvDoubleToBool:
zero = builder.makeDoubleConstant(0.0);
zero = makeSmearedConstant(zero, vectorSize);
- return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
+ return builder.createBinOp(spv::OpFUnordNotEqual, destType, operand, zero);
case glslang::EOpConvFloat16ToBool:
zero = builder.makeFloat16Constant(0.0F);
zero = makeSmearedConstant(zero, vectorSize);
- return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
+ return builder.createBinOp(spv::OpFUnordNotEqual, destType, operand, zero);
case glslang::EOpConvBoolToDouble:
convOp = spv::OpSelect;
zero = builder.makeDoubleConstant(0.0);
@@ -6395,7 +6673,9 @@ spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vector
}
// For glslang ops that map to SPV atomic opCodes
-spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
+spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/,
+ spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy,
+ const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
{
spv::Op opCode = spv::OpNop;
@@ -6404,6 +6684,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
case glslang::EOpImageAtomicAdd:
case glslang::EOpAtomicCounterAdd:
opCode = spv::OpAtomicIAdd;
+ if (typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
+ opCode = spv::OpAtomicFAddEXT;
+ builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add);
+ if (typeProxy == glslang::EbtFloat)
+ builder.addCapability(spv::CapabilityAtomicFloat32AddEXT);
+ else
+ builder.addCapability(spv::CapabilityAtomicFloat64AddEXT);
+ }
break;
case glslang::EOpAtomicCounterSubtract:
opCode = spv::OpAtomicISub;
@@ -6411,12 +6699,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
case glslang::EOpAtomicMin:
case glslang::EOpImageAtomicMin:
case glslang::EOpAtomicCounterMin:
- opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? spv::OpAtomicUMin : spv::OpAtomicSMin;
+ opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ?
+ spv::OpAtomicUMin : spv::OpAtomicSMin;
break;
case glslang::EOpAtomicMax:
case glslang::EOpImageAtomicMax:
case glslang::EOpAtomicCounterMax:
- opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? spv::OpAtomicUMax : spv::OpAtomicSMax;
+ opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ?
+ spv::OpAtomicUMax : spv::OpAtomicSMax;
break;
case glslang::EOpAtomicAnd:
case glslang::EOpImageAtomicAnd:
@@ -6481,7 +6771,8 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
scopeId = builder.makeUintConstant(spv::ScopeDevice);
}
// semantics default to relaxed
- spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() && glslangIntermediate->usingVulkanMemoryModel() ?
+ spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() &&
+ glslangIntermediate->usingVulkanMemoryModel() ?
spv::MemorySemanticsVolatileMask :
spv::MemorySemanticsMaskNone);
spv::Id semanticsId2 = semanticsId;
@@ -6494,20 +6785,24 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
valueId = operands[2];
if (operands.size() > 3) {
scopeId = operands[3];
- semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[4]) | builder.getConstantScalar(operands[5]));
- semanticsId2 = builder.makeUintConstant(builder.getConstantScalar(operands[6]) | builder.getConstantScalar(operands[7]));
+ semanticsId = builder.makeUintConstant(
+ builder.getConstantScalar(operands[4]) | builder.getConstantScalar(operands[5]));
+ semanticsId2 = builder.makeUintConstant(
+ builder.getConstantScalar(operands[6]) | builder.getConstantScalar(operands[7]));
}
} else if (opCode == spv::OpAtomicLoad) {
if (operands.size() > 1) {
scopeId = operands[1];
- semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]));
+ semanticsId = builder.makeUintConstant(
+ builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]));
}
} else {
// atomic store or RMW
valueId = operands[1];
if (operands.size() > 2) {
scopeId = operands[2];
- semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[3]) | builder.getConstantScalar(operands[4]));
+ semanticsId = builder.makeUintConstant
+ (builder.getConstantScalar(operands[3]) | builder.getConstantScalar(operands[4]));
}
}
@@ -6552,7 +6847,8 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
}
// Create group invocation operations.
-spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId,
+ std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
{
bool isUnsigned = isTypeUnsignedInt(typeProxy);
bool isFloat = isTypeFloat(typeProxy);
@@ -6766,8 +7062,10 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast ||
op == spv::OpSubgroupReadInvocationKHR ||
- op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD || op == spv::OpGroupSMinNonUniformAMD ||
- op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD || op == spv::OpGroupSMaxNonUniformAMD ||
+ op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD ||
+ op == spv::OpGroupSMinNonUniformAMD ||
+ op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD ||
+ op == spv::OpGroupSMaxNonUniformAMD ||
op == spv::OpGroupFAddNonUniformAMD || op == spv::OpGroupIAddNonUniformAMD);
// Handle group invocation operations scalar by scalar.
@@ -7156,7 +7454,8 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s
return builder.createOp(opCode, typeId, spvGroupOperands);
}
-spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision,
+ spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
{
bool isUnsigned = isTypeUnsignedInt(typeProxy);
bool isFloat = isTypeFloat(typeProxy);
@@ -7258,14 +7557,16 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
unsigned int executionScope = builder.getConstantScalar(operands[0]);
unsigned int memoryScope = builder.getConstantScalar(operands[1]);
unsigned int semantics = builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]);
- builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics);
+ builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope,
+ (spv::MemorySemanticsMask)semantics);
if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask |
spv::MemorySemanticsMakeVisibleKHRMask |
spv::MemorySemanticsOutputMemoryKHRMask |
spv::MemorySemanticsVolatileMask)) {
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
}
- if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || memoryScope == spv::ScopeDevice)) {
+ if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice ||
+ memoryScope == spv::ScopeDevice)) {
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
}
return 0;
@@ -7348,7 +7649,8 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
if (builder.getNumComponents(operands[0]) == 1)
frexpIntType = builder.makeIntegerType(width, true);
else
- frexpIntType = builder.makeVectorType(builder.makeIntegerType(width, true), builder.getNumComponents(operands[0]));
+ frexpIntType = builder.makeVectorType(builder.makeIntegerType(width, true),
+ builder.getNumComponents(operands[0]));
typeId = builder.makeStructResultType(typeId0, frexpIntType);
consumedOperands = 1;
}
@@ -7451,24 +7753,105 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
libCall = spv::InterpolateAtVertexAMD;
break;
- case glslang::EOpReportIntersectionNV:
- {
+ case glslang::EOpReportIntersection:
typeId = builder.makeBoolType();
- opCode = spv::OpReportIntersectionNV;
- }
- break;
- case glslang::EOpTraceNV:
- {
- builder.createNoResultOp(spv::OpTraceNV, operands);
+ opCode = spv::OpReportIntersectionKHR;
+ break;
+ case glslang::EOpTrace:
+ builder.createNoResultOp(spv::OpTraceRayKHR, operands);
return 0;
- }
- break;
- case glslang::EOpExecuteCallableNV:
- {
- builder.createNoResultOp(spv::OpExecuteCallableNV, operands);
+ case glslang::EOpExecuteCallable:
+ builder.createNoResultOp(spv::OpExecuteCallableKHR, operands);
return 0;
- }
- break;
+
+ case glslang::EOpRayQueryInitialize:
+ builder.createNoResultOp(spv::OpRayQueryInitializeKHR, operands);
+ return 0;
+ case glslang::EOpRayQueryTerminate:
+ builder.createNoResultOp(spv::OpRayQueryTerminateKHR, operands);
+ return 0;
+ case glslang::EOpRayQueryGenerateIntersection:
+ builder.createNoResultOp(spv::OpRayQueryGenerateIntersectionKHR, operands);
+ return 0;
+ case glslang::EOpRayQueryConfirmIntersection:
+ builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR, operands);
+ return 0;
+ case glslang::EOpRayQueryProceed:
+ typeId = builder.makeBoolType();
+ opCode = spv::OpRayQueryProceedKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionType:
+ typeId = builder.makeUintType(32);
+ opCode = spv::OpRayQueryGetIntersectionTypeKHR;
+ break;
+ case glslang::EOpRayQueryGetRayTMin:
+ typeId = builder.makeFloatType(32);
+ opCode = spv::OpRayQueryGetRayTMinKHR;
+ break;
+ case glslang::EOpRayQueryGetRayFlags:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetRayFlagsKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionT:
+ typeId = builder.makeFloatType(32);
+ opCode = spv::OpRayQueryGetIntersectionTKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetIntersectionInstanceCustomIndexKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionInstanceId:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetIntersectionInstanceIdKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionGeometryIndex:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetIntersectionGeometryIndexKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionPrimitiveIndex:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetIntersectionPrimitiveIndexKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionBarycentrics:
+ typeId = builder.makeVectorType(builder.makeFloatType(32), 2);
+ opCode = spv::OpRayQueryGetIntersectionBarycentricsKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionFrontFace:
+ typeId = builder.makeBoolType();
+ opCode = spv::OpRayQueryGetIntersectionFrontFaceKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque:
+ typeId = builder.makeBoolType();
+ opCode = spv::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionObjectRayDirection:
+ typeId = builder.makeVectorType(builder.makeFloatType(32), 3);
+ opCode = spv::OpRayQueryGetIntersectionObjectRayDirectionKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionObjectRayOrigin:
+ typeId = builder.makeVectorType(builder.makeFloatType(32), 3);
+ opCode = spv::OpRayQueryGetIntersectionObjectRayOriginKHR;
+ break;
+ case glslang::EOpRayQueryGetWorldRayDirection:
+ typeId = builder.makeVectorType(builder.makeFloatType(32), 3);
+ opCode = spv::OpRayQueryGetWorldRayDirectionKHR;
+ break;
+ case glslang::EOpRayQueryGetWorldRayOrigin:
+ typeId = builder.makeVectorType(builder.makeFloatType(32), 3);
+ opCode = spv::OpRayQueryGetWorldRayOriginKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionObjectToWorld:
+ typeId = builder.makeMatrixType(builder.makeFloatType(32), 4, 3);
+ opCode = spv::OpRayQueryGetIntersectionObjectToWorldKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionWorldToObject:
+ typeId = builder.makeMatrixType(builder.makeFloatType(32), 4, 3);
+ opCode = spv::OpRayQueryGetIntersectionWorldToObjectKHR;
+ break;
case glslang::EOpWritePackedPrimitiveIndices4x8NV:
builder.createNoResultOp(spv::OpWritePackedPrimitiveIndices4x8NV, operands);
return 0;
@@ -7558,7 +7941,8 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId)
{
// GLSL memory barriers use queuefamily scope in new model, device scope in old model
- spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
+ spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ?
+ spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
switch (op) {
case glslang::EOpBarrier:
@@ -7664,13 +8048,24 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv:
spv::Id id = builder.createBuiltinCall(typeId, getExtBuiltins(spv::E_SPV_AMD_gcn_shader), spv::TimeAMD, args);
return builder.setPrecision(id, precision);
}
- case glslang::EOpIgnoreIntersectionNV:
- builder.createNoResultOp(spv::OpIgnoreIntersectionNV);
+ case glslang::EOpIgnoreIntersection:
+ builder.createNoResultOp(spv::OpIgnoreIntersectionKHR);
return 0;
- case glslang::EOpTerminateRayNV:
- builder.createNoResultOp(spv::OpTerminateRayNV);
+ case glslang::EOpTerminateRay:
+ builder.createNoResultOp(spv::OpTerminateRayKHR);
+ return 0;
+ case glslang::EOpRayQueryInitialize:
+ builder.createNoResultOp(spv::OpRayQueryInitializeKHR);
+ return 0;
+ case glslang::EOpRayQueryTerminate:
+ builder.createNoResultOp(spv::OpRayQueryTerminateKHR);
+ return 0;
+ case glslang::EOpRayQueryGenerateIntersection:
+ builder.createNoResultOp(spv::OpRayQueryGenerateIntersectionKHR);
+ return 0;
+ case glslang::EOpRayQueryConfirmIntersection:
+ builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR);
return 0;
-
case glslang::EOpBeginInvocationInterlock:
builder.createNoResultOp(spv::OpBeginInvocationInterlockEXT);
return 0;
@@ -7722,7 +8117,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
// it was not found, create it
spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false);
- auto forcedType = getForcedType(builtIn, symbol->getType());
+ auto forcedType = getForcedType(symbol->getQualifier().builtIn, symbol->getType());
id = createSpvVariable(symbol, forcedType.first);
symbolValues[symbol->getId()] = id;
if (forcedType.second != spv::NoType)
@@ -7787,7 +8182,8 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
#ifndef GLSLANG_WEB
if (symbol->getType().isImage()) {
std::vector<spv::Decoration> memory;
- TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, glslangIntermediate->usingVulkanMemoryModel());
+ TranslateMemoryDecoration(symbol->getType().getQualifier(), memory,
+ glslangIntermediate->usingVulkanMemoryModel());
for (unsigned int i = 0; i < memory.size(); ++i)
builder.addDecoration(id, memory[i]);
}
@@ -7841,7 +8237,8 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
}
if (symbol->isReference()) {
- builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
+ builder.addDecoration(id, symbol->getType().getQualifier().restrict ?
+ spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
}
#endif
@@ -7903,12 +8300,25 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
// hand off to the non-spec-constant path
assert(node.getAsConstantUnion() != nullptr || node.getAsSymbolNode() != nullptr);
int nextConst = 0;
- return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(),
- nextConst, false);
+ return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ?
+ node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(),
+ nextConst, false);
}
// We now know we have a specialization constant to build
+ // Extra capabilities may be needed.
+ if (node.getType().contains8BitInt())
+ builder.addCapability(spv::CapabilityInt8);
+ if (node.getType().contains16BitFloat())
+ builder.addCapability(spv::CapabilityFloat16);
+ if (node.getType().contains16BitInt())
+ builder.addCapability(spv::CapabilityInt16);
+ if (node.getType().contains64BitInt())
+ builder.addCapability(spv::CapabilityInt64);
+ if (node.getType().containsDouble())
+ builder.addCapability(spv::CapabilityFloat64);
+
// gl_WorkGroupSize is a special case until the front-end handles hierarchical specialization constants,
// even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ...
if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) {
@@ -7957,7 +8367,8 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
// If there are not enough elements present in 'consts', 0 will be substituted;
// an empty 'consts' can be used to create a fully zeroed SPIR-V constant.
//
-spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glslang::TType& glslangType, const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant)
+spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glslang::TType& glslangType,
+ const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant)
{
// vector of constants for SPIR-V
std::vector<spv::Id> spvConsts;
@@ -8075,6 +8486,9 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
scalar = builder.createUnaryOp(spv::OpBitcast, typeId, scalar);
break;
#endif
+ case glslang::EbtString:
+ scalar = builder.getStringId(consts[nextConst].getSConst()->c_str());
+ break;
default:
assert(0);
break;
@@ -8175,7 +8589,8 @@ bool TGlslangToSpvTraverser::isTrivial(const glslang::TIntermTyped* node)
// Emit short-circuiting code, where 'right' is never evaluated unless
// the left side is true (for &&) or false (for ||).
-spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslang::TIntermTyped& left, glslang::TIntermTyped& right)
+spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslang::TIntermTyped& left,
+ glslang::TIntermTyped& right)
{
spv::Id boolTypeId = builder.makeBoolType();
@@ -8259,7 +8674,9 @@ int GetSpirvGeneratorVersion()
// return 6; // revert version 5 change, which makes a different (new) kind of incorrect code,
// versions 4 and 6 each generate OpArrayLength as it has long been done
// return 7; // GLSL volatile keyword maps to both SPIR-V decorations Volatile and Coherent
- return 8; // switch to new dead block eliminator; use OpUnreachable
+ // return 8; // switch to new dead block eliminator; use OpUnreachable
+ // return 9; // don't include opaque function parameters in OpEntryPoint global's operand list
+ return 10; // Generate OpFUnordNotEqual for != comparisons
}
// Write SPIR-V out to a binary file
@@ -8279,14 +8696,15 @@ void OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName)
// Write SPIR-V out to a text file with 32-bit hexadecimal words
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName)
{
-#ifndef GLSLANG_WEB
+#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
std::ofstream out;
out.open(baseName, std::ios::binary | std::ios::out);
if (out.fail())
printf("ERROR: Failed to open file: %s\n", baseName);
- out << "\t// " <<
- GetSpirvGeneratorVersion() << "." << GLSLANG_MINOR_VERSION << "." << GLSLANG_PATCH_LEVEL <<
- std::endl;
+ out << "\t// " <<
+ GetSpirvGeneratorVersion() <<
+ GLSLANG_VERSION_MAJOR << "." << GLSLANG_VERSION_MINOR << "." << GLSLANG_VERSION_PATCH <<
+ GLSLANG_VERSION_FLAVOR << std::endl;
if (varName != nullptr) {
out << "\t #pragma once" << std::endl;
out << "const uint32_t " << varName << "[] = {" << std::endl;
@@ -8305,6 +8723,7 @@ void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName,
}
if (varName != nullptr) {
out << "};";
+ out << std::endl;
}
out.close();
#endif
@@ -8342,10 +8761,14 @@ void GlslangToSpv(const TIntermediate& intermediate, std::vector<unsigned int>&
// If from HLSL, run spirv-opt to "legalize" the SPIR-V for Vulkan
// eg. forward and remove memory writes of opaque types.
bool prelegalization = intermediate.getSource() == EShSourceHlsl;
- if ((intermediate.getSource() == EShSourceHlsl || options->optimizeSize) && !options->disableOptimizer) {
- SpirvToolsLegalize(intermediate, spirv, logger, options);
+ if ((prelegalization || options->optimizeSize) && !options->disableOptimizer) {
+ SpirvToolsTransform(intermediate, spirv, logger, options);
prelegalization = false;
}
+ else if (options->stripDebugInfo) {
+ // Strip debug info even if optimization is disabled.
+ SpirvToolsStripDebugInfo(intermediate, spirv, logger);
+ }
if (options->validate)
SpirvToolsValidate(intermediate, spirv, logger, prelegalization);
diff --git a/thirdparty/glslang/SPIRV/GlslangToSpv.h b/thirdparty/glslang/SPIRV/GlslangToSpv.h
index 3907be43b7..3907be43b7 100755..100644
--- a/thirdparty/glslang/SPIRV/GlslangToSpv.h
+++ b/thirdparty/glslang/SPIRV/GlslangToSpv.h
diff --git a/thirdparty/glslang/SPIRV/Logger.cpp b/thirdparty/glslang/SPIRV/Logger.cpp
index 7ea0c6342b..cdc8469c44 100644
--- a/thirdparty/glslang/SPIRV/Logger.cpp
+++ b/thirdparty/glslang/SPIRV/Logger.cpp
@@ -69,4 +69,4 @@ std::string SpvBuildLogger::getAllMessages() const {
} // end spv namespace
-#endif \ No newline at end of file
+#endif
diff --git a/thirdparty/glslang/SPIRV/NonSemanticDebugPrintf.h b/thirdparty/glslang/SPIRV/NonSemanticDebugPrintf.h
new file mode 100644
index 0000000000..83796d75e5
--- /dev/null
+++ b/thirdparty/glslang/SPIRV/NonSemanticDebugPrintf.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2020 The Khronos Group Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and/or associated documentation files (the
+// "Materials"), to deal in the Materials without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Materials, and to
+// permit persons to whom the Materials are furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Materials.
+//
+// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
+// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
+// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
+// https://www.khronos.org/registry/
+//
+// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+//
+
+#ifndef SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
+#define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ NonSemanticDebugPrintfRevision = 1,
+ NonSemanticDebugPrintfRevision_BitWidthPadding = 0x7fffffff
+};
+
+enum NonSemanticDebugPrintfInstructions {
+ NonSemanticDebugPrintfDebugPrintf = 1,
+ NonSemanticDebugPrintfInstructionsMax = 0x7fffffff
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
diff --git a/thirdparty/glslang/SPIRV/SPVRemapper.cpp b/thirdparty/glslang/SPIRV/SPVRemapper.cpp
index fd0bb8950c..1adc6a3042 100644
--- a/thirdparty/glslang/SPIRV/SPVRemapper.cpp
+++ b/thirdparty/glslang/SPIRV/SPVRemapper.cpp
@@ -625,6 +625,9 @@ namespace spv {
break;
}
+ case spv::OperandVariableLiteralStrings:
+ return nextInst;
+
// Execution mode might have extra literal operands. Skip them.
case spv::OperandExecutionMode:
return nextInst;
diff --git a/thirdparty/glslang/SPIRV/SpvBuilder.cpp b/thirdparty/glslang/SPIRV/SpvBuilder.cpp
index bd208952e0..9680331469 100644
--- a/thirdparty/glslang/SPIRV/SpvBuilder.cpp
+++ b/thirdparty/glslang/SPIRV/SpvBuilder.cpp
@@ -1,6 +1,7 @@
//
// Copyright (C) 2014-2015 LunarG, Inc.
// Copyright (C) 2015-2018 Google, Inc.
+// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
@@ -496,7 +497,8 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
return type->getResultId();
}
-Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format)
+Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled,
+ ImageFormat format)
{
assert(sampled == 1 || sampled == 2);
@@ -601,16 +603,31 @@ Id Builder::makeSampledImageType(Id imageType)
}
#ifndef GLSLANG_WEB
-Id Builder::makeAccelerationStructureNVType()
+Id Builder::makeAccelerationStructureType()
{
Instruction *type;
- if (groupedTypes[OpTypeAccelerationStructureNV].size() == 0) {
- type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureNV);
- groupedTypes[OpTypeAccelerationStructureNV].push_back(type);
+ if (groupedTypes[OpTypeAccelerationStructureKHR].size() == 0) {
+ type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureKHR);
+ groupedTypes[OpTypeAccelerationStructureKHR].push_back(type);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type);
} else {
- type = groupedTypes[OpTypeAccelerationStructureNV].back();
+ type = groupedTypes[OpTypeAccelerationStructureKHR].back();
+ }
+
+ return type->getResultId();
+}
+
+Id Builder::makeRayQueryType()
+{
+ Instruction *type;
+ if (groupedTypes[OpTypeRayQueryProvisionalKHR].size() == 0) {
+ type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryProvisionalKHR);
+ groupedTypes[OpTypeRayQueryProvisionalKHR].push_back(type);
+ constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
+ module.mapInstruction(type);
+ } else {
+ type = groupedTypes[OpTypeRayQueryProvisionalKHR].back();
}
return type->getResultId();
@@ -1166,6 +1183,28 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int val
executionModes.push_back(std::unique_ptr<Instruction>(instr));
}
+void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const std::vector<unsigned>& literals)
+{
+ Instruction* instr = new Instruction(OpExecutionMode);
+ instr->addIdOperand(entryPoint->getId());
+ instr->addImmediateOperand(mode);
+ for (auto literal : literals)
+ instr->addImmediateOperand(literal);
+
+ executionModes.push_back(std::unique_ptr<Instruction>(instr));
+}
+
+void Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, const std::vector<Id>& operandIds)
+{
+ Instruction* instr = new Instruction(OpExecutionModeId);
+ instr->addIdOperand(entryPoint->getId());
+ instr->addImmediateOperand(mode);
+ for (auto operandId : operandIds)
+ instr->addIdOperand(operandId);
+
+ executionModes.push_back(std::unique_ptr<Instruction>(instr));
+}
+
void Builder::addName(Id id, const char* string)
{
Instruction* name = new Instruction(OpName);
@@ -1204,7 +1243,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s)
if (decoration == spv::DecorationMax)
return;
- Instruction* dec = new Instruction(OpDecorateStringGOOGLE);
+ Instruction* dec = new Instruction(OpDecorateString);
dec->addIdOperand(id);
dec->addImmediateOperand(decoration);
dec->addStringOperand(s);
@@ -1212,6 +1251,34 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s)
decorations.push_back(std::unique_ptr<Instruction>(dec));
}
+void Builder::addDecoration(Id id, Decoration decoration, const std::vector<unsigned>& literals)
+{
+ if (decoration == spv::DecorationMax)
+ return;
+
+ Instruction* dec = new Instruction(OpDecorate);
+ dec->addIdOperand(id);
+ dec->addImmediateOperand(decoration);
+ for (auto literal : literals)
+ dec->addImmediateOperand(literal);
+
+ decorations.push_back(std::unique_ptr<Instruction>(dec));
+}
+
+void Builder::addDecoration(Id id, Decoration decoration, const std::vector<const char*>& strings)
+{
+ if (decoration == spv::DecorationMax)
+ return;
+
+ Instruction* dec = new Instruction(OpDecorateString);
+ dec->addIdOperand(id);
+ dec->addImmediateOperand(decoration);
+ for (auto string : strings)
+ dec->addStringOperand(string);
+
+ decorations.push_back(std::unique_ptr<Instruction>(dec));
+}
+
void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
{
if (decoration == spv::DecorationMax)
@@ -1225,6 +1292,21 @@ void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
decorations.push_back(std::unique_ptr<Instruction>(dec));
}
+void Builder::addDecorationId(Id id, Decoration decoration, const std::vector<Id>& operandIds)
+{
+ if(decoration == spv::DecorationMax)
+ return;
+
+ Instruction* dec = new Instruction(OpDecorateId);
+ dec->addIdOperand(id);
+ dec->addImmediateOperand(decoration);
+
+ for (auto operandId : operandIds)
+ dec->addIdOperand(operandId);
+
+ decorations.push_back(std::unique_ptr<Instruction>(dec));
+}
+
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
{
if (decoration == spv::DecorationMax)
@@ -1254,6 +1336,36 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
decorations.push_back(std::unique_ptr<Instruction>(dec));
}
+void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<unsigned>& literals)
+{
+ if (decoration == spv::DecorationMax)
+ return;
+
+ Instruction* dec = new Instruction(OpMemberDecorate);
+ dec->addIdOperand(id);
+ dec->addImmediateOperand(member);
+ dec->addImmediateOperand(decoration);
+ for (auto literal : literals)
+ dec->addImmediateOperand(literal);
+
+ decorations.push_back(std::unique_ptr<Instruction>(dec));
+}
+
+void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<const char*>& strings)
+{
+ if (decoration == spv::DecorationMax)
+ return;
+
+ Instruction* dec = new Instruction(OpMemberDecorateString);
+ dec->addIdOperand(id);
+ dec->addImmediateOperand(member);
+ dec->addImmediateOperand(decoration);
+ for (auto string : strings)
+ dec->addStringOperand(string);
+
+ decorations.push_back(std::unique_ptr<Instruction>(dec));
+}
+
// Comments in header
Function* Builder::makeEntryPoint(const char* entryPoint)
{
@@ -1270,7 +1382,8 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
// Comments in header
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
- const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& decorations, Block **entry)
+ const std::vector<Id>& paramTypes,
+ const std::vector<std::vector<Decoration>>& decorations, Block **entry)
{
// Make the function and initial instructions in it
Id typeId = makeFunctionType(returnType, paramTypes);
@@ -1279,9 +1392,12 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
// Set up the precisions
setPrecision(function->getId(), precision);
+ function->setReturnPrecision(precision);
for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) {
- for (int d = 0; d < (int)decorations[p].size(); ++d)
+ for (int d = 0; d < (int)decorations[p].size(); ++d) {
addDecoration(firstParamId + p, decorations[p][d]);
+ function->addParamPrecision(p, decorations[p][d]);
+ }
}
// CFG
@@ -1338,7 +1454,7 @@ void Builder::makeDiscard()
}
// Comments in header
-Id Builder::createVariable(StorageClass storageClass, Id type, const char* name, Id initializer)
+Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name, Id initializer)
{
Id pointerType = makePointer(storageClass, type);
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
@@ -1360,6 +1476,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name,
if (name)
addName(inst->getResultId(), name);
+ setPrecision(inst->getResultId(), precision);
return inst->getResultId();
}
@@ -1373,7 +1490,8 @@ Id Builder::createUndefined(Id type)
}
// av/vis/nonprivate are unnecessary and illegal for some storage classes.
-spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const
+spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
+ const
{
switch (sc) {
case spv::StorageClassUniform:
@@ -1392,7 +1510,8 @@ spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAc
}
// Comments in header
-void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
+void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope,
+ unsigned int alignment)
{
Instruction* store = new Instruction(OpStore);
store->addIdOperand(lValue);
@@ -1414,7 +1533,8 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce
}
// Comments in header
-Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
+Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMask memoryAccess,
+ spv::Scope scope, unsigned int alignment)
{
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
load->addIdOperand(lValue);
@@ -1432,6 +1552,7 @@ Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope
}
buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
+ setPrecision(load->getResultId(), precision);
return load->getResultId();
}
@@ -1495,7 +1616,8 @@ Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index)
// Generate code for spec constants if in spec constant operation
// generation mode.
if (generatingOpCodeForSpecConst) {
- return createSpecConstantOp(OpCompositeExtract, typeId, std::vector<Id>(1, composite), std::vector<Id>(1, index));
+ return createSpecConstantOp(OpCompositeExtract, typeId, std::vector<Id>(1, composite),
+ std::vector<Id>(1, index));
}
Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);
extract->addIdOperand(composite);
@@ -1697,7 +1819,8 @@ Id Builder::createOp(Op opCode, Id typeId, const std::vector<IdImmediate>& opera
return op->getResultId();
}
-Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands, const std::vector<unsigned>& literals)
+Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands,
+ const std::vector<unsigned>& literals)
{
Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp);
op->addImmediateOperand((unsigned) opCode);
@@ -2144,7 +2267,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
Op op;
switch (getMostBasicTypeClass(valueType)) {
case OpTypeFloat:
- op = equal ? OpFOrdEqual : OpFOrdNotEqual;
+ op = equal ? OpFOrdEqual : OpFUnordNotEqual;
break;
case OpTypeInt:
default:
@@ -2187,7 +2310,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
if (constituent == 0)
resultId = subResultId;
else
- resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), precision);
+ resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId),
+ precision);
}
return resultId;
@@ -2196,7 +2320,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
// OpCompositeConstruct
Id Builder::createCompositeConstruct(Id typeId, const std::vector<Id>& constituents)
{
- assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && getNumTypeConstituents(typeId) == (int)constituents.size()));
+ assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 &&
+ getNumTypeConstituents(typeId) == (int)constituents.size()));
if (generatingOpCodeForSpecConst) {
// Sometime, even in spec-constant-op mode, the constant composite to be
@@ -2609,7 +2734,8 @@ void Builder::clearAccessChain()
}
// Comments in header
-void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
+void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType,
+ AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
{
accessChain.coherentFlags |= coherentFlags;
accessChain.alignment |= alignment;
@@ -2649,7 +2775,7 @@ void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, sp
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
// extract and insert elements to perform writeMask and/or swizzle.
if (accessChain.swizzle.size() > 0) {
- Id tempBaseId = createLoad(base);
+ Id tempBaseId = createLoad(base, spv::NoPrecision);
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
}
@@ -2663,7 +2789,8 @@ void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, sp
}
// Comments in header
-Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
+Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType,
+ spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
{
Id id;
@@ -2687,17 +2814,19 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
if (constant) {
id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
+ setPrecision(id, precision);
} else {
Id lValue = NoResult;
- if (spvVersion >= Spv_1_4) {
+ if (spvVersion >= Spv_1_4 && isValidInitializer(accessChain.base)) {
// make a new function variable for this r-value, using an initializer,
// and mark it as NonWritable so that downstream it can be detected as a lookup
// table
- lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable",
- accessChain.base);
+ lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base),
+ "indexable", accessChain.base);
addDecoration(lValue, DecorationNonWritable);
} else {
- lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
+ lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base),
+ "indexable");
// store into it
createStore(accessChain.base, lValue);
}
@@ -2706,9 +2835,8 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
accessChain.isRValue = false;
// load through the access chain
- id = createLoad(collapseAccessChain());
+ id = createLoad(collapseAccessChain(), precision);
}
- setPrecision(id, precision);
} else
id = accessChain.base; // no precision, it was set when this was defined
} else {
@@ -2721,8 +2849,13 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
}
// load through the access chain
- id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment);
- setPrecision(id, precision);
+ id = collapseAccessChain();
+ // Apply nonuniform both to the access chain and the loaded value.
+ // Buffer accesses need the access chain decorated, and this is where
+ // loaded image types get decorated. TODO: This should maybe move to
+ // createImageTextureFunctionCall.
+ addDecoration(id, nonUniform);
+ id = createLoad(id, precision, memoryAccess, scope, alignment);
addDecoration(id, nonUniform);
}
@@ -3075,7 +3208,8 @@ void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
dumpSourceInstructions(iItr->first, *iItr->second, out);
}
-void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector<std::unique_ptr<Instruction> >& instructions) const
+void Builder::dumpInstructions(std::vector<unsigned int>& out,
+ const std::vector<std::unique_ptr<Instruction> >& instructions) const
{
for (int i = 0; i < (int)instructions.size(); ++i) {
instructions[i]->dump(out);
diff --git a/thirdparty/glslang/SPIRV/SpvBuilder.h b/thirdparty/glslang/SPIRV/SpvBuilder.h
index 31fee975fc..077945e77b 100644
--- a/thirdparty/glslang/SPIRV/SpvBuilder.h
+++ b/thirdparty/glslang/SPIRV/SpvBuilder.h
@@ -1,7 +1,8 @@
//
// Copyright (C) 2014-2015 LunarG, Inc.
-// Copyright (C) 2015-2018 Google, Inc.
+// Copyright (C) 2015-2020 Google, Inc.
// Copyright (C) 2017 ARM Limited.
+// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
@@ -94,6 +95,7 @@ public:
const char* file_c_str = str.c_str();
fileString->addStringOperand(file_c_str);
strings.push_back(std::unique_ptr<Instruction>(fileString));
+ module.mapInstruction(fileString);
stringIds[file_c_str] = strId;
return strId;
}
@@ -181,7 +183,9 @@ public:
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
// accelerationStructureNV type
- Id makeAccelerationStructureNVType();
+ Id makeAccelerationStructureType();
+ // rayQueryEXT type
+ Id makeRayQueryType();
// For querying about types.
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
@@ -196,7 +200,8 @@ public:
Id getContainedTypeId(Id typeId) const;
Id getContainedTypeId(Id typeId, int) const;
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
- ImageFormat getImageTypeFormat(Id typeId) const { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
+ ImageFormat getImageTypeFormat(Id typeId) const
+ { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
@@ -206,12 +211,17 @@ public:
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
- bool isBoolType(Id typeId) { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
- bool isIntType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
- bool isUintType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
+ bool isBoolType(Id typeId)
+ { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
+ bool isIntType(Id typeId) const
+ { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
+ bool isUintType(Id typeId) const
+ { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
bool isFloatType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat; }
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
- bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; }
+ bool isScalarType(Id typeId) const
+ { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt ||
+ getTypeClass(typeId) == OpTypeBool; }
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
@@ -221,7 +231,8 @@ public:
#else
bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; }
#endif
- bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
+ bool isAggregateType(Id typeId) const
+ { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
@@ -233,9 +244,17 @@ public:
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
- unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); }
+ unsigned int getConstantScalar(Id resultId) const
+ { return module.getInstruction(resultId)->getImmediateOperand(0); }
StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
+ bool isVariableOpCode(Op opcode) const { return opcode == OpVariable; }
+ bool isVariable(Id resultId) const { return isVariableOpCode(getOpCode(resultId)); }
+ bool isGlobalStorage(Id resultId) const { return getStorageClass(resultId) != StorageClassFunction; }
+ bool isGlobalVariable(Id resultId) const { return isVariable(resultId) && isGlobalStorage(resultId); }
+ // See if a resultId is valid for use as an initializer.
+ bool isValidInitializer(Id resultId) const { return isConstant(resultId) || isGlobalVariable(resultId); }
+
int getScalarTypeWidth(Id typeId) const
{
Id scalarTypeId = getScalarTypeId(typeId);
@@ -275,14 +294,22 @@ public:
// For making new constants (will return old constant if the requested one was already made).
Id makeBoolConstant(bool b, bool specConstant = false);
- Id makeInt8Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
- Id makeUint8Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(8), u, specConstant); }
- Id makeInt16Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); }
- Id makeUint16Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(16), u, specConstant); }
- Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
- Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); }
- Id makeInt64Constant(long long i, bool specConstant = false) { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
- Id makeUint64Constant(unsigned long long u, bool specConstant = false) { return makeInt64Constant(makeUintType(64), u, specConstant); }
+ Id makeInt8Constant(int i, bool specConstant = false)
+ { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
+ Id makeUint8Constant(unsigned u, bool specConstant = false)
+ { return makeIntConstant(makeUintType(8), u, specConstant); }
+ Id makeInt16Constant(int i, bool specConstant = false)
+ { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); }
+ Id makeUint16Constant(unsigned u, bool specConstant = false)
+ { return makeIntConstant(makeUintType(16), u, specConstant); }
+ Id makeIntConstant(int i, bool specConstant = false)
+ { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
+ Id makeUintConstant(unsigned u, bool specConstant = false)
+ { return makeIntConstant(makeUintType(32), u, specConstant); }
+ Id makeInt64Constant(long long i, bool specConstant = false)
+ { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
+ Id makeUint64Constant(unsigned long long u, bool specConstant = false)
+ { return makeInt64Constant(makeUintType(64), u, specConstant); }
Id makeFloatConstant(float f, bool specConstant = false);
Id makeDoubleConstant(double d, bool specConstant = false);
Id makeFloat16Constant(float f16, bool specConstant = false);
@@ -294,13 +321,20 @@ public:
// Methods for adding information outside the CFG.
Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
+ void addExecutionMode(Function*, ExecutionMode mode, const std::vector<unsigned>& literals);
+ void addExecutionModeId(Function*, ExecutionMode mode, const std::vector<Id>& operandIds);
void addName(Id, const char* name);
void addMemberName(Id, int member, const char* name);
void addDecoration(Id, Decoration, int num = -1);
void addDecoration(Id, Decoration, const char*);
+ void addDecoration(Id, Decoration, const std::vector<unsigned>& literals);
+ void addDecoration(Id, Decoration, const std::vector<const char*>& strings);
void addDecorationId(Id id, Decoration, Id idDecoration);
+ void addDecorationId(Id id, Decoration, const std::vector<Id>& operandIds);
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
void addMemberDecoration(Id, unsigned int member, Decoration, const char*);
+ void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<unsigned>& literals);
+ void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<const char*>& strings);
// At the end of what block do the next create*() instructions go?
void setBuildPoint(Block* bp) { buildPoint = bp; }
@@ -313,8 +347,8 @@ public:
// Make a shader-style function, and create its entry block if entry is non-zero.
// Return the function, pass back the entry.
// The returned pointer is only valid for the lifetime of this builder.
- Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector<Id>& paramTypes,
- const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
+ Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name,
+ const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
// Create a return. An 'implicit' return is one not appearing in the source
// code. In the case of an implicit return, no post-return block is inserted.
@@ -327,16 +361,20 @@ public:
void makeDiscard();
// Create a global or function local or IO variable.
- Id createVariable(StorageClass, Id type, const char* name = 0, Id initializer = NoResult);
+ Id createVariable(Decoration precision, StorageClass, Id type, const char* name = nullptr,
+ Id initializer = NoResult);
// Create an intermediate with an undefined value.
Id createUndefined(Id type);
// Store into an Id and return the l-value
- void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
+ void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
+ spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
// Load from an Id and return it
- Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
+ Id createLoad(Id lValue, spv::Decoration precision,
+ spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
+ spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
// Create an OpAccessChain instruction
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
@@ -495,7 +533,7 @@ public:
// recursion stack can hold the memory for it.
//
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
- const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB); // return argument
+ const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB);
// Add a branch to the innermost switch's merge block.
void addSwitchBreak();
@@ -512,7 +550,7 @@ public:
Block &head, &body, &merge, &continue_target;
private:
LoopBlocks();
- LoopBlocks& operator=(const LoopBlocks&);
+ LoopBlocks& operator=(const LoopBlocks&) = delete;
};
// Start a new loop and prepare the builder to generate code for it. Until
@@ -569,10 +607,13 @@ public:
std::vector<Id> indexChain;
Id instr; // cache the instruction that generates this access chain
std::vector<unsigned> swizzle; // each std::vector element selects the next GLSL component number
- Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
- Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
+ Id component; // a dynamic component index, can coexist with a swizzle,
+ // done after the swizzle, NoResult if not present
+ Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied;
+ // NoType unless a swizzle or component is present
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
- unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment. Only tracks base and (optional) component selection alignment.
+ unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment.
+ // Only tracks base and (optional) component selection alignment.
// Accumulate whether anything in the chain of structures has coherent decorations.
struct CoherentFlags {
@@ -583,12 +624,17 @@ public:
CoherentFlags operator |=(const CoherentFlags &other) { return *this; }
#else
bool isVolatile() const { return volatil; }
+ bool anyCoherent() const {
+ return coherent || devicecoherent || queuefamilycoherent || workgroupcoherent ||
+ subgroupcoherent || shadercallcoherent;
+ }
unsigned coherent : 1;
unsigned devicecoherent : 1;
unsigned queuefamilycoherent : 1;
unsigned workgroupcoherent : 1;
unsigned subgroupcoherent : 1;
+ unsigned shadercallcoherent : 1;
unsigned nonprivate : 1;
unsigned volatil : 1;
unsigned isImage : 1;
@@ -599,6 +645,7 @@ public:
queuefamilycoherent = 0;
workgroupcoherent = 0;
subgroupcoherent = 0;
+ shadercallcoherent = 0;
nonprivate = 0;
volatil = 0;
isImage = 0;
@@ -610,6 +657,7 @@ public:
queuefamilycoherent |= other.queuefamilycoherent;
workgroupcoherent |= other.workgroupcoherent;
subgroupcoherent |= other.subgroupcoherent;
+ shadercallcoherent |= other.shadercallcoherent;
nonprivate |= other.nonprivate;
volatil |= other.volatil;
isImage |= other.isImage;
@@ -655,11 +703,13 @@ public:
}
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
- void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
+ void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType,
+ AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
// push a dynamic component selection onto the access chain, only applicable with a
// non-trivial swizzle or no swizzle
- void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
+ void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags,
+ unsigned int alignment)
{
if (accessChain.swizzle.size() != 1) {
accessChain.component = component;
@@ -671,10 +721,18 @@ public:
}
// use accessChain and swizzle to store value
- void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
+ void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
+ spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
// use accessChain and swizzle to load an r-value
- Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
+ Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType,
+ spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax,
+ unsigned int alignment = 0);
+
+ // Return whether or not the access chain can be represented in SPIR-V
+ // as an l-value.
+ // E.g., a[3].yx cannot be, while a[3].y and a[3].y[x] can be.
+ bool isSpvLvalue() const { return accessChain.swizzle.size() <= 1; }
// get the direct pointer for an l-value
Id accessChainGetLValue();
@@ -703,7 +761,8 @@ public:
void createBranch(Block* block);
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
- void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, const std::vector<unsigned int>& operands);
+ void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
+ const std::vector<unsigned int>& operands);
// Sets to generate opcode for specialization constants.
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
@@ -729,7 +788,8 @@ public:
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
void dumpModuleProcesses(std::vector<unsigned int>&) const;
- spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const;
+ spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
+ const;
unsigned int spvVersion; // the version of SPIR-V to emit in the header
SourceLanguage source;
@@ -764,10 +824,14 @@ public:
std::vector<std::unique_ptr<Instruction> > externals;
std::vector<std::unique_ptr<Function> > functions;
- // not output, internally used for quick & dirty canonical (unique) creation
- std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants; // map type opcodes to constant inst.
- std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants; // map struct-id to constant instructions
- std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes; // map type opcodes to type instructions
+ // not output, internally used for quick & dirty canonical (unique) creation
+
+ // map type opcodes to constant inst.
+ std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants;
+ // map struct-id to constant instructions
+ std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
+ // map type opcodes to type instructions
+ std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;
// stack of switches
std::stack<Block*> switchMerges;
diff --git a/thirdparty/glslang/SPIRV/SpvTools.cpp b/thirdparty/glslang/SPIRV/SpvTools.cpp
index 97bd4e7427..112ac33c5c 100644
--- a/thirdparty/glslang/SPIRV/SpvTools.cpp
+++ b/thirdparty/glslang/SPIRV/SpvTools.cpp
@@ -1,6 +1,6 @@
//
// Copyright (C) 2014-2016 LunarG, Inc.
-// Copyright (C) 2018 Google, Inc.
+// Copyright (C) 2018-2020 Google, Inc.
//
// All rights reserved.
//
@@ -80,6 +80,39 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
}
+// Callback passed to spvtools::Optimizer::SetMessageConsumer
+void OptimizerMesssageConsumer(spv_message_level_t level, const char *source,
+ const spv_position_t &position, const char *message)
+{
+ auto &out = std::cerr;
+ switch (level)
+ {
+ case SPV_MSG_FATAL:
+ case SPV_MSG_INTERNAL_ERROR:
+ case SPV_MSG_ERROR:
+ out << "error: ";
+ break;
+ case SPV_MSG_WARNING:
+ out << "warning: ";
+ break;
+ case SPV_MSG_INFO:
+ case SPV_MSG_DEBUG:
+ out << "info: ";
+ break;
+ default:
+ break;
+ }
+ if (source)
+ {
+ out << source << ":";
+ }
+ out << position.line << ":" << position.column << ":" << position.index << ":";
+ if (message)
+ {
+ out << " " << message;
+ }
+ out << std::endl;
+}
// Use the SPIRV-Tools disassembler to print SPIR-V.
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
@@ -128,45 +161,14 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<
spvContextDestroy(context);
}
-// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
-// legalizing HLSL SPIR-V.
-void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>& spirv,
- spv::SpvBuildLogger*, const SpvOptions* options)
+// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process.
+void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
+ spv::SpvBuildLogger* logger, const SpvOptions* options)
{
- spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2;
+ spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger);
spvtools::Optimizer optimizer(target_env);
- optimizer.SetMessageConsumer(
- [](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) {
- auto &out = std::cerr;
- switch (level)
- {
- case SPV_MSG_FATAL:
- case SPV_MSG_INTERNAL_ERROR:
- case SPV_MSG_ERROR:
- out << "error: ";
- break;
- case SPV_MSG_WARNING:
- out << "warning: ";
- break;
- case SPV_MSG_INFO:
- case SPV_MSG_DEBUG:
- out << "info: ";
- break;
- default:
- break;
- }
- if (source)
- {
- out << source << ":";
- }
- out << position.line << ":" << position.column << ":" << position.index << ":";
- if (message)
- {
- out << " " << message;
- }
- out << std::endl;
- });
+ optimizer.SetMessageConsumer(OptimizerMesssageConsumer);
// If debug (specifically source line info) is being generated, propagate
// line information into all SPIR-V instructions. This avoids loss of
@@ -175,6 +177,9 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>
if (options->generateDebugInfo) {
optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass());
}
+ else if (options->stripDebugInfo) {
+ optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
+ }
optimizer.RegisterPass(spvtools::CreateWrapOpKillPass());
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
@@ -207,7 +212,27 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>
}
spvtools::OptimizerOptions spvOptOptions;
- spvOptOptions.set_run_validator(false); // The validator may run as a seperate step later on
+ optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
+ spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on
+ optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
+}
+
+// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by
+// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if
+// optimization is disabled.
+void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
+ std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger)
+{
+ spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger);
+
+ spvtools::Optimizer optimizer(target_env);
+ optimizer.SetMessageConsumer(OptimizerMesssageConsumer);
+
+ optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
+
+ spvtools::OptimizerOptions spvOptOptions;
+ optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
+ spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
}
diff --git a/thirdparty/glslang/SPIRV/SpvTools.h b/thirdparty/glslang/SPIRV/SpvTools.h
index 59c914da0b..7779dfa779 100644
--- a/thirdparty/glslang/SPIRV/SpvTools.h
+++ b/thirdparty/glslang/SPIRV/SpvTools.h
@@ -52,9 +52,10 @@
namespace glslang {
struct SpvOptions {
- SpvOptions() : generateDebugInfo(false), disableOptimizer(true),
+ SpvOptions() : generateDebugInfo(false), stripDebugInfo(false), disableOptimizer(true),
optimizeSize(false), disassemble(false), validate(false) { }
bool generateDebugInfo;
+ bool stripDebugInfo;
bool disableOptimizer;
bool optimizeSize;
bool disassemble;
@@ -70,10 +71,15 @@ void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& s
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger*, bool prelegalization);
-// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
-// legalizing HLSL SPIR-V.
-void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
- spv::SpvBuildLogger*, const SpvOptions*);
+// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process.
+void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
+ spv::SpvBuildLogger*, const SpvOptions*);
+
+// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by
+// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if
+// optimization is disabled.
+void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
+ std::vector<unsigned int>& spirv, spv::SpvBuildLogger*);
#endif
diff --git a/thirdparty/glslang/SPIRV/disassemble.cpp b/thirdparty/glslang/SPIRV/disassemble.cpp
index 930e799493..a95ded49d2 100644
--- a/thirdparty/glslang/SPIRV/disassemble.cpp
+++ b/thirdparty/glslang/SPIRV/disassemble.cpp
@@ -75,6 +75,7 @@ enum ExtInstSet {
GLSLextAMDInst,
GLSLextNVInst,
OpenCLExtInst,
+ NonSemanticDebugPrintfExtInst,
};
// Container class for a single instance of a SPIR-V stream, with methods for disassembly.
@@ -480,8 +481,12 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
if (opCode == OpExtInst) {
ExtInstSet extInstSet = GLSL450Inst;
const char* name = idDescriptor[stream[word - 2]].c_str();
- if (0 == memcmp("OpenCL", name, 6)) {
+ if (strcmp("OpenCL.std", name) == 0) {
extInstSet = OpenCLExtInst;
+ } else if (strcmp("OpenCL.DebugInfo.100", name) == 0) {
+ extInstSet = OpenCLExtInst;
+ } else if (strcmp("NonSemantic.DebugPrintf", name) == 0) {
+ extInstSet = NonSemanticDebugPrintfExtInst;
} else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 ||
strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 ||
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
@@ -505,6 +510,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
}
else if (extInstSet == GLSLextNVInst) {
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
+ } else if (extInstSet == NonSemanticDebugPrintfExtInst) {
+ out << "(DebugPrintf)";
}
}
break;
@@ -512,6 +519,10 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
case OperandLiteralString:
numOperands -= disassembleString();
break;
+ case OperandVariableLiteralStrings:
+ while (numOperands > 0)
+ numOperands -= disassembleString();
+ return;
case OperandMemoryAccess:
outputMask(OperandMemoryAccess, stream[word++]);
--numOperands;
diff --git a/thirdparty/glslang/SPIRV/doc.cpp b/thirdparty/glslang/SPIRV/doc.cpp
index bee5c79729..1d052f8c29 100644
--- a/thirdparty/glslang/SPIRV/doc.cpp
+++ b/thirdparty/glslang/SPIRV/doc.cpp
@@ -1,5 +1,6 @@
//
// Copyright (C) 2014-2015 LunarG, Inc.
+// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
@@ -99,12 +100,12 @@ const char* ExecutionModelString(int model)
default: return "Bad";
- case ExecutionModelRayGenerationNV: return "RayGenerationNV";
- case ExecutionModelIntersectionNV: return "IntersectionNV";
- case ExecutionModelAnyHitNV: return "AnyHitNV";
- case ExecutionModelClosestHitNV: return "ClosestHitNV";
- case ExecutionModelMissNV: return "MissNV";
- case ExecutionModelCallableNV: return "CallableNV";
+ case ExecutionModelRayGenerationKHR: return "RayGenerationKHR";
+ case ExecutionModelIntersectionKHR: return "IntersectionKHR";
+ case ExecutionModelAnyHitKHR: return "AnyHitKHR";
+ case ExecutionModelClosestHitKHR: return "ClosestHitKHR";
+ case ExecutionModelMissKHR: return "MissKHR";
+ case ExecutionModelCallableKHR: return "CallableKHR";
}
}
@@ -133,7 +134,7 @@ const char* MemoryString(int mem)
}
}
-const int ExecutionModeCeiling = 33;
+const int ExecutionModeCeiling = 40;
const char* ExecutionModeString(int mode)
{
@@ -172,7 +173,21 @@ const char* ExecutionModeString(int mode)
case 31: return "ContractionOff";
case 32: return "Bad";
- case 4446: return "PostDepthCoverage";
+ case ExecutionModeInitializer: return "Initializer";
+ case ExecutionModeFinalizer: return "Finalizer";
+ case ExecutionModeSubgroupSize: return "SubgroupSize";
+ case ExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup";
+ case ExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId";
+ case ExecutionModeLocalSizeId: return "LocalSizeId";
+ case ExecutionModeLocalSizeHintId: return "LocalSizeHintId";
+
+ case ExecutionModePostDepthCoverage: return "PostDepthCoverage";
+ case ExecutionModeDenormPreserve: return "DenormPreserve";
+ case ExecutionModeDenormFlushToZero: return "DenormFlushToZero";
+ case ExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve";
+ case ExecutionModeRoundingModeRTE: return "RoundingModeRTE";
+ case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ";
+ case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT";
case ExecutionModeOutputLinesNV: return "OutputLinesNV";
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
@@ -187,6 +202,11 @@ const char* ExecutionModeString(int mode)
case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT";
case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT";
+ case ExecutionModeMaxWorkgroupSizeINTEL: return "MaxWorkgroupSizeINTEL";
+ case ExecutionModeMaxWorkDimINTEL: return "MaxWorkDimINTEL";
+ case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL";
+ case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL";
+
case ExecutionModeCeiling:
default: return "Bad";
}
@@ -209,12 +229,12 @@ const char* StorageClassString(int StorageClass)
case 11: return "Image";
case 12: return "StorageBuffer";
- case StorageClassRayPayloadNV: return "RayPayloadNV";
- case StorageClassHitAttributeNV: return "HitAttributeNV";
- case StorageClassIncomingRayPayloadNV: return "IncomingRayPayloadNV";
- case StorageClassShaderRecordBufferNV: return "ShaderRecordBufferNV";
- case StorageClassCallableDataNV: return "CallableDataNV";
- case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV";
+ case StorageClassRayPayloadKHR: return "RayPayloadKHR";
+ case StorageClassHitAttributeKHR: return "HitAttributeKHR";
+ case StorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR";
+ case StorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR";
+ case StorageClassCallableDataKHR: return "CallableDataKHR";
+ case StorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR";
case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT";
@@ -361,32 +381,33 @@ const char* BuiltInString(int builtIn)
case 4996: return "BaryCoordSmoothCentroidAMD";
case 4997: return "BaryCoordSmoothSampleAMD";
case 4998: return "BaryCoordPullModelAMD";
- case BuiltInLaunchIdNV: return "LaunchIdNV";
- case BuiltInLaunchSizeNV: return "LaunchSizeNV";
- case BuiltInWorldRayOriginNV: return "WorldRayOriginNV";
- case BuiltInWorldRayDirectionNV: return "WorldRayDirectionNV";
- case BuiltInObjectRayOriginNV: return "ObjectRayOriginNV";
- case BuiltInObjectRayDirectionNV: return "ObjectRayDirectionNV";
- case BuiltInRayTminNV: return "RayTminNV";
- case BuiltInRayTmaxNV: return "RayTmaxNV";
- case BuiltInInstanceCustomIndexNV: return "InstanceCustomIndexNV";
- case BuiltInObjectToWorldNV: return "ObjectToWorldNV";
- case BuiltInWorldToObjectNV: return "WorldToObjectNV";
- case BuiltInHitTNV: return "HitTNV";
- case BuiltInHitKindNV: return "HitKindNV";
- case BuiltInIncomingRayFlagsNV: return "IncomingRayFlagsNV";
- case BuiltInViewportMaskNV: return "ViewportMaskNV";
- case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
- case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
- case BuiltInPositionPerViewNV: return "PositionPerViewNV";
- case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
+ case BuiltInLaunchIdKHR: return "LaunchIdKHR";
+ case BuiltInLaunchSizeKHR: return "LaunchSizeKHR";
+ case BuiltInWorldRayOriginKHR: return "WorldRayOriginKHR";
+ case BuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR";
+ case BuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR";
+ case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR";
+ case BuiltInRayTminKHR: return "RayTminKHR";
+ case BuiltInRayTmaxKHR: return "RayTmaxKHR";
+ case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR";
+ case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR";
+ case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR";
+ case BuiltInWorldToObjectKHR: return "WorldToObjectKHR";
+ case BuiltInHitTKHR: return "HitTKHR";
+ case BuiltInHitKindKHR: return "HitKindKHR";
+ case BuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR";
+ case BuiltInViewportMaskNV: return "ViewportMaskNV";
+ case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
+ case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
+ case BuiltInPositionPerViewNV: return "PositionPerViewNV";
+ case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
// case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT
// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
- case BuiltInBaryCoordNV: return "BaryCoordNV";
- case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
+ case BuiltInBaryCoordNV: return "BaryCoordNV";
+ case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
- case BuiltInFragSizeEXT: return "FragSizeEXT";
- case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
+ case BuiltInFragSizeEXT: return "FragSizeEXT";
+ case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
case 5264: return "FullyCoveredEXT";
@@ -890,6 +911,9 @@ const char* CapabilityString(int info)
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
case CapabilityRayTracingNV: return "RayTracingNV";
+ case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
+ case CapabilityRayQueryProvisionalKHR: return "RayQueryProvisionalKHR";
+ case CapabilityRayTraversalPrimitiveCullingProvisionalKHR: return "RayTraversalPrimitiveCullingProvisionalKHR";
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
@@ -933,6 +957,9 @@ const char* CapabilityString(int info)
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
+ case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
+ case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
+
default: return "Bad";
}
}
@@ -1264,6 +1291,7 @@ const char* OpcodeString(int op)
case 320: return "OpImageSparseRead";
case OpModuleProcessed: return "OpModuleProcessed";
+ case OpExecutionModeId: return "OpExecutionModeId";
case OpDecorateId: return "OpDecorateId";
case 333: return "OpGroupNonUniformElect";
@@ -1308,6 +1336,8 @@ const char* OpcodeString(int op)
case 4430: return "OpSubgroupAllEqualKHR";
case 4432: return "OpSubgroupReadInvocationKHR";
+ case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
+
case 5000: return "OpGroupIAddNonUniformAMD";
case 5001: return "OpGroupFAddNonUniformAMD";
case 5002: return "OpGroupFMinNonUniformAMD";
@@ -1326,15 +1356,40 @@ const char* OpcodeString(int op)
case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV";
- case OpReportIntersectionNV: return "OpReportIntersectionNV";
- case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV";
- case OpTerminateRayNV: return "OpTerminateRayNV";
- case OpTraceNV: return "OpTraceNV";
- case OpTypeAccelerationStructureNV: return "OpTypeAccelerationStructureNV";
- case OpExecuteCallableNV: return "OpExecuteCallableNV";
+ case OpReportIntersectionKHR: return "OpReportIntersectionKHR";
+ case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR";
+ case OpTerminateRayKHR: return "OpTerminateRayKHR";
+ case OpTraceRayKHR: return "OpTraceRayKHR";
+ case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR";
+ case OpExecuteCallableKHR: return "OpExecuteCallableKHR";
case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV";
case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV";
+ case OpTypeRayQueryProvisionalKHR: return "OpTypeRayQueryProvisionalKHR";
+ case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR";
+ case OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR";
+ case OpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR";
+ case OpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR";
+ case OpRayQueryProceedKHR: return "OpRayQueryProceedKHR";
+ case OpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR";
+ case OpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR";
+ case OpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR";
+ case OpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR";
+ case OpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR";
+ case OpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR";
+ case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR";
+ case OpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR";
+ case OpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR";
+ case OpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR";
+ case OpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR";
+ case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR";
+ case OpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR";
+ case OpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR";
+ case OpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR";
+ case OpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR";
+ case OpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR";
+ case OpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR";
+
case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV";
case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV";
case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV";
@@ -1388,6 +1443,7 @@ void Parameterize()
InstructionDesc[OpMemoryModel].setResultAndType(false, false);
InstructionDesc[OpEntryPoint].setResultAndType(false, false);
InstructionDesc[OpExecutionMode].setResultAndType(false, false);
+ InstructionDesc[OpExecutionModeId].setResultAndType(false, false);
InstructionDesc[OpTypeVoid].setResultAndType(true, false);
InstructionDesc[OpTypeBool].setResultAndType(true, false);
InstructionDesc[OpTypeInt].setResultAndType(true, false);
@@ -1574,6 +1630,10 @@ void Parameterize()
InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode, "'Mode'");
InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <<Execution_Mode,Execution Mode>>");
+ InstructionDesc[OpExecutionModeId].operands.push(OperandId, "'Entry Point'");
+ InstructionDesc[OpExecutionModeId].operands.push(OperandExecutionMode, "'Mode'");
+ InstructionDesc[OpExecutionModeId].operands.push(OperandVariableIds, "See <<Execution_Mode,Execution Mode>>");
+
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Width'");
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Signedness'");
@@ -1667,7 +1727,7 @@ void Parameterize()
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'");
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandDecoration, "");
- InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'");
+ InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'");
InstructionDesc[OpMemberDecorate].operands.push(OperandId, "'Structure Type'");
InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'");
@@ -1677,7 +1737,7 @@ void Parameterize()
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'");
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'");
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandDecoration, "");
- InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'");
+ InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'");
InstructionDesc[OpGroupDecorate].operands.push(OperandId, "'Decoration Group'");
InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'");
@@ -2230,6 +2290,11 @@ void Parameterize()
InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics, "'Semantics'");
InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Value'");
+ InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Pointer'");
+ InstructionDesc[OpAtomicFAddEXT].operands.push(OperandScope, "'Scope'");
+ InstructionDesc[OpAtomicFAddEXT].operands.push(OperandMemorySemantics, "'Semantics'");
+ InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Value'");
+
InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'");
InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'");
@@ -2694,31 +2759,125 @@ void Parameterize()
InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
- InstructionDesc[OpTypeAccelerationStructureNV].setResultAndType(true, false);
+ InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'NV Acceleration Structure'");
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Flags'");
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'");
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'");
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Stride'");
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'Miss Index'");
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Origin'");
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMin'");
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Direction'");
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMax'");
- InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
- InstructionDesc[OpTraceNV].setResultAndType(false, false);
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'NV Acceleration Structure'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Offset'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Stride'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Miss Index'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Origin'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMin'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Direction'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMax'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Payload'");
+ InstructionDesc[OpTraceRayKHR].setResultAndType(false, false);
- InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Parameter'");
- InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Kind'");
+ InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Parameter'");
+ InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Kind'");
- InstructionDesc[OpIgnoreIntersectionNV].setResultAndType(false, false);
+ InstructionDesc[OpIgnoreIntersectionKHR].setResultAndType(false, false);
- InstructionDesc[OpTerminateRayNV].setResultAndType(false, false);
+ InstructionDesc[OpTerminateRayKHR].setResultAndType(false, false);
- InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "SBT Record Index");
- InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID");
- InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false);
+ InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "SBT Record Index");
+ InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "CallableData ID");
+ InstructionDesc[OpExecuteCallableKHR].setResultAndType(false, false);
+
+ // Ray Query
+ InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
+ InstructionDesc[OpTypeRayQueryProvisionalKHR].setResultAndType(true, false);
+
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'AccelerationS'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayFlags'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'CullMask'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Origin'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmin'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Direction'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmax'");
+ InstructionDesc[OpRayQueryInitializeKHR].setResultAndType(false, false);
+
+ InstructionDesc[OpRayQueryTerminateKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryTerminateKHR].setResultAndType(false, false);
+
+ InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'THit'");
+ InstructionDesc[OpRayQueryGenerateIntersectionKHR].setResultAndType(false, false);
+
+ InstructionDesc[OpRayQueryConfirmIntersectionKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryConfirmIntersectionKHR].setResultAndType(false, false);
+
+ InstructionDesc[OpRayQueryProceedKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryProceedKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionTypeKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetRayTMinKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetRayTMinKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetRayFlagsKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetRayFlagsKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionTKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetWorldRayOriginKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetWorldRayOriginKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].setResultAndType(true, true);
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'");
diff --git a/thirdparty/glslang/SPIRV/doc.h b/thirdparty/glslang/SPIRV/doc.h
index 293256a2c6..2a0b28c6b3 100644
--- a/thirdparty/glslang/SPIRV/doc.h
+++ b/thirdparty/glslang/SPIRV/doc.h
@@ -125,6 +125,7 @@ enum OperandClass {
OperandVariableLiteralId,
OperandLiteralNumber,
OperandLiteralString,
+ OperandVariableLiteralStrings,
OperandSource,
OperandExecutionModel,
OperandAddressing,
diff --git a/thirdparty/glslang/SPIRV/hex_float.h b/thirdparty/glslang/SPIRV/hex_float.h
index 905b21a45a..8be8e9f7e3 100644
--- a/thirdparty/glslang/SPIRV/hex_float.h
+++ b/thirdparty/glslang/SPIRV/hex_float.h
@@ -784,8 +784,8 @@ inline std::istream& ParseNormalFloat(std::istream& is, bool negate_value,
if (val.isInfinity()) {
// Fail the parse. Emulate standard behaviour by setting the value to
// the closest normal value, and set the fail bit on the stream.
- value.set_value((value.isNegative() | negate_value) ? T::lowest()
- : T::max());
+ value.set_value((value.isNegative() || negate_value) ? T::lowest()
+ : T::max());
is.setstate(std::ios_base::failbit);
}
return is;
diff --git a/thirdparty/glslang/SPIRV/spirv.hpp b/thirdparty/glslang/SPIRV/spirv.hpp
index 1e96f7b4a9..35482ea5e2 100644
--- a/thirdparty/glslang/SPIRV/spirv.hpp
+++ b/thirdparty/glslang/SPIRV/spirv.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2019 The Khronos Group Inc.
+// Copyright (c) 2014-2020 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@@ -49,12 +49,12 @@ namespace spv {
typedef unsigned int Id;
-#define SPV_VERSION 0x10400
-#define SPV_REVISION 1
+#define SPV_VERSION 0x10500
+#define SPV_REVISION 3
static const unsigned int MagicNumber = 0x07230203;
-static const unsigned int Version = 0x00010400;
-static const unsigned int Revision = 1;
+static const unsigned int Version = 0x00010500;
+static const unsigned int Revision = 3;
static const unsigned int OpCodeMask = 0xffff;
static const unsigned int WordCountShift = 16;
@@ -78,11 +78,17 @@ enum ExecutionModel {
ExecutionModelKernel = 6,
ExecutionModelTaskNV = 5267,
ExecutionModelMeshNV = 5268,
+ ExecutionModelRayGenerationKHR = 5313,
ExecutionModelRayGenerationNV = 5313,
+ ExecutionModelIntersectionKHR = 5314,
ExecutionModelIntersectionNV = 5314,
+ ExecutionModelAnyHitKHR = 5315,
ExecutionModelAnyHitNV = 5315,
+ ExecutionModelClosestHitKHR = 5316,
ExecutionModelClosestHitNV = 5316,
+ ExecutionModelMissKHR = 5317,
ExecutionModelMissNV = 5317,
+ ExecutionModelCallableKHR = 5318,
ExecutionModelCallableNV = 5318,
ExecutionModelMax = 0x7fffffff,
};
@@ -162,6 +168,10 @@ enum ExecutionMode {
ExecutionModeSampleInterlockUnorderedEXT = 5369,
ExecutionModeShadingRateInterlockOrderedEXT = 5370,
ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
+ ExecutionModeMaxWorkgroupSizeINTEL = 5893,
+ ExecutionModeMaxWorkDimINTEL = 5894,
+ ExecutionModeNoGlobalOffsetINTEL = 5895,
+ ExecutionModeNumSIMDWorkitemsINTEL = 5896,
ExecutionModeMax = 0x7fffffff,
};
@@ -179,14 +189,21 @@ enum StorageClass {
StorageClassAtomicCounter = 10,
StorageClassImage = 11,
StorageClassStorageBuffer = 12,
+ StorageClassCallableDataKHR = 5328,
StorageClassCallableDataNV = 5328,
+ StorageClassIncomingCallableDataKHR = 5329,
StorageClassIncomingCallableDataNV = 5329,
+ StorageClassRayPayloadKHR = 5338,
StorageClassRayPayloadNV = 5338,
+ StorageClassHitAttributeKHR = 5339,
StorageClassHitAttributeNV = 5339,
+ StorageClassIncomingRayPayloadKHR = 5342,
StorageClassIncomingRayPayloadNV = 5342,
+ StorageClassShaderRecordBufferKHR = 5343,
StorageClassShaderRecordBufferNV = 5343,
StorageClassPhysicalStorageBuffer = 5349,
StorageClassPhysicalStorageBufferEXT = 5349,
+ StorageClassCodeSectionINTEL = 5605,
StorageClassMax = 0x7fffffff,
};
@@ -465,11 +482,24 @@ enum Decoration {
DecorationRestrictPointerEXT = 5355,
DecorationAliasedPointer = 5356,
DecorationAliasedPointerEXT = 5356,
+ DecorationReferencedIndirectlyINTEL = 5602,
DecorationCounterBuffer = 5634,
DecorationHlslCounterBufferGOOGLE = 5634,
DecorationHlslSemanticGOOGLE = 5635,
DecorationUserSemantic = 5635,
DecorationUserTypeGOOGLE = 5636,
+ DecorationRegisterINTEL = 5825,
+ DecorationMemoryINTEL = 5826,
+ DecorationNumbanksINTEL = 5827,
+ DecorationBankwidthINTEL = 5828,
+ DecorationMaxPrivateCopiesINTEL = 5829,
+ DecorationSinglepumpINTEL = 5830,
+ DecorationDoublepumpINTEL = 5831,
+ DecorationMaxReplicatesINTEL = 5832,
+ DecorationSimpleDualPortINTEL = 5833,
+ DecorationMergeINTEL = 5834,
+ DecorationBankBitsINTEL = 5835,
+ DecorationForcePow2DepthINTEL = 5836,
DecorationMax = 0x7fffffff,
};
@@ -558,20 +588,35 @@ enum BuiltIn {
BuiltInFragmentSizeNV = 5292,
BuiltInFragInvocationCountEXT = 5293,
BuiltInInvocationsPerPixelNV = 5293,
+ BuiltInLaunchIdKHR = 5319,
BuiltInLaunchIdNV = 5319,
+ BuiltInLaunchSizeKHR = 5320,
BuiltInLaunchSizeNV = 5320,
+ BuiltInWorldRayOriginKHR = 5321,
BuiltInWorldRayOriginNV = 5321,
+ BuiltInWorldRayDirectionKHR = 5322,
BuiltInWorldRayDirectionNV = 5322,
+ BuiltInObjectRayOriginKHR = 5323,
BuiltInObjectRayOriginNV = 5323,
+ BuiltInObjectRayDirectionKHR = 5324,
BuiltInObjectRayDirectionNV = 5324,
+ BuiltInRayTminKHR = 5325,
BuiltInRayTminNV = 5325,
+ BuiltInRayTmaxKHR = 5326,
BuiltInRayTmaxNV = 5326,
+ BuiltInInstanceCustomIndexKHR = 5327,
BuiltInInstanceCustomIndexNV = 5327,
+ BuiltInObjectToWorldKHR = 5330,
BuiltInObjectToWorldNV = 5330,
+ BuiltInWorldToObjectKHR = 5331,
BuiltInWorldToObjectNV = 5331,
+ BuiltInHitTKHR = 5332,
BuiltInHitTNV = 5332,
+ BuiltInHitKindKHR = 5333,
BuiltInHitKindNV = 5333,
+ BuiltInIncomingRayFlagsKHR = 5351,
BuiltInIncomingRayFlagsNV = 5351,
+ BuiltInRayGeometryIndexKHR = 5352,
BuiltInWarpsPerSMNV = 5374,
BuiltInSMCountNV = 5375,
BuiltInWarpIDNV = 5376,
@@ -601,6 +646,13 @@ enum LoopControlShift {
LoopControlIterationMultipleShift = 6,
LoopControlPeelCountShift = 7,
LoopControlPartialCountShift = 8,
+ LoopControlInitiationIntervalINTELShift = 16,
+ LoopControlMaxConcurrencyINTELShift = 17,
+ LoopControlDependencyArrayINTELShift = 18,
+ LoopControlPipelineEnableINTELShift = 19,
+ LoopControlLoopCoalesceINTELShift = 20,
+ LoopControlMaxInterleavingINTELShift = 21,
+ LoopControlSpeculatedIterationsINTELShift = 22,
LoopControlMax = 0x7fffffff,
};
@@ -615,6 +667,13 @@ enum LoopControlMask {
LoopControlIterationMultipleMask = 0x00000040,
LoopControlPeelCountMask = 0x00000080,
LoopControlPartialCountMask = 0x00000100,
+ LoopControlInitiationIntervalINTELMask = 0x00010000,
+ LoopControlMaxConcurrencyINTELMask = 0x00020000,
+ LoopControlDependencyArrayINTELMask = 0x00040000,
+ LoopControlPipelineEnableINTELMask = 0x00080000,
+ LoopControlLoopCoalesceINTELMask = 0x00100000,
+ LoopControlMaxInterleavingINTELMask = 0x00200000,
+ LoopControlSpeculatedIterationsINTELMask = 0x00400000,
};
enum FunctionControlShift {
@@ -709,6 +768,7 @@ enum Scope {
ScopeInvocation = 4,
ScopeQueueFamily = 5,
ScopeQueueFamilyKHR = 5,
+ ScopeShaderCallKHR = 6,
ScopeMax = 0x7fffffff,
};
@@ -833,6 +893,8 @@ enum Capability {
CapabilitySignedZeroInfNanPreserve = 4466,
CapabilityRoundingModeRTE = 4467,
CapabilityRoundingModeRTZ = 4468,
+ CapabilityRayQueryProvisionalKHR = 4471,
+ CapabilityRayTraversalPrimitiveCullingProvisionalKHR = 4478,
CapabilityFloat16ImageAMD = 5008,
CapabilityImageGatherBiasLodAMD = 5009,
CapabilityFragmentMaskAMD = 5010,
@@ -886,6 +948,7 @@ enum Capability {
CapabilityPhysicalStorageBufferAddresses = 5347,
CapabilityPhysicalStorageBufferAddressesEXT = 5347,
CapabilityComputeDerivativeGroupLinearNV = 5350,
+ CapabilityRayTracingProvisionalKHR = 5353,
CapabilityCooperativeMatrixNV = 5357,
CapabilityFragmentShaderSampleInterlockEXT = 5363,
CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
@@ -897,12 +960,70 @@ enum Capability {
CapabilitySubgroupImageBlockIOINTEL = 5570,
CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
CapabilityIntegerFunctions2INTEL = 5584,
+ CapabilityFunctionPointersINTEL = 5603,
+ CapabilityIndirectReferencesINTEL = 5604,
CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
+ CapabilityFPGAMemoryAttributesINTEL = 5824,
+ CapabilityUnstructuredLoopControlsINTEL = 5886,
+ CapabilityFPGALoopControlsINTEL = 5888,
+ CapabilityKernelAttributesINTEL = 5892,
+ CapabilityFPGAKernelAttributesINTEL = 5897,
+ CapabilityBlockingPipesINTEL = 5945,
+ CapabilityFPGARegINTEL = 5948,
+ CapabilityAtomicFloat32AddEXT = 6033,
+ CapabilityAtomicFloat64AddEXT = 6034,
CapabilityMax = 0x7fffffff,
};
+enum RayFlagsShift {
+ RayFlagsOpaqueKHRShift = 0,
+ RayFlagsNoOpaqueKHRShift = 1,
+ RayFlagsTerminateOnFirstHitKHRShift = 2,
+ RayFlagsSkipClosestHitShaderKHRShift = 3,
+ RayFlagsCullBackFacingTrianglesKHRShift = 4,
+ RayFlagsCullFrontFacingTrianglesKHRShift = 5,
+ RayFlagsCullOpaqueKHRShift = 6,
+ RayFlagsCullNoOpaqueKHRShift = 7,
+ RayFlagsSkipTrianglesKHRShift = 8,
+ RayFlagsSkipAABBsKHRShift = 9,
+ RayFlagsMax = 0x7fffffff,
+};
+
+enum RayFlagsMask {
+ RayFlagsMaskNone = 0,
+ RayFlagsOpaqueKHRMask = 0x00000001,
+ RayFlagsNoOpaqueKHRMask = 0x00000002,
+ RayFlagsTerminateOnFirstHitKHRMask = 0x00000004,
+ RayFlagsSkipClosestHitShaderKHRMask = 0x00000008,
+ RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010,
+ RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020,
+ RayFlagsCullOpaqueKHRMask = 0x00000040,
+ RayFlagsCullNoOpaqueKHRMask = 0x00000080,
+ RayFlagsSkipTrianglesKHRMask = 0x00000100,
+ RayFlagsSkipAABBsKHRMask = 0x00000200,
+};
+
+enum RayQueryIntersection {
+ RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0,
+ RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1,
+ RayQueryIntersectionMax = 0x7fffffff,
+};
+
+enum RayQueryCommittedIntersectionType {
+ RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0,
+ RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1,
+ RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2,
+ RayQueryCommittedIntersectionTypeMax = 0x7fffffff,
+};
+
+enum RayQueryCandidateIntersectionType {
+ RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0,
+ RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1,
+ RayQueryCandidateIntersectionTypeMax = 0x7fffffff,
+};
+
enum Op {
OpNop = 0,
OpUndef = 1,
@@ -1254,6 +1375,13 @@ enum Op {
OpSubgroupAnyKHR = 4429,
OpSubgroupAllEqualKHR = 4430,
OpSubgroupReadInvocationKHR = 4432,
+ OpTypeRayQueryProvisionalKHR = 4472,
+ OpRayQueryInitializeKHR = 4473,
+ OpRayQueryTerminateKHR = 4474,
+ OpRayQueryGenerateIntersectionKHR = 4475,
+ OpRayQueryConfirmIntersectionKHR = 4476,
+ OpRayQueryProceedKHR = 4477,
+ OpRayQueryGetIntersectionTypeKHR = 4479,
OpGroupIAddNonUniformAMD = 5000,
OpGroupFAddNonUniformAMD = 5001,
OpGroupFMinNonUniformAMD = 5002,
@@ -1268,11 +1396,17 @@ enum Op {
OpImageSampleFootprintNV = 5283,
OpGroupNonUniformPartitionNV = 5296,
OpWritePackedPrimitiveIndices4x8NV = 5299,
+ OpReportIntersectionKHR = 5334,
OpReportIntersectionNV = 5334,
+ OpIgnoreIntersectionKHR = 5335,
OpIgnoreIntersectionNV = 5335,
+ OpTerminateRayKHR = 5336,
OpTerminateRayNV = 5336,
OpTraceNV = 5337,
+ OpTraceRayKHR = 5337,
+ OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341,
+ OpExecuteCallableKHR = 5344,
OpExecuteCallableNV = 5344,
OpTypeCooperativeMatrixNV = 5358,
OpCooperativeMatrixLoadNV = 5359,
@@ -1307,6 +1441,8 @@ enum Op {
OpUSubSatINTEL = 5596,
OpIMul32x16INTEL = 5597,
OpUMul32x16INTEL = 5598,
+ OpFunctionPointerINTEL = 5600,
+ OpFunctionPointerCallINTEL = 5601,
OpDecorateString = 5632,
OpDecorateStringGOOGLE = 5632,
OpMemberDecorateString = 5633,
@@ -1429,6 +1565,28 @@ enum Op {
OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
+ OpLoopControlINTEL = 5887,
+ OpReadPipeBlockingINTEL = 5946,
+ OpWritePipeBlockingINTEL = 5947,
+ OpFPGARegINTEL = 5949,
+ OpRayQueryGetRayTMinKHR = 6016,
+ OpRayQueryGetRayFlagsKHR = 6017,
+ OpRayQueryGetIntersectionTKHR = 6018,
+ OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019,
+ OpRayQueryGetIntersectionInstanceIdKHR = 6020,
+ OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021,
+ OpRayQueryGetIntersectionGeometryIndexKHR = 6022,
+ OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023,
+ OpRayQueryGetIntersectionBarycentricsKHR = 6024,
+ OpRayQueryGetIntersectionFrontFaceKHR = 6025,
+ OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026,
+ OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027,
+ OpRayQueryGetIntersectionObjectRayOriginKHR = 6028,
+ OpRayQueryGetWorldRayDirectionKHR = 6029,
+ OpRayQueryGetWorldRayOriginKHR = 6030,
+ OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
+ OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
+ OpAtomicFAddEXT = 6035,
OpMax = 0x7fffffff,
};
@@ -1787,6 +1945,13 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
+ case OpTypeRayQueryProvisionalKHR: *hasResult = true; *hasResultType = false; break;
+ case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
+ case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
+ case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break;
+ case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break;
+ case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break;
case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
@@ -1840,6 +2005,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
+ case OpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break;
case OpDecorateString: *hasResult = false; *hasResultType = false; break;
case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
@@ -1960,6 +2127,28 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
+ case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;
+ case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;
}
}
#endif /* SPV_ENABLE_UTILITY_CODE */
@@ -1974,6 +2163,7 @@ inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask
inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); }
inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); }
inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); }
+inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); }
} // end namespace spv
diff --git a/thirdparty/glslang/SPIRV/spvIR.h b/thirdparty/glslang/SPIRV/spvIR.h
index cf6a71159a..868b9bf82d 100755..100644
--- a/thirdparty/glslang/SPIRV/spvIR.h
+++ b/thirdparty/glslang/SPIRV/spvIR.h
@@ -55,6 +55,7 @@
#include <iostream>
#include <memory>
#include <vector>
+#include <set>
namespace spv {
@@ -235,8 +236,7 @@ public:
assert(instructions.size() > 0);
instructions.resize(1);
successors.clear();
- Instruction* unreachable = new Instruction(OpUnreachable);
- addInstruction(std::unique_ptr<Instruction>(unreachable));
+ addInstruction(std::unique_ptr<Instruction>(new Instruction(OpUnreachable)));
}
// Change this block into a canonical dead continue target branching to the
// given header ID. Delete instructions as necessary. A canonical dead continue
@@ -352,10 +352,28 @@ public:
const std::vector<Block*>& getBlocks() const { return blocks; }
void addLocalVariable(std::unique_ptr<Instruction> inst);
Id getReturnType() const { return functionInstruction.getTypeId(); }
+ void setReturnPrecision(Decoration precision)
+ {
+ if (precision == DecorationRelaxedPrecision)
+ reducedPrecisionReturn = true;
+ }
+ Decoration getReturnPrecision() const
+ { return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; }
void setImplicitThis() { implicitThis = true; }
bool hasImplicitThis() const { return implicitThis; }
+ void addParamPrecision(unsigned param, Decoration precision)
+ {
+ if (precision == DecorationRelaxedPrecision)
+ reducedPrecisionParams.insert(param);
+ }
+ Decoration getParamPrecision(unsigned param) const
+ {
+ return reducedPrecisionParams.find(param) != reducedPrecisionParams.end() ?
+ DecorationRelaxedPrecision : NoPrecision;
+ }
+
void dump(std::vector<unsigned int>& out) const
{
// OpFunction
@@ -380,6 +398,8 @@ protected:
std::vector<Instruction*> parameterInstructions;
std::vector<Block*> blocks;
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
+ bool reducedPrecisionReturn;
+ std::set<int> reducedPrecisionParams; // list of parameter indexes that need a relaxed precision arg
};
//
@@ -440,7 +460,8 @@ protected:
// - the OpFunction instruction
// - all the OpFunctionParameter instructions
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
- : parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false)
+ : parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false),
+ reducedPrecisionReturn(false)
{
// OpFunction
functionInstruction.addImmediateOperand(FunctionControlMaskNone);