diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp index a9ae36446..830c3ea11 100644 --- a/source/val/validate_memory.cpp +++ b/source/val/validate_memory.cpp @@ -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; } diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp index 6f425310c..2afcacc33 100644 --- a/source/val/validation_state.cpp +++ b/source/val/validation_state.cpp @@ -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: diff --git a/test/val/val_memory_test.cpp b/test/val/val_memory_test.cpp index df92fff4c..ae78b1450 100644 --- a/test/val/val_memory_test.cpp +++ b/test/val/val_memory_test.cpp @@ -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