diff --git a/DEPS b/DEPS index da4846c756..8b340ab546 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 're2_revision': '6dcd83d60f7944926bfd308cc13979fc53dd69ca', - 'spirv_headers_revision': 'd92cf88c371424591115a87499009dfad41b669c', + 'spirv_headers_revision': '07ddb1c0f1ffa929262d4568481a692bb0fb1535', } deps = { @@ -37,4 +37,3 @@ deps = { Var('github') + '/KhronosGroup/SPIRV-Headers.git@' + Var('spirv_headers_revision'), } - diff --git a/source/name_mapper.cpp b/source/name_mapper.cpp index 7e5f091740..24c24e2c73 100644 --- a/source/name_mapper.cpp +++ b/source/name_mapper.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2016 Google Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -241,6 +243,10 @@ spv_result_t FriendlyNameMapper::ParseInstruction( SaveName(result_id, std::string("_runtimearr_") + NameForId(inst.words[2])); break; + case spv::Op::OpTypeNodePayloadArrayAMDX: + SaveName(result_id, + std::string("_payloadarr_") + NameForId(inst.words[2])); + break; case spv::Op::OpTypePointer: SaveName(result_id, std::string("_ptr_") + NameForEnumOperand(SPV_OPERAND_TYPE_STORAGE_CLASS, diff --git a/source/opcode.cpp b/source/opcode.cpp index ea03bd6711..a6fb4e783d 100644 --- a/source/opcode.cpp +++ b/source/opcode.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2015-2022 The Khronos Group Inc. -// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights -// reserved. +// Modifications Copyright (C) 2020-2024 Advanced Micro Devices, Inc. All +// rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -265,12 +265,14 @@ int32_t spvOpcodeIsConstant(const spv::Op opcode) { case spv::Op::OpConstantSampler: case spv::Op::OpConstantNull: case spv::Op::OpConstantFunctionPointerINTEL: + case spv::Op::OpConstantStringAMDX: case spv::Op::OpSpecConstantTrue: case spv::Op::OpSpecConstantFalse: case spv::Op::OpSpecConstant: case spv::Op::OpSpecConstantComposite: case spv::Op::OpSpecConstantCompositeReplicateEXT: case spv::Op::OpSpecConstantOp: + case spv::Op::OpSpecConstantStringAMDX: return true; default: return false; @@ -318,6 +320,7 @@ bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode) { case spv::Op::OpFunctionParameter: case spv::Op::OpImageTexelPointer: case spv::Op::OpCopyObject: + case spv::Op::OpAllocateNodePayloadsAMDX: case spv::Op::OpSelect: case spv::Op::OpPhi: case spv::Op::OpFunctionCall: @@ -344,6 +347,7 @@ int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) { case spv::Op::OpImageTexelPointer: case spv::Op::OpCopyObject: case spv::Op::OpRawAccessChainNV: + case spv::Op::OpAllocateNodePayloadsAMDX: return true; default: return false; @@ -382,6 +386,7 @@ int32_t spvOpcodeGeneratesType(spv::Op op) { case spv::Op::OpTypeRayQueryKHR: case spv::Op::OpTypeHitObjectNV: case spv::Op::OpTypeUntypedPointerKHR: + case spv::Op::OpTypeNodePayloadArrayAMDX: return true; default: // In particular, OpTypeForwardPointer does not generate a type, diff --git a/source/opt/fix_storage_class.cpp b/source/opt/fix_storage_class.cpp index b64026e6a5..608285e663 100644 --- a/source/opt/fix_storage_class.cpp +++ b/source/opt/fix_storage_class.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2019 Google LLC +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -99,6 +101,7 @@ bool FixStorageClass::PropagateStorageClass(Instruction* inst, case spv::Op::OpCopyMemorySized: case spv::Op::OpVariable: case spv::Op::OpBitcast: + case spv::Op::OpAllocateNodePayloadsAMDX: // Nothing to change for these opcode. The result type is the same // regardless of the storage class of the operand. return false; @@ -319,6 +322,7 @@ uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) { switch (type_inst->opcode()) { case spv::Op::OpTypeArray: case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeNodePayloadArrayAMDX: case spv::Op::OpTypeMatrix: case spv::Op::OpTypeVector: case spv::Op::OpTypeCooperativeMatrixKHR: diff --git a/source/opt/ir_context.cpp b/source/opt/ir_context.cpp index d864b7c02e..c36b8fdee7 100644 --- a/source/opt/ir_context.cpp +++ b/source/opt/ir_context.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2017 Google Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -539,6 +541,7 @@ void IRContext::AddCombinatorsForCapability(uint32_t capability) { (uint32_t)spv::Op::OpTypeHitObjectNV, (uint32_t)spv::Op::OpTypeArray, (uint32_t)spv::Op::OpTypeRuntimeArray, + (uint32_t)spv::Op::OpTypeNodePayloadArrayAMDX, (uint32_t)spv::Op::OpTypeStruct, (uint32_t)spv::Op::OpTypeOpaque, (uint32_t)spv::Op::OpTypePointer, diff --git a/source/opt/local_access_chain_convert_pass.cpp b/source/opt/local_access_chain_convert_pass.cpp index ad0277474e..8f24d9df9d 100644 --- a/source/opt/local_access_chain_convert_pass.cpp +++ b/source/opt/local_access_chain_convert_pass.cpp @@ -1,6 +1,8 @@ // Copyright (c) 2017 The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -430,7 +432,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_AMDX_shader_enqueue"}); } 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..708b3286d3 100644 --- a/source/opt/local_single_block_elim_pass.cpp +++ b/source/opt/local_single_block_elim_pass.cpp @@ -1,6 +1,8 @@ // Copyright (c) 2017 The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -238,6 +240,7 @@ void LocalSingleBlockLoadStoreElimPass::InitExtensions() { "SPV_AMD_gcn_shader", "SPV_KHR_shader_ballot", "SPV_AMD_shader_ballot", + "SPV_AMDX_shader_enqueue", "SPV_AMD_gpu_shader_half_float", "SPV_KHR_shader_draw_parameters", "SPV_KHR_subgroup_vote", diff --git a/source/opt/local_single_store_elim_pass.cpp b/source/opt/local_single_store_elim_pass.cpp index bb7bba87eb..4c15815fea 100644 --- a/source/opt/local_single_store_elim_pass.cpp +++ b/source/opt/local_single_store_elim_pass.cpp @@ -1,6 +1,8 @@ // Copyright (c) 2017 The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -144,7 +146,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_AMDX_shader_enqueue"}); } bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) { std::vector users; diff --git a/source/opt/scalar_replacement_pass.cpp b/source/opt/scalar_replacement_pass.cpp index 38c8aeccc6..ff81fae3ff 100644 --- a/source/opt/scalar_replacement_pass.cpp +++ b/source/opt/scalar_replacement_pass.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2017 Google Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -671,7 +673,8 @@ bool ScalarReplacementPass::CheckTypeAnnotations( for (auto inst : get_decoration_mgr()->GetDecorationsFor(typeInst->result_id(), false)) { uint32_t decoration; - if (inst->opcode() == spv::Op::OpDecorate) { + if (inst->opcode() == spv::Op::OpDecorate || + inst->opcode() == spv::Op::OpDecorateId) { decoration = inst->GetSingleWordInOperand(1u); } else { assert(inst->opcode() == spv::Op::OpMemberDecorate); diff --git a/source/opt/type_manager.cpp b/source/opt/type_manager.cpp index 79648ad497..0d1c37e584 100644 --- a/source/opt/type_manager.cpp +++ b/source/opt/type_manager.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2016 Google Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -335,6 +337,17 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { std::initializer_list{{SPV_OPERAND_TYPE_ID, {subtype}}}); break; } + case Type::kNodePayloadArrayAMDX: { + uint32_t subtype = + GetTypeInstruction(type->AsNodePayloadArrayAMDX()->element_type()); + if (subtype == 0) { + return 0; + } + typeInst = MakeUnique( + context(), spv::Op::OpTypeNodePayloadArrayAMDX, 0, id, + std::initializer_list{{SPV_OPERAND_TYPE_ID, {subtype}}}); + break; + } case Type::kStruct: { std::vector ops; const Struct* structTy = type->AsStruct(); @@ -601,6 +614,13 @@ Type* TypeManager::RebuildType(uint32_t type_id, const Type& type) { MakeUnique(RebuildType(GetId(ele_ty), *ele_ty)); break; } + case Type::kNodePayloadArrayAMDX: { + const NodePayloadArrayAMDX* array_ty = type.AsNodePayloadArrayAMDX(); + const Type* ele_ty = array_ty->element_type(); + rebuilt_ty = + MakeUnique(RebuildType(GetId(ele_ty), *ele_ty)); + break; + } case Type::kStruct: { const Struct* struct_ty = type.AsStruct(); std::vector subtypes; @@ -803,6 +823,14 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { return type; } break; + case spv::Op::OpTypeNodePayloadArrayAMDX: + type = new NodePayloadArrayAMDX(GetType(inst.GetSingleWordInOperand(0))); + if (id_to_incomplete_type_.count(inst.GetSingleWordInOperand(0))) { + incomplete_types_.emplace_back(inst.result_id(), type); + id_to_incomplete_type_[inst.result_id()] = type; + return type; + } + break; case spv::Op::OpTypeStruct: { std::vector element_types; bool incomplete_type = false; @@ -940,7 +968,8 @@ void TypeManager::AttachDecoration(const Instruction& inst, Type* type) { if (!IsAnnotationInst(opcode)) return; switch (opcode) { - case spv::Op::OpDecorate: { + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: { const auto count = inst.NumOperands(); std::vector data; for (uint32_t i = 1; i < count; ++i) { diff --git a/source/opt/types.cpp b/source/opt/types.cpp index b18b8cb1ae..cfeb42927c 100644 --- a/source/opt/types.cpp +++ b/source/opt/types.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2016 Google Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -90,6 +92,7 @@ bool Type::IsUniqueType() const { case kStruct: case kArray: case kRuntimeArray: + case kNodePayloadArrayAMDX: return false; default: return true; @@ -162,6 +165,7 @@ bool Type::operator==(const Type& other) const { DeclareKindCase(SampledImage); DeclareKindCase(Array); DeclareKindCase(RuntimeArray); + DeclareKindCase(NodePayloadArrayAMDX); DeclareKindCase(Struct); DeclareKindCase(Opaque); DeclareKindCase(Pointer); @@ -218,6 +222,7 @@ size_t Type::ComputeHashValue(size_t hash, SeenTypes* seen) const { DeclareKindCase(SampledImage); DeclareKindCase(Array); DeclareKindCase(RuntimeArray); + DeclareKindCase(NodePayloadArrayAMDX); DeclareKindCase(Struct); DeclareKindCase(Opaque); DeclareKindCase(Pointer); @@ -485,6 +490,34 @@ void RuntimeArray::ReplaceElementType(const Type* type) { element_type_ = type; } +NodePayloadArrayAMDX::NodePayloadArrayAMDX(const Type* type) + : Type(kNodePayloadArrayAMDX), element_type_(type) { + assert(!type->AsVoid()); +} + +bool NodePayloadArrayAMDX::IsSameImpl(const Type* that, + IsSameCache* seen) const { + const NodePayloadArrayAMDX* rat = that->AsNodePayloadArrayAMDX(); + if (!rat) return false; + return element_type_->IsSameImpl(rat->element_type_, seen) && + HasSameDecorations(that); +} + +std::string NodePayloadArrayAMDX::str() const { + std::ostringstream oss; + oss << "[" << element_type_->str() << "]"; + return oss.str(); +} + +size_t NodePayloadArrayAMDX::ComputeExtraStateHash(size_t hash, + SeenTypes* seen) const { + return element_type_->ComputeHashValue(hash, seen); +} + +void NodePayloadArrayAMDX::ReplaceElementType(const Type* type) { + element_type_ = type; +} + Struct::Struct(const std::vector& types) : Type(kStruct), element_types_(types) { for (const auto* t : types) { diff --git a/source/opt/types.h b/source/opt/types.h index 16a948cec5..27089a171c 100644 --- a/source/opt/types.h +++ b/source/opt/types.h @@ -1,4 +1,6 @@ // Copyright (c) 2016 Google Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -46,6 +48,7 @@ class Sampler; class SampledImage; class Array; class RuntimeArray; +class NodePayloadArrayAMDX; class Struct; class Opaque; class Pointer; @@ -87,6 +90,7 @@ class Type { kSampledImage, kArray, kRuntimeArray, + kNodePayloadArrayAMDX, kStruct, kOpaque, kPointer, @@ -189,6 +193,7 @@ class Type { DeclareCastMethod(SampledImage) DeclareCastMethod(Array) DeclareCastMethod(RuntimeArray) + DeclareCastMethod(NodePayloadArrayAMDX) DeclareCastMethod(Struct) DeclareCastMethod(Opaque) DeclareCastMethod(Pointer) @@ -434,6 +439,29 @@ class RuntimeArray : public Type { const Type* element_type_; }; +class NodePayloadArrayAMDX : public Type { + public: + NodePayloadArrayAMDX(const Type* element_type); + NodePayloadArrayAMDX(const NodePayloadArrayAMDX&) = default; + + std::string str() const override; + const Type* element_type() const { return element_type_; } + + NodePayloadArrayAMDX* AsNodePayloadArrayAMDX() override { return this; } + const NodePayloadArrayAMDX* AsNodePayloadArrayAMDX() const override { + return this; + } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + void ReplaceElementType(const Type* element_type); + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const Type* element_type_; +}; + class Struct : public Type { public: Struct(const std::vector& element_types); diff --git a/source/val/validate_annotation.cpp b/source/val/validate_annotation.cpp index cf6f96b8b0..243ccc8121 100644 --- a/source/val/validate_annotation.cpp +++ b/source/val/validate_annotation.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2018 Google LLC. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,6 +32,11 @@ bool DecorationTakesIdParameters(spv::Decoration type) { case spv::Decoration::AlignmentId: case spv::Decoration::MaxByteOffsetId: case spv::Decoration::HlslCounterBufferGOOGLE: + case spv::Decoration::NodeMaxPayloadsAMDX: + case spv::Decoration::NodeSharesPayloadLimitsWithAMDX: + case spv::Decoration::PayloadNodeArraySizeAMDX: + case spv::Decoration::PayloadNodeNameAMDX: + case spv::Decoration::PayloadNodeBaseIndexAMDX: return true; default: break; diff --git a/source/val/validate_composites.cpp b/source/val/validate_composites.cpp index 26486dac70..c08eb2d2e8 100644 --- a/source/val/validate_composites.cpp +++ b/source/val/validate_composites.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2017 Google Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -104,7 +106,8 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, } break; } - case spv::Op::OpTypeRuntimeArray: { + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeNodePayloadArrayAMDX: { *member_type = type_inst->word(2); // Array size is unknown. break; diff --git a/source/val/validate_function.cpp b/source/val/validate_function.cpp index 26b3668282..34e22fc9e3 100644 --- a/source/val/validate_function.cpp +++ b/source/val/validate_function.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2018 Google LLC. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -302,6 +304,7 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, case spv::StorageClass::Private: case spv::StorageClass::Workgroup: case spv::StorageClass::AtomicCounter: + case spv::StorageClass::NodePayloadAMDX: // These are always allowed. break; case spv::StorageClass::StorageBuffer: diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp index 830c3ea119..038128a0c4 100644 --- a/source/val/validate_memory.cpp +++ b/source/val/validate_memory.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2018 Google LLC. -// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights -// reserved. +// Modifications Copyright (C) 2020-2024 Advanced Micro Devices, Inc. All +// rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -492,7 +492,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { storage_class != spv::StorageClass::CallableDataKHR && storage_class != spv::StorageClass::IncomingCallableDataKHR && storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT && - storage_class != spv::StorageClass::HitObjectAttributeNV) { + storage_class != spv::StorageClass::HitObjectAttributeNV && + storage_class != spv::StorageClass::NodePayloadAMDX) { bool storage_input_or_output = storage_class == spv::StorageClass::Input || storage_class == spv::StorageClass::Output; bool builtin = false; @@ -520,7 +521,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { "Classes: Workgroup, CrossWorkgroup, Private, Function, " "Input, Output, RayPayloadKHR, IncomingRayPayloadKHR, " "HitAttributeKHR, CallableDataKHR, " - "IncomingCallableDataKHR, or UniformConstant"; + "IncomingCallableDataKHR, NodePayloadAMDX, or " + "UniformConstant"; } } } @@ -1594,7 +1596,8 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, case spv::Op::OpTypeCooperativeMatrixNV: case spv::Op::OpTypeCooperativeMatrixKHR: case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: { + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeNodePayloadArrayAMDX: { // In OpTypeMatrix, OpTypeVector, spv::Op::OpTypeCooperativeMatrixNV, // OpTypeArray, and OpTypeRuntimeArray, word 2 is the Element Type. type_pointee = _.FindDef(type_pointee->word(2)); diff --git a/source/val/validate_mode_setting.cpp b/source/val/validate_mode_setting.cpp index 8502fda534..9287c46f1a 100644 --- a/source/val/validate_mode_setting.cpp +++ b/source/val/validate_mode_setting.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2018 Google LLC. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -347,6 +349,12 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, case spv::ExecutionMode::LocalSizeId: case spv::ExecutionMode::FPFastMathDefault: case spv::ExecutionMode::MaximumRegistersIdINTEL: + case spv::ExecutionMode::IsApiEntryAMDX: + case spv::ExecutionMode::MaxNodeRecursionAMDX: + case spv::ExecutionMode::MaxNumWorkgroupsAMDX: + case spv::ExecutionMode::ShaderIndexAMDX: + case spv::ExecutionMode::SharesInputWithAMDX: + case spv::ExecutionMode::StaticNumWorkgroupsAMDX: valid_mode = true; break; default: @@ -368,6 +376,12 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, case spv::ExecutionMode::SubgroupsPerWorkgroupId: case spv::ExecutionMode::LocalSizeHintId: case spv::ExecutionMode::LocalSizeId: + case spv::ExecutionMode::IsApiEntryAMDX: + case spv::ExecutionMode::MaxNodeRecursionAMDX: + case spv::ExecutionMode::MaxNumWorkgroupsAMDX: + case spv::ExecutionMode::ShaderIndexAMDX: + case spv::ExecutionMode::SharesInputWithAMDX: + case spv::ExecutionMode::StaticNumWorkgroupsAMDX: if (!spvOpcodeIsConstant(operand_inst->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "For OpExecutionModeId all Extra Operand ids must be " @@ -426,7 +440,13 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, } else if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId || mode == spv::ExecutionMode::LocalSizeHintId || mode == spv::ExecutionMode::LocalSizeId || - mode == spv::ExecutionMode::FPFastMathDefault) { + mode == spv::ExecutionMode::FPFastMathDefault || + mode == spv::ExecutionMode::IsApiEntryAMDX || + mode == spv::ExecutionMode::MaxNodeRecursionAMDX || + mode == spv::ExecutionMode::MaxNumWorkgroupsAMDX || + mode == spv::ExecutionMode::ShaderIndexAMDX || + mode == spv::ExecutionMode::SharesInputWithAMDX || + mode == spv::ExecutionMode::StaticNumWorkgroupsAMDX) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "OpExecutionMode is only valid when the Mode operand is an " "execution mode that takes no Extra Operands, or takes Extra " diff --git a/source/val/validate_type.cpp b/source/val/validate_type.cpp index 32024b7356..39ad675e09 100644 --- a/source/val/validate_type.cpp +++ b/source/val/validate_type.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2018 Google LLC. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,6 +37,7 @@ spv_result_t ValidateUniqueness(ValidationState_t& _, const Instruction* inst) { const auto opcode = inst->opcode(); if (opcode != spv::Op::OpTypeArray && opcode != spv::Op::OpTypeRuntimeArray && + opcode != spv::Op::OpTypeNodePayloadArrayAMDX && opcode != spv::Op::OpTypeStruct && opcode != spv::Op::OpTypePointer && opcode != spv::Op::OpTypeUntypedPointerKHR && !_.RegisterUniqueTypeDeclaration(inst)) { diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp index 2afcacc337..fac16b200d 100644 --- a/source/val/validation_state.cpp +++ b/source/val/validation_state.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2015-2016 The Khronos Group Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -1185,6 +1187,7 @@ bool ValidationState_t::GetStructMemberTypes( } bool ValidationState_t::IsPointerType(uint32_t id) const { + if (!id) return false; const Instruction* inst = FindDef(id); assert(inst); return inst->opcode() == spv::Op::OpTypePointer || @@ -1771,6 +1774,7 @@ bool ValidationState_t::IsValidStorageClass( case spv::StorageClass::TaskPayloadWorkgroupEXT: case spv::StorageClass::HitObjectAttributeNV: case spv::StorageClass::TileImageEXT: + case spv::StorageClass::NodePayloadAMDX: return true; default: return false; diff --git a/test/opt/type_manager_test.cpp b/test/opt/type_manager_test.cpp index d4d0fef524..5469244c02 100644 --- a/test/opt/type_manager_test.cpp +++ b/test/opt/type_manager_test.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2016 Google Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -175,6 +177,10 @@ std::vector> GenerateAllTypes() { types.emplace_back(new RayQueryKHR()); types.emplace_back(new HitObjectNV()); + // NodePayloadArrayAMDX (SPV_AMDX_shader_enqueue) + types.emplace_back( + new NodePayloadArrayAMDX(new Struct(std::vector{s32}))); + return types; } diff --git a/test/val/val_id_test.cpp b/test/val/val_id_test.cpp index 1e050183b2..63de09f185 100644 --- a/test/val/val_id_test.cpp +++ b/test/val/val_id_test.cpp @@ -1,4 +1,6 @@ // Copyright (c) 2015-2016 The Khronos Group Inc. +// Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights +// reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -2469,7 +2471,8 @@ OpFunctionEnd "be used with non-externally visible shader Storage Classes: " "Workgroup, CrossWorkgroup, Private, Function, Input, Output, " "RayPayloadKHR, IncomingRayPayloadKHR, HitAttributeKHR, " - "CallableDataKHR, IncomingCallableDataKHR, or UniformConstant"))); + "CallableDataKHR, IncomingCallableDataKHR, NodePayloadAMDX, or " + "UniformConstant"))); } TEST_P(ValidateIdWithMessage, OpVariableContainsBoolPrivateGood) {