diff --git a/source/val/validate_annotation.cpp b/source/val/validate_annotation.cpp index b8ac6cb87a..5a11f92f05 100644 --- a/source/val/validate_annotation.cpp +++ b/source/val/validate_annotation.cpp @@ -53,9 +53,10 @@ bool IsMemberDecorationOnly(spv::Decoration dec) { case spv::Decoration::RowMajor: case spv::Decoration::ColMajor: case spv::Decoration::MatrixStride: - // SPIR-V spec bug? Offset is generated on variables when dealing with - // transform feedback. - // case spv::Decoration::Offset: + // Spec ambiguity where this is allowed or not currently + // See https://gitlab.khronos.org/spirv/SPIR-V/-/issues/937 + // case spv::Decoration::Offset: + case spv::Decoration::OffsetIdEXT: return true; default: break; @@ -409,11 +410,12 @@ spv_result_t ValidateDecorateId(ValidationState_t& _, const Instruction* inst) { } } - // No member decorations take id parameters, so we don't bother checking if - // we are using a member only decoration here. + if (IsMemberDecorationOnly(decoration)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.SpvDecorationString(decoration) + << " can only be applied to structure members"; + } - // TODO: Add validations for these decorations. - // UniformId is covered elsewhere. return SPV_SUCCESS; } diff --git a/test/val/val_extension_spv_ext_descriptor_heap.cpp b/test/val/val_extension_spv_ext_descriptor_heap.cpp index e387546fe0..ce6c1fe3db 100644 --- a/test/val/val_extension_spv_ext_descriptor_heap.cpp +++ b/test/val/val_extension_spv_ext_descriptor_heap.cpp @@ -2417,6 +2417,47 @@ TEST_F(ValidateSpvEXTDescriptorHeap, ArrayStrideSpecConstantZero) { EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_4)); } +// https://github.com/KhronosGroup/SPIRV-Tools/issues/6696 +TEST_F(ValidateSpvEXTDescriptorHeap, OffsetIdOnArray) { + const std::string str = R"( + OpCapability Shader + OpCapability UntypedPointersKHR + OpCapability DescriptorHeapEXT + OpCapability Sampled1D + OpExtension "SPV_KHR_untyped_pointers" + OpExtension "SPV_EXT_descriptor_heap" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %1 "main" %2 + OpExecutionMode %1 LocalSize 1 1 1 + OpDecorate %2 BuiltIn ResourceHeapEXT + OpDecorateId %7 OffsetIdEXT %4 + %11 = OpTypeVoid + %12 = OpTypeFunction %11 + %13 = OpTypeInt 32 0 + %16 = OpConstant %13 0 + %4 = OpConstant %13 0 + %20 = OpTypeImage %13 1D 0 0 0 1 Unknown + %21 = OpTypeBufferEXT StorageBuffer + %22 = OpTypeSampler + %23 = OpTypeSampledImage %20 + %7 = OpTypeRuntimeArray %20 + %24 = OpTypeUntypedPointerKHR UniformConstant + %25 = OpTypeUntypedPointerKHR StorageBuffer + %2 = OpUntypedVariableKHR %24 UniformConstant + %1 = OpFunction %11 None %12 + %26 = OpLabel + %27 = OpUntypedAccessChainKHR %24 %7 %2 %16 + %28 = OpLoad %20 %27 + OpReturn + OpFunctionEnd + )"; + CompileSuccessfully(str.c_str(), SPV_ENV_VULKAN_1_4); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_4)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OffsetIdEXT can only be applied to structure members")); +} + } // namespace } // namespace val } // namespace spvtools