From a0370efd589be33d5d9a85cfde2f85841b3755af Mon Sep 17 00:00:00 2001 From: David Neto Date: Thu, 10 Dec 2020 17:15:46 -0500 Subject: [PATCH] validate OpTypeImage Sampled values for environemnts (#4064) Fixes #4063 --- source/val/validate_image.cpp | 20 ++- test/val/val_image_test.cpp | 318 ++++++++++++++++++++++++++-------- test/val/val_opencl_test.cpp | 2 +- 3 files changed, 257 insertions(+), 83 deletions(-) diff --git a/source/val/validate_image.cpp b/source/val/validate_image.cpp index 17ddfc052..0a0eeee83 100644 --- a/source/val/validate_image.cpp +++ b/source/val/validate_image.cpp @@ -736,7 +736,8 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Corrupt image type definition"; } - if (spvIsVulkanEnv(_.context()->target_env)) { + const auto target_env = _.context()->target_env; + if (spvIsVulkanEnv(target_env)) { if ((!_.IsFloatScalarType(info.sampled_type) && !_.IsIntScalarType(info.sampled_type)) || (32 != _.GetBitWidth(info.sampled_type) && @@ -746,7 +747,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Expected Sampled Type to be a 32-bit int or float " "scalar type for Vulkan environment"; } - } else if (spvIsOpenCLEnv(_.context()->target_env)) { + } else if (spvIsOpenCLEnv(target_env)) { if (!_.IsVoidType(info.sampled_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Sampled Type must be OpTypeVoid in the OpenCL environment."; @@ -774,7 +775,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Invalid Arrayed " << info.arrayed << " (must be 0 or 1)"; } - if (spvIsOpenCLEnv(_.context()->target_env)) { + if (spvIsOpenCLEnv(target_env)) { if ((info.arrayed == 1) && (info.dim != SpvDim1D) && (info.dim != SpvDim2D)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -788,10 +789,10 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Invalid MS " << info.multisampled << " (must be 0 or 1)"; } - if (spvIsOpenCLEnv(_.context()->target_env)) { + if (spvIsOpenCLEnv(target_env)) { if (info.multisampled != 0) { return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "MS must be 0 in the OpenCL environement."; + << "MS must be 0 in the OpenCL environment."; } } @@ -800,6 +801,15 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)"; } + if (spvIsVulkanEnv(target_env) || spvIsWebGPUEnv(target_env)) { + if (info.sampled == 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Sampled must be 1 or 2 in the " + << (spvIsVulkanEnv(target_env) ? "Vulkan" : "WebGPU") + << " environment."; + } + } + if (spvIsOpenCLEnv(_.context()->target_env)) { if (info.sampled != 0) { return _.diag(SPV_ERROR_INVALID_DATA, inst) diff --git a/test/val/val_image_test.cpp b/test/val/val_image_test.cpp index d2e1a55ad..31f93752e 100644 --- a/test/val/val_image_test.cpp +++ b/test/val/val_image_test.cpp @@ -66,9 +66,9 @@ OpCapability ImageBuffer %uniform_image_f32_1d_0001 %uniform_image_f32_1d_0002_rgba32f %uniform_image_f32_2d_0001 -%uniform_image_f32_2d_0010 +%uniform_image_f32_2d_0011 %uniform_image_u32_2d_0001 -%uniform_image_u32_2d_0000 +%uniform_image_u32_2d_0002 %uniform_image_s32_3d_0001 %uniform_image_f32_2d_0002 %uniform_image_s32_2d_0002 @@ -99,12 +99,12 @@ OpDecorate %uniform_image_f32_1d_0002_rgba32f DescriptorSet 0 OpDecorate %uniform_image_f32_1d_0002_rgba32f Binding 1 OpDecorate %uniform_image_f32_2d_0001 DescriptorSet 0 OpDecorate %uniform_image_f32_2d_0001 Binding 2 -OpDecorate %uniform_image_f32_2d_0010 DescriptorSet 0 -OpDecorate %uniform_image_f32_2d_0010 Binding 3 +OpDecorate %uniform_image_f32_2d_0011 DescriptorSet 0 +OpDecorate %uniform_image_f32_2d_0011 Binding 3 OpDecorate %uniform_image_u32_2d_0001 DescriptorSet 1 OpDecorate %uniform_image_u32_2d_0001 Binding 0 -OpDecorate %uniform_image_u32_2d_0000 DescriptorSet 1 -OpDecorate %uniform_image_u32_2d_0000 Binding 1 +OpDecorate %uniform_image_u32_2d_0002 DescriptorSet 1 +OpDecorate %uniform_image_u32_2d_0002 Binding 1 OpDecorate %uniform_image_s32_3d_0001 DescriptorSet 1 OpDecorate %uniform_image_s32_3d_0001 Binding 2 OpDecorate %uniform_image_f32_2d_0002 DescriptorSet 1 @@ -230,20 +230,20 @@ OpDecorate %uniform_sampler Binding 0 %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001 -%type_image_f32_2d_0010 = OpTypeImage %f32 2D 0 0 1 0 Unknown -%ptr_image_f32_2d_0010 = OpTypePointer UniformConstant %type_image_f32_2d_0010 -%uniform_image_f32_2d_0010 = OpVariable %ptr_image_f32_2d_0010 UniformConstant -%type_sampled_image_f32_2d_0010 = OpTypeSampledImage %type_image_f32_2d_0010 +%type_image_f32_2d_0011 = OpTypeImage %f32 2D 0 0 1 1 Unknown +%ptr_image_f32_2d_0011 = OpTypePointer UniformConstant %type_image_f32_2d_0011 +%uniform_image_f32_2d_0011 = OpVariable %ptr_image_f32_2d_0011 UniformConstant +%type_sampled_image_f32_2d_0011 = OpTypeSampledImage %type_image_f32_2d_0011 %type_image_u32_2d_0001 = OpTypeImage %u32 2D 0 0 0 1 Unknown %ptr_image_u32_2d_0001 = OpTypePointer UniformConstant %type_image_u32_2d_0001 %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_2d_0000 = OpTypeImage %u32 2D 0 0 0 0 Unknown -%ptr_image_u32_2d_0000 = OpTypePointer UniformConstant %type_image_u32_2d_0000 -%uniform_image_u32_2d_0000 = OpVariable %ptr_image_u32_2d_0000 UniformConstant -%type_sampled_image_u32_2d_0000 = OpTypeSampledImage %type_image_u32_2d_0000 +%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 +%type_sampled_image_u32_2d_0002 = OpTypeSampledImage %type_image_u32_2d_0002 %type_image_s32_3d_0001 = OpTypeImage %s32 3D 0 0 0 1 Unknown %ptr_image_s32_3d_0001 = OpTypePointer UniformConstant %type_image_s32_3d_0001 @@ -400,15 +400,15 @@ OpMemoryModel Physical32 OpenCL %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001 -%type_image_f32_2d_0010 = OpTypeImage %f32 2D 0 0 1 0 Unknown -%ptr_image_f32_2d_0010 = OpTypePointer UniformConstant %type_image_f32_2d_0010 -%uniform_image_f32_2d_0010 = OpVariable %ptr_image_f32_2d_0010 UniformConstant -%type_sampled_image_f32_2d_0010 = OpTypeSampledImage %type_image_f32_2d_0010 +%type_image_f32_2d_0011 = OpTypeImage %f32 2D 0 0 1 1 Unknown +%ptr_image_f32_2d_0011 = OpTypePointer UniformConstant %type_image_f32_2d_0011 +%uniform_image_f32_2d_0011 = OpVariable %ptr_image_f32_2d_0011 UniformConstant +%type_sampled_image_f32_2d_0011 = OpTypeSampledImage %type_image_f32_2d_0011 -%type_image_f32_3d_0010 = OpTypeImage %f32 3D 0 0 1 0 Unknown -%ptr_image_f32_3d_0010 = OpTypePointer UniformConstant %type_image_f32_3d_0010 -%uniform_image_f32_3d_0010 = OpVariable %ptr_image_f32_3d_0010 UniformConstant -%type_sampled_image_f32_3d_0010 = OpTypeSampledImage %type_image_f32_3d_0010 +%type_image_f32_3d_0011 = OpTypeImage %f32 3D 0 0 1 1 Unknown +%ptr_image_f32_3d_0011 = OpTypePointer UniformConstant %type_image_f32_3d_0011 +%uniform_image_f32_3d_0011 = OpVariable %ptr_image_f32_3d_0011 UniformConstant +%type_sampled_image_f32_3d_0011 = OpTypeSampledImage %type_image_f32_3d_0011 %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001 @@ -431,6 +431,41 @@ OpFunctionEnd)"; return ss.str(); } +std::string GetKernelHeader() { + return R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpMemoryModel Physical32 OpenCL + %void = OpTypeVoid + %func = OpTypeFunction %void + %f32 = OpTypeFloat 32 + %u32 = OpTypeInt 32 0 + )"; +} + +std::string TrivialMain() { + return R"( + %main = OpFunction %void None %func + %entry = OpLabel + OpReturn + OpFunctionEnd + )"; +} + +std::string GetWebGPUShaderHeader() { + return R"( + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main LocalSize 1 1 1 + %void = OpTypeVoid + %func = OpTypeFunction %void + %f32 = OpTypeFloat 32 + %u32 = OpTypeInt 32 0 + )"; +} + std::string GetShaderHeader(const std::string& capabilities_and_extensions = "", bool include_entry_point = true) { std::ostringstream ss; @@ -571,6 +606,112 @@ TEST_F(ValidateImage, TypeImageWrongSampledForSubpassData) { HasSubstr("Dim SubpassData requires Sampled to be 2")); } +TEST_F(ValidateImage, TypeImage_OpenCL_Sampled0_OK) { + const std::string code = GetKernelHeader() + R"( +%img_type = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly +)"; + + CompileSuccessfully(code.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_1)); + EXPECT_THAT(getDiagnosticString(), Eq("")); +} + +TEST_F(ValidateImage, TypeImage_OpenCL_Sampled1_Invalid) { + const std::string code = GetKernelHeader() + R"( +%img_type = OpTypeImage %void 2D 0 0 0 1 Unknown ReadOnly +)"; + + CompileSuccessfully(code.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Sampled must be 0 in the OpenCL environment.")); +} + +TEST_F(ValidateImage, TypeImage_OpenCL_Sampled2_Invalid) { + const std::string code = GetKernelHeader() + R"( +%img_type = OpTypeImage %void 2D 0 0 0 2 Unknown ReadOnly +)"; + + CompileSuccessfully(code.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Sampled must be 0 in the OpenCL environment.")); +} + +TEST_F(ValidateImage, TypeImage_OpenCL_AccessQualifierMissing) { + const std::string code = GetKernelHeader() + R"( +%img_type = OpTypeImage %void 2D 0 0 0 0 Unknown +)"; + + CompileSuccessfully(code.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("In the OpenCL environment, the optional Access " + "Qualifier must be present")); +} + +TEST_F(ValidateImage, TypeImage_Vulkan_Sampled1_OK) { + const std::string code = GetShaderHeader() + R"( +%img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown +)" + TrivialMain(); + + CompileSuccessfully(code.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT(getDiagnosticString(), Eq("")); +} + +TEST_F(ValidateImage, TypeImage_Vulkan_Sampled2_OK) { + const std::string code = GetShaderHeader() + R"( +%img_type = OpTypeImage %f32 2D 0 0 0 2 Rgba32f +)" + TrivialMain(); + + CompileSuccessfully(code.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT(getDiagnosticString(), Eq("")); +} + +TEST_F(ValidateImage, TypeImage_Vulkan_Sampled0_Invalid) { + const std::string code = GetShaderHeader() + R"( +%img_type = OpTypeImage %f32 2D 0 0 0 0 Unknown +)" + TrivialMain(); + + CompileSuccessfully(code.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Sampled must be 1 or 2 in the Vulkan environment.")); +} + +TEST_F(ValidateImage, TypeImage_WebGPU_Sampled1_OK) { + const std::string code = GetWebGPUShaderHeader() + R"( +%img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown +)" + TrivialMain(); + + CompileSuccessfully(code.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); + EXPECT_THAT(getDiagnosticString(), Eq("")); +} + +TEST_F(ValidateImage, TypeImage_WebGPU_Sampled2_OK) { + const std::string code = GetWebGPUShaderHeader() + R"( +%img_type = OpTypeImage %f32 2D 0 0 0 2 Rgba32f +)" + TrivialMain(); + + CompileSuccessfully(code.c_str()); + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); + EXPECT_THAT(getDiagnosticString(), Eq("")); +} + +TEST_F(ValidateImage, TypeImage_WebGPU_Sampled0_Invalid) { + const std::string code = GetWebGPUShaderHeader() + R"( +%img_type = OpTypeImage %f32 2D 0 0 0 0 Unknown +)" + TrivialMain(); + + CompileSuccessfully(code.c_str()); + ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Sampled must be 1 or 2 in the WebGPU environment.")); +} + TEST_F(ValidateImage, TypeImageWrongFormatForSubpassData) { const std::string code = GetShaderHeader("OpCapability InputAttachment\n", false) + @@ -697,9 +838,9 @@ TEST_F(ValidateImage, SampledImageImageNotForSampling) { TEST_F(ValidateImage, SampledImageVulkanUnknownSampled) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %sampler = OpLoad %type_sampler %uniform_sampler -%simg = OpSampledImage %type_sampled_image_u32_2d_0000 %img %sampler +%simg = OpSampledImage %type_sampled_image_u32_2d_0002 %img %sampler )"; const spv_target_env env = SPV_ENV_VULKAN_1_0; @@ -838,7 +979,7 @@ TEST_F(ValidateImage, ImageTexelPointerImageCoordTypeBad) { TEST_F(ValidateImage, ImageTexelPointerImageCoordSizeBad) { const std::string body = R"( -%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_u32_2d_0000 %u32vec3_012 %u32_0 +%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_u32_2d_0002 %u32vec3_012 %u32_0 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1 )"; @@ -1221,9 +1362,9 @@ TEST_F(ValidateImage, LodWrongDim) { TEST_F(ValidateImage, LodMultisampled) { const std::string body = R"( -%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010 +%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011 %sampler = OpLoad %type_sampler %uniform_sampler -%simg = OpSampledImage %type_sampled_image_f32_2d_0010 %img %sampler +%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32_0)"; CompileSuccessfully(GenerateShaderCode(body).c_str()); @@ -2386,7 +2527,7 @@ TEST_F(ValidateImage, FetchSampledImageDirectly) { TEST_F(ValidateImage, FetchNotSampled) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01 )"; @@ -2777,7 +2918,7 @@ TEST_F(ValidateImage, DrefGatherWrongDrefType) { TEST_F(ValidateImage, ReadSuccess1) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 )"; @@ -2820,7 +2961,7 @@ TEST_F(ValidateImage, ReadSuccess4) { TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 )"; @@ -2830,7 +2971,7 @@ TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) { TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 )"; @@ -2873,7 +3014,7 @@ TEST_F(ValidateImage, ReadNeedCapabilityImageCubeArray) { // TODO(atgoo@github.com) Disabled until the spec is clarified. TEST_F(ValidateImage, DISABLED_ReadWrongResultType) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %f32 %img %u32vec2_01 )"; @@ -2887,7 +3028,7 @@ TEST_F(ValidateImage, DISABLED_ReadWrongResultType) { // TODO(atgoo@github.com) Disabled until the spec is clarified. TEST_F(ValidateImage, DISABLED_ReadWrongNumComponentsResultType) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %f32vec3 %img %u32vec2_01 )"; @@ -2926,7 +3067,7 @@ TEST_F(ValidateImage, ReadImageSampled) { TEST_F(ValidateImage, ReadWrongSampledType) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %f32vec4 %img %u32vec2_01 )"; @@ -2953,7 +3094,7 @@ TEST_F(ValidateImage, ReadVoidSampledType) { TEST_F(ValidateImage, ReadWrongCoordinateType) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %f32vec2_00 )"; @@ -2966,7 +3107,7 @@ TEST_F(ValidateImage, ReadWrongCoordinateType) { TEST_F(ValidateImage, ReadCoordinateSizeTooSmall) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32_1 )"; @@ -2980,7 +3121,7 @@ TEST_F(ValidateImage, ReadCoordinateSizeTooSmall) { TEST_F(ValidateImage, WriteSuccess1) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %u32vec4_0123 )"; @@ -3013,14 +3154,25 @@ OpImageWrite %img %u32vec3_012 %f32vec4_0000 TEST_F(ValidateImage, WriteSuccess4) { const std::string body = R"( -%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010 -;TODO(atgoo@github.com) Is it legal to write to MS image without sample index? -OpImageWrite %img %u32vec2_01 %f32vec4_0000 +%img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1 )"; - const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n"; - CompileSuccessfully(GenerateShaderCode(body, extra).c_str()); + const std::string extra = R"( + OpCapability StorageImageWriteWithoutFormat + OpCapability StorageImageMultisample + )"; + + const std::string declarations = R"( +%type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown +%ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012 +%uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant +%type_sampled_image_f32_2d_0012 = OpTypeSampledImage %type_image_f32_2d_0012 + )"; + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", + SPV_ENV_UNIVERSAL_1_0, "GLSL450", + declarations) + .c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -3038,7 +3190,7 @@ OpImageWrite %img %u32vec2_01 %f32vec4_0000 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %u32vec4_0123 )"; @@ -3048,7 +3200,7 @@ OpImageWrite %img %u32vec2_01 %u32vec4_0123 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %u32vec4_0123 )"; @@ -3117,7 +3269,7 @@ OpImageWrite %img %u32vec2_01 %f32vec4_0000 TEST_F(ValidateImage, WriteWrongCoordinateType) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %f32vec2_00 %u32vec4_0123 )"; @@ -3130,7 +3282,7 @@ OpImageWrite %img %f32vec2_00 %u32vec4_0123 TEST_F(ValidateImage, WriteCoordinateSizeTooSmall) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32_1 %u32vec4_0123 )"; @@ -3144,7 +3296,7 @@ OpImageWrite %img %u32_1 %u32vec4_0123 TEST_F(ValidateImage, WriteTexelWrongType) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %img )"; @@ -3157,7 +3309,7 @@ OpImageWrite %img %u32vec2_01 %img TEST_F(ValidateImage, DISABLED_WriteTexelNotVector4) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %u32vec3_012 )"; @@ -3170,7 +3322,7 @@ OpImageWrite %img %u32vec2_01 %u32vec3_012 TEST_F(ValidateImage, WriteTexelWrongComponentType) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %f32vec4_0000 )"; @@ -3185,12 +3337,24 @@ OpImageWrite %img %u32vec2_01 %f32vec4_0000 TEST_F(ValidateImage, WriteSampleNotInteger) { const std::string body = R"( -%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010 +%img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1 )"; - const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n"; - CompileSuccessfully(GenerateShaderCode(body, extra).c_str()); + const std::string extra = R"( + OpCapability StorageImageWriteWithoutFormat + OpCapability StorageImageMultisample + )"; + const std::string declarations = R"( +%type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown +%ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012 +%uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant +%type_sampled_image_f32_2d_0012 = OpTypeSampledImage %type_image_f32_2d_0012 + )"; + CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", + SPV_ENV_UNIVERSAL_1_0, "GLSL450", + declarations) + .c_str()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Expected Image Operand Sample to be int scalar")); @@ -3212,9 +3376,9 @@ OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1 TEST_F(ValidateImage, SampleWrongOpcode) { const std::string body = R"( -%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010 +%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011 %sampler = OpLoad %type_sampler %uniform_sampler -%simg = OpSampledImage %type_sampled_image_f32_2d_0010 %img %sampler +%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Sample %u32_1 )"; @@ -3430,7 +3594,7 @@ TEST_F(ValidateImage, QuerySizeLodWrongImageDim) { TEST_F(ValidateImage, QuerySizeLodMultisampled) { const std::string body = R"( -%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010 +%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1 )"; @@ -3453,7 +3617,7 @@ TEST_F(ValidateImage, QuerySizeLodWrongLodType) { TEST_F(ValidateImage, QuerySizeSuccess) { const std::string body = R"( -%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010 +%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011 %res1 = OpImageQuerySize %u32vec2 %img )"; @@ -3463,7 +3627,7 @@ TEST_F(ValidateImage, QuerySizeSuccess) { TEST_F(ValidateImage, QuerySizeWrongResultType) { const std::string body = R"( -%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010 +%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011 %res1 = OpImageQuerySize %f32vec2 %img )"; @@ -3476,7 +3640,7 @@ TEST_F(ValidateImage, QuerySizeWrongResultType) { TEST_F(ValidateImage, QuerySizeNotImage) { const std::string body = R"( -%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010 +%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011 %sampler = OpLoad %type_sampler %uniform_sampler %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler %res1 = OpImageQuerySize %u32vec2 %sampler @@ -3490,7 +3654,7 @@ TEST_F(ValidateImage, QuerySizeNotImage) { TEST_F(ValidateImage, QuerySizeSampledImageDirectly) { const std::string body = R"( -%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010 +%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011 %sampler = OpLoad %type_sampler %uniform_sampler %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler %res1 = OpImageQuerySize %u32vec2 %simg @@ -3715,7 +3879,7 @@ TEST_F(ValidateImage, QueryLevelsWrongDim) { TEST_F(ValidateImage, QuerySamplesSuccess) { const std::string body = R"( -%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010 +%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011 %res1 = OpImageQuerySamples %u32 %img )"; @@ -3725,7 +3889,7 @@ TEST_F(ValidateImage, QuerySamplesSuccess) { TEST_F(ValidateImage, QuerySamplesNot2D) { const std::string body = R"( -%img = OpLoad %type_image_f32_3d_0010 %uniform_image_f32_3d_0010 +%img = OpLoad %type_image_f32_3d_0011 %uniform_image_f32_3d_0011 %res1 = OpImageQuerySamples %u32 %img )"; @@ -4490,7 +4654,7 @@ TEST_F(ValidateImage, SparseTexelsResidentResultTypeNotBool) { TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageRead) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2 )"; @@ -4548,7 +4712,7 @@ OpExtension "SPV_KHR_vulkan_memory_model" TEST_F(ValidateImage, MakeTexelVisibleKHRFailureMissingNonPrivate) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR %u32_1 )"; @@ -4569,7 +4733,7 @@ OpExtension "SPV_KHR_vulkan_memory_model" TEST_F(ValidateImage, MakeTexelAvailableKHRSuccessImageWrite) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2 )"; @@ -4609,7 +4773,7 @@ OpExtension "SPV_KHR_vulkan_memory_model" TEST_F(ValidateImage, MakeTexelAvailableKHRFailureMissingNonPrivate) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1 )"; @@ -4630,7 +4794,7 @@ OpExtension "SPV_KHR_vulkan_memory_model" TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteBad) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1 )"; @@ -4652,7 +4816,7 @@ OpExtension "SPV_KHR_vulkan_memory_model" TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteGood) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1 )"; @@ -4670,7 +4834,7 @@ OpExtension "SPV_KHR_vulkan_memory_model" TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadBad) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1 )"; @@ -4692,7 +4856,7 @@ OpExtension "SPV_KHR_vulkan_memory_model" TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadGood) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1 )"; @@ -4745,7 +4909,7 @@ TEST_F(ValidateImage, Issue2463NoSegFault) { TEST_F(ValidateImage, SignExtendV13Bad) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend )"; @@ -4756,7 +4920,7 @@ TEST_F(ValidateImage, SignExtendV13Bad) { TEST_F(ValidateImage, ZeroExtendV13Bad) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend )"; @@ -4768,7 +4932,7 @@ TEST_F(ValidateImage, ZeroExtendV13Bad) { TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) { // Unsigned int sampled type const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32 %img %u32vec2_01 SignExtend )"; const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; @@ -4797,7 +4961,7 @@ TEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) { TEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend )"; const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; @@ -4829,7 +4993,7 @@ TEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) { TEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) { // Unsigned int sampled type const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32 %img %u32vec2_01 ZeroExtend )"; const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; @@ -4858,7 +5022,7 @@ TEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) { TEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend )"; const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n"; @@ -4886,7 +5050,7 @@ TEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) { TEST_F(ValidateImage, ReadLodAMDSuccess1) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 Lod %u32_0 )"; @@ -4951,7 +5115,7 @@ TEST_F(ValidateImage, ReadLodAMDNeedCapability) { TEST_F(ValidateImage, WriteLodAMDSuccess1) { const std::string body = R"( -%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000 +%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002 OpImageWrite %img %u32vec2_01 %u32vec4_0123 Lod %u32_0 )"; diff --git a/test/val/val_opencl_test.cpp b/test/val/val_opencl_test.cpp index 10641587f..e5e3b12b4 100644 --- a/test/val/val_opencl_test.cpp +++ b/test/val/val_opencl_test.cpp @@ -91,7 +91,7 @@ TEST_F(ValidateOpenCL, NonZeroMSImageBad) { EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2)); EXPECT_THAT( getDiagnosticString(), - HasSubstr("MS must be 0 in the OpenCL environement." + HasSubstr("MS must be 0 in the OpenCL environment." "\n %2 = OpTypeImage %void 2D 0 0 1 0 Unknown ReadOnly\n")); }