spirv-val: Disallow stores according to VUID 06924 (#5368)

Ensure that the validator rejects stores to objects of types
`OpTypeImage`, `OpTypeSampler`, `OpTypeSampledImage`,
`OpTypeAccelerationStructureKHR`, and arrays of these types, according
to `VUID-StandaloneSpirv-OpTypeImage-06924`.

Guard the check behind the before_hlsl_legalization option, as
sometimes we may have temporaries or local variables that are expected
to get optimized away.

Fixes #4796


Change-Id: Ie035c01c5f94e7bdfc16b5c6c85705f302b7bda3

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
This commit is contained in:
Sven van Haastregt 2024-09-23 14:34:30 +02:00 committed by GitHub
parent 01c8438ee4
commit 7ba72f14f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 171 additions and 0 deletions

View File

@ -1165,6 +1165,23 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) {
}
}
if (spvIsVulkanEnv(_.context()->target_env) &&
!_.options()->before_hlsl_legalization) {
const auto isForbiddenType = [](const Instruction* type_inst) {
auto opcode = type_inst->opcode();
return opcode == spv::Op::OpTypeImage ||
opcode == spv::Op::OpTypeSampler ||
opcode == spv::Op::OpTypeSampledImage ||
opcode == spv::Op::OpTypeAccelerationStructureKHR;
};
if (_.ContainsType(object_type->id(), isForbiddenType)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< _.VkErrorID(6924)
<< "Cannot store to OpTypeImage, OpTypeSampler, "
"OpTypeSampledImage, or OpTypeAccelerationStructureKHR objects";
}
}
return SPV_SUCCESS;
}

View File

@ -2368,6 +2368,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06807);
case 6808:
return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06808);
case 6924:
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-06924);
case 6925:
return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06925);
case 7041:

View File

@ -3934,6 +3934,158 @@ OpMemoryModel Logical GLSL450
HasSubstr("Initializer type must match the data type"));
}
TEST_F(ValidateMemory, StoreToImage) {
const std::string spirv = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%void = OpTypeVoid
%int = OpTypeInt 32 0
%img = OpTypeImage %int 2D 2 0 0 2 R32i
%ptr_img = OpTypePointer Function %img
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%entry = OpLabel
%var = OpVariable %ptr_img Function
%value = OpLoad %img %var
OpStore %var %value
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06924"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Cannot store to OpTypeImage, OpTypeSampler, "
"OpTypeSampledImage, or OpTypeAccelerationStructureKHR"));
}
TEST_F(ValidateMemory, StoreToImageArray) {
const std::string spirv = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%void = OpTypeVoid
%int = OpTypeInt 32 0
%img = OpTypeImage %int 2D 2 0 0 2 R32i
%arr_size = OpConstant %int 5
%i = OpConstant %int 2
%arr_img = OpTypeArray %img %arr_size
%ptr_img = OpTypePointer Function %img
%ptr_arr_img = OpTypePointer Function %arr_img
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%entry = OpLabel
%var = OpVariable %ptr_arr_img Function
%value = OpLoad %arr_img %var
OpStore %var %value
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06924"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Cannot store to OpTypeImage, OpTypeSampler, "
"OpTypeSampledImage, or OpTypeAccelerationStructureKHR"));
}
TEST_F(ValidateMemory, StoreToSampler) {
const std::string spirv = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%void = OpTypeVoid
%smp = OpTypeSampler
%ptr_smp = OpTypePointer Function %smp
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%entry = OpLabel
%var = OpVariable %ptr_smp Function
%value = OpLoad %smp %var
OpStore %var %value
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06924"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Cannot store to OpTypeImage, OpTypeSampler, "
"OpTypeSampledImage, or OpTypeAccelerationStructureKHR"));
}
TEST_F(ValidateMemory, StoreToSampledImage) {
const std::string spirv = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%void = OpTypeVoid
%int = OpTypeInt 32 0
%img = OpTypeImage %int 2D 2 0 0 1 R32i
%samp_img = OpTypeSampledImage %img
%ptr_samp_img = OpTypePointer Function %samp_img
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%entry = OpLabel
%var = OpVariable %ptr_samp_img Function
%value = OpLoad %samp_img %var
OpStore %var %value
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06924"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Cannot store to OpTypeImage, OpTypeSampler, "
"OpTypeSampledImage, or OpTypeAccelerationStructureKHR"));
}
TEST_F(ValidateMemory, StoreToAccelarationStructureKHR) {
const std::string spirv = R"(
OpCapability Shader
OpCapability RayQueryKHR
OpExtension "SPV_KHR_ray_query"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%void = OpTypeVoid
%as = OpTypeAccelerationStructureKHR
%ptr_as = OpTypePointer Function %as
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%entry = OpLabel
%var = OpVariable %ptr_as Function
%value = OpLoad %as %var
OpStore %var %value
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06924"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Cannot store to OpTypeImage, OpTypeSampler, "
"OpTypeSampledImage, or OpTypeAccelerationStructureKHR"));
}
TEST_F(ValidateMemory, StoreToUniformBlock) {
const std::string spirv = R"(
OpCapability Shader