| // Copyright (c) 2017 Google Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| // Tests validation rules of GLSL.450.std and OpenCL.std extended instructions. |
| // Doesn't test OpenCL.std vector size 2, 3, 4, 8 or 16 rules (not supported |
| // by standard SPIR-V). |
| |
| #include <sstream> |
| #include <string> |
| #include <vector> |
| |
| #include "gmock/gmock.h" |
| #include "test/unit_spirv.h" |
| #include "test/val/val_fixtures.h" |
| |
| namespace spvtools { |
| namespace val { |
| namespace { |
| |
| using ::testing::Eq; |
| using ::testing::HasSubstr; |
| using ::testing::Not; |
| |
| using ValidateExtInst = spvtest::ValidateBase<bool>; |
| using ValidateGlslStd450SqrtLike = spvtest::ValidateBase<std::string>; |
| using ValidateGlslStd450FMinLike = spvtest::ValidateBase<std::string>; |
| using ValidateGlslStd450FClampLike = spvtest::ValidateBase<std::string>; |
| using ValidateGlslStd450SAbsLike = spvtest::ValidateBase<std::string>; |
| using ValidateGlslStd450UMinLike = spvtest::ValidateBase<std::string>; |
| using ValidateGlslStd450UClampLike = spvtest::ValidateBase<std::string>; |
| using ValidateGlslStd450SinLike = spvtest::ValidateBase<std::string>; |
| using ValidateGlslStd450PowLike = spvtest::ValidateBase<std::string>; |
| using ValidateGlslStd450Pack = spvtest::ValidateBase<std::string>; |
| using ValidateGlslStd450Unpack = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdSqrtLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdFMinLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdFClampLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdSAbsLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdUMinLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdUClampLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdUMul24Like = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdUMad24Like = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdLengthLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdDistanceLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdNormalizeLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdVStoreHalfLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdVLoadHalfLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdFractLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdFrexpLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdLdexpLike = spvtest::ValidateBase<std::string>; |
| using ValidateOpenCLStdUpsampleLike = spvtest::ValidateBase<std::string>; |
| using ValidateClspvReflection = spvtest::ValidateBase<bool>; |
| |
| // Returns number of components in Pack/Unpack extended instructions. |
| // |ext_inst_name| is expected to be of the format "PackHalf2x16". |
| // Number of components is assumed to be single-digit. |
| uint32_t GetPackedNumComponents(const std::string& ext_inst_name) { |
| const size_t x_index = ext_inst_name.find_last_of('x'); |
| const std::string num_components_str = |
| ext_inst_name.substr(x_index - 1, x_index); |
| return uint32_t(std::stoul(num_components_str)); |
| } |
| |
| // Returns packed bit width in Pack/Unpack extended instructions. |
| // |ext_inst_name| is expected to be of the format "PackHalf2x16". |
| uint32_t GetPackedBitWidth(const std::string& ext_inst_name) { |
| const size_t x_index = ext_inst_name.find_last_of('x'); |
| const std::string packed_bit_width_str = ext_inst_name.substr(x_index + 1); |
| return uint32_t(std::stoul(packed_bit_width_str)); |
| } |
| |
| std::string GenerateShaderCode( |
| const std::string& body, |
| const std::string& capabilities_and_extensions = "", |
| const std::string& execution_model = "Fragment") { |
| std::ostringstream ss; |
| ss << R"( |
| OpCapability Shader |
| OpCapability Float16 |
| OpCapability Float64 |
| OpCapability Int16 |
| OpCapability Int64 |
| )"; |
| |
| ss << capabilities_and_extensions; |
| ss << "%extinst = OpExtInstImport \"GLSL.std.450\"\n"; |
| ss << "OpMemoryModel Logical GLSL450\n"; |
| ss << "OpEntryPoint " << execution_model << " %main \"main\"" |
| << " %f32_output" |
| << " %f32vec2_output" |
| << " %u32_output" |
| << " %u32vec2_output" |
| << " %u64_output" |
| << " %f32_input" |
| << " %f32vec2_input" |
| << " %u32_input" |
| << " %u32vec2_input" |
| << " %u64_input" |
| << "\n"; |
| if (execution_model == "Fragment") { |
| ss << "OpExecutionMode %main OriginUpperLeft\n"; |
| } |
| |
| ss << R"( |
| %void = OpTypeVoid |
| %func = OpTypeFunction %void |
| %bool = OpTypeBool |
| %f16 = OpTypeFloat 16 |
| %f32 = OpTypeFloat 32 |
| %f64 = OpTypeFloat 64 |
| %u32 = OpTypeInt 32 0 |
| %s32 = OpTypeInt 32 1 |
| %u64 = OpTypeInt 64 0 |
| %s64 = OpTypeInt 64 1 |
| %u16 = OpTypeInt 16 0 |
| %s16 = OpTypeInt 16 1 |
| %f32vec2 = OpTypeVector %f32 2 |
| %f32vec3 = OpTypeVector %f32 3 |
| %f32vec4 = OpTypeVector %f32 4 |
| %f64vec2 = OpTypeVector %f64 2 |
| %f64vec3 = OpTypeVector %f64 3 |
| %f64vec4 = OpTypeVector %f64 4 |
| %u32vec2 = OpTypeVector %u32 2 |
| %u32vec3 = OpTypeVector %u32 3 |
| %s32vec2 = OpTypeVector %s32 2 |
| %u32vec4 = OpTypeVector %u32 4 |
| %s32vec4 = OpTypeVector %s32 4 |
| %u64vec2 = OpTypeVector %u64 2 |
| %s64vec2 = OpTypeVector %s64 2 |
| %f64mat22 = OpTypeMatrix %f64vec2 2 |
| %f32mat22 = OpTypeMatrix %f32vec2 2 |
| %f32mat23 = OpTypeMatrix %f32vec2 3 |
| %f32mat32 = OpTypeMatrix %f32vec3 2 |
| %f32mat33 = OpTypeMatrix %f32vec3 3 |
| |
| %f32_0 = OpConstant %f32 0 |
| %f32_1 = OpConstant %f32 1 |
| %f32_2 = OpConstant %f32 2 |
| %f32_3 = OpConstant %f32 3 |
| %f32_4 = OpConstant %f32 4 |
| %f32_h = OpConstant %f32 0.5 |
| %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1 |
| %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2 |
| %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2 |
| %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3 |
| %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3 |
| %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4 |
| |
| %f64_0 = OpConstant %f64 0 |
| %f64_1 = OpConstant %f64 1 |
| %f64_2 = OpConstant %f64 2 |
| %f64_3 = OpConstant %f64 3 |
| %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1 |
| %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2 |
| %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3 |
| |
| %f16_0 = OpConstant %f16 0 |
| %f16_1 = OpConstant %f16 1 |
| %f16_h = OpConstant %f16 0.5 |
| |
| %u32_0 = OpConstant %u32 0 |
| %u32_1 = OpConstant %u32 1 |
| %u32_2 = OpConstant %u32 2 |
| %u32_3 = OpConstant %u32 3 |
| |
| %s32_0 = OpConstant %s32 0 |
| %s32_1 = OpConstant %s32 1 |
| %s32_2 = OpConstant %s32 2 |
| %s32_3 = OpConstant %s32 3 |
| |
| %u64_0 = OpConstant %u64 0 |
| %u64_1 = OpConstant %u64 1 |
| %u64_2 = OpConstant %u64 2 |
| %u64_3 = OpConstant %u64 3 |
| |
| %s64_0 = OpConstant %s64 0 |
| %s64_1 = OpConstant %s64 1 |
| %s64_2 = OpConstant %s64 2 |
| %s64_3 = OpConstant %s64 3 |
| |
| %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1 |
| %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1 |
| |
| %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2 |
| %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2 |
| |
| %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3 |
| %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3 |
| |
| %s64vec2_01 = OpConstantComposite %s64vec2 %s64_0 %s64_1 |
| %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1 |
| |
| %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12 |
| %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12 |
| |
| %f32_ptr_output = OpTypePointer Output %f32 |
| %f32vec2_ptr_output = OpTypePointer Output %f32vec2 |
| |
| %u32_ptr_output = OpTypePointer Output %u32 |
| %u32vec2_ptr_output = OpTypePointer Output %u32vec2 |
| |
| %u64_ptr_output = OpTypePointer Output %u64 |
| |
| %f32_output = OpVariable %f32_ptr_output Output |
| %f32vec2_output = OpVariable %f32vec2_ptr_output Output |
| |
| %u32_output = OpVariable %u32_ptr_output Output |
| %u32vec2_output = OpVariable %u32vec2_ptr_output Output |
| |
| %u64_output = OpVariable %u64_ptr_output Output |
| |
| %f32_ptr_input = OpTypePointer Input %f32 |
| %f32vec2_ptr_input = OpTypePointer Input %f32vec2 |
| |
| %u32_ptr_input = OpTypePointer Input %u32 |
| %u32vec2_ptr_input = OpTypePointer Input %u32vec2 |
| |
| %u64_ptr_input = OpTypePointer Input %u64 |
| |
| %f32_input = OpVariable %f32_ptr_input Input |
| %f32vec2_input = OpVariable %f32vec2_ptr_input Input |
| |
| %u32_input = OpVariable %u32_ptr_input Input |
| %u32vec2_input = OpVariable %u32vec2_ptr_input Input |
| |
| %u64_input = OpVariable %u64_ptr_input Input |
| |
| %struct_f16_u16 = OpTypeStruct %f16 %u16 |
| %struct_f32_f32 = OpTypeStruct %f32 %f32 |
| %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32 |
| %struct_f32_u32 = OpTypeStruct %f32 %u32 |
| %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32 |
| %struct_u32_f32 = OpTypeStruct %u32 %f32 |
| %struct_u32_u32 = OpTypeStruct %u32 %u32 |
| %struct_f32_f64 = OpTypeStruct %f32 %f64 |
| %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2 |
| %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2 |
| |
| %main = OpFunction %void None %func |
| %main_entry = OpLabel |
| )"; |
| |
| ss << body; |
| |
| ss << R"( |
| OpReturn |
| OpFunctionEnd)"; |
| |
| return ss.str(); |
| } |
| |
| std::string GenerateKernelCode( |
| const std::string& body, |
| const std::string& capabilities_and_extensions = "", |
| const std::string& memory_model = "Physical32") { |
| std::ostringstream ss; |
| ss << R"( |
| OpCapability Addresses |
| OpCapability Kernel |
| OpCapability Linkage |
| OpCapability GenericPointer |
| OpCapability Int8 |
| OpCapability Int16 |
| OpCapability Int64 |
| OpCapability Float16 |
| OpCapability Float64 |
| OpCapability Vector16 |
| OpCapability Matrix |
| )"; |
| |
| ss << capabilities_and_extensions; |
| ss << "%extinst = OpExtInstImport \"OpenCL.std\"\n"; |
| ss << "OpMemoryModel " << memory_model << " OpenCL\n"; |
| |
| ss << R"( |
| %void = OpTypeVoid |
| %func = OpTypeFunction %void |
| %bool = OpTypeBool |
| %f16 = OpTypeFloat 16 |
| %f32 = OpTypeFloat 32 |
| %f64 = OpTypeFloat 64 |
| %u32 = OpTypeInt 32 0 |
| %u64 = OpTypeInt 64 0 |
| %u16 = OpTypeInt 16 0 |
| %u8 = OpTypeInt 8 0 |
| %f32vec2 = OpTypeVector %f32 2 |
| %f32vec3 = OpTypeVector %f32 3 |
| %f32vec4 = OpTypeVector %f32 4 |
| %f32vec8 = OpTypeVector %f32 8 |
| %f16vec8 = OpTypeVector %f16 8 |
| %f32vec16 = OpTypeVector %f32 16 |
| %f64vec2 = OpTypeVector %f64 2 |
| %f64vec3 = OpTypeVector %f64 3 |
| %f64vec4 = OpTypeVector %f64 4 |
| %u32vec2 = OpTypeVector %u32 2 |
| %u32vec3 = OpTypeVector %u32 3 |
| %u32vec4 = OpTypeVector %u32 4 |
| %u32vec8 = OpTypeVector %u32 8 |
| %u64vec2 = OpTypeVector %u64 2 |
| %f64mat22 = OpTypeMatrix %f64vec2 2 |
| %f32mat22 = OpTypeMatrix %f32vec2 2 |
| %f32mat23 = OpTypeMatrix %f32vec2 3 |
| %f32mat32 = OpTypeMatrix %f32vec3 2 |
| %f32mat33 = OpTypeMatrix %f32vec3 3 |
| |
| %f32_0 = OpConstant %f32 0 |
| %f32_1 = OpConstant %f32 1 |
| %f32_2 = OpConstant %f32 2 |
| %f32_3 = OpConstant %f32 3 |
| %f32_4 = OpConstant %f32 4 |
| %f32_h = OpConstant %f32 0.5 |
| %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1 |
| %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2 |
| %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2 |
| %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3 |
| %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3 |
| %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4 |
| %f32vec8_01010101 = OpConstantComposite %f32vec8 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1 |
| |
| %f64_0 = OpConstant %f64 0 |
| %f64_1 = OpConstant %f64 1 |
| %f64_2 = OpConstant %f64 2 |
| %f64_3 = OpConstant %f64 3 |
| %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1 |
| %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2 |
| %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3 |
| |
| %f16_0 = OpConstant %f16 0 |
| %f16_1 = OpConstant %f16 1 |
| |
| %u8_0 = OpConstant %u8 0 |
| %u8_1 = OpConstant %u8 1 |
| %u8_2 = OpConstant %u8 2 |
| %u8_3 = OpConstant %u8 3 |
| |
| %u16_0 = OpConstant %u16 0 |
| %u16_1 = OpConstant %u16 1 |
| %u16_2 = OpConstant %u16 2 |
| %u16_3 = OpConstant %u16 3 |
| |
| %u32_0 = OpConstant %u32 0 |
| %u32_1 = OpConstant %u32 1 |
| %u32_2 = OpConstant %u32 2 |
| %u32_3 = OpConstant %u32 3 |
| %u32_256 = OpConstant %u32 256 |
| |
| %u64_0 = OpConstant %u64 0 |
| %u64_1 = OpConstant %u64 1 |
| %u64_2 = OpConstant %u64 2 |
| %u64_3 = OpConstant %u64 3 |
| %u64_256 = OpConstant %u64 256 |
| |
| %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1 |
| %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2 |
| %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2 |
| %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3 |
| |
| %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1 |
| |
| %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12 |
| %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12 |
| |
| %struct_f32_f32 = OpTypeStruct %f32 %f32 |
| %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32 |
| %struct_f32_u32 = OpTypeStruct %f32 %u32 |
| %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32 |
| %struct_u32_f32 = OpTypeStruct %u32 %f32 |
| %struct_u32_u32 = OpTypeStruct %u32 %u32 |
| %struct_f32_f64 = OpTypeStruct %f32 %f64 |
| %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2 |
| %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2 |
| |
| %f16vec8_ptr_workgroup = OpTypePointer Workgroup %f16vec8 |
| %f16vec8_workgroup = OpVariable %f16vec8_ptr_workgroup Workgroup |
| %f16_ptr_workgroup = OpTypePointer Workgroup %f16 |
| |
| %u32vec8_ptr_workgroup = OpTypePointer Workgroup %u32vec8 |
| %u32vec8_workgroup = OpVariable %u32vec8_ptr_workgroup Workgroup |
| %u32_ptr_workgroup = OpTypePointer Workgroup %u32 |
| |
| %f32vec8_ptr_workgroup = OpTypePointer Workgroup %f32vec8 |
| %f32vec8_workgroup = OpVariable %f32vec8_ptr_workgroup Workgroup |
| %f32_ptr_workgroup = OpTypePointer Workgroup %f32 |
| |
| %u32arr = OpTypeArray %u32 %u32_256 |
| %u32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32arr |
| %u32arr_cross_workgroup = OpVariable %u32arr_ptr_cross_workgroup CrossWorkgroup |
| %u32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32 |
| |
| %f32arr = OpTypeArray %f32 %u32_256 |
| %f32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32arr |
| %f32arr_cross_workgroup = OpVariable %f32arr_ptr_cross_workgroup CrossWorkgroup |
| %f32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32 |
| |
| %f32vec2arr = OpTypeArray %f32vec2 %u32_256 |
| %f32vec2arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2arr |
| %f32vec2arr_cross_workgroup = OpVariable %f32vec2arr_ptr_cross_workgroup CrossWorkgroup |
| %f32vec2_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2 |
| |
| %struct_arr = OpTypeArray %struct_f32_f32 %u32_256 |
| %struct_arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_arr |
| %struct_arr_cross_workgroup = OpVariable %struct_arr_ptr_cross_workgroup CrossWorkgroup |
| %struct_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_f32_f32 |
| |
| %f16vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f16vec8 |
| %f16vec8_uniform_constant = OpVariable %f16vec8_ptr_uniform_constant UniformConstant |
| %f16_ptr_uniform_constant = OpTypePointer UniformConstant %f16 |
| |
| %u32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %u32vec8 |
| %u32vec8_uniform_constant = OpVariable %u32vec8_ptr_uniform_constant UniformConstant |
| %u32_ptr_uniform_constant = OpTypePointer UniformConstant %u32 |
| |
| %f32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f32vec8 |
| %f32vec8_uniform_constant = OpVariable %f32vec8_ptr_uniform_constant UniformConstant |
| %f32_ptr_uniform_constant = OpTypePointer UniformConstant %f32 |
| |
| %f16vec8_ptr_input = OpTypePointer Input %f16vec8 |
| %f16vec8_input = OpVariable %f16vec8_ptr_input Input |
| %f16_ptr_input = OpTypePointer Input %f16 |
| |
| %u32vec8_ptr_input = OpTypePointer Input %u32vec8 |
| %u32vec8_input = OpVariable %u32vec8_ptr_input Input |
| %u32_ptr_input = OpTypePointer Input %u32 |
| |
| %f32_ptr_generic = OpTypePointer Generic %f32 |
| %u32_ptr_generic = OpTypePointer Generic %u32 |
| |
| %f32_ptr_function = OpTypePointer Function %f32 |
| %f32vec2_ptr_function = OpTypePointer Function %f32vec2 |
| %u32_ptr_function = OpTypePointer Function %u32 |
| %u64_ptr_function = OpTypePointer Function %u64 |
| %u32vec2_ptr_function = OpTypePointer Function %u32vec2 |
| |
| %u8arr = OpTypeArray %u8 %u32_256 |
| %u8arr_ptr_uniform_constant = OpTypePointer UniformConstant %u8arr |
| %u8arr_uniform_constant = OpVariable %u8arr_ptr_uniform_constant UniformConstant |
| %u8_ptr_uniform_constant = OpTypePointer UniformConstant %u8 |
| %u8_ptr_generic = OpTypePointer Generic %u8 |
| |
| %main = OpFunction %void None %func |
| %main_entry = OpLabel |
| )"; |
| |
| ss << body; |
| |
| ss << R"( |
| OpReturn |
| OpFunctionEnd)"; |
| |
| return ss.str(); |
| } |
| |
| TEST_P(ValidateGlslStd450SqrtLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01\n"; |
| ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n"; |
| CompileSuccessfully(GenerateShaderCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateGlslStd450SqrtLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected Result Type to be a float scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateGlslStd450SqrtLike, IntOperand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllSqrtLike, ValidateGlslStd450SqrtLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "Round", |
| "RoundEven", |
| "FAbs", |
| "Trunc", |
| "FSign", |
| "Floor", |
| "Ceil", |
| "Fract", |
| "Sqrt", |
| "InverseSqrt", |
| "Normalize", |
| })); |
| |
| TEST_P(ValidateGlslStd450FMinLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %f32_1\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01 %f32vec2_12\n"; |
| ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name |
| << " %f64_0 %f64_0\n"; |
| CompileSuccessfully(GenerateShaderCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateGlslStd450FMinLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected Result Type to be a float scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateGlslStd450FMinLike, IntOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450FMinLike, IntOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateGlslStd450FMinLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "FMin", |
| "FMax", |
| "Step", |
| "Reflect", |
| "NMin", |
| "NMax", |
| })); |
| |
| TEST_P(ValidateGlslStd450FClampLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %f32_1 %f32_2\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n"; |
| ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name |
| << " %f64_0 %f64_0 %f64_1\n"; |
| CompileSuccessfully(GenerateShaderCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateGlslStd450FClampLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %f32_0 %f32_1 %f32_2\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected Result Type to be a float scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateGlslStd450FClampLike, IntOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %u32_0 %f32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450FClampLike, IntOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %f32_0 %u32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450FClampLike, IntOperand3) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %f32_1 %f32_0 %u32_2\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateGlslStd450FClampLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "FClamp", |
| "FMix", |
| "SmoothStep", |
| "Fma", |
| "FaceForward", |
| "NClamp", |
| })); |
| |
| TEST_P(ValidateGlslStd450SAbsLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name << " %u32_1\n"; |
| ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name << " %s32_1\n"; |
| ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n"; |
| ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %s32_1\n"; |
| ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name |
| << " %s32vec2_01\n"; |
| ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01\n"; |
| ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %s32vec2_01\n"; |
| ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01\n"; |
| CompileSuccessfully(GenerateShaderCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateGlslStd450SAbsLike, FloatResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected Result Type to be an int scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateGlslStd450SAbsLike, FloatOperand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to be int scalars or " |
| "vectors")); |
| } |
| |
| TEST_P(ValidateGlslStd450SAbsLike, WrongDimOperand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %s32vec2_01\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same dimension as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450SAbsLike, WrongBitWidthOperand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same bit width as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450SAbsLike, TypelessOperand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %main_entry\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to be int scalars or vectors")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateGlslStd450SAbsLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "SAbs", |
| "SSign", |
| "FindILsb", |
| "FindUMsb", |
| "FindSMsb", |
| })); |
| |
| TEST_F(ValidateExtInst, FindUMsbNot32Bit) { |
| const std::string body = R"( |
| %val1 = OpExtInst %s64 %extinst FindUMsb %u64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 FindUMsb: this instruction is currently " |
| "limited to 32-bit width components")); |
| } |
| |
| TEST_F(ValidateExtInst, FindSMsbNot32Bit) { |
| const std::string body = R"( |
| %val1 = OpExtInst %s64 %extinst FindSMsb %u64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 FindSMsb: this instruction is currently " |
| "limited to 32-bit width components")); |
| } |
| |
| TEST_P(ValidateGlslStd450UMinLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name |
| << " %u32_1 %s32_2\n"; |
| ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name |
| << " %s32_1 %u32_2\n"; |
| ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_1 %s32_2\n"; |
| ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %s32_1 %u32_2\n"; |
| ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name |
| << " %s32vec2_01 %u32vec2_01\n"; |
| ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %s32vec2_01\n"; |
| ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %s32vec2_01 %u32vec2_01\n"; |
| ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %s32vec2_01\n"; |
| ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name |
| << " %u64_1 %s64_0\n"; |
| CompileSuccessfully(GenerateShaderCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateGlslStd450UMinLike, FloatResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected Result Type to be an int scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UMinLike, FloatOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to be int scalars or " |
| "vectors")); |
| } |
| |
| TEST_P(ValidateGlslStd450UMinLike, FloatOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to be int scalars or " |
| "vectors")); |
| } |
| |
| TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + |
| " %s32vec2_01 %s32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same dimension as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + |
| " %s32_0 %s32vec2_01\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same dimension as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0 %s64_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same bit width as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s64_0 %s32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same bit width as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UMinLike, TypelessOperand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + |
| " %s64_0 %main_entry\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to be int scalars or vectors")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateGlslStd450UMinLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "UMin", |
| "SMin", |
| "UMax", |
| "SMax", |
| })); |
| |
| TEST_P(ValidateGlslStd450UClampLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name |
| << " %s32_0 %u32_1 %s32_2\n"; |
| ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name |
| << " %u32_0 %s32_1 %u32_2\n"; |
| ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %s32_0 %u32_1 %s32_2\n"; |
| ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_0 %s32_1 %u32_2\n"; |
| ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name |
| << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n"; |
| ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n"; |
| ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n"; |
| ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n"; |
| ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name |
| << " %u64_1 %s64_0 %s64_1\n"; |
| CompileSuccessfully(GenerateShaderCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, FloatResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %u32_0 %u32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected Result Type to be an int scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, FloatOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + |
| " %f32_0 %u32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to be int scalars or " |
| "vectors")); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, FloatOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + |
| " %u32_0 %f32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to be int scalars or " |
| "vectors")); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, FloatOperand3) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + |
| " %u32_0 %u32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to be int scalars or " |
| "vectors")); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + |
| " %s32vec2_01 %s32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same dimension as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + |
| " %s32_0 %s32vec2_01 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same dimension as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand3) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + |
| " %s32_0 %u32_1 %s32vec2_01\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same dimension as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + |
| " %s32_0 %s64_0 %s64_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same bit width as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + |
| " %s64_0 %s32_0 %s64_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same bit width as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand3) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + |
| " %s64_0 %s64_0 %s32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to have the same bit width as " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450UClampLike, TypelessOperand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + |
| " %main_entry %s64_0 %s64_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected all operands to be int scalars or vectors")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateGlslStd450UClampLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "UClamp", |
| "SClamp", |
| })); |
| |
| TEST_P(ValidateGlslStd450SinLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01\n"; |
| CompileSuccessfully(GenerateShaderCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateGlslStd450SinLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected Result Type to be a 16 or 32-bit scalar " |
| "or vector float type")); |
| } |
| |
| TEST_P(ValidateGlslStd450SinLike, F64ResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected Result Type to be a 16 or 32-bit scalar " |
| "or vector float type")); |
| } |
| |
| TEST_P(ValidateGlslStd450SinLike, IntOperand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllSinLike, ValidateGlslStd450SinLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "Radians", |
| "Degrees", |
| "Sin", |
| "Cos", |
| "Tan", |
| "Asin", |
| "Acos", |
| "Atan", |
| "Sinh", |
| "Cosh", |
| "Tanh", |
| "Asinh", |
| "Acosh", |
| "Atanh", |
| "Exp", |
| "Exp2", |
| "Log", |
| "Log2", |
| })); |
| |
| TEST_P(ValidateGlslStd450PowLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_1 %f32_1\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01 %f32vec2_12\n"; |
| CompileSuccessfully(GenerateShaderCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateGlslStd450PowLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_1 %f32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected Result Type to be a 16 or 32-bit scalar " |
| "or vector float type")); |
| } |
| |
| TEST_P(ValidateGlslStd450PowLike, F64ResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_1 %f32_0\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected Result Type to be a 16 or 32-bit scalar " |
| "or vector float type")); |
| } |
| |
| TEST_P(ValidateGlslStd450PowLike, IntOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateGlslStd450PowLike, IntOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllPowLike, ValidateGlslStd450PowLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "Atan2", |
| "Pow", |
| })); |
| |
| TEST_F(ValidateExtInst, GlslStd450DeterminantSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Determinant %f32mat22_1212 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450DeterminantIncompatibleResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst Determinant %f32mat22_1212 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Determinant: " |
| "expected operand X component type to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450DeterminantNotMatrix) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Determinant %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Determinant: " |
| "expected operand X to be a square matrix")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450DeterminantMatrixNotSquare) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Determinant %f32mat23_121212 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Determinant: " |
| "expected operand X to be a square matrix")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450MatrixInverseSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32mat22 %extinst MatrixInverse %f32mat22_1212 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450MatrixInverseIncompatibleResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32mat33 %extinst MatrixInverse %f32mat22_1212 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 MatrixInverse: " |
| "expected operand X type to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450MatrixInverseNotMatrix) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst MatrixInverse %f32mat22_1212 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 MatrixInverse: " |
| "expected Result Type to be a square matrix")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450MatrixInverseMatrixNotSquare) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32mat23 %extinst MatrixInverse %f32mat23_121212 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 MatrixInverse: " |
| "expected Result Type to be a square matrix")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_output |
| %val2 = OpExtInst %f32vec2 %extinst Modf %f32vec2_01 %f32vec2_output |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfIntResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst Modf %f32_h %f32_output |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Modf: " |
| "expected Result Type to be a scalar or vector " |
| "float type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfXNotOfResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Modf %f64_0 %f32_output |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Modf: " |
| "expected operand X type to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfINotPointer) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Modf: " |
| "expected operand I to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfIDataNotOfResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32vec2_output |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Modf: " |
| "expected operand I data type to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfStructSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f32_h |
| %val2 = OpExtInst %struct_f32vec2_f32vec2 %extinst ModfStruct %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeNotStruct) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst ModfStruct %f32_h |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 ModfStruct: " |
| "expected Result Type to be a struct with two " |
| "identical scalar or vector float type members")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongSize) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_f32_f32_f32 %extinst ModfStruct %f32_h |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 ModfStruct: " |
| "expected Result Type to be a struct with two " |
| "identical scalar or vector float type members")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongFirstMember) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_u32_f32 %extinst ModfStruct %f32_h |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 ModfStruct: " |
| "expected Result Type to be a struct with two " |
| "identical scalar or vector float type members")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructMembersNotEqual) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_f32_f64 %extinst ModfStruct %f32_h |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 ModfStruct: " |
| "expected Result Type to be a struct with two " |
| "identical scalar or vector float type members")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450ModfStructXWrongType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f64_0 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 ModfStruct: " |
| "expected operand X type to be equal to members of " |
| "Result Type struct")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Frexp %f32_h %u32_output |
| %val2 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32vec2_output |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpIntResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst Frexp %f32_h %u32_output |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Frexp: " |
| "expected Result Type to be a scalar or vector " |
| "float type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpWrongXType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Frexp %u32_1 %u32_output |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Frexp: " |
| "expected operand X type to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpExpNotPointer) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Frexp: " |
| "expected operand Exp to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpExpNotInt32Pointer) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %f32_output |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Frexp: " |
| "expected operand Exp data type to be a 32-bit int " |
| "scalar or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpExpWrongComponentNumber) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32_output |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Frexp: " |
| "expected operand Exp data type to have the same " |
| "component number as Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450LdexpSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Ldexp %f32_h %u32_2 |
| %val2 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_01 %u32vec2_12 |
| %val3 = OpExtInst %f32 %extinst Ldexp %f32_h %u64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450LdexpIntResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst Ldexp %f32_h %u32_2 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Ldexp: " |
| "expected Result Type to be a scalar or vector " |
| "float type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450LdexpWrongXType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Ldexp %u32_1 %u32_2 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Ldexp: " |
| "expected operand X type to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450LdexpFloatExp) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Ldexp %f32_1 %f32_2 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Ldexp: " |
| "expected operand Exp to be a 32-bit int scalar " |
| "or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450LdexpExpWrongSize) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_12 %u32_2 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Ldexp: " |
| "expected operand Exp to have the same component " |
| "number as Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450LdexpExpNoType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Ldexp %f32_1 %main_entry |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Ldexp: " |
| "expected operand Exp to be a 32-bit int scalar " |
| "or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpStructSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f32_h |
| %val2 = OpExtInst %struct_f32vec2_u32vec2 %extinst FrexpStruct %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeNotStruct) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst FrexpStruct %f32_h |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 FrexpStruct: " |
| "expected Result Type to be a struct with two members, " |
| "first member a float scalar or vector, second member " |
| "a 32-bit int scalar or vector with the same number of " |
| "components as the first member")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongSize) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_f32_u32_f32 %extinst FrexpStruct %f32_h |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 FrexpStruct: " |
| "expected Result Type to be a struct with two members, " |
| "first member a float scalar or vector, second member " |
| "a 32-bit int scalar or vector with the same number of " |
| "components as the first member")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember1) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_u32_u32 %extinst FrexpStruct %f32_h |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 FrexpStruct: " |
| "expected Result Type to be a struct with two members, " |
| "first member a float scalar or vector, second member " |
| "a 32-bit int scalar or vector with the same number of " |
| "components as the first member")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember2) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_f32_f32 %extinst FrexpStruct %f32_h |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 FrexpStruct: " |
| "expected Result Type to be a struct with two members, " |
| "first member a float scalar or vector, second member " |
| "a 32-bit int scalar or vector with the same number of " |
| "components as the first member")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450FrexpStructXWrongType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f64_0 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 FrexpStruct: " |
| "expected operand X type to be equal to the first " |
| "member of Result Type struct")); |
| } |
| |
| TEST_F(ValidateExtInst, |
| GlslStd450FrexpStructResultTypeStructRightInt16Member2) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h |
| )"; |
| |
| const std::string extension = R"( |
| OpExtension "SPV_AMD_gpu_shader_int16" |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body, extension)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, |
| GlslStd450FrexpStructResultTypeStructWrongInt16Member2) { |
| const std::string body = R"( |
| %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 FrexpStruct: " |
| "expected Result Type to be a struct with two members, " |
| "first member a float scalar or vector, second member " |
| "a 32-bit int scalar or vector with the same number of " |
| "components as the first member")); |
| } |
| |
| TEST_P(ValidateGlslStd450Pack, Success) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string vec_str = |
| num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst " |
| << ext_inst_name << vec_str; |
| body << "%val2 = OpExtInst %s" << total_bit_width << " %extinst " |
| << ext_inst_name << vec_str; |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateGlslStd450Pack, Float32ResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string vec_str = |
| num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst %f" << total_bit_width << " %extinst " |
| << ext_inst_name << vec_str; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected Result Type to be " << total_bit_width |
| << "-bit int scalar type"; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| TEST_P(ValidateGlslStd450Pack, Int16ResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string vec_str = |
| num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << vec_str; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected Result Type to be " << total_bit_width |
| << "-bit int scalar type"; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| TEST_P(ValidateGlslStd450Pack, VNotVector) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst " |
| << ext_inst_name << " %f32_1\n"; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected operand V to be a 32-bit float vector of size " |
| << num_components; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| TEST_P(ValidateGlslStd450Pack, VNotFloatVector) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string vec_str = |
| num_components == 2 ? " %u32vec2_01\n" : " %u32vec4_0123\n"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst " |
| << ext_inst_name << vec_str; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected operand V to be a 32-bit float vector of size " |
| << num_components; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| TEST_P(ValidateGlslStd450Pack, VNotFloat32Vector) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string vec_str = |
| num_components == 2 ? " %f64vec2_01\n" : " %f64vec4_0123\n"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst " |
| << ext_inst_name << vec_str; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected operand V to be a 32-bit float vector of size " |
| << num_components; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| TEST_P(ValidateGlslStd450Pack, VWrongSizeVector) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string vec_str = |
| num_components == 4 ? " %f32vec2_01\n" : " %f32vec4_0123\n"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst " |
| << ext_inst_name << vec_str; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected operand V to be a 32-bit float vector of size " |
| << num_components; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllPack, ValidateGlslStd450Pack, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "PackSnorm4x8", |
| "PackUnorm4x8", |
| "PackSnorm2x16", |
| "PackUnorm2x16", |
| "PackHalf2x16", |
| })); |
| |
| TEST_F(ValidateExtInst, PackDouble2x32Success) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, PackDouble2x32Float32ResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst PackDouble2x32 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to " |
| "be 64-bit float scalar type")); |
| } |
| |
| TEST_F(ValidateExtInst, PackDouble2x32Int64ResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u64 %extinst PackDouble2x32 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to " |
| "be 64-bit float scalar type")); |
| } |
| |
| TEST_F(ValidateExtInst, PackDouble2x32VNotVector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be " |
| "a 32-bit int vector of size 2")); |
| } |
| |
| TEST_F(ValidateExtInst, PackDouble2x32VNotIntVector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst PackDouble2x32 %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be " |
| "a 32-bit int vector of size 2")); |
| } |
| |
| TEST_F(ValidateExtInst, PackDouble2x32VNotInt32Vector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be " |
| "a 32-bit int vector of size 2")); |
| } |
| |
| TEST_F(ValidateExtInst, PackDouble2x32VWrongSize) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec4_0123 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be " |
| "a 32-bit int vector of size 2")); |
| } |
| |
| TEST_P(ValidateGlslStd450Unpack, Success) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string result_type_str = |
| num_components == 2 ? "%f32vec2" : " %f32vec4"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst " << result_type_str << " %extinst " |
| << ext_inst_name << " %u" << total_bit_width << "_1\n"; |
| body << "%val2 = OpExtInst " << result_type_str << " %extinst " |
| << ext_inst_name << " %s" << total_bit_width << "_1\n"; |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateGlslStd450Unpack, ResultTypeNotVector) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string result_type_str = "%f32"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst " << result_type_str << " %extinst " |
| << ext_inst_name << " %u" << total_bit_width << "_1\n"; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected Result Type to be a 32-bit float vector of size " |
| << num_components; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloatVector) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string result_type_str = |
| num_components == 2 ? "%u32vec2" : " %u32vec4"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst " << result_type_str << " %extinst " |
| << ext_inst_name << " %u" << total_bit_width << "_1\n"; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected Result Type to be a 32-bit float vector of size " |
| << num_components; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloat32Vector) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string result_type_str = |
| num_components == 2 ? "%f64vec2" : " %f64vec4"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst " << result_type_str << " %extinst " |
| << ext_inst_name << " %u" << total_bit_width << "_1\n"; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected Result Type to be a 32-bit float vector of size " |
| << num_components; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| TEST_P(ValidateGlslStd450Unpack, ResultTypeWrongSize) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string result_type_str = |
| num_components == 4 ? "%f32vec2" : " %f32vec4"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst " << result_type_str << " %extinst " |
| << ext_inst_name << " %u" << total_bit_width << "_1\n"; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected Result Type to be a 32-bit float vector of size " |
| << num_components; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| TEST_P(ValidateGlslStd450Unpack, ResultPNotInt) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const std::string result_type_str = |
| num_components == 2 ? "%f32vec2" : " %f32vec4"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst " << result_type_str << " %extinst " |
| << ext_inst_name << " %f" << total_bit_width << "_1\n"; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected operand P to be a " << total_bit_width |
| << "-bit int scalar"; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| TEST_P(ValidateGlslStd450Unpack, ResultPWrongBitWidth) { |
| const std::string ext_inst_name = GetParam(); |
| const uint32_t num_components = GetPackedNumComponents(ext_inst_name); |
| const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name); |
| const uint32_t total_bit_width = num_components * packed_bit_width; |
| const uint32_t wrong_bit_width = total_bit_width == 32 ? 64 : 32; |
| const std::string result_type_str = |
| num_components == 2 ? "%f32vec2" : " %f32vec4"; |
| |
| std::ostringstream body; |
| body << "%val1 = OpExtInst " << result_type_str << " %extinst " |
| << ext_inst_name << " %u" << wrong_bit_width << "_1\n"; |
| |
| std::ostringstream expected; |
| expected << "GLSL.std.450 " << ext_inst_name |
| << ": expected operand P to be a " << total_bit_width |
| << "-bit int scalar"; |
| |
| CompileSuccessfully(GenerateShaderCode(body.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str())); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllUnpack, ValidateGlslStd450Unpack, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "UnpackSnorm4x8", |
| "UnpackUnorm4x8", |
| "UnpackSnorm2x16", |
| "UnpackUnorm2x16", |
| "UnpackHalf2x16", |
| })); |
| |
| TEST_F(ValidateExtInst, UnpackDouble2x32Success) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotVector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u64 %extinst UnpackDouble2x32 %f64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type " |
| "to be a 32-bit int vector of size 2")); |
| } |
| |
| TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotIntVector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst UnpackDouble2x32 %f64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type " |
| "to be a 32-bit int vector of size 2")); |
| } |
| |
| TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotInt32Vector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u64vec2 %extinst UnpackDouble2x32 %f64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type " |
| "to be a 32-bit int vector of size 2")); |
| } |
| |
| TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeWrongSize) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32vec4 %extinst UnpackDouble2x32 %f64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type " |
| "to be a 32-bit int vector of size 2")); |
| } |
| |
| TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %u64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to " |
| "be a 64-bit float scalar")); |
| } |
| |
| TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat64) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to " |
| "be a 64-bit float scalar")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450LengthSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Length %f32_1 |
| %val2 = OpExtInst %f32 %extinst Length %f32vec2_01 |
| %val3 = OpExtInst %f32 %extinst Length %f32vec4_0123 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450LengthIntResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst Length %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Length: " |
| "expected Result Type to be a float scalar type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450LengthIntX) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Length %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Length: " |
| "expected operand X to be of float scalar or " |
| "vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450LengthDifferentType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst Length %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Length: " |
| "expected operand X component type to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450DistanceSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Distance %f32_0 %f32_1 |
| %val2 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec2_12 |
| %val3 = OpExtInst %f32 %extinst Distance %f32vec4_0123 %f32vec4_1234 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450DistanceIntResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst Distance %f32vec2_01 %f32vec2_12 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Distance: " |
| "expected Result Type to be a float scalar type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450DistanceIntP0) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Distance %u32_0 %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Distance: " |
| "expected operand P0 to be of float scalar or " |
| "vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP0) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Distance %f64vec2_01 %f32vec2_12 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Distance: " |
| "expected operand P0 component type to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450DistanceIntP1) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Distance %f32_0 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Distance: " |
| "expected operand P1 to be of float scalar or " |
| "vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP1) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Distance %f32vec2_12 %f64vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Distance: " |
| "expected operand P1 component type to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450DistanceDifferentSize) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec4_0123 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Distance: " |
| "expected operands P0 and P1 to have the same number " |
| "of components")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450CrossSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_012 %f32vec3_123 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450CrossIntVectorResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32vec3 %extinst Cross %f32vec3_012 %f32vec3_123 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Cross: " |
| "expected Result Type to be a float vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450CrossResultTypeWrongSize) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst Cross %f32vec3_012 %f32vec3_123 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Cross: " |
| "expected Result Type to have 3 components")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450CrossXWrongType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec3 %extinst Cross %f64vec3_012 %f32vec3_123 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Cross: " |
| "expected operand X type to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450CrossYWrongType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_123 %f64vec3_012 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Cross: " |
| "expected operand Y type to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450RefractSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst Refract %f32_1 %f32_1 %f32_1 |
| %val2 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f16_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450RefractIntVectorResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Refract: " |
| "expected Result Type to be a float scalar or " |
| "vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450RefractIntVectorI) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst Refract %u32vec2_01 %f32vec2_01 %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Refract: " |
| "expected operand I to be of type equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450RefractIntVectorN) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %u32vec2_01 %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Refract: " |
| "expected operand N to be of type equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450RefractIntEta) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Refract: " |
| "expected operand Eta to be a float scalar")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450RefractFloat64Eta) { |
| // SPIR-V issue 337: Eta can be 64-bit float scalar. |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), Eq("")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450RefractVectorEta) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 Refract: " |
| "expected operand Eta to be a float scalar")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input |
| %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %f32vec2_input |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidInternalSuccess) { |
| const std::string body = R"( |
| %ld1 = OpLoad %f32 %f32_input |
| %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %ld1 |
| %ld2 = OpLoad %f32vec2 %f32vec2_input |
| %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %ld2 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| getValidatorOptions()->before_hlsl_legalization = true; |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidInternalInvalidDataF32) { |
| const std::string body = R"( |
| %ld1 = OpLoad %f32 %f32_input |
| %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %ld1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtCentroid: " |
| "expected Interpolant to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, |
| GlslStd450InterpolateAtCentroidInternalInvalidDataF32Vec2) { |
| const std::string body = R"( |
| %ld2 = OpLoad %f32vec2 %f32vec2_input |
| %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %ld2 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtCentroid: " |
| "expected Interpolant to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNoCapability) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtCentroid requires " |
| "capability InterpolationFunction")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidIntResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst InterpolateAtCentroid %f32_input |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtCentroid: " |
| "expected Result Type to be a 32-bit float scalar " |
| "or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidF64ResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst InterpolateAtCentroid %f32_input |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtCentroid: " |
| "expected Result Type to be a 32-bit float scalar " |
| "or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNotPointer) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtCentroid: " |
| "expected Interpolant to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongDataType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32vec2_input |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtCentroid: " |
| "expected Interpolant data type to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongStorageClass) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_output |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtCentroid: " |
| "expected Interpolant storage class to be Input")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongExecutionModel) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode( |
| body, "OpCapability InterpolationFunction\n", "Vertex")); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtCentroid requires " |
| "Fragment execution model")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1 |
| %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %f32vec2_input %u32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleInternalSuccess) { |
| const std::string body = R"( |
| %ld1 = OpLoad %f32 %f32_input |
| %val1 = OpExtInst %f32 %extinst InterpolateAtSample %ld1 %u32_1 |
| %ld2 = OpLoad %f32vec2 %f32vec2_input |
| %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %ld2 %u32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| getValidatorOptions()->before_hlsl_legalization = true; |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleInternalInvalidDataF32) { |
| const std::string body = R"( |
| %ld1 = OpLoad %f32 %f32_input |
| %val1 = OpExtInst %f32 %extinst InterpolateAtSample %ld1 %u32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample: " |
| "expected Interpolant to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, |
| GlslStd450InterpolateAtSampleInternalInvalidDataF32Vec2) { |
| const std::string body = R"( |
| %ld2 = OpLoad %f32vec2 %f32vec2_input |
| %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %ld2 %u32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample: " |
| "expected Interpolant to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNoCapability) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample requires " |
| "capability InterpolationFunction")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleIntResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst InterpolateAtSample %f32_input %u32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample: " |
| "expected Result Type to be a 32-bit float scalar " |
| "or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleF64ResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst InterpolateAtSample %f32_input %u32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample: " |
| "expected Result Type to be a 32-bit float scalar " |
| "or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNotPointer) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_1 %u32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample: " |
| "expected Interpolant to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongDataType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32vec2_input %u32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample: " |
| "expected Interpolant data type to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongStorageClass) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_output %u32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample: " |
| "expected Interpolant storage class to be Input")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleFloatSample) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %f32_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample: " |
| "expected Sample to be 32-bit integer")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleU64Sample) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u64_1 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample: " |
| "expected Sample to be 32-bit integer")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongExecutionModel) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode( |
| body, "OpCapability InterpolationFunction\n", "Vertex")); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtSample requires " |
| "Fragment execution model")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01 |
| %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetInternalSuccess) { |
| const std::string body = R"( |
| %ld1 = OpLoad %f32 %f32_input |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %ld1 %f32vec2_01 |
| %ld2 = OpLoad %f32vec2 %f32vec2_input |
| %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %ld2 %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| getValidatorOptions()->before_hlsl_legalization = true; |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetInternalInvalidDataF32) { |
| const std::string body = R"( |
| %ld1 = OpLoad %f32 %f32_input |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %ld1 %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Interpolant to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, |
| GlslStd450InterpolateAtOffsetInternalInvalidDataF32Vec2) { |
| const std::string body = R"( |
| %ld2 = OpLoad %f32vec2 %f32vec2_input |
| %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %ld2 %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Interpolant to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNoCapability) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset requires " |
| "capability InterpolationFunction")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetIntResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst InterpolateAtOffset %f32_input %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Result Type to be a 32-bit float scalar " |
| "or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetF64ResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst InterpolateAtOffset %f32_input %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Result Type to be a 32-bit float scalar " |
| "or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNotPointer) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_1 %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Interpolant to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongDataType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Interpolant data type to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongStorageClass) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_output %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Interpolant storage class to be Input")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32_0 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Offset to be a vector of 2 32-bit floats")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector2) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec3_012 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Offset to be a vector of 2 32-bit floats")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloatVector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Offset to be a vector of 2 32-bit floats")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloat32Vector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f64vec2_01 |
| )"; |
| |
| CompileSuccessfully( |
| GenerateShaderCode(body, "OpCapability InterpolationFunction\n")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset: " |
| "expected Offset to be a vector of 2 32-bit floats")); |
| } |
| |
| TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongExecutionModel) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateShaderCode( |
| body, "OpCapability InterpolationFunction\n", "Vertex")); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("GLSL.std.450 InterpolateAtOffset requires " |
| "Fragment execution model")); |
| } |
| |
| TEST_P(ValidateOpenCLStdSqrtLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01\n"; |
| ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name |
| << " %f32vec4_0123\n"; |
| ss << "%val4 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n"; |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdSqrtLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a float scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdSqrtLike, IntOperand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| AllSqrtLike, ValidateOpenCLStdSqrtLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "acos", "acosh", "acospi", "asin", |
| "asinh", "asinpi", "atan", "atanh", |
| "atanpi", "cbrt", "ceil", "cos", |
| "cosh", "cospi", "erfc", "erf", |
| "exp", "exp2", "exp10", "expm1", |
| "fabs", "floor", "log", "log2", |
| "log10", "log1p", "logb", "rint", |
| "round", "rsqrt", "sin", "sinh", |
| "sinpi", "sqrt", "tan", "tanh", |
| "tanpi", "tgamma", "trunc", "half_cos", |
| "half_exp", "half_exp2", "half_exp10", "half_log", |
| "half_log2", "half_log10", "half_recip", "half_rsqrt", |
| "half_sin", "half_sqrt", "half_tan", "lgamma", |
| "native_cos", "native_exp", "native_exp2", "native_exp10", |
| "native_log", "native_log2", "native_log10", "native_recip", |
| "native_rsqrt", "native_sin", "native_sqrt", "native_tan", |
| "degrees", "radians", "sign", |
| })); |
| |
| TEST_P(ValidateOpenCLStdFMinLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %f32_1\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01 %f32vec2_12\n"; |
| ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name |
| << " %f64_0 %f64_0\n"; |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdFMinLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a float scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFMinLike, IntOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFMinLike, IntOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateOpenCLStdFMinLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "atan2", "atan2pi", "copysign", |
| "fdim", "fmax", "fmin", |
| "fmod", "maxmag", "minmag", |
| "hypot", "nextafter", "pow", |
| "powr", "remainder", "half_divide", |
| "half_powr", "native_divide", "native_powr", |
| "step", "fmax_common", "fmin_common", |
| })); |
| |
| TEST_P(ValidateOpenCLStdFClampLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %f32_1 %f32_2\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n"; |
| ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name |
| << " %f64_0 %f64_0 %f64_1\n"; |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdFClampLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %f32_0 %f32_1 %f32_2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a float scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFClampLike, IntOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %u32_0 %f32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFClampLike, IntOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %f32_0 %u32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFClampLike, IntOperand3) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %f32_1 %f32_0 %u32_2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to " |
| "Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateOpenCLStdFClampLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "fma", |
| "mad", |
| "fclamp", |
| "mix", |
| "smoothstep", |
| })); |
| |
| TEST_P(ValidateOpenCLStdSAbsLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n"; |
| ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n"; |
| ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n"; |
| ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n"; |
| ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01\n"; |
| ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01\n"; |
| ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01\n"; |
| ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01\n"; |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdSAbsLike, FloatResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be an int scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdSAbsLike, FloatOperand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdSAbsLike, U64Operand) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateOpenCLStdSAbsLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "s_abs", |
| "clz", |
| "ctz", |
| "popcount", |
| "u_abs", |
| })); |
| |
| TEST_P(ValidateOpenCLStdUMinLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01\n"; |
| ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01\n"; |
| ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01\n"; |
| ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01\n"; |
| ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name |
| << " %u64_1 %u64_0\n"; |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMinLike, FloatResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be an int scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMinLike, FloatOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMinLike, FloatOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMinLike, U64Operand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMinLike, U64Operand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateOpenCLStdUMinLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "s_max", |
| "u_max", |
| "s_min", |
| "u_min", |
| "s_abs_diff", |
| "s_add_sat", |
| "u_add_sat", |
| "s_mul_hi", |
| "rotate", |
| "s_sub_sat", |
| "u_sub_sat", |
| "s_hadd", |
| "u_hadd", |
| "s_rhadd", |
| "u_rhadd", |
| "u_abs_diff", |
| "u_mul_hi", |
| })); |
| |
| TEST_P(ValidateOpenCLStdUClampLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_0 %u32_1 %u32_2\n"; |
| ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_0 %u32_1 %u32_2\n"; |
| ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_0 %u32_1 %u32_2\n"; |
| ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_0 %u32_1 %u32_2\n"; |
| ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n"; |
| ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n"; |
| ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n"; |
| ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n"; |
| ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name |
| << " %u64_1 %u64_0 %u64_1\n"; |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdUClampLike, FloatResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %u32_0 %u32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be an int scalar " |
| "or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUClampLike, FloatOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %f32_0 %u32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUClampLike, FloatOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %u32_0 %f32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUClampLike, FloatOperand3) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %u32_0 %u32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUClampLike, U64Operand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %f32_0 %u32_0 %u64_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUClampLike, U64Operand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %u32_0 %f32_0 %u64_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUClampLike, U64Operand3) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %u32_0 %u32_0 %u64_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateOpenCLStdUClampLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "s_clamp", |
| "u_clamp", |
| "s_mad_hi", |
| "u_mad_sat", |
| "s_mad_sat", |
| "u_mad_hi", |
| })); |
| |
| // ------------------------------------------------------------- |
| TEST_P(ValidateOpenCLStdUMul24Like, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01\n"; |
| ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01\n"; |
| ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01\n"; |
| ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01\n"; |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMul24Like, FloatResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a 32-bit int scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMul24Like, U64ResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u64 %extinst " + ext_inst_name + " %u64_0 %u64_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a 32-bit int scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMul24Like, U64Operand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMul24Like, U64Operand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllUMul24Like, ValidateOpenCLStdUMul24Like, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "s_mul24", |
| "u_mul24", |
| })); |
| |
| TEST_P(ValidateOpenCLStdUMad24Like, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_0 %u32_1 %u32_2\n"; |
| ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_0 %u32_1 %u32_2\n"; |
| ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_0 %u32_1 %u32_2\n"; |
| ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u32_0 %u32_1 %u32_2\n"; |
| ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n"; |
| ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n"; |
| ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n"; |
| ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n"; |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMad24Like, FloatResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %u32_0 %u32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a 32-bit int scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMad24Like, U64ResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u64 %extinst " + ext_inst_name + |
| " %u64_0 %u64_0 %u64_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a 32-bit int scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %f32_0 %u32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %u32_0 %f32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand3) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %u32_0 %u32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMad24Like, U64Operand1) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %f32_0 %u32_0 %u64_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMad24Like, U64Operand2) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %u32_0 %f32_0 %u64_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUMad24Like, U64Operand3) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %u32_0 %u32_0 %u64_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected types of all operands to be equal to Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllUMad24Like, ValidateOpenCLStdUMad24Like, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "s_mad24", |
| "u_mad24", |
| })); |
| |
| TEST_F(ValidateExtInst, OpenCLStdCrossSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_012 %f32vec3_123 |
| %val2 = OpExtInst %f32vec4 %extinst cross %f32vec4_0123 %f32vec4_0123 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdCrossIntVectorResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32vec3 %extinst cross %f32vec3_012 %f32vec3_123 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std cross: " |
| "expected Result Type to be a float vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdCrossResultTypeWrongSize) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst cross %f32vec3_012 %f32vec3_123 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std cross: " |
| "expected Result Type to have 3 or 4 components")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdCrossXWrongType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec3 %extinst cross %f64vec3_012 %f32vec3_123 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std cross: " |
| "expected operand X type to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdCrossYWrongType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_123 %f64vec3_012 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std cross: " |
| "expected operand Y type to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdLengthLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32vec2_01\n"; |
| ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32vec4_0123\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdLengthLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32vec2_01\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected Result Type to be a float scalar type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdLengthLike, IntX) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32vec2_01\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected operand P to be a float scalar or vector")); |
| } |
| |
| TEST_P(ValidateOpenCLStdLengthLike, VectorTooBig) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %f32vec8_01010101\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected operand P to have no more than 4 components")); |
| } |
| |
| TEST_P(ValidateOpenCLStdLengthLike, DifferentType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32vec2_01\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected operand P component type to be equal to " |
| "Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllLengthLike, ValidateOpenCLStdLengthLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "length", |
| "fast_length", |
| })); |
| |
| TEST_P(ValidateOpenCLStdDistanceLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32vec2_01 %f32vec2_01\n"; |
| ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32vec4_0123 %f32vec4_1234\n"; |
| ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdDistanceLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + |
| " %f32vec2_01 %f32vec2_12\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected Result Type to be a float scalar type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdDistanceLike, IntP0) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %u32vec2_01 %f32vec2_12\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected operand P0 to be of float scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdDistanceLike, VectorTooBig) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %f32vec8_01010101 %f32vec8_01010101\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected operand P0 to have no more than 4 components")); |
| } |
| |
| TEST_P(ValidateOpenCLStdDistanceLike, F64P0) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + |
| " %f64vec2_01 %f32vec2_12\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std " + ext_inst_name + |
| ": " |
| "expected operand P0 component type to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdDistanceLike, DifferentOperands) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + |
| " %f64vec2_01 %f32vec2_12\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected operands P0 and P1 to be of the same type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllDistanceLike, ValidateOpenCLStdDistanceLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "distance", |
| "fast_distance", |
| })); |
| |
| TEST_P(ValidateOpenCLStdNormalizeLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01\n"; |
| ss << "%val2 = OpExtInst %f32vec4 %extinst " << ext_inst_name |
| << " %f32vec4_0123\n"; |
| ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdNormalizeLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected Result Type to be a float scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdNormalizeLike, VectorTooBig) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = "%val1 = OpExtInst %f32vec8 %extinst " + |
| ext_inst_name + " %f32vec8_01010101\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected Result Type to have no more than 4 components")); |
| } |
| |
| TEST_P(ValidateOpenCLStdNormalizeLike, DifferentType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string body = |
| "%val1 = OpExtInst %f64vec2 %extinst " + ext_inst_name + " %f32vec2_01\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected operand P type to be equal to Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllNormalizeLike, ValidateOpenCLStdNormalizeLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "normalize", |
| "fast_normalize", |
| })); |
| |
| TEST_F(ValidateExtInst, OpenCLStdBitselectSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst bitselect %f32_2 %f32_1 %f32_1 |
| %val2 = OpExtInst %f32vec4 %extinst bitselect %f32vec4_0123 %f32vec4_1234 %f32vec4_0123 |
| %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %u32_1 |
| %val4 = OpExtInst %u32vec4 %extinst bitselect %u32vec4_0123 %u32vec4_0123 %u32vec4_0123 |
| %val5 = OpExtInst %u64 %extinst bitselect %u64_2 %u64_1 %u64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdBitselectWrongResultType) { |
| const std::string body = R"( |
| %val3 = OpExtInst %struct_f32_f32 %extinst bitselect %u32_2 %u32_1 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std bitselect: " |
| "expected Result Type to be an int or float scalar or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdBitselectAWrongType) { |
| const std::string body = R"( |
| %val3 = OpExtInst %u32 %extinst bitselect %f32_2 %u32_1 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std bitselect: " |
| "expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdBitselectBWrongType) { |
| const std::string body = R"( |
| %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %f32_1 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std bitselect: " |
| "expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdBitselectCWrongType) { |
| const std::string body = R"( |
| %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std bitselect: " |
| "expected types of all operands to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdSelectSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %u32_1 |
| %val2 = OpExtInst %f32vec4 %extinst select %f32vec4_0123 %f32vec4_1234 %u32vec4_0123 |
| %val3 = OpExtInst %u32 %extinst select %u32_2 %u32_1 %u32_1 |
| %val4 = OpExtInst %u32vec4 %extinst select %u32vec4_0123 %u32vec4_0123 %u32vec4_0123 |
| %val5 = OpExtInst %u64 %extinst select %u64_2 %u64_1 %u64_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdSelectWrongResultType) { |
| const std::string body = R"( |
| %val3 = OpExtInst %struct_f32_f32 %extinst select %u32_2 %u32_1 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std select: " |
| "expected Result Type to be an int or float scalar or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdSelectAWrongType) { |
| const std::string body = R"( |
| %val3 = OpExtInst %u32 %extinst select %f32_2 %u32_1 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std select: " |
| "expected operand A type to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdSelectBWrongType) { |
| const std::string body = R"( |
| %val3 = OpExtInst %u32 %extinst select %u32_2 %f32_1 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std select: " |
| "expected operand B type to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdSelectCWrongType) { |
| const std::string body = R"( |
| %val3 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std select: " |
| "expected operand C to be an int scalar or vector")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdSelectCWrongComponentNumber) { |
| const std::string body = R"( |
| %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std select: " |
| "expected operand C to have the same number of " |
| "components as Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdSelectCWrongBitWidth) { |
| const std::string body = R"( |
| %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u64vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std select: " |
| "expected operand C to have the same bit width as Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical32) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string rounding_mode = |
| ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : ""; |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| if (std::string::npos == ext_inst_name.find("halfn")) { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n"; |
| ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f64_0 %u32_2 %ptr" << rounding_mode << "\n"; |
| } else { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n"; |
| ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32vec4_0123 %u32_0 %ptr" << rounding_mode << "\n"; |
| ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f64vec2_01 %u32_2 %ptr" << rounding_mode << "\n"; |
| } |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical64) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string rounding_mode = |
| ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : ""; |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| if (std::string::npos == ext_inst_name.find("halfn")) { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32_1 %u64_1 %ptr" << rounding_mode << "\n"; |
| ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f64_0 %u64_2 %ptr" << rounding_mode << "\n"; |
| } else { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32vec2_01 %u64_1 %ptr" << rounding_mode << "\n"; |
| ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32vec4_0123 %u64_0 %ptr" << rounding_mode << "\n"; |
| ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f64vec2_01 %u64_2 %ptr" << rounding_mode << "\n"; |
| } |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdVStoreHalfLike, NonVoidResultType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string rounding_mode = |
| ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : ""; |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| if (std::string::npos == ext_inst_name.find("halfn")) { |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n"; |
| } else { |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n"; |
| } |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be void")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVStoreHalfLike, WrongDataType) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string rounding_mode = |
| ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : ""; |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| if (std::string::npos == ext_inst_name.find("halfn")) { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f64vec2_01 %u32_1 %ptr" << rounding_mode << "\n"; |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Data to be a 32 or 64-bit float scalar")); |
| } else { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f64_0 %u32_1 %ptr" << rounding_mode << "\n"; |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Data to be a 32 or 64-bit float vector")); |
| } |
| } |
| |
| TEST_P(ValidateOpenCLStdVStoreHalfLike, AddressingModelLogical) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string rounding_mode = |
| ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : ""; |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| if (std::string::npos == ext_inst_name.find("halfn")) { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n"; |
| } else { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n"; |
| } |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| " can only be used with physical addressing models")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVStoreHalfLike, OffsetNotSizeT) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string rounding_mode = |
| ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : ""; |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| if (std::string::npos == ext_inst_name.find("halfn")) { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n"; |
| } else { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n"; |
| } |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": " |
| "expected operand Offset to be of type size_t (64-bit integer " |
| "for the addressing model used in the module)")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVStoreHalfLike, PNotPointer) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string rounding_mode = |
| ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : ""; |
| |
| std::ostringstream ss; |
| if (std::string::npos == ext_inst_name.find("halfn")) { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32_0 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n"; |
| } else { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32vec2_01 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n"; |
| } |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Operand '89[%_ptr_Workgroup_half]' cannot be a type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVStoreHalfLike, ConstPointer) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string rounding_mode = |
| ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : ""; |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant " |
| "%f16vec8_uniform_constant %u32_1\n"; |
| if (std::string::npos == ext_inst_name.find("halfn")) { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n"; |
| } else { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n"; |
| } |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected operand P storage class to be Generic, " |
| "CrossWorkgroup, Workgroup or Function")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeInt) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string rounding_mode = |
| ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : ""; |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n"; |
| if (std::string::npos == ext_inst_name.find("halfn")) { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n"; |
| } else { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n"; |
| } |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected operand P data type to be 16-bit float scalar")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeFloat32) { |
| const std::string ext_inst_name = GetParam(); |
| const std::string rounding_mode = |
| ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : ""; |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n"; |
| if (std::string::npos == ext_inst_name.find("halfn")) { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n"; |
| } else { |
| ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name |
| << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n"; |
| } |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected operand P data type to be 16-bit float scalar")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllVStoreHalfLike, ValidateOpenCLStdVStoreHalfLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "vstore_half", |
| "vstore_half_r", |
| "vstore_halfn", |
| "vstore_halfn_r", |
| "vstorea_halfn", |
| "vstorea_halfn_r", |
| })); |
| |
| TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical32) { |
| const std::string ext_inst_name = GetParam(); |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %u32_1 %ptr 2\n"; |
| ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name |
| << " %u32_1 %ptr 3\n"; |
| ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name |
| << " %u32_1 %ptr 4\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical64) { |
| const std::string ext_inst_name = GetParam(); |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %u64_1 %ptr 2\n"; |
| ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name |
| << " %u64_1 %ptr 3\n"; |
| ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name |
| << " %u64_1 %ptr 4\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdVLoadHalfLike, ResultTypeNotFloatVector) { |
| const std::string ext_inst_name = GetParam(); |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %u32_1 %ptr 1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a float vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVLoadHalfLike, AddressingModelLogical) { |
| const std::string ext_inst_name = GetParam(); |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %u32_1 %ptr 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| " can only be used with physical addressing models")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetNotSizeT) { |
| const std::string ext_inst_name = GetParam(); |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %u64_1 %ptr 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected operand Offset to be of type size_t (32-bit " |
| "integer for the addressing model used in the module)")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVLoadHalfLike, PNotPointer) { |
| const std::string ext_inst_name = GetParam(); |
| |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %u32_1 %f16_ptr_workgroup 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Operand '89[%_ptr_Workgroup_half]' cannot be a type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetWrongStorageType) { |
| const std::string ext_inst_name = GetParam(); |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %u32_1 %ptr 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected operand P storage class to be UniformConstant, " |
| "Generic, CrossWorkgroup, Workgroup or Function")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeInt) { |
| const std::string ext_inst_name = GetParam(); |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %u32_1 %ptr 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected operand P data type to be 16-bit float scalar")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeFloat32) { |
| const std::string ext_inst_name = GetParam(); |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %u32_1 %ptr 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected operand P data type to be 16-bit float scalar")); |
| } |
| |
| TEST_P(ValidateOpenCLStdVLoadHalfLike, WrongN) { |
| const std::string ext_inst_name = GetParam(); |
| |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %u32_1 %ptr 3\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected literal N to be equal to the number of " |
| "components of Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllVLoadHalfLike, ValidateOpenCLStdVLoadHalfLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "vload_halfn", |
| "vloada_halfn", |
| })); |
| |
| TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical32) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n"; |
| ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u32_1 %ptr 3\n"; |
| ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u32_1 %ptr 4\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical32) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant " |
| "%u32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n"; |
| ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u32_1 %ptr 3\n"; |
| ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u32_1 %ptr 4\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical64) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n"; |
| ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u64_1 %ptr 3\n"; |
| ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u64_1 %ptr 4\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical64) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant " |
| "%u32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u64_1 %ptr 2\n"; |
| ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u64_1 %ptr 3\n"; |
| ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u64_1 %ptr 4\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadNWrongResultType) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst vloadn %u32_1 %ptr 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std vloadn: " |
| "expected Result Type to be an int or float vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadNAddressingModelLogical) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vloadn can only be used with physical " |
| "addressing models")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadNOffsetNotSizeT) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std vloadn: expected operand Offset to be of type size_t " |
| "(32-bit integer for the addressing model used in the module)")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadNPNotPointer) { |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 " |
| "%f32_ptr_uniform_constant 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("Operand '120[%_ptr_UniformConstant_float]' cannot be a " |
| "type")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadNWrongStorageClass) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %u32_ptr_input %u32vec8_input %u32_1\n"; |
| ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vloadn: expected operand P storage class " |
| "to be UniformConstant, Generic, CrossWorkgroup, " |
| "Workgroup or Function")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadNWrongComponentType) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vloadn: expected operand P data type to be " |
| "equal to component type of Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadNWrongN) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 3\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vloadn: expected literal N to be equal to " |
| "the number of components of Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical32) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant " |
| "%f16vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n"; |
| ss << "%val2 = OpExtInst %f64 %extinst vload_half %u32_1 %ptr\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical64) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant " |
| "%f16vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n"; |
| ss << "%val2 = OpExtInst %f64 %extinst vload_half %u64_1 %ptr\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadHalfWrongResultType) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant " |
| "%f16vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %u32 %extinst vload_half %u32_1 %ptr\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vload_half: " |
| "expected Result Type to be a float scalar type")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadHalfAddressingModelLogical) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant " |
| "%f16vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vload_half can only be used with physical " |
| "addressing models")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadHalfOffsetNotSizeT) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant " |
| "%f16vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std vload_half: expected operand Offset to be of type size_t " |
| "(32-bit integer for the addressing model used in the module)")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadHalfPNotPointer) { |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 " |
| "%f16_ptr_uniform_constant\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Operand '114[%_ptr_UniformConstant_half]' cannot be a " |
| "type")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadHalfWrongStorageClass) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std vload_half: expected operand P storage class to be " |
| "UniformConstant, Generic, CrossWorkgroup, Workgroup or Function")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadHalfPDataTypeInt) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant " |
| "%u32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vload_half: expected operand P data type " |
| "to be 16-bit float scalar")); |
| } |
| |
| TEST_F(ValidateExtInst, VLoadHalfPDataTypeFloat32) { |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vload_half: expected operand P data type " |
| "to be 16-bit float scalar")); |
| } |
| |
| TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical32) { |
| std::ostringstream ss; |
| ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n"; |
| ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n"; |
| ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n"; |
| ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u32_1 " |
| "%ptr_g\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical64) { |
| std::ostringstream ss; |
| ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n"; |
| ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n"; |
| ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u64_1 %ptr_g\n"; |
| ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u64_1 " |
| "%ptr_g\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical32) { |
| std::ostringstream ss; |
| ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n"; |
| ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n"; |
| ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n"; |
| ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u32_1 " |
| "%ptr_g\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical64) { |
| std::ostringstream ss; |
| ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n"; |
| ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n"; |
| ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u64_1 %ptr_g\n"; |
| ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u64_1 " |
| "%ptr_g\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, VStoreNResultTypeNotVoid) { |
| std::ostringstream ss; |
| ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n"; |
| ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vstoren: expected Result Type to be void")); |
| } |
| |
| TEST_F(ValidateExtInst, VStoreNDataWrongType) { |
| std::ostringstream ss; |
| ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n"; |
| ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n"; |
| ss << "%val1 = OpExtInst %void %extinst vstoren %f32_1 %u32_1 %ptr_g\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std vstoren: expected Data to be an int or float vector")); |
| } |
| |
| TEST_F(ValidateExtInst, VStoreNAddressingModelLogical) { |
| std::ostringstream ss; |
| ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n"; |
| ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n"; |
| ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vstoren can only be used with physical " |
| "addressing models")); |
| } |
| |
| TEST_F(ValidateExtInst, VStoreNOffsetNotSizeT) { |
| std::ostringstream ss; |
| ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n"; |
| ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n"; |
| ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std vstoren: expected operand Offset to be of type size_t " |
| "(64-bit integer for the addressing model used in the module)")); |
| } |
| |
| TEST_F(ValidateExtInst, VStoreNPNotPointer) { |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 " |
| "%f32_ptr_generic\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Operand '127[%_ptr_Generic_float]' cannot be a type")); |
| } |
| |
| TEST_F(ValidateExtInst, VStoreNWrongStorageClass) { |
| std::ostringstream ss; |
| ss << "%ptr_w = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_w\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std vstoren: expected operand P storage class " |
| "to be Generic, CrossWorkgroup, Workgroup or Function")); |
| } |
| |
| TEST_F(ValidateExtInst, VStorePWrongDataType) { |
| std::ostringstream ss; |
| ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n"; |
| ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n"; |
| ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std vstoren: expected operand P data type to " |
| "be equal to the type of operand Data components")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffleSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %u32vec2_01 |
| %val2 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec4_0123 |
| %val3 = OpExtInst %u32vec2 %extinst shuffle %u32vec4_0123 %u32vec2_01 |
| %val4 = OpExtInst %u32vec4 %extinst shuffle %u32vec4_0123 %u32vec4_0123 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffleWrongResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst shuffle %f32vec4_0123 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle: " |
| "expected Result Type to be an int or float vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffleResultTypeInvalidNumComponents) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec3 %extinst shuffle %f32vec4_0123 %u32vec3_012 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle: " |
| "expected Result Type to have 2, 4, 8 or 16 components")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffleXWrongType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle %f32_0 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle: " |
| "expected operand X to be an int or float vector")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidNumComponents) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec3_012 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle: " |
| "expected operand X to have 2, 4, 8 or 16 components")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidComponentType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std shuffle: " |
| "expected operand X and Result Type to have equal component types")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskNotIntVector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle: " |
| "expected operand Shuffle Mask to be an int vector")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidNumComponents) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle: " |
| "expected operand Shuffle Mask to have the same number " |
| "of components as Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidBitWidth) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle: " |
| "expected operand Shuffle Mask components to have the " |
| "same bit width as Result Type components")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffle2Success) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01 |
| %val2 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec4_0123 |
| %val3 = OpExtInst %u32vec2 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec2_01 |
| %val4 = OpExtInst %u32vec4 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec4_0123 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffle2WrongResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle2: " |
| "expected Result Type to be an int or float vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffle2ResultTypeInvalidNumComponents) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec3 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec3_012 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle2: " |
| "expected Result Type to have 2, 4, 8 or 16 components")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffle2XWrongType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32_0 %f32_0 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle2: " |
| "expected operand X to be an int or float vector")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffle2YTypeDifferentFromX) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec2_01 %f32vec4_0123 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle2: " |
| "expected operands X and Y to be of the same type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidNumComponents) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec3_012 %f32vec3_012 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle2: " |
| "expected operand X to have 2, 4, 8 or 16 components")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidComponentType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std shuffle2: " |
| "expected operand X and Result Type to have equal component types")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskNotIntVector) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %f32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle2: " |
| "expected operand Shuffle Mask to be an int vector")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidNumComponents) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle2: " |
| "expected operand Shuffle Mask to have the same number " |
| "of components as Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidBitWidth) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std shuffle2: " |
| "expected operand Shuffle Mask components to have the " |
| "same bit width as Result Type components")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrintfSuccess) { |
| const std::string body = R"( |
| %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0 |
| %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrintfBoolResultType) { |
| const std::string body = R"( |
| %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0 |
| %val1 = OpExtInst %bool %extinst printf %format %u32_0 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std printf: expected Result Type to be a 32-bit int type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrintfU64ResultType) { |
| const std::string body = R"( |
| %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0 |
| %val1 = OpExtInst %u64 %extinst printf %format %u32_0 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std printf: expected Result Type to be a 32-bit int type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotPointer) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst printf %u8_ptr_uniform_constant %u32_0 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("Operand '137[%_ptr_UniformConstant_uchar]' cannot be a " |
| "type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotUniformConstStorageClass) { |
| const std::string body = R"( |
| %format_const = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0 |
| %format = OpBitcast %u8_ptr_generic %format_const |
| %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std printf: expected Format storage class to " |
| "be UniformConstant")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotU8Pointer) { |
| const std::string body = R"( |
| %format = OpAccessChain %u32_ptr_uniform_constant %u32vec8_uniform_constant %u32_0 |
| %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std printf: expected Format data type to be 8-bit int")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Success) { |
| const std::string body = R"( |
| %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0 |
| %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Physical64Success) { |
| const std::string body = R"( |
| %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0 |
| %val1 = OpExtInst %void %extinst prefetch %ptr %u64_256 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body, "", "Physical64")); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Success) { |
| const std::string body = R"( |
| %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0 |
| %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Vec2Success) { |
| const std::string body = R"( |
| %ptr = OpAccessChain %f32vec2_ptr_cross_workgroup %f32vec2arr_cross_workgroup %u32_0 |
| %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrefetchResultTypeNotVoid) { |
| const std::string body = R"( |
| %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0 |
| %val1 = OpExtInst %u32 %extinst prefetch %ptr %u32_256 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std prefetch: expected Result Type to be void")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotPointer) { |
| const std::string body = R"( |
| %val1 = OpExtInst %void %extinst prefetch %u32_ptr_cross_workgroup %u32_256 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Operand '99[%_ptr_CrossWorkgroup_uint]' cannot be a " |
| "type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotCrossWorkgroup) { |
| const std::string body = R"( |
| %ptr = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0 |
| %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std prefetch: expected operand Ptr storage " |
| "class to be CrossWorkgroup")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrefetchInvalidDataType) { |
| const std::string body = R"( |
| %ptr = OpAccessChain %struct_ptr_cross_workgroup %struct_arr_cross_workgroup %u32_0 |
| %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std prefetch: expected Ptr data type to be int " |
| "or float scalar or vector")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrefetchAddressingModelLogical) { |
| const std::string body = R"( |
| %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0 |
| %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body, "", "Logical")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std prefetch can only be used with physical " |
| "addressing models")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdPrefetchNumElementsNotSizeT) { |
| const std::string body = R"( |
| %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0 |
| %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body, "", "Physical64")); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std prefetch: expected operand Num Elements to " |
| "be of type size_t (64-bit integer for the addressing " |
| "model used in the module)")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFractLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_f32 = OpVariable %f32_ptr_function Function\n"; |
| ss << "%var_f32vec2 = OpVariable %f32vec2_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %var_f32\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01 %var_f32vec2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdFractLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_f32 = OpVariable %f32_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %f32_0 %var_f32\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a float scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFractLike, XWrongType) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_f32 = OpVariable %f32_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f64_0 %var_f32\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected type of operand X to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFractLike, NotPointer) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_f32 = OpVariable %f32_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected the last operand to be a pointer")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFractLike, PointerInvalidStorageClass) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected storage class of the pointer to be " |
| "Generic, CrossWorkgroup, Workgroup or Function")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFractLike, PointerWrongDataType) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_u32 = OpVariable %u32_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %var_u32\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std " + ext_inst_name + |
| ": expected data type of the pointer to be equal to Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllFractLike, ValidateOpenCLStdFractLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "fract", |
| "modf", |
| "sincos", |
| })); |
| |
| TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) { |
| const std::string body = R"( |
| %var_u32 = OpVariable %u32_ptr_function Function |
| %var_u32vec2 = OpVariable %u32vec2_ptr_function Function |
| %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32 |
| %val2 = OpExtInst %f32vec2 %extinst remquo %f32vec2_01 %f32vec2_12 %var_u32vec2 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) { |
| const std::string body = R"( |
| %var_u32 = OpVariable %u32_ptr_function Function |
| %val1 = OpExtInst %u32 %extinst remquo %f32_3 %f32_2 %var_u32 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std remquo: " |
| "expected Result Type to be a float scalar or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) { |
| const std::string body = R"( |
| %var_u32 = OpVariable %f32_ptr_function Function |
| %val1 = OpExtInst %f32 %extinst remquo %u32_3 %f32_2 %var_u32 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std remquo: " |
| "expected type of operand X to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdRemquoYWrongType) { |
| const std::string body = R"( |
| %var_u32 = OpVariable %f32_ptr_function Function |
| %val1 = OpExtInst %f32 %extinst remquo %f32_3 %u32_2 %var_u32 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std remquo: " |
| "expected type of operand Y to be equal to Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdRemquoNotPointer) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std remquo: " |
| "expected the last operand to be a pointer")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongStorageClass) { |
| const std::string body = R"( |
| %ptr = OpAccessChain %f32_ptr_uniform_constant %f32vec8_uniform_constant %u32_1 |
| %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %ptr |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std remquo: " |
| "expected storage class of the pointer to be Generic, " |
| "CrossWorkgroup, Workgroup or Function")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataType) { |
| const std::string body = R"( |
| %var_f32 = OpVariable %f32_ptr_function Function |
| %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_f32 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std remquo: " |
| "expected data type of the pointer to be a 32-bit int " |
| "scalar or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataTypeWidth) { |
| const std::string body = R"( |
| %var_u64 = OpVariable %u64_ptr_function Function |
| %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u64 |
| )"; |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std remquo: " |
| "expected data type of the pointer to be a 32-bit int " |
| "scalar or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongNumberOfComponents) { |
| const std::string body = R"( |
| %var_u32vec2 = OpVariable %u32vec2_ptr_function Function |
| %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32vec2 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std remquo: " |
| "expected data type of the pointer to have the same number " |
| "of components as Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFrexpLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_u32 = OpVariable %u32_ptr_function Function\n"; |
| ss << "%var_u32vec2 = OpVariable %u32vec2_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %var_u32\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01 %var_u32vec2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdFrexpLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_u32 = OpVariable %u32_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %f32_0 %var_u32\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a float scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFrexpLike, XWrongType) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_u32 = OpVariable %u32_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f64_0 %var_u32\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected type of operand X to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFrexpLike, NotPointer) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected the last operand to be a pointer")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFrexpLike, PointerInvalidStorageClass) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant " |
| "%f32vec8_uniform_constant %u32_1\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected storage class of the pointer to be " |
| "Generic, CrossWorkgroup, Workgroup or Function")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeFloat) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_f32 = OpVariable %f32_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %var_f32\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected data type of the pointer to be a 32-bit " |
| "int scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeU64) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_u64 = OpVariable %u64_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %var_u64\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected data type of the pointer to be a 32-bit " |
| "int scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeDiffSize) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%var_u32 = OpVariable %u32_ptr_function Function\n"; |
| ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_01 %var_u32\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected data type of the pointer to have the same " |
| "number of components as Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllFrexpLike, ValidateOpenCLStdFrexpLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "frexp", |
| "lgamma_r", |
| })); |
| |
| TEST_F(ValidateExtInst, OpenCLStdIlogbSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst ilogb %f32_3 |
| %val2 = OpExtInst %u32vec2 %extinst ilogb %f32vec2_12 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdIlogbFloatResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst ilogb %f32_3 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std ilogb: " |
| "expected Result Type to be a 32-bit int scalar or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdIlogbIntX) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst ilogb %u32_3 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std ilogb: " |
| "expected operand X to be a float scalar or vector")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdIlogbDiffSize) { |
| const std::string body = R"( |
| %val2 = OpExtInst %u32vec2 %extinst ilogb %f32_1 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std ilogb: " |
| "expected operand X to have the same number of " |
| "components as Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdNanSuccess) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst nan %u32_3 |
| %val2 = OpExtInst %f32vec2 %extinst nan %u32vec2_12 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdNanIntResultType) { |
| const std::string body = R"( |
| %val1 = OpExtInst %u32 %extinst nan %u32_3 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std nan: " |
| "expected Result Type to be a float scalar or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdNanFloatNancode) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst nan %f32_3 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std nan: " |
| "expected Nancode to be an int scalar or vector type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffSize) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f32 %extinst nan %u32vec2_12 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std nan: " |
| "expected Nancode to have the same number of " |
| "components as Result Type")); |
| } |
| |
| TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffBitWidth) { |
| const std::string body = R"( |
| %val1 = OpExtInst %f64 %extinst nan %u32_2 |
| )"; |
| |
| CompileSuccessfully(GenerateKernelCode(body)); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std nan: " |
| "expected Nancode to have the same bit width as Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdLdexpLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %u32_1\n"; |
| ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name |
| << " %f32vec2_12 %u32vec2_12\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdLdexpLike, IntResultType) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %f32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be a float scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdLdexpLike, XWrongType) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %u32_0 %u32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected type of operand X to be equal to Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %f32_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected the exponent to be a 32-bit int scalar or vector")); |
| } |
| |
| TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt32) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %u64_1\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected the exponent to be a 32-bit int scalar or vector")); |
| } |
| |
| TEST_P(ValidateOpenCLStdLdexpLike, ExponentWrongSize) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name |
| << " %f32_0 %u32vec2_01\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected the exponent to have the same number of " |
| "components as Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllLdexpLike, ValidateOpenCLStdLdexpLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "ldexp", |
| "pown", |
| "rootn", |
| })); |
| |
| TEST_P(ValidateOpenCLStdUpsampleLike, Success) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << " %u8_1 %u8_2\n"; |
| ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name |
| << " %u16_1 %u16_2\n"; |
| ss << "%val3 = OpExtInst %u64 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| ss << "%val4 = OpExtInst %u64vec2 %extinst " << ext_inst_name |
| << " %u32vec2_01 %u32vec2_01\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ValidateOpenCLStdUpsampleLike, FloatResultType) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %f64 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Result Type to be an int scalar or vector type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUpsampleLike, InvalidResultTypeBitWidth) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u8 %extinst " << ext_inst_name << " %u8_1 %u8_2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr( |
| "OpenCL.std " + ext_inst_name + |
| ": expected bit width of Result Type components to be 16, 32 or 64")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUpsampleLike, LoHiDiffType) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name |
| << " %u32_1 %u16_2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Hi and Lo operands to have the same type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUpsampleLike, DiffNumberOfComponents) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u64vec2 %extinst " << ext_inst_name |
| << " %u32_1 %u32_2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected Hi and Lo operands to have the same number " |
| "of components as Result Type")); |
| } |
| |
| TEST_P(ValidateOpenCLStdUpsampleLike, HiLoWrongBitWidth) { |
| const std::string ext_inst_name = GetParam(); |
| std::ostringstream ss; |
| ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name |
| << " %u16_1 %u16_2\n"; |
| |
| CompileSuccessfully(GenerateKernelCode(ss.str())); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("OpenCL.std " + ext_inst_name + |
| ": expected bit width of components of Hi and Lo operands to " |
| "be half of the bit width of components of Result Type")); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(AllUpsampleLike, ValidateOpenCLStdUpsampleLike, |
| ::testing::ValuesIn(std::vector<std::string>{ |
| "u_upsample", |
| "s_upsample", |
| })); |
| |
| TEST_F(ValidateClspvReflection, RequiresNonSemanticExtension) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpCapability Linkage |
| %1 = OpExtInstImport "NonSemantic.ClspvReflection.1" |
| OpMemoryModel Logical GLSL450 |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("NonSemantic extended instruction sets cannot be " |
| "declared without SPV_KHR_non_semantic_info")); |
| } |
| |
| TEST_F(ValidateClspvReflection, DoesNotRequiresNonSemanticExtensionPost1p6) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpCapability Linkage |
| %1 = OpExtInstImport "NonSemantic.ClspvReflection.1" |
| OpMemoryModel Logical GLSL450 |
| )"; |
| |
| CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6)); |
| } |
| |
| TEST_F(ValidateClspvReflection, MissingVersion) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpCapability Linkage |
| OpExtension "SPV_KHR_non_semantic_info" |
| %1 = OpExtInstImport "NonSemantic.ClspvReflection." |
| OpMemoryModel Logical GLSL450 |
| %2 = OpTypeVoid |
| %3 = OpTypeInt 32 0 |
| %4 = OpConstant %3 1 |
| %5 = OpExtInst %2 %1 SpecConstantWorkDim %4 |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Missing NonSemantic.ClspvReflection import version")); |
| } |
| |
| TEST_F(ValidateClspvReflection, BadVersion0) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpCapability Linkage |
| OpExtension "SPV_KHR_non_semantic_info" |
| %1 = OpExtInstImport "NonSemantic.ClspvReflection.0" |
| OpMemoryModel Logical GLSL450 |
| %2 = OpTypeVoid |
| %3 = OpTypeInt 32 0 |
| %4 = OpConstant %3 1 |
| %5 = OpExtInst %2 %1 SpecConstantWorkDim %4 |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Unknown NonSemantic.ClspvReflection import version")); |
| } |
| |
| TEST_F(ValidateClspvReflection, BadVersionNotANumber) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpCapability Linkage |
| OpExtension "SPV_KHR_non_semantic_info" |
| %1 = OpExtInstImport "NonSemantic.ClspvReflection.1a" |
| OpMemoryModel Logical GLSL450 |
| %2 = OpTypeVoid |
| %3 = OpTypeInt 32 0 |
| %4 = OpConstant %3 1 |
| %5 = OpExtInst %2 %1 SpecConstantWorkDim %4 |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("NonSemantic.ClspvReflection import does not encode " |
| "the version correctly")); |
| } |
| |
| TEST_F(ValidateClspvReflection, Kernel) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.1" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelNotAFunction) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.1" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo_name %foo_name |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Kernel does not reference a function")); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelNotAnEntryPoint) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.1" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %bar = OpFunction %void None %void_fn |
| %bar_entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %bar %foo_name |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Kernel does not reference an entry-point")); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelNotGLCompute) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.1" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Fragment %foo "foo" |
| OpExecutionMode %foo OriginUpperLeft |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Kernel must refer only to GLCompute entry-points")); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelNameMismatch) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.1" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "bar" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Name must match an entry-point for Kernel")); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelArgumentsVersionGood) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %int = OpTypeInt 32 0 |
| %int_1 = OpConstant %int 1 |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name %int_1 |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelArgumentsVersionBad) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.4" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %int = OpTypeInt 32 0 |
| %int_1 = OpConstant %int 1 |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name %int_1 |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Version 4 of the Kernel instruction can only have 2 " |
| "additional operands")); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelNumArgumentsNotInt) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %float = OpTypeFloat 32 |
| %float_0 = OpConstant %float 0 |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name %float_0 |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("NumArguments must be a 32-bit unsigned integer OpConstant")); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelNumArgumentsNotConstant) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %null = OpConstantNull %int |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name %null |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("NumArguments must be a 32-bit unsigned integer OpConstant")); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelFlagsNotInt) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %float = OpTypeFloat 32 |
| %float_0 = OpConstant %float 0 |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name %int_0 %float_0 |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Flags must be a 32-bit unsigned integer OpConstant")); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelFlagsNotConstant) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %null = OpConstantNull %int |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name %int_0 %null |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Flags must be a 32-bit unsigned integer OpConstant")); |
| } |
| |
| TEST_F(ValidateClspvReflection, KernelAttributesNotString) { |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %void_fn = OpTypeFunction %void |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %float = OpTypeFloat 32 |
| %float_0 = OpConstant %float 0 |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name %int_0 %int_0 %int_0 |
| )"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Attributes must be an OpString")); |
| } |
| |
| using ArgumentBasics = |
| spvtest::ValidateBase<std::pair<std::string, std::string>>; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| ValidateClspvReflectionArgumentKernel, ArgumentBasics, |
| ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{ |
| std::make_pair("ArgumentStorageBuffer", "%int_0 %int_0"), |
| std::make_pair("ArgumentUniform", "%int_0 %int_0"), |
| std::make_pair("ArgumentPodStorageBuffer", |
| "%int_0 %int_0 %int_0 %int_4"), |
| std::make_pair("ArgumentPodUniform", "%int_0 %int_0 %int_0 %int_4"), |
| std::make_pair("ArgumentPodPushConstant", "%int_0 %int_4"), |
| std::make_pair("ArgumentSampledImage", "%int_0 %int_0"), |
| std::make_pair("ArgumentStorageImage", "%int_0 %int_0"), |
| std::make_pair("ArgumentSampler", "%int_0 %int_0"), |
| std::make_pair("ArgumentWorkgroup", "%int_0 %int_0"), |
| std::make_pair("ArgumentPointerPushConstant", "%int_0 %int_4"), |
| std::make_pair("ArgumentPointerUniform", "%int_0 %int_0 %int_0 %int_4"), |
| std::make_pair("ArgumentStorageTexelBuffer", "%int_0 %int_0"), |
| std::make_pair("ArgumentUniformTexelBuffer", "%int_0 %int_0")})); |
| |
| TEST_P(ArgumentBasics, KernelNotAnExtendedInstruction) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const std::string extra = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_4 = OpConstant %int 4 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %in = OpExtInst %void %ext )" + |
| ext_inst + " %int_0 %int_0 " + extra; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Kernel must be a Kernel extended instruction")); |
| } |
| |
| TEST_P(ArgumentBasics, KernelFromDifferentImport) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const std::string extra = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_4 = OpConstant %int 4 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext2 Kernel %foo %foo_name |
| %in = OpExtInst %void %ext )" + |
| ext_inst + " %decl %int_0 " + extra; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("Kernel must be from the same extended instruction import")); |
| } |
| |
| TEST_P(ArgumentBasics, KernelWrongExtendedInstruction) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const std::string extra = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_4 = OpConstant %int 4 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext ArgumentInfo %foo_name |
| %in = OpExtInst %void %ext )" + |
| ext_inst + " %decl %int_0 " + extra; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("Kernel must be a Kernel extended instruction")); |
| } |
| |
| TEST_P(ArgumentBasics, ArgumentInfo) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const std::string operands = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %in_name = OpString "in" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_4 = OpConstant %int 4 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| %info = OpExtInst %void %ext ArgumentInfo %in_name |
| %in = OpExtInst %void %ext )" + |
| ext_inst + " %decl %int_0 " + operands + " %info"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } |
| |
| TEST_P(ArgumentBasics, ArgumentInfoNotAnExtendedInstruction) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const std::string operands = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_4 = OpConstant %int 4 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| %in = OpExtInst %void %ext )" + |
| ext_inst + " %decl %int_0 " + operands + " %int_0"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("ArgInfo must be an ArgumentInfo extended instruction")); |
| } |
| |
| TEST_P(ArgumentBasics, ArgumentInfoFromDifferentImport) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const std::string operands = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %in_name = OpString "in" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_4 = OpConstant %int 4 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| %info = OpExtInst %void %ext2 ArgumentInfo %in_name |
| %in = OpExtInst %void %ext )" + |
| ext_inst + " %decl %int_0 " + operands + " %info"; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr("ArgInfo must be from the same extended instruction import")); |
| } |
| |
| using Uint32Constant = |
| spvtest::ValidateBase<std::pair<std::string, std::string>>; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| ValidateClspvReflectionUint32Constants, Uint32Constant, |
| ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{ |
| std::make_pair("ArgumentStorageBuffer %decl %float_0 %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentStorageBuffer %decl %null %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentStorageBuffer %decl %int_0 %float_0 %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentStorageBuffer %decl %int_0 %null %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %float_0", |
| "Binding"), |
| std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %null", |
| "Binding"), |
| std::make_pair("ArgumentUniform %decl %float_0 %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentUniform %decl %null %int_0 %int_0", "Ordinal"), |
| std::make_pair("ArgumentUniform %decl %int_0 %float_0 %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentUniform %decl %int_0 %null %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentUniform %decl %int_0 %int_0 %float_0", |
| "Binding"), |
| std::make_pair("ArgumentUniform %decl %int_0 %int_0 %null", "Binding"), |
| std::make_pair("ArgumentSampledImage %decl %float_0 %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentSampledImage %decl %null %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentSampledImage %decl %int_0 %float_0 %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentSampledImage %decl %int_0 %null %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %float_0", |
| "Binding"), |
| std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %null", |
| "Binding"), |
| std::make_pair("ArgumentStorageImage %decl %float_0 %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentStorageImage %decl %null %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentStorageImage %decl %int_0 %float_0 %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentStorageImage %decl %int_0 %null %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %float_0", |
| "Binding"), |
| std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %null", |
| "Binding"), |
| std::make_pair("ArgumentSampler %decl %float_0 %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentSampler %decl %null %int_0 %int_0", "Ordinal"), |
| std::make_pair("ArgumentSampler %decl %int_0 %float_0 %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentSampler %decl %int_0 %null %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentSampler %decl %int_0 %int_0 %float_0", |
| "Binding"), |
| std::make_pair("ArgumentSampler %decl %int_0 %int_0 %null", "Binding"), |
| std::make_pair("ArgumentPodStorageBuffer %decl %float_0 %int_0 %int_0 " |
| "%int_0 %int_4", |
| "Ordinal"), |
| std::make_pair( |
| "ArgumentPodStorageBuffer %decl %null %int_0 %int_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %float_0 %int_0 " |
| "%int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair( |
| "ArgumentPodStorageBuffer %decl %int_0 %null %int_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %float_0 " |
| "%int_0 %int_4", |
| "Binding"), |
| std::make_pair( |
| "ArgumentPodStorageBuffer %decl %int_0 %int_0 %null %int_0 %int_4", |
| "Binding"), |
| std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 " |
| "%float_0 %int_4", |
| "Offset"), |
| std::make_pair( |
| "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %null %int_4", |
| "Offset"), |
| std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 " |
| "%int_0 %float_0", |
| "Size"), |
| std::make_pair( |
| "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %int_0 %null", |
| "Size"), |
| std::make_pair( |
| "ArgumentPodUniform %decl %float_0 %int_0 %int_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair( |
| "ArgumentPodUniform %decl %null %int_0 %int_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair( |
| "ArgumentPodUniform %decl %int_0 %float_0 %int_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair( |
| "ArgumentPodUniform %decl %int_0 %null %int_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair( |
| "ArgumentPodUniform %decl %int_0 %int_0 %float_0 %int_0 %int_4", |
| "Binding"), |
| std::make_pair( |
| "ArgumentPodUniform %decl %int_0 %int_0 %null %int_0 %int_4", |
| "Binding"), |
| std::make_pair( |
| "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %float_0 %int_4", |
| "Offset"), |
| std::make_pair( |
| "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %null %int_4", |
| "Offset"), |
| std::make_pair( |
| "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %float_0", |
| "Size"), |
| std::make_pair( |
| "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %null", |
| "Size"), |
| std::make_pair("ArgumentPodPushConstant %decl %float_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ArgumentPodPushConstant %decl %null %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ArgumentPodPushConstant %decl %int_0 %float_0 %int_4", |
| "Offset"), |
| std::make_pair("ArgumentPodPushConstant %decl %int_0 %null %int_4", |
| "Offset"), |
| std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %float_0", |
| "Size"), |
| std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %null", |
| "Size"), |
| std::make_pair("ArgumentWorkgroup %decl %float_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ArgumentWorkgroup %decl %null %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ArgumentWorkgroup %decl %int_0 %float_0 %int_4", |
| "SpecId"), |
| std::make_pair("ArgumentWorkgroup %decl %int_0 %null %int_4", "SpecId"), |
| std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %float_0", |
| "ElemSize"), |
| std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %null", |
| "ElemSize"), |
| std::make_pair("SpecConstantWorkgroupSize %float_0 %int_0 %int_4", "X"), |
| std::make_pair("SpecConstantWorkgroupSize %null %int_0 %int_4", "X"), |
| std::make_pair("SpecConstantWorkgroupSize %int_0 %float_0 %int_4", "Y"), |
| std::make_pair("SpecConstantWorkgroupSize %int_0 %null %int_4", "Y"), |
| std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %float_0", "Z"), |
| std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %null", "Z"), |
| std::make_pair("SpecConstantGlobalOffset %float_0 %int_0 %int_4", "X"), |
| std::make_pair("SpecConstantGlobalOffset %null %int_0 %int_4", "X"), |
| std::make_pair("SpecConstantGlobalOffset %int_0 %float_0 %int_4", "Y"), |
| std::make_pair("SpecConstantGlobalOffset %int_0 %null %int_4", "Y"), |
| std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %float_0", "Z"), |
| std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %null", "Z"), |
| std::make_pair("SpecConstantWorkDim %float_0", "Dim"), |
| std::make_pair("SpecConstantWorkDim %null", "Dim"), |
| std::make_pair("PushConstantGlobalOffset %float_0 %int_0", "Offset"), |
| std::make_pair("PushConstantGlobalOffset %null %int_0", "Offset"), |
| std::make_pair("PushConstantGlobalOffset %int_0 %float_0", "Size"), |
| std::make_pair("PushConstantGlobalOffset %int_0 %null", "Size"), |
| std::make_pair("PushConstantEnqueuedLocalSize %float_0 %int_0", |
| "Offset"), |
| std::make_pair("PushConstantEnqueuedLocalSize %null %int_0", "Offset"), |
| std::make_pair("PushConstantEnqueuedLocalSize %int_0 %float_0", "Size"), |
| std::make_pair("PushConstantEnqueuedLocalSize %int_0 %null", "Size"), |
| std::make_pair("PushConstantGlobalSize %float_0 %int_0", "Offset"), |
| std::make_pair("PushConstantGlobalSize %null %int_0", "Offset"), |
| std::make_pair("PushConstantGlobalSize %int_0 %float_0", "Size"), |
| std::make_pair("PushConstantGlobalSize %int_0 %null", "Size"), |
| std::make_pair("PushConstantRegionOffset %float_0 %int_0", "Offset"), |
| std::make_pair("PushConstantRegionOffset %null %int_0", "Offset"), |
| std::make_pair("PushConstantRegionOffset %int_0 %float_0", "Size"), |
| std::make_pair("PushConstantRegionOffset %int_0 %null", "Size"), |
| std::make_pair("PushConstantNumWorkgroups %float_0 %int_0", "Offset"), |
| std::make_pair("PushConstantNumWorkgroups %null %int_0", "Offset"), |
| std::make_pair("PushConstantNumWorkgroups %int_0 %float_0", "Size"), |
| std::make_pair("PushConstantNumWorkgroups %int_0 %null", "Size"), |
| std::make_pair("PushConstantRegionGroupOffset %float_0 %int_0", |
| "Offset"), |
| std::make_pair("PushConstantRegionGroupOffset %null %int_0", "Offset"), |
| std::make_pair("PushConstantRegionGroupOffset %int_0 %float_0", "Size"), |
| std::make_pair("PushConstantRegionGroupOffset %int_0 %null", "Size"), |
| std::make_pair("ConstantDataStorageBuffer %float_0 %int_0 %data", |
| "DescriptorSet"), |
| std::make_pair("ConstantDataStorageBuffer %null %int_0 %data", |
| "DescriptorSet"), |
| std::make_pair("ConstantDataStorageBuffer %int_0 %float_0 %data", |
| "Binding"), |
| std::make_pair("ConstantDataStorageBuffer %int_0 %null %data", |
| "Binding"), |
| std::make_pair("ConstantDataUniform %float_0 %int_0 %data", |
| "DescriptorSet"), |
| std::make_pair("ConstantDataUniform %null %int_0 %data", |
| "DescriptorSet"), |
| std::make_pair("ConstantDataUniform %int_0 %float_0 %data", "Binding"), |
| std::make_pair("ConstantDataUniform %int_0 %null %data", "Binding"), |
| std::make_pair("LiteralSampler %float_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair("LiteralSampler %null %int_0 %int_4", "DescriptorSet"), |
| std::make_pair("LiteralSampler %int_0 %float_0 %int_4", "Binding"), |
| std::make_pair("LiteralSampler %int_0 %null %int_4", "Binding"), |
| std::make_pair("LiteralSampler %int_0 %int_0 %float_0", "Mask"), |
| std::make_pair("LiteralSampler %int_0 %int_0 %null", "Mask"), |
| std::make_pair( |
| "PropertyRequiredWorkgroupSize %decl %float_0 %int_1 %int_4", "X"), |
| std::make_pair( |
| "PropertyRequiredWorkgroupSize %decl %null %int_1 %int_4", "X"), |
| std::make_pair( |
| "PropertyRequiredWorkgroupSize %decl %int_1 %float_0 %int_4", "Y"), |
| std::make_pair( |
| "PropertyRequiredWorkgroupSize %decl %int_1 %null %int_4", "Y"), |
| std::make_pair( |
| "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %float_0", "Z"), |
| std::make_pair( |
| "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %null", "Z"), |
| std::make_pair("SpecConstantSubgroupMaxSize %float_0", "Size"), |
| std::make_pair("SpecConstantSubgroupMaxSize %null", "Size"), |
| std::make_pair( |
| "ArgumentPointerPushConstant %decl %float_0 %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentPointerPushConstant %decl %null %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair( |
| "ArgumentPointerPushConstant %decl %int_0 %float_0 %int_0", |
| "Offset"), |
| std::make_pair("ArgumentPointerPushConstant %decl %int_0 %null %int_0", |
| "Offset"), |
| std::make_pair( |
| "ArgumentPointerPushConstant %decl %int_0 %int_0 %float_0", "Size"), |
| std::make_pair("ArgumentPointerPushConstant %decl %int_0 %int_0 %null", |
| "Size"), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %float_0 %int_0 %int_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %null %int_0 %int_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %int_0 %float_0 %int_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %int_0 %null %int_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %int_0 %int_0 %float_0 %int_0 %int_4", |
| "Binding"), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %int_0 %int_0 %null %int_0 %int_4", |
| "Binding"), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %float_0 %int_4", |
| "Offset"), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %null %int_4", |
| "Offset"), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %int_0 %float_0", |
| "Size"), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %int_0 %null", |
| "Size"), |
| std::make_pair( |
| "ProgramScopeVariablesStorageBuffer %float_0 %int_0 %data", |
| "DescriptorSet"), |
| std::make_pair("ProgramScopeVariablesStorageBuffer %null %int_0 %data", |
| "DescriptorSet"), |
| std::make_pair( |
| "ProgramScopeVariablesStorageBuffer %int_0 %float_0 %data", |
| "Binding"), |
| std::make_pair("ProgramScopeVariablesStorageBuffer %int_0 %null %data", |
| "Binding"), |
| std::make_pair( |
| "ProgramScopeVariablePointerRelocation %float_0 %int_0 %int_4", |
| "ObjectOffset"), |
| std::make_pair( |
| "ProgramScopeVariablePointerRelocation %null %int_0 %int_4", |
| "ObjectOffset"), |
| std::make_pair( |
| "ProgramScopeVariablePointerRelocation %int_0 %float_0 %int_4", |
| "PointerOffset"), |
| std::make_pair( |
| "ProgramScopeVariablePointerRelocation %int_0 %null %int_4", |
| "PointerOffset"), |
| std::make_pair( |
| "ProgramScopeVariablePointerRelocation %int_0 %int_0 %float_0", |
| "PointerSize"), |
| std::make_pair( |
| "ProgramScopeVariablePointerRelocation %int_0 %int_0 %null", |
| "PointerSize"), |
| std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl " |
| "%float_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %null " |
| "%int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 " |
| "%float_0 %int_4", |
| "Offset"), |
| std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 " |
| "%null %int_4", |
| "Offset"), |
| std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 " |
| "%int_0 %float_0", |
| "Size"), |
| std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 " |
| "%int_0 %null", |
| "Size"), |
| std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " |
| "%float_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " |
| "%null %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " |
| "%int_0 %float_0 %int_4", |
| "Offset"), |
| std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " |
| "%int_0 %null %int_4", |
| "Offset"), |
| std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " |
| "%int_0 %int_0 %float_0", |
| "Size"), |
| std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " |
| "%int_0 %int_0 %null", |
| "Size"), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %float_0 " |
| "%int_0 %int_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %null " |
| "%int_0 %int_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " |
| "%float_0 %int_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " |
| "%null %int_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " |
| "%int_0 %float_0 %int_0 %int_4", |
| "Binding"), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " |
| "%int_0 %null %int_0 %int_4", |
| "Binding"), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " |
| "%int_0 %int_0 %float_0 %int_4", |
| "Offset"), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " |
| "%int_0 %int_0 %null %int_4", |
| "Offset"), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " |
| "%int_0 %int_0 %int_0 %float_0", |
| "Size"), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " |
| "%int_0 %int_0 %int_0 %null", |
| "Size"), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %float_0 " |
| "%int_0 %int_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %null " |
| "%int_0 %int_0 %int_0 %int_4", |
| "Ordinal"), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " |
| "%float_0 %int_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " |
| "%null %int_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " |
| "%int_0 %float_0 %int_0 %int_4", |
| "Binding"), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " |
| "%int_0 %null %int_0 %int_4", |
| "Binding"), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " |
| "%int_0 %int_0 %float_0 %int_4", |
| "Offset"), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " |
| "%int_0 %int_0 %null %int_4", |
| "Offset"), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " |
| "%int_0 %int_0 %int_0 %float_0", |
| "Size"), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " |
| "%int_0 %int_0 %int_0 %null", |
| "Size"), |
| std::make_pair( |
| "ArgumentStorageTexelBuffer %decl %float_0 %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentStorageTexelBuffer %decl %null %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair( |
| "ArgumentStorageTexelBuffer %decl %int_0 %float_0 %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentStorageTexelBuffer %decl %int_0 %null %int_0", |
| "DescriptorSet"), |
| std::make_pair( |
| "ArgumentStorageTexelBuffer %decl %int_0 %int_0 %float_0", |
| "Binding"), |
| std::make_pair("ArgumentStorageTexelBuffer %decl %int_0 %int_0 %null", |
| "Binding"), |
| std::make_pair( |
| "ArgumentUniformTexelBuffer %decl %float_0 %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair("ArgumentUniformTexelBuffer %decl %null %int_0 %int_0", |
| "Ordinal"), |
| std::make_pair( |
| "ArgumentUniformTexelBuffer %decl %int_0 %float_0 %int_0", |
| "DescriptorSet"), |
| std::make_pair("ArgumentUniformTexelBuffer %decl %int_0 %null %int_0", |
| "DescriptorSet"), |
| std::make_pair( |
| "ArgumentUniformTexelBuffer %decl %int_0 %int_0 %float_0", |
| "Binding"), |
| std::make_pair("ArgumentUniformTexelBuffer %decl %int_0 %int_0 %null", |
| "Binding"), |
| std::make_pair("ConstantDataPointerPushConstant %float_0 %int_4 %data", |
| "Offset"), |
| std::make_pair("ConstantDataPointerPushConstant %null %int_4 %data", |
| "Offset"), |
| std::make_pair("ConstantDataPointerPushConstant %int_0 %float_0 %data", |
| "Size"), |
| std::make_pair("ConstantDataPointerPushConstant %int_0 %null %data", |
| "Size"), |
| std::make_pair( |
| "ProgramScopeVariablePointerPushConstant %float_0 %int_4 %data", |
| "Offset"), |
| std::make_pair( |
| "ProgramScopeVariablePointerPushConstant %null %int_4 %data", |
| "Offset"), |
| std::make_pair( |
| "ProgramScopeVariablePointerPushConstant %int_0 %float_0 %data", |
| "Size"), |
| std::make_pair( |
| "ProgramScopeVariablePointerPushConstant %int_0 %null %data", |
| "Size"), |
| std::make_pair("PrintfInfo %float_0 %data %int_0 %int_0 %int_0", |
| "PrintfID"), |
| std::make_pair("PrintfInfo %null %data %int_0 %int_0 %int_0", |
| "PrintfID"), |
| std::make_pair("PrintfInfo %int_0 %data %float_0 %int_0 %int_0", |
| "ArgumentSizes"), |
| std::make_pair("PrintfInfo %int_0 %data %null %int_0 %int_0", |
| "ArgumentSizes"), |
| std::make_pair("PrintfInfo %int_0 %data %int_0 %float_0 %int_0", |
| "ArgumentSizes"), |
| std::make_pair("PrintfInfo %int_0 %data %int_0 %null %int_0", |
| "ArgumentSizes"), |
| std::make_pair("PrintfInfo %int_0 %data %int_0 %int_0 %null", |
| "ArgumentSizes"), |
| std::make_pair("PrintfInfo %int_0 %data %int_0 %int_0 %float_0", |
| "ArgumentSizes"), |
| std::make_pair("PrintfInfo %int_0 %data %int_0 %float_0", |
| "ArgumentSizes"), |
| std::make_pair("PrintfInfo %int_0 %data %int_0 %null", "ArgumentSizes"), |
| std::make_pair("PrintfBufferStorageBuffer %float_0 %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair("PrintfBufferStorageBuffer %null %int_0 %int_4", |
| "DescriptorSet"), |
| std::make_pair("PrintfBufferStorageBuffer %int_0 %float_0 %int_4", |
| "Binding"), |
| std::make_pair("PrintfBufferStorageBuffer %int_0 %null %int_4", |
| "Binding"), |
| std::make_pair("PrintfBufferStorageBuffer %int_0 %int_0 %float_0", |
| "Size"), |
| std::make_pair("PrintfBufferStorageBuffer %int_0 %int_0 %null", "Size"), |
| std::make_pair("PrintfBufferPointerPushConstant %float_0 %int_0 %int_4", |
| "Offset"), |
| std::make_pair("PrintfBufferPointerPushConstant %null %int_0 %int_4", |
| "Offset"), |
| std::make_pair("PrintfBufferPointerPushConstant %int_0 %float_0 %int_4", |
| "Size"), |
| std::make_pair("PrintfBufferPointerPushConstant %int_0 %null %int_4", |
| "Size"), |
| std::make_pair("PrintfBufferPointerPushConstant %int_0 %int_0 %float_0", |
| "BufferSize"), |
| std::make_pair("PrintfBufferPointerPushConstant %int_0 %int_0 %null", |
| "BufferSize")})); |
| |
| TEST_P(Uint32Constant, Invalid) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const std::string name = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %data = OpString "1234" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_4 = OpConstant %int 4 |
| %null = OpConstantNull %int |
| %float = OpTypeFloat 32 |
| %float_0 = OpConstant %float 0 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| %inst = OpExtInst %void %ext )" + |
| ext_inst; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT( |
| getDiagnosticString(), |
| HasSubstr(name + " must be a 32-bit unsigned integer OpConstant")); |
| } |
| |
| using StringOperand = |
| spvtest::ValidateBase<std::pair<std::string, std::string>>; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| ValidateClspvReflectionStringOperands, StringOperand, |
| ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{ |
| std::make_pair("ConstantDataStorageBuffer %int_0 %int_0 %int_0", |
| "Data"), |
| std::make_pair("ConstantDataUniform %int_0 %int_0 %int_0", "Data"), |
| std::make_pair( |
| "ProgramScopeVariablesStorageBuffer %int_0 %int_0 %int_0", "Data"), |
| std::make_pair("ConstantDataPointerPushConstant %int_0 %int_0 %int_0", |
| "Data"), |
| std::make_pair( |
| "ProgramScopeVariablePointerPushConstant %int_0 %int_0 %int_0", |
| "Data"), |
| std::make_pair("PrintfInfo %int_0 %int_0", "FormatString")})); |
| |
| TEST_P(StringOperand, Invalid) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const std::string name = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %data = OpString "1234" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_4 = OpConstant %int 4 |
| %null = OpConstantNull %int |
| %float = OpTypeFloat 32 |
| %float_0 = OpConstant %float 0 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| %inst = OpExtInst %void %ext )" + |
| ext_inst; |
| |
| CompileSuccessfully(text); |
| ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), HasSubstr(name + " must be an OpString")); |
| } |
| |
| using VersionCheck = spvtest::ValidateBase<std::pair<std::string, uint32_t>>; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| ValidateClspvReflectionVersionCheck, VersionCheck, |
| ::testing::ValuesIn(std::vector<std::pair<std::string, uint32_t>>{ |
| std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %int_0", 1), |
| std::make_pair("ArgumentUniform %decl %int_0 %int_0 %int_0", 1), |
| std::make_pair( |
| "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %int_0 %int_0", |
| 1), |
| std::make_pair( |
| "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %int_0", 1), |
| std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %int_0", 1), |
| std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %int_0", 1), |
| std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %int_0", 1), |
| std::make_pair("ArgumentSampler %decl %int_0 %int_0 %int_0", 1), |
| std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %int_0", 1), |
| std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %int_0", 1), |
| std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %int_0", 1), |
| std::make_pair("SpecConstantWorkDim %int_0", 1), |
| std::make_pair("PushConstantGlobalOffset %int_0 %int_0", 1), |
| std::make_pair("PushConstantEnqueuedLocalSize %int_0 %int_0", 1), |
| std::make_pair("PushConstantGlobalSize %int_0 %int_0", 1), |
| std::make_pair("PushConstantRegionOffset %int_0 %int_0", 1), |
| std::make_pair("PushConstantNumWorkgroups %int_0 %int_0", 1), |
| std::make_pair("PushConstantRegionGroupOffset %int_0 %int_0", 1), |
| std::make_pair("ConstantDataStorageBuffer %int_0 %int_0 %data", 1), |
| std::make_pair("ConstantDataUniform %int_0 %int_0 %data", 1), |
| std::make_pair("LiteralSampler %int_0 %int_0 %int_0", 1), |
| std::make_pair( |
| "PropertyRequiredWorkgroupSize %decl %int_0 %int_0 %int_0", 1), |
| std::make_pair("SpecConstantSubgroupMaxSize %int_0", 2), |
| std::make_pair("ArgumentPointerPushConstant %decl %int_0 %int_0 %int_0", |
| 3), |
| std::make_pair( |
| "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %int_0 %int_0", |
| 3), |
| std::make_pair("ProgramScopeVariablesStorageBuffer %int_0 %int_0 %data", |
| 3), |
| std::make_pair( |
| "ProgramScopeVariablePointerRelocation %int_0 %int_0 %int_0", 3), |
| std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 " |
| "%int_0 %int_0", |
| 3), |
| std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " |
| "%int_0 %int_0 %int_0", |
| 3), |
| std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " |
| "%int_0 %int_0 %int_0 %int_0", |
| 3), |
| std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " |
| "%int_0 %int_0 %int_0 %int_0", |
| 3), |
| std::make_pair("ArgumentStorageTexelBuffer %decl %int_0 %int_0 %int_0", |
| 4), |
| std::make_pair("ArgumentUniformTexelBuffer %decl %int_0 %int_0 %int_0", |
| 4), |
| std::make_pair("ConstantDataPointerPushConstant %int_0 %int_0 %data", |
| 5), |
| std::make_pair( |
| "ProgramScopeVariablePointerPushConstant %int_0 %int_0 %data", 5), |
| std::make_pair("PrintfInfo %int_0 %data", 5), |
| std::make_pair("PrintfBufferStorageBuffer %int_0 %int_0 %int_0", 5), |
| std::make_pair("PrintfBufferPointerPushConstant %int_0 %int_0 %int_0", |
| 5)})); |
| |
| TEST_P(VersionCheck, V1) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const uint32_t version = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.1" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %data = OpString "1234" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_4 = OpConstant %int 4 |
| %null = OpConstantNull %int |
| %float = OpTypeFloat 32 |
| %float_0 = OpConstant %float 0 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| %inst = OpExtInst %void %ext )" + |
| ext_inst; |
| |
| CompileSuccessfully(text); |
| if (version <= 1) { |
| EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } else { |
| EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("requires version " + std::to_string(version) + |
| ", but parsed version is 1")); |
| } |
| } |
| |
| TEST_P(VersionCheck, V2) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const uint32_t version = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.2" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %data = OpString "1234" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_4 = OpConstant %int 4 |
| %null = OpConstantNull %int |
| %float = OpTypeFloat 32 |
| %float_0 = OpConstant %float 0 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| %inst = OpExtInst %void %ext )" + |
| ext_inst; |
| |
| CompileSuccessfully(text); |
| if (version <= 2) { |
| EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } else { |
| EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("requires version " + std::to_string(version) + |
| ", but parsed version is 2")); |
| } |
| } |
| |
| TEST_P(VersionCheck, V3) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const uint32_t version = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.3" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %data = OpString "1234" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_4 = OpConstant %int 4 |
| %null = OpConstantNull %int |
| %float = OpTypeFloat 32 |
| %float_0 = OpConstant %float 0 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| %inst = OpExtInst %void %ext )" + |
| ext_inst; |
| |
| CompileSuccessfully(text); |
| if (version <= 3) { |
| EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } else { |
| EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("requires version " + std::to_string(version) + |
| ", but parsed version is 3")); |
| } |
| } |
| |
| TEST_P(VersionCheck, V4) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const uint32_t version = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.4" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %data = OpString "1234" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_4 = OpConstant %int 4 |
| %null = OpConstantNull %int |
| %float = OpTypeFloat 32 |
| %float_0 = OpConstant %float 0 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| %inst = OpExtInst %void %ext )" + |
| ext_inst; |
| |
| CompileSuccessfully(text); |
| if (version <= 4) { |
| EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } else { |
| EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("requires version " + std::to_string(version) + |
| ", but parsed version is 4")); |
| } |
| } |
| |
| TEST_P(VersionCheck, V5) { |
| const std::string ext_inst = std::get<0>(GetParam()); |
| const uint32_t version = std::get<1>(GetParam()); |
| const std::string text = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %ext = OpExtInstImport "NonSemantic.ClspvReflection.5" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %foo "foo" |
| OpExecutionMode %foo LocalSize 1 1 1 |
| %foo_name = OpString "foo" |
| %data = OpString "1234" |
| %void = OpTypeVoid |
| %int = OpTypeInt 32 0 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_4 = OpConstant %int 4 |
| %null = OpConstantNull %int |
| %float = OpTypeFloat 32 |
| %float_0 = OpConstant %float 0 |
| %void_fn = OpTypeFunction %void |
| %foo = OpFunction %void None %void_fn |
| %entry = OpLabel |
| OpReturn |
| OpFunctionEnd |
| %decl = OpExtInst %void %ext Kernel %foo %foo_name |
| %inst = OpExtInst %void %ext )" + |
| ext_inst; |
| |
| CompileSuccessfully(text); |
| if (version <= 5) { |
| EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); |
| } else { |
| EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); |
| EXPECT_THAT(getDiagnosticString(), |
| HasSubstr("requires version " + std::to_string(version) + |
| ", but parsed version is 1")); |
| } |
| } |
| |
| } // namespace |
| } // namespace val |
| } // namespace spvtools |