diff options
author | sfricke-samsung <46493288+sfricke-samsung@users.noreply.github.com> | 2022-03-10 12:08:26 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-10 13:08:26 -0500 |
commit | 7963fa13c7966b6e8a252dce60f633ed81505ea8 (patch) | |
tree | 5d3b08d04423d7507f336028d90d8b223ad8670e | |
parent | 5c9d55a59a054bf73d5d33638d26c2919e18daf5 (diff) | |
download | spirv-tools-7963fa13c7966b6e8a252dce60f633ed81505ea8.tar.gz |
spirv-val: Add Vulkan Dref not allowed 3D dim VUID (#4751)
-rw-r--r-- | source/val/validate_image.cpp | 36 | ||||
-rw-r--r-- | source/val/validation_state.cpp | 2 | ||||
-rw-r--r-- | test/val/val_image_test.cpp | 47 |
3 files changed, 73 insertions, 12 deletions
diff --git a/source/val/validate_image.cpp b/source/val/validate_image.cpp index fc7a960f..c06f3417 100644 --- a/source/val/validate_image.cpp +++ b/source/val/validate_image.cpp @@ -1276,6 +1276,27 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { return SPV_SUCCESS; } +// Validates anything OpImage*Dref* instruction +spv_result_t ValidateImageDref(ValidationState_t& _, const Instruction* inst, + const ImageTypeInfo& info) { + const uint32_t dref_type = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Dref to be of 32-bit float type"; + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (info.dim == SpvDim3D) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4777) + << "In Vulkan, OpImage*Dref* instructions must not use images " + "with a 3D Dim"; + } + } + + return SPV_SUCCESS; +} + spv_result_t ValidateImageDrefLod(ValidationState_t& _, const Instruction* inst) { const SpvOp opcode = inst->opcode(); @@ -1333,11 +1354,7 @@ spv_result_t ValidateImageDrefLod(ValidationState_t& _, << " components, but given only " << actual_coord_size; } - const uint32_t dref_type = _.GetOperandTypeId(inst, 4); - if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected Dref to be of 32-bit float type"; - } + if (spv_result_t result = ValidateImageDref(_, inst, info)) return result; if (spv_result_t result = ValidateImageOperands(_, inst, info, /* word_index = */ 7)) @@ -1472,7 +1489,8 @@ spv_result_t ValidateImageGather(ValidationState_t& _, if (info.dim != SpvDim2D && info.dim != SpvDimCube && info.dim != SpvDimRect) { return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected Image 'Dim' cannot be Cube"; + << _.VkErrorID(4777) + << "Expected Image 'Dim' to be 2D, Cube, or Rect"; } const uint32_t coord_type = _.GetOperandTypeId(inst, 3); @@ -1508,11 +1526,7 @@ spv_result_t ValidateImageGather(ValidationState_t& _, } else { assert(opcode == SpvOpImageDrefGather || opcode == SpvOpImageSparseDrefGather); - const uint32_t dref_type = _.GetOperandTypeId(inst, 4); - if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected Dref to be of 32-bit float type"; - } + if (spv_result_t result = ValidateImageDref(_, inst, info)) return result; } if (spv_result_t result = diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp index f7acaabe..bc2b6ae5 100644 --- a/source/val/validation_state.cpp +++ b/source/val/validation_state.cpp @@ -1886,6 +1886,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id, return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04733); case 4734: return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04734); + case 4777: + return VUID_WRAP(VUID-StandaloneSpirv-OpImage-04777); case 4780: return VUID_WRAP(VUID-StandaloneSpirv-Result-04780); case 4915: diff --git a/test/val/val_image_test.cpp b/test/val/val_image_test.cpp index dabb905a..87bec223 100644 --- a/test/val/val_image_test.cpp +++ b/test/val/val_image_test.cpp @@ -246,6 +246,11 @@ OpDecorate %input_flat_u32 Location 0 %uniform_image_u32_2d_0001 = OpVariable %ptr_image_u32_2d_0001 UniformConstant %type_sampled_image_u32_2d_0001 = OpTypeSampledImage %type_image_u32_2d_0001 +%type_image_u32_3d_0001 = OpTypeImage %u32 3D 0 0 0 1 Unknown +%ptr_image_u32_3d_0001 = OpTypePointer UniformConstant %type_image_u32_3d_0001 +%uniform_image_u32_3d_0001 = OpVariable %ptr_image_u32_3d_0001 UniformConstant +%type_sampled_image_u32_3d_0001 = OpTypeSampledImage %type_image_u32_3d_0001 + %type_image_u32_2d_0002 = OpTypeImage %u32 2D 0 0 0 2 Unknown %ptr_image_u32_2d_0002 = OpTypePointer UniformConstant %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 = OpVariable %ptr_image_u32_2d_0002 UniformConstant @@ -272,6 +277,11 @@ OpDecorate %input_flat_u32 Location 0 %uniform_image_f32_3d_0111 = OpVariable %ptr_image_f32_3d_0111 UniformConstant %type_sampled_image_f32_3d_0111 = OpTypeSampledImage %type_image_f32_3d_0111 +%type_image_f32_3d_0001 = OpTypeImage %f32 3D 0 0 0 1 Unknown +%ptr_image_f32_3d_0001 = OpTypePointer UniformConstant %type_image_f32_3d_0001 +%uniform_image_f32_3d_0001 = OpVariable %ptr_image_f32_3d_0001 UniformConstant +%type_sampled_image_f32_3d_0001 = OpTypeSampledImage %type_image_f32_3d_0001 + %type_image_f32_cube_0101 = OpTypeImage %f32 Cube 0 1 0 1 Unknown %ptr_image_f32_cube_0101 = OpTypePointer UniformConstant %type_image_f32_cube_0101 %uniform_image_f32_cube_0101 = OpVariable %ptr_image_f32_cube_0101 UniformConstant @@ -1090,7 +1100,7 @@ TEST_F(ValidateImage, ImageTexelPointerImageNotResultTypePointer) { CompileSuccessfully(GenerateShaderCode(body).c_str()); ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 137[%137] cannot be a " + EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 145[%145] cannot be a " "type")); } @@ -2321,6 +2331,24 @@ TEST_F(ValidateImage, SampleDrefImplicitLodWrongDrefType) { HasSubstr("Expected Dref to be of 32-bit float type")); } +TEST_F(ValidateImage, SampleDrefImplicitLodWrongDimVulkan) { + const std::string body = R"( +%img = OpLoad %type_image_u32_3d_0001 %uniform_image_u32_3d_0001 +%sampler = OpLoad %type_sampler %uniform_sampler +%simg = OpSampledImage %type_sampled_image_u32_3d_0001 %img %sampler +%res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_1 +)"; + + CompileSuccessfully( + GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-OpImage-04777")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("In Vulkan, OpImage*Dref* instructions must not use " + "images with a 3D Dim")); +} + TEST_F(ValidateImage, SampleDrefExplicitLodSuccess) { const std::string body = R"( %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001 @@ -3277,6 +3305,23 @@ TEST_F(ValidateImage, DrefGatherWrongDrefType) { HasSubstr("Expected Dref to be of 32-bit float type")); } +TEST_F(ValidateImage, DrefGatherWrongDimVulkan) { + const std::string body = R"( +%img = OpLoad %type_image_f32_3d_0001 %uniform_image_f32_3d_0001 +%sampler = OpLoad %type_sampler %uniform_sampler +%simg = OpSampledImage %type_sampled_image_f32_3d_0001 %img %sampler +%res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 +)"; + + CompileSuccessfully( + GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-OpImage-04777")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Expected Image 'Dim' to be 2D, Cube, or Rect")); +} + TEST_F(ValidateImage, ReadSuccess1) { const std::string body = R"( %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 |