diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp index 4f3d9cdb7..01285489f 100644 --- a/source/val/validate_memory.cpp +++ b/source/val/validate_memory.cpp @@ -519,20 +519,21 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } } - // Vulkan 14.5.1: Check type of PushConstant variables. - // Vulkan 14.5.2: Check type of UniformConstant and Uniform variables. if (spvIsVulkanEnv(_.context()->target_env)) { + // Vulkan Push Constant Interface section: Check type of PushConstant + // variables. if (storage_class == SpvStorageClassPushConstant) { - if (!IsAllowedTypeOrArrayOfSame(_, pointee, {SpvOpTypeStruct})) { + if (pointee->opcode() != SpvOpTypeStruct) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "PushConstant OpVariable '" << _.getIdName(inst->id()) << "' has illegal type.\n" - << "From Vulkan spec, section 14.5.1:\n" - << "Such variables must be typed as OpTypeStruct, " - << "or an array of this type"; + << "From Vulkan spec, Push Constant Interface section:\n" + << "Such variables must be typed as OpTypeStruct"; } } + // Vulkan Descriptor Set Interface: Check type of UniformConstant and + // Uniform variables. if (storage_class == SpvStorageClassUniformConstant) { if (!IsAllowedTypeOrArrayOfSame( _, pointee, diff --git a/test/val/val_memory_test.cpp b/test/val/val_memory_test.cpp index 7215974a6..d368a89cf 100644 --- a/test/val/val_memory_test.cpp +++ b/test/val/val_memory_test.cpp @@ -833,11 +833,45 @@ TEST_F(ValidateMemory, VulkanPushConstantNotStructBad) { )"; CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("PushConstant OpVariable '6[%6]' has illegal " - "type.\nFrom Vulkan spec, section 14.5.1:\n" - "Such variables must be typed as OpTypeStruct, " - "or an array of this type")); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("PushConstant OpVariable '6[%6]' has illegal " + "type.\nFrom Vulkan spec, Push Constant Interface section:\n" + "Such variables must be typed as OpTypeStruct")); +} + +TEST_F(ValidateMemory, VulkanPushConstantArrayOfStructBad) { + std::string spirv = R"( + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %1 "main" + OpExecutionMode %1 OriginUpperLeft + + OpDecorate %struct Block + OpMemberDecorate %struct 0 Offset 0 + + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + %float = OpTypeFloat 32 + %int = OpTypeInt 32 0 + %int_1 = OpConstant %int 1 + %struct = OpTypeStruct %float + %array = OpTypeArray %struct %int_1 + %ptr = OpTypePointer PushConstant %array + %pc = OpVariable %ptr PushConstant + + %1 = OpFunction %void None %voidfn + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("PushConstant OpVariable '10[%10]' has illegal " + "type.\nFrom Vulkan spec, Push Constant Interface section:\n" + "Such variables must be typed as OpTypeStruct")); } TEST_F(ValidateMemory, VulkanPushConstant) {