diff --git a/external/SPIRV-Headers b/external/SPIRV-Headers index 7bfaab982..e0282aa7d 160000 --- a/external/SPIRV-Headers +++ b/external/SPIRV-Headers @@ -1 +1 @@ -Subproject commit 7bfaab982d2452bd990804f9815775342b3467cb +Subproject commit e0282aa7d54631502b4af567a85d3b6565fd5464 diff --git a/external/SPIRV-Tools b/external/SPIRV-Tools index 6cc772c3c..18618061c 160000 --- a/external/SPIRV-Tools +++ b/external/SPIRV-Tools @@ -1 +1 @@ -Subproject commit 6cc772c3ce358193aac132a2c798e79e21aec0ad +Subproject commit 18618061cb87652246d35b45b3c401d2f0510b04 diff --git a/tools/clang/include/clang/SPIRV/Constant.h b/tools/clang/include/clang/SPIRV/Constant.h index 24f7c11a4..31b5f763a 100644 --- a/tools/clang/include/clang/SPIRV/Constant.h +++ b/tools/clang/include/clang/SPIRV/Constant.h @@ -13,7 +13,7 @@ #include #include -#include "spirv/1.0/spirv.hpp11" +#include "spirv/unified1/spirv.hpp11" #include "clang/SPIRV/Decoration.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" diff --git a/tools/clang/include/clang/SPIRV/Decoration.h b/tools/clang/include/clang/SPIRV/Decoration.h index ba224b4f2..0f5d20f13 100644 --- a/tools/clang/include/clang/SPIRV/Decoration.h +++ b/tools/clang/include/clang/SPIRV/Decoration.h @@ -11,7 +11,7 @@ #include -#include "spirv/1.0/spirv.hpp11" +#include "spirv/unified1/spirv.hpp11" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" diff --git a/tools/clang/include/clang/SPIRV/InstBuilder.h b/tools/clang/include/clang/SPIRV/InstBuilder.h index e933f1aa8..ea229a183 100644 --- a/tools/clang/include/clang/SPIRV/InstBuilder.h +++ b/tools/clang/include/clang/SPIRV/InstBuilder.h @@ -20,7 +20,7 @@ #include #include -#include "spirv/1.0/spirv.hpp11" +#include "spirv/unified1/spirv.hpp11" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" @@ -86,6 +86,7 @@ public: /// \brief Finalizes the building and returns the generated SPIR-V words. /// Returns an empty vector if errors happened during the construction. std::vector take(); + /// \brief Clears the current instruction under building. void clear(); @@ -777,6 +778,34 @@ public: opImageSparseRead(uint32_t result_type, uint32_t result_id, uint32_t image, uint32_t coordinate, llvm::Optional image_operands); + InstBuilder &opSizeOf(uint32_t result_type, uint32_t result_id, + uint32_t pointer); + InstBuilder &opTypePipeStorage(uint32_t result_id); + InstBuilder &opConstantPipeStorage(uint32_t result_type, uint32_t result_id, + uint32_t packet_size, + uint32_t packet_alignment, + uint32_t capacity); + InstBuilder &opCreatePipeFromPipeStorage(uint32_t result_type, + uint32_t result_id, + uint32_t pipe_storage); + InstBuilder & + opGetKernelLocalSizeForSubgroupCount(uint32_t result_type, uint32_t result_id, + uint32_t subgroup_count, uint32_t invoke, + uint32_t param, uint32_t param_size, + uint32_t param_align); + InstBuilder &opGetKernelMaxNumSubgroups(uint32_t result_type, + uint32_t result_id, uint32_t invoke, + uint32_t param, uint32_t param_size, + uint32_t param_align); + InstBuilder &opTypeNamedBarrier(uint32_t result_id); + InstBuilder &opNamedBarrierInitialize(uint32_t result_type, + uint32_t result_id, + uint32_t subgroup_count); + InstBuilder &opMemoryNamedBarrier(uint32_t named_barrier, uint32_t memory, + uint32_t semantics); + InstBuilder &opModuleProcessed(std::string process); + InstBuilder &opExecutionModeId(uint32_t entry_point, spv::ExecutionMode mode); + InstBuilder &opDecorateId(uint32_t target, spv::Decoration decoration); InstBuilder &opSubgroupBallotKHR(uint32_t result_type, uint32_t result_id, uint32_t predicate); InstBuilder &opSubgroupFirstInvocationKHR(uint32_t result_type, @@ -896,6 +925,7 @@ private: }; void encodeImageOperands(spv::ImageOperandsMask value); + void encodeLoopControl(spv::LoopControlMask value); void encodeMemoryAccess(spv::MemoryAccessMask value); void encodeExecutionMode(spv::ExecutionMode value); void encodeDecoration(spv::Decoration value); diff --git a/tools/clang/include/clang/SPIRV/Structure.h b/tools/clang/include/clang/SPIRV/Structure.h index ac8428358..da602ee25 100644 --- a/tools/clang/include/clang/SPIRV/Structure.h +++ b/tools/clang/include/clang/SPIRV/Structure.h @@ -24,7 +24,7 @@ #include #include -#include "spirv/1.0/spirv.hpp11" +#include "spirv/unified1/spirv.hpp11" #include "clang/SPIRV/Constant.h" #include "clang/SPIRV/InstBuilder.h" #include "clang/SPIRV/Type.h" diff --git a/tools/clang/include/clang/SPIRV/Type.h b/tools/clang/include/clang/SPIRV/Type.h index ebbcbccee..9552e1d5c 100644 --- a/tools/clang/include/clang/SPIRV/Type.h +++ b/tools/clang/include/clang/SPIRV/Type.h @@ -13,7 +13,7 @@ #include #include -#include "spirv/1.0/spirv.hpp11" +#include "spirv/unified1/spirv.hpp11" #include "clang/SPIRV/Decoration.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" diff --git a/tools/clang/lib/SPIRV/DeclResultIdMapper.h b/tools/clang/lib/SPIRV/DeclResultIdMapper.h index c37695503..9826e9e0d 100644 --- a/tools/clang/lib/SPIRV/DeclResultIdMapper.h +++ b/tools/clang/lib/SPIRV/DeclResultIdMapper.h @@ -16,7 +16,7 @@ #include "dxc/HLSL/DxilSemantic.h" #include "dxc/HLSL/DxilShaderModel.h" #include "dxc/HLSL/DxilSigPoint.h" -#include "spirv/1.0/spirv.hpp11" +#include "spirv/unified1/spirv.hpp11" #include "clang/AST/Attr.h" #include "clang/SPIRV/EmitSPIRVOptions.h" #include "clang/SPIRV/ModuleBuilder.h" diff --git a/tools/clang/lib/SPIRV/InstBuilderAuto.cpp b/tools/clang/lib/SPIRV/InstBuilderAuto.cpp index e7e5fa3b8..c47eb068d 100644 --- a/tools/clang/lib/SPIRV/InstBuilderAuto.cpp +++ b/tools/clang/lib/SPIRV/InstBuilderAuto.cpp @@ -16,7 +16,7 @@ namespace clang { namespace spirv { -static_assert(spv::Version == 0x00010000 && spv::Revision == 12, +static_assert(spv::Version == 0x00010200 && spv::Revision == 3, "Needs to regenerate outdated InstBuilder"); namespace { @@ -24,6 +24,10 @@ inline bool bitEnumContains(spv::ImageOperandsMask bits, spv::ImageOperandsMask bit) { return (uint32_t(bits) & uint32_t(bit)) != 0; } +inline bool bitEnumContains(spv::LoopControlMask bits, + spv::LoopControlMask bit) { + return (uint32_t(bits) & uint32_t(bit)) != 0; +} inline bool bitEnumContains(spv::MemoryAccessMask bits, spv::MemoryAccessMask bit) { return (uint32_t(bits) & uint32_t(bit)) != 0; @@ -5445,7 +5449,7 @@ InstBuilder &InstBuilder::opLoopMerge(uint32_t merge_block, TheInst.emplace_back(static_cast(spv::Op::OpLoopMerge)); TheInst.emplace_back(merge_block); TheInst.emplace_back(continue_target); - TheInst.emplace_back(static_cast(loop_control)); + encodeLoopControl(loop_control); return *this; } @@ -7166,6 +7170,265 @@ InstBuilder &InstBuilder::opImageSparseRead( return *this; } +InstBuilder &InstBuilder::opSizeOf(uint32_t result_type, uint32_t result_id, + uint32_t pointer) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + if (result_type == 0) { + TheStatus = Status::ZeroResultType; + return *this; + } + if (result_id == 0) { + TheStatus = Status::ZeroResultId; + return *this; + } + + TheInst.reserve(4); + TheInst.emplace_back(static_cast(spv::Op::OpSizeOf)); + TheInst.emplace_back(result_type); + TheInst.emplace_back(result_id); + TheInst.emplace_back(pointer); + + return *this; +} + +InstBuilder &InstBuilder::opTypePipeStorage(uint32_t result_id) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + if (result_id == 0) { + TheStatus = Status::ZeroResultId; + return *this; + } + + TheInst.reserve(2); + TheInst.emplace_back(static_cast(spv::Op::OpTypePipeStorage)); + TheInst.emplace_back(result_id); + + return *this; +} + +InstBuilder &InstBuilder::opConstantPipeStorage(uint32_t result_type, + uint32_t result_id, + uint32_t packet_size, + uint32_t packet_alignment, + uint32_t capacity) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + if (result_type == 0) { + TheStatus = Status::ZeroResultType; + return *this; + } + if (result_id == 0) { + TheStatus = Status::ZeroResultId; + return *this; + } + + TheInst.reserve(6); + TheInst.emplace_back(static_cast(spv::Op::OpConstantPipeStorage)); + TheInst.emplace_back(result_type); + TheInst.emplace_back(result_id); + TheInst.emplace_back(packet_size); + TheInst.emplace_back(packet_alignment); + TheInst.emplace_back(capacity); + + return *this; +} + +InstBuilder &InstBuilder::opCreatePipeFromPipeStorage(uint32_t result_type, + uint32_t result_id, + uint32_t pipe_storage) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + if (result_type == 0) { + TheStatus = Status::ZeroResultType; + return *this; + } + if (result_id == 0) { + TheStatus = Status::ZeroResultId; + return *this; + } + + TheInst.reserve(4); + TheInst.emplace_back( + static_cast(spv::Op::OpCreatePipeFromPipeStorage)); + TheInst.emplace_back(result_type); + TheInst.emplace_back(result_id); + TheInst.emplace_back(pipe_storage); + + return *this; +} + +InstBuilder &InstBuilder::opGetKernelLocalSizeForSubgroupCount( + uint32_t result_type, uint32_t result_id, uint32_t subgroup_count, + uint32_t invoke, uint32_t param, uint32_t param_size, + uint32_t param_align) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + if (result_type == 0) { + TheStatus = Status::ZeroResultType; + return *this; + } + if (result_id == 0) { + TheStatus = Status::ZeroResultId; + return *this; + } + + TheInst.reserve(8); + TheInst.emplace_back( + static_cast(spv::Op::OpGetKernelLocalSizeForSubgroupCount)); + TheInst.emplace_back(result_type); + TheInst.emplace_back(result_id); + TheInst.emplace_back(subgroup_count); + TheInst.emplace_back(invoke); + TheInst.emplace_back(param); + TheInst.emplace_back(param_size); + TheInst.emplace_back(param_align); + + return *this; +} + +InstBuilder &InstBuilder::opGetKernelMaxNumSubgroups( + uint32_t result_type, uint32_t result_id, uint32_t invoke, uint32_t param, + uint32_t param_size, uint32_t param_align) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + if (result_type == 0) { + TheStatus = Status::ZeroResultType; + return *this; + } + if (result_id == 0) { + TheStatus = Status::ZeroResultId; + return *this; + } + + TheInst.reserve(7); + TheInst.emplace_back( + static_cast(spv::Op::OpGetKernelMaxNumSubgroups)); + TheInst.emplace_back(result_type); + TheInst.emplace_back(result_id); + TheInst.emplace_back(invoke); + TheInst.emplace_back(param); + TheInst.emplace_back(param_size); + TheInst.emplace_back(param_align); + + return *this; +} + +InstBuilder &InstBuilder::opTypeNamedBarrier(uint32_t result_id) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + if (result_id == 0) { + TheStatus = Status::ZeroResultId; + return *this; + } + + TheInst.reserve(2); + TheInst.emplace_back(static_cast(spv::Op::OpTypeNamedBarrier)); + TheInst.emplace_back(result_id); + + return *this; +} + +InstBuilder &InstBuilder::opNamedBarrierInitialize(uint32_t result_type, + uint32_t result_id, + uint32_t subgroup_count) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + if (result_type == 0) { + TheStatus = Status::ZeroResultType; + return *this; + } + if (result_id == 0) { + TheStatus = Status::ZeroResultId; + return *this; + } + + TheInst.reserve(4); + TheInst.emplace_back( + static_cast(spv::Op::OpNamedBarrierInitialize)); + TheInst.emplace_back(result_type); + TheInst.emplace_back(result_id); + TheInst.emplace_back(subgroup_count); + + return *this; +} + +InstBuilder &InstBuilder::opMemoryNamedBarrier(uint32_t named_barrier, + uint32_t memory, + uint32_t semantics) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + + TheInst.reserve(4); + TheInst.emplace_back(static_cast(spv::Op::OpMemoryNamedBarrier)); + TheInst.emplace_back(named_barrier); + TheInst.emplace_back(memory); + TheInst.emplace_back(semantics); + + return *this; +} + +InstBuilder &InstBuilder::opModuleProcessed(std::string process) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + + TheInst.reserve(2); + TheInst.emplace_back(static_cast(spv::Op::OpModuleProcessed)); + encodeString(process); + + return *this; +} + +InstBuilder &InstBuilder::opExecutionModeId(uint32_t entry_point, + spv::ExecutionMode mode) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + + TheInst.reserve(3); + TheInst.emplace_back(static_cast(spv::Op::OpExecutionModeId)); + TheInst.emplace_back(entry_point); + encodeExecutionMode(mode); + + return *this; +} + +InstBuilder &InstBuilder::opDecorateId(uint32_t target, + spv::Decoration decoration) { + if (!TheInst.empty()) { + TheStatus = Status::NestedInst; + return *this; + } + + TheInst.reserve(3); + TheInst.emplace_back(static_cast(spv::Op::OpDecorateId)); + TheInst.emplace_back(target); + encodeDecoration(decoration); + + return *this; +} + InstBuilder &InstBuilder::opSubgroupBallotKHR(uint32_t result_type, uint32_t result_id, uint32_t predicate) { @@ -7831,6 +8094,13 @@ void InstBuilder::encodeImageOperands(spv::ImageOperandsMask value) { TheInst.emplace_back(static_cast(value)); } +void InstBuilder::encodeLoopControl(spv::LoopControlMask value) { + if (bitEnumContains(value, spv::LoopControlMask::DependencyLength)) { + Expectation.emplace_back(OperandKind::LiteralInteger); + } + TheInst.emplace_back(static_cast(value)); +} + void InstBuilder::encodeMemoryAccess(spv::MemoryAccessMask value) { if (bitEnumContains(value, spv::MemoryAccessMask::Aligned)) { Expectation.emplace_back(OperandKind::LiteralInteger); @@ -7859,6 +8129,23 @@ void InstBuilder::encodeExecutionMode(spv::ExecutionMode value) { case spv::ExecutionMode::VecTypeHint: { Expectation.emplace_back(OperandKind::LiteralInteger); } break; + case spv::ExecutionMode::SubgroupSize: { + Expectation.emplace_back(OperandKind::LiteralInteger); + } break; + case spv::ExecutionMode::SubgroupsPerWorkgroup: { + Expectation.emplace_back(OperandKind::LiteralInteger); + } break; + case spv::ExecutionMode::SubgroupsPerWorkgroupId: { + Expectation.emplace_back(OperandKind::IdRef); + } break; + case spv::ExecutionMode::LocalSizeId: { + Expectation.emplace_back(OperandKind::IdRef); + Expectation.emplace_back(OperandKind::IdRef); + Expectation.emplace_back(OperandKind::IdRef); + } break; + case spv::ExecutionMode::LocalSizeHintId: { + Expectation.emplace_back(OperandKind::IdRef); + } break; default: break; } @@ -7926,6 +8213,15 @@ void InstBuilder::encodeDecoration(spv::Decoration value) { case spv::Decoration::Alignment: { Expectation.emplace_back(OperandKind::LiteralInteger); } break; + case spv::Decoration::MaxByteOffset: { + Expectation.emplace_back(OperandKind::LiteralInteger); + } break; + case spv::Decoration::AlignmentId: { + Expectation.emplace_back(OperandKind::IdRef); + } break; + case spv::Decoration::MaxByteOffsetId: { + Expectation.emplace_back(OperandKind::IdRef); + } break; case spv::Decoration::SecondaryViewportRelativeNV: { Expectation.emplace_back(OperandKind::LiteralInteger); } break; diff --git a/tools/clang/lib/SPIRV/ModuleBuilder.cpp b/tools/clang/lib/SPIRV/ModuleBuilder.cpp index a5b9c00fb..2e77d0968 100644 --- a/tools/clang/lib/SPIRV/ModuleBuilder.cpp +++ b/tools/clang/lib/SPIRV/ModuleBuilder.cpp @@ -10,7 +10,7 @@ #include "clang/SPIRV/ModuleBuilder.h" #include "TypeTranslator.h" -#include "spirv/1.0//spirv.hpp11" +#include "spirv/unified1//spirv.hpp11" #include "clang/SPIRV/InstBuilder.h" #include "llvm/llvm_assert/assert.h" diff --git a/tools/clang/lib/SPIRV/SPIRVEmitter.h b/tools/clang/lib/SPIRV/SPIRVEmitter.h index 3249ddbb3..6349f2dcd 100644 --- a/tools/clang/lib/SPIRV/SPIRVEmitter.h +++ b/tools/clang/lib/SPIRV/SPIRVEmitter.h @@ -21,7 +21,7 @@ #include "dxc/HLSL/DxilShaderModel.h" #include "dxc/HlslIntrinsicOp.h" -#include "spirv/1.0/GLSL.std.450.h" +#include "spirv/unified1/GLSL.std.450.h" #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" diff --git a/tools/clang/lib/SPIRV/SpirvEvalInfo.h b/tools/clang/lib/SPIRV/SpirvEvalInfo.h index 0f3abc4ef..6bf8b3d4b 100644 --- a/tools/clang/lib/SPIRV/SpirvEvalInfo.h +++ b/tools/clang/lib/SPIRV/SpirvEvalInfo.h @@ -14,7 +14,7 @@ #ifndef LLVM_CLANG_LIB_SPIRV_SPIRVEVALINFO_H #define LLVM_CLANG_LIB_SPIRV_SPIRVEVALINFO_H -#include "spirv/1.0/spirv.hpp11" +#include "spirv/unified1/spirv.hpp11" namespace clang { namespace spirv { diff --git a/tools/clang/lib/SPIRV/Structure.cpp b/tools/clang/lib/SPIRV/Structure.cpp index 94b00d5d9..f6de89480 100644 --- a/tools/clang/lib/SPIRV/Structure.cpp +++ b/tools/clang/lib/SPIRV/Structure.cpp @@ -171,7 +171,9 @@ void Function::getReachableBasicBlocks(std::vector *bbVec) const { // === Module components implementations === Header::Header() - : magicNumber(spv::MagicNumber), version(spv::Version), + // We are using the unfied header, which shows spv::Version as the newest + // version. But we need to stick to 1.0 for Vulkan consumption. + : magicNumber(spv::MagicNumber), version(0x00010000), generator((kGeneratorNumber << 16) | kToolVersion), bound(0), reserved(0) {} @@ -370,4 +372,4 @@ void SPIRVModule::takeConstantForArrayType(const Type &arrType, } } // end namespace spirv -} // end namespace clang \ No newline at end of file +} // end namespace clang diff --git a/tools/clang/unittests/SPIRV/ModuleBuilderTest.cpp b/tools/clang/unittests/SPIRV/ModuleBuilderTest.cpp index 3e974a519..7856ebb29 100644 --- a/tools/clang/unittests/SPIRV/ModuleBuilderTest.cpp +++ b/tools/clang/unittests/SPIRV/ModuleBuilderTest.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "spirv/1.0/spirv.hpp11" +#include "spirv/unified1/spirv.hpp11" #include "clang/SPIRV/ModuleBuilder.h" #include "SPIRVTestUtils.h" @@ -24,7 +24,7 @@ TEST(ModuleBuilder, TakeModuleDirectlyCreatesHeader) { ModuleBuilder builder(&context); EXPECT_THAT(builder.takeModule(), - ElementsAre(spv::MagicNumber, spv::Version, 14u << 16, 1u, 0u)); + ElementsAre(spv::MagicNumber, 0x00010000, 14u << 16, 1u, 0u)); } TEST(ModuleBuilder, CreateFunction) { diff --git a/tools/clang/unittests/SPIRV/SPIRVTestUtils.h b/tools/clang/unittests/SPIRV/SPIRVTestUtils.h index ce3904027..27d3fb03e 100644 --- a/tools/clang/unittests/SPIRV/SPIRVTestUtils.h +++ b/tools/clang/unittests/SPIRV/SPIRVTestUtils.h @@ -18,7 +18,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "spirv/1.0/spirv.hpp11" +#include "spirv/unified1/spirv.hpp11" #include "clang/SPIRV/InstBuilder.h" #include "llvm/ADT/ArrayRef.h" @@ -35,7 +35,7 @@ inline InstBuilder constructInstBuilder(std::vector &binary) { /// Returns the words in SPIR-V module header with the given id bound. inline std::vector getModuleHeader(uint32_t bound) { - return {spv::MagicNumber, spv::Version, 14u << 16, bound, 0}; + return {spv::MagicNumber, 0x00010000, 14u << 16, bound, 0}; } /// Creates a SPIR-V instruction.