From 895bb9ffecc2c48646b50f77aeb85f5b70b9bb37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Mon, 21 Oct 2024 20:25:49 +0200 Subject: [PATCH 01/26] opt: add KHR_fragment_shading_rate to allowlist (#5859) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allowing this extensions to the few gated optimization passes. Signed-off-by: Nathan Gauër --- source/opt/aggressive_dead_code_elim_pass.cpp | 3 ++- source/opt/local_access_chain_convert_pass.cpp | 3 ++- source/opt/local_single_block_elim_pass.cpp | 3 ++- source/opt/local_single_store_elim_pass.cpp | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp index 79654224ac..444b0dbc28 100644 --- a/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/source/opt/aggressive_dead_code_elim_pass.cpp @@ -1029,7 +1029,8 @@ void AggressiveDCEPass::InitExtensions() { "SPV_KHR_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_KHR_cooperative_matrix", - "SPV_KHR_ray_tracing_position_fetch" + "SPV_KHR_ray_tracing_position_fetch", + "SPV_KHR_fragment_shading_rate" }); // clang-format on } diff --git a/source/opt/local_access_chain_convert_pass.cpp b/source/opt/local_access_chain_convert_pass.cpp index ad0277474e..91ea7c69ad 100644 --- a/source/opt/local_access_chain_convert_pass.cpp +++ b/source/opt/local_access_chain_convert_pass.cpp @@ -430,7 +430,8 @@ void LocalAccessChainConvertPass::InitExtensions() { "SPV_NV_bindless_texture", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_fragment_shader_interlock", "SPV_KHR_compute_shader_derivatives", "SPV_NV_cooperative_matrix", - "SPV_KHR_cooperative_matrix", "SPV_KHR_ray_tracing_position_fetch"}); + "SPV_KHR_cooperative_matrix", "SPV_KHR_ray_tracing_position_fetch", + "SPV_KHR_fragment_shading_rate"}); } bool LocalAccessChainConvertPass::AnyIndexIsOutOfBounds( diff --git a/source/opt/local_single_block_elim_pass.cpp b/source/opt/local_single_block_elim_pass.cpp index 7df17d5d62..f9c5a79769 100644 --- a/source/opt/local_single_block_elim_pass.cpp +++ b/source/opt/local_single_block_elim_pass.cpp @@ -294,7 +294,8 @@ void LocalSingleBlockLoadStoreElimPass::InitExtensions() { "SPV_KHR_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_KHR_cooperative_matrix", - "SPV_KHR_ray_tracing_position_fetch"}); + "SPV_KHR_ray_tracing_position_fetch", + "SPV_KHR_fragment_shading_rate"}); } } // namespace opt diff --git a/source/opt/local_single_store_elim_pass.cpp b/source/opt/local_single_store_elim_pass.cpp index bb7bba87eb..38fa14ef46 100644 --- a/source/opt/local_single_store_elim_pass.cpp +++ b/source/opt/local_single_store_elim_pass.cpp @@ -144,7 +144,8 @@ void LocalSingleStoreElimPass::InitExtensionAllowList() { "SPV_KHR_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_KHR_cooperative_matrix", - "SPV_KHR_ray_tracing_position_fetch"}); + "SPV_KHR_ray_tracing_position_fetch", + "SPV_KHR_fragment_shading_rate"}); } bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) { std::vector users; From 298055b25cab863d73a8588ce482d8e77c77b807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Thu, 24 Oct 2024 12:21:17 +0200 Subject: [PATCH 02/26] opt: add StorageImageWriteWithoutFormat to trimm pass (#5860) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * opt: add StorageImageWriteWithoutFormat to trimm pass --------- Signed-off-by: Nathan Gauër --- source/opt/trim_capabilities_pass.cpp | 26 ++++++- source/opt/trim_capabilities_pass.h | 1 + test/opt/trim_capabilities_pass_test.cpp | 88 ++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 1 deletion(-) diff --git a/source/opt/trim_capabilities_pass.cpp b/source/opt/trim_capabilities_pass.cpp index 8a8535143d..34fbc4496b 100644 --- a/source/opt/trim_capabilities_pass.cpp +++ b/source/opt/trim_capabilities_pass.cpp @@ -49,6 +49,7 @@ constexpr uint32_t kOpTypeImageMSIndex = kOpTypeImageArrayedIndex + 1; constexpr uint32_t kOpTypeImageSampledIndex = kOpTypeImageMSIndex + 1; constexpr uint32_t kOpTypeImageFormatIndex = kOpTypeImageSampledIndex + 1; constexpr uint32_t kOpImageReadImageIndex = 0; +constexpr uint32_t kOpImageWriteImageIndex = 0; constexpr uint32_t kOpImageSparseReadImageIndex = 0; constexpr uint32_t kOpExtInstSetInIndex = 0; constexpr uint32_t kOpExtInstInstructionInIndex = 1; @@ -338,6 +339,8 @@ Handler_OpImageRead_StorageImageReadWithoutFormat( const uint32_t dim = type->GetSingleWordInOperand(kOpTypeImageDimIndex); const uint32_t format = type->GetSingleWordInOperand(kOpTypeImageFormatIndex); + // If the Image Format is Unknown and Dim is SubpassData, + // StorageImageReadWithoutFormat is required. const bool is_unknown = spv::ImageFormat(format) == spv::ImageFormat::Unknown; const bool requires_capability_for_unknown = spv::Dim(dim) != spv::Dim::SubpassData; @@ -346,6 +349,26 @@ Handler_OpImageRead_StorageImageReadWithoutFormat( : std::nullopt; } +static std::optional +Handler_OpImageWrite_StorageImageWriteWithoutFormat( + const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpImageWrite && + "This handler only support OpImageWrite opcodes."); + const auto* def_use_mgr = instruction->context()->get_def_use_mgr(); + + const uint32_t image_index = + instruction->GetSingleWordInOperand(kOpImageWriteImageIndex); + const uint32_t type_index = def_use_mgr->GetDef(image_index)->type_id(); + + // If the Image Format is Unknown, StorageImageWriteWithoutFormat is required. + const Instruction* type = def_use_mgr->GetDef(type_index); + const uint32_t format = type->GetSingleWordInOperand(kOpTypeImageFormatIndex); + const bool is_unknown = spv::ImageFormat(format) == spv::ImageFormat::Unknown; + return is_unknown + ? std::optional(spv::Capability::StorageImageWriteWithoutFormat) + : std::nullopt; +} + static std::optional Handler_OpImageSparseRead_StorageImageReadWithoutFormat( const Instruction* instruction) { @@ -365,9 +388,10 @@ Handler_OpImageSparseRead_StorageImageReadWithoutFormat( } // Opcode of interest to determine capabilities requirements. -constexpr std::array, 12> kOpcodeHandlers{{ +constexpr std::array, 13> kOpcodeHandlers{{ // clang-format off {spv::Op::OpImageRead, Handler_OpImageRead_StorageImageReadWithoutFormat}, + {spv::Op::OpImageWrite, Handler_OpImageWrite_StorageImageWriteWithoutFormat}, {spv::Op::OpImageSparseRead, Handler_OpImageSparseRead_StorageImageReadWithoutFormat}, {spv::Op::OpTypeFloat, Handler_OpTypeFloat_Float16 }, {spv::Op::OpTypeFloat, Handler_OpTypeFloat_Float64 }, diff --git a/source/opt/trim_capabilities_pass.h b/source/opt/trim_capabilities_pass.h index 91d32a563b..1d1183ab23 100644 --- a/source/opt/trim_capabilities_pass.h +++ b/source/opt/trim_capabilities_pass.h @@ -100,6 +100,7 @@ class TrimCapabilitiesPass : public Pass { spv::Capability::Shader, spv::Capability::ShaderClockKHR, spv::Capability::StorageImageReadWithoutFormat, + spv::Capability::StorageImageWriteWithoutFormat, spv::Capability::StorageInputOutput16, spv::Capability::StoragePushConstant16, spv::Capability::StorageUniform16, diff --git a/test/opt/trim_capabilities_pass_test.cpp b/test/opt/trim_capabilities_pass_test.cpp index 66004f07bd..fe5290520c 100644 --- a/test/opt/trim_capabilities_pass_test.cpp +++ b/test/opt/trim_capabilities_pass_test.cpp @@ -2366,6 +2366,94 @@ TEST_F(TrimCapabilitiesPassTest, EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); } +TEST_F(TrimCapabilitiesPassTest, + StorageImageWriteWithoutFormat_RemainsWhenRequiredWithWrite) { + const std::string kTest = R"( + OpCapability StorageImageWriteWithoutFormat +; CHECK: OpCapability StorageImageWriteWithoutFormat + OpCapability Shader + OpCapability StorageImageExtendedFormats + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" %id %img + OpExecutionMode %main LocalSize 8 8 8 + OpSource HLSL 670 + OpName %type_image "type.3d.image" + OpName %img "img" + OpName %main "main" + OpDecorate %id BuiltIn GlobalInvocationId + OpDecorate %img DescriptorSet 0 + OpDecorate %img Binding 0 + %float = OpTypeFloat 32 + %float_4 = OpConstant %float 4 + %float_5 = OpConstant %float 5 + %v2float = OpTypeVector %float 2 + %9 = OpConstantComposite %v2float %float_4 %float_5 + %type_image = OpTypeImage %float 3D 2 0 0 2 Unknown + %ptr_img = OpTypePointer UniformConstant %type_image + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 + %ptr_input = OpTypePointer Input %v3uint + %void = OpTypeVoid + %15 = OpTypeFunction %void + %img = OpVariable %ptr_img UniformConstant + %id = OpVariable %ptr_input Input + %main = OpFunction %void None %15 + %16 = OpLabel + %17 = OpLoad %v3uint %id + %18 = OpLoad %type_image %img + OpImageWrite %18 %17 %9 None + OpReturn + OpFunctionEnd + )"; + const auto result = + SinglePassRunAndMatch(kTest, /* skip_nop= */ false); + EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); +} + +TEST_F(TrimCapabilitiesPassTest, + StorageImageWriteWithoutFormat_RemovedWithWriteOnKnownFormat) { + const std::string kTest = R"( + OpCapability StorageImageWriteWithoutFormat +; CHECK-NOT: OpCapability StorageImageWriteWithoutFormat + OpCapability Shader + OpCapability StorageImageExtendedFormats + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" %id %img + OpExecutionMode %main LocalSize 8 8 8 + OpSource HLSL 670 + OpName %type_image "type.3d.image" + OpName %img "img" + OpName %main "main" + OpDecorate %id BuiltIn GlobalInvocationId + OpDecorate %img DescriptorSet 0 + OpDecorate %img Binding 0 + %float = OpTypeFloat 32 + %float_4 = OpConstant %float 4 + %float_5 = OpConstant %float 5 + %v2float = OpTypeVector %float 2 + %9 = OpConstantComposite %v2float %float_4 %float_5 + %type_image = OpTypeImage %float 3D 2 0 0 2 Rg32f + %ptr_img = OpTypePointer UniformConstant %type_image + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 + %ptr_input = OpTypePointer Input %v3uint + %void = OpTypeVoid + %15 = OpTypeFunction %void + %img = OpVariable %ptr_img UniformConstant + %id = OpVariable %ptr_input Input + %main = OpFunction %void None %15 + %16 = OpLabel + %17 = OpLoad %v3uint %id + %18 = OpLoad %type_image %img + OpImageWrite %18 %17 %9 None + OpReturn + OpFunctionEnd + )"; + const auto result = + SinglePassRunAndMatch(kTest, /* skip_nop= */ false); + EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); +} + TEST_F(TrimCapabilitiesPassTest, PhysicalStorageBuffer_RemovedWhenUnused) { const std::string kTest = R"( OpCapability PhysicalStorageBufferAddresses From ce92630396c2fd2d6d04819369116af4fb141a28 Mon Sep 17 00:00:00 2001 From: Jeff Bolz Date: Thu, 24 Oct 2024 12:55:04 -0500 Subject: [PATCH 03/26] Add validation for SPV_NV_tensor_addressing and SPV_NV_cooperative_matrix2 (#5865) --- Android.mk | 1 + BUILD.gn | 1 + DEPS | 2 +- include/spirv-tools/libspirv.h | 6 + source/CMakeLists.txt | 1 + source/binary.cpp | 5 +- source/opcode.cpp | 2 + source/operand.cpp | 19 + source/opt/aggressive_dead_code_elim_pass.cpp | 6 + source/opt/eliminate_dead_members_pass.cpp | 15 + source/opt/ir_context.cpp | 28 +- source/opt/type_manager.cpp | 48 ++ source/opt/types.cpp | 54 +- source/opt/types.h | 53 ++ source/text.cpp | 4 +- source/val/validate.cpp | 1 + source/val/validate.h | 3 + source/val/validate_arithmetics.cpp | 128 +++- source/val/validate_conversion.cpp | 53 +- source/val/validate_function.cpp | 83 ++- source/val/validate_instruction.cpp | 6 + source/val/validate_memory.cpp | 227 ++++++- source/val/validate_tensor_layout.cpp | 184 +++++ source/val/validate_type.cpp | 147 ++++ source/val/validation_state.cpp | 20 +- source/val/validation_state.h | 30 +- test/opt/type_manager_test.cpp | 6 + test/val/val_arithmetics_test.cpp | 255 ++++++- test/val/val_conversion_test.cpp | 190 +++++- test/val/val_memory_test.cpp | 633 ++++++++++++++++++ test/val/val_misc_test.cpp | 71 ++ utils/check_copyright.py | 3 +- 32 files changed, 2247 insertions(+), 38 deletions(-) create mode 100644 source/val/validate_tensor_layout.cpp diff --git a/Android.mk b/Android.mk index abbd42b23f..1414b52497 100644 --- a/Android.mk +++ b/Android.mk @@ -75,6 +75,7 @@ SPVTOOLS_SRC_FILES := \ source/val/validate_ray_tracing_reorder.cpp \ source/val/validate_scopes.cpp \ source/val/validate_small_type_uses.cpp \ + source/val/validate_tensor_layout.cpp \ source/val/validate_type.cpp SPVTOOLS_OPT_SRC_FILES := \ diff --git a/BUILD.gn b/BUILD.gn index 59a34d6f94..23610262ea 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -557,6 +557,7 @@ static_library("spvtools_val") { "source/val/validate_scopes.cpp", "source/val/validate_scopes.h", "source/val/validate_small_type_uses.cpp", + "source/val/validate_tensor_layout.cpp", "source/val/validate_type.cpp", "source/val/validation_state.cpp", "source/val/validation_state.h", diff --git a/DEPS b/DEPS index 69ad610900..4543be7bc2 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 're2_revision': '6dcd83d60f7944926bfd308cc13979fc53dd69ca', - 'spirv_headers_revision': '50bc4debdc3eec5045edbeb8ce164090e29b91f3', + 'spirv_headers_revision': '22c4d1b1e9d1c7d9aa5086c93e6491f21080019b', } deps = { diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h index 1a21ccef0f..70931cb6c4 100644 --- a/include/spirv-tools/libspirv.h +++ b/include/spirv-tools/libspirv.h @@ -314,6 +314,12 @@ typedef enum spv_operand_type_t { SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS, // Optional enum type from SPV_NV_raw_access_chains SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS, + // Enum type from SPV_NV_tensor_addressing + SPV_OPERAND_TYPE_TENSOR_CLAMP_MODE, + // Enum type from SPV_NV_cooperative_matrix2 + SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE, + // Enum type from SPV_NV_cooperative_matrix2 + SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS, // This is a sentinel value, and does not represent an operand type. // It should come last. diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index cb6026ad50..b20357bbc1 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -334,6 +334,7 @@ set(SPIRV_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_tracing_reorder.cpp ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_scopes.cpp ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_small_type_uses.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_tensor_layout.cpp ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_type.cpp ${CMAKE_CURRENT_SOURCE_DIR}/val/decoration.h ${CMAKE_CURRENT_SOURCE_DIR}/val/basic_block.cpp diff --git a/source/binary.cpp b/source/binary.cpp index 772e98c0a2..ed57498576 100644 --- a/source/binary.cpp +++ b/source/binary.cpp @@ -717,13 +717,16 @@ spv_result_t Parser::parseOperand(size_t inst_offset, case SPV_OPERAND_TYPE_LOOP_CONTROL: case SPV_OPERAND_TYPE_IMAGE: case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: + case SPV_OPERAND_TYPE_MEMORY_ACCESS: case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS: case SPV_OPERAND_TYPE_SELECTION_CONTROL: case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS: - case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: { + case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE: + case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS: { // This operand is a mask. // Map an optional operand type to its corresponding concrete type. diff --git a/source/opcode.cpp b/source/opcode.cpp index ea03bd6711..2b25fc3da1 100644 --- a/source/opcode.cpp +++ b/source/opcode.cpp @@ -382,6 +382,8 @@ int32_t spvOpcodeGeneratesType(spv::Op op) { case spv::Op::OpTypeRayQueryKHR: case spv::Op::OpTypeHitObjectNV: case spv::Op::OpTypeUntypedPointerKHR: + case spv::Op::OpTypeTensorLayoutNV: + case spv::Op::OpTypeTensorViewNV: return true; default: // In particular, OpTypeForwardPointer does not generate a type, diff --git a/source/operand.cpp b/source/operand.cpp index 9bee647fca..548564662e 100644 --- a/source/operand.cpp +++ b/source/operand.cpp @@ -231,6 +231,12 @@ const char* spvOperandTypeStr(spv_operand_type_t type) { return "cooperative matrix layout"; case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE: return "cooperative matrix use"; + case SPV_OPERAND_TYPE_TENSOR_CLAMP_MODE: + return "tensor clamp mode"; + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE: + return "cooperative matrix reduce"; + case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS: + return "tensor addressing operands"; case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER: return "initialization mode qualifier"; case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER: @@ -389,6 +395,7 @@ bool spvOperandIsConcrete(spv_operand_type_t type) { case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL: case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS: case SPV_OPERAND_TYPE_FPENCODING: + case SPV_OPERAND_TYPE_TENSOR_CLAMP_MODE: return true; default: break; @@ -409,6 +416,8 @@ bool spvOperandIsConcreteMask(spv_operand_type_t type) { case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS: case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS: + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE: + case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS: return true; default: break; @@ -598,6 +607,16 @@ std::function spvOperandCanBeForwardDeclaredFunction( case spv::Op::OpTypeArray: out = [](unsigned index) { return index == 1; }; break; + case spv::Op::OpCooperativeMatrixPerElementOpNV: + out = [](unsigned index) { return index == 3; }; + break; + case spv::Op::OpCooperativeMatrixReduceNV: + out = [](unsigned index) { return index == 4; }; + break; + case spv::Op::OpCooperativeMatrixLoadTensorNV: + // approximate, due to variable operands + out = [](unsigned index) { return index > 6; }; + break; default: out = [](unsigned) { return false; }; break; diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp index 444b0dbc28..d78d63ca02 100644 --- a/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/source/opt/aggressive_dead_code_elim_pass.cpp @@ -43,6 +43,7 @@ constexpr uint32_t kGlobalVariableVariableIndex = 12; constexpr uint32_t kExtInstSetInIdx = 0; constexpr uint32_t kExtInstOpInIdx = 1; constexpr uint32_t kInterpolantInIdx = 2; +constexpr uint32_t kCooperativeMatrixLoadSourceAddrInIdx = 0; // Sorting functor to present annotation instructions in an easy-to-process // order. The functor orders by opcode first and falls back on unique id @@ -438,6 +439,11 @@ uint32_t AggressiveDCEPass::GetLoadedVariableFromNonFunctionCalls( } break; } + case spv::Op::OpCooperativeMatrixLoadNV: + case spv::Op::OpCooperativeMatrixLoadKHR: + case spv::Op::OpCooperativeMatrixLoadTensorNV: + return GetVariableId( + inst->GetSingleWordInOperand(kCooperativeMatrixLoadSourceAddrInIdx)); default: break; } diff --git a/source/opt/eliminate_dead_members_pass.cpp b/source/opt/eliminate_dead_members_pass.cpp index 1c98502e22..e440296ffd 100644 --- a/source/opt/eliminate_dead_members_pass.cpp +++ b/source/opt/eliminate_dead_members_pass.cpp @@ -70,6 +70,11 @@ void EliminateDeadMembersPass::FindLiveMembers() { MarkPointeeTypeAsFullUsed(inst.type_id()); break; } + } else if (inst.opcode() == spv::Op::OpTypePointer) { + uint32_t storage_class = inst.GetSingleWordInOperand(0); + if (storage_class == uint32_t(spv::StorageClass::PhysicalStorageBuffer)) { + MarkTypeAsFullyUsed(inst.GetSingleWordInOperand(1)); + } } } @@ -200,6 +205,8 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForExtract( case spv::Op::OpTypeRuntimeArray: case spv::Op::OpTypeVector: case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: type_id = type_inst->GetSingleWordInOperand(0); break; default: @@ -246,6 +253,8 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForAccessChain( case spv::Op::OpTypeRuntimeArray: case spv::Op::OpTypeVector: case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: type_id = type_inst->GetSingleWordInOperand(0); break; default: @@ -505,6 +514,8 @@ bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) { case spv::Op::OpTypeRuntimeArray: case spv::Op::OpTypeVector: case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: new_operands.emplace_back(inst->GetInOperand(i)); type_id = type_inst->GetSingleWordInOperand(0); break; @@ -578,6 +589,8 @@ bool EliminateDeadMembersPass::UpdateCompsiteExtract(Instruction* inst) { case spv::Op::OpTypeRuntimeArray: case spv::Op::OpTypeVector: case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: type_id = type_inst->GetSingleWordInOperand(0); break; default: @@ -639,6 +652,8 @@ bool EliminateDeadMembersPass::UpdateCompositeInsert(Instruction* inst) { case spv::Op::OpTypeRuntimeArray: case spv::Op::OpTypeVector: case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: type_id = type_inst->GetSingleWordInOperand(0); break; default: diff --git a/source/opt/ir_context.cpp b/source/opt/ir_context.cpp index d864b7c02e..1cf0d74bf5 100644 --- a/source/opt/ir_context.cpp +++ b/source/opt/ir_context.cpp @@ -926,9 +926,35 @@ uint32_t IRContext::GetBuiltinInputVarId(uint32_t builtin) { void IRContext::AddCalls(const Function* func, std::queue* todo) { for (auto bi = func->begin(); bi != func->end(); ++bi) - for (auto ii = bi->begin(); ii != bi->end(); ++ii) + for (auto ii = bi->begin(); ii != bi->end(); ++ii) { if (ii->opcode() == spv::Op::OpFunctionCall) todo->push(ii->GetSingleWordInOperand(0)); + if (ii->opcode() == spv::Op::OpCooperativeMatrixPerElementOpNV) + todo->push(ii->GetSingleWordInOperand(1)); + if (ii->opcode() == spv::Op::OpCooperativeMatrixReduceNV) + todo->push(ii->GetSingleWordInOperand(2)); + if (ii->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) { + const auto memory_operands_index = 3; + auto mask = ii->GetSingleWordInOperand(memory_operands_index); + + uint32_t count = 1; + if (mask & uint32_t(spv::MemoryAccessMask::Aligned)) ++count; + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) + ++count; + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) + ++count; + + const auto tensor_operands_index = memory_operands_index + count; + mask = ii->GetSingleWordInOperand(tensor_operands_index); + count = 1; + if (mask & uint32_t(spv::TensorAddressingOperandsMask::TensorView)) + ++count; + + if (mask & uint32_t(spv::TensorAddressingOperandsMask::DecodeFunc)) { + todo->push(ii->GetSingleWordInOperand(tensor_operands_index + count)); + } + } + } } bool IRContext::ProcessEntryPointCallTree(ProcessFunction& pfn) { diff --git a/source/opt/type_manager.cpp b/source/opt/type_manager.cpp index 79648ad497..88106b6087 100644 --- a/source/opt/type_manager.cpp +++ b/source/opt/type_manager.cpp @@ -441,6 +441,28 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { {SPV_OPERAND_TYPE_ID, {coop_mat->use_id()}}}); break; } + case Type::kTensorLayoutNV: { + auto tensor_layout = type->AsTensorLayoutNV(); + typeInst = MakeUnique( + context(), spv::Op::OpTypeTensorLayoutNV, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {tensor_layout->dim_id()}}, + {SPV_OPERAND_TYPE_ID, {tensor_layout->clamp_mode_id()}}}); + break; + } + case Type::kTensorViewNV: { + auto tensor_view = type->AsTensorViewNV(); + std::vector operands; + operands.push_back(Operand{SPV_OPERAND_TYPE_ID, {tensor_view->dim_id()}}); + operands.push_back( + Operand{SPV_OPERAND_TYPE_ID, {tensor_view->has_dimensions_id()}}); + for (auto p : tensor_view->perm()) { + operands.push_back(Operand{SPV_OPERAND_TYPE_ID, {p}}); + } + typeInst = MakeUnique(context(), spv::Op::OpTypeTensorViewNV, + 0, id, operands); + break; + } default: assert(false && "Unexpected type"); break; @@ -667,6 +689,18 @@ Type* TypeManager::RebuildType(uint32_t type_id, const Type& type) { cm_type->use_id()); break; } + case Type::kTensorLayoutNV: { + const TensorLayoutNV* tl_type = type.AsTensorLayoutNV(); + rebuilt_ty = MakeUnique(tl_type->dim_id(), + tl_type->clamp_mode_id()); + break; + } + case Type::kTensorViewNV: { + const TensorViewNV* tv_type = type.AsTensorViewNV(); + rebuilt_ty = MakeUnique( + tv_type->dim_id(), tv_type->has_dimensions_id(), tv_type->perm()); + break; + } default: assert(false && "Unhandled type"); return nullptr; @@ -914,6 +948,20 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { case spv::Op::OpTypeHitObjectNV: type = new HitObjectNV(); break; + case spv::Op::OpTypeTensorLayoutNV: + type = new TensorLayoutNV(inst.GetSingleWordInOperand(0), + inst.GetSingleWordInOperand(1)); + break; + case spv::Op::OpTypeTensorViewNV: { + const auto count = inst.NumOperands(); + std::vector perm; + for (uint32_t i = 2; i < count; ++i) { + perm.push_back(inst.GetSingleWordOperand(i)); + } + type = new TensorViewNV(inst.GetSingleWordInOperand(0), + inst.GetSingleWordInOperand(1), perm); + break; + } default: assert(false && "Type not handled by the type manager."); break; diff --git a/source/opt/types.cpp b/source/opt/types.cpp index b18b8cb1ae..8ccf6c9a2f 100644 --- a/source/opt/types.cpp +++ b/source/opt/types.cpp @@ -179,6 +179,8 @@ bool Type::operator==(const Type& other) const { DeclareKindCase(CooperativeMatrixKHR); DeclareKindCase(RayQueryKHR); DeclareKindCase(HitObjectNV); + DeclareKindCase(TensorLayoutNV); + DeclareKindCase(TensorViewNV); #undef DeclareKindCase default: assert(false && "Unhandled type"); @@ -235,6 +237,8 @@ size_t Type::ComputeHashValue(size_t hash, SeenTypes* seen) const { DeclareKindCase(CooperativeMatrixKHR); DeclareKindCase(RayQueryKHR); DeclareKindCase(HitObjectNV); + DeclareKindCase(TensorLayoutNV); + DeclareKindCase(TensorViewNV); #undef DeclareKindCase default: assert(false && "Unhandled type"); @@ -747,7 +751,55 @@ bool CooperativeMatrixKHR::IsSameImpl(const Type* that, if (!mt) return false; return component_type_->IsSameImpl(mt->component_type_, seen) && scope_id_ == mt->scope_id_ && rows_id_ == mt->rows_id_ && - columns_id_ == mt->columns_id_ && HasSameDecorations(that); + columns_id_ == mt->columns_id_ && use_id_ == mt->use_id_ && + HasSameDecorations(that); +} + +TensorLayoutNV::TensorLayoutNV(const uint32_t dim, const uint32_t clamp_mode) + : Type(kTensorLayoutNV), dim_id_(dim), clamp_mode_id_(clamp_mode) {} + +std::string TensorLayoutNV::str() const { + std::ostringstream oss; + oss << "<" << dim_id_ << ", " << clamp_mode_id_ << ">"; + return oss.str(); +} + +size_t TensorLayoutNV::ComputeExtraStateHash(size_t hash, SeenTypes*) const { + return hash_combine(hash, dim_id_, clamp_mode_id_); +} + +bool TensorLayoutNV::IsSameImpl(const Type* that, IsSameCache*) const { + const TensorLayoutNV* tl = that->AsTensorLayoutNV(); + if (!tl) return false; + return dim_id_ == tl->dim_id_ && clamp_mode_id_ == tl->clamp_mode_id_; +} + +TensorViewNV::TensorViewNV(const uint32_t dim, const uint32_t clamp_mode, + const std::vector& perm) + : Type(kTensorViewNV), + dim_id_(dim), + has_dimensions_id_(clamp_mode), + perm_(perm) {} + +std::string TensorViewNV::str() const { + std::ostringstream oss; + oss << "<" << dim_id_ << ", " << has_dimensions_id_; + for (auto p : perm_) { + oss << ", " << p; + } + oss << ">"; + return oss.str(); +} + +size_t TensorViewNV::ComputeExtraStateHash(size_t hash, SeenTypes*) const { + return hash_combine(hash, dim_id_, has_dimensions_id_, perm_); +} + +bool TensorViewNV::IsSameImpl(const Type* that, IsSameCache*) const { + const TensorViewNV* tv = that->AsTensorViewNV(); + if (!tv) return false; + return dim_id_ == tv->dim_id_ && + has_dimensions_id_ == tv->has_dimensions_id_ && perm_ == tv->perm_; } } // namespace analysis diff --git a/source/opt/types.h b/source/opt/types.h index 16a948cec5..6092c3c92c 100644 --- a/source/opt/types.h +++ b/source/opt/types.h @@ -63,6 +63,8 @@ class CooperativeMatrixNV; class CooperativeMatrixKHR; class RayQueryKHR; class HitObjectNV; +class TensorLayoutNV; +class TensorViewNV; // Abstract class for a SPIR-V type. It has a bunch of As() methods, // which is used as a way to probe the actual . @@ -104,6 +106,8 @@ class Type { kCooperativeMatrixKHR, kRayQueryKHR, kHitObjectNV, + kTensorLayoutNV, + kTensorViewNV, kLast }; @@ -206,6 +210,8 @@ class Type { DeclareCastMethod(CooperativeMatrixKHR) DeclareCastMethod(RayQueryKHR) DeclareCastMethod(HitObjectNV) + DeclareCastMethod(TensorLayoutNV) + DeclareCastMethod(TensorViewNV) #undef DeclareCastMethod protected: @@ -659,6 +665,53 @@ class CooperativeMatrixKHR : public Type { const uint32_t use_id_; }; +class TensorLayoutNV : public Type { + public: + TensorLayoutNV(const uint32_t dim, const uint32_t clamp_mode); + TensorLayoutNV(const TensorLayoutNV&) = default; + + std::string str() const override; + + TensorLayoutNV* AsTensorLayoutNV() override { return this; } + const TensorLayoutNV* AsTensorLayoutNV() const override { return this; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + uint32_t dim_id() const { return dim_id_; } + uint32_t clamp_mode_id() const { return clamp_mode_id_; } + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const uint32_t dim_id_; + const uint32_t clamp_mode_id_; +}; + +class TensorViewNV : public Type { + public: + TensorViewNV(const uint32_t dim, const uint32_t clamp_mode, + const std::vector& perm); + TensorViewNV(const TensorViewNV&) = default; + + std::string str() const override; + + TensorViewNV* AsTensorViewNV() override { return this; } + const TensorViewNV* AsTensorViewNV() const override { return this; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + uint32_t dim_id() const { return dim_id_; } + uint32_t has_dimensions_id() const { return has_dimensions_id_; } + const std::vector& perm() const { return perm_; } + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const uint32_t dim_id_; + const uint32_t has_dimensions_id_; + std::vector perm_; +}; + #define DefineParameterlessType(type, name) \ class type : public Type { \ public: \ diff --git a/source/text.cpp b/source/text.cpp index fda46ec2ef..1723bb3171 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -414,7 +414,9 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, case SPV_OPERAND_TYPE_SELECTION_CONTROL: case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: - case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: { + case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: + case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS: + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE: { uint32_t value; if (auto error = grammar.parseMaskOperand(type, textValue, &value)) { return context->diagnostic(error) diff --git a/source/val/validate.cpp b/source/val/validate.cpp index 32368075c5..2d10347d80 100644 --- a/source/val/validate.cpp +++ b/source/val/validate.cpp @@ -366,6 +366,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( if (auto error = RayTracingPass(*vstate, &instruction)) return error; if (auto error = RayReorderNVPass(*vstate, &instruction)) return error; if (auto error = MeshShadingPass(*vstate, &instruction)) return error; + if (auto error = TensorLayoutPass(*vstate, &instruction)) return error; } // Validate the preconditions involving adjacent instructions. e.g. diff --git a/source/val/validate.h b/source/val/validate.h index 78093ce5fd..5514ff738e 100644 --- a/source/val/validate.h +++ b/source/val/validate.h @@ -226,6 +226,9 @@ spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst); /// Calculates the reachability of basic blocks. void ReachabilityPass(ValidationState_t& _); +/// Validates tensor layout and view instructions. +spv_result_t TensorLayoutPass(ValidationState_t& _, const Instruction* inst); + /// Validates execution limitations. /// /// Verifies execution models are allowed for all functionality they contain. diff --git a/source/val/validate_arithmetics.cpp b/source/val/validate_arithmetics.cpp index b608a85952..8b0049c5b4 100644 --- a/source/val/validate_arithmetics.cpp +++ b/source/val/validate_arithmetics.cpp @@ -62,7 +62,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { << operand_index; } spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, type_id, result_type); + _.CooperativeMatrixShapesMatch(inst, result_type, type_id, false); if (ret != SPV_SUCCESS) return ret; } else if (_.GetOperandTypeId(inst, operand_index) != result_type) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -96,7 +96,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { << operand_index; } spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, type_id, result_type); + _.CooperativeMatrixShapesMatch(inst, result_type, type_id, false); if (ret != SPV_SUCCESS) return ret; } else if (_.GetOperandTypeId(inst, operand_index) != result_type) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -142,7 +142,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { << operand_index; } spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, type_id, result_type); + _.CooperativeMatrixShapesMatch(inst, result_type, type_id, false); if (ret != SPV_SUCCESS) return ret; } @@ -672,6 +672,128 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } + case spv::Op::OpCooperativeMatrixReduceNV: { + if (!_.IsCooperativeMatrixKHRType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result Type must be a cooperative matrix type: " + << spvOpcodeString(opcode); + } + + const auto result_comp_type_id = + _.FindDef(result_type)->GetOperandAs(1); + + const auto matrix_id = inst->GetOperandAs(2); + const auto matrix = _.FindDef(matrix_id); + const auto matrix_type_id = matrix->type_id(); + if (!_.IsCooperativeMatrixKHRType(matrix_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Matrix must have a cooperative matrix type: " + << spvOpcodeString(opcode); + } + const auto matrix_type = _.FindDef(matrix_type_id); + const auto matrix_comp_type_id = matrix_type->GetOperandAs(1); + if (matrix_comp_type_id != result_comp_type_id) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result Type and Matrix type must have the same component " + "type: " + << spvOpcodeString(opcode); + } + if (_.FindDef(result_type)->GetOperandAs(2) != + matrix_type->GetOperandAs(2)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result Type and Matrix type must have the same scope: " + << spvOpcodeString(opcode); + } + + if (!_.IsCooperativeMatrixAccType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result Type must have UseAccumulator: " + << spvOpcodeString(opcode); + } + if (!_.IsCooperativeMatrixAccType(matrix_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Matrix type must have UseAccumulator: " + << spvOpcodeString(opcode); + } + + const auto reduce_value = inst->GetOperandAs(3); + + if ((reduce_value & + uint32_t( + spv::CooperativeMatrixReduceMask::CooperativeMatrixReduce2x2)) && + (reduce_value & uint32_t(spv::CooperativeMatrixReduceMask::Row | + spv::CooperativeMatrixReduceMask::Column))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Reduce 2x2 must not be used with Row/Column: " + << spvOpcodeString(opcode); + } + + std::tuple result_rows, result_cols, matrix_rows, + matrix_cols; + result_rows = + _.EvalInt32IfConst(_.FindDef(result_type)->GetOperandAs(3)); + result_cols = + _.EvalInt32IfConst(_.FindDef(result_type)->GetOperandAs(4)); + matrix_rows = _.EvalInt32IfConst(matrix_type->GetOperandAs(3)); + matrix_cols = _.EvalInt32IfConst(matrix_type->GetOperandAs(4)); + + if (reduce_value & + uint32_t( + spv::CooperativeMatrixReduceMask::CooperativeMatrixReduce2x2)) { + if (std::get<1>(result_rows) && std::get<1>(result_cols) && + std::get<1>(matrix_rows) && std::get<1>(matrix_cols) && + (std::get<2>(result_rows) != std::get<2>(matrix_rows) / 2 || + std::get<2>(result_cols) != std::get<2>(matrix_cols) / 2)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "For Reduce2x2, result rows/cols must be half of matrix " + "rows/cols: " + << spvOpcodeString(opcode); + } + } + if (reduce_value == uint32_t(spv::CooperativeMatrixReduceMask::Row)) { + if (std::get<1>(result_rows) && std::get<1>(matrix_rows) && + std::get<2>(result_rows) != std::get<2>(matrix_rows)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "For ReduceRow, result rows must match matrix rows: " + << spvOpcodeString(opcode); + } + } + if (reduce_value == uint32_t(spv::CooperativeMatrixReduceMask::Column)) { + if (std::get<1>(result_cols) && std::get<1>(matrix_cols) && + std::get<2>(result_cols) != std::get<2>(matrix_cols)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "For ReduceColumn, result cols must match matrix cols: " + << spvOpcodeString(opcode); + } + } + + const auto combine_func_id = inst->GetOperandAs(4); + const auto combine_func = _.FindDef(combine_func_id); + if (!combine_func || combine_func->opcode() != spv::Op::OpFunction) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "CombineFunc must be a function: " << spvOpcodeString(opcode); + } + const auto function_type_id = combine_func->GetOperandAs(3); + const auto function_type = _.FindDef(function_type_id); + if (function_type->operands().size() != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "CombineFunc must have two parameters: " + << spvOpcodeString(opcode); + } + for (uint32_t i = 0; i < 3; ++i) { + // checks return type and two params + const auto param_type_id = function_type->GetOperandAs(i + 1); + if (param_type_id != matrix_comp_type_id) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "CombineFunc return type and parameters must match matrix " + "component type: " + << spvOpcodeString(opcode); + } + } + + break; + } + default: break; } diff --git a/source/val/validate_conversion.cpp b/source/val/validate_conversion.cpp index b2892a8630..770b8e2e33 100644 --- a/source/val/validate_conversion.cpp +++ b/source/val/validate_conversion.cpp @@ -49,7 +49,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { if (_.IsCooperativeMatrixType(result_type) || _.IsCooperativeMatrixType(input_type)) { spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + _.CooperativeMatrixShapesMatch(inst, result_type, input_type, true); if (ret != SPV_SUCCESS) return ret; } else { if (_.GetDimension(result_type) != _.GetDimension(input_type)) @@ -79,7 +79,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { if (_.IsCooperativeMatrixType(result_type) || _.IsCooperativeMatrixType(input_type)) { spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + _.CooperativeMatrixShapesMatch(inst, result_type, input_type, true); if (ret != SPV_SUCCESS) return ret; } else { if (_.GetDimension(result_type) != _.GetDimension(input_type)) @@ -111,7 +111,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { if (_.IsCooperativeMatrixType(result_type) || _.IsCooperativeMatrixType(input_type)) { spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + _.CooperativeMatrixShapesMatch(inst, result_type, input_type, true); if (ret != SPV_SUCCESS) return ret; } else { if (_.GetDimension(result_type) != _.GetDimension(input_type)) @@ -142,7 +142,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { if (_.IsCooperativeMatrixType(result_type) || _.IsCooperativeMatrixType(input_type)) { spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + _.CooperativeMatrixShapesMatch(inst, result_type, input_type, true); if (ret != SPV_SUCCESS) return ret; } else { if (_.GetDimension(result_type) != _.GetDimension(input_type)) @@ -177,7 +177,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { if (_.IsCooperativeMatrixType(result_type) || _.IsCooperativeMatrixType(input_type)) { spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + _.CooperativeMatrixShapesMatch(inst, result_type, input_type, true); if (ret != SPV_SUCCESS) return ret; } else { if (_.GetDimension(result_type) != _.GetDimension(input_type)) @@ -213,7 +213,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { if (_.IsCooperativeMatrixType(result_type) || _.IsCooperativeMatrixType(input_type)) { spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + _.CooperativeMatrixShapesMatch(inst, result_type, input_type, true); if (ret != SPV_SUCCESS) return ret; } else { if (_.GetDimension(result_type) != _.GetDimension(input_type)) @@ -497,8 +497,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "matrix: " << spvOpcodeString(opcode); if (result_is_coopmat) { - spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + spv_result_t ret = _.CooperativeMatrixShapesMatch(inst, result_type, + input_type, false); if (ret != SPV_SUCCESS) return ret; } @@ -568,6 +568,43 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } + case spv::Op::OpCooperativeMatrixConvertNV: + case spv::Op::OpCooperativeMatrixTransposeNV: { + if (!_.IsCooperativeMatrixType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected cooperative matrix Result Type: " + << spvOpcodeString(opcode); + } + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!_.IsCooperativeMatrixType(input_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected cooperative matrix type for Matrix input: " + << spvOpcodeString(opcode); + } + + bool swap_row_col = (opcode == spv::Op::OpCooperativeMatrixTransposeNV); + if (auto error = _.CooperativeMatrixShapesMatch( + inst, result_type, input_type, true, swap_row_col)) + return error; + + if (opcode == spv::Op::OpCooperativeMatrixConvertNV) { + if (_.FindDef(result_type)->GetOperandAs(1) != + _.FindDef(input_type)->GetOperandAs(1)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result Type and Matrix component types mismatch: " + << spvOpcodeString(opcode); + } + } + + if (opcode == spv::Op::OpCooperativeMatrixTransposeNV) { + if (!_.IsCooperativeMatrixBType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result Type must have UseB: " << spvOpcodeString(opcode); + } + } + break; + } + default: break; } diff --git a/source/val/validate_function.cpp b/source/val/validate_function.cpp index 26b3668282..67758c66f6 100644 --- a/source/val/validate_function.cpp +++ b/source/val/validate_function.cpp @@ -86,7 +86,10 @@ spv_result_t ValidateFunction(ValidationState_t& _, const Instruction* inst) { spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple, spv::Op::OpGetKernelLocalSizeForSubgroupCount, spv::Op::OpGetKernelMaxNumSubgroups, - spv::Op::OpName}; + spv::Op::OpName, + spv::Op::OpCooperativeMatrixPerElementOpNV, + spv::Op::OpCooperativeMatrixReduceNV, + spv::Op::OpCooperativeMatrixLoadTensorNV}; for (auto& pair : inst->uses()) { const auto* use = pair.first; if (std::find(acceptable.begin(), acceptable.end(), use->opcode()) == @@ -341,6 +344,80 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, return SPV_SUCCESS; } +spv_result_t ValidateCooperativeMatrixPerElementOp(ValidationState_t& _, + const Instruction* inst) { + const auto function_id = inst->GetOperandAs(3); + const auto function = _.FindDef(function_id); + if (!function || spv::Op::OpFunction != function->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpCooperativeMatrixPerElementOpNV Function " + << _.getIdName(function_id) << " is not a function."; + } + + const auto matrix_id = inst->GetOperandAs(2); + const auto matrix = _.FindDef(matrix_id); + const auto matrix_type_id = matrix->type_id(); + if (!_.IsCooperativeMatrixKHRType(matrix_type_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpCooperativeMatrixPerElementOpNV Matrix " + << _.getIdName(matrix_id) << " is not a cooperative matrix."; + } + + const auto result_type_id = inst->GetOperandAs(0); + if (matrix_type_id != result_type_id) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpCooperativeMatrixPerElementOpNV Result Type " + << _.getIdName(result_type_id) << " must match matrix type " + << _.getIdName(matrix_type_id) << "."; + } + + const auto matrix_comp_type_id = + _.FindDef(matrix_type_id)->GetOperandAs(1); + const auto function_type_id = function->GetOperandAs(3); + const auto function_type = _.FindDef(function_type_id); + auto return_type_id = function_type->GetOperandAs(1); + if (return_type_id != matrix_comp_type_id) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpCooperativeMatrixPerElementOpNV function return type " + << _.getIdName(return_type_id) + << " must match matrix component type " + << _.getIdName(matrix_comp_type_id) << "."; + } + + if (function_type->operands().size() < 5) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpCooperativeMatrixPerElementOpNV function type " + << _.getIdName(function_type_id) + << " must have a least three parameters."; + } + + const auto param0_id = function_type->GetOperandAs(2); + const auto param1_id = function_type->GetOperandAs(3); + const auto param2_id = function_type->GetOperandAs(4); + if (!_.IsIntScalarType(param0_id) || _.GetBitWidth(param0_id) != 32) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpCooperativeMatrixPerElementOpNV function type first parameter " + "type " + << _.getIdName(param0_id) << " must be a 32-bit integer."; + } + + if (!_.IsIntScalarType(param1_id) || _.GetBitWidth(param1_id) != 32) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpCooperativeMatrixPerElementOpNV function type second " + "parameter type " + << _.getIdName(param1_id) << " must be a 32-bit integer."; + } + + if (param2_id != matrix_comp_type_id) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpCooperativeMatrixPerElementOpNV function type third parameter " + "type " + << _.getIdName(param2_id) << " must match matrix component type."; + } + + return SPV_SUCCESS; +} + } // namespace spv_result_t FunctionPass(ValidationState_t& _, const Instruction* inst) { @@ -354,6 +431,10 @@ spv_result_t FunctionPass(ValidationState_t& _, const Instruction* inst) { case spv::Op::OpFunctionCall: if (auto error = ValidateFunctionCall(_, inst)) return error; break; + case spv::Op::OpCooperativeMatrixPerElementOpNV: + if (auto error = ValidateCooperativeMatrixPerElementOp(_, inst)) + return error; + break; default: break; } diff --git a/source/val/validate_instruction.cpp b/source/val/validate_instruction.cpp index 5bc4d2cef4..39b1c02167 100644 --- a/source/val/validate_instruction.cpp +++ b/source/val/validate_instruction.cpp @@ -475,6 +475,12 @@ spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst) { const uint32_t entry_point = inst->word(1); _.RegisterExecutionModeForEntryPoint(entry_point, spv::ExecutionMode(inst->word(2))); + if (inst->GetOperandAs(1) == + spv::ExecutionMode::LocalSize || + inst->GetOperandAs(1) == + spv::ExecutionMode::LocalSizeId) { + _.RegisterEntryPointLocalSize(entry_point, inst); + } } else if (opcode == spv::Op::OpVariable) { const auto storage_class = inst->GetOperandAs(2); if (auto error = LimitCheckNumVars(_, inst->id(), storage_class)) { diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp index 830c3ea119..ef05d6e6cf 100644 --- a/source/val/validate_memory.cpp +++ b/source/val/validate_memory.cpp @@ -233,6 +233,7 @@ std::pair GetStorageClass( spv::StorageClass src_sc = spv::StorageClass::Max; switch (inst->opcode()) { case spv::Op::OpCooperativeMatrixLoadNV: + case spv::Op::OpCooperativeMatrixLoadTensorNV: case spv::Op::OpCooperativeMatrixLoadKHR: case spv::Op::OpLoad: { auto load_pointer = _.FindDef(inst->GetOperandAs(2)); @@ -241,6 +242,7 @@ std::pair GetStorageClass( break; } case spv::Op::OpCooperativeMatrixStoreNV: + case spv::Op::OpCooperativeMatrixStoreTensorNV: case spv::Op::OpCooperativeMatrixStoreKHR: case spv::Op::OpStore: { auto store_pointer = _.FindDef(inst->GetOperandAs(0)); @@ -330,6 +332,7 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) { if (inst->opcode() == spv::Op::OpLoad || inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV || + inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV || inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "MakePointerAvailableKHR cannot be used with OpLoad."; @@ -350,7 +353,8 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) { if (inst->opcode() == spv::Op::OpStore || inst->opcode() == spv::Op::OpCooperativeMatrixStoreNV || - inst->opcode() == spv::Op::OpCooperativeMatrixStoreKHR) { + inst->opcode() == spv::Op::OpCooperativeMatrixStoreKHR || + inst->opcode() == spv::Op::OpCooperativeMatrixStoreTensorNV) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "MakePointerVisibleKHR cannot be used with OpStore."; } @@ -2176,6 +2180,222 @@ spv_result_t ValidateCooperativeMatrixLoadStoreKHR(ValidationState_t& _, return SPV_SUCCESS; } +// Returns the number of instruction words taken up by a tensor addressing +// operands argument and its implied operands. +int TensorAddressingOperandsNumWords(spv::TensorAddressingOperandsMask mask) { + int result = 1; // Count the mask + if ((mask & spv::TensorAddressingOperandsMask::TensorView) != + spv::TensorAddressingOperandsMask::MaskNone) + ++result; + if ((mask & spv::TensorAddressingOperandsMask::DecodeFunc) != + spv::TensorAddressingOperandsMask::MaskNone) + ++result; + return result; +} + +spv_result_t ValidateCooperativeMatrixLoadStoreTensorNV( + ValidationState_t& _, const Instruction* inst) { + uint32_t type_id; + const char* opname; + if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) { + type_id = inst->type_id(); + opname = "spv::Op::OpCooperativeMatrixLoadTensorNV"; + } else { + // get Object operand's type + type_id = _.FindDef(inst->GetOperandAs(1))->type_id(); + opname = "spv::Op::OpCooperativeMatrixStoreTensorNV"; + } + + auto matrix_type = _.FindDef(type_id); + + if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) { + if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "spv::Op::OpCooperativeMatrixLoadTensorNV Result Type " + << _.getIdName(type_id) << " is not a cooperative matrix type."; + } else { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "spv::Op::OpCooperativeMatrixStoreTensorNV Object type " + << _.getIdName(type_id) << " is not a cooperative matrix type."; + } + } + + const auto pointer_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) ? 2u : 0u; + const auto pointer_id = inst->GetOperandAs(pointer_index); + const auto pointer = _.FindDef(pointer_id); + if (!pointer || + ((_.addressing_model() == spv::AddressingModel::Logical) && + ((!_.features().variable_pointers && + !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || + (_.features().variable_pointers && + !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " Pointer " << _.getIdName(pointer_id) + << " is not a logical pointer."; + } + + const auto pointer_type_id = pointer->type_id(); + const auto pointer_type = _.FindDef(pointer_type_id); + if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " type for pointer " << _.getIdName(pointer_id) + << " is not a pointer type."; + } + + const auto storage_class_index = 1u; + const auto storage_class = + pointer_type->GetOperandAs(storage_class_index); + + if (storage_class != spv::StorageClass::Workgroup && + storage_class != spv::StorageClass::StorageBuffer && + storage_class != spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(8973) << opname + << " storage class for pointer type " + << _.getIdName(pointer_type_id) + << " is not Workgroup, StorageBuffer, or PhysicalStorageBuffer."; + } + + if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) { + const auto object_index = 3; + const auto object_id = inst->GetOperandAs(object_index); + const auto object = _.FindDef(object_id); + if (!object || object->type_id() != type_id) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " Object " << _.getIdName(object_id) + << " type does not match Result Type."; + } + } + + const auto tensor_layout_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) ? 4u : 2u; + const auto tensor_layout_id = + inst->GetOperandAs(tensor_layout_index); + const auto tensor_layout = _.FindDef(tensor_layout_id); + if (!tensor_layout || _.FindDef(tensor_layout->type_id())->opcode() != + spv::Op::OpTypeTensorLayoutNV) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " TensorLayout " << _.getIdName(tensor_layout_id) + << " does not have a tensor layout type."; + } + + const auto memory_access_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) ? 5u : 3u; + if (inst->operands().size() > memory_access_index) { + if (auto error = CheckMemoryAccess(_, inst, memory_access_index)) + return error; + } + + const auto memory_access_mask = + inst->GetOperandAs(memory_access_index); + const auto tensor_operands_index = + memory_access_index + MemoryAccessNumWords(memory_access_mask); + const auto tensor_operands = + inst->GetOperandAs( + tensor_operands_index); + + if (inst->operands().size() < + tensor_operands_index + + TensorAddressingOperandsNumWords(tensor_operands)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " not enough tensor addressing operands."; + } + + uint32_t tensor_operand_index = tensor_operands_index + 1; + if ((tensor_operands & spv::TensorAddressingOperandsMask::TensorView) != + spv::TensorAddressingOperandsMask::MaskNone) { + const auto tensor_view_id = + inst->GetOperandAs(tensor_operand_index); + const auto tensor_view = _.FindDef(tensor_view_id); + if (!tensor_view || _.FindDef(tensor_view->type_id())->opcode() != + spv::Op::OpTypeTensorViewNV) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " TensorView " << _.getIdName(tensor_view_id) + << " does not have a tensor view type."; + } + + tensor_operand_index++; + } + + if ((tensor_operands & spv::TensorAddressingOperandsMask::DecodeFunc) != + spv::TensorAddressingOperandsMask::MaskNone) { + if (inst->opcode() == spv::Op::OpCooperativeMatrixStoreTensorNV) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpCooperativeMatrixStoreTensorNV does not support DecodeFunc."; + } + const auto decode_func_id = + inst->GetOperandAs(tensor_operand_index); + const auto decode_func = _.FindDef(decode_func_id); + + if (!decode_func || decode_func->opcode() != spv::Op::OpFunction) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " DecodeFunc " << _.getIdName(decode_func_id) + << " is not a function."; + } + + const auto component_type_index = 1; + const auto component_type_id = + matrix_type->GetOperandAs(component_type_index); + + const auto function_type = + _.FindDef(decode_func->GetOperandAs(3)); + if (function_type->GetOperandAs(1) != component_type_id) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " DecodeFunc " << _.getIdName(decode_func_id) + << " return type must match matrix component type."; + } + + const auto decode_ptr_type_id = function_type->GetOperandAs(2); + const auto decode_ptr_type = _.FindDef(decode_ptr_type_id); + auto decode_storage_class = + decode_ptr_type->GetOperandAs(storage_class_index); + + if (decode_storage_class != spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " DecodeFunc " << _.getIdName(decode_func_id) + << " first parameter must be pointer to PhysicalStorageBuffer."; + } + + const auto tensor_layout_type = _.FindDef(tensor_layout->type_id()); + + for (uint32_t param = 3; param < 5; ++param) { + const auto param_type_id = function_type->GetOperandAs(param); + const auto param_type = _.FindDef(param_type_id); + if (param_type->opcode() != spv::Op::OpTypeArray) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " DecodeFunc " << _.getIdName(decode_func_id) + << " second/third parameter must be array of 32-bit integer " + "with " + << " dimension equal to the tensor dimension."; + } + const auto length_index = 2u; + uint64_t array_length; + if (_.EvalConstantValUint64( + param_type->GetOperandAs(length_index), + &array_length)) { + const auto tensor_layout_dim_id = + tensor_layout_type->GetOperandAs(1); + uint64_t dim_value; + if (_.EvalConstantValUint64(tensor_layout_dim_id, &dim_value)) { + if (array_length != dim_value) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " DecodeFunc " + << _.getIdName(decode_func_id) + << " second/third parameter must be array of 32-bit integer " + "with " + << " dimension equal to the tensor dimension."; + } + } + } + } + + tensor_operand_index++; + } + + return SPV_SUCCESS; +} + spv_result_t ValidatePtrComparison(ValidationState_t& _, const Instruction* inst) { if (_.addressing_model() == spv::AddressingModel::Logical && @@ -2284,6 +2504,11 @@ spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst) { if (auto error = ValidateCooperativeMatrixLoadStoreKHR(_, inst)) return error; break; + case spv::Op::OpCooperativeMatrixLoadTensorNV: + case spv::Op::OpCooperativeMatrixStoreTensorNV: + if (auto error = ValidateCooperativeMatrixLoadStoreTensorNV(_, inst)) + return error; + break; case spv::Op::OpPtrEqual: case spv::Op::OpPtrNotEqual: case spv::Op::OpPtrDiff: diff --git a/source/val/validate_tensor_layout.cpp b/source/val/validate_tensor_layout.cpp new file mode 100644 index 0000000000..35c766b83d --- /dev/null +++ b/source/val/validate_tensor_layout.cpp @@ -0,0 +1,184 @@ +// Copyright (c) 2024 NVIDIA Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validate instructions that manipulate tensor layout and view objects + +#include "source/opcode.h" +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +spv_result_t ValidateTensorLayoutResultTypeNV(ValidationState_t& _, + const Instruction* inst) { + const auto result_type_index = 0; + const auto result_type_id = inst->GetOperandAs(result_type_index); + const auto result_type = _.FindDef(result_type_id); + + if (!result_type || spv::Op::OpTypeTensorLayoutNV != result_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " Result Type " + << _.getIdName(result_type_id) << " is not a tensor layout type."; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateTensorViewResultTypeNV(ValidationState_t& _, + const Instruction* inst) { + const auto result_type_index = 0; + const auto result_type_id = inst->GetOperandAs(result_type_index); + const auto result_type = _.FindDef(result_type_id); + + if (!result_type || spv::Op::OpTypeTensorViewNV != result_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " Result Type " + << _.getIdName(result_type_id) << " is not a tensor view type."; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateCreateTensorLayoutNV(ValidationState_t& _, + const Instruction* inst) { + if (auto error = ValidateTensorLayoutResultTypeNV(_, inst)) return error; + + return SPV_SUCCESS; +} + +spv_result_t ValidateCreateTensorViewNV(ValidationState_t& _, + const Instruction* inst) { + if (auto error = ValidateTensorViewResultTypeNV(_, inst)) return error; + + return SPV_SUCCESS; +} + +enum ExpectedNumValues { + DIM, + DIMx2, + ONE, + FOUR, +}; + +spv_result_t ValidateTensorTypeWithDimValuesNV(ValidationState_t& _, + const Instruction* inst, + ExpectedNumValues expected, + bool is_view) { + std::string type_str; + if (is_view) { + if (auto error = ValidateTensorViewResultTypeNV(_, inst)) return error; + type_str = "TensorView"; + } else { + if (auto error = ValidateTensorLayoutResultTypeNV(_, inst)) return error; + type_str = "TensorLayout"; + } + + const auto result_type_id = inst->GetOperandAs(0); + const auto tensor_id = inst->GetOperandAs(2); + const auto tensor = _.FindDef(tensor_id); + if (!tensor || result_type_id != tensor->type_id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " Result Type " + << _.getIdName(result_type_id) << " does not match " << type_str + << " type."; + } + + const auto num_values = inst->operands().size() - 3; + + const auto result_type = _.FindDef(result_type_id); + const auto dim_index = 1; + const auto dim_id = result_type->GetOperandAs(dim_index); + uint64_t dim_value; + if (_.EvalConstantValUint64(dim_id, &dim_value)) { + uint64_t expected_num_values = 0; + switch (expected) { + case DIM: + expected_num_values = dim_value; + break; + case DIMx2: + expected_num_values = dim_value * 2; + break; + case ONE: + expected_num_values = 1; + break; + case FOUR: + expected_num_values = 4; + break; + } + + if (num_values != expected_num_values) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) + << " unexpected number of operands."; + } + } + + for (uint32_t i = 0; i < num_values; ++i) { + const auto val_id = inst->GetOperandAs(i + 3); + const auto val = _.FindDef(val_id); + if (!val || !_.IsIntScalarType(val->type_id()) || + _.GetBitWidth(val->type_id()) != 32) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " operand " + << _.getIdName(val_id) << " is not a 32-bit integer."; + } + } + + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t TensorLayoutPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpCreateTensorLayoutNV: + if (auto error = ValidateCreateTensorLayoutNV(_, inst)) return error; + break; + case spv::Op::OpCreateTensorViewNV: + if (auto error = ValidateCreateTensorViewNV(_, inst)) return error; + break; + case spv::Op::OpTensorLayoutSetBlockSizeNV: + case spv::Op::OpTensorLayoutSetDimensionNV: + case spv::Op::OpTensorLayoutSetStrideNV: + if (auto error = ValidateTensorTypeWithDimValuesNV(_, inst, DIM, false)) + return error; + break; + case spv::Op::OpTensorLayoutSliceNV: + if (auto error = ValidateTensorTypeWithDimValuesNV(_, inst, DIMx2, false)) + return error; + break; + case spv::Op::OpTensorLayoutSetClampValueNV: + if (auto error = ValidateTensorTypeWithDimValuesNV(_, inst, ONE, false)) + return error; + break; + case spv::Op::OpTensorViewSetDimensionNV: + case spv::Op::OpTensorViewSetStrideNV: + if (auto error = ValidateTensorTypeWithDimValuesNV(_, inst, DIM, true)) + return error; + break; + case spv::Op::OpTensorViewSetClipNV: + if (auto error = ValidateTensorTypeWithDimValuesNV(_, inst, FOUR, true)) + return error; + break; + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/source/val/validate_type.cpp b/source/val/validate_type.cpp index 32024b7356..5101a40c45 100644 --- a/source/val/validate_type.cpp +++ b/source/val/validate_type.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2018 Google LLC. +// Copyright (c) 2024 NVIDIA Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -582,6 +583,37 @@ spv_result_t ValidateTypeCooperativeMatrix(ValidationState_t& _, } } + uint64_t scope_value; + if (_.EvalConstantValUint64(scope_id, &scope_value)) { + if (scope_value == static_cast(spv::Scope::Workgroup)) { + for (auto entry_point_id : _.entry_points()) { + if (!_.EntryPointHasLocalSizeOrId(entry_point_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeCooperativeMatrixKHR with ScopeWorkgroup " + << "used without specifying LocalSize or LocalSizeId " + << "for entry point " << _.getIdName(entry_point_id); + } + const auto local_size = _.EntryPointLocalSizeOrId(entry_point_id); + const auto mode = local_size->GetOperandAs(1); + if (mode == spv::ExecutionMode::LocalSizeId) { + uint32_t local_size_ids[3] = { + local_size->GetOperandAs(2), + local_size->GetOperandAs(3), + local_size->GetOperandAs(4), + }; + for (auto id : local_size_ids) { + if (_.FindDef(id) > inst) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeCooperativeMatrixKHR with ScopeWorkgroup " + << "used before LocalSizeId constant value " + << _.getIdName(id) << " is defined."; + } + } + } + } + } + } + return SPV_SUCCESS; } @@ -611,6 +643,115 @@ spv_result_t ValidateTypeUntypedPointerKHR(ValidationState_t& _, } return SPV_SUCCESS; } + +spv_result_t ValidateTensorDim(ValidationState_t& _, const Instruction* inst) { + const auto dim_index = 1; + const auto dim_id = inst->GetOperandAs(dim_index); + const auto dim = _.FindDef(dim_id); + if (!dim || !_.IsIntScalarType(dim->type_id()) || + _.GetBitWidth(dim->type_id()) != 32) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " Dim " + << _.getIdName(dim_id) << " is not a 32-bit integer."; + } + + constexpr uint32_t max_tensor_dim = 5; + + uint64_t dim_value; + if (_.EvalConstantValUint64(dim_id, &dim_value)) { + if (dim_value == 0 || dim_value > max_tensor_dim) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " Dim " + << _.getIdName(dim_id) << " must be between 1 and " + << max_tensor_dim << "."; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeTensorLayoutNV(ValidationState_t& _, + const Instruction* inst) { + if (auto error = ValidateTensorDim(_, inst)) return error; + + const auto clamp_index = 2; + const auto clamp_id = inst->GetOperandAs(clamp_index); + const auto clamp = _.FindDef(clamp_id); + if (!clamp || !_.IsIntScalarType(clamp->type_id()) || + _.GetBitWidth(clamp->type_id()) != 32) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " ClampMode " + << _.getIdName(clamp_id) << " is not a 32-bit integer."; + } + + uint64_t clamp_value; + if (_.EvalConstantValUint64(clamp_id, &clamp_value)) { + if (clamp_value > + static_cast(spv::TensorClampMode::RepeatMirrored)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " ClampMode " + << _.getIdName(clamp_id) << " must be a valid TensorClampMode."; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeTensorViewNV(ValidationState_t& _, + const Instruction* inst) { + if (auto error = ValidateTensorDim(_, inst)) return error; + + const auto has_dim_index = 2; + const auto has_dim_id = inst->GetOperandAs(has_dim_index); + const auto has_dim = _.FindDef(has_dim_id); + if (!has_dim || !_.IsBoolScalarType(has_dim->type_id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " HasDimensions " + << _.getIdName(has_dim_id) << " is not a boolean value."; + } + + uint32_t permutation_mask = 0; + bool all_constant = true; + const auto num_dim = inst->operands().size() - 3; + for (size_t p_index = 3; p_index < inst->operands().size(); ++p_index) { + auto p_id = inst->GetOperandAs(p_index); + const auto p = _.FindDef(p_id); + if (!p || !_.IsIntScalarType(p->type_id()) || + _.GetBitWidth(p->type_id()) != 32) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " Permutation " + << _.getIdName(p_id) << " is not a 32-bit integer."; + } + + uint64_t p_value; + if (_.EvalConstantValUint64(p_id, &p_value)) { + if (p_value >= num_dim) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) << " Permutation " + << _.getIdName(p_id) << " must be a valid dimension."; + } + permutation_mask |= 1 << p_value; + } else { + all_constant = false; + } + } + if (all_constant && permutation_mask != (1U << num_dim) - 1U) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) + << " Permutation values don't form a valid permutation."; + } + + uint64_t dim_value; + if (_.EvalConstantValUint64(inst->GetOperandAs(1), &dim_value)) { + if (dim_value != num_dim) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << spvOpcodeString(inst->opcode()) + << " Incorrect number of permutation values."; + } + } + + return SPV_SUCCESS; +} } // namespace spv_result_t TypePass(ValidationState_t& _, const Instruction* inst) { @@ -659,6 +800,12 @@ spv_result_t TypePass(ValidationState_t& _, const Instruction* inst) { case spv::Op::OpTypeUntypedPointerKHR: if (auto error = ValidateTypeUntypedPointerKHR(_, inst)) return error; break; + case spv::Op::OpTypeTensorLayoutNV: + if (auto error = ValidateTypeTensorLayoutNV(_, inst)) return error; + break; + case spv::Op::OpTypeTensorViewNV: + if (auto error = ValidateTypeTensorViewNV(_, inst)) return error; + break; default: break; } diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp index 2afcacc337..da9174fa5c 100644 --- a/source/val/validation_state.cpp +++ b/source/val/validation_state.cpp @@ -1290,8 +1290,9 @@ bool ValidationState_t::IsUnsigned64BitHandle(uint32_t id) const { } spv_result_t ValidationState_t::CooperativeMatrixShapesMatch( - const Instruction* inst, uint32_t m1, uint32_t m2) { - const auto m1_type = FindDef(m1); + const Instruction* inst, uint32_t result_type_id, uint32_t m2, + bool is_conversion, bool swap_row_col) { + const auto m1_type = FindDef(result_type_id); const auto m2_type = FindDef(m2); if (m1_type->opcode() != m2_type->opcode()) { @@ -1307,6 +1308,10 @@ spv_result_t ValidationState_t::CooperativeMatrixShapesMatch( uint32_t m2_rows_id = m2_type->GetOperandAs(3); uint32_t m2_cols_id = m2_type->GetOperandAs(4); + if (swap_row_col) { + std::swap(m1_rows_id, m1_cols_id); + } + bool m1_is_int32 = false, m1_is_const_int32 = false, m2_is_int32 = false, m2_is_const_int32 = false; uint32_t m1_value = 0, m2_value = 0; @@ -1330,7 +1335,7 @@ spv_result_t ValidationState_t::CooperativeMatrixShapesMatch( if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { return diag(SPV_ERROR_INVALID_DATA, inst) << "Expected rows of Matrix type and Result Type to be " - << "identical"; + << (swap_row_col ? "swapped with columns" : "identical"); } std::tie(m1_is_int32, m1_is_const_int32, m1_value) = @@ -1341,7 +1346,7 @@ spv_result_t ValidationState_t::CooperativeMatrixShapesMatch( if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { return diag(SPV_ERROR_INVALID_DATA, inst) << "Expected columns of Matrix type and Result Type to be " - << "identical"; + << (swap_row_col ? "swapped with rows" : "identical"); } if (m1_type->opcode() == spv::Op::OpTypeCooperativeMatrixKHR) { @@ -1352,7 +1357,12 @@ spv_result_t ValidationState_t::CooperativeMatrixShapesMatch( std::tie(m2_is_int32, m2_is_const_int32, m2_value) = EvalInt32IfConst(m2_use_id); - if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { + if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value && + // CooperativeMatrixConversionsNV allows conversions from Acc->A/B + !(is_conversion && + HasCapability(spv::Capability::CooperativeMatrixConversionsNV) && + m2_value == + (uint32_t)spv::CooperativeMatrixUse::MatrixAccumulatorKHR)) { return diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Use of Matrix type and Result Type to be " << "identical"; diff --git a/source/val/validation_state.h b/source/val/validation_state.h index 372b5b7b9f..44551add35 100644 --- a/source/val/validation_state.h +++ b/source/val/validation_state.h @@ -240,6 +240,21 @@ class ValidationState_t { entry_point_to_execution_modes_[entry_point].insert(execution_mode); } + /// Registers that the entry point declares its local size + void RegisterEntryPointLocalSize(uint32_t entry_point, + const Instruction* inst) { + entry_point_to_local_size_or_id_[entry_point] = inst; + } + /// Returns whether the entry point declares its local size + bool EntryPointHasLocalSizeOrId(uint32_t entry_point) const { + return entry_point_to_local_size_or_id_.find(entry_point) != + entry_point_to_local_size_or_id_.end(); + } + /// Returns the id of the local size + const Instruction* EntryPointLocalSizeOrId(uint32_t entry_point) const { + return entry_point_to_local_size_or_id_.find(entry_point)->second; + } + /// Returns the interface descriptions of a given entry point. const std::vector& entry_point_descriptions( uint32_t entry_point) { @@ -759,11 +774,14 @@ class ValidationState_t { return SpvDecorationString(uint32_t(decoration)); } - // Returns whether type m1 and type m2 are cooperative matrices with - // the same "shape" (matching scope, rows, cols). If any are specialization - // constants, we assume they can match because we can't prove they don't. + // Returns whether type result_type_id and type m2 are cooperative matrices + // with the same "shape" (matching scope, rows, cols). If any are + // specialization constants, we assume they can match because we can't prove + // they don't. spv_result_t CooperativeMatrixShapesMatch(const Instruction* inst, - uint32_t m1, uint32_t m2); + uint32_t result_type_id, + uint32_t m2, bool is_conversion, + bool swap_row_col = false); // Returns true if |lhs| and |rhs| logically match and, if the decorations of // |rhs| are a subset of |lhs|. @@ -949,6 +967,10 @@ class ValidationState_t { std::unordered_map> entry_point_to_execution_modes_; + // Mapping entry point -> local size execution mode instruction + std::unordered_map + entry_point_to_local_size_or_id_; + /// Mapping function -> array of entry points inside this /// module which can (indirectly) call the function. std::unordered_map> function_to_entry_points_; diff --git a/test/opt/type_manager_test.cpp b/test/opt/type_manager_test.cpp index d4d0fef524..865bfbb07d 100644 --- a/test/opt/type_manager_test.cpp +++ b/test/opt/type_manager_test.cpp @@ -175,6 +175,9 @@ std::vector> GenerateAllTypes() { types.emplace_back(new RayQueryKHR()); types.emplace_back(new HitObjectNV()); + types.emplace_back(new TensorLayoutNV(1002, 1000)); + types.emplace_back(new TensorViewNV(1002, 1003, {1000, 1001})); + return types; } @@ -1102,11 +1105,14 @@ OpMemoryModel Logical GLSL450 %uint = OpTypeInt 32 0 %1 = OpTypePointer Input %uint %2 = OpTypePointer Uniform %uint +%1000 = OpConstant %uint 0 +%1001 = OpConstant %uint 1 %1002 = OpConstant %uint 2 %8 = OpConstant %uint 8 %24 = OpConstant %uint 24 %42 = OpConstant %uint 42 %100 = OpConstant %uint 100 +%1003 = OpConstantFalse %bool )"; std::unique_ptr context = diff --git a/test/val/val_arithmetics_test.cpp b/test/val/val_arithmetics_test.cpp index 58ac4423e9..8b2a8d0b78 100644 --- a/test/val/val_arithmetics_test.cpp +++ b/test/val/val_arithmetics_test.cpp @@ -1280,14 +1280,14 @@ TEST_F(ValidateArithmetics, CoopMatMatrixTimesScalarMismatchFail) { TEST_F(ValidateArithmetics, CoopMatScopeFail) { const std::string types = R"( -%workgroup = OpConstant %u32 2 +%device = OpConstant %u32 1 -%mat16x16_wg = OpTypeCooperativeMatrixNV %f16 %workgroup %u32_16 %u32_16 -%f16matwg_16x16_1 = OpConstantComposite %mat16x16_wg %f16_1 +%mat16x16_dv = OpTypeCooperativeMatrixNV %f16 %device %u32_16 %u32_16 +%f16matdv_16x16_1 = OpConstantComposite %mat16x16_dv %f16_1 )"; const std::string body = R"( -%val1 = OpCooperativeMatrixMulAddNV %mat16x16 %f16mat_16x4_1 %f16mat_4x16_1 %f16matwg_16x16_1 +%val1 = OpCooperativeMatrixMulAddNV %mat16x16 %f16mat_16x4_1 %f16mat_4x16_1 %f16matdv_16x16_1 )"; CompileSuccessfully(GenerateCoopMatCode(types, body).c_str()); @@ -1475,7 +1475,10 @@ std::string GenerateCoopMatKHRCode(const std::string& extra_types, OpCapability Shader OpCapability Float16 OpCapability CooperativeMatrixKHR +OpCapability CooperativeMatrixReductionsNV +OpCapability CooperativeMatrixPerElementOperationsNV OpExtension "SPV_KHR_cooperative_matrix" +OpExtension "SPV_NV_cooperative_matrix2" OpExtension "SPV_KHR_vulkan_memory_model" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %main "main" @@ -1487,6 +1490,7 @@ OpEntryPoint GLCompute %main "main" %u32 = OpTypeInt 32 0 %s32 = OpTypeInt 32 1 +%u32_8 = OpConstant %u32 8 %u32_16 = OpConstant %u32 16 %u32_4 = OpConstant %u32 4 %subgroup = OpConstant %u32 3 @@ -1579,13 +1583,13 @@ TEST_F(ValidateArithmetics, CoopMatMatrixKHRTimesScalarMismatchFail) { TEST_F(ValidateArithmetics, CoopMatKHRScopeFail) { const std::string types = R"( -%workgroup = OpConstant %u32 2 -%mat16x16_wg = OpTypeCooperativeMatrixKHR %f16 %workgroup %u32_16 %u32_16 %useC -%f16matwg_16x16_1 = OpConstantComposite %mat16x16_wg %f16_1 +%device = OpConstant %u32 1 +%mat16x16_dv = OpTypeCooperativeMatrixKHR %f16 %device %u32_16 %u32_16 %useC +%f16matdv_16x16_1 = OpConstantComposite %mat16x16_dv %f16_1 )"; const std::string body = R"( -%val1 = OpFAdd %f16matA %f16matwg_16x16_1 %f16mat_A_1 +%val1 = OpFAdd %f16matA %f16matdv_16x16_1 %f16mat_A_1 )"; CompileSuccessfully(GenerateCoopMatKHRCode(types, body).c_str()); @@ -1612,6 +1616,241 @@ TEST_F(ValidateArithmetics, CoopMatKHRDimFail) { HasSubstr("Cooperative matrix 'N' mismatch: CooperativeMatrixMulAddKHR")); } +TEST_F(ValidateArithmetics, CoopMat2ReduceSuccess) { + const std::string extra_types = R"( + +%f16matC8 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %useC +%f16matC16x8 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_8 %useC +%f16matC8x16 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_16 %useC + +%functy = OpTypeFunction %f16 %f16 %f16 +%reducefunc = OpFunction %f16 None %functy +%x = OpFunctionParameter %f16 +%y = OpFunctionParameter %f16 +%entry2 = OpLabel +%sum = OpFAdd %f16 %x %y +OpReturnValue %sum +OpFunctionEnd + + )"; + const std::string body = R"( +%val1 = OpCooperativeMatrixReduceNV %f16matC8 %f16mat_C_1 2x2 %reducefunc +%val2 = OpCooperativeMatrixReduceNV %f16matC16x8 %f16mat_C_1 Row %reducefunc +%val3 = OpCooperativeMatrixReduceNV %f16matC8x16 %f16mat_C_1 Column %reducefunc +%val4 = OpCooperativeMatrixReduceNV %f16matC %f16mat_C_1 Row|Column %reducefunc +%val5 = OpCooperativeMatrixReduceNV %f16matC8 %f16mat_C_1 Row|Column %reducefunc +)"; + + CompileSuccessfully(GenerateCoopMatKHRCode(extra_types, body).c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateArithmetics, CoopMat2Reduce2x2DimFail) { + const std::string extra_types = R"( + +%functy = OpTypeFunction %f16 %f16 %f16 +%reducefunc = OpFunction %f16 None %functy +%x = OpFunctionParameter %f16 +%y = OpFunctionParameter %f16 +%entry2 = OpLabel +%sum = OpFAdd %f16 %x %y +OpReturnValue %sum +OpFunctionEnd + + )"; + const std::string body = R"( +%val1 = OpCooperativeMatrixReduceNV %f16matC %f16mat_C_1 2x2 %reducefunc +)"; + + CompileSuccessfully(GenerateCoopMatKHRCode(extra_types, body).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("For Reduce2x2, result rows/cols must be half of " + "matrix rows/cols: CooperativeMatrixReduceNV")); +} + +TEST_F(ValidateArithmetics, CoopMat2ReduceRowDimFail) { + const std::string extra_types = R"( + +%f16matC8x16 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_16 %useC + +%functy = OpTypeFunction %f16 %f16 %f16 +%reducefunc = OpFunction %f16 None %functy +%x = OpFunctionParameter %f16 +%y = OpFunctionParameter %f16 +%entry2 = OpLabel +%sum = OpFAdd %f16 %x %y +OpReturnValue %sum +OpFunctionEnd + + )"; + const std::string body = R"( +%val1 = OpCooperativeMatrixReduceNV %f16matC8x16 %f16mat_C_1 Row %reducefunc +)"; + + CompileSuccessfully(GenerateCoopMatKHRCode(extra_types, body).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("For ReduceRow, result rows must match matrix rows: " + "CooperativeMatrixReduceNV")); +} + +TEST_F(ValidateArithmetics, CoopMat2ReduceColDimFail) { + const std::string extra_types = R"( + +%f16matC16x8 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_8 %useC + +%functy = OpTypeFunction %f16 %f16 %f16 +%reducefunc = OpFunction %f16 None %functy +%x = OpFunctionParameter %f16 +%y = OpFunctionParameter %f16 +%entry2 = OpLabel +%sum = OpFAdd %f16 %x %y +OpReturnValue %sum +OpFunctionEnd + + )"; + const std::string body = R"( +%val1 = OpCooperativeMatrixReduceNV %f16matC16x8 %f16mat_C_1 Column %reducefunc +)"; + + CompileSuccessfully(GenerateCoopMatKHRCode(extra_types, body).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("For ReduceColumn, result cols must match matrix cols: " + "CooperativeMatrixReduceNV")); +} + +TEST_F(ValidateArithmetics, CoopMat2ReduceMaskFail) { + const std::string extra_types = R"( + +%f16matC8 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %useC + +%functy = OpTypeFunction %f16 %f16 %f16 +%reducefunc = OpFunction %f16 None %functy +%x = OpFunctionParameter %f16 +%y = OpFunctionParameter %f16 +%entry2 = OpLabel +%sum = OpFAdd %f16 %x %y +OpReturnValue %sum +OpFunctionEnd + + )"; + const std::string body = R"( +%val1 = OpCooperativeMatrixReduceNV %f16matC8 %f16mat_C_1 Row|Column|2x2 %reducefunc +)"; + + CompileSuccessfully(GenerateCoopMatKHRCode(extra_types, body).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Reduce 2x2 must not be used with Row/Column: " + "CooperativeMatrixReduceNV")); +} + +TEST_F(ValidateArithmetics, CoopMat2ReduceFuncTypeFail) { + const std::string extra_types = R"( + +%functy = OpTypeFunction %f32 %f32 %f32 +%reducefunc = OpFunction %f32 None %functy +%x = OpFunctionParameter %f32 +%y = OpFunctionParameter %f32 +%entry2 = OpLabel +%sum = OpFAdd %f32 %x %y +OpReturnValue %sum +OpFunctionEnd + + )"; + const std::string body = R"( +%val1 = OpCooperativeMatrixReduceNV %f16matC %f16mat_C_1 Row|Column %reducefunc +)"; + + CompileSuccessfully(GenerateCoopMatKHRCode(extra_types, body).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("CombineFunc return type and parameters must match " + "matrix component type: CooperativeMatrixReduceNV")); +} + +TEST_F(ValidateArithmetics, CoopMat2PerElementOpSuccess) { + const std::string extra_types = R"( + +%functy = OpTypeFunction %f16 %u32 %u32 %f16 +%functy2 = OpTypeFunction %f16 %u32 %u32 %f16 %u32 + +%elemfunc = OpFunction %f16 None %functy +%row = OpFunctionParameter %u32 +%col = OpFunctionParameter %u32 +%el = OpFunctionParameter %f16 +%entry2 = OpLabel +OpReturnValue %el +OpFunctionEnd + +%elemfunc2 = OpFunction %f16 None %functy2 +%row2 = OpFunctionParameter %u32 +%col2 = OpFunctionParameter %u32 +%el2 = OpFunctionParameter %f16 +%x = OpFunctionParameter %u32 +%entry3 = OpLabel +OpReturnValue %el2 +OpFunctionEnd + + )"; + const std::string body = R"( +%val1 = OpCooperativeMatrixPerElementOpNV %f16matC %f16mat_C_1 %elemfunc +%val2 = OpCooperativeMatrixPerElementOpNV %f16matC %f16mat_C_1 %elemfunc2 %f16_1 +)"; + + CompileSuccessfully(GenerateCoopMatKHRCode(extra_types, body).c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateArithmetics, CoopMat2PerElementOpElemTyFail) { + const std::string extra_types = R"( + +%functy = OpTypeFunction %f32 %u32 %u32 %f32 + +%elemfunc = OpFunction %f32 None %functy +%row = OpFunctionParameter %u32 +%col = OpFunctionParameter %u32 +%el = OpFunctionParameter %f32 +%entry2 = OpLabel +OpReturnValue %el +OpFunctionEnd + + )"; + const std::string body = R"( +%val1 = OpCooperativeMatrixPerElementOpNV %f16matC %f16mat_C_1 %elemfunc +)"; + + CompileSuccessfully(GenerateCoopMatKHRCode(extra_types, body).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("must match matrix component type")); +} + +TEST_F(ValidateArithmetics, CoopMat2PerElementOpRowTyFail) { + const std::string extra_types = R"( + +%functy = OpTypeFunction %f16 %f16 %u32 %f16 + +%elemfunc = OpFunction %f16 None %functy +%row = OpFunctionParameter %f16 +%col = OpFunctionParameter %u32 +%el = OpFunctionParameter %f16 +%entry2 = OpLabel +OpReturnValue %el +OpFunctionEnd + + )"; + const std::string body = R"( +%val1 = OpCooperativeMatrixPerElementOpNV %f16matC %f16mat_C_1 %elemfunc +)"; + + CompileSuccessfully(GenerateCoopMatKHRCode(extra_types, body).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a 32-bit integer")); +} + } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_conversion_test.cpp b/test/val/val_conversion_test.cpp index 748ad64f86..3869626ef0 100644 --- a/test/val/val_conversion_test.cpp +++ b/test/val/val_conversion_test.cpp @@ -1338,11 +1338,11 @@ OpEntryPoint GLCompute %main "main" %u32_8 = OpConstant %u32 8 %u32_4 = OpConstant %u32 4 %subgroup = OpConstant %u32 3 -%workgroup = OpConstant %u32 2 +%device = OpConstant %u32 1 %use_A = OpConstant %u32 0 %f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A -%f32mat = OpTypeCooperativeMatrixKHR %f32 %workgroup %u32_8 %u32_8 %use_A +%f32mat = OpTypeCooperativeMatrixKHR %f32 %device %u32_8 %u32_8 %use_A %f16_1 = OpConstant %f16 1 @@ -2140,6 +2140,192 @@ INSTANTIATE_TEST_SUITE_P(SmallConversionInstructions, ValidateSmallConversions, "%inst = OpBitcast %short %ld_half", "%inst = OpBitcast %short2 %ld_half2")); +TEST_F(ValidateConversion, CoopMat2ConversionSuccess) { + const std::string body = R"( +OpCapability Shader +OpCapability Float16 +OpCapability Int16 +OpCapability CooperativeMatrixConversionsNV +OpCapability CooperativeMatrixKHR +OpExtension "SPV_KHR_cooperative_matrix" +OpExtension "SPV_NV_cooperative_matrix2" +OpExtension "SPV_KHR_vulkan_memory_model" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +%void = OpTypeVoid +%func = OpTypeFunction %void +%bool = OpTypeBool +%f16 = OpTypeFloat 16 +%f32 = OpTypeFloat 32 +%u16 = OpTypeInt 16 0 +%u32 = OpTypeInt 32 0 +%s16 = OpTypeInt 16 1 +%s32 = OpTypeInt 32 1 + +%u32_8 = OpConstant %u32 8 +%u32_16 = OpConstant %u32 16 +%use_A = OpConstant %u32 0 +%use_B = OpConstant %u32 1 +%use_Acc = OpConstant %u32 2 +%subgroup = OpConstant %u32 3 + +%f16matA = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A +%f32matA = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_A +%u16matA = OpTypeCooperativeMatrixKHR %u16 %subgroup %u32_8 %u32_8 %use_A +%u32matA = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_8 %u32_8 %use_A +%s16matA = OpTypeCooperativeMatrixKHR %s16 %subgroup %u32_8 %u32_8 %use_A +%s32matA = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_8 %u32_8 %use_A + +%f16matB = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_B +%f32matB = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_B +%u16matB = OpTypeCooperativeMatrixKHR %u16 %subgroup %u32_8 %u32_8 %use_B +%u32matB = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_8 %u32_8 %use_B +%s16matB = OpTypeCooperativeMatrixKHR %s16 %subgroup %u32_8 %u32_8 %use_B +%s32matB = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_8 %u32_8 %use_B + +%f16matAcc = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_Acc +%f32matAcc = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_Acc +%u16matAcc = OpTypeCooperativeMatrixKHR %u16 %subgroup %u32_8 %u32_8 %use_Acc +%u32matAcc = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_8 %u32_8 %use_Acc +%s16matAcc = OpTypeCooperativeMatrixKHR %s16 %subgroup %u32_8 %u32_8 %use_Acc +%s32matAcc = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_8 %u32_8 %use_Acc + +%f16matAcc16x8 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_8 %use_Acc +%f16matB8x16 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_16 %use_B + +%f16_1 = OpConstant %f16 1 +%f32_1 = OpConstant %f32 1 +%u16_1 = OpConstant %u16 1 +%u32_1 = OpConstant %u32 1 +%s16_1 = OpConstant %s16 1 +%s32_1 = OpConstant %s32 1 + +%f16matAcc_1 = OpConstantComposite %f16matAcc %f16_1 +%f32matAcc_1 = OpConstantComposite %f32matAcc %f32_1 +%u16matAcc_1 = OpConstantComposite %u16matAcc %u16_1 +%u32matAcc_1 = OpConstantComposite %u32matAcc %u32_1 +%s16matAcc_1 = OpConstantComposite %s16matAcc %s16_1 +%s32matAcc_1 = OpConstantComposite %s32matAcc %s32_1 + +%f16matAcc16x8_1 = OpConstantComposite %f16matAcc16x8 %f16_1 + +%main = OpFunction %void None %func +%main_entry = OpLabel + +%val11A = OpConvertFToU %u16matA %f16matAcc_1 +%val12A = OpConvertFToU %u32matA %f16matAcc_1 +%val13A = OpConvertFToS %s16matA %f16matAcc_1 +%val14A = OpConvertFToS %s32matA %f16matAcc_1 +%val15A = OpFConvert %f32matA %f16matAcc_1 + +%val11B = OpConvertFToU %u16matB %f16matAcc_1 +%val12B = OpConvertFToU %u32matB %f16matAcc_1 +%val13B = OpConvertFToS %s16matB %f16matAcc_1 +%val14B = OpConvertFToS %s32matB %f16matAcc_1 +%val15B = OpFConvert %f32matB %f16matAcc_1 + +%val21A = OpConvertFToU %u16matA %f32matAcc_1 +%val22A = OpConvertFToU %u32matA %f32matAcc_1 +%val23A = OpConvertFToS %s16matA %f32matAcc_1 +%val24A = OpConvertFToS %s32matA %f32matAcc_1 +%val25A = OpFConvert %f16matA %f32matAcc_1 + +%val21B = OpConvertFToU %u16matB %f32matAcc_1 +%val22B = OpConvertFToU %u32matB %f32matAcc_1 +%val23B = OpConvertFToS %s16matB %f32matAcc_1 +%val24B = OpConvertFToS %s32matB %f32matAcc_1 +%val25B = OpFConvert %f16matB %f32matAcc_1 + +%val31A = OpConvertUToF %f16matA %u16matAcc_1 +%val32A = OpConvertUToF %f32matA %u16matAcc_1 +%val33A = OpUConvert %u32matA %u16matAcc_1 +%val34A = OpSConvert %s32matA %u16matAcc_1 + +%val31B = OpConvertUToF %f16matB %u16matAcc_1 +%val32B = OpConvertUToF %f32matB %u16matAcc_1 +%val33B = OpUConvert %u32matB %u16matAcc_1 +%val34B = OpSConvert %s32matB %u16matAcc_1 + +%val41A = OpConvertSToF %f16matA %s16matAcc_1 +%val42A = OpConvertSToF %f32matA %s16matAcc_1 +%val43A = OpUConvert %u32matA %s16matAcc_1 +%val44A = OpSConvert %s32matA %s16matAcc_1 + +%val41B = OpConvertSToF %f16matB %s16matAcc_1 +%val42B = OpConvertSToF %f32matB %s16matAcc_1 +%val43B = OpUConvert %u32matB %s16matAcc_1 +%val44B = OpSConvert %s32matB %s16matAcc_1 + +%val51A = OpCooperativeMatrixConvertNV %f16matA %f16matAcc_1 +%val52A = OpCooperativeMatrixConvertNV %f32matA %f32matAcc_1 +%val53A = OpCooperativeMatrixConvertNV %u16matA %u16matAcc_1 +%val54A = OpCooperativeMatrixConvertNV %s16matA %s16matAcc_1 + +%val51B = OpCooperativeMatrixConvertNV %f16matB %f16matAcc_1 +%val52B = OpCooperativeMatrixConvertNV %f32matB %f32matAcc_1 +%val53B = OpCooperativeMatrixConvertNV %u16matB %u16matAcc_1 +%val54B = OpCooperativeMatrixConvertNV %s16matB %s16matAcc_1 + +%val61B = OpCooperativeMatrixTransposeNV %f16matB %f16matAcc_1 +%val62B = OpCooperativeMatrixTransposeNV %f32matB %f32matAcc_1 +%val63B = OpCooperativeMatrixTransposeNV %u16matB %u16matAcc_1 +%val64B = OpCooperativeMatrixTransposeNV %s16matB %s16matAcc_1 + +%val71B = OpCooperativeMatrixTransposeNV %f16matB8x16 %f16matAcc16x8_1 + +OpReturn +OpFunctionEnd)"; + + CompileSuccessfully(body.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateConversion, CoopMat2TransposeShapeFail) { + const std::string body = R"( +OpCapability Shader +OpCapability Float16 +OpCapability Int16 +OpCapability CooperativeMatrixConversionsNV +OpCapability CooperativeMatrixKHR +OpExtension "SPV_KHR_cooperative_matrix" +OpExtension "SPV_NV_cooperative_matrix2" +OpExtension "SPV_KHR_vulkan_memory_model" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +%void = OpTypeVoid +%func = OpTypeFunction %void +%bool = OpTypeBool +%f16 = OpTypeFloat 16 +%u32 = OpTypeInt 32 0 + +%u32_8 = OpConstant %u32 8 +%u32_16 = OpConstant %u32 16 +%use_B = OpConstant %u32 1 +%use_Acc = OpConstant %u32 2 +%subgroup = OpConstant %u32 3 + +%f16matAcc16x8 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_8 %use_Acc +%f16matB16x8 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_8 %use_B + +%f16_1 = OpConstant %f16 1 + +%f16matAcc16x8_1 = OpConstantComposite %f16matAcc16x8 %f16_1 + +%main = OpFunction %void None %func +%main_entry = OpLabel + +%val71B = OpCooperativeMatrixTransposeNV %f16matB16x8 %f16matAcc16x8_1 + +OpReturn +OpFunctionEnd)"; + + CompileSuccessfully(body.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Expected rows of Matrix type and Result Type to be " + "swapped with columns")); +} + } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_memory_test.cpp b/test/val/val_memory_test.cpp index ae78b14500..0a918c9898 100644 --- a/test/val/val_memory_test.cpp +++ b/test/val/val_memory_test.cpp @@ -7171,6 +7171,639 @@ OpFunctionEnd EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3)); } +std::string GenCoopMat2Shader(const std::string& extra_types, + const std::string& main_body, + const std::string& after_main = "", + const std::string& extra_decorations = "") { + const std::string prefix = R"( +OpCapability Shader +OpCapability Float16 +OpCapability PhysicalStorageBufferAddresses +OpCapability VulkanMemoryModel +OpCapability CooperativeMatrixKHR +OpCapability TensorAddressingNV +OpCapability CooperativeMatrixTensorAddressingNV +OpCapability CooperativeMatrixBlockLoadsNV +OpExtension "SPV_KHR_physical_storage_buffer" +OpExtension "SPV_KHR_storage_buffer_storage_class" +OpExtension "SPV_NV_tensor_addressing" +OpExtension "SPV_NV_cooperative_matrix2" +OpExtension "SPV_KHR_cooperative_matrix" +OpExtension "SPV_KHR_vulkan_memory_model" +OpMemoryModel Logical VulkanKHR +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 + +OpDecorate %f16_arr ArrayStride 2 +OpDecorate %46 Block +OpMemberDecorate %46 0 Offset 0 +OpDecorate %48 Binding 0 +OpDecorate %48 DescriptorSet 0 +OpDecorate %psb Restrict +)" + extra_decorations + R"( +%void = OpTypeVoid +%bool = OpTypeBool +%func = OpTypeFunction %void +%f16 = OpTypeFloat 16 +%f32 = OpTypeFloat 32 +%u32 = OpTypeInt 32 0 +%s32 = OpTypeInt 32 1 + +%s32_0 = OpConstant %s32 0 +%f16_0 = OpConstant %f16 0 +%u32_2 = OpConstant %u32 2 +%u32_8 = OpConstant %u32 8 +%use_A = OpConstant %u32 0 +%workgroup = OpConstant %u32 2 +%subgroup = OpConstant %u32 3 + +%f16_arr = OpTypeRuntimeArray %f16 +%46 = OpTypeStruct %f16_arr +%47 = OpTypePointer StorageBuffer %46 +%48 = OpVariable %47 StorageBuffer +%51 = OpTypePointer StorageBuffer %f16_arr +%psbptr = OpTypePointer PhysicalStorageBuffer %f16_arr + +%f16mat = OpTypeCooperativeMatrixKHR %f16 %workgroup %u32_8 %u32_8 %use_A +%f32mat = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_A + +%arr2 = OpTypeArray %u32 %u32_2 +%functy = OpTypeFunction %f16 %psbptr %arr2 %arr2 +)"; + + const std::string decode_func = + R"( +%decodefunc = OpFunction %f16 None %functy +%psb = OpFunctionParameter %psbptr +%c0 = OpFunctionParameter %arr2 +%c1 = OpFunctionParameter %arr2 +%entry2 = OpLabel +OpReturnValue %f16_0 +OpFunctionEnd +)"; + + const std::string func_begin = + R"( +%main = OpFunction %void None %func +%main_entry = OpLabel + +%array_ptr = OpAccessChain %51 %48 %s32_0 +)"; + + const std::string suffix = + R"( +OpReturn +OpFunctionEnd)"; + + return prefix + extra_types + func_begin + main_body + suffix + decode_func + + after_main; +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutAndViewSuccess) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 2 + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %hasdim = OpConstantFalse %bool + %layout = OpTypeTensorLayoutNV %dim %clamp + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 + )", + R"( + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutInvalidDimFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 6 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), HasSubstr("must be between 1 and 5")); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutInvalidClampFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 6 + %dim = OpConstant %u32 2 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("must be a valid TensorClampMode")); +} + +TEST_F(ValidateMemory, CoopMat2TensorViewInvalidDimFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %dim = OpConstant %u32 6 + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %hasdim = OpConstantFalse %bool + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 + )", + R"( + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), HasSubstr("must be between 1 and 5")); +} + +TEST_F(ValidateMemory, CoopMat2TensorViewInvalidPermutationFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %dim = OpConstant %u32 3 + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %hasdim = OpConstantFalse %bool + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p1 + )", + R"( + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Permutation values don't form a valid permutation")); +} + +TEST_F(ValidateMemory, CoopMat2TensorViewInvalidPermutation2Fail) { + std::string spirv = GenCoopMat2Shader( + R"( + %dim = OpConstant %u32 3 + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %hasdim = OpConstantFalse %bool + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 + )", + R"( + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Incorrect number of permutation values.")); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutBlockSizePass) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 3 + %b = OpConstant %u32 1 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + %tl = OpCreateTensorLayoutNV %layout + %tl2 = OpTensorLayoutSetBlockSizeNV %layout %tl %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutBlockSizeFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 3 + %b = OpConstant %u32 1 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + %tl = OpCreateTensorLayoutNV %layout + %tl2 = OpTensorLayoutSetBlockSizeNV %layout %tl %b %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("unexpected number of operands")); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutDimensionPass) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 3 + %b = OpConstant %u32 1 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + %tl = OpCreateTensorLayoutNV %layout + %tl2 = OpTensorLayoutSetDimensionNV %layout %tl %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutDimensionFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 3 + %b = OpConstant %u32 1 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + %tl = OpCreateTensorLayoutNV %layout + %tl2 = OpTensorLayoutSetDimensionNV %layout %tl %b %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("unexpected number of operands")); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutStridePass) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 3 + %b = OpConstant %u32 1 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + %tl = OpCreateTensorLayoutNV %layout + %tl2 = OpTensorLayoutSetStrideNV %layout %tl %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutStrideFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 3 + %b = OpConstant %u32 1 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + %tl = OpCreateTensorLayoutNV %layout + %tl2 = OpTensorLayoutSetStrideNV %layout %tl %b %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("unexpected number of operands")); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutSlicePass) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 3 + %b = OpConstant %u32 1 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + %tl = OpCreateTensorLayoutNV %layout + %tl2 = OpTensorLayoutSliceNV %layout %tl %b %b %b %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutSliceFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 3 + %b = OpConstant %u32 1 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + %tl = OpCreateTensorLayoutNV %layout + %tl2 = OpTensorLayoutSliceNV %layout %tl %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("unexpected number of operands")); +} + +TEST_F(ValidateMemory, CoopMat2TensorLayoutSetClampValuePass) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 3 + %b = OpConstant %u32 1 + %layout = OpTypeTensorLayoutNV %dim %clamp + )", + R"( + %tl = OpCreateTensorLayoutNV %layout + %tl2 = OpTensorLayoutSetClampValueNV %layout %tl %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateMemory, CoopMat2TensorViewDimensionPass) { + std::string spirv = GenCoopMat2Shader( + R"( + %dim = OpConstant %u32 3 + %hasdim = OpConstantFalse %bool + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %p2 = OpConstant %u32 2 + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p2 + %b = OpConstant %u32 1 + )", + R"( + %tv = OpCreateTensorViewNV %view + %tv2 = OpTensorViewSetDimensionNV %view %tv %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateMemory, CoopMat2TensorViewDimensionFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %dim = OpConstant %u32 3 + %hasdim = OpConstantFalse %bool + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %p2 = OpConstant %u32 2 + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p2 + %b = OpConstant %u32 1 + )", + R"( + %tv = OpCreateTensorViewNV %view + %tv2 = OpTensorViewSetDimensionNV %view %tv %b %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("unexpected number of operands")); +} + +TEST_F(ValidateMemory, CoopMat2TensorViewStridePass) { + std::string spirv = GenCoopMat2Shader( + R"( + %dim = OpConstant %u32 3 + %hasdim = OpConstantFalse %bool + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %p2 = OpConstant %u32 2 + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p2 + %b = OpConstant %u32 1 + )", + R"( + %tv = OpCreateTensorViewNV %view + %tv2 = OpTensorViewSetStrideNV %view %tv %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateMemory, CoopMat2TensorViewStrideFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %dim = OpConstant %u32 3 + %hasdim = OpConstantFalse %bool + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %p2 = OpConstant %u32 2 + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p2 + %b = OpConstant %u32 1 + )", + R"( + %tv = OpCreateTensorViewNV %view + %tv2 = OpTensorViewSetStrideNV %view %tv %b %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("unexpected number of operands")); +} + +TEST_F(ValidateMemory, CoopMat2TensorViewClipPass) { + std::string spirv = GenCoopMat2Shader( + R"( + %dim = OpConstant %u32 3 + %hasdim = OpConstantFalse %bool + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %p2 = OpConstant %u32 2 + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 %p2 + %b = OpConstant %u32 1 + )", + R"( + %tv = OpCreateTensorViewNV %view + %tv2 = OpTensorViewSetClipNV %view %tv %b %b %b %b + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateMemory, CoopMat2LoadStoreTensorPass) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 2 + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %hasdim = OpConstantFalse %bool + %layout = OpTypeTensorLayoutNV %dim %clamp + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 + )", + R"( + %mat = OpUndef %f16mat + %tl = OpCreateTensorLayoutNV %layout + %tv = OpCreateTensorViewNV %view + %mat2 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None None + %mat3 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl Aligned 4 None + %mat4 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None TensorView %tv + %mat5 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None DecodeFunc %decodefunc + %mat6 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None TensorView|DecodeFunc %tv %decodefunc + %mat7 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl Aligned 4 TensorView|DecodeFunc %tv %decodefunc + OpCooperativeMatrixStoreTensorNV %array_ptr %mat %tl None None + OpCooperativeMatrixStoreTensorNV %array_ptr %mat %tl Aligned 4 None + OpCooperativeMatrixStoreTensorNV %array_ptr %mat %tl None TensorView %tv + OpCooperativeMatrixStoreTensorNV %array_ptr %mat %tl Aligned 4 TensorView %tv + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateMemory, CoopMat2LoadTensorWrongLayoutTypeFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 2 + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %hasdim = OpConstantFalse %bool + %layout = OpTypeTensorLayoutNV %dim %clamp + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 + )", + R"( + %mat = OpUndef %f16mat + %tl = OpCreateTensorLayoutNV %layout + %tv = OpCreateTensorViewNV %view + %mat2 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tv None None + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("does not have a tensor layout type")); +} + +TEST_F(ValidateMemory, CoopMat2LoadTensorWrongObjectTypeFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 2 + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %hasdim = OpConstantFalse %bool + %layout = OpTypeTensorLayoutNV %dim %clamp + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 + )", + R"( + %mat = OpUndef %f32mat + %tl = OpCreateTensorLayoutNV %layout + %tv = OpCreateTensorViewNV %view + %mat2 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None None + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("type does not match Result Type")); +} + +TEST_F(ValidateMemory, CoopMat2LoadTensorDecodeFuncTypeFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 2 + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %hasdim = OpConstantFalse %bool + %layout = OpTypeTensorLayoutNV %dim %clamp + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 + )", + R"( + %mat = OpUndef %f32mat + %tl = OpCreateTensorLayoutNV %layout + %tv = OpCreateTensorViewNV %view + %mat2 = OpCooperativeMatrixLoadTensorNV %f32mat %array_ptr %mat %tl None DecodeFunc %decodefunc + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("return type must match matrix component type")); +} + +TEST_F(ValidateMemory, CoopMat2LoadTensorDecodeFuncArrayTypeFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 2 + %u32_3 = OpConstant %u32 3 + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %hasdim = OpConstantFalse %bool + %layout = OpTypeTensorLayoutNV %dim %clamp + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 + %arr3 = OpTypeArray %u32 %u32_3 + %functy2 = OpTypeFunction %f16 %psbptr %arr3 %arr3 + )", + R"( + %mat = OpUndef %f16mat + %tl = OpCreateTensorLayoutNV %layout + %tv = OpCreateTensorViewNV %view + %mat2 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None DecodeFunc %decodefunc2 + )", + R"( + %decodefunc2 = OpFunction %f16 None %functy2 + %psb2 = OpFunctionParameter %psbptr + %c02 = OpFunctionParameter %arr3 + %c12 = OpFunctionParameter %arr3 + %entry3 = OpLabel + OpReturnValue %f16_0 + OpFunctionEnd + )", + R"( + OpDecorate %psb2 Restrict + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("dimension equal to the tensor dimension")); +} + +TEST_F(ValidateMemory, CoopMat2LoadTensorDecodeFuncPointerTypeFail) { + std::string spirv = GenCoopMat2Shader( + R"( + %clamp = OpConstant %u32 0 + %dim = OpConstant %u32 2 + %p0 = OpConstant %u32 0 + %p1 = OpConstant %u32 1 + %hasdim = OpConstantFalse %bool + %layout = OpTypeTensorLayoutNV %dim %clamp + %view = OpTypeTensorViewNV %dim %hasdim %p0 %p1 + %sbptr = OpTypePointer StorageBuffer %f16_arr + %functy2 = OpTypeFunction %f16 %sbptr %arr2 %arr2 + )", + R"( + %mat = OpUndef %f16mat + %tl = OpCreateTensorLayoutNV %layout + %tv = OpCreateTensorViewNV %view + %mat2 = OpCooperativeMatrixLoadTensorNV %f16mat %array_ptr %mat %tl None DecodeFunc %decodefunc2 + )", + R"( + %decodefunc2 = OpFunction %f16 None %functy2 + %sb = OpFunctionParameter %sbptr + %c02 = OpFunctionParameter %arr2 + %c12 = OpFunctionParameter %arr2 + %entry3 = OpLabel + OpReturnValue %f16_0 + OpFunctionEnd + )"); + + CompileSuccessfully(spirv.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("first parameter must be pointer to PhysicalStorageBuffer")); +} + } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_misc_test.cpp b/test/val/val_misc_test.cpp index 6d5897c123..5304c59e00 100644 --- a/test/val/val_misc_test.cpp +++ b/test/val/val_misc_test.cpp @@ -350,6 +350,77 @@ OpEntryPoint Vertex %func "shader" EXPECT_THAT(getDiagnosticString(), HasSubstr("Invalid storage class for target environment")); } + +TEST_F(ValidateMisc, CoopMat2WorkgroupLocalSizeIdPass) { + const std::string body = R"( +OpCapability Shader +OpCapability Float16 +OpCapability Int16 +OpCapability CooperativeMatrixKHR +OpExtension "SPV_KHR_cooperative_matrix" +OpExtension "SPV_KHR_vulkan_memory_model" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionModeId %main LocalSizeId %u32_16 %u32_16 %u32_16 +%void = OpTypeVoid +%func = OpTypeFunction %void +%bool = OpTypeBool +%f16 = OpTypeFloat 16 +%u32 = OpTypeInt 32 0 + +%u32_16 = OpConstant %u32 16 +%use_Acc = OpConstant %u32 2 +%workgroup = OpConstant %u32 2 + +%f16mat = OpTypeCooperativeMatrixKHR %f16 %workgroup %u32_16 %u32_16 %use_Acc + +%main = OpFunction %void None %func +%main_entry = OpLabel + +OpReturn +OpFunctionEnd)"; + + CompileSuccessfully(body.c_str(), SPV_ENV_UNIVERSAL_1_3); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); +} + +TEST_F(ValidateMisc, CoopMat2WorkgroupLocalSizeIdConstantNotDeclaredYetFail) { + const std::string body = R"( +OpCapability Shader +OpCapability Float16 +OpCapability Int16 +OpCapability CooperativeMatrixKHR +OpExtension "SPV_KHR_cooperative_matrix" +OpExtension "SPV_KHR_vulkan_memory_model" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionModeId %main LocalSizeId %u32_16 %u32_8 %u32_16 +%void = OpTypeVoid +%func = OpTypeFunction %void +%bool = OpTypeBool +%f16 = OpTypeFloat 16 +%u32 = OpTypeInt 32 0 + +%u32_16 = OpConstant %u32 16 +%use_Acc = OpConstant %u32 2 +%workgroup = OpConstant %u32 2 + +%f16mat = OpTypeCooperativeMatrixKHR %f16 %workgroup %u32_16 %u32_16 %use_Acc +%u32_8 = OpConstant %u32 8 + +%main = OpFunction %void None %func +%main_entry = OpLabel + +OpReturn +OpFunctionEnd)"; + + CompileSuccessfully(body.c_str(), SPV_ENV_UNIVERSAL_1_3); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpTypeCooperativeMatrixKHR with ScopeWorkgroup used " + "before LocalSizeId constant value")); +} + } // namespace } // namespace val } // namespace spvtools diff --git a/utils/check_copyright.py b/utils/check_copyright.py index a6459233a5..c477ece9af 100755 --- a/utils/check_copyright.py +++ b/utils/check_copyright.py @@ -43,7 +43,8 @@ 'Shiyu Liu', 'ZHOU He', 'Nintendo', - 'Epic Games, Inc.'] + 'Epic Games, Inc.', + 'NVIDIA Corporation'] CURRENT_YEAR = 2023 FIRST_YEAR = 2014 From 5f1e86cb55c48949d8a25eb8e03e6930c4179ed9 Mon Sep 17 00:00:00 2001 From: Shahbaz Youssefi Date: Mon, 28 Oct 2024 13:31:54 -0400 Subject: [PATCH 04/26] tools: Move io utils to cpp (#5869) In preparation for more code in that file, which would get unwieldy in a header. --- BUILD.bazel | 1 + BUILD.gn | 17 ++++ test/fuzz/CMakeLists.txt | 3 +- test/reduce/CMakeLists.txt | 1 + tools/CMakeLists.txt | 19 ++-- tools/as/as.cpp | 2 +- tools/cfg/cfg.cpp | 2 +- tools/diff/diff.cpp | 4 +- tools/dis/dis.cpp | 2 +- tools/fuzz/fuzz.cpp | 5 +- tools/io.cpp | 175 +++++++++++++++++++++++++++++++++++++ tools/io.h | 163 +++------------------------------- tools/link/linker.cpp | 2 +- tools/opt/opt.cpp | 2 +- tools/reduce/reduce.cpp | 2 +- tools/val/val.cpp | 2 +- 16 files changed, 229 insertions(+), 173 deletions(-) create mode 100644 tools/io.cpp diff --git a/BUILD.bazel b/BUILD.bazel index 7dc73d0811..e6ff97dd6e 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -269,6 +269,7 @@ cc_library( cc_library( name = "tools_io", hdrs = ["tools/io.h"], + srcs = ["tools/io.cpp"], copts = COMMON_COPTS, ) diff --git a/BUILD.gn b/BUILD.gn index 23610262ea..533cca37fd 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1466,6 +1466,15 @@ source_set("spvtools_tools_util") { configs += [ ":spvtools_internal_config" ] } +source_set("spvtools_tools_io") { + sources = [ + "tools/io.cpp", + "tools/io.h", + ] + deps = [ ":spvtools_headers" ] + configs += [ ":spvtools_internal_config" ] +} + if (spvtools_build_executables) { executable("spirv-as") { sources = [ "tools/as/as.cpp" ] @@ -1473,6 +1482,7 @@ if (spvtools_build_executables) { ":spvtools", ":spvtools_software_version", ":spvtools_tools_util", + ":spvtools_tools_io", ] configs += [ ":spvtools_internal_config" ] } @@ -1483,6 +1493,7 @@ if (spvtools_build_executables) { ":spvtools", ":spvtools_software_version", ":spvtools_tools_util", + ":spvtools_tools_io", ] configs += [ ":spvtools_internal_config" ] } @@ -1493,6 +1504,7 @@ if (spvtools_build_executables) { ":spvtools", ":spvtools_software_version", ":spvtools_tools_util", + ":spvtools_tools_io", ":spvtools_val", ] configs += [ ":spvtools_internal_config" ] @@ -1508,6 +1520,7 @@ if (spvtools_build_executables) { ":spvtools", ":spvtools_software_version", ":spvtools_tools_util", + ":spvtools_tools_io", ] configs += [ ":spvtools_internal_config" ] } @@ -1519,6 +1532,7 @@ if (spvtools_build_executables) { ":spvtools_opt", ":spvtools_software_version", ":spvtools_tools_util", + ":spvtools_tools_io", ":spvtools_val", ] configs += [ ":spvtools_internal_config" ] @@ -1532,6 +1546,7 @@ if (spvtools_build_executables) { ":spvtools_opt", ":spvtools_software_version", ":spvtools_tools_util", + ":spvtools_tools_io", ":spvtools_val", ] configs += [ ":spvtools_internal_config" ] @@ -1552,6 +1567,7 @@ if (!is_ios && !spirv_is_winuwp && build_with_chromium && spvtools_build_executa ":spvtools_reduce", ":spvtools_software_version", ":spvtools_tools_util", + ":spvtools_tools_io", ":spvtools_val", "//third_party/protobuf:protobuf_full", ] @@ -1571,6 +1587,7 @@ if (!is_ios && !spirv_is_winuwp && spvtools_build_executables) { ":spvtools_reduce", ":spvtools_software_version", ":spvtools_tools_util", + ":spvtools_tools_io", ":spvtools_val", ] configs += [ ":spvtools_internal_config" ] diff --git a/test/fuzz/CMakeLists.txt b/test/fuzz/CMakeLists.txt index 56af0b9dd6..6232d6c4dd 100644 --- a/test/fuzz/CMakeLists.txt +++ b/test/fuzz/CMakeLists.txt @@ -123,7 +123,8 @@ if (${SPIRV_BUILD_FUZZER}) transformation_wrap_early_terminator_in_function_test.cpp transformation_wrap_region_in_selection_test.cpp transformation_wrap_vector_synonym_test.cpp - uniform_buffer_element_descriptor_test.cpp) + uniform_buffer_element_descriptor_test.cpp + ${spirv-tools_SOURCE_DIR}/tools/io.cpp) if (${SPIRV_ENABLE_LONG_FUZZER_TESTS}) # These are long-running tests that depend on random seeds. We do not want diff --git a/test/reduce/CMakeLists.txt b/test/reduce/CMakeLists.txt index 121cd4f08a..d3eaa84642 100644 --- a/test/reduce/CMakeLists.txt +++ b/test/reduce/CMakeLists.txt @@ -31,6 +31,7 @@ add_spvtools_unittest(TARGET reduce structured_construct_to_block_test.cpp structured_loop_to_selection_test.cpp validation_during_reduction_test.cpp + ${spirv-tools_SOURCE_DIR}/tools/io.cpp LIBS SPIRV-Tools-reduce ) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index a93f640432..a6736ca3ca 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -42,17 +42,18 @@ endfunction() set(COMMON_TOOLS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/util/flags.cpp") if (NOT ${SPIRV_SKIP_EXECUTABLES}) - add_spvtools_tool(TARGET spirv-diff SRCS ${COMMON_TOOLS_SRCS} diff/diff.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-diff SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) - add_spvtools_tool(TARGET spirv-dis SRCS ${COMMON_TOOLS_SRCS} dis/dis.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) - add_spvtools_tool(TARGET spirv-val SRCS ${COMMON_TOOLS_SRCS} val/val.cpp util/cli_consumer.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) - add_spvtools_tool(TARGET spirv-opt SRCS ${COMMON_TOOLS_SRCS} opt/opt.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-diff SRCS ${COMMON_TOOLS_SRCS} diff/diff.cpp util/cli_consumer.cpp io.cpp LIBS SPIRV-Tools-diff SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-dis SRCS ${COMMON_TOOLS_SRCS} dis/dis.cpp io.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-val SRCS ${COMMON_TOOLS_SRCS} val/val.cpp util/cli_consumer.cpp io.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-opt SRCS ${COMMON_TOOLS_SRCS} opt/opt.cpp util/cli_consumer.cpp io.cpp LIBS SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL "iOS")) # iOS does not allow std::system calls which spirv-reduce requires - add_spvtools_tool(TARGET spirv-reduce SRCS ${COMMON_TOOLS_SRCS} reduce/reduce.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-reduce ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-reduce SRCS ${COMMON_TOOLS_SRCS} reduce/reduce.cpp util/cli_consumer.cpp io.cpp LIBS SPIRV-Tools-reduce ${SPIRV_TOOLS_FULL_VISIBILITY}) endif() - add_spvtools_tool(TARGET spirv-link SRCS ${COMMON_TOOLS_SRCS} link/linker.cpp LIBS SPIRV-Tools-link ${SPIRV_TOOLS_FULL_VISIBILITY}) - add_spvtools_tool(TARGET spirv-lint SRCS ${COMMON_TOOLS_SRCS} lint/lint.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-lint SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-link SRCS ${COMMON_TOOLS_SRCS} link/linker.cpp io.cpp LIBS SPIRV-Tools-link ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-lint SRCS ${COMMON_TOOLS_SRCS} lint/lint.cpp util/cli_consumer.cpp io.cpp LIBS SPIRV-Tools-lint SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) add_spvtools_tool(TARGET spirv-as SRCS as/as.cpp + io.cpp ${COMMON_TOOLS_SRCS} LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) target_include_directories(spirv-as PRIVATE ${spirv-tools_SOURCE_DIR} @@ -61,6 +62,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES}) SRCS cfg/cfg.cpp cfg/bin_to_dot.h cfg/bin_to_dot.cpp + io.cpp ${COMMON_TOOLS_SRCS} LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) target_include_directories(spirv-cfg PRIVATE ${spirv-tools_SOURCE_DIR} @@ -73,6 +75,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES}) SRCS objdump/objdump.cpp objdump/extract_source.cpp util/cli_consumer.cpp + io.cpp ${COMMON_TOOLS_SRCS} LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) target_include_directories(spirv-objdump PRIVATE ${spirv-tools_SOURCE_DIR} @@ -85,7 +88,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES}) endif() if(SPIRV_BUILD_FUZZER) - add_spvtools_tool(TARGET spirv-fuzz SRCS fuzz/fuzz.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-fuzz ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-fuzz SRCS fuzz/fuzz.cpp util/cli_consumer.cpp io.cpp LIBS SPIRV-Tools-fuzz ${SPIRV_TOOLS_FULL_VISIBILITY}) set(SPIRV_INSTALL_TARGETS ${SPIRV_INSTALL_TARGETS} spirv-fuzz) endif(SPIRV_BUILD_FUZZER) diff --git a/tools/as/as.cpp b/tools/as/as.cpp index 2a000cf09b..ab18aeb359 100644 --- a/tools/as/as.cpp +++ b/tools/as/as.cpp @@ -106,7 +106,7 @@ int main(int, const char** argv) { std::string inFile = flags::positional_arguments[0]; std::vector contents; - if (!ReadTextFile(inFile.c_str(), &contents)) return 1; + if (!ReadTextFile(inFile.c_str(), &contents)) return 1; spv_binary binary; spv_diagnostic diagnostic = nullptr; diff --git a/tools/cfg/cfg.cpp b/tools/cfg/cfg.cpp index 2d11e6fb06..2c68904227 100644 --- a/tools/cfg/cfg.cpp +++ b/tools/cfg/cfg.cpp @@ -75,7 +75,7 @@ int main(int, const char** argv) { // Read the input binary. std::vector contents; - if (!ReadBinaryFile(inFile.c_str(), &contents)) return 1; + if (!ReadBinaryFile(inFile.c_str(), &contents)) return 1; spv_context context = spvContextCreate(kDefaultEnvironment); spv_diagnostic diagnostic = nullptr; diff --git a/tools/diff/diff.cpp b/tools/diff/diff.cpp index 2217896c3b..d60edb2e13 100644 --- a/tools/diff/diff.cpp +++ b/tools/diff/diff.cpp @@ -82,7 +82,7 @@ bool is_assembly(const char* path) { std::unique_ptr load_module(const char* path) { if (is_assembly(path)) { std::vector contents; - if (!ReadTextFile(path, &contents)) return {}; + if (!ReadTextFile(path, &contents)) return {}; return spvtools::BuildModule( kDefaultEnvironment, spvtools::utils::CLIMessageConsumer, @@ -92,7 +92,7 @@ std::unique_ptr load_module(const char* path) { } std::vector contents; - if (!ReadBinaryFile(path, &contents)) return {}; + if (!ReadBinaryFile(path, &contents)) return {}; return spvtools::BuildModule(kDefaultEnvironment, spvtools::utils::CLIMessageConsumer, diff --git a/tools/dis/dis.cpp b/tools/dis/dis.cpp index b8ce3e36ec..6b8a1ae637 100644 --- a/tools/dis/dis.cpp +++ b/tools/dis/dis.cpp @@ -153,7 +153,7 @@ int main(int, const char** argv) { // Read the input binary. std::vector contents; - if (!ReadBinaryFile(inFile.c_str(), &contents)) return 1; + if (!ReadBinaryFile(inFile.c_str(), &contents)) return 1; // If printing to standard output, then spvBinaryToText should // do the printing. In particular, colour printing on Windows is diff --git a/tools/fuzz/fuzz.cpp b/tools/fuzz/fuzz.cpp index 5f2a0080d4..e671e31eb9 100644 --- a/tools/fuzz/fuzz.cpp +++ b/tools/fuzz/fuzz.cpp @@ -584,8 +584,7 @@ bool Fuzz(const spv_target_env& target_env, [donor_filename, message_consumer, target_env]() -> std::unique_ptr { std::vector donor_binary; - if (!ReadBinaryFile(donor_filename.c_str(), - &donor_binary)) { + if (!ReadBinaryFile(donor_filename.c_str(), &donor_binary)) { return nullptr; } return spvtools::BuildModule(target_env, message_consumer, @@ -712,7 +711,7 @@ int main(int argc, const char** argv) { } std::vector binary_in; - if (!ReadBinaryFile(in_binary_file.c_str(), &binary_in)) { + if (!ReadBinaryFile(in_binary_file.c_str(), &binary_in)) { return 1; } diff --git a/tools/io.cpp b/tools/io.cpp new file mode 100644 index 0000000000..288f380ad8 --- /dev/null +++ b/tools/io.cpp @@ -0,0 +1,175 @@ +// Copyright (c) 2024 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "io.h" + +#include + +#if defined(SPIRV_WINDOWS) +#include +#include + +#define SET_STDIN_TO_BINARY_MODE() _setmode(_fileno(stdin), O_BINARY); +#define SET_STDIN_TO_TEXT_MODE() _setmode(_fileno(stdin), O_TEXT); +#define SET_STDOUT_TO_BINARY_MODE() _setmode(_fileno(stdout), O_BINARY); +#define SET_STDOUT_TO_TEXT_MODE() _setmode(_fileno(stdout), O_TEXT); +#define SET_STDOUT_MODE(mode) _setmode(_fileno(stdout), mode); +#else +#define SET_STDIN_TO_BINARY_MODE() +#define SET_STDIN_TO_TEXT_MODE() +#define SET_STDOUT_TO_BINARY_MODE() 0 +#define SET_STDOUT_TO_TEXT_MODE() 0 +#define SET_STDOUT_MODE(mode) +#endif + +namespace { +// Appends the contents of the |file| to |data|, assuming each element in the +// file is of type |T|. +template +void ReadFile(FILE* file, std::vector* data) { + if (file == nullptr) return; + + const int buf_size = 1024; + T buf[buf_size]; + while (size_t len = fread(buf, sizeof(T), buf_size, file)) { + data->insert(data->end(), buf, buf + len); + } +} + +// Returns true if |file| has encountered an error opening the file or reading +// the file as a series of element of type |T|. If there was an error, writes an +// error message to standard error. +template +bool WasFileCorrectlyRead(FILE* file, const char* filename) { + if (file == nullptr) { + fprintf(stderr, "error: file does not exist '%s'\n", filename); + return false; + } + + if (ftell(file) == -1L) { + if (ferror(file)) { + fprintf(stderr, "error: error reading file '%s'\n", filename); + return false; + } + } else { + if (sizeof(T) != 1 && (ftell(file) % sizeof(T))) { + fprintf( + stderr, + "error: file size should be a multiple of %zd; file '%s' corrupt\n", + sizeof(T), filename); + return false; + } + } + return true; +} +} // namespace + +bool ReadBinaryFile(const char* filename, std::vector* data) { + assert(data->empty()); + + const bool use_file = filename && strcmp("-", filename); + FILE* fp = nullptr; + if (use_file) { + fp = fopen(filename, "rb"); + } else { + SET_STDIN_TO_BINARY_MODE(); + fp = stdin; + } + + ReadFile(fp, data); + bool succeeded = WasFileCorrectlyRead(fp, filename); + if (use_file && fp) fclose(fp); + return succeeded; +} + +bool ReadTextFile(const char* filename, std::vector* data) { + assert(data->empty()); + + const bool use_file = filename && strcmp("-", filename); + FILE* fp = nullptr; + if (use_file) { + fp = fopen(filename, "r"); + } else { + SET_STDIN_TO_TEXT_MODE(); + fp = stdin; + } + + ReadFile(fp, data); + bool succeeded = WasFileCorrectlyRead(fp, filename); + if (use_file && fp) fclose(fp); + return succeeded; +} + +namespace { +// A class to create and manage a file for outputting data. +class OutputFile { + public: + // Opens |filename| in the given mode. If |filename| is nullptr, the empty + // string or "-", stdout will be set to the given mode. + OutputFile(const char* filename, const char* mode) : old_mode_(0) { + const bool use_stdout = + !filename || (filename[0] == '-' && filename[1] == '\0'); + if (use_stdout) { + if (strchr(mode, 'b')) { + old_mode_ = SET_STDOUT_TO_BINARY_MODE(); + } else { + old_mode_ = SET_STDOUT_TO_TEXT_MODE(); + } + fp_ = stdout; + } else { + fp_ = fopen(filename, mode); + } + } + + ~OutputFile() { + if (fp_ == stdout) { + fflush(stdout); + SET_STDOUT_MODE(old_mode_); + } else if (fp_ != nullptr) { + fclose(fp_); + } + } + + // Returns a file handle to the file. + FILE* GetFileHandle() const { return fp_; } + + private: + FILE* fp_; + int old_mode_; +}; +} // namespace + +template +bool WriteFile(const char* filename, const char* mode, const T* data, + size_t count) { + OutputFile file(filename, mode); + FILE* fp = file.GetFileHandle(); + if (fp == nullptr) { + fprintf(stderr, "error: could not open file '%s'\n", filename); + return false; + } + + size_t written = fwrite(data, sizeof(T), count, fp); + if (count != written) { + fprintf(stderr, "error: could not write to file '%s'\n", filename); + return false; + } + + return true; +} + +template bool WriteFile(const char* filename, const char* mode, + const uint32_t* data, size_t count); +template bool WriteFile(const char* filename, const char* mode, + const char* data, size_t count); diff --git a/tools/io.h b/tools/io.h index a48e3c325e..3c87fcc0d1 100644 --- a/tools/io.h +++ b/tools/io.h @@ -20,145 +20,19 @@ #include #include -#if defined(SPIRV_WINDOWS) -#include -#include - -#define SET_STDIN_TO_BINARY_MODE() _setmode(_fileno(stdin), O_BINARY); -#define SET_STDIN_TO_TEXT_MODE() _setmode(_fileno(stdin), O_TEXT); -#define SET_STDOUT_TO_BINARY_MODE() _setmode(_fileno(stdout), O_BINARY); -#define SET_STDOUT_TO_TEXT_MODE() _setmode(_fileno(stdout), O_TEXT); -#define SET_STDOUT_MODE(mode) _setmode(_fileno(stdout), mode); -#else -#define SET_STDIN_TO_BINARY_MODE() -#define SET_STDIN_TO_TEXT_MODE() -#define SET_STDOUT_TO_BINARY_MODE() 0 -#define SET_STDOUT_TO_TEXT_MODE() 0 -#define SET_STDOUT_MODE(mode) -#endif - -// Appends the contents of the |file| to |data|, assuming each element in the -// file is of type |T|. -template -void ReadFile(FILE* file, std::vector* data) { - if (file == nullptr) return; - - const int buf_size = 1024; - T buf[buf_size]; - while (size_t len = fread(buf, sizeof(T), buf_size, file)) { - data->insert(data->end(), buf, buf + len); - } -} - -// Returns true if |file| has encountered an error opening the file or reading -// the file as a series of element of type |T|. If there was an error, writes an -// error message to standard error. -template -bool WasFileCorrectlyRead(FILE* file, const char* filename) { - if (file == nullptr) { - fprintf(stderr, "error: file does not exist '%s'\n", filename); - return false; - } - - if (ftell(file) == -1L) { - if (ferror(file)) { - fprintf(stderr, "error: error reading file '%s'\n", filename); - return false; - } - } else { - if (sizeof(T) != 1 && (ftell(file) % sizeof(T))) { - fprintf( - stderr, - "error: file size should be a multiple of %zd; file '%s' corrupt\n", - sizeof(T), filename); - return false; - } - } - return true; -} - -// Appends the contents of the file named |filename| to |data|, assuming -// each element in the file is of type |T|. The file is opened as a binary file -// If |filename| is nullptr or "-", reads from the standard input, but +// Sets the contents of the file named |filename| in |data|, assuming each +// element in the file is of type |uint32_t|. The file is opened as a binary +// file. If |filename| is nullptr or "-", reads from the standard input, but // reopened as a binary file. If any error occurs, writes error messages to // standard error and returns false. -template -bool ReadBinaryFile(const char* filename, std::vector* data) { - const bool use_file = filename && strcmp("-", filename); - FILE* fp = nullptr; - if (use_file) { - fp = fopen(filename, "rb"); - } else { - SET_STDIN_TO_BINARY_MODE(); - fp = stdin; - } - - ReadFile(fp, data); - bool succeeded = WasFileCorrectlyRead(fp, filename); - if (use_file && fp) fclose(fp); - return succeeded; -} - -// Appends the contents of the file named |filename| to |data|, assuming -// each element in the file is of type |T|. The file is opened as a text file -// If |filename| is nullptr or "-", reads from the standard input, but -// reopened as a text file. If any error occurs, writes error messages to -// standard error and returns false. -template -bool ReadTextFile(const char* filename, std::vector* data) { - const bool use_file = filename && strcmp("-", filename); - FILE* fp = nullptr; - if (use_file) { - fp = fopen(filename, "r"); - } else { - SET_STDIN_TO_TEXT_MODE(); - fp = stdin; - } - - ReadFile(fp, data); - bool succeeded = WasFileCorrectlyRead(fp, filename); - if (use_file && fp) fclose(fp); - return succeeded; -} - -namespace { -// A class to create and manage a file for outputting data. -class OutputFile { - public: - // Opens |filename| in the given mode. If |filename| is nullptr, the empty - // string or "-", stdout will be set to the given mode. - OutputFile(const char* filename, const char* mode) : old_mode_(0) { - const bool use_stdout = - !filename || (filename[0] == '-' && filename[1] == '\0'); - if (use_stdout) { - if (strchr(mode, 'b')) { - old_mode_ = SET_STDOUT_TO_BINARY_MODE(); - } else { - old_mode_ = SET_STDOUT_TO_TEXT_MODE(); - } - fp_ = stdout; - } else { - fp_ = fopen(filename, mode); - } - } +bool ReadBinaryFile(const char* filename, std::vector* data); - ~OutputFile() { - if (fp_ == stdout) { - fflush(stdout); - SET_STDOUT_MODE(old_mode_); - } else if (fp_ != nullptr) { - fclose(fp_); - } - } - - // Returns a file handle to the file. - FILE* GetFileHandle() const { return fp_; } - - private: - FILE* fp_; - int old_mode_; -}; -} // namespace +// Sets the contents of the file named |filename| in |data|, assuming each +// element in the file is of type |char|. The file is opened as a text file. If +// |filename| is nullptr or "-", reads from the standard input, but reopened as +// a text file. If any error occurs, writes error messages to standard error and +// returns false. +bool ReadTextFile(const char* filename, std::vector* data); // Writes the given |data| into the file named as |filename| using the given // |mode|, assuming |data| is an array of |count| elements of type |T|. If @@ -166,21 +40,6 @@ class OutputFile { // returns false and outputs error message to standard error. template bool WriteFile(const char* filename, const char* mode, const T* data, - size_t count) { - OutputFile file(filename, mode); - FILE* fp = file.GetFileHandle(); - if (fp == nullptr) { - fprintf(stderr, "error: could not open file '%s'\n", filename); - return false; - } - - size_t written = fwrite(data, sizeof(T), count, fp); - if (count != written) { - fprintf(stderr, "error: could not write to file '%s'\n", filename); - return false; - } - - return true; -} + size_t count); #endif // TOOLS_IO_H_ diff --git a/tools/link/linker.cpp b/tools/link/linker.cpp index 7dbd8596fa..2f47dd4bb1 100644 --- a/tools/link/linker.cpp +++ b/tools/link/linker.cpp @@ -143,7 +143,7 @@ int main(int, const char* argv[]) { std::vector> contents(inFiles.size()); for (size_t i = 0u; i < inFiles.size(); ++i) { - if (!ReadBinaryFile(inFiles[i].c_str(), &contents[i])) return 1; + if (!ReadBinaryFile(inFiles[i].c_str(), &contents[i])) return 1; } const spvtools::MessageConsumer consumer = [](spv_message_level_t level, diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 52e5448989..07a57252d4 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -876,7 +876,7 @@ int main(int argc, const char** argv) { } std::vector binary; - if (!ReadBinaryFile(in_file, &binary)) { + if (!ReadBinaryFile(in_file, &binary)) { return 1; } diff --git a/tools/reduce/reduce.cpp b/tools/reduce/reduce.cpp index 959f5a2f27..143779989e 100644 --- a/tools/reduce/reduce.cpp +++ b/tools/reduce/reduce.cpp @@ -307,7 +307,7 @@ int main(int argc, const char** argv) { reducer.SetMessageConsumer(spvtools::utils::CLIMessageConsumer); std::vector binary_in; - if (!ReadBinaryFile(in_binary_file.c_str(), &binary_in)) { + if (!ReadBinaryFile(in_binary_file.c_str(), &binary_in)) { return 1; } diff --git a/tools/val/val.cpp b/tools/val/val.cpp index 33d1ddedfb..c75c6177fd 100644 --- a/tools/val/val.cpp +++ b/tools/val/val.cpp @@ -193,7 +193,7 @@ int main(int argc, char** argv) { } std::vector contents; - if (!ReadBinaryFile(inFile, &contents)) return 1; + if (!ReadBinaryFile(inFile, &contents)) return 1; spvtools::SpirvTools tools(target_env); tools.SetMessageConsumer(spvtools::utils::CLIMessageConsumer); From e5c1498afa1daa8cf3a48af7a74e3b7429afb05d Mon Sep 17 00:00:00 2001 From: dan sinclair Date: Thu, 31 Oct 2024 21:08:25 -0400 Subject: [PATCH 05/26] Update proto JSON options call. (#5867) This CL updates the usage of JsonOptions which is deprecated to the newer JsonPrintOptions. --- test/fuzz/fuzz_test_util.cpp | 2 +- tools/fuzz/fuzz.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/fuzz/fuzz_test_util.cpp b/test/fuzz/fuzz_test_util.cpp index 93c9c584d9..b238455dbb 100644 --- a/test/fuzz/fuzz_test_util.cpp +++ b/test/fuzz/fuzz_test_util.cpp @@ -145,7 +145,7 @@ void DumpTransformationsJson( const protobufs::TransformationSequence& transformations, const char* filename) { std::string json_string; - auto json_options = google::protobuf::util::JsonOptions(); + auto json_options = google::protobuf::util::JsonPrintOptions(); json_options.add_whitespace = true; auto json_generation_status = google::protobuf::util::MessageToJsonString( transformations, &json_string, json_options); diff --git a/tools/fuzz/fuzz.cpp b/tools/fuzz/fuzz.cpp index e671e31eb9..391d338981 100644 --- a/tools/fuzz/fuzz.cpp +++ b/tools/fuzz/fuzz.cpp @@ -672,7 +672,7 @@ void DumpTransformationsJson( const spvtools::fuzz::protobufs::TransformationSequence& transformations, const char* filename) { std::string json_string; - auto json_options = google::protobuf::util::JsonOptions(); + auto json_options = google::protobuf::util::JsonPrintOptions(); json_options.add_whitespace = true; auto json_generation_status = google::protobuf::util::MessageToJsonString( transformations, &json_string, json_options); @@ -800,7 +800,7 @@ int main(int argc, const char** argv) { } std::string json_string; - auto json_options = google::protobuf::util::JsonOptions(); + auto json_options = google::protobuf::util::JsonPrintOptions(); json_options.add_whitespace = true; auto json_generation_status = google::protobuf::util::MessageToJsonString( transformations_applied, &json_string, json_options); From 9aaa2601400a29ce39ce1111aa9f790e5c9d4c1b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 2 Nov 2024 10:46:42 +0000 Subject: [PATCH 06/26] roll deps (#5850) * Roll external/googletest/ 71815bbf7..1204d6344 (4 commits) https://github.com/google/googletest/compare/71815bbf7de6...1204d634444b Created with: roll-dep external/googletest * Roll external/abseil_cpp/ 40cab2445..4b4f41e93 (12 commits) https://github.com/abseil/abseil-cpp/compare/40cab244558f...4b4f41e93d14 Created with: roll-dep external/abseil_cpp * Roll external/spirv-headers/ 22c4d1b1e..cb6b2c32d (1 commit) https://github.com/KhronosGroup/SPIRV-Headers/compare/22c4d1b1e9d1...cb6b2c32dbfc Created with: roll-dep external/spirv-headers --------- Co-authored-by: GitHub Actions[bot] <> --- DEPS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DEPS b/DEPS index 4543be7bc2..0faeb49a2c 100644 --- a/DEPS +++ b/DEPS @@ -3,18 +3,18 @@ use_relative_paths = True vars = { 'github': 'https://github.com', - 'abseil_revision': '40cab244558f225cadcb943f84c5209f7ce876b1', + 'abseil_revision': '4b4f41e93d14812481b7692f89dccb1f0d609a28', 'effcee_revision': '2c97e5689ed8d7ab6ae5820f884f03a601ae124b', - 'googletest_revision': '71815bbf7de6e10c11821d654a2fae2cf42de0f7', + 'googletest_revision': '1204d634444b0ba6da53201a8b6caf2a502d883c', # Use protobufs before they gained the dependency on abseil 'protobuf_revision': 'v21.12', 're2_revision': '6dcd83d60f7944926bfd308cc13979fc53dd69ca', - 'spirv_headers_revision': '22c4d1b1e9d1c7d9aa5086c93e6491f21080019b', + 'spirv_headers_revision': 'cb6b2c32dbfc3257c1e9142a116fe9ee3d9b80a2', } deps = { From d426fc53bbdac559456f2f626b71ff2709e59290 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 07:23:22 -0500 Subject: [PATCH 07/26] build(deps): bump the github-actions group across 1 directory with 3 updates (#5866) Bumps the github-actions group with 3 updates in the / directory: [actions/checkout](https://github.com/actions/checkout), [actions/cache](https://github.com/actions/cache) and [github/codeql-action](https://github.com/github/codeql-action). Updates `actions/checkout` from 4.2.1 to 4.2.2 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871...11bd71901bbe5b1630ceea73d27597364c9af683) Updates `actions/cache` from 4.1.1 to 4.1.2 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/3624ceb22c1c5a301c8db4169662070a689d9ea8...6849a6489940f00c2f30c0fb92c6274307ccb58a) Updates `github/codeql-action` from 3.26.12 to 3.27.0 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/c36620d31ac7c881962c3d9dd939c40ec9434f2b...662472033e021d55d94146f66f6058822b0b39fd) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/autoroll.yml | 2 +- .github/workflows/bazel.yml | 4 ++-- .github/workflows/ios.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/scorecard.yml | 4 ++-- .github/workflows/wasm.yml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/autoroll.yml b/.github/workflows/autoroll.yml index a264a7b49c..eb0b0feaa7 100644 --- a/.github/workflows/autoroll.yml +++ b/.github/workflows/autoroll.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 # Checkout the depot tools they are needed by roll_deps.sh - name: Checkout depot tools diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 672ab9bb4e..45bbabf510 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -18,13 +18,13 @@ jobs: runs-on: ${{matrix.os}} steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: '0' - name: Download dependencies run: python3 utils/git-sync-deps - name: Mount Bazel cache - uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: path: ~/.bazel/cache key: bazel-cache-${{ runner.os }} diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 710d4f5afa..961d273c99 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -11,7 +11,7 @@ jobs: matrix: os: [ macos-latest ] steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: lukka/get-cmake@b516803a3c5fac40e2e922349d15cdebdba01e60 # v3.30.5 - name: Download dependencies run: python3 utils/git-sync-deps diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 06ccfe9ec9..1e0d865a8e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: prepare-release-job: runs-on: ubuntu-latest steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Prepare CHANGELOG for version run: | python utils/generate_changelog.py CHANGES "${{ github.ref_name }}" VERSION_CHANGELOG diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 828d518a7c..039880d49e 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -23,7 +23,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false @@ -48,6 +48,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 + uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: sarif_file: results.sarif diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index 511fd1f8b1..cbe21435a0 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: '0' - name: Build web From 02433568af277324e6d7fe4582b663f14165c563 Mon Sep 17 00:00:00 2001 From: Shahbaz Youssefi Date: Mon, 4 Nov 2024 09:57:37 -0500 Subject: [PATCH 08/26] tools: Accept hex representation as binary input (#5870) Sometimes when debugging or logging, SPIR-V may be dumped as a stream of hex values. There are tools to convert such a stream to binary (such as [1]) but they create an inconvenient extra step when for example the disassembly of that hex stream is needed. [1]: https://www.khronos.org/spir/visualizer/hexdump.html In this change, the binary reader used by the tools is enhanced to detect when the binary is actually a hex stream, and parse that instead. The following formats are accepted, detected based on how the SPIR-V magic number is output: === Words If the first token of the hex stream is one of 0x07230203, 0x7230203, x07230203, or x7230203, the hex stream is expected to consist of 32-bit hex words prefixed with 0x or x. For example: 0x7230203, 0x10400, 0x180001, 0x79, 0x0 is parsed as: 0x07230203 0x00010400 0x00180001 0x00000079 0x00000000 Note that `,` is optional in the stream, but the hex values are expected to be delimited by either `,` or whitespace. === Bytes With Prefix If the first token of the hex stream is one of 0x07, 0x7, x07, x7, 0x03, 0x3, x03, or x3, the hex stream is expected to consist of 8-bit hex bytes prefixed with 0x or x. If the first token has a value of 7, the stream is big-endian. Otherwise it's little-endian. For example: 0x3, 0x2, 0x23, 0x7, 0x0, 0x4, 0x1, 0x0, 0x1, 0x0, 0x18, 0x0, 0x79, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 is parsed as: 0x07230203 0x00010400 0x00180001 0x00000079 0x00000000 Similar to "Words", `,` is optional in the stream, but the hex values are expected to be delimited by either `,` or whitespace. === Bytes Without Prefix If the first two characters of the hex stream is 07, or 03, the hex stream is expected to consist of 8-bit hex bytes of 2 characters each. If the first token is 07, the stream is big-endian. Otherwise it's little-endian. Unlike the other modes, delimiter is optional (which automatically handles 32-bit word streams), but no 0-padding is done. For example, all of the following: 03, 02, 23, 07, 00, 04, 01, 00, 01, 00, 18, 00, 79, 00, 00, 00, 00, 00, 00, 00 03 02 23 07 00 04 01 00 01 00 18 00 79 00 00 00 00 00 00 00 03022307 00040100 01001800 79000000 00000000 07,23,02,03,00,01,04,00,00,18,00,01,00,00,00,79,00,00,00,00 07230203, 00010400, 00180001, 00000079, 00000000 are parsed as: 0x07230203 0x00010400 0x00180001 0x00000079 0x00000000 --- BUILD.bazel | 1 + BUILD.gn | 2 + README.md | 2 + test/CMakeLists.txt | 3 + test/diff/diff_test.cpp | 1 - test/diff/diff_test_utils.cpp | 1 - test/hex_to_text_test.cpp | 429 ++++++++++++++++++++++++++++++++++ tools/dis/dis.cpp | 4 + tools/io.cpp | 327 ++++++++++++++++++++++++-- tools/io.h | 20 ++ 10 files changed, 775 insertions(+), 15 deletions(-) create mode 100644 test/hex_to_text_test.cpp diff --git a/BUILD.bazel b/BUILD.bazel index e6ff97dd6e..526d08e39f 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -447,6 +447,7 @@ cc_library( "tools_util", ":spirv_tools_internal", ":test_lib", + ":tools_io", "@googletest//:gtest", "@googletest//:gtest_main", ], diff --git a/BUILD.gn b/BUILD.gn index 533cca37fd..7c361f0337 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1377,6 +1377,7 @@ if (build_with_chromium && spvtools_build_executables) { "test/fix_word_test.cpp", "test/generator_magic_number_test.cpp", "test/hex_float_test.cpp", + "test/hex_to_text_test.cpp", "test/immediate_int_test.cpp", "test/libspirv_macros_test.cpp", "test/name_mapper_test.cpp", @@ -1424,6 +1425,7 @@ if (build_with_chromium && spvtools_build_executables) { ":spvtools_language_header_cldebuginfo100", ":spvtools_language_header_debuginfo", ":spvtools_language_header_vkdebuginfo100", + ":spvtools_tools_io", ":spvtools_val", "//testing/gmock", "//testing/gtest", diff --git a/README.md b/README.md index 7db5bd42a7..d1ce2fbed8 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ further notice. * Assembler only does basic syntax checking. No cross validation of IDs or types is performed, except to check literal arguments to `OpConstant`, `OpSpecConstant`, and `OpSwitch`. +* Where tools expect binary input, a hex stream may be provided instead. See + `spirv-dis --help`. See [`docs/syntax.md`](docs/syntax.md) for the assembly language syntax. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 76940ce1f2..119e9c9f25 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -88,6 +88,7 @@ endfunction() set(TEST_SOURCES test_fixture.h unit_spirv.h + ${spirv-tools_SOURCE_DIR}/tools/io.h assembly_context_test.cpp assembly_format_test.cpp @@ -110,6 +111,7 @@ set(TEST_SOURCES fix_word_test.cpp generator_magic_number_test.cpp hex_float_test.cpp + hex_to_text_test.cpp immediate_int_test.cpp libspirv_macros_test.cpp named_id_test.cpp @@ -154,6 +156,7 @@ set(TEST_SOURCES to_string_test.cpp unit_spirv.cpp + ${spirv-tools_SOURCE_DIR}/tools/io.cpp ) spvtools_pch(TEST_SOURCES pch_test) diff --git a/test/diff/diff_test.cpp b/test/diff/diff_test.cpp index 3b63c69c7c..da869315da 100644 --- a/test/diff/diff_test.cpp +++ b/test/diff/diff_test.cpp @@ -20,7 +20,6 @@ #include "source/opt/ir_context.h" #include "source/spirv_constant.h" #include "spirv-tools/libspirv.hpp" -#include "tools/io.h" #include "tools/util/cli_consumer.h" #include diff --git a/test/diff/diff_test_utils.cpp b/test/diff/diff_test_utils.cpp index 14bb821536..3bea9c3b18 100644 --- a/test/diff/diff_test_utils.cpp +++ b/test/diff/diff_test_utils.cpp @@ -18,7 +18,6 @@ #include "source/opt/ir_context.h" #include "spirv-tools/libspirv.hpp" -#include "tools/io.h" #include "tools/util/cli_consumer.h" #include "gtest/gtest.h" diff --git a/test/hex_to_text_test.cpp b/test/hex_to_text_test.cpp new file mode 100644 index 0000000000..cc5c673f8d --- /dev/null +++ b/test/hex_to_text_test.cpp @@ -0,0 +1,429 @@ +// Copyright (c) 2024 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "gmock/gmock.h" +#include "test/test_fixture.h" +#include "tools/io.h" + +namespace spvtools { +namespace { + +using spvtest::ScopedContext; + +class HexToText : public ::testing::Test { + public: + void VerifyDisassembly(const char* hex_stream, + const char* expected_disassembly) { + std::vector stream(hex_stream, hex_stream + strlen(hex_stream)); + std::vector binary; + + // Convert hext to binary first. + EXPECT_TRUE(ConvertHexToBinary(stream, &binary)); + + // Then disassemble it. + spv_diagnostic diagnostic = nullptr; + spv_text disassembly = nullptr; + EXPECT_EQ(spvBinaryToText(ScopedContext().context, binary.data(), + binary.size(), SPV_BINARY_TO_TEXT_OPTION_NONE, + &disassembly, &diagnostic), + SPV_SUCCESS); + EXPECT_EQ(diagnostic, nullptr); + + // Verify disassembly is as expected and clean up. + EXPECT_STREQ(disassembly->str, expected_disassembly); + + spvDiagnosticDestroy(diagnostic); + spvTextDestroy(disassembly); + } + + void EnsureError(const char* hex_stream) { + std::vector stream(hex_stream, hex_stream + strlen(hex_stream)); + std::vector binary; + + // Make sure there is a parse error + EXPECT_FALSE(ConvertHexToBinary(stream, &binary)); + } +}; + +// The actual assembly doesn't matter, just the hex parsing. All the tests use +// the following SPIR-V. +constexpr char kDisassembly[] = R"(; SPIR-V +; Version: 1.6 +; Generator: Khronos SPIR-V Tools Assembler; 0 +; Bound: 11 +; Schema: 0 +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint Vertex %1 "main" %2 %3 +OpName %2 "fancy_attribute" +OpName %3 "useful_output" +OpDecorate %2 Location 4 +OpDecorate %3 Location 2 +%4 = OpTypeFloat 32 +%5 = OpTypePointer Input %4 +%2 = OpVariable %5 Input +%6 = OpTypePointer Output %4 +%3 = OpVariable %6 Output +%7 = OpTypeVoid +%8 = OpTypeFunction %7 +%1 = OpFunction %7 None %8 +%9 = OpLabel +%10 = OpLoad %4 %2 +OpStore %3 %10 +OpReturn +OpFunctionEnd +)"; + +TEST_F(HexToText, Words) { + constexpr char kHex[] = R"(0x07230203, 0x00010600, 0x00070000, 0x0000000b +0x00000000, 0x00020011, 0x00000001, 0x0003000e +0x00000000, 0x00000001, 0x0007000f, 0x00000000 +0x00000001, 0x6e69616d, 0x00000000, 0x00000002 +0x00000003, 0x00060005, 0x00000002, 0x636e6166 +0x74615f79, 0x62697274, 0x00657475, 0x00060005 +0x00000003, 0x66657375, 0x6f5f6c75, 0x75707475 +0x00000074, 0x00040047, 0x00000002, 0x0000001e +0x00000004, 0x00040047, 0x00000003, 0x0000001e +0x00000002, 0x00030016, 0x00000004, 0x00000020 +0x00040020, 0x00000005, 0x00000001, 0x00000004 +0x0004003b, 0x00000005, 0x00000002, 0x00000001 +0x00040020, 0x00000006, 0x00000003, 0x00000004 +0x0004003b, 0x00000006, 0x00000003, 0x00000003 +0x00020013, 0x00000007, 0x00030021, 0x00000008 +0x00000007, 0x00050036, 0x00000007, 0x00000001 +0x00000000, 0x00000008, 0x000200f8, 0x00000009 +0x0004003d, 0x00000004, 0x0000000a, 0x00000002 +0x0003003e, 0x00000003, 0x0000000a, 0x000100fd +0x00010038)"; + + VerifyDisassembly(kHex, kDisassembly); +} + +TEST_F(HexToText, WordsLeadingSpace) { + constexpr char kHex[] = R"( +x07230203, x00010600, x00070000, x0000000b +x00000000, x00020011, x00000001, x0003000e +x00000000, x00000001, x0007000f, x00000000 +x00000001, x6e69616d, x00000000, x00000002 +x00000003, x00060005, x00000002, x636e6166 +x74615f79, x62697274, x00657475, x00060005 +x00000003, x66657375, x6f5f6c75, x75707475 +x00000074, x00040047, x00000002, x0000001e +x00000004, x00040047, x00000003, x0000001e +x00000002, x00030016, x00000004, x00000020 +x00040020, x00000005, x00000001, x00000004 +x0004003b, x00000005, x00000002, x00000001 +x00040020, x00000006, x00000003, x00000004 +x0004003b, x00000006, x00000003, x00000003 +x00020013, x00000007, x00030021, x00000008 +x00000007, x00050036, x00000007, x00000001 +x00000000, x00000008, x000200f8, x00000009 +x0004003d, x00000004, x0000000a, x00000002 +x0003003e, x00000003, x0000000a, x000100fd +x00010038)"; + + VerifyDisassembly(kHex, kDisassembly); +} + +TEST_F(HexToText, WordsTrailingSpace) { + constexpr char kHex[] = R"(0X7230203, 0X10600, 0X70000, 0XB +0X0, 0X20011, 0X1, 0X3000E +0X0, 0X1, 0X7000F, 0X0 +0X1, X6E69616D, 0X0, 0X2 +0X3, 0X60005, 0X2, X636E6166 +X74615F79, X62697274, 0X657475, 0X60005 +0X3, X66657375, X6F5F6C75, X75707475 +0X74, 0X40047, 0X2, 0X1E +0X4, 0X40047, 0X3, 0X1E +0X2, 0X30016, 0X4, 0X20 +0X40020, 0X5, 0X1, 0X4 +0X4003B, 0X5, 0X2, 0X1 +0X40020, 0X6, 0X3, 0X4 +0X4003B, 0X6, 0X3, 0X3 +0X20013, 0X7, 0X30021, 0X8 +0X7, 0X50036, 0X7, 0X1 +0X0, 0X8, 0X200F8, 0X9 +0X4003D, 0X4, 0XA, 0X2 +0X3003E, 0X3, 0XA, 0X100FD +0X10038 + +)"; + + VerifyDisassembly(kHex, kDisassembly); +} + +TEST_F(HexToText, BytesLittleEndian) { + constexpr char kHex[] = R"( +0x03 0x02 0x23 0x07 0x00 0x06 0x01 0x00 0x00 0x00 0x07 0x00 0x0b 0x00 0x00 0x00 +0x00 0x00 0x00 0x00 0x11 0x00 0x02 0x00 0x01 0x00 0x00 0x00 0x0e 0x00 0x03 0x00 +0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x0f 0x00 0x07 0x00 0x00 0x00 0x00 0x00 +0x01 0x00 0x00 0x00 0x6d 0x61 0x69 0x6e 0x00 0x00 0x00 0x00 0x02 0x00 0x00 0x00 +0x03 0x00 0x00 0x00 0x05 0x00 0x06 0x00 0x02 0x00 0x00 0x00 0x66 0x61 0x6e 0x63 +0x79 0x5f 0x61 0x74 0x74 0x72 0x69 0x62 0x75 0x74 0x65 0x00 0x05 0x00 0x06 0x00 +0x03 0x00 0x00 0x00 0x75 0x73 0x65 0x66 0x75 0x6c 0x5f 0x6f 0x75 0x74 0x70 0x75 +0x74 0x00 0x00 0x00 0x47 0x00 0x04 0x00 0x02 0x00 0x00 0x00 0x1e 0x00 0x00 0x00 +0x04 0x00 0x00 0x00 0x47 0x00 0x04 0x00 0x03 0x00 0x00 0x00 0x1e 0x00 0x00 0x00 +0x02 0x00 0x00 0x00 0x16 0x00 0x03 0x00 0x04 0x00 0x00 0x00 0x20 0x00 0x00 0x00 +0x20 0x00 0x04 0x00 0x05 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x04 0x00 0x00 0x00 +0x3b 0x00 0x04 0x00 0x05 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x01 0x00 0x00 0x00 +0x20 0x00 0x04 0x00 0x06 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x04 0x00 0x00 0x00 +0x3b 0x00 0x04 0x00 0x06 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x03 0x00 0x00 0x00 +0x13 0x00 0x02 0x00 0x07 0x00 0x00 0x00 0x21 0x00 0x03 0x00 0x08 0x00 0x00 0x00 +0x07 0x00 0x00 0x00 0x36 0x00 0x05 0x00 0x07 0x00 0x00 0x00 0x01 0x00 0x00 0x00 +0x00 0x00 0x00 0x00 0x08 0x00 0x00 0x00 0xf8 0x00 0x02 0x00 0x09 0x00 0x00 0x00 +0x3d 0x00 0x04 0x00 0x04 0x00 0x00 0x00 0x0a 0x00 0x00 0x00 0x02 0x00 0x00 0x00 +0x3e 0x00 0x03 0x00 0x03 0x00 0x00 0x00 0x0a 0x00 0x00 0x00 0xfd 0x00 0x01 0x00 +0x38 0x00 0x01 0x00 +)"; + + VerifyDisassembly(kHex, kDisassembly); +} + +TEST_F(HexToText, BytesBigEndian) { + constexpr char kHex[] = R"( +X07,X23,X02,X03, X00,X01,X06,X00, X00,X07,X00,X00, X00,X00,X00,X0B +X00,X00,X00,X00, X00,X02,X00,X11, X00,X00,X00,X01, X00,X03,X00,X0E +X00,X00,X00,X00, X00,X00,X00,X01, X00,X07,X00,X0F, X00,X00,X00,X00 +X00,X00,X00,X01, X6E,X69,X61,X6D, X00,X00,X00,X00, X00,X00,X00,X02 +X00,X00,X00,X03, X00,X06,X00,X05, X00,X00,X00,X02, X63,X6E,X61,X66 +X74,X61,X5F,X79, X62,X69,X72,X74, X00,X65,X74,X75, X00,X06,X00,X05 +X00,X00,X00,X03, X66,X65,X73,X75, X6F,X5F,X6C,X75, X75,X70,X74,X75 +X00,X00,X00,X74, X00,X04,X00,X47, X00,X00,X00,X02, X00,X00,X00,X1E +X00,X00,X00,X04, X00,X04,X00,X47, X00,X00,X00,X03, X00,X00,X00,X1E +X00,X00,X00,X02, X00,X03,X00,X16, X00,X00,X00,X04, X00,X00,X00,X20 +X00,X04,X00,X20, X00,X00,X00,X05, X00,X00,X00,X01, X00,X00,X00,X04 +X00,X04,X00,X3B, X00,X00,X00,X05, X00,X00,X00,X02, X00,X00,X00,X01 +X00,X04,X00,X20, X00,X00,X00,X06, X00,X00,X00,X03, X00,X00,X00,X04 +X00,X04,X00,X3B, X00,X00,X00,X06, X00,X00,X00,X03, X00,X00,X00,X03 +X00,X02,X00,X13, X00,X00,X00,X07, X00,X03,X00,X21, X00,X00,X00,X08 +X00,X00,X00,X07, X00,X05,X00,X36, X00,X00,X00,X07, X00,X00,X00,X01 +X00,X00,X00,X00, X00,X00,X00,X08, X00,X02,X00,XF8, X00,X00,X00,X09 +X00,X04,X00,X3D, X00,X00,X00,X04, X00,X00,X00,X0A, X00,X00,X00,X02 +X00,X03,X00,X3E, X00,X00,X00,X03, X00,X00,X00,X0A, X00,X01,X00,XFD +X00,X01,X00,X38, +)"; + + VerifyDisassembly(kHex, kDisassembly); +} + +TEST_F(HexToText, StreamLittleEndian) { + constexpr char kHex[] = R"( +03 02 23 07 00 06 01 00 00 00 07 00 0b 00 00 00 +00 00 00 00 11 00 02 00 01 00 00 00 0e 00 03 00 +00 00 00 00 01 00 00 00 0f 00 07 00 00 00 00 00 +01 00 00 00 6d 61 69 6e 00 00 00 00 02 00 00 00 +03 00 00 00 05 00 06 00 02 00 00 00 66 61 6e 63 +79 5f 61 74 74 72 69 62 75 74 65 00 05 00 06 00 +03 00 00 00 75 73 65 66 75 6c 5f 6f 75 74 70 75 +74 00 00 00 47 00 04 00 02 00 00 00 1e 00 00 00 +04 00 00 00 47 00 04 00 03 00 00 00 1e 00 00 00 +02 00 00 00 16 00 03 00 04 00 00 00 20 00 00 00 +20 00 04 00 05 00 00 00 01 00 00 00 04 00 00 00 +3b 00 04 00 05 00 00 00 02 00 00 00 01 00 00 00 +20 00 04 00 06 00 00 00 03 00 00 00 04 00 00 00 +3b 00 04 00 06 00 00 00 03 00 00 00 03 00 00 00 +13 00 02 00 07 00 00 00 21 00 03 00 08 00 00 00 +07 00 00 00 36 00 05 00 07 00 00 00 01 00 00 00 +00 00 00 00 08 00 00 00 f8 00 02 00 09 00 00 00 +3d 00 04 00 04 00 00 00 0a 00 00 00 02 00 00 00 +3e 00 03 00 03 00 00 00 0a 00 00 00 fd 00 01 00 +38 00 01 00 +)"; + + VerifyDisassembly(kHex, kDisassembly); +} + +TEST_F(HexToText, StreamLittleEndianNoDelim) { + constexpr char kHex[] = R"( +0302230700060100000007000B000000 +0000000011000200010000000E000300 +00000000010000000F00070000000000 +010000006D61696E0000000002000000 +03000000050006000200000066616E63 +795F6174747269627574650005000600 +0300000075736566756C5F6F75747075 +7400000047000400020000001E000000 +0400000047000400030000001E000000 +02000000160003000400000020000000 +20000400050000000100000004000000 +3B000400050000000200000001000000 +20000400060000000300000004000000 +3B000400060000000300000003000000 +13000200070000002100030008000000 +07000000360005000700000001000000 +0000000008000000F800020009000000 +3D000400040000000A00000002000000 +3E000300030000000A000000FD000100 +38000100 +)"; + + VerifyDisassembly(kHex, kDisassembly); +} + +TEST_F(HexToText, StreamBigEndian) { + constexpr char kHex[] = R"( +07230203, 00010600, 00070000, 0000000b +00000000, 00020011, 00000001, 0003000e +00000000, 00000001, 0007000f, 00000000 +00000001, 6e69616d, 00000000, 00000002 +00000003, 00060005, 00000002, 636e6166 +74615f79, 62697274, 00657475, 00060005 +00000003, 66657375, 6f5f6c75, 75707475 +00000074, 00040047, 00000002, 0000001e +00000004, 00040047, 00000003, 0000001e +00000002, 00030016, 00000004, 00000020 +00040020, 00000005, 00000001, 00000004 +0004003b, 00000005, 00000002, 00000001 +00040020, 00000006, 00000003, 00000004 +0004003b, 00000006, 00000003, 00000003 +00020013, 00000007, 00030021, 00000008 +00000007, 00050036, 00000007, 00000001 +00000000, 00000008, 000200f8, 00000009 +0004003d, 00000004, 0000000a, 00000002 +0003003e, 00000003, 0000000a, 000100fd +00010038, +)"; + + VerifyDisassembly(kHex, kDisassembly); +} + +TEST_F(HexToText, WordsNoDelimieter) { + constexpr char kHex[] = R"(0x07230203 0x00010600 0x00070000 0x0000000b +0x00000000 0x00020011 0x00000001 0x0003000e +0x00000000 0x00000001 0x0007000f 0x00000000 +0x00000001 0x6e69616d 0x00000000 0x00000002 +0x00000003 0x00060005 0x00000002 0x636e6166 +0x74615f79 0x62697274 0x00657475 0x00060005 +0x00000003 0x666573750x6f5f6c75 0x75707475 +0x00000074 0x00040047 0x00000002 0x0000001e +0x00000004 0x00040047 0x00000003 0x0000001e +0x00000002 0x00030016 0x00000004 0x00000020 +0x00040020 0x00000005 0x00000001 0x00000004 +0x0004003b 0x00000005 0x00000002 0x00000001 +0x00040020 0x00000006 0x00000003 0x00000004 +0x0004003b 0x00000006 0x00000003 0x00000003 +0x00020013 0x00000007 0x00030021 0x00000008 +0x00000007 0x00050036 0x00000007 0x00000001 +0x00000000 0x00000008 0x000200f8 0x00000009 +0x0004003d 0x00000004 0x0000000a 0x00000002 +0x0003003e 0x00000003 0x0000000a 0x000100fd +0x00010038)"; + + EnsureError(kHex); +} + +TEST_F(HexToText, InvalidFirstToken) { + constexpr char kHex[] = R"(0x17230203, 0x00010600, 0x00070000, 0x0000000b +0x00000000, 0x00020011, 0x00000001, 0x0003000e +0x00000000, 0x00000001, 0x0007000f, 0x00000000 +0x00000001, 0x6e69616d, 0x00000000, 0x00000002 +0x00000003, 0x00060005, 0x00000002, 0x636e6166 +0x74615f79, 0x62697274, 0x00657475, 0x00060005 +0x00000003, 0x66657375, 0x6f5f6c75, 0x75707475 +0x00000074, 0x00040047, 0x00000002, 0x0000001e +0x00000004, 0x00040047, 0x00000003, 0x0000001e +0x00000002, 0x00030016, 0x00000004, 0x00000020 +0x00040020, 0x00000005, 0x00000001, 0x00000004 +0x0004003b, 0x00000005, 0x00000002, 0x00000001 +0x00040020, 0x00000006, 0x00000003, 0x00000004 +0x0004003b, 0x00000006, 0x00000003, 0x00000003 +0x00020013, 0x00000007, 0x00030021, 0x00000008 +0x00000007, 0x00050036, 0x00000007, 0x00000001 +0x00000000, 0x00000008, 0x000200f8, 0x00000009 +0x0004003d, 0x00000004, 0x0000000a, 0x00000002 +0x0003003e, 0x00000003, 0x0000000a, 0x000100fd +0x00010038)"; + + EnsureError(kHex); +} + +TEST_F(HexToText, NonHexCharacter) { + // Note: a 6 is replaced with G in this stream + constexpr char kHex[] = R"(0x07230203, 0x00010600, 0x00070000, 0x0000000b +0x00000000, 0x00020011, 0x00000001, 0x0003000e +0x00000000, 0x00000001, 0x0007000f, 0x00000000 +0x00000001, 0x6e69616d, 0x00000000, 0x00000002 +0x00000003, 0x00060005, 0x00000002, 0x636e6166 +0x74615f79, 0x62697274, 0x00657475, 0x00060005 +0x00000003, 0x66657375, 0x6f5f6c75, 0x75707475 +0x00000074, 0x00040047, 0x00000002, 0x0000001e +0x00000004, 0x00040047, 0x00000003, 0x0000001e +0x00000002, 0x0003001G, 0x00000004, 0x00000020 +0x00040020, 0x00000005, 0x00000001, 0x00000004 +0x0004003b, 0x00000005, 0x00000002, 0x00000001 +0x00040020, 0x00000006, 0x00000003, 0x00000004 +0x0004003b, 0x00000006, 0x00000003, 0x00000003 +0x00020013, 0x00000007, 0x00030021, 0x00000008 +0x00000007, 0x00050036, 0x00000007, 0x00000001 +0x00000000, 0x00000008, 0x000200f8, 0x00000009 +0x0004003d, 0x00000004, 0x0000000a, 0x00000002 +0x0003003e, 0x00000003, 0x0000000a, 0x000100fd +0x00010038)"; + + EnsureError(kHex); +} + +TEST_F(HexToText, MissingExpectedPrefix) { + constexpr char kHex[] = R"(0x07230203, 0x00010600, 0x00070000, 0x0000000b +0x00000000, 0x00020011, 0x00000001, 0x0003000e +0x00000000, 0x00000001, 0x0007000f, 0x00000000 +0x00000001, 0x6e69616d, 0x00000000, 0x00000002 +0x00000003, 0x00060005, 0x00000002, 0x636e6166 +0x74615f79, 0x62697274, 0x00657475, 0x00060005 +0x00000003, 0x66657375, 0x6f5f6c75, 0x75707475 +0x00000074, 0x00040047, 0x00000002, 0x0000001e +0x00000004, 0x00040047, 0x00000003, 0x0000001e +0x00000002, 0x00030016, 0x00000004, 0x00000020 +0x00040020, 0x00000005, 00000001, 0x00000004 +0x0004003b, 0x00000005, 0x00000002, 0x00000001 +0x00040020, 0x00000006, 0x00000003, 0x00000004 +0x0004003b, 0x00000006, 0x00000003, 0x00000003 +0x00020013, 0x00000007, 0x00030021, 0x00000008 +0x00000007, 0x00050036, 0x00000007, 0x00000001 +0x00000000, 0x00000008, 0x000200f8, 0x00000009 +0x0004003d, 0x00000004, 0x0000000a, 0x00000002 +0x0003003e, 0x00000003, 0x0000000a, 0x000100fd +0x00010038)"; + + EnsureError(kHex); +} + +TEST_F(HexToText, UnexpectedPrefix) { + constexpr char kHex[] = R"(07230203, 00010600, 00070000, 0000000b +00000000, 00020011, 00000001, 0003000e +00000000, 00000001, 0007000f, 00000000 +00000001, 6e69616d, 00000000, 00000002 +00000003, 00060005, 00000002, 636e6166 +74615f79, 62697274, 00657475, 00060005 +00000003, 66657375, 6f5f6c75, 75707475 +00000074, 00040047, 00000002, 0000001e +00000004, 00040047, 00000003, 0000001e +00000002, 00030016, 00000004, 00000020 +00040020, 00000005, 0x00000001, 00000004 +0004003b, 00000005, 00000002, 00000001 +00040020, 00000006, 00000003, 00000004 +0004003b, 00000006, 00000003, 00000003 +00020013, 00000007, 00030021, 00000008 +00000007, 00050036, 00000007, 00000001 +00000000, 00000008, 000200f8, 00000009 +0004003d, 00000004, 0000000a, 00000002 +0003003e, 00000003, 0000000a, 000100fd +00010038)"; + + EnsureError(kHex); +} +} // namespace +} // namespace spvtools diff --git a/tools/dis/dis.cpp b/tools/dis/dis.cpp index 6b8a1ae637..c294d039ce 100644 --- a/tools/dis/dis.cpp +++ b/tools/dis/dis.cpp @@ -33,6 +33,10 @@ Usage: %s [options] [] The SPIR-V binary is read from . If no file is specified, or if the filename is "-", then the binary is read from standard input. +A text-based hex stream is also accepted as binary input, which should either +consist of 32-bit words or 8-bit bytes. The 0x or x prefix is optional, but +should be consistently present in the stream. + Options: -h, --help Print this help. diff --git a/tools/io.cpp b/tools/io.cpp index 288f380ad8..9c7d21f723 100644 --- a/tools/io.cpp +++ b/tools/io.cpp @@ -15,6 +15,8 @@ #include "io.h" #include +#include +#include #if defined(SPIRV_WINDOWS) #include @@ -40,7 +42,7 @@ template void ReadFile(FILE* file, std::vector* data) { if (file == nullptr) return; - const int buf_size = 1024; + const int buf_size = 4096 / sizeof(T); T buf[buf_size]; while (size_t len = fread(buf, sizeof(T), buf_size, file)) { data->insert(data->end(), buf, buf + len); @@ -48,9 +50,7 @@ void ReadFile(FILE* file, std::vector* data) { } // Returns true if |file| has encountered an error opening the file or reading -// the file as a series of element of type |T|. If there was an error, writes an -// error message to standard error. -template +// from it. If there was an error, writes an error message to standard error. bool WasFileCorrectlyRead(FILE* file, const char* filename) { if (file == nullptr) { fprintf(stderr, "error: file does not exist '%s'\n", filename); @@ -62,17 +62,291 @@ bool WasFileCorrectlyRead(FILE* file, const char* filename) { fprintf(stderr, "error: error reading file '%s'\n", filename); return false; } - } else { - if (sizeof(T) != 1 && (ftell(file) % sizeof(T))) { - fprintf( - stderr, - "error: file size should be a multiple of %zd; file '%s' corrupt\n", - sizeof(T), filename); + } + return true; +} + +// Ensure the file contained an exact number of elements, whose size is given in +// |alignment|. +bool WasFileSizeAligned(const char* filename, size_t read_size, + size_t alignment) { + assert(alignment != 1); + if ((read_size % alignment) != 0) { + fprintf(stderr, + "error: file size should be a multiple of %zd; file '%s' corrupt\n", + alignment, filename); + return false; + } + return true; +} + +// Different formats the hex is expected to be in. +enum class HexMode { + // 0x07230203, ... + Words, + // 0x07, 0x23, 0x02, 0x03, ... + BytesBigEndian, + // 0x03, 0x02, 0x23, 0x07, ... + BytesLittleEndian, + // 07 23 02 03 ... + StreamBigEndian, + // 03 02 23 07 ... + StreamLittleEndian, +}; + +// Whether a character should be skipped as whitespace / separator / +// end-of-file. +bool IsSpace(char c) { return isspace(c) || c == ',' || c == '\0'; } + +bool IsHexStream(const std::vector& stream) { + for (char c : stream) { + if (IsSpace(c)) { + continue; + } + + // Every possible case of a SPIR-V hex stream starts with either '0' or 'x' + // (see |HexMode| values). Make a decision upon inspecting the first + // non-space character. + return c == '0' || c == 'x' || c == 'X'; + } + + return false; +} + +bool MatchIgnoreCase(const char* token, const char* expect, size_t len) { + for (size_t i = 0; i < len; ++i) { + if (tolower(token[i]) != tolower(expect[i])) { return false; } } + return true; } + +// Helper class to tokenize a hex stream +class HexTokenizer { + public: + HexTokenizer(const char* filename, const std::vector& stream, + std::vector* data) + : filename_(filename), stream_(stream), data_(data) { + DetermineMode(); + } + + bool Parse() { + while (current_ < stream_.size() && !encountered_error_) { + data_->push_back(GetNextWord()); + + // Make sure trailing space does not lead to parse error by skipping it + // and exiting the loop. + SkipSpace(); + } + + return !encountered_error_; + } + + private: + void ParseError(const char* reason) { + if (!encountered_error_) { + fprintf(stderr, + "error: hex stream parse error at character %zu: %s in '%s'\n", + current_, reason, filename_); + encountered_error_ = true; + } + } + + // Skip whitespace until the next non-whitespace non-comma character. + void SkipSpace() { + while (current_ < stream_.size()) { + char c = stream_[current_]; + if (!IsSpace(c)) { + return; + } + + ++current_; + } + } + + // Skip the 0x or x at the beginning of a hex value. + void Skip0x() { + // The first character must be 0 or x. + const char first = Next(); + if (first != '0' && first != 'x' && first != 'X') { + ParseError("expected 0x or x"); + } else if (first == '0') { + const char second = Next(); + if (second != 'x' && second != 'X') { + ParseError("expected 0x"); + } + } + } + + // Consume the next character. + char Next() { return current_ < stream_.size() ? stream_[current_++] : '\0'; } + + // Determine how to read the hex stream based on the first token. + void DetermineMode() { + SkipSpace(); + + // Read 11 bytes, that is the size of the biggest token (10) + one more. + char first_token[11]; + for (uint32_t i = 0; i < 11; ++i) { + first_token[i] = Next(); + } + + // Table of how to match the first token with a mode. + struct { + const char* expect; + bool must_have_delimiter; + HexMode mode; + } parse_info[] = { + {"0x07230203", true, HexMode::Words}, + {"0x7230203", true, HexMode::Words}, + {"x07230203", true, HexMode::Words}, + {"x7230203", true, HexMode::Words}, + + {"0x07", true, HexMode::BytesBigEndian}, + {"0x7", true, HexMode::BytesBigEndian}, + {"x07", true, HexMode::BytesBigEndian}, + {"x7", true, HexMode::BytesBigEndian}, + + {"0x03", true, HexMode::BytesLittleEndian}, + {"0x3", true, HexMode::BytesLittleEndian}, + {"x03", true, HexMode::BytesLittleEndian}, + {"x3", true, HexMode::BytesLittleEndian}, + + {"07", false, HexMode::StreamBigEndian}, + {"03", false, HexMode::StreamLittleEndian}, + }; + + // Check to see if any of the possible first tokens are matched. If not, + // this is not a recognized hex stream. + encountered_error_ = true; + for (const auto& info : parse_info) { + const size_t expect_len = strlen(info.expect); + const bool matches_expect = + MatchIgnoreCase(first_token, info.expect, expect_len); + const bool satisfies_delimeter = + !info.must_have_delimiter || IsSpace(first_token[expect_len]); + if (matches_expect && satisfies_delimeter) { + mode_ = info.mode; + encountered_error_ = false; + break; + } + } + + if (encountered_error_) { + fprintf(stderr, + "error: hex format detected, but pattern '%.11s' is not " + "recognized '%s'\n", + first_token, filename_); + } + + // Reset the position to restart parsing with the determined mode. + current_ = 0; + } + + // Consume up to |max_len| characters and put them in |token_chars|. A + // delimiter is expected. The resulting string is NUL-terminated. + void NextN(char token_chars[9], size_t max_len) { + assert(max_len < 9); + + for (size_t i = 0; i <= max_len; ++i) { + char c = Next(); + if (IsSpace(c)) { + token_chars[i] = '\0'; + return; + } + + token_chars[i] = c; + if (!isxdigit(c)) { + ParseError("encountered non-hex character"); + } + } + + // If space is not reached before the maximum number of characters where + // consumed, that's an error. + ParseError("expected delimiter (space or comma)"); + token_chars[max_len] = '\0'; + } + + // Consume one hex digit. + char NextHexDigit() { + char c = Next(); + if (!isxdigit(c)) { + ParseError("encountered non-hex character"); + } + return c; + } + + // Extract a token out of the stream. It could be either a word or a byte, + // based on |mode_|. + uint32_t GetNextToken() { + SkipSpace(); + + // The longest token can be 8 chars (for |HexMode::Words|), add one for + // '\0'. + char token_chars[9]; + + switch (mode_) { + case HexMode::Words: + case HexMode::BytesBigEndian: + case HexMode::BytesLittleEndian: + // Start with 0x, followed by up to 8 (for Word) or 2 (for Byte*) + // digits. + Skip0x(); + NextN(token_chars, mode_ == HexMode::Words ? 8 : 2); + break; + case HexMode::StreamBigEndian: + case HexMode::StreamLittleEndian: + // Always expected to see two consecutive hex digits. + token_chars[0] = NextHexDigit(); + token_chars[1] = NextHexDigit(); + token_chars[2] = '\0'; + break; + } + + if (encountered_error_) { + return 0; + } + + // Parse the hex value that was just read. + return static_cast(strtol(token_chars, nullptr, 16)); + } + + // Construct a word out of tokens + uint32_t GetNextWord() { + if (mode_ == HexMode::Words) { + return GetNextToken(); + } + + uint32_t tokens[4] = { + GetNextToken(), + GetNextToken(), + GetNextToken(), + GetNextToken(), + }; + + switch (mode_) { + case HexMode::BytesBigEndian: + case HexMode::StreamBigEndian: + return tokens[0] << 24 | tokens[1] << 16 | tokens[2] << 8 | tokens[3]; + case HexMode::BytesLittleEndian: + case HexMode::StreamLittleEndian: + return tokens[3] << 24 | tokens[2] << 16 | tokens[1] << 8 | tokens[0]; + default: + assert(false); + return 0; + } + } + + const char* filename_; + const std::vector& stream_; + std::vector* data_; + + HexMode mode_ = HexMode::Words; + size_t current_ = 0; + bool encountered_error_ = false; +}; } // namespace bool ReadBinaryFile(const char* filename, std::vector* data) { @@ -87,12 +361,39 @@ bool ReadBinaryFile(const char* filename, std::vector* data) { fp = stdin; } - ReadFile(fp, data); - bool succeeded = WasFileCorrectlyRead(fp, filename); + // Read into a char vector first. If this is a hex stream, it needs to be + // processed as such. + std::vector data_raw; + ReadFile(fp, &data_raw); + bool succeeded = WasFileCorrectlyRead(fp, filename); if (use_file && fp) fclose(fp); + + if (!succeeded) { + return false; + } + + if (IsHexStream(data_raw)) { + // If a hex stream, parse it and fill |data|. + HexTokenizer tokenizer(filename, data_raw, data); + succeeded = tokenizer.Parse(); + } else { + // If not a hex stream, convert it to uint32_t via memcpy. + succeeded = WasFileSizeAligned(filename, data_raw.size(), sizeof(uint32_t)); + if (succeeded) { + data->resize(data_raw.size() / sizeof(uint32_t), 0); + memcpy(data->data(), data_raw.data(), data_raw.size()); + } + } + return succeeded; } +bool ConvertHexToBinary(const std::vector& stream, + std::vector* data) { + HexTokenizer tokenizer("", stream, data); + return tokenizer.Parse(); +} + bool ReadTextFile(const char* filename, std::vector* data) { assert(data->empty()); @@ -106,7 +407,7 @@ bool ReadTextFile(const char* filename, std::vector* data) { } ReadFile(fp, data); - bool succeeded = WasFileCorrectlyRead(fp, filename); + bool succeeded = WasFileCorrectlyRead(fp, filename); if (use_file && fp) fclose(fp); return succeeded; } diff --git a/tools/io.h b/tools/io.h index 3c87fcc0d1..536009d531 100644 --- a/tools/io.h +++ b/tools/io.h @@ -25,8 +25,28 @@ // file. If |filename| is nullptr or "-", reads from the standard input, but // reopened as a binary file. If any error occurs, writes error messages to // standard error and returns false. +// +// If the given input is detected to be in ascii hex, it is converted to binary +// automatically. In that case, the shape of the input data is determined based +// on the representation of the magic number: +// +// * "[0]x[0]7230203": Every following "0x..." represents a word. +// * "[0]x[0]7[,] [0]x23...": Every following "0x..." represents a byte, stored +// in big-endian order +// * "[0]x[0]3[,] [0]x[0]2...": Every following "0x..." represents a byte, +// stored in little-endian order +// * "07[, ]23...": Every following "XY" represents a byte, stored in +// big-endian order +// * "03[, ]02...": Every following "XY" represents a byte, stored in +// little-endian order bool ReadBinaryFile(const char* filename, std::vector* data); +// The hex->binary logic of |ReadBinaryFile| applied to a pre-loaded stream of +// bytes. Used by tests to avoid having to call |ReadBinaryFile| with temp +// files. Returns false in case of parse errors. +bool ConvertHexToBinary(const std::vector& stream, + std::vector* data); + // Sets the contents of the file named |filename| in |data|, assuming each // element in the file is of type |char|. The file is opened as a text file. If // |filename| is nullptr or "-", reads from the standard input, but reopened as From 9117e042b93d4ff08d2406542708170f77aaa2a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 03:12:15 +0000 Subject: [PATCH 09/26] roll deps (#5871) * Roll external/googletest/ 1204d6344..d14403194 (1 commit) https://github.com/google/googletest/compare/1204d634444b...d14403194054 Created with: roll-dep external/googletest * Roll external/abseil_cpp/ 4b4f41e93..a3027054a (6 commits) https://github.com/abseil/abseil-cpp/compare/4b4f41e93d14...a3027054aba8 Created with: roll-dep external/abseil_cpp * Roll external/spirv-headers/ cb6b2c32d..996c728cf (1 commit) https://github.com/KhronosGroup/SPIRV-Headers/compare/cb6b2c32dbfc...996c728cf7dc Created with: roll-dep external/spirv-headers --------- Co-authored-by: GitHub Actions[bot] <> --- DEPS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DEPS b/DEPS index 0faeb49a2c..3e09b97c49 100644 --- a/DEPS +++ b/DEPS @@ -3,18 +3,18 @@ use_relative_paths = True vars = { 'github': 'https://github.com', - 'abseil_revision': '4b4f41e93d14812481b7692f89dccb1f0d609a28', + 'abseil_revision': 'a3027054aba8c264d2ef9663061f99228fa16645', 'effcee_revision': '2c97e5689ed8d7ab6ae5820f884f03a601ae124b', - 'googletest_revision': '1204d634444b0ba6da53201a8b6caf2a502d883c', + 'googletest_revision': 'd144031940543e15423a25ae5a8a74141044862f', # Use protobufs before they gained the dependency on abseil 'protobuf_revision': 'v21.12', 're2_revision': '6dcd83d60f7944926bfd308cc13979fc53dd69ca', - 'spirv_headers_revision': 'cb6b2c32dbfc3257c1e9142a116fe9ee3d9b80a2', + 'spirv_headers_revision': '996c728cf7dcfb29845cfa15222822318f047810', } deps = { From 384d527ebb7578b5a8d69fb05f41c5aa9a363115 Mon Sep 17 00:00:00 2001 From: Sven van Haastregt Date: Mon, 11 Nov 2024 17:18:45 +0100 Subject: [PATCH 10/26] spirv-val: Report VUID 08973 only in Vulkan environments (#5873) The storage class restriction for `OpCooperativeMatrixLoadKHR` and `OpCooperativeMatrixStoreKHR` comes from the Vulkan specification; as such VUID 08973 should not be reported outside of Vulkan target environments. Signed-off-by: Sven van Haastregt --- source/val/validate_memory.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp index ef05d6e6cf..32f642712c 100644 --- a/source/val/validate_memory.cpp +++ b/source/val/validate_memory.cpp @@ -2115,14 +2115,16 @@ spv_result_t ValidateCooperativeMatrixLoadStoreKHR(ValidationState_t& _, const auto storage_class = pointer_type->GetOperandAs(storage_class_index); - if (storage_class != spv::StorageClass::Workgroup && - storage_class != spv::StorageClass::StorageBuffer && - storage_class != spv::StorageClass::PhysicalStorageBuffer) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << _.VkErrorID(8973) << opname - << " storage class for pointer type " - << _.getIdName(pointer_type_id) - << " is not Workgroup, StorageBuffer, or PhysicalStorageBuffer."; + if (spvIsVulkanEnv(_.context()->target_env)) { + if (storage_class != spv::StorageClass::Workgroup && + storage_class != spv::StorageClass::StorageBuffer && + storage_class != spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(8973) << opname + << " storage class for pointer type " + << _.getIdName(pointer_type_id) + << " is not Workgroup, StorageBuffer, or PhysicalStorageBuffer."; + } } if (!untyped) { From 671e7ca5eee70d20ba62227cd3995a9f1b8655f8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:37:18 +0000 Subject: [PATCH 11/26] Roll external/abseil_cpp/ a3027054a..27a0c7308 (7 commits) (#5875) https://github.com/abseil/abseil-cpp/compare/a3027054aba8...27a0c7308f04 Created with: roll-dep external/abseil_cpp Co-authored-by: GitHub Actions[bot] <> --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 3e09b97c49..ec1700041b 100644 --- a/DEPS +++ b/DEPS @@ -3,7 +3,7 @@ use_relative_paths = True vars = { 'github': 'https://github.com', - 'abseil_revision': 'a3027054aba8c264d2ef9663061f99228fa16645', + 'abseil_revision': '27a0c7308f04e4560fabe5a7beca837e8f3f2c5b', 'effcee_revision': '2c97e5689ed8d7ab6ae5820f884f03a601ae124b', From 1601ec2639799a1ef7ea38b2aa6862d8d86aeb4e Mon Sep 17 00:00:00 2001 From: Spencer Fricke <115671160+spencer-lunarg@users.noreply.github.com> Date: Tue, 12 Nov 2024 10:49:08 -0500 Subject: [PATCH 12/26] ci: Make MacOS builds only run if other things pass (#5872) --- .github/workflows/bazel.yml | 25 ++++++++++++++++++++++++- .github/workflows/ios.yml | 13 ++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 45bbabf510..38dd1b3435 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 120 strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-2019] + os: [ubuntu-latest, windows-2019] runs-on: ${{matrix.os}} @@ -32,3 +32,26 @@ jobs: run: bazel --output_user_root=~/.bazel/cache build //... - name: Test All run: bazel --output_user_root=~/.bazel/cache test //... + + # iOS is 10x expensive to run on GitHub machines, so only run if we know something else passed + # The steps are unfortunately duplicated because github actions requires 2 jobs for a dependency + build-macos: + needs: build + timeout-minutes: 120 + runs-on: macos-latest + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: '0' + - name: Download dependencies + run: python3 utils/git-sync-deps + - name: Mount Bazel cache + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + with: + path: ~/.bazel/cache + key: bazel-cache-${{ runner.os }} + - name: Build All + run: bazel --output_user_root=~/.bazel/cache build //... + - name: Test All + run: bazel --output_user_root=~/.bazel/cache test //... diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 961d273c99..36de27bc2b 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -2,14 +2,17 @@ name: iOS permissions: contents: read -on: [push, pull_request, workflow_dispatch] +on: + workflow_run: + # iOS is 10x expensive to run on GitHub machines, so only run if we know something else passed + workflows: ["Wasm Build"] + types: + - completed jobs: build: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ macos-latest ] + runs-on: macos-latest + if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: lukka/get-cmake@b516803a3c5fac40e2e922349d15cdebdba01e60 # v3.30.5 From df94b2db4a6ca825c507db3d6833b824174cbea8 Mon Sep 17 00:00:00 2001 From: Steven Perron Date: Tue, 12 Nov 2024 12:38:56 -0500 Subject: [PATCH 13/26] Avoid maintaining a list of all operating systems by hand. (#5881) See #5467 Co-authored-by: Patrick Welche --- CMakeLists.txt | 24 ------------------------ source/print.cpp | 33 +++++++-------------------------- 2 files changed, 7 insertions(+), 50 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19d7107616..e50fb56c49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,37 +49,13 @@ option(ENABLE_RTTI "Enables RTTI" OFF) option(SPIRV_ALLOW_TIMERS "Allow timers via clock_gettime on supported platforms" ON) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") - add_definitions(-DSPIRV_LINUX) set(SPIRV_TIMER_ENABLED ${SPIRV_ALLOW_TIMERS}) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Emscripten") - add_definitions(-DSPIRV_EMSCRIPTEN) elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Windows") add_definitions(-DSPIRV_WINDOWS) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN") add_definitions(-DSPIRV_WINDOWS) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") - add_definitions(-DSPIRV_MAC) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "iOS") - add_definitions(-DSPIRV_IOS) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "tvOS") - add_definitions(-DSPIRV_TVOS) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "visionOS") - add_definitions(-DSPIRV_VISIONOS) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Android") - add_definitions(-DSPIRV_ANDROID) set(SPIRV_TIMER_ENABLED ${SPIRV_ALLOW_TIMERS}) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") - add_definitions(-DSPIRV_FREEBSD) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD") - add_definitions(-DSPIRV_OPENBSD) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia") - add_definitions(-DSPIRV_FUCHSIA) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "GNU") - add_definitions(-DSPIRV_GNU) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "QNX") - add_definitions(-DSPIRV_QNX) -else() - message(FATAL_ERROR "Your platform '${CMAKE_SYSTEM_NAME}' is not supported!") endif() if (${SPIRV_TIMER_ENABLED}) diff --git a/source/print.cpp b/source/print.cpp index f36812ef56..3143db1781 100644 --- a/source/print.cpp +++ b/source/print.cpp @@ -14,26 +14,7 @@ #include "source/print.h" -#if defined(SPIRV_ANDROID) || defined(SPIRV_LINUX) || defined(SPIRV_MAC) || \ - defined(SPIRV_IOS) || defined(SPIRV_TVOS) || defined(SPIRV_FREEBSD) || \ - defined(SPIRV_OPENBSD) || defined(SPIRV_EMSCRIPTEN) || \ - defined(SPIRV_FUCHSIA) || defined(SPIRV_GNU) || defined(SPIRV_QNX) -namespace spvtools { - -clr::reset::operator const char*() { return "\x1b[0m"; } - -clr::grey::operator const char*() { return "\x1b[1;30m"; } - -clr::red::operator const char*() { return "\x1b[31m"; } - -clr::green::operator const char*() { return "\x1b[32m"; } - -clr::yellow::operator const char*() { return "\x1b[33m"; } - -clr::blue::operator const char*() { return "\x1b[34m"; } - -} // namespace spvtools -#elif defined(SPIRV_WINDOWS) +#if defined(SPIRV_WINDOWS) #include namespace spvtools { @@ -111,17 +92,17 @@ clr::blue::operator const char*() { #else namespace spvtools { -clr::reset::operator const char*() { return ""; } +clr::reset::operator const char*() { return "\x1b[0m"; } -clr::grey::operator const char*() { return ""; } +clr::grey::operator const char*() { return "\x1b[1;30m"; } -clr::red::operator const char*() { return ""; } +clr::red::operator const char*() { return "\x1b[31m"; } -clr::green::operator const char*() { return ""; } +clr::green::operator const char*() { return "\x1b[32m"; } -clr::yellow::operator const char*() { return ""; } +clr::yellow::operator const char*() { return "\x1b[33m"; } -clr::blue::operator const char*() { return ""; } +clr::blue::operator const char*() { return "\x1b[34m"; } } // namespace spvtools #endif From 707da36c703581c5722cd2a16a7aa2781a6e2f2c Mon Sep 17 00:00:00 2001 From: "Qiaojin.Bao" Date: Wed, 13 Nov 2024 02:13:48 +0800 Subject: [PATCH 14/26] Correct a spelling error 'diagnostic' (#5878) --- source/text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/text.cpp b/source/text.cpp index 1723bb3171..2154e8552e 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -201,7 +201,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, } // Optional literal operands can fail to parse. In that case use - // SPV_FAILED_MATCH to avoid emitting a diagostic. Use the following + // SPV_FAILED_MATCH to avoid emitting a diagnostic. Use the following // for those situations. spv_result_t error_code_for_literals = spvOperandIsOptional(type) ? SPV_FAILED_MATCH : SPV_ERROR_INVALID_TEXT; From 692529b941dc5d7dfbd90dfa5796c60cd0a50431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Tue, 12 Nov 2024 20:45:05 +0100 Subject: [PATCH 15/26] [NFC] Apply small clang-tidy fixes (#5709) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [NFC] Apply small clang-tidy fixes - const for passed-by-value has no effect on prototypes. - transitive includes. - dead stores - uses after move Signed-off-by: Nathan Gauër * pr-feedback Signed-off-by: Nathan Gauër --------- Signed-off-by: Nathan Gauër --- source/disassemble.cpp | 2 ++ source/disassemble.h | 8 ++++---- source/opt/folding_rules.cpp | 1 + source/opt/loop_fission.cpp | 1 + source/val/validate_decorations.cpp | 2 +- source/val/validate_function.cpp | 2 +- source/val/validate_non_uniform.cpp | 5 ++--- test/enum_set_test.cpp | 5 +---- test/opt/ir_context_test.cpp | 1 + test/opt/propagator_test.cpp | 2 +- test/opt/trim_capabilities_pass_test.cpp | 5 +++++ 11 files changed, 20 insertions(+), 14 deletions(-) diff --git a/source/disassemble.cpp b/source/disassemble.cpp index db99151a90..93791a0ca7 100644 --- a/source/disassemble.cpp +++ b/source/disassemble.cpp @@ -23,8 +23,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/source/disassemble.h b/source/disassemble.h index 9baeaa43e0..b6d13c647b 100644 --- a/source/disassemble.h +++ b/source/disassemble.h @@ -15,7 +15,7 @@ #ifndef SOURCE_DISASSEMBLE_H_ #define SOURCE_DISASSEMBLE_H_ -#include +#include #include #include @@ -94,11 +94,11 @@ class InstructionDisassembler { // Emits an operand for the given instruction, where the instruction // is at offset words from the start of the binary. void EmitOperand(std::ostream& stream, const spv_parsed_instruction_t& inst, - const uint16_t operand_index) const; + uint16_t operand_index) const; // Emits a mask expression for the given mask word of the specified type. - void EmitMaskOperand(std::ostream& stream, const spv_operand_type_t type, - const uint32_t word) const; + void EmitMaskOperand(std::ostream& stream, spv_operand_type_t type, + uint32_t word) const; // Generate part of the instruction as a comment to be added to // |id_comments_|. diff --git a/source/opt/folding_rules.cpp b/source/opt/folding_rules.cpp index b1152f473b..5748f97188 100644 --- a/source/opt/folding_rules.cpp +++ b/source/opt/folding_rules.cpp @@ -1790,6 +1790,7 @@ bool CompositeExtractFeedingConstruct( return false; } } + assert(first_element_inst != nullptr); // The last check it to see that the object being extracted from is the // correct type. diff --git a/source/opt/loop_fission.cpp b/source/opt/loop_fission.cpp index 2ae05c3c3f..1bbe4baa34 100644 --- a/source/opt/loop_fission.cpp +++ b/source/opt/loop_fission.cpp @@ -499,6 +499,7 @@ Pass::Status LoopFissionPass::Process() { // next iteration. if (split_multiple_times_) { inner_most_loops = std::move(new_loops_to_split); + new_loops_to_split = {}; } else { break; } diff --git a/source/val/validate_decorations.cpp b/source/val/validate_decorations.cpp index 7f374bbd27..e680bd6eb9 100644 --- a/source/val/validate_decorations.cpp +++ b/source/val/validate_decorations.cpp @@ -169,7 +169,7 @@ uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, case spv::Op::OpTypeSampler: case spv::Op::OpTypeImage: if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) - return baseAlignment = vstate.samplerimage_variable_address_mode() / 8; + return vstate.samplerimage_variable_address_mode() / 8; assert(0); return 0; case spv::Op::OpTypeInt: diff --git a/source/val/validate_function.cpp b/source/val/validate_function.cpp index 67758c66f6..624b4e244b 100644 --- a/source/val/validate_function.cpp +++ b/source/val/validate_function.cpp @@ -283,7 +283,7 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, function_type->GetOperandAs(param_index); const auto parameter_type = _.FindDef(parameter_type_id); if (!parameter_type || argument_type->id() != parameter_type->id()) { - if (!_.options()->before_hlsl_legalization || + if (!parameter_type || !_.options()->before_hlsl_legalization || !DoPointeesLogicallyMatch(argument_type, parameter_type, _)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpFunctionCall Argument " << _.getIdName(argument_id) diff --git a/source/val/validate_non_uniform.cpp b/source/val/validate_non_uniform.cpp index 75967d2ff9..fd422a50ed 100644 --- a/source/val/validate_non_uniform.cpp +++ b/source/val/validate_non_uniform.cpp @@ -390,9 +390,8 @@ spv_result_t ValidateGroupNonUniformRotateKHR(ValidationState_t& _, if (inst->words().size() > 6) { const uint32_t cluster_size_op_id = inst->GetOperandAs(5); const Instruction* cluster_size_inst = _.FindDef(cluster_size_op_id); - const uint32_t cluster_size_type = - cluster_size_inst ? cluster_size_inst->type_id() : 0; - if (!_.IsUnsignedIntScalarType(cluster_size_type)) { + if (!cluster_size_inst || + !_.IsUnsignedIntScalarType(cluster_size_inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "ClusterSize must be a scalar of integer type, whose " "Signedness operand is 0."; diff --git a/test/enum_set_test.cpp b/test/enum_set_test.cpp index 11105f9918..08a4693d6c 100644 --- a/test/enum_set_test.cpp +++ b/test/enum_set_test.cpp @@ -846,9 +846,6 @@ TEST_P(CapabilitySetForEachTest, MoveConstructor) { CapabilitySet copy(GetParam().capabilities); CapabilitySet moved(std::move(copy)); EXPECT_THAT(ElementsIn(moved), Eq(GetParam().expected)); - - // The moved-from set is empty. - EXPECT_THAT(ElementsIn(copy), Eq(std::vector{})); } TEST_P(CapabilitySetForEachTest, OperatorEquals) { @@ -858,7 +855,7 @@ TEST_P(CapabilitySetForEachTest, OperatorEquals) { TEST_P(CapabilitySetForEachTest, OperatorEqualsSelfAssign) { CapabilitySet assigned{GetParam().capabilities}; - assigned = assigned; + assigned = assigned; // NOLINT EXPECT_THAT(ElementsIn(assigned), Eq(GetParam().expected)); } diff --git a/test/opt/ir_context_test.cpp b/test/opt/ir_context_test.cpp index 621fe8cf09..ce02191373 100644 --- a/test/opt/ir_context_test.cpp +++ b/test/opt/ir_context_test.cpp @@ -871,6 +871,7 @@ TEST_F(IRContextTest, AsanErrorTest) { opt::Function* fun = context->cfg()->block(5)->GetParent(); // Computes the CFG analysis opt::DominatorAnalysis* dom = nullptr; + // NOLINTNEXTLINE dom = context->GetDominatorAnalysis(fun); // Computes the dominator analysis, // which depends on the CFG // analysis diff --git a/test/opt/propagator_test.cpp b/test/opt/propagator_test.cpp index 307a2a12b2..0a98cfa8f4 100644 --- a/test/opt/propagator_test.cpp +++ b/test/opt/propagator_test.cpp @@ -184,7 +184,7 @@ TEST_F(PropagatorTest, PropagateThroughPhis) { } } else if (instr->opcode() == spv::Op::OpPhi) { phi_instr = instr; - SSAPropagator::PropStatus retval; + SSAPropagator::PropStatus retval = SSAPropagator::kNotInteresting; for (uint32_t i = 2; i < instr->NumOperands(); i += 2) { uint32_t phi_arg_id = instr->GetSingleWordOperand(i); auto it = values_.find(phi_arg_id); diff --git a/test/opt/trim_capabilities_pass_test.cpp b/test/opt/trim_capabilities_pass_test.cpp index fe5290520c..1569ad73de 100644 --- a/test/opt/trim_capabilities_pass_test.cpp +++ b/test/opt/trim_capabilities_pass_test.cpp @@ -12,6 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include + +#include + #include "spirv-tools/optimizer.hpp" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" From 35e5f1160ecd2b963682e14e869001a60160a0c4 Mon Sep 17 00:00:00 2001 From: Sven van Haastregt Date: Wed, 13 Nov 2024 16:54:31 +0100 Subject: [PATCH 16/26] spirv-val: Accept valid OpSizeOf instructions (#5879) Ensure valid `OpSizeOf` instructions are not rejected by spirv-val. Until now, validation of a valid `OpSizeOf` instruction would fail with the message that the operand "cannot be a type". Signed-off-by: Sven van Haastregt --- source/val/validate_id.cpp | 2 ++ test/val/val_misc_test.cpp | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/source/val/validate_id.cpp b/source/val/validate_id.cpp index 0d1e84123e..00be150cb5 100644 --- a/source/val/validate_id.cpp +++ b/source/val/validate_id.cpp @@ -163,6 +163,7 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { !spvOpcodeGeneratesType(opcode) && !spvOpcodeIsDebug(opcode) && !inst->IsDebugInfo() && !inst->IsNonSemantic() && !spvOpcodeIsDecoration(opcode) && opcode != spv::Op::OpFunction && + opcode != spv::Op::OpSizeOf && opcode != spv::Op::OpCooperativeMatrixLengthNV && opcode != spv::Op::OpCooperativeMatrixLengthKHR && !spvOpcodeGeneratesUntypedPointer(opcode) && @@ -185,6 +186,7 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { opcode != spv::Op::OpSelectionMerge && opcode != spv::Op::OpLoopMerge && opcode != spv::Op::OpFunction && + opcode != spv::Op::OpSizeOf && opcode != spv::Op::OpCooperativeMatrixLengthNV && opcode != spv::Op::OpCooperativeMatrixLengthKHR && !spvOpcodeGeneratesUntypedPointer(opcode) && diff --git a/test/val/val_misc_test.cpp b/test/val/val_misc_test.cpp index 5304c59e00..2188e037c4 100644 --- a/test/val/val_misc_test.cpp +++ b/test/val/val_misc_test.cpp @@ -84,6 +84,27 @@ OpMemoryModel Logical GLSL450 HasSubstr("Cannot create undefined values with 8- or 16-bit types")); } +TEST_F(ValidateMisc, SizeOfValid) { + const std::string spirv = R"( + OpCapability Addresses + OpCapability Kernel + OpMemoryModel Physical64 OpenCL + OpEntryPoint Kernel %f "f" + %void = OpTypeVoid + %i32 = OpTypeInt 32 0 + %ptr = OpTypePointer CrossWorkgroup %i32 + %fnTy = OpTypeFunction %void + %f = OpFunction %void None %fnTy + %entry = OpLabel + %s = OpSizeOf %i32 %ptr + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_1); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); +} + const std::string ShaderClockSpirv = R"( OpCapability Shader OpCapability Int64 From 27433b11e9e9e2738eb34d7dd07694a82fc0b51d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 03:23:45 +0000 Subject: [PATCH 17/26] roll deps (#5883) * Roll external/abseil_cpp/ 27a0c7308..8f739d18b (3 commits) https://github.com/abseil/abseil-cpp/compare/27a0c7308f04...8f739d18b9d6 Created with: roll-dep external/abseil_cpp * Roll external/spirv-headers/ 996c728cf..45b314049 (2 commits) https://github.com/KhronosGroup/SPIRV-Headers/compare/996c728cf7dc...45b314049d62 Created with: roll-dep external/spirv-headers --------- Co-authored-by: GitHub Actions[bot] <> --- DEPS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index ec1700041b..736899b29f 100644 --- a/DEPS +++ b/DEPS @@ -3,7 +3,7 @@ use_relative_paths = True vars = { 'github': 'https://github.com', - 'abseil_revision': '27a0c7308f04e4560fabe5a7beca837e8f3f2c5b', + 'abseil_revision': '8f739d18b9d6cbf96d8143779888de0e984ba96b', 'effcee_revision': '2c97e5689ed8d7ab6ae5820f884f03a601ae124b', @@ -14,7 +14,7 @@ vars = { 're2_revision': '6dcd83d60f7944926bfd308cc13979fc53dd69ca', - 'spirv_headers_revision': '996c728cf7dcfb29845cfa15222822318f047810', + 'spirv_headers_revision': '45b314049d6262c850cc873c8f9a30f41a1e0c13', } deps = { From 16fa89f0607431bd5f7a77446e2e547e0a0609e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 17:02:55 -0500 Subject: [PATCH 18/26] build(deps): bump the github-actions group across 1 directory with 2 updates (#5885) Bumps the github-actions group with 2 updates in the / directory: [lukka/get-cmake](https://github.com/lukka/get-cmake) and [github/codeql-action](https://github.com/github/codeql-action). Updates `lukka/get-cmake` from 3.30.5 to 3.31.0 - [Release notes](https://github.com/lukka/get-cmake/releases) - [Commits](https://github.com/lukka/get-cmake/compare/b516803a3c5fac40e2e922349d15cdebdba01e60...71b7adfe2603f48bb9ed50d2b01a72499ae94885) Updates `github/codeql-action` from 3.27.0 to 3.27.4 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/662472033e021d55d94146f66f6058822b0b39fd...ea9e4e37992a54ee68a9622e985e60c8e8f12d9f) --- updated-dependencies: - dependency-name: lukka/get-cmake dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ios.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 36de27bc2b..b856e7223b 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -15,7 +15,7 @@ jobs: if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: lukka/get-cmake@b516803a3c5fac40e2e922349d15cdebdba01e60 # v3.30.5 + - uses: lukka/get-cmake@71b7adfe2603f48bb9ed50d2b01a72499ae94885 # v3.31.0 - name: Download dependencies run: python3 utils/git-sync-deps # NOTE: The MacOS SDK ships universal binaries. CI should reflect this. diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 039880d49e..e82a650cbe 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -48,6 +48,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: sarif_file: results.sarif From ea1d8cd9814852428d25d3ea113683a6c9686afb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 12:41:36 +0000 Subject: [PATCH 19/26] Roll external/abseil_cpp/ 8f739d18b..917bfee46 (2 commits) (#5887) https://github.com/abseil/abseil-cpp/compare/8f739d18b9d6...917bfee46514 Created with: roll-dep external/abseil_cpp Co-authored-by: GitHub Actions[bot] <> --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 736899b29f..753b379779 100644 --- a/DEPS +++ b/DEPS @@ -3,7 +3,7 @@ use_relative_paths = True vars = { 'github': 'https://github.com', - 'abseil_revision': '8f739d18b9d6cbf96d8143779888de0e984ba96b', + 'abseil_revision': '917bfee46514a1da47df74265571f47700922c0a', 'effcee_revision': '2c97e5689ed8d7ab6ae5820f884f03a601ae124b', From f3c4a5053f1bd34056282e56659659873f9d47ad Mon Sep 17 00:00:00 2001 From: Spencer Fricke <115671160+spencer-lunarg@users.noreply.github.com> Date: Mon, 25 Nov 2024 13:47:25 -0500 Subject: [PATCH 20/26] spirv-val: Add missing NonSemantic.Shader.DebugInfo.100 (#5846) * spirv-val: Cleanup DebugExtension tests * spirv-val: Cleanup DebugExtension tests extensions * spirv-val: Add missing NonSemantic.Shader.DebugInfo.100 * spirv-opt: Fix broken DebugLine in tests --- source/val/function.h | 2 +- source/val/validate_extensions.cpp | 123 +- source/val/validate_layout.cpp | 4 +- test/opt/inline_test.cpp | 6 +- test/opt/loop_optimizations/unroll_simple.cpp | 18 +- test/val/val_ext_inst_debug_test.cpp | 1818 +++++++---------- 6 files changed, 797 insertions(+), 1174 deletions(-) diff --git a/source/val/function.h b/source/val/function.h index 481179442e..c4cd5a4648 100644 --- a/source/val/function.h +++ b/source/val/function.h @@ -278,7 +278,7 @@ class Function { Construct& FindConstructForEntryBlock(const BasicBlock* entry_block, ConstructType t); - /// The result id of the OpLabel that defined this block + /// The result id of OpFunction uint32_t id_; /// The type of the function diff --git a/source/val/validate_extensions.cpp b/source/val/validate_extensions.cpp index 74974a4fef..cb4768dcfa 100644 --- a/source/val/validate_extensions.cpp +++ b/source/val/validate_extensions.cpp @@ -3090,7 +3090,6 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { // validation. case NonSemanticShaderDebugInfo100DebugInfoNone: case NonSemanticShaderDebugInfo100DebugCompilationUnit: - case NonSemanticShaderDebugInfo100DebugTypeBasic: case NonSemanticShaderDebugInfo100DebugTypePointer: case NonSemanticShaderDebugInfo100DebugTypeQualifier: case NonSemanticShaderDebugInfo100DebugTypeArray: @@ -3116,7 +3115,6 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { case NonSemanticShaderDebugInfo100DebugInlinedAt: case NonSemanticShaderDebugInfo100DebugLocalVariable: case NonSemanticShaderDebugInfo100DebugInlinedVariable: - case NonSemanticShaderDebugInfo100DebugDeclare: case NonSemanticShaderDebugInfo100DebugValue: case NonSemanticShaderDebugInfo100DebugOperation: case NonSemanticShaderDebugInfo100DebugExpression: @@ -3125,6 +3123,24 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { case NonSemanticShaderDebugInfo100DebugImportedEntity: case NonSemanticShaderDebugInfo100DebugSource: break; + + // These checks are for operands that are differnet in + // ShaderDebugInfo100 + case NonSemanticShaderDebugInfo100DebugTypeBasic: { + CHECK_CONST_UINT_OPERAND("Flags", 8); + break; + } + case NonSemanticShaderDebugInfo100DebugDeclare: { + for (uint32_t word_index = 8; word_index < num_words; ++word_index) { + auto index_inst = _.FindDef(inst->word(word_index)); + auto type_id = index_inst != nullptr ? index_inst->type_id() : 0; + if (type_id == 0 || !IsIntScalar(_, type_id, false, false)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected index must be scalar integer"; + } + break; + } case NonSemanticShaderDebugInfo100DebugTypeMatrix: { CHECK_DEBUG_OPERAND("Vector Type", CommonDebugInfoDebugTypeVector, 5); @@ -3146,14 +3162,83 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } break; } - // TODO: Add validation rules for remaining cases as well. - case NonSemanticShaderDebugInfo100DebugFunctionDefinition: - case NonSemanticShaderDebugInfo100DebugSourceContinued: - case NonSemanticShaderDebugInfo100DebugLine: + case NonSemanticShaderDebugInfo100DebugFunctionDefinition: { + CHECK_DEBUG_OPERAND("Function", CommonDebugInfoDebugFunction, 5); + CHECK_OPERAND("Definition", spv::Op::OpFunction, 6); + const auto* current_function = inst->function(); + if (current_function->first_block()->id() != inst->block()->id()) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() + << ": must be in the entry basic block of the function"; + } + + const uint32_t definition_id = inst->word(6); + if (definition_id != current_function->id()) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() + << ": operand Definition must point to the OpFunction it is " + "inside"; + } + break; + } + case NonSemanticShaderDebugInfo100DebugLine: { + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 5); + CHECK_CONST_UINT_OPERAND("Line Start", 6); + CHECK_CONST_UINT_OPERAND("Line End", 7); + CHECK_CONST_UINT_OPERAND("Column Start", 8); + CHECK_CONST_UINT_OPERAND("Column End", 9); + + // above already validates if 32-bit and non-spec constant + // but want to use EvalInt32IfConst to be consistent with other Eval + // locations + bool is_int32 = false, is_const_int32 = false; + uint32_t line_start = 0; + uint32_t line_end = 0; + uint32_t column_start = 0; + uint32_t column_end = 0; + std::tie(is_int32, is_const_int32, line_start) = + _.EvalInt32IfConst(inst->word(6)); + std::tie(is_int32, is_const_int32, line_end) = + _.EvalInt32IfConst(inst->word(7)); + std::tie(is_int32, is_const_int32, column_start) = + _.EvalInt32IfConst(inst->word(8)); + std::tie(is_int32, is_const_int32, column_end) = + _.EvalInt32IfConst(inst->word(9)); + if (line_end < line_start) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": operand Line End (" << line_end + << ") is less than Line Start (" << line_start << ")"; + } else if (column_end < column_start) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": operand Column End (" << column_end + << ") is less than Column Start (" << column_start << ")"; + } + break; + } + case NonSemanticShaderDebugInfo100DebugSourceContinued: { + CHECK_OPERAND("Text", spv::Op::OpString, 5); + break; + } + case NonSemanticShaderDebugInfo100DebugBuildIdentifier: { + CHECK_OPERAND("Identifier", spv::Op::OpString, 5); + CHECK_CONST_UINT_OPERAND("Flags", 6); + break; + } + case NonSemanticShaderDebugInfo100DebugStoragePath: { + CHECK_OPERAND("Path", spv::Op::OpString, 5); + break; + } + case NonSemanticShaderDebugInfo100DebugEntryPoint: { + CHECK_DEBUG_OPERAND("Entry Point", CommonDebugInfoDebugFunction, 5); + CHECK_DEBUG_OPERAND("Compilation Unit", + CommonDebugInfoDebugCompilationUnit, 6); + CHECK_OPERAND("Compiler Signature", spv::Op::OpString, 7); + CHECK_OPERAND("Command-line Arguments", spv::Op::OpString, 8); + break; + } + + // Has no additional checks case NonSemanticShaderDebugInfo100DebugNoLine: - case NonSemanticShaderDebugInfo100DebugBuildIdentifier: - case NonSemanticShaderDebugInfo100DebugStoragePath: - case NonSemanticShaderDebugInfo100DebugEntryPoint: break; case NonSemanticShaderDebugInfo100InstructionsMax: assert(0); @@ -3455,9 +3540,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } case CommonDebugInfoDebugFunction: { CHECK_OPERAND("Name", spv::Op::OpString, 5); - auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, - ext_inst_name, false); - if (validate_type != SPV_SUCCESS) return validate_type; + CHECK_DEBUG_OPERAND("Type", CommonDebugInfoDebugTypeFunction, 6); CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); CHECK_CONST_UINT_OPERAND("Line", 8); CHECK_CONST_UINT_OPERAND("Column", 9); @@ -3492,9 +3575,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } case CommonDebugInfoDebugFunctionDeclaration: { CHECK_OPERAND("Name", spv::Op::OpString, 5); - auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, - ext_inst_name, false); - if (validate_type != SPV_SUCCESS) return validate_type; + CHECK_DEBUG_OPERAND("Type", CommonDebugInfoDebugTypeFunction, 6); CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); CHECK_CONST_UINT_OPERAND("Line", 8); CHECK_CONST_UINT_OPERAND("Column", 9); @@ -3556,18 +3637,6 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } CHECK_DEBUG_OPERAND("Expression", CommonDebugInfoDebugExpression, 7); - - if (vulkanDebugInfo) { - for (uint32_t word_index = 8; word_index < num_words; - ++word_index) { - auto index_inst = _.FindDef(inst->word(word_index)); - auto type_id = index_inst != nullptr ? index_inst->type_id() : 0; - if (type_id == 0 || !IsIntScalar(_, type_id, false, false)) - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << ext_inst_name() << ": " - << "expected index must be scalar integer"; - } - } break; } case CommonDebugInfoDebugExpression: { diff --git a/source/val/validate_layout.cpp b/source/val/validate_layout.cpp index 05a8675101..baf36b89bd 100644 --- a/source/val/validate_layout.cpp +++ b/source/val/validate_layout.cpp @@ -75,8 +75,8 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _, if (local_debug_info) { if (_.in_function_body() == false) { - // DebugScope, DebugNoScope, DebugDeclare, DebugValue must - // appear in a function body. + // TODO - Print the actual name of the instruction as this list is + // not complete (see ext_inst_name in ValidateExtInst() for example) return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "DebugScope, DebugNoScope, DebugDeclare, DebugValue " << "of debug info extension must appear in a function " diff --git a/test/opt/inline_test.cpp b/test/opt/inline_test.cpp index bf791811d5..ef7ac37d18 100644 --- a/test/opt/inline_test.cpp +++ b/test/opt/inline_test.cpp @@ -3749,13 +3749,13 @@ float4 main(float4 color : COLOR) : SV_TARGET { %color = OpFunctionParameter %_ptr_Function_v4float %bb_entry = OpLabel %140 = OpExtInst %void %1 DebugFunctionDefinition %22 %src_main - %141 = OpExtInst %void %1 DebugLine %5 %uint_1 %uint_1 %uint_1 %uint_1 + %141 = OpExtInst %void %1 DebugLine %15 %uint_1 %uint_1 %uint_1 %uint_1 %34 = OpExtInst %void %1 DebugScope %22 %36 = OpExtInst %void %1 DebugDeclare %25 %color %13 %38 = OpExtInst %void %1 DebugScope %26 - %142 = OpExtInst %void %1 DebugLine %5 %uint_2 %uint_2 %uint_10 %uint_10 + %142 = OpExtInst %void %1 DebugLine %15 %uint_2 %uint_2 %uint_10 %uint_10 %39 = OpLoad %v4float %color - %143 = OpExtInst %void %1 DebugLine %5 %uint_2 %uint_2 %uint_3 %uint_3 + %143 = OpExtInst %void %1 DebugLine %15 %uint_2 %uint_2 %uint_3 %uint_3 OpReturnValue %39 OpFunctionEnd )"; diff --git a/test/opt/loop_optimizations/unroll_simple.cpp b/test/opt/loop_optimizations/unroll_simple.cpp index 6468adf48b..b4fd3eaa4d 100644 --- a/test/opt/loop_optimizations/unroll_simple.cpp +++ b/test/opt/loop_optimizations/unroll_simple.cpp @@ -510,36 +510,36 @@ OpBranch %24 %24 = OpLabel %35 = OpPhi %8 %10 %23 %34 %26 %s1 = OpExtInst %6 %ext DebugScope %dbg_main -%d10 = OpExtInst %6 %ext DebugLine %file_name %uint_1 %uint_1 %uint_0 %uint_0 +%d10 = OpExtInst %6 %ext DebugLine %src %uint_1 %uint_1 %uint_0 %uint_0 %value0 = OpExtInst %6 %ext DebugValue %dbg_f %35 %null_expr OpLoopMerge %25 %26 Unroll OpBranch %27 %27 = OpLabel %s2 = OpExtInst %6 %ext DebugScope %dbg_main -%d1 = OpExtInst %6 %ext DebugLine %file_name %uint_1 %uint_1 %uint_1 %uint_1 +%d1 = OpExtInst %6 %ext DebugLine %src %uint_1 %uint_1 %uint_1 %uint_1 %29 = OpSLessThan %12 %35 %11 -%d2 = OpExtInst %6 %ext DebugLine %file_name %uint_2 %uint_2 %uint_0 %uint_0 +%d2 = OpExtInst %6 %ext DebugLine %src %uint_2 %uint_2 %uint_0 %uint_0 OpBranchConditional %29 %30 %25 %30 = OpLabel %s3 = OpExtInst %6 %ext DebugScope %bb %decl0 = OpExtInst %6 %ext DebugDeclare %dbg_f %5 %null_expr %decl1 = OpExtInst %6 %ext DebugValue %dbg_i %5 %deref_expr -%d3 = OpExtInst %6 %ext DebugLine %file_name %uint_3 %uint_3 %uint_0 %uint_0 +%d3 = OpExtInst %6 %ext DebugLine %src %uint_3 %uint_3 %uint_0 %uint_0 %32 = OpAccessChain %19 %5 %35 -%d4 = OpExtInst %6 %ext DebugLine %file_name %uint_4 %uint_4 %uint_0 %uint_0 +%d4 = OpExtInst %6 %ext DebugLine %src %uint_4 %uint_4 %uint_0 %uint_0 OpStore %32 %18 -%d5 = OpExtInst %6 %ext DebugLine %file_name %uint_5 %uint_5 %uint_0 %uint_0 +%d5 = OpExtInst %6 %ext DebugLine %src %uint_5 %uint_5 %uint_0 %uint_0 OpBranch %26 %26 = OpLabel %s4 = OpExtInst %6 %ext DebugScope %dbg_main -%d6 = OpExtInst %6 %ext DebugLine %file_name %uint_6 %uint_6 %uint_0 %uint_0 +%d6 = OpExtInst %6 %ext DebugLine %src %uint_6 %uint_6 %uint_0 %uint_0 %34 = OpIAdd %8 %35 %20 %value1 = OpExtInst %6 %ext DebugValue %dbg_f %34 %null_expr -%d7 = OpExtInst %6 %ext DebugLine %file_name %uint_7 %uint_7 %uint_0 %uint_0 +%d7 = OpExtInst %6 %ext DebugLine %src %uint_7 %uint_7 %uint_0 %uint_0 OpBranch %24 %25 = OpLabel %s5 = OpExtInst %6 %ext DebugScope %dbg_main -%d8 = OpExtInst %6 %ext DebugLine %file_name %uint_8 %uint_8 %uint_0 %uint_0 +%d8 = OpExtInst %6 %ext DebugLine %src %uint_8 %uint_8 %uint_0 %uint_0 OpReturn OpFunctionEnd)"; diff --git a/test/val/val_ext_inst_debug_test.cpp b/test/val/val_ext_inst_debug_test.cpp index 8f0da42d55..bd4ab3c75b 100644 --- a/test/val/val_ext_inst_debug_test.cpp +++ b/test/val/val_ext_inst_debug_test.cpp @@ -21,6 +21,7 @@ #include #include "gmock/gmock.h" +#include "spirv-tools/libspirv.h" #include "test/unit_spirv.h" #include "test/val/val_fixtures.h" @@ -84,6 +85,15 @@ using ValidateVulkan100DebugInfoDebugValue = spvtest::ValidateBase>; using ValidateVulkan100DebugInfo = spvtest::ValidateBase; +const static std::string shader_extension = R"( +OpExtension "SPV_KHR_non_semantic_info" +%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" +)"; + +const static std::string opencl_extension = R"( +%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" +)"; + std::string GenerateShaderCodeForDebugInfo( const std::string& op_string_instructions, const std::string& op_const_instructions, @@ -118,6 +128,7 @@ OpCapability Int64 ss << "OpExecutionMode %main OriginUpperLeft\n"; } + ss << "%main_name = OpString \"main\"\n"; ss << op_string_instructions; ss << R"( @@ -181,6 +192,9 @@ OpCapability Int64 %u32_1 = OpConstant %u32 1 %u32_2 = OpConstant %u32 2 %u32_3 = OpConstant %u32 3 +%u32_4 = OpConstant %u32 4 +%u32_5 = OpConstant %u32 5 +%u32_32 = OpConstant %u32 32 %s32_0 = OpConstant %s32 0 %s32_1 = OpConstant %s32 1 @@ -308,12 +322,8 @@ TEST_F(ValidateOpenCL100DebugInfo, UseDebugInstructionOutOfFunction) { %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code )"; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "", - extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -327,12 +337,8 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugSourceInFunction) { %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code )"; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", "", dbg_inst, - extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", "", dbg_inst, opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -352,13 +358,8 @@ TEST_F(ValidateVulkan100DebugInfo, DebugSourceInFunction) { %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code )"; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", "", dbg_inst, - extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", "", dbg_inst, shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -373,8 +374,6 @@ TEST_P(ValidateLocalDebugInfoOutOfFunction, OpenCLDebugInfo100DebugScope) { %src = OpString "simple.hlsl" %code = OpString "void main() {}" %void_name = OpString "void" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" %int_name = OpString "int" %foo_name = OpString "foo" )"; @@ -384,7 +383,7 @@ TEST_P(ValidateLocalDebugInfoOutOfFunction, OpenCLDebugInfo100DebugScope) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %int_info = OpExtInst %void %DbgExt DebugTypeBasic %int_name %u32_0 Signed %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %int_info %dbg_src 1 1 %main_info FlagIsLocal %expr = OpExtInst %void %DbgExt DebugExpression )"; @@ -392,14 +391,10 @@ TEST_P(ValidateLocalDebugInfoOutOfFunction, OpenCLDebugInfo100DebugScope) { const std::string body = R"( %foo = OpVariable %u32_ptr_function Function %foo_val = OpLoad %u32 %foo -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, "", dbg_inst_header + GetParam(), body, extension, "Vertex")); + src, "", dbg_inst_header + GetParam(), body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("DebugScope, DebugNoScope, DebugDeclare, DebugValue " @@ -412,8 +407,6 @@ TEST_P(ValidateLocalDebugInfoOutOfFunction, VulkanDebugInfo100DebugScope) { %src = OpString "simple.hlsl" %code = OpString "void main() {}" %void_name = OpString "void" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" %int_name = OpString "int" %foo_name = OpString "foo" )"; @@ -423,7 +416,7 @@ TEST_P(ValidateLocalDebugInfoOutOfFunction, VulkanDebugInfo100DebugScope) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %int_info = OpExtInst %void %DbgExt DebugTypeBasic %int_name %u32_0 %u32_1 %u32_0 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_linkage_name %u32_3 %u32_1 +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %int_info %dbg_src %u32_1 %u32_1 %main_info %u32_4 %expr = OpExtInst %void %DbgExt DebugExpression )"; @@ -432,20 +425,10 @@ TEST_P(ValidateLocalDebugInfoOutOfFunction, VulkanDebugInfo100DebugScope) { %foo = OpVariable %u32_ptr_function Function %main_def = OpExtInst %void %DbgExt DebugFunctionDefinition %main_info %main %foo_val = OpLoad %u32 %foo -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header + GetParam(), body, extension, "Vertex")); + src, "", dbg_inst_header + GetParam(), body, shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("DebugScope, DebugNoScope, DebugDeclare, DebugValue " @@ -465,27 +448,21 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionForwardReference) { %src = OpString "simple.hlsl" %code = OpString "void main() {}" %void_name = OpString "void" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" )"; const std::string dbg_inst_header = R"( %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main )"; const std::string body = R"( %main_scope = OpExtInst %void %DbgExt DebugScope %main_info -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, "", dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -494,8 +471,6 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionMissingOpFunction) { %src = OpString "simple.hlsl" %code = OpString "void main() {}" %void_name = OpString "void" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" )"; const std::string dbg_inst_header = R"( @@ -503,19 +478,15 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionMissingOpFunction) { %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %dbgNone +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %dbgNone )"; const std::string body = R"( %main_scope = OpExtInst %void %DbgExt DebugScope %main_info -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, "", dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -528,8 +499,6 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugScopeBeforeOpVariableInFunction) { } " %float_name = OpString "float" -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const std::string size_const = R"( @@ -542,20 +511,16 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugScopeBeforeOpVariableInFunction) { %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_name FlagIsPublic 13 %main )"; const std::string body = R"( %main_scope = OpExtInst %void %DbgExt DebugScope %main_info %foo = OpVariable %f32_ptr_function Function -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, body, extension, "Vertex")); + src, size_const, dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -575,12 +540,8 @@ main() {} %opaque = OpExtInst %void %DbgExt DebugTypeComposite %ty_name Class %dbg_src 1 1 %comp_unit %ty_name %dbg_none FlagIsPublic )"; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header, - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -613,14 +574,10 @@ main() {} %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic %VS_OUTPUT_color_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_color_name %v4float_info %dbg_src 3 3 %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -652,14 +609,10 @@ main() {} %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("forward referenced IDs have not been defined")); @@ -753,12 +706,8 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugCompilationUnit) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL )"; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "", - extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -773,12 +722,8 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugCompilationUnitFail) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %src HLSL )"; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "", - extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Source must be a result id of " @@ -796,18 +741,8 @@ TEST_F(ValidateVulkan100DebugInfo, DebugCompilationUnitFail) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %src %u32_5 )"; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, constants, dbg_inst, - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Source must be a result id of " @@ -833,14 +768,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeBasicFailName) { %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %int_32 %int_32 Float -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Name must be a result id of " @@ -856,27 +787,16 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeBasicFailName) { } " %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %u32_32 %u32_32 %u32_3 %u32_0 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Name must be a result id of " @@ -902,14 +822,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeBasicFailSize) { %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %float_name Float -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Size must be a result id of " @@ -925,33 +841,47 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeBasicFailSize) { } " %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %float_name %u32_3 %u32_0 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Size must be a result id of " "OpConstant")); } +TEST_F(ValidateVulkan100DebugInfo, DebugTypeBasicFailFlags) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() {}" +%float_name = OpString "float" +)"; + + const std::string constants = R"( +%f32_32 = OpConstant %f32 32 +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 +%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_3 %u32_3 %f32_32 +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("expected operand Flags must be a result id of 32-bit " + "unsigned OpConstant")); +} + TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointer) { const std::string src = R"( %src = OpString "simple.hlsl" @@ -972,14 +902,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointer) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %pfloat_info = OpExtInst %void %DbgExt DebugTypePointer %float_info Function FlagIsLocal -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1003,14 +929,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointerFail) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %pfloat_info = OpExtInst %void %DbgExt DebugTypePointer %dbg_src Function FlagIsLocal -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -1037,14 +959,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifier) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %cfloat_info = OpExtInst %void %DbgExt DebugTypeQualifier %float_info ConstType -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1068,14 +986,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifierFail) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %cfloat_info = OpExtInst %void %DbgExt DebugTypeQualifier %comp_unit ConstType -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -1090,12 +1004,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeQualifier) { } " %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1103,15 +1011,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeQualifier) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %cfloat_info = OpExtInst %void %DbgExt DebugTypeQualifier %float_info %u32_0 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1124,12 +1027,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeQualifierFail) { } " %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1137,15 +1034,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeQualifierFail) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %cfloat_info = OpExtInst %void %DbgExt DebugTypeQualifier %comp_unit %u32_0 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -1168,14 +1060,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArray) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %int_32 -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1185,7 +1073,6 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayWithVariableSize) { %code = OpString "main() {}" %float_name = OpString "float" %int_name = OpString "int" -%main_name = OpString "main" %foo_name = OpString "foo" )"; @@ -1202,14 +1089,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayWithVariableSize) { %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %uint_info %dbg_src 1 1 %main_info FlagIsLocal %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %foo_info -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1229,14 +1112,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailBaseType) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %comp_unit %int_32 -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Base Type is not a valid debug " @@ -1259,14 +1138,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCount) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %float_info -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Component Count must be OpConstant with a 32- or " @@ -1291,14 +1166,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCountFloat) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %f32_4 -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Component Count must be OpConstant with a 32- or " @@ -1323,14 +1194,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCountZero) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %u32_0 -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Component Count must be OpConstant with a 32- or " @@ -1344,7 +1211,6 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailVariableSizeTypeFloat) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -%main_name = OpString "main" %foo_name = OpString "foo" )"; @@ -1360,14 +1226,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailVariableSizeTypeFloat) { %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 1 %main_info FlagIsLocal %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %foo_info -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Component Count must be OpConstant with a 32- or " @@ -1381,12 +1243,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArray) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1394,15 +1250,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArray) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %u32_32 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1412,15 +1263,11 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayWithVariableSize) { %code = OpString "main() {}" %float_name = OpString "float" %uint_name = OpString "uint" -%main_name = OpString "main" %foo_name = OpString "foo" )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_6 = OpConstant %u32 6 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1432,15 +1279,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayWithVariableSize) { %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %uint_info %dbg_src %u32_1 %u32_1 %main_info %u32_4 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %foo_info -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1449,12 +1291,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayFailBaseType) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1462,15 +1298,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayFailBaseType) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %comp_unit %u32_32 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Base Type is not a valid debug " @@ -1482,12 +1313,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayFailComponentCount) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1495,15 +1320,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayFailComponentCount) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %float_info -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Component Count must be OpConstant with a 32- or " @@ -1517,12 +1337,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayFailComponentCountFloat) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1530,15 +1344,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayFailComponentCountFloat) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %f32_4 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Component Count must be OpConstant with a 32- or " @@ -1552,12 +1361,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayComponentCountZero) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1565,15 +1368,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayComponentCountZero) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %u32_0 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1582,15 +1380,11 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayFailVariableSizeTypeFloat) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -%main_name = OpString "main" %foo_name = OpString "foo" )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_6 = OpConstant %u32 6 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1601,15 +1395,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeArrayFailVariableSizeTypeFloat) { %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src %u32_1 %u32_1 %main_info %u32_4 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %foo_info -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Component Count must be OpConstant with a 32- or " @@ -1634,14 +1423,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVector) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4 -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1661,14 +1446,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFail) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 4 -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Base Type must be a result id of " @@ -1691,14 +1472,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFailComponentZero) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 0 -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Base Type must be a result id of " @@ -1721,14 +1498,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFailComponentFive) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 5 -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Base Type must be a result id of " @@ -1740,12 +1513,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeVector) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1753,15 +1520,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeVector) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1770,12 +1532,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeVectorFail) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1783,15 +1539,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeVectorFail) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src %u32_4 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Base Type must be a result id of " @@ -1803,12 +1554,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeVectorFailComponentZero) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1816,15 +1561,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeVectorFailComponentZero) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_0 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Component Count must be positive " @@ -1836,12 +1576,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeVectorFailComponentFive) { %src = OpString "simple.hlsl" %code = OpString "main() {}" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -1849,15 +1583,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeVectorFailComponentFive) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_5 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Component Count must be positive " @@ -1872,9 +1601,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrix) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 %true = OpConstantTrue %bool )"; @@ -1884,15 +1610,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrix) { %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4 %mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %u32_4 %true -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1904,9 +1625,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorTypeType) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 %true = OpConstantTrue %bool )"; @@ -1916,15 +1634,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorTypeType) { %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4 %mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %dbg_src %u32_4 %true -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Vector Type must be a result id of " @@ -1939,9 +1652,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountType) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 %true = OpConstantTrue %bool )"; @@ -1951,15 +1661,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountType) { %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4 %mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %dbg_src %true -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Vector Count must be a result id of " @@ -1974,9 +1679,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountZero) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 %true = OpConstantTrue %bool )"; @@ -1986,15 +1688,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountZero) { %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4 %mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %u32_0 %true -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Vector Count must be positive " @@ -2009,9 +1706,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountFive) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 %true = OpConstantTrue %bool )"; @@ -2021,15 +1715,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountFive) { %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4 %mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %u32_5 %true -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Vector Count must be positive " @@ -2053,14 +1742,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypedef) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %foo_info = OpExtInst %void %DbgExt DebugTypedef %foo_name %float_info %dbg_src 1 1 %comp_unit -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -2086,12 +1771,8 @@ TEST_P(ValidateOpenCL100DebugInfoDebugTypedef, Fail) { %foo_info = OpExtInst %void %DbgExt DebugTypedef )"; ss << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, size_const, ss.str(), "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second + @@ -2117,12 +1798,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypedef) { %code = OpString "main() {}" %float_name = OpString "float" %foo_name = OpString "foo" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -2130,15 +1805,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypedef) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %foo_info = OpExtInst %void %DbgExt DebugTypedef %foo_name %float_info %dbg_src %u32_1 %u32_1 %comp_unit -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -2148,12 +1818,6 @@ TEST_P(ValidateVulkan100DebugInfoDebugTypedef, Fail) { %code = OpString "main() {}" %float_name = OpString "float" %foo_name = OpString "foo" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const auto& param = GetParam(); @@ -2166,13 +1830,8 @@ TEST_P(ValidateVulkan100DebugInfoDebugTypedef, Fail) { %foo_info = OpExtInst %void %DbgExt DebugTypedef )"; ss << param.first; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, constants, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", ss.str(), "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second + @@ -2200,8 +1859,6 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunction) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "main() {}" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" %float_name = OpString "float" )"; @@ -2217,14 +1874,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunction) { %main_type_info2 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info %main_type_info3 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info %float_info %main_type_info4 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void %float_info %float_info -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -2232,8 +1885,6 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunctionFailReturn) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "main() {}" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" %float_name = OpString "float" )"; @@ -2246,14 +1897,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunctionFailReturn) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %dbg_src %float_info -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -2264,8 +1911,6 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunctionFailParam) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "main() {}" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" %float_name = OpString "float" )"; @@ -2278,14 +1923,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunctionFailParam) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info %void -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -2296,15 +1937,7 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeFunctionAndParams) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "main() {}" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -2315,15 +1948,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeFunctionAndParams) { %main_type_info2 = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %float_info %main_type_info3 = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %float_info %float_info %main_type_info4 = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void %float_info %float_info -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -2331,15 +1959,7 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeFunctionFailReturn) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "main() {}" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -2347,15 +1967,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeFunctionFailReturn) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %dbg_src %float_info -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -2366,15 +1981,7 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeFunctionFailParam) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "main() {}" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" %float_name = OpString "float" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -2382,15 +1989,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeFunctionFailParam) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %float_info %void -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -2417,14 +2019,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeEnum) { %foo_info1 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name %u32_1 %foo_name %foo_info2 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %none %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name %u32_1 %foo_name %foo_info3 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %none %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -2450,12 +2048,8 @@ TEST_P(ValidateOpenCL100DebugInfoDebugTypeEnum, Fail) { %foo_info = OpExtInst %void %DbgExt DebugTypeEnum )"; ss << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, size_const, ss.str(), "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -2496,12 +2090,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeEnum) { %code = OpString "main() {}" %float_name = OpString "float" %foo_name = OpString "foo" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -2512,15 +2100,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugTypeEnum) { %foo_info1 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %float_info %dbg_src %u32_1 %u32_1 %comp_unit %u32_32 %u32_3 %u32_0 %foo_name %u32_1 %foo_name %foo_info2 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %none %dbg_src %u32_1 %u32_1 %comp_unit %u32_32 %u32_3 %u32_0 %foo_name %u32_1 %foo_name %foo_info3 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %none %dbg_src %u32_1 %u32_1 %comp_unit %u32_32 %u32_3 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -2530,12 +2113,6 @@ TEST_P(ValidateVulkan100DebugInfoDebugTypeEnum, Fail) { %code = OpString "main() {}" %float_name = OpString "float" %foo_name = OpString "foo" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const auto& param = GetParam(); @@ -2548,13 +2125,8 @@ TEST_P(ValidateVulkan100DebugInfoDebugTypeEnum, Fail) { %foo_info = OpExtInst %void %DbgExt DebugTypeEnum )"; ss << param.first; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, constants, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", ss.str(), "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -2604,8 +2176,6 @@ main() {} %foo_name = OpString "foo" %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION" %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT" -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const std::string size_const = R"( @@ -2621,17 +2191,13 @@ main() {} %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_name FlagIsPublic 13 %main %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic %child = OpExtInst %void %DbgExt DebugTypeInheritance %foo_info %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -2650,8 +2216,6 @@ main() {} %foo_name = OpString "foo" %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION" %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT" -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const std::string size_const = R"( @@ -2672,17 +2236,13 @@ main() {} %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_name FlagIsPublic 13 %main %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic %child = OpExtInst %void %DbgExt DebugTypeInheritance %foo_info %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic )"; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, size_const, ss.str(), "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second + " must be ")); @@ -2746,12 +2306,8 @@ main() {} %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember )"; ss << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, size_const, ss.str(), "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); if (!param.second.empty()) { EXPECT_THAT(getDiagnosticString(), @@ -2805,12 +2361,8 @@ struct foo : VS_OUTPUT {}; %child = OpExtInst %void %DbgExt DebugTypeInheritance )" << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "", - extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", ss.str(), "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -2849,14 +2401,9 @@ main() {} %foo_name = OpString "foo" %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION" %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT" -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 %u32_128 = OpConstant %u32 128 )"; @@ -2868,15 +2415,10 @@ main() {} %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src %u32_2 %u32_3 %u32_0 %u32_128 %u32_3 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name %u32_1 %dbg_src %u32_1 %u32_1 %comp_unit %VS_OUTPUT_linkage_name %u32_128 %u32_3 %VS_OUTPUT_pos_info %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name %u32_1 %dbg_src %u32_1 %u32_1 %comp_unit %foo_name %u32_0 %u32_3 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -2895,14 +2437,9 @@ main() {} %foo_name = OpString "foo" %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION" %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT" -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 %u32_128 = OpConstant %u32 128 )"; @@ -2918,13 +2455,8 @@ main() {} %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite )"; ss << param.first; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, constants, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, constants, ss.str(), "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second + " must be ")); @@ -2971,9 +2503,6 @@ main() {} )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 %u32_128 = OpConstant %u32 128 )"; @@ -2987,13 +2516,8 @@ main() {} %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember )"; ss << param.first; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, constants, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, constants, ss.str(), "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); if (!param.second.empty()) { EXPECT_THAT(getDiagnosticString(), @@ -3033,23 +2557,17 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionDeclaration) { }; main() {} " -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const std::string dbg_inst_header = R"( %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void -%main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; +%main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_name FlagIsPublic +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_name FlagIsPublic 13 %main)"; - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header, - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -3061,8 +2579,6 @@ TEST_P(ValidateOpenCL100DebugInfoDebugFunction, Fail) { }; main() {} " -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const auto& param = GetParam(); @@ -3072,16 +2588,12 @@ main() {} %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void -%main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic +%main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_name FlagIsPublic %main_info = OpExtInst %void %DbgExt DebugFunction )" << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "", - extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", ss.str(), "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -3091,25 +2603,25 @@ INSTANTIATE_TEST_SUITE_P( AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugFunction, ::testing::ValuesIn(std::vector>{ std::make_pair( - R"(%u32_0 %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)", + R"(%u32_0 %main_type_info %dbg_src 12 1 %comp_unit %main_name FlagIsPublic 13 %main)", "Name"), std::make_pair( - R"(%main_name %dbg_src %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)", + R"(%main_name %dbg_src %dbg_src 12 1 %comp_unit %main_name FlagIsPublic 13 %main)", "Type"), std::make_pair( - R"(%main_name %main_type_info %comp_unit 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)", + R"(%main_name %main_type_info %comp_unit 12 1 %comp_unit %main_name FlagIsPublic 13 %main)", "Source"), std::make_pair( - R"(%main_name %main_type_info %dbg_src 12 1 %dbg_src %main_linkage_name FlagIsPublic 13 %main)", + R"(%main_name %main_type_info %dbg_src 12 1 %dbg_src %main_name FlagIsPublic 13 %main)", "Parent"), std::make_pair( R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %void FlagIsPublic 13 %main)", "Linkage Name"), std::make_pair( - R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %void)", + R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %main_name FlagIsPublic 13 %void)", "Function"), std::make_pair( - R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main %dbg_src)", + R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %main_name FlagIsPublic 13 %main %dbg_src)", "Declaration"), })); @@ -3121,8 +2633,6 @@ TEST_P(ValidateOpenCL100DebugInfoDebugFunctionDeclaration, Fail) { }; main() {} " -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const auto& param = GetParam(); @@ -3135,12 +2645,8 @@ main() {} %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration )" << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "", - extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", ss.str(), "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -3151,16 +2657,16 @@ INSTANTIATE_TEST_SUITE_P( ValidateOpenCL100DebugInfoDebugFunctionDeclaration, ::testing::ValuesIn(std::vector>{ std::make_pair( - R"(%u32_0 %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic)", + R"(%u32_0 %main_type_info %dbg_src 12 1 %comp_unit %main_name FlagIsPublic)", "Name"), std::make_pair( - R"(%main_name %dbg_src %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic)", + R"(%main_name %dbg_src %dbg_src 12 1 %comp_unit %main_name FlagIsPublic)", "Type"), std::make_pair( - R"(%main_name %main_type_info %comp_unit 12 1 %comp_unit %main_linkage_name FlagIsPublic)", + R"(%main_name %main_type_info %comp_unit 12 1 %comp_unit %main_name FlagIsPublic)", "Source"), std::make_pair( - R"(%main_name %main_type_info %dbg_src 12 1 %dbg_src %main_linkage_name FlagIsPublic)", + R"(%main_name %main_type_info %dbg_src 12 1 %dbg_src %main_name FlagIsPublic)", "Parent"), std::make_pair( R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %void FlagIsPublic)", @@ -3175,13 +2681,9 @@ TEST_F(ValidateVulkan100DebugInfo, DebugFunctionDeclaration) { }; main() {} " -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_12 = OpConstant %u32 12 %u32_13 = OpConstant %u32 13 )"; @@ -3190,17 +2692,12 @@ main() {} %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void -%main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_linkage_name %u32_3 -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_linkage_name %u32_3 %u32_13 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" +%main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_name %u32_3 +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_name %u32_3 %u32_13 )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -3212,13 +2709,9 @@ TEST_P(ValidateVulkan100DebugInfoDebugFunction, Fail) { }; main() {} " -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_12 = OpConstant %u32 12 %u32_13 = OpConstant %u32 13 )"; @@ -3230,17 +2723,12 @@ main() {} %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void -%main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_linkage_name %u32_3 +%main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_name %u32_3 %main_info = OpExtInst %void %DbgExt DebugFunction )" << param.first; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, constants, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, constants, ss.str(), "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -3250,22 +2738,22 @@ INSTANTIATE_TEST_SUITE_P( AllVulkan100DebugInfoFail, ValidateVulkan100DebugInfoDebugFunction, ::testing::ValuesIn(std::vector>{ std::make_pair( - R"(%u32_0 %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_linkage_name %u32_3 %u32_13)", + R"(%u32_0 %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_name %u32_3 %u32_13)", "Name"), std::make_pair( - R"(%main_name %dbg_src %dbg_src %u32_12 %u32_1 %comp_unit %main_linkage_name %u32_3 %u32_13)", + R"(%main_name %dbg_src %dbg_src %u32_12 %u32_1 %comp_unit %main_name %u32_3 %u32_13)", "Type"), std::make_pair( - R"(%main_name %main_type_info %comp_unit %u32_12 %u32_1 %comp_unit %main_linkage_name %u32_3 %u32_13)", + R"(%main_name %main_type_info %comp_unit %u32_12 %u32_1 %comp_unit %main_name %u32_3 %u32_13)", "Source"), std::make_pair( - R"(%main_name %main_type_info %dbg_src %u32_12 %u32_1 %dbg_src %main_linkage_name %u32_3 %u32_13)", + R"(%main_name %main_type_info %dbg_src %u32_12 %u32_1 %dbg_src %main_name %u32_3 %u32_13)", "Parent"), std::make_pair( R"(%main_name %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %void %u32_3 %u32_13)", "Linkage Name"), std::make_pair( - R"(%main_name %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_linkage_name %u32_3 %u32_13 %dbg_src)", + R"(%main_name %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_name %u32_3 %u32_13 %dbg_src)", "Declaration"), })); @@ -3277,13 +2765,9 @@ TEST_P(ValidateVulkan100DebugInfoDebugFunctionDeclaration, Fail) { }; main() {} " -%main_name = OpString "main" -%main_linkage_name = OpString "v4f_main_f" )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_12 = OpConstant %u32 12 %u32_13 = OpConstant %u32 13 )"; @@ -3298,13 +2782,8 @@ main() {} %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration )" << param.first; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, constants, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, constants, ss.str(), "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -3315,27 +2794,54 @@ INSTANTIATE_TEST_SUITE_P( ValidateVulkan100DebugInfoDebugFunctionDeclaration, ::testing::ValuesIn(std::vector>{ std::make_pair( - R"(%u32_0 %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_linkage_name %u32_3)", + R"(%u32_0 %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %main_name %u32_3)", "Name"), std::make_pair( - R"(%main_name %dbg_src %dbg_src %u32_12 %u32_1 %comp_unit %main_linkage_name %u32_3)", + R"(%main_name %dbg_src %dbg_src %u32_12 %u32_1 %comp_unit %main_name %u32_3)", "Type"), std::make_pair( - R"(%main_name %main_type_info %comp_unit %u32_12 %u32_1 %comp_unit %main_linkage_name %u32_3)", + R"(%main_name %main_type_info %comp_unit %u32_12 %u32_1 %comp_unit %main_name %u32_3)", "Source"), std::make_pair( - R"(%main_name %main_type_info %dbg_src %u32_12 %u32_1 %dbg_src %main_linkage_name %u32_3)", + R"(%main_name %main_type_info %dbg_src %u32_12 %u32_1 %dbg_src %main_name %u32_3)", "Parent"), std::make_pair( R"(%main_name %main_type_info %dbg_src %u32_12 %u32_1 %comp_unit %void %u32_3)", "Linkage Name"), })); +TEST_F(ValidateVulkan100DebugInfo, DebugFunctionType) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "main() {}" +%float_name = OpString "float" +%uint_name = OpString "uint" +)"; + + const std::string constants = R"( +%u32_6 = OpConstant %u32 6 +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 +%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 +%uint_info = OpExtInst %void %DbgExt DebugTypeBasic %uint_name %u32_32 %u32_6 %u32_0 +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %uint_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugFunction: expected operand Type must be a result " + "id of DebugTypeFunction")); +} + TEST_F(ValidateOpenCL100DebugInfo, DebugLexicalBlock) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "main() {}" -%main_name = OpString "main" )"; const std::string dbg_inst_header = R"( @@ -3343,12 +2849,8 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugLexicalBlock) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %main_block = OpExtInst %void %DbgExt DebugLexicalBlock %dbg_src 1 1 %comp_unit %main_name)"; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header, - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -3356,7 +2858,6 @@ TEST_P(ValidateOpenCL100DebugInfoDebugLexicalBlock, Fail) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "main() {}" -%main_name = OpString "main" )"; const auto& param = GetParam(); @@ -3368,12 +2869,8 @@ TEST_P(ValidateOpenCL100DebugInfoDebugLexicalBlock, Fail) { %main_block = OpExtInst %void %DbgExt DebugLexicalBlock )" << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "", - extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", ss.str(), "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -3400,14 +2897,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugScopeFailScope) { const std::string body = R"( %main_scope = OpExtInst %void %DbgExt DebugScope %dbg_src -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, "", dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Scope")); } @@ -3425,14 +2918,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugScopeFailInlinedAt) { const std::string body = R"( %main_scope = OpExtInst %void %DbgExt DebugScope %comp_unit %dbg_src -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, "", dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Inlined At")); } @@ -3441,27 +2930,16 @@ TEST_F(ValidateVulkan100DebugInfo, DebugLexicalBlock) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "main() {}" -%main_name = OpString "main" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 )"; const std::string dbg_inst_header = R"( %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %main_block = OpExtInst %void %DbgExt DebugLexicalBlock %dbg_src %u32_1 %u32_1 %comp_unit %main_name -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -3469,12 +2947,6 @@ TEST_P(ValidateVulkan100DebugInfoDebugLexicalBlock, Fail) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "main() {}" -%main_name = OpString "main" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 )"; const auto& param = GetParam(); @@ -3486,13 +2958,8 @@ TEST_P(ValidateVulkan100DebugInfoDebugLexicalBlock, Fail) { %main_block = OpExtInst %void %DbgExt DebugLexicalBlock )" << param.first; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, constants, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", ss.str(), "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -3512,11 +2979,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugScopeFailScope) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "void main() {}" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 )"; const std::string dbg_inst_header = R"( @@ -3526,15 +2988,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugScopeFailScope) { const std::string body = R"( %main_scope = OpExtInst %void %DbgExt DebugScope %dbg_src -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Scope")); } @@ -3543,11 +3000,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugScopeFailInlinedAt) { const std::string src = R"( %src = OpString "simple.hlsl" %code = OpString "void main() {}" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 )"; const std::string dbg_inst_header = R"( @@ -3557,15 +3009,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugScopeFailInlinedAt) { const std::string body = R"( %main_scope = OpExtInst %void %DbgExt DebugScope %comp_unit %dbg_src -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Inlined At")); } @@ -3587,14 +3034,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugLocalVariable) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %foo = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0 -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -3620,12 +3063,8 @@ TEST_P(ValidateOpenCL100DebugInfoDebugLocalVariable, Fail) { %foo = OpExtInst %void %DbgExt DebugLocalVariable )" << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, size_const, ss.str(), "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -3657,10 +3096,7 @@ TEST_F(ValidateVulkan100DebugInfo, DebugLocalVariable) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_10 = OpConstant %u32 10 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -3668,15 +3104,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugLocalVariable) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %foo = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src %u32_1 %u32_10 %comp_unit %u32_4 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, constants, dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -3689,10 +3120,7 @@ TEST_P(ValidateVulkan100DebugInfoDebugLocalVariable, Fail) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_10 = OpConstant %u32 10 -%u32_32 = OpConstant %u32 32 )"; const auto& param = GetParam(); @@ -3705,13 +3133,8 @@ TEST_P(ValidateVulkan100DebugInfoDebugLocalVariable, Fail) { %foo = OpExtInst %void %DbgExt DebugLocalVariable )" << param.first; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, constants, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, constants, ss.str(), "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -3757,14 +3180,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugDeclare) { const std::string body = R"( %foo = OpVariable %f32_ptr_function Function %decl = OpExtInst %void %DbgExt DebugDeclare %foo_info %foo %null_expr -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, body, extension, "Vertex")); + src, size_const, dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -3859,12 +3278,8 @@ TEST_P(ValidateOpenCL100DebugInfoDebugDeclare, Fail) { %decl = OpExtInst %void %DbgExt DebugDeclare )" << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, ss.str(), extension, "Vertex")); + src, size_const, dbg_inst_header, ss.str(), opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -3887,10 +3302,7 @@ TEST_F(ValidateVulkan100DebugInfo, DebugDeclare) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_10 = OpConstant %u32 10 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -3899,11 +3311,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugDeclare) { %null_expr = OpExtInst %void %DbgExt DebugExpression %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src %u32_1 %u32_10 %comp_unit %u32_4 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; const std::string body = R"( @@ -3912,7 +3319,7 @@ OpExtension "SPV_KHR_non_semantic_info" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, body, extension, "Vertex")); + src, constants, dbg_inst_header, body, shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -3994,10 +3401,7 @@ TEST_P(ValidateVulkan100DebugInfoDebugDeclare, Fail) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_10 = OpConstant %u32 10 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4006,11 +3410,6 @@ TEST_P(ValidateVulkan100DebugInfoDebugDeclare, Fail) { %null_expr = OpExtInst %void %DbgExt DebugExpression %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src %u32_1 %u32_10 %comp_unit %u32_4 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; const auto& param = GetParam(); @@ -4022,7 +3421,7 @@ OpExtension "SPV_KHR_non_semantic_info" << param.first; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, ss.str(), extension, "Vertex")); + src, constants, dbg_inst_header, ss.str(), shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -4043,12 +3442,8 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugExpression) { %null_expr = OpExtInst %void %DbgExt DebugExpression %op0 %op1 )"; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo("", "", dbg_inst_header, - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + "", "", dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4058,12 +3453,8 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugExpressionFail) { %null_expr = OpExtInst %void %DbgExt DebugExpression %op %void )"; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo("", "", dbg_inst_header, - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + "", "", dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -4078,13 +3469,8 @@ TEST_F(ValidateVulkan100DebugInfo, DebugExpression) { %null_expr = OpExtInst %void %DbgExt DebugExpression %op0 %op1 )"; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo("", "", dbg_inst_header, - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + "", "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4094,13 +3480,8 @@ TEST_F(ValidateVulkan100DebugInfo, DebugExpressionFail) { %null_expr = OpExtInst %void %DbgExt DebugExpression %op %void )"; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo("", "", dbg_inst_header, - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + "", "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -4132,14 +3513,10 @@ main() {} %opaque = OpExtInst %void %DbgExt DebugTypeComposite %ty_name Class %dbg_src 1 1 %comp_unit %ty_name %dbg_none FlagIsPublic %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %opaque %param -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4169,14 +3546,10 @@ main() {} %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %opaque %param %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %temp %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4189,7 +3562,6 @@ main() {} %float_name = OpString "float" %ty_name = OpString "Texture" %t_name = OpString "T" -%main_name = OpString "main" )"; const std::string size_const = R"( @@ -4206,14 +3578,10 @@ main() {} %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %param %param %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main %temp = OpExtInst %void %DbgExt DebugTypeTemplate %main_info %param -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4226,7 +3594,6 @@ main() {} %float_name = OpString "float" %ty_name = OpString "Texture" %t_name = OpString "T" -%main_name = OpString "main" )"; const std::string size_const = R"( @@ -4241,14 +3608,10 @@ main() {} %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %float_info %param -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Target must be DebugTypeComposite or " @@ -4264,7 +3627,6 @@ main() {} %float_name = OpString "float" %ty_name = OpString "Texture" %t_name = OpString "T" -%main_name = OpString "main" )"; const std::string size_const = R"( @@ -4281,14 +3643,10 @@ main() {} %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %param %param %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main %temp = OpExtInst %void %DbgExt DebugTypeTemplate %main_info %float_info -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -4306,12 +3664,6 @@ main() {} %float_name = OpString "float" %ty_name = OpString "Texture" %t_name = OpString "T" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4322,15 +3674,10 @@ main() {} %opaque = OpExtInst %void %DbgExt DebugTypeComposite %ty_name %u32_1 %dbg_src %u32_1 %u32_1 %comp_unit %ty_name %dbg_none %u32_3 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src %u32_0 %u32_0 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %opaque %param -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4344,12 +3691,6 @@ main() {} %ty_name = OpString "Texture" %t_name = OpString "T" %foo_name = OpString "foo" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4361,15 +3702,10 @@ main() {} %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src %u32_0 %u32_0 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %opaque %param %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %temp %dbg_src %u32_0 %u32_0 %comp_unit %foo_name %f32_input %u32_3 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4382,13 +3718,6 @@ main() {} %float_name = OpString "float" %ty_name = OpString "Texture" %t_name = OpString "T" -%main_name = OpString "main" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4400,15 +3729,10 @@ main() {} %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %param %param %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %main_info %param -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4421,13 +3745,6 @@ main() {} %float_name = OpString "float" %ty_name = OpString "Texture" %t_name = OpString "T" -%main_name = OpString "main" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4437,15 +3754,10 @@ main() {} %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src %u32_0 %u32_0 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %float_info %param -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Target must be DebugTypeComposite or " @@ -4461,13 +3773,6 @@ main() {} %float_name = OpString "float" %ty_name = OpString "Texture" %t_name = OpString "T" -%main_name = OpString "main" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4478,15 +3783,10 @@ main() {} %opaque = OpExtInst %void %DbgExt DebugTypeComposite %ty_name %u32_1 %dbg_src %u32_1 %u32_1 %comp_unit %ty_name %dbg_none %u32_3 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src %u32_0 %u32_0 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %opaque %float_info -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -4512,14 +3812,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariable) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4542,14 +3838,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariableStaticMember) { %t = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Class %dbg_src 0 0 %comp_unit %foo_name %int_32 FlagIsPublic %a %a = OpExtInst %void %DbgExt DebugTypeMember %foo_name %float_info %dbg_src 0 0 %t %u32_0 %int_32 FlagIsPublic %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate %a -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4571,14 +3863,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariableDebugInfoNone) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %dbgNone FlagIsProtected|FlagIsPrivate -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4599,14 +3887,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariableConst) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %int_32 FlagIsProtected|FlagIsPrivate -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, "", extension, "Vertex")); + src, size_const, dbg_inst_header, "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4632,12 +3916,8 @@ TEST_P(ValidateOpenCL100DebugInfoDebugGlobalVariable, Fail) { %foo = OpExtInst %void %DbgExt DebugGlobalVariable )" << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, size_const, ss.str(), "", opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -4672,12 +3952,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugGlobalVariable) { %code = OpString "float foo; void main() {}" %float_name = OpString "float" %foo_name = OpString "foo" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4685,15 +3959,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugGlobalVariable) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src %u32_0 %u32_0 %comp_unit %foo_name %f32_input %u32_3 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4703,12 +3972,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugGlobalVariableStaticMember) { %code = OpString "float foo; void main() {}" %float_name = OpString "float" %foo_name = OpString "foo" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4718,15 +3981,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugGlobalVariableStaticMember) { %a = OpExtInst %void %DbgExt DebugTypeMember %foo_name %float_info %dbg_src %u32_0 %u32_0 %u32_0 %u32_32 %u32_3 %t = OpExtInst %void %DbgExt DebugTypeComposite %foo_name %u32_1 %dbg_src %u32_0 %u32_0 %comp_unit %foo_name %u32_32 %u32_3 %a %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %t %dbg_src %u32_0 %u32_0 %comp_unit %foo_name %f32_input %u32_3 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4736,12 +3994,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugGlobalVariableDebugInfoNone) { %code = OpString "float foo; void main() {}" %float_name = OpString "float" %foo_name = OpString "foo" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4750,15 +4002,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugGlobalVariableDebugInfoNone) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src %u32_0 %u32_0 %comp_unit %foo_name %dbgNone %u32_3 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4768,12 +4015,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugGlobalVariableConst) { %code = OpString "float foo; void main() {}" %float_name = OpString "float" %foo_name = OpString "foo" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4781,15 +4022,10 @@ TEST_F(ValidateVulkan100DebugInfo, DebugGlobalVariableConst) { %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src %u32_0 %u32_0 %comp_unit %foo_name %u32_32 %u32_3 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, "", extension, "Vertex")); + src, "", dbg_inst_header, "", shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4799,12 +4035,6 @@ TEST_P(ValidateVulkan100DebugInfoDebugGlobalVariable, Fail) { %code = OpString "float foo; void main() {}" %float_name = OpString "float" %foo_name = OpString "foo" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const auto& param = GetParam(); @@ -4817,13 +4047,8 @@ TEST_P(ValidateVulkan100DebugInfoDebugGlobalVariable, Fail) { %foo = OpExtInst %void %DbgExt DebugGlobalVariable )" << param.first; - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" -)"; - - CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, constants, ss.str(), - "", extension, "Vertex")); + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", ss.str(), "", shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -4857,29 +4082,23 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugInlinedAt) { %src = OpString "simple.hlsl" %code = OpString "void main() {}" %void_name = OpString "void" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" )"; const std::string dbg_inst_header = R"( %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info %inlined_at )"; const std::string body = R"( %main_scope = OpExtInst %void %DbgExt DebugScope %main_info %inlined_at -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, "", dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4888,29 +4107,23 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugInlinedAtFail) { %src = OpString "simple.hlsl" %code = OpString "void main() {}" %void_name = OpString "void" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" )"; const std::string dbg_inst_header = R"( %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt 0 %inlined_at )"; const std::string body = R"( %main_scope = OpExtInst %void %DbgExt DebugScope %main_info %inlined_at -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, "", dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Scope")); } @@ -4920,29 +4133,23 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugInlinedAtFail2) { %src = OpString "simple.hlsl" %code = OpString "void main() {}" %void_name = OpString "void" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" )"; const std::string dbg_inst_header = R"( %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void -%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info %main_info )"; const std::string body = R"( %main_scope = OpExtInst %void %DbgExt DebugScope %main_info %inlined_at -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, "", dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Inlined")); } @@ -4952,14 +4159,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugInlinedAt) { %src = OpString "simple.hlsl" %code = OpString "void main() {}" %void_name = OpString "void" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -4969,11 +4168,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugInlinedAt) { %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt %u32_0 %main_info %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt %u32_0 %main_info %inlined_at -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; const std::string body = R"( @@ -4981,7 +4175,7 @@ OpExtension "SPV_KHR_non_semantic_info" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -4990,14 +4184,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugInlinedAtFail) { %src = OpString "simple.hlsl" %code = OpString "void main() {}" %void_name = OpString "void" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -5007,11 +4193,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugInlinedAtFail) { %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt %u32_0 %main_info %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt %u32_0 %inlined_at %inlined_at -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; const std::string body = R"( @@ -5019,7 +4200,7 @@ OpExtension "SPV_KHR_non_semantic_info" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Scope")); } @@ -5029,14 +4210,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugInlinedAtFail2) { %src = OpString "simple.hlsl" %code = OpString "void main() {}" %void_name = OpString "void" -%main_name = OpString "main" -%main_linkage_name = OpString "v_main" -)"; - - const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -5046,11 +4219,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugInlinedAtFail2) { %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt %u32_0 %main_info %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt %u32_0 %main_info %main_info -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; const std::string body = R"( @@ -5058,7 +4226,7 @@ OpExtension "SPV_KHR_non_semantic_info" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, body, extension, "Vertex")); + src, "", dbg_inst_header, body, shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Inlined")); } @@ -5087,14 +4255,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugValue) { const std::string body = R"( %value = OpExtInst %void %DbgExt DebugValue %foo_info %int_32 %null_expr %int_3 -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, body, extension, "Vertex")); + src, size_const, dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -5126,14 +4290,10 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugValueWithVariableIndex) { const std::string body = R"( %value = OpExtInst %void %DbgExt DebugValue %foo_info %int_32 %null_expr %len_info -)"; - - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, body, extension, "Vertex")); + src, size_const, dbg_inst_header, body, opencl_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -5164,12 +4324,8 @@ TEST_P(ValidateOpenCL100DebugInfoDebugValue, Fail) { %decl = OpExtInst %void %DbgExt DebugValue )" << param.first; - const std::string extension = R"( -%DbgExt = OpExtInstImport "OpenCL.DebugInfo.100" -)"; - CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, size_const, dbg_inst_header, ss.str(), extension, "Vertex")); + src, size_const, dbg_inst_header, ss.str(), opencl_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -5192,10 +4348,7 @@ TEST_F(ValidateVulkan100DebugInfo, DebugValue) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_10 = OpConstant %u32 10 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -5205,11 +4358,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugValue) { %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %v4float_info %dbg_src %u32_1 %u32_10 %comp_unit %u32_4 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; const std::string body = R"( @@ -5217,7 +4365,7 @@ OpExtension "SPV_KHR_non_semantic_info" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, body, extension, "Vertex")); + src, constants, dbg_inst_header, body, shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -5232,10 +4380,7 @@ TEST_F(ValidateVulkan100DebugInfo, DebugValueWithVariableIndex) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_10 = OpConstant %u32 10 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -5247,11 +4392,6 @@ TEST_F(ValidateVulkan100DebugInfo, DebugValueWithVariableIndex) { %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %v4float_info %dbg_src %u32_1 %u32_10 %comp_unit %u32_4 %u32_0 %len_info = OpExtInst %void %DbgExt DebugLocalVariable %len_name %int_info %dbg_src %u32_0 %u32_0 %comp_unit %u32_4 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; const std::string body = R"( @@ -5259,7 +4399,7 @@ OpExtension "SPV_KHR_non_semantic_info" )"; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, body, extension, "Vertex")); + src, constants, dbg_inst_header, body, shader_extension, "Vertex")); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -5272,10 +4412,7 @@ TEST_P(ValidateVulkan100DebugInfoDebugValue, Fail) { )"; const std::string constants = R"( -%u32_4 = OpConstant %u32 4 -%u32_5 = OpConstant %u32 5 %u32_10 = OpConstant %u32 10 -%u32_32 = OpConstant %u32 32 )"; const std::string dbg_inst_header = R"( @@ -5285,11 +4422,6 @@ TEST_P(ValidateVulkan100DebugInfoDebugValue, Fail) { %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %v4float_info %dbg_src %u32_1 %u32_10 %comp_unit %u32_4 %u32_0 -)"; - - const std::string extension = R"( -OpExtension "SPV_KHR_non_semantic_info" -%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" )"; const auto& param = GetParam(); @@ -5300,7 +4432,7 @@ OpExtension "SPV_KHR_non_semantic_info" << param.first; CompileSuccessfully(GenerateShaderCodeForDebugInfo( - src, constants, dbg_inst_header, ss.str(), extension, "Vertex")); + src, constants, dbg_inst_header, ss.str(), shader_extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand " + param.second)); @@ -5475,6 +4607,428 @@ TEST_F(ValidateVulkan100DebugInfo, VulkanDebugInfoSample) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } +TEST_F(ValidateVulkan100DebugInfo, DebugFunctionDefinition) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 +%main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +)"; + + const std::string body = R"( +%main_def = OpExtInst %void %DbgExt DebugFunctionDefinition %main_info %main +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugFunctionDefinitionFailFunction) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 +%main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +)"; + + const std::string body = R"( +%main_def = OpExtInst %void %DbgExt DebugFunctionDefinition %main_type_info %main +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugFunctionDefinition: expected operand Function " + "must be a result id of DebugFunction")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugFunctionDefinitionFailDefinition) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 +%main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +)"; + + const std::string body = R"( +%main_def = OpExtInst %void %DbgExt DebugFunctionDefinition %main_info %main_name +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugFunctionDefinition: expected operand Definition " + "must be a result id of OpFunction")); +} + +// TODO - Need to track in function scope +TEST_F(ValidateVulkan100DebugInfo, DISABLED_DebugFunctionDefinitionDuplicate) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 +%main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void +%main_info1 = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +%main_info2 = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +)"; + + const std::string body = R"( +%main_def1 = OpExtInst %void %DbgExt DebugFunctionDefinition %main_info1 %main +%main_def2 = OpExtInst %void %DbgExt DebugFunctionDefinition %main_info2 %main +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugFunctionDefinition: Was used multiple times in " + "single function block")); +} + +// TODO - Need to track in function scope +TEST_F(ValidateVulkan100DebugInfo, + DISABLED_DebugFunctionDefinitionDuplicateReference) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 +%main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +)"; + + const std::string body = R"( +%main_def = OpExtInst %void %DbgExt DebugFunctionDefinition %main_info %main +OpReturn +OpFunctionEnd + +%foo = OpFunction %void None %func +%foo_entry = OpLabel +%foo_def = OpExtInst %void %DbgExt DebugFunctionDefinition %main_info %foo +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugFunctionDefinition: Was referenced a " + "DebugFunction that was already referenced before")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugFunctionDefinitionWrongDefinition) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 +%main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +%foo_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +)"; + + const std::string body = R"( +%main_def = OpExtInst %void %DbgExt DebugFunctionDefinition %main_info %main +OpReturn +OpFunctionEnd + +%foo = OpFunction %void None %func +%foo_entry = OpLabel +%foo_def = OpExtInst %void %DbgExt DebugFunctionDefinition %foo_info %main +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugFunctionDefinition: operand Definition must " + "point to the OpFunction it is inside")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugFunctionDefinitionNonEntryBlock) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string constants = R"( +%false = OpConstantFalse %bool +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 +%main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +)"; + + const std::string body = R"( +OpSelectionMerge %merge_block None +OpBranchConditional %false %second_block %merge_block +%second_block = OpLabel +OpReturn +%merge_block = OpLabel +%main_def = OpExtInst %void %DbgExt DebugFunctionDefinition %main_info %main +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, constants, dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugFunctionDefinition: must be in the entry basic " + "block of the function")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugFunctionDefinitionMultiFunctions) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5 +%main_type_info = OpExtInst %void %DbgExt DebugTypeFunction %u32_3 %void +%main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +%foo_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src %u32_1 %u32_1 %comp_unit %main_name %u32_3 %u32_1 +)"; + + const std::string body = R"( +%main_def = OpExtInst %void %DbgExt DebugFunctionDefinition %main_info %main +OpReturn +OpFunctionEnd + +%foo = OpFunction %void None %func +%foo_entry = OpLabel +%foo_def = OpExtInst %void %DbgExt DebugFunctionDefinition %foo_info %foo +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugLine) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +)"; + + const std::string body = R"( +%line1 = OpExtInst %void %DbgExt DebugLine %dbg_src %u32_1 %u32_2 %u32_0 %u32_0 +%line2 = OpExtInst %void %DbgExt DebugLine %dbg_src %u32_1 %u32_2 %u32_0 %u32_0 +%no_line = OpExtInst %void %DbgExt DebugNoLine +%line3 = OpExtInst %void %DbgExt DebugLine %dbg_src %u32_1 %u32_2 %u32_0 %u32_0 +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugNoLineOutOfBlock) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%no_line = OpExtInst %void %DbgExt DebugNoLine +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, "", shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("debug info extension must appear in a function body")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugLineOutOfBlock) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%line = OpExtInst %void %DbgExt DebugLine %dbg_src %u32_1 %u32_2 %u32_0 %u32_0 +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, "", shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("debug info extension must appear in a function body")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugLineSource) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +%int_name = OpString "int" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%int_info = OpExtInst %void %DbgExt DebugTypeBasic %int_name %u32_0 %u32_1 %u32_0 +)"; + + const std::string body = R"( +%line = OpExtInst %void %DbgExt DebugLine %int_info %u32_2 %u32_2 %u32_0 %u32_0 +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugLine: expected operand Source must be a result " + "id of DebugSource")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugLineFloat) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +)"; + + const std::string body = R"( +%line1 = OpExtInst %void %DbgExt DebugLine %dbg_src %f32_1 %u32_2 %u32_0 %u32_0 +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugLine: expected operand Line Start must be a " + "result id of 32-bit unsigned OpConstant")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugLineInt64) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +)"; + + const std::string body = R"( +%line1 = OpExtInst %void %DbgExt DebugLine %dbg_src %u64_1 %u64_1 %u32_0 %u32_0 +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugLine: expected operand Line Start must be a " + "result id of 32-bit unsigned OpConstant")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugLineSpecConstant) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +%spec_int = OpSpecConstant %u32 2 +)"; + + const std::string body = R"( +%line1 = OpExtInst %void %DbgExt DebugLine %dbg_src %spec_int %u32_1 %u32_0 %u32_0 +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("DebugLine: expected operand Line Start must be a " + "result id of 32-bit unsigned OpConstant")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugLineLineEndSmaller) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +)"; + + const std::string body = R"( +%line1 = OpExtInst %void %DbgExt DebugLine %dbg_src %u32_2 %u32_1 %u32_0 %u32_0 +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("DebugLine: operand Line End (1) is less than Line Start (2)")); +} + +TEST_F(ValidateVulkan100DebugInfo, DebugLineColumnEndSmaller) { + const std::string src = R"( +%src = OpString "simple.hlsl" +%code = OpString "int main() { }" +)"; + + const std::string dbg_inst_header = R"( +%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code +)"; + + const std::string body = R"( +%line1 = OpExtInst %void %DbgExt DebugLine %dbg_src %u32_1 %u32_1 %u32_1 %u32_0 +)"; + + CompileSuccessfully(GenerateShaderCodeForDebugInfo( + src, "", dbg_inst_header, body, shader_extension, "Vertex")); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "DebugLine: operand Column End (0) is less than Column Start (1)")); +} + } // namespace } // namespace val } // namespace spvtools From a9d884e58db82c2c7e6227a24096616f4c6c8783 Mon Sep 17 00:00:00 2001 From: David Neto Date: Tue, 26 Nov 2024 17:57:32 -0500 Subject: [PATCH 21/26] spirv-as: Assume target from spvasm text (#5893) * spirv-as: Assume target from spvasm text Assume the desired SPIR-V target version when the command line option is not provided. This is especially important when the source being assembled does not match the default (latest version), because it may create an invalid SPIR-V binary result. Also, clarify the wording for where a copy of spirv-headers is expected (to match expected capitalization). * fix formatting * Add unit tests, static asserts on supported SPIR-V versions Rework the algorithm so it accepts earlier termination of the version string. That made testing easier and more intuitive. * Fix compilation problems --------- Co-authored-by: mmoult <30711895+mmoult@users.noreply.github.com> --- external/CMakeLists.txt | 2 +- source/spirv_target_env.cpp | 120 ++++++++++++++++++++++++++++-------- source/spirv_target_env.h | 7 +++ test/target_env_test.cpp | 57 ++++++++++++++++- tools/as/as.cpp | 47 +++++++------- 5 files changed, 180 insertions(+), 53 deletions(-) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 5d8a3dab09..1ccab19640 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -45,7 +45,7 @@ if (IS_DIRECTORY ${SPIRV_HEADER_DIR}) endif() else() message(FATAL_ERROR - "SPIRV-Headers was not found - please checkout a copy under external/.") + "SPIRV-Headers was not found - please checkout a copy at external/spirv-headers.") endif() if (NOT ${SPIRV_SKIP_TESTS}) diff --git a/source/spirv_target_env.cpp b/source/spirv_target_env.cpp index 585f8b65a2..a787481d9b 100644 --- a/source/spirv_target_env.cpp +++ b/source/spirv_target_env.cpp @@ -14,11 +14,13 @@ #include "source/spirv_target_env.h" +#include #include +#include #include #include -#include +#include "source/latest_version_spirv_header.h" #include "source/spirv_constant.h" #include "spirv-tools/libspirv.h" @@ -128,32 +130,43 @@ uint32_t spvVersionForTargetEnv(spv_target_env env) { return SPV_SPIRV_VERSION_WORD(0, 0); } -static const std::pair spvTargetEnvNameMap[] = { - {"vulkan1.1spv1.4", SPV_ENV_VULKAN_1_1_SPIRV_1_4}, - {"vulkan1.0", SPV_ENV_VULKAN_1_0}, - {"vulkan1.1", SPV_ENV_VULKAN_1_1}, - {"vulkan1.2", SPV_ENV_VULKAN_1_2}, - {"vulkan1.3", SPV_ENV_VULKAN_1_3}, - {"spv1.0", SPV_ENV_UNIVERSAL_1_0}, - {"spv1.1", SPV_ENV_UNIVERSAL_1_1}, - {"spv1.2", SPV_ENV_UNIVERSAL_1_2}, - {"spv1.3", SPV_ENV_UNIVERSAL_1_3}, - {"spv1.4", SPV_ENV_UNIVERSAL_1_4}, - {"spv1.5", SPV_ENV_UNIVERSAL_1_5}, - {"spv1.6", SPV_ENV_UNIVERSAL_1_6}, - {"opencl1.2embedded", SPV_ENV_OPENCL_EMBEDDED_1_2}, - {"opencl1.2", SPV_ENV_OPENCL_1_2}, - {"opencl2.0embedded", SPV_ENV_OPENCL_EMBEDDED_2_0}, - {"opencl2.0", SPV_ENV_OPENCL_2_0}, - {"opencl2.1embedded", SPV_ENV_OPENCL_EMBEDDED_2_1}, - {"opencl2.1", SPV_ENV_OPENCL_2_1}, - {"opencl2.2embedded", SPV_ENV_OPENCL_EMBEDDED_2_2}, - {"opencl2.2", SPV_ENV_OPENCL_2_2}, - {"opengl4.0", SPV_ENV_OPENGL_4_0}, - {"opengl4.1", SPV_ENV_OPENGL_4_1}, - {"opengl4.2", SPV_ENV_OPENGL_4_2}, - {"opengl4.3", SPV_ENV_OPENGL_4_3}, - {"opengl4.5", SPV_ENV_OPENGL_4_5}, +// When a new SPIR-V version is released, update this table. +static_assert(spv::Version == 0x10600); +constexpr auto ordered_universal_envs = std::array{ + SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_2, + SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_4, SPV_ENV_UNIVERSAL_1_5, + SPV_ENV_UNIVERSAL_1_6, +}; + +// When a new SPIR-V version is released, update this table. +static_assert(spv::Version == 0x10600); +inline constexpr std::pair spvTargetEnvNameMap[] = + { + {"vulkan1.1spv1.4", SPV_ENV_VULKAN_1_1_SPIRV_1_4}, + {"vulkan1.0", SPV_ENV_VULKAN_1_0}, + {"vulkan1.1", SPV_ENV_VULKAN_1_1}, + {"vulkan1.2", SPV_ENV_VULKAN_1_2}, + {"vulkan1.3", SPV_ENV_VULKAN_1_3}, + {"spv1.0", SPV_ENV_UNIVERSAL_1_0}, + {"spv1.1", SPV_ENV_UNIVERSAL_1_1}, + {"spv1.2", SPV_ENV_UNIVERSAL_1_2}, + {"spv1.3", SPV_ENV_UNIVERSAL_1_3}, + {"spv1.4", SPV_ENV_UNIVERSAL_1_4}, + {"spv1.5", SPV_ENV_UNIVERSAL_1_5}, + {"spv1.6", SPV_ENV_UNIVERSAL_1_6}, + {"opencl1.2embedded", SPV_ENV_OPENCL_EMBEDDED_1_2}, + {"opencl1.2", SPV_ENV_OPENCL_1_2}, + {"opencl2.0embedded", SPV_ENV_OPENCL_EMBEDDED_2_0}, + {"opencl2.0", SPV_ENV_OPENCL_2_0}, + {"opencl2.1embedded", SPV_ENV_OPENCL_EMBEDDED_2_1}, + {"opencl2.1", SPV_ENV_OPENCL_2_1}, + {"opencl2.2embedded", SPV_ENV_OPENCL_EMBEDDED_2_2}, + {"opencl2.2", SPV_ENV_OPENCL_2_2}, + {"opengl4.0", SPV_ENV_OPENGL_4_0}, + {"opengl4.1", SPV_ENV_OPENGL_4_1}, + {"opengl4.2", SPV_ENV_OPENGL_4_2}, + {"opengl4.3", SPV_ENV_OPENGL_4_3}, + {"opengl4.5", SPV_ENV_OPENGL_4_5}, }; bool spvParseTargetEnv(const char* s, spv_target_env* env) { @@ -172,6 +185,59 @@ bool spvParseTargetEnv(const char* s, spv_target_env* env) { return false; } +bool spvReadEnvironmentFromText(const std::vector& text, + spv_target_env* env) { + // Version is expected to match "; Version: 1.X" + // Version string must occur in header, that is, initial lines of comments + // Once a non-comment line occurs, the header has ended + for (std::size_t i = 0; i < text.size(); ++i) { + char c = text[i]; + + if (c == ';') { + // Try to match against the expected version string + constexpr const char* kVersionPrefix = "; Version: 1."; + constexpr const auto kPrefixLength = 13; + // 'minor_digit_pos' is the expected position of the version digit. + const auto minor_digit_pos = i + kPrefixLength; + if (minor_digit_pos >= text.size()) return false; + + // Match the prefix. + auto j = 1; + for (; j < kPrefixLength; ++j) { + if (kVersionPrefix[j] != text[i + j]) break; + } + // j will match the prefix length if all characters before matched + if (j == kPrefixLength) { + // This expects only one digit in the minor number. + static_assert(((spv::Version >> 8) & 0xff) < 10); + char minor = text[minor_digit_pos]; + char next_char = + minor_digit_pos + 1 < text.size() ? text[minor_digit_pos + 1] : 0; + if (std::isdigit(minor) && !std::isdigit(next_char)) { + const auto index = minor - '0'; + assert(index >= 0); + if (static_cast(index) < ordered_universal_envs.size()) { + *env = ordered_universal_envs[index]; + return true; + } + } + } + + // If no match, determine whether the header has ended (in which case, + // assumption has failed.) + // Skip until the next line. + i = j; + for (; i < text.size(); ++i) { + if (text[i] == '\n') break; + } + } else if (!std::isspace(c)) { + // Allow blanks, but end the search if we find something else. + break; + } + } + return false; +} + #define VULKAN_VER(MAJOR, MINOR) ((MAJOR << 22) | (MINOR << 12)) #define SPIRV_VER(MAJOR, MINOR) ((MAJOR << 16) | (MINOR << 8)) diff --git a/source/spirv_target_env.h b/source/spirv_target_env.h index f3b0c2f6f2..4378f06fa4 100644 --- a/source/spirv_target_env.h +++ b/source/spirv_target_env.h @@ -16,6 +16,8 @@ #define SOURCE_SPIRV_TARGET_ENV_H_ #include +#include +#include #include "spirv-tools/libspirv.h" @@ -46,4 +48,9 @@ std::string spvLogStringForEnv(spv_target_env env); // occur to satisfy this limit. std::string spvTargetEnvList(const int pad, const int wrap); +// Reads the target environment from the header comments of disassembly. Returns +// true if valid name found, false otherwise. +bool spvReadEnvironmentFromText(const std::vector& text, + spv_target_env* env); + #endif // SOURCE_SPIRV_TARGET_ENV_H_ diff --git a/test/target_env_test.cpp b/test/target_env_test.cpp index 7917cbfb44..faffa8a1e0 100644 --- a/test/target_env_test.cpp +++ b/test/target_env_test.cpp @@ -170,5 +170,60 @@ INSTANTIATE_TEST_SUITE_P( {VK(99, 0), SPV(1, 0), false, SPV_ENV_UNIVERSAL_1_0}, })); -} // namespace +// A test case for parsing the text header of disassembly. +struct ParseEnvInDisassemblyCase { + std::string text; + bool success; // Expect to successfully parse? + spv_target_env env; // The parsed environment, if successful. +}; + +using TargetParseEnvInDisassemblyTest = + ::testing::TestWithParam; + +constexpr spv_target_env kSentinelEnv = SPV_ENV_OPENCL_2_2; + +TEST_P(TargetParseEnvInDisassemblyTest, Samples) { + const std::string& text = GetParam().text; + const std::vector text_vec(text.begin(), text.end()); + spv_target_env got_env = kSentinelEnv; + bool parsed = spvReadEnvironmentFromText(text_vec, &got_env); + EXPECT_EQ(parsed, GetParam().success); + EXPECT_EQ(got_env, GetParam().env) << '"' << text << '"'; +} + +INSTANTIATE_TEST_SUITE_P( + TargetTextParsing, TargetParseEnvInDisassemblyTest, + ValuesIn(std::vector{ + {"; Version: 1.0", true, SPV_ENV_UNIVERSAL_1_0}, + {"; Version: 1.1", true, SPV_ENV_UNIVERSAL_1_1}, + {"; Version: 1.2", true, SPV_ENV_UNIVERSAL_1_2}, + {"; Version: 1.3", true, SPV_ENV_UNIVERSAL_1_3}, + {"; Version: 1.4", true, SPV_ENV_UNIVERSAL_1_4}, + {"; Version: 1.5", true, SPV_ENV_UNIVERSAL_1_5}, + {"; Version: 1.6", true, SPV_ENV_UNIVERSAL_1_6}, + {"; Version: 1.7", false, kSentinelEnv}, + {"; Version: 1.8", false, kSentinelEnv}, + {"; Version: 1.9", false, kSentinelEnv}, + {"; Version: 2.0", false, kSentinelEnv}, + + // Check trailing text + {"; Version: 1.1\n", true, SPV_ENV_UNIVERSAL_1_1}, + {"; Version: 1.1\t", true, SPV_ENV_UNIVERSAL_1_1}, + {"; Version: 1.1 ", true, SPV_ENV_UNIVERSAL_1_1}, + {"; Version: 1.1x", true, SPV_ENV_UNIVERSAL_1_1}, + // Not a digit. + {"; Version: 1.10", false, kSentinelEnv}, + + // Unexpected prefix + {";Version: 1.1", false, kSentinelEnv}, + + // Leading spaces + {" \t ; Version: 1.1", true, SPV_ENV_UNIVERSAL_1_1}, + // Previous lines + {"; SPIR-V\n; Version: 1.1", true, SPV_ENV_UNIVERSAL_1_1}, + + // After a non-header line + {"OpCapability Shader\n; Version: 1.1", false, kSentinelEnv}})); + +} // anonymous namespace } // namespace spvtools diff --git a/tools/as/as.cpp b/tools/as/as.cpp index ab18aeb359..8e821701de 100644 --- a/tools/as/as.cpp +++ b/tools/as/as.cpp @@ -22,7 +22,7 @@ #include "tools/io.h" #include "tools/util/flags.h" -static const auto kDefaultEnvironment = "spv1.6"; +constexpr auto kDefaultTarget = SPV_ENV_UNIVERSAL_1_6; static const std::string kHelpText = R"(%s - Create a SPIR-V binary module from SPIR-V assembly text @@ -48,12 +48,13 @@ is used. )"; // clang-format off -FLAG_SHORT_bool( h, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( help, /* default_value= */ false, /* required= */false); -FLAG_LONG_bool( version, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( preserve_numeric_ids, /* default_value= */ false, /* required= */ false); -FLAG_SHORT_string(o, /* default_value= */ "", /* required= */ false); -FLAG_LONG_string( target_env, /* default_value= */ kDefaultEnvironment, /* required= */ false); +// flag name= default_value= required= +FLAG_SHORT_bool( h, false, false); +FLAG_LONG_bool( help, false, false); +FLAG_LONG_bool( version, false, false); +FLAG_LONG_bool( preserve_numeric_ids, false, false); +FLAG_SHORT_string(o, "", false); +FLAG_LONG_string( target_env, "", false); // clang-format on int main(int, const char** argv) { @@ -68,17 +69,8 @@ int main(int, const char** argv) { } if (flags::version.value()) { - spv_target_env target_env; - bool success = spvParseTargetEnv(kDefaultEnvironment, &target_env); - assert(success && "Default environment should always parse."); - if (!success) { - fprintf(stderr, - "error: invalid default target environment. Please report this " - "issue."); - return 1; - } printf("%s\n", spvSoftwareVersionDetailsString()); - printf("Target: %s\n", spvTargetEnvDescription(target_env)); + printf("Target: %s\n", spvTargetEnvDescription(kDefaultTarget)); return 0; } @@ -92,13 +84,6 @@ int main(int, const char** argv) { options |= SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS; } - spv_target_env target_env; - if (!spvParseTargetEnv(flags::target_env.value().c_str(), &target_env)) { - fprintf(stderr, "error: Unrecognized target env: %s\n", - flags::target_env.value().c_str()); - return 1; - } - if (flags::positional_arguments.size() != 1) { fprintf(stderr, "error: exactly one input file must be specified.\n"); return 1; @@ -108,6 +93,20 @@ int main(int, const char** argv) { std::vector contents; if (!ReadTextFile(inFile.c_str(), &contents)) return 1; + // Can only deduce target after the file has been read + spv_target_env target_env; + if (flags::target_env.value().empty()) { + if (!spvReadEnvironmentFromText(contents, &target_env)) { + // Revert to default version since deduction failed + target_env = kDefaultTarget; + } + } else if (!spvParseTargetEnv(flags::target_env.value().c_str(), + &target_env)) { + fprintf(stderr, "error: Unrecognized target env: %s\n", + flags::target_env.value().c_str()); + return 1; + } + spv_binary binary; spv_diagnostic diagnostic = nullptr; spv_context context = spvContextCreate(target_env); From 7c58952fa8ab2fff009cb6710fad34bd1ce7dff3 Mon Sep 17 00:00:00 2001 From: sushraja-msft <44513542+sushraja-msft@users.noreply.github.com> Date: Wed, 27 Nov 2024 06:26:01 -0800 Subject: [PATCH 22/26] Update path-to-regexp to address CVE-2024-45296 (#5895) * Update path-to-regexp to address CVE-2024-45296 * Update yarn.lock Continue to use yarnpkg.com --- tools/sva/yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/sva/yarn.lock b/tools/sva/yarn.lock index ef65c75fcc..38788e2bde 100644 --- a/tools/sva/yarn.lock +++ b/tools/sva/yarn.lock @@ -1083,10 +1083,10 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-to-regexp@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45" - integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ== +path-to-regexp@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-3.3.0.tgz#f7f31d32e8518c2660862b644414b6d5c63a611b" + integrity sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw== pathval@^1.1.1: version "1.1.1" @@ -1231,7 +1231,7 @@ serve-handler@6.1.5: mime-types "2.1.18" minimatch "3.1.2" path-is-inside "1.0.2" - path-to-regexp "2.2.1" + path-to-regexp "3.3.0" range-parser "1.2.0" serve@^14.2.0: From eebdb15753f83094bb5fa84148b50431b214eda3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 01:36:51 +0000 Subject: [PATCH 23/26] Roll external/abseil_cpp/ 917bfee46..b67caffec (3 commits) (#5889) * Roll external/googletest/ d14403194..35d0c3656 (1 commit) https://github.com/google/googletest/compare/d14403194054...35d0c3656092 Created with: roll-dep external/googletest * Roll external/abseil_cpp/ 917bfee46..c7cf999bd (6 commits) https://github.com/abseil/abseil-cpp/compare/917bfee46514...c7cf999bda83 Created with: roll-dep external/abseil_cpp * Roll external/spirv-headers/ 45b314049..36d5e2dda (1 commit) https://github.com/KhronosGroup/SPIRV-Headers/compare/45b314049d62...36d5e2ddaa54 Created with: roll-dep external/spirv-headers --------- Co-authored-by: GitHub Actions[bot] <> --- DEPS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DEPS b/DEPS index 753b379779..ea86b4cf48 100644 --- a/DEPS +++ b/DEPS @@ -3,18 +3,18 @@ use_relative_paths = True vars = { 'github': 'https://github.com', - 'abseil_revision': '917bfee46514a1da47df74265571f47700922c0a', + 'abseil_revision': 'c7cf999bda8390d2dd294ef903716a80135e6f4c', 'effcee_revision': '2c97e5689ed8d7ab6ae5820f884f03a601ae124b', - 'googletest_revision': 'd144031940543e15423a25ae5a8a74141044862f', + 'googletest_revision': '35d0c365609296fa4730d62057c487e3cfa030ff', # Use protobufs before they gained the dependency on abseil 'protobuf_revision': 'v21.12', 're2_revision': '6dcd83d60f7944926bfd308cc13979fc53dd69ca', - 'spirv_headers_revision': '45b314049d6262c850cc873c8f9a30f41a1e0c13', + 'spirv_headers_revision': '36d5e2ddaa54c70d2f29081510c66f4fc98e5e53', } deps = { From 7d5bc35197be75e10000f14ea9eb3954ca2b0aab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 07:38:29 -0500 Subject: [PATCH 24/26] build(deps): bump github/codeql-action in the github-actions group (#5891) Bumps the github-actions group with 1 update: [github/codeql-action](https://github.com/github/codeql-action). Updates `github/codeql-action` from 3.27.4 to 3.27.5 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/ea9e4e37992a54ee68a9622e985e60c8e8f12d9f...f09c1c0a94de965c15400f5634aa42fac8fb8f88) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index e82a650cbe..8a2c9ecbb8 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -48,6 +48,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 + uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 with: sarif_file: results.sarif From 3fb52548bc8a68d349d31e21bd4e80e3d953e87c Mon Sep 17 00:00:00 2001 From: David Neto Date: Mon, 2 Dec 2024 18:25:00 -0500 Subject: [PATCH 25/26] Vulkan 1.4 support (#5899) * Add a Vulkan 1.4 environment * Fix test: Vulkan 1.3 accepts SPIR-V 1.6 * Fix comments about Vulkan 1.4 * Add test cases for Vulkan 1.4, optimizer ir_context tests --------- Co-authored-by: Faith Ekstrand --- include/spirv-tools/libspirv.h | 2 ++ source/ext_inst.cpp | 1 + source/spirv_target_env.cpp | 14 +++++++++++-- source/table.cpp | 1 + test/opt/ir_context_test.cpp | 20 ++++++++++++++----- test/val/val_version_test.cpp | 36 +++++++++++++++++++++++++++++++++- 6 files changed, 66 insertions(+), 8 deletions(-) diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h index 70931cb6c4..100e61e1d8 100644 --- a/include/spirv-tools/libspirv.h +++ b/include/spirv-tools/libspirv.h @@ -540,6 +540,7 @@ SPIRV_TOOLS_EXPORT const char* spvSoftwareVersionDetailsString(void); // SPV_ENV_VULKAN_1_1_SPIRV_1_4 -> SPIR-V 1.4 // SPV_ENV_VULKAN_1_2 -> SPIR-V 1.5 // SPV_ENV_VULKAN_1_3 -> SPIR-V 1.6 +// SPV_ENV_VULKAN_1_4 -> SPIR-V 1.6 // Consult the description of API entry points for specific rules. typedef enum { SPV_ENV_UNIVERSAL_1_0, // SPIR-V 1.0 latest revision, no other restrictions. @@ -577,6 +578,7 @@ typedef enum { SPV_ENV_UNIVERSAL_1_6, // SPIR-V 1.6 latest revision, no other restrictions. SPV_ENV_VULKAN_1_3, // Vulkan 1.3 latest revision. + SPV_ENV_VULKAN_1_4, // Vulkan 1.4 latest revision. SPV_ENV_MAX // Keep this as the last enum value. } spv_target_env; diff --git a/source/ext_inst.cpp b/source/ext_inst.cpp index 9a5ba84e46..f2ff63fc20 100644 --- a/source/ext_inst.cpp +++ b/source/ext_inst.cpp @@ -102,6 +102,7 @@ spv_result_t spvExtInstTableGet(spv_ext_inst_table* pExtInstTable, case SPV_ENV_VULKAN_1_2: case SPV_ENV_UNIVERSAL_1_6: case SPV_ENV_VULKAN_1_3: + case SPV_ENV_VULKAN_1_4: *pExtInstTable = &kTable_1_0; return SPV_SUCCESS; default: diff --git a/source/spirv_target_env.cpp b/source/spirv_target_env.cpp index a787481d9b..8e1b2dd79c 100644 --- a/source/spirv_target_env.cpp +++ b/source/spirv_target_env.cpp @@ -79,6 +79,8 @@ const char* spvTargetEnvDescription(spv_target_env env) { return "SPIR-V 1.6"; case SPV_ENV_VULKAN_1_3: return "SPIR-V 1.6 (under Vulkan 1.3 semantics)"; + case SPV_ENV_VULKAN_1_4: + return "SPIR-V 1.6 (under Vulkan 1.4 semantics)"; case SPV_ENV_MAX: assert(false && "Invalid target environment value."); break; @@ -122,6 +124,7 @@ uint32_t spvVersionForTargetEnv(spv_target_env env) { return SPV_SPIRV_VERSION_WORD(1, 5); case SPV_ENV_UNIVERSAL_1_6: case SPV_ENV_VULKAN_1_3: + case SPV_ENV_VULKAN_1_4: return SPV_SPIRV_VERSION_WORD(1, 6); case SPV_ENV_MAX: assert(false && "Invalid target environment value."); @@ -147,6 +150,7 @@ inline constexpr std::pair spvTargetEnvNameMap[] = {"vulkan1.1", SPV_ENV_VULKAN_1_1}, {"vulkan1.2", SPV_ENV_VULKAN_1_2}, {"vulkan1.3", SPV_ENV_VULKAN_1_3}, + {"vulkan1.4", SPV_ENV_VULKAN_1_4}, {"spv1.0", SPV_ENV_UNIVERSAL_1_0}, {"spv1.1", SPV_ENV_UNIVERSAL_1_1}, {"spv1.2", SPV_ENV_UNIVERSAL_1_2}, @@ -254,7 +258,8 @@ static const VulkanEnv ordered_vulkan_envs[] = { {SPV_ENV_VULKAN_1_1, VULKAN_VER(1, 1), SPIRV_VER(1, 3)}, {SPV_ENV_VULKAN_1_1_SPIRV_1_4, VULKAN_VER(1, 1), SPIRV_VER(1, 4)}, {SPV_ENV_VULKAN_1_2, VULKAN_VER(1, 2), SPIRV_VER(1, 5)}, - {SPV_ENV_VULKAN_1_3, VULKAN_VER(1, 3), SPIRV_VER(1, 6)}}; + {SPV_ENV_VULKAN_1_3, VULKAN_VER(1, 3), SPIRV_VER(1, 6)}, + {SPV_ENV_VULKAN_1_4, VULKAN_VER(1, 4), SPIRV_VER(1, 6)}}; bool spvParseVulkanEnv(uint32_t vulkan_ver, uint32_t spirv_ver, spv_target_env* env) { @@ -295,6 +300,7 @@ bool spvIsVulkanEnv(spv_target_env env) { case SPV_ENV_VULKAN_1_1_SPIRV_1_4: case SPV_ENV_VULKAN_1_2: case SPV_ENV_VULKAN_1_3: + case SPV_ENV_VULKAN_1_4: return true; case SPV_ENV_WEBGPU_0: assert(false && "Deprecated target environment value."); @@ -325,6 +331,7 @@ bool spvIsOpenCLEnv(spv_target_env env) { case SPV_ENV_VULKAN_1_2: case SPV_ENV_UNIVERSAL_1_6: case SPV_ENV_VULKAN_1_3: + case SPV_ENV_VULKAN_1_4: return false; case SPV_ENV_OPENCL_1_2: case SPV_ENV_OPENCL_EMBEDDED_1_2: @@ -367,6 +374,7 @@ bool spvIsOpenGLEnv(spv_target_env env) { case SPV_ENV_VULKAN_1_2: case SPV_ENV_UNIVERSAL_1_6: case SPV_ENV_VULKAN_1_3: + case SPV_ENV_VULKAN_1_4: return false; case SPV_ENV_OPENGL_4_0: case SPV_ENV_OPENGL_4_1: @@ -406,6 +414,7 @@ bool spvIsValidEnv(spv_target_env env) { case SPV_ENV_VULKAN_1_2: case SPV_ENV_UNIVERSAL_1_6: case SPV_ENV_VULKAN_1_3: + case SPV_ENV_VULKAN_1_4: case SPV_ENV_OPENGL_4_0: case SPV_ENV_OPENGL_4_1: case SPV_ENV_OPENGL_4_2: @@ -442,7 +451,8 @@ std::string spvLogStringForEnv(spv_target_env env) { case SPV_ENV_VULKAN_1_1: case SPV_ENV_VULKAN_1_1_SPIRV_1_4: case SPV_ENV_VULKAN_1_2: - case SPV_ENV_VULKAN_1_3: { + case SPV_ENV_VULKAN_1_3: + case SPV_ENV_VULKAN_1_4: { return "Vulkan"; } case SPV_ENV_UNIVERSAL_1_0: diff --git a/source/table.cpp b/source/table.cpp index 822cefebd7..01df1bc0d8 100644 --- a/source/table.cpp +++ b/source/table.cpp @@ -43,6 +43,7 @@ spv_context spvContextCreate(spv_target_env env) { case SPV_ENV_VULKAN_1_2: case SPV_ENV_UNIVERSAL_1_6: case SPV_ENV_VULKAN_1_3: + case SPV_ENV_VULKAN_1_4: break; default: return nullptr; diff --git a/test/opt/ir_context_test.cpp b/test/opt/ir_context_test.cpp index ce02191373..d499506ea7 100644 --- a/test/opt/ir_context_test.cpp +++ b/test/opt/ir_context_test.cpp @@ -1155,10 +1155,7 @@ struct TargetEnvCompareTestData { using TargetEnvCompareTest = ::testing::TestWithParam; -TEST_P(TargetEnvCompareTest, Case) { - // If new environments are added, then we must update the list of tests. - ASSERT_EQ(SPV_ENV_VULKAN_1_3 + 1, SPV_ENV_MAX); - +TEST_P(TargetEnvCompareTest, IsTargetEnvAtLeast) { const auto& tc = GetParam(); std::unique_ptr module(new Module()); @@ -1422,6 +1419,8 @@ TEST_F(IRContextTest, RemovesMultipleCapabilities) { 1); } +// If new environments are added, then we must update the list of tests. +static_assert(SPV_ENV_VULKAN_1_4 + 1 == SPV_ENV_MAX); INSTANTIATE_TEST_SUITE_P( TestCase, TargetEnvCompareTest, ::testing::Values( @@ -1464,6 +1463,7 @@ INSTANTIATE_TEST_SUITE_P( TargetEnvCompareTestData{SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_1}, TargetEnvCompareTestData{SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_2}, TargetEnvCompareTestData{SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_3}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_0}, TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_4, SPV_ENV_VULKAN_1_1}, TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_5, SPV_ENV_VULKAN_1_1}, TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_VULKAN_1_1}, @@ -1473,6 +1473,7 @@ INSTANTIATE_TEST_SUITE_P( TargetEnvCompareTestData{SPV_ENV_VULKAN_1_2, SPV_ENV_UNIVERSAL_1_3}, TargetEnvCompareTestData{SPV_ENV_VULKAN_1_2, SPV_ENV_UNIVERSAL_1_4}, TargetEnvCompareTestData{SPV_ENV_VULKAN_1_2, SPV_ENV_UNIVERSAL_1_5}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_2, SPV_ENV_VULKAN_1_1}, TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_VULKAN_1_2}, TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_0}, TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_1}, @@ -1480,7 +1481,16 @@ INSTANTIATE_TEST_SUITE_P( TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_3}, TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_4}, TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_5}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_6})); + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_6}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_VULKAN_1_2}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_0}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_1}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_2}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_3}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_4}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_5}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_6}, + TargetEnvCompareTestData{SPV_ENV_VULKAN_1_4, SPV_ENV_VULKAN_1_3})); } // namespace } // namespace opt diff --git a/test/val/val_version_test.cpp b/test/val/val_version_test.cpp index 6b7c4fe840..743567c34f 100644 --- a/test/val/val_version_test.cpp +++ b/test/val/val_version_test.cpp @@ -79,6 +79,7 @@ std::string version(spv_target_env env) { return "1.5"; case SPV_ENV_UNIVERSAL_1_6: case SPV_ENV_VULKAN_1_3: + case SPV_ENV_VULKAN_1_4: return "1.6"; default: return "0"; @@ -117,6 +118,7 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_VULKAN_1_1_SPIRV_1_4,vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_VULKAN_1_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_0, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_1, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_2, vulkan_spirv, true), @@ -135,6 +137,7 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_VULKAN_1_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), @@ -153,6 +156,7 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), @@ -171,6 +175,7 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), @@ -189,6 +194,7 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_4, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_4, SPV_ENV_VULKAN_1_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_4, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_UNIVERSAL_1_4, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_4, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_4, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_4, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), @@ -207,6 +213,7 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_5, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_5, SPV_ENV_VULKAN_1_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_5, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_UNIVERSAL_1_5, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_5, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_5, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_5, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), @@ -225,6 +232,7 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_6, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_6, SPV_ENV_VULKAN_1_2, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_6, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_UNIVERSAL_1_6, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_6, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_6, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_6, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), @@ -248,6 +256,7 @@ INSTANTIATE_TEST_SUITE_P(Vulkan, ValidateVersion, std::make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_OPENGL_4_0, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_OPENGL_4_1, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_OPENGL_4_2, vulkan_spirv, true), @@ -266,6 +275,7 @@ INSTANTIATE_TEST_SUITE_P(Vulkan, ValidateVersion, std::make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), @@ -284,6 +294,7 @@ INSTANTIATE_TEST_SUITE_P(Vulkan, ValidateVersion, std::make_tuple(SPV_ENV_VULKAN_1_1_SPIRV_1_4, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_1_SPIRV_1_4, SPV_ENV_VULKAN_1_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_1_SPIRV_1_4, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_VULKAN_1_1_SPIRV_1_4, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_1_SPIRV_1_4, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_1_SPIRV_1_4, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_1_SPIRV_1_4, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), @@ -302,6 +313,7 @@ INSTANTIATE_TEST_SUITE_P(Vulkan, ValidateVersion, std::make_tuple(SPV_ENV_VULKAN_1_2, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_2, SPV_ENV_VULKAN_1_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_2, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_VULKAN_1_2, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_2, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_2, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_2, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), @@ -320,11 +332,33 @@ INSTANTIATE_TEST_SUITE_P(Vulkan, ValidateVersion, std::make_tuple(SPV_ENV_VULKAN_1_3, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_3, SPV_ENV_VULKAN_1_2, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_3, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_VULKAN_1_3, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), std::make_tuple(SPV_ENV_VULKAN_1_3, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_3, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_3, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), std::make_tuple(SPV_ENV_VULKAN_1_3, SPV_ENV_OPENGL_4_3, vulkan_spirv, false), - std::make_tuple(SPV_ENV_VULKAN_1_3, SPV_ENV_OPENGL_4_5, vulkan_spirv, false) + std::make_tuple(SPV_ENV_VULKAN_1_3, SPV_ENV_OPENGL_4_5, vulkan_spirv, false), + + // Assembling for Vulkan 1.4 produces SPIR-V 1.6 + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_0, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_1, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_2, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_3, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_4, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_5, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_UNIVERSAL_1_6, vulkan_spirv, true), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_VULKAN_1_0, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_VULKAN_1_1, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_VULKAN_1_1_SPIRV_1_4, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_VULKAN_1_2, vulkan_spirv, false), + // Vulkan 1.3 accepts SPIR-V 1.6 + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_VULKAN_1_3, vulkan_spirv, true), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_VULKAN_1_4, vulkan_spirv, true), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_OPENGL_4_0, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_OPENGL_4_3, vulkan_spirv, false), + std::make_tuple(SPV_ENV_VULKAN_1_4, SPV_ENV_OPENGL_4_5, vulkan_spirv, false) ) ); From 4d2f0b40bfe290dea6c6904dafdf7fd8328ba346 Mon Sep 17 00:00:00 2001 From: Cassandra Beckley Date: Thu, 5 Dec 2024 07:17:32 -0800 Subject: [PATCH 26/26] Prepare release (#5905) This is the second release candidate for v2024.4. Includes new commits since September, including Vulkan 1.4 support. --- CHANGES | 7 ++++++- DEPS | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index c671ceb03c..007e9010a3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,16 +1,21 @@ Revision history for SPIRV-Tools -v2024.4 2024-09-19 +v2024.4 2024-12-04 - General - Add FPEncoding operand type. (#5726) - Support SPV_KHR_untyped_pointers (#5736) - add support for SPV_INTEL_global_variable_host_access (#5786) + - Add support for SPV_KHR_compute_shader_derivative (#5817) + - Accept hex representation as binary input (#5870) + - Vulkan 1.4 support (#5899) - Optimizer - Add knowledge of cooperative matrices (#5720) - Add struct-packing pass and unit test. (#5778) - Validator - Validate presence of Stride operand to OpCooperativeMatrix{Load,Store}KHR (#5777) - Update sampled image validation (#5789) + - Disallow stores according to VUID 06924 (#5368) + - Add validation for SPV_NV_tensor_addressing and SPV_NV_cooperative_matrix2 (#5865) - Linker - allow linking functions with different pointer arguments (#5534) diff --git a/DEPS b/DEPS index ea86b4cf48..a119d1a4ec 100644 --- a/DEPS +++ b/DEPS @@ -3,7 +3,7 @@ use_relative_paths = True vars = { 'github': 'https://github.com', - 'abseil_revision': 'c7cf999bda8390d2dd294ef903716a80135e6f4c', + 'abseil_revision': '7316f5616bad0a794b2a75901cc20b0099718085', 'effcee_revision': '2c97e5689ed8d7ab6ae5820f884f03a601ae124b', @@ -14,7 +14,7 @@ vars = { 're2_revision': '6dcd83d60f7944926bfd308cc13979fc53dd69ca', - 'spirv_headers_revision': '36d5e2ddaa54c70d2f29081510c66f4fc98e5e53', + 'spirv_headers_revision': '3f17b2af6784bfa2c5aa5dbb8e0e74a607dd8b3b', } deps = {