From f0c96f40c79d03e42688aae48642a4759a5e376f Mon Sep 17 00:00:00 2001 From: sfricke-samsung <46493288+sfricke-samsung@users.noreply.github.com> Date: Fri, 5 Feb 2021 12:12:38 -0800 Subject: [PATCH] spriv-val: Vulkan image gather constant component (#4133) --- source/val/validate_image.cpp | 11 ++++++++- source/val/validation_state.cpp | 2 ++ test/val/val_image_test.cpp | 40 +++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/source/val/validate_image.cpp b/source/val/validate_image.cpp index f7ddec73a..bdb2516e7 100644 --- a/source/val/validate_image.cpp +++ b/source/val/validate_image.cpp @@ -1457,12 +1457,21 @@ spv_result_t ValidateImageGather(ValidationState_t& _, } if (opcode == SpvOpImageGather || opcode == SpvOpImageSparseGather) { - const uint32_t component_index_type = _.GetOperandTypeId(inst, 4); + const uint32_t component = inst->GetOperandAs(4); + const uint32_t component_index_type = _.GetTypeId(component); if (!_.IsIntScalarType(component_index_type) || _.GetBitWidth(component_index_type) != 32) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Component to be 32-bit int scalar"; } + if (spvIsVulkanEnv(_.context()->target_env)) { + if (!spvOpcodeIsConstant(_.GetIdOpcode(component))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4664) + << "Expected Component Operand to be a const object for Vulkan " + "environment"; + } + } } else { assert(opcode == SpvOpImageDrefGather || opcode == SpvOpImageSparseDrefGather); diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp index 8050c96a5..6dfc7bf6b 100644 --- a/source/val/validation_state.cpp +++ b/source/val/validation_state.cpp @@ -1708,6 +1708,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id, return VUID_WRAP(VUID-StandaloneSpirv-Offset-04662); case 4663: return VUID_WRAP(VUID-StandaloneSpirv-Offset-04663); + case 4664: + return VUID_WRAP(VUID-StandaloneSpirv-OpImageGather-04664); case 4669: return VUID_WRAP(VUID-StandaloneSpirv-GLSLShared-04669); case 4675: diff --git a/test/val/val_image_test.cpp b/test/val/val_image_test.cpp index 5030e4113..6a0333cd2 100644 --- a/test/val/val_image_test.cpp +++ b/test/val/val_image_test.cpp @@ -80,6 +80,7 @@ OpCapability ImageBuffer %private_image_u32_buffer_0002_r32ui %private_image_u32_spd_0002 %private_image_f32_buffer_0002_r32ui +%input_flat_u32 )"; ss << capabilities_and_extensions; @@ -121,6 +122,8 @@ OpDecorate %uniform_image_f32_cube_0102_rgba32f DescriptorSet 2 OpDecorate %uniform_image_f32_cube_0102_rgba32f Binding 3 OpDecorate %uniform_sampler DescriptorSet 3 OpDecorate %uniform_sampler Binding 0 +OpDecorate %input_flat_u32 Flat +OpDecorate %input_flat_u32 Location 0 )"; } @@ -294,6 +297,9 @@ OpDecorate %uniform_sampler Binding 0 %ptr_Image_f32 = OpTypePointer Image %f32 %ptr_image_f32_buffer_0002_r32ui = OpTypePointer Private %type_image_f32_buffer_0002_r32ui %private_image_f32_buffer_0002_r32ui = OpVariable %ptr_image_f32_buffer_0002_r32ui Private + +%ptr_input_flat_u32 = OpTypePointer Input %u32 +%input_flat_u32 = OpVariable %ptr_input_flat_u32 Input )"; if (env == SPV_ENV_UNIVERSAL_1_0) { @@ -3016,6 +3022,40 @@ TEST_F(ValidateImage, GatherComponentNot32Bit) { HasSubstr("Expected Component to be 32-bit int scalar")); } +TEST_F(ValidateImage, GatherComponentSuccessVulkan) { + const std::string body = R"( +%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101 +%sampler = OpLoad %type_sampler %uniform_sampler +%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler +%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_0 +)"; + + spv_target_env env = SPV_ENV_VULKAN_1_0; + CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(), + env); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env)); +} + +TEST_F(ValidateImage, GatherComponentNotConstantVulkan) { + const std::string body = R"( +%input_u32 = OpLoad %u32 %input_flat_u32 +%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101 +%sampler = OpLoad %type_sampler %uniform_sampler +%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler +%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %input_u32 +)"; + + spv_target_env env = SPV_ENV_VULKAN_1_0; + CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(), + env); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); + EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-OpImageGather-04664")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Expected Component Operand to be a const object for " + "Vulkan environment")); +} + TEST_F(ValidateImage, GatherDimCube) { const std::string body = R"( %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101