1fd4e5da5Sopenharmony_ci// Copyright (c) 2017 Google Inc.
2fd4e5da5Sopenharmony_ci// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
3fd4e5da5Sopenharmony_ci// reserved.
4fd4e5da5Sopenharmony_ci//
5fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
6fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
7fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
10fd4e5da5Sopenharmony_ci//
11fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
12fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
13fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
15fd4e5da5Sopenharmony_ci// limitations under the License.
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci// Tests for unique type declaration rules validator.
18fd4e5da5Sopenharmony_ci
19fd4e5da5Sopenharmony_ci#include <sstream>
20fd4e5da5Sopenharmony_ci#include <string>
21fd4e5da5Sopenharmony_ci
22fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
23fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h"
24fd4e5da5Sopenharmony_ci#include "test/val/val_fixtures.h"
25fd4e5da5Sopenharmony_ci
26fd4e5da5Sopenharmony_cinamespace spvtools {
27fd4e5da5Sopenharmony_cinamespace val {
28fd4e5da5Sopenharmony_cinamespace {
29fd4e5da5Sopenharmony_ci
30fd4e5da5Sopenharmony_ciusing ::testing::Eq;
31fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr;
32fd4e5da5Sopenharmony_ciusing ::testing::Not;
33fd4e5da5Sopenharmony_ci
34fd4e5da5Sopenharmony_ciusing ValidateImage = spvtest::ValidateBase<bool>;
35fd4e5da5Sopenharmony_ci
36fd4e5da5Sopenharmony_cistd::string GenerateShaderCode(
37fd4e5da5Sopenharmony_ci    const std::string& body,
38fd4e5da5Sopenharmony_ci    const std::string& capabilities_and_extensions = "",
39fd4e5da5Sopenharmony_ci    const std::string& execution_model = "Fragment",
40fd4e5da5Sopenharmony_ci    const std::string& execution_mode = "",
41fd4e5da5Sopenharmony_ci    const spv_target_env env = SPV_ENV_UNIVERSAL_1_0,
42fd4e5da5Sopenharmony_ci    const std::string& memory_model = "GLSL450",
43fd4e5da5Sopenharmony_ci    const std::string& declarations = "") {
44fd4e5da5Sopenharmony_ci  std::ostringstream ss;
45fd4e5da5Sopenharmony_ci  ss << R"(
46fd4e5da5Sopenharmony_ciOpCapability Shader
47fd4e5da5Sopenharmony_ciOpCapability InputAttachment
48fd4e5da5Sopenharmony_ciOpCapability ImageGatherExtended
49fd4e5da5Sopenharmony_ciOpCapability MinLod
50fd4e5da5Sopenharmony_ciOpCapability Sampled1D
51fd4e5da5Sopenharmony_ciOpCapability ImageQuery
52fd4e5da5Sopenharmony_ciOpCapability Int64
53fd4e5da5Sopenharmony_ciOpCapability Float64
54fd4e5da5Sopenharmony_ciOpCapability SparseResidency
55fd4e5da5Sopenharmony_ciOpCapability ImageBuffer
56fd4e5da5Sopenharmony_ci)";
57fd4e5da5Sopenharmony_ci
58fd4e5da5Sopenharmony_ci  if (env == SPV_ENV_UNIVERSAL_1_0) {
59fd4e5da5Sopenharmony_ci    ss << "OpCapability SampledRect\n";
60fd4e5da5Sopenharmony_ci  }
61fd4e5da5Sopenharmony_ci
62fd4e5da5Sopenharmony_ci  // In 1.4, the entry point must list all module-scope variables used.  Just
63fd4e5da5Sopenharmony_ci  // list all of them.
64fd4e5da5Sopenharmony_ci  //
65fd4e5da5Sopenharmony_ci  // For Vulkan, anything Location decoration needs to be an interface variable
66fd4e5da5Sopenharmony_ci  std::string interface_vars =
67fd4e5da5Sopenharmony_ci      (env != SPV_ENV_UNIVERSAL_1_4) ? "%input_flat_u32" :
68fd4e5da5Sopenharmony_ci                                     R"(
69fd4e5da5Sopenharmony_ci%uniform_image_f32_1d_0001
70fd4e5da5Sopenharmony_ci%uniform_image_f32_1d_0002_rgba32f
71fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0001
72fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0011 ; multisampled sampled
73fd4e5da5Sopenharmony_ci%uniform_image_u32_2d_0001
74fd4e5da5Sopenharmony_ci%uniform_image_u32_2d_0002
75fd4e5da5Sopenharmony_ci%uniform_image_s32_3d_0001
76fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0002
77fd4e5da5Sopenharmony_ci%uniform_image_s32_2d_0002
78fd4e5da5Sopenharmony_ci%uniform_image_f32_spd_0002
79fd4e5da5Sopenharmony_ci%uniform_image_f32_3d_0111
80fd4e5da5Sopenharmony_ci%uniform_image_f32_cube_0101
81fd4e5da5Sopenharmony_ci%uniform_image_f32_cube_0102_rgba32f
82fd4e5da5Sopenharmony_ci%uniform_sampler
83fd4e5da5Sopenharmony_ci%private_image_u32_buffer_0002_r32ui
84fd4e5da5Sopenharmony_ci%private_image_u32_spd_0002
85fd4e5da5Sopenharmony_ci%private_image_f32_buffer_0002_r32ui
86fd4e5da5Sopenharmony_ci%input_flat_u32
87fd4e5da5Sopenharmony_ci)";
88fd4e5da5Sopenharmony_ci
89fd4e5da5Sopenharmony_ci  ss << capabilities_and_extensions;
90fd4e5da5Sopenharmony_ci  ss << "OpMemoryModel Logical " << memory_model << "\n";
91fd4e5da5Sopenharmony_ci  ss << "OpEntryPoint " << execution_model
92fd4e5da5Sopenharmony_ci     << " %main \"main\" " + interface_vars + "\n";
93fd4e5da5Sopenharmony_ci  if (execution_model == "Fragment") {
94fd4e5da5Sopenharmony_ci    ss << "OpExecutionMode %main OriginUpperLeft\n";
95fd4e5da5Sopenharmony_ci  }
96fd4e5da5Sopenharmony_ci  ss << execution_mode;
97fd4e5da5Sopenharmony_ci
98fd4e5da5Sopenharmony_ci  if (env == SPV_ENV_VULKAN_1_0) {
99fd4e5da5Sopenharmony_ci    ss << R"(
100fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_1d_0001 DescriptorSet 0
101fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_1d_0001 Binding 0
102fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_1d_0002_rgba32f DescriptorSet 0
103fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_1d_0002_rgba32f Binding 1
104fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_2d_0001 DescriptorSet 0
105fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_2d_0001 Binding 2
106fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_2d_0011 DescriptorSet 0
107fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_2d_0011 Binding 3
108fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_u32_2d_0001 DescriptorSet 1
109fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_u32_2d_0001 Binding 0
110fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_u32_2d_0002 DescriptorSet 1
111fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_u32_2d_0002 Binding 1
112fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_s32_3d_0001 DescriptorSet 1
113fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_s32_3d_0001 Binding 2
114fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_2d_0002 DescriptorSet 1
115fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_2d_0002 Binding 3
116fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_s32_2d_0002 DescriptorSet 1
117fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_s32_2d_0002 Binding 4
118fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_spd_0002 DescriptorSet 2
119fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_spd_0002 Binding 0
120fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_3d_0111 DescriptorSet 2
121fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_3d_0111 Binding 1
122fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_cube_0101 DescriptorSet 2
123fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_cube_0101 Binding 2
124fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_cube_0102_rgba32f DescriptorSet 2
125fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_cube_0102_rgba32f Binding 3
126fd4e5da5Sopenharmony_ciOpDecorate %uniform_sampler DescriptorSet 3
127fd4e5da5Sopenharmony_ciOpDecorate %uniform_sampler Binding 0
128fd4e5da5Sopenharmony_ciOpDecorate %input_flat_u32 Flat
129fd4e5da5Sopenharmony_ciOpDecorate %input_flat_u32 Location 0
130fd4e5da5Sopenharmony_ci)";
131fd4e5da5Sopenharmony_ci  }
132fd4e5da5Sopenharmony_ci
133fd4e5da5Sopenharmony_ci  ss << R"(
134fd4e5da5Sopenharmony_ci%void = OpTypeVoid
135fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
136fd4e5da5Sopenharmony_ci%bool = OpTypeBool
137fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
138fd4e5da5Sopenharmony_ci%f64 = OpTypeFloat 64
139fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
140fd4e5da5Sopenharmony_ci%s32 = OpTypeInt 32 1
141fd4e5da5Sopenharmony_ci%u64 = OpTypeInt 64 0
142fd4e5da5Sopenharmony_ci%s64 = OpTypeInt 64 1
143fd4e5da5Sopenharmony_ci%s32vec2 = OpTypeVector %s32 2
144fd4e5da5Sopenharmony_ci%u32vec2 = OpTypeVector %u32 2
145fd4e5da5Sopenharmony_ci%f32vec2 = OpTypeVector %f32 2
146fd4e5da5Sopenharmony_ci%u32vec3 = OpTypeVector %u32 3
147fd4e5da5Sopenharmony_ci%s32vec3 = OpTypeVector %s32 3
148fd4e5da5Sopenharmony_ci%f32vec3 = OpTypeVector %f32 3
149fd4e5da5Sopenharmony_ci%u32vec4 = OpTypeVector %u32 4
150fd4e5da5Sopenharmony_ci%s32vec4 = OpTypeVector %s32 4
151fd4e5da5Sopenharmony_ci%f32vec4 = OpTypeVector %f32 4
152fd4e5da5Sopenharmony_ci%boolvec4 = OpTypeVector %bool 4
153fd4e5da5Sopenharmony_ci
154fd4e5da5Sopenharmony_ci%f32_0 = OpConstant %f32 0
155fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1
156fd4e5da5Sopenharmony_ci%f32_0_5 = OpConstant %f32 0.5
157fd4e5da5Sopenharmony_ci%f32_0_25 = OpConstant %f32 0.25
158fd4e5da5Sopenharmony_ci%f32_0_75 = OpConstant %f32 0.75
159fd4e5da5Sopenharmony_ci
160fd4e5da5Sopenharmony_ci%f64_0 = OpConstant %f64 0
161fd4e5da5Sopenharmony_ci%f64_1 = OpConstant %f64 1
162fd4e5da5Sopenharmony_ci
163fd4e5da5Sopenharmony_ci%s32_0 = OpConstant %s32 0
164fd4e5da5Sopenharmony_ci%s32_1 = OpConstant %s32 1
165fd4e5da5Sopenharmony_ci%s32_2 = OpConstant %s32 2
166fd4e5da5Sopenharmony_ci%s32_3 = OpConstant %s32 3
167fd4e5da5Sopenharmony_ci%s32_4 = OpConstant %s32 4
168fd4e5da5Sopenharmony_ci%s32_m1 = OpConstant %s32 -1
169fd4e5da5Sopenharmony_ci
170fd4e5da5Sopenharmony_ci%u32_0 = OpConstant %u32 0
171fd4e5da5Sopenharmony_ci%u32_1 = OpConstant %u32 1
172fd4e5da5Sopenharmony_ci%u32_2 = OpConstant %u32 2
173fd4e5da5Sopenharmony_ci%u32_3 = OpConstant %u32 3
174fd4e5da5Sopenharmony_ci%u32_4 = OpConstant %u32 4
175fd4e5da5Sopenharmony_ci
176fd4e5da5Sopenharmony_ci%u64_0 = OpConstant %u64 0
177fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %u64 1
178fd4e5da5Sopenharmony_ci
179fd4e5da5Sopenharmony_ci%bool_t = OpConstantTrue %bool
180fd4e5da5Sopenharmony_ci
181fd4e5da5Sopenharmony_ci%u32vec2arr4 = OpTypeArray %u32vec2 %u32_4
182fd4e5da5Sopenharmony_ci%u32vec2arr3 = OpTypeArray %u32vec2 %u32_3
183fd4e5da5Sopenharmony_ci%u32arr4 = OpTypeArray %u32 %u32_4
184fd4e5da5Sopenharmony_ci%u32vec3arr4 = OpTypeArray %u32vec3 %u32_4
185fd4e5da5Sopenharmony_ci
186fd4e5da5Sopenharmony_ci%struct_u32_f32vec4 = OpTypeStruct %u32 %f32vec4
187fd4e5da5Sopenharmony_ci%struct_u64_f32vec4 = OpTypeStruct %u64 %f32vec4
188fd4e5da5Sopenharmony_ci%struct_u32_u32vec4 = OpTypeStruct %u32 %u32vec4
189fd4e5da5Sopenharmony_ci%struct_u32_f32vec3 = OpTypeStruct %u32 %f32vec3
190fd4e5da5Sopenharmony_ci%struct_f32_f32vec4 = OpTypeStruct %f32 %f32vec4
191fd4e5da5Sopenharmony_ci%struct_u32_u32 = OpTypeStruct %u32 %u32
192fd4e5da5Sopenharmony_ci%struct_f32_f32 = OpTypeStruct %f32 %f32
193fd4e5da5Sopenharmony_ci%struct_u32 = OpTypeStruct %u32
194fd4e5da5Sopenharmony_ci%struct_u32_f32_u32 = OpTypeStruct %u32 %f32 %u32
195fd4e5da5Sopenharmony_ci%struct_u32_f32vec4_u32 = OpTypeStruct %u32 %f32vec4 %u32
196fd4e5da5Sopenharmony_ci%struct_u32_u32arr4 = OpTypeStruct %u32 %u32arr4
197fd4e5da5Sopenharmony_ci
198fd4e5da5Sopenharmony_ci%u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
199fd4e5da5Sopenharmony_ci%u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
200fd4e5da5Sopenharmony_ci%u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
201fd4e5da5Sopenharmony_ci%u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
202fd4e5da5Sopenharmony_ci%u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
203fd4e5da5Sopenharmony_ci%u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
204fd4e5da5Sopenharmony_ci
205fd4e5da5Sopenharmony_ci%s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
206fd4e5da5Sopenharmony_ci%s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
207fd4e5da5Sopenharmony_ci%s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
208fd4e5da5Sopenharmony_ci%s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
209fd4e5da5Sopenharmony_ci%s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
210fd4e5da5Sopenharmony_ci%s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
211fd4e5da5Sopenharmony_ci
212fd4e5da5Sopenharmony_ci%f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
213fd4e5da5Sopenharmony_ci%f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
214fd4e5da5Sopenharmony_ci%f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
215fd4e5da5Sopenharmony_ci%f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
216fd4e5da5Sopenharmony_ci%f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
217fd4e5da5Sopenharmony_ci
218fd4e5da5Sopenharmony_ci%f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
219fd4e5da5Sopenharmony_ci%f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
220fd4e5da5Sopenharmony_ci
221fd4e5da5Sopenharmony_ci%f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
222fd4e5da5Sopenharmony_ci
223fd4e5da5Sopenharmony_ci%boolvec4_tttt = OpConstantComposite %boolvec4 %bool_t %bool_t %bool_t %bool_t
224fd4e5da5Sopenharmony_ci
225fd4e5da5Sopenharmony_ci%const_offsets = OpConstantComposite %u32vec2arr4 %u32vec2_01 %u32vec2_12 %u32vec2_01 %u32vec2_12
226fd4e5da5Sopenharmony_ci%const_offsets3x2 = OpConstantComposite %u32vec2arr3 %u32vec2_01 %u32vec2_12 %u32vec2_01
227fd4e5da5Sopenharmony_ci%const_offsets4xu = OpConstantComposite %u32arr4 %u32_0 %u32_0 %u32_0 %u32_0
228fd4e5da5Sopenharmony_ci%const_offsets4x3 = OpConstantComposite %u32vec3arr4 %u32vec3_012 %u32vec3_012 %u32vec3_012 %u32vec3_012
229fd4e5da5Sopenharmony_ci
230fd4e5da5Sopenharmony_ci%type_image_f32_1d_0001 = OpTypeImage %f32 1D 0 0 0 1 Unknown
231fd4e5da5Sopenharmony_ci%ptr_image_f32_1d_0001 = OpTypePointer UniformConstant %type_image_f32_1d_0001
232fd4e5da5Sopenharmony_ci%uniform_image_f32_1d_0001 = OpVariable %ptr_image_f32_1d_0001 UniformConstant
233fd4e5da5Sopenharmony_ci%type_sampled_image_f32_1d_0001 = OpTypeSampledImage %type_image_f32_1d_0001
234fd4e5da5Sopenharmony_ci
235fd4e5da5Sopenharmony_ci%type_image_f32_1d_0002_rgba32f = OpTypeImage %f32 1D 0 0 0 2 Rgba32f
236fd4e5da5Sopenharmony_ci%ptr_image_f32_1d_0002_rgba32f = OpTypePointer UniformConstant %type_image_f32_1d_0002_rgba32f
237fd4e5da5Sopenharmony_ci%uniform_image_f32_1d_0002_rgba32f = OpVariable %ptr_image_f32_1d_0002_rgba32f UniformConstant
238fd4e5da5Sopenharmony_ci
239fd4e5da5Sopenharmony_ci%type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
240fd4e5da5Sopenharmony_ci%ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
241fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
242fd4e5da5Sopenharmony_ci%type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
243fd4e5da5Sopenharmony_ci
244fd4e5da5Sopenharmony_ci%type_image_f32_2d_0011 = OpTypeImage %f32 2D 0 0 1 1 Unknown
245fd4e5da5Sopenharmony_ci%ptr_image_f32_2d_0011 = OpTypePointer UniformConstant %type_image_f32_2d_0011
246fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0011 = OpVariable %ptr_image_f32_2d_0011 UniformConstant
247fd4e5da5Sopenharmony_ci%type_sampled_image_f32_2d_0011 = OpTypeSampledImage %type_image_f32_2d_0011
248fd4e5da5Sopenharmony_ci
249fd4e5da5Sopenharmony_ci%type_image_u32_2d_0001 = OpTypeImage %u32 2D 0 0 0 1 Unknown
250fd4e5da5Sopenharmony_ci%ptr_image_u32_2d_0001 = OpTypePointer UniformConstant %type_image_u32_2d_0001
251fd4e5da5Sopenharmony_ci%uniform_image_u32_2d_0001 = OpVariable %ptr_image_u32_2d_0001 UniformConstant
252fd4e5da5Sopenharmony_ci%type_sampled_image_u32_2d_0001 = OpTypeSampledImage %type_image_u32_2d_0001
253fd4e5da5Sopenharmony_ci
254fd4e5da5Sopenharmony_ci%type_image_u32_3d_0001 = OpTypeImage %u32 3D 0 0 0 1 Unknown
255fd4e5da5Sopenharmony_ci%ptr_image_u32_3d_0001 = OpTypePointer UniformConstant %type_image_u32_3d_0001
256fd4e5da5Sopenharmony_ci%uniform_image_u32_3d_0001 = OpVariable %ptr_image_u32_3d_0001 UniformConstant
257fd4e5da5Sopenharmony_ci%type_sampled_image_u32_3d_0001 = OpTypeSampledImage %type_image_u32_3d_0001
258fd4e5da5Sopenharmony_ci
259fd4e5da5Sopenharmony_ci%type_image_u32_2d_0002 = OpTypeImage %u32 2D 0 0 0 2 Unknown
260fd4e5da5Sopenharmony_ci%ptr_image_u32_2d_0002 = OpTypePointer UniformConstant %type_image_u32_2d_0002
261fd4e5da5Sopenharmony_ci%uniform_image_u32_2d_0002 = OpVariable %ptr_image_u32_2d_0002 UniformConstant
262fd4e5da5Sopenharmony_ci
263fd4e5da5Sopenharmony_ci%type_image_s32_3d_0001 = OpTypeImage %s32 3D 0 0 0 1 Unknown
264fd4e5da5Sopenharmony_ci%ptr_image_s32_3d_0001 = OpTypePointer UniformConstant %type_image_s32_3d_0001
265fd4e5da5Sopenharmony_ci%uniform_image_s32_3d_0001 = OpVariable %ptr_image_s32_3d_0001 UniformConstant
266fd4e5da5Sopenharmony_ci%type_sampled_image_s32_3d_0001 = OpTypeSampledImage %type_image_s32_3d_0001
267fd4e5da5Sopenharmony_ci
268fd4e5da5Sopenharmony_ci%type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Unknown
269fd4e5da5Sopenharmony_ci%ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
270fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
271fd4e5da5Sopenharmony_ci
272fd4e5da5Sopenharmony_ci%type_image_s32_2d_0002 = OpTypeImage %s32 2D 0 0 0 2 Unknown
273fd4e5da5Sopenharmony_ci%ptr_image_s32_2d_0002 = OpTypePointer UniformConstant %type_image_s32_2d_0002
274fd4e5da5Sopenharmony_ci%uniform_image_s32_2d_0002 = OpVariable %ptr_image_s32_2d_0002 UniformConstant
275fd4e5da5Sopenharmony_ci
276fd4e5da5Sopenharmony_ci%type_image_f32_spd_0002 = OpTypeImage %f32 SubpassData 0 0 0 2 Unknown
277fd4e5da5Sopenharmony_ci%ptr_image_f32_spd_0002 = OpTypePointer UniformConstant %type_image_f32_spd_0002
278fd4e5da5Sopenharmony_ci%uniform_image_f32_spd_0002 = OpVariable %ptr_image_f32_spd_0002 UniformConstant
279fd4e5da5Sopenharmony_ci
280fd4e5da5Sopenharmony_ci%type_image_f32_3d_0111 = OpTypeImage %f32 3D 0 1 1 1 Unknown
281fd4e5da5Sopenharmony_ci%ptr_image_f32_3d_0111 = OpTypePointer UniformConstant %type_image_f32_3d_0111
282fd4e5da5Sopenharmony_ci%uniform_image_f32_3d_0111 = OpVariable %ptr_image_f32_3d_0111 UniformConstant
283fd4e5da5Sopenharmony_ci%type_sampled_image_f32_3d_0111 = OpTypeSampledImage %type_image_f32_3d_0111
284fd4e5da5Sopenharmony_ci
285fd4e5da5Sopenharmony_ci%type_image_f32_3d_0001 = OpTypeImage %f32 3D 0 0 0 1 Unknown
286fd4e5da5Sopenharmony_ci%ptr_image_f32_3d_0001 = OpTypePointer UniformConstant %type_image_f32_3d_0001
287fd4e5da5Sopenharmony_ci%uniform_image_f32_3d_0001 = OpVariable %ptr_image_f32_3d_0001 UniformConstant
288fd4e5da5Sopenharmony_ci%type_sampled_image_f32_3d_0001 = OpTypeSampledImage %type_image_f32_3d_0001
289fd4e5da5Sopenharmony_ci
290fd4e5da5Sopenharmony_ci%type_image_f32_cube_0101 = OpTypeImage %f32 Cube 0 1 0 1 Unknown
291fd4e5da5Sopenharmony_ci%ptr_image_f32_cube_0101 = OpTypePointer UniformConstant %type_image_f32_cube_0101
292fd4e5da5Sopenharmony_ci%uniform_image_f32_cube_0101 = OpVariable %ptr_image_f32_cube_0101 UniformConstant
293fd4e5da5Sopenharmony_ci%type_sampled_image_f32_cube_0101 = OpTypeSampledImage %type_image_f32_cube_0101
294fd4e5da5Sopenharmony_ci
295fd4e5da5Sopenharmony_ci%type_image_f32_cube_0102_rgba32f = OpTypeImage %f32 Cube 0 1 0 2 Rgba32f
296fd4e5da5Sopenharmony_ci%ptr_image_f32_cube_0102_rgba32f = OpTypePointer UniformConstant %type_image_f32_cube_0102_rgba32f
297fd4e5da5Sopenharmony_ci%uniform_image_f32_cube_0102_rgba32f = OpVariable %ptr_image_f32_cube_0102_rgba32f UniformConstant
298fd4e5da5Sopenharmony_ci
299fd4e5da5Sopenharmony_ci%type_sampler = OpTypeSampler
300fd4e5da5Sopenharmony_ci%ptr_sampler = OpTypePointer UniformConstant %type_sampler
301fd4e5da5Sopenharmony_ci%uniform_sampler = OpVariable %ptr_sampler UniformConstant
302fd4e5da5Sopenharmony_ci
303fd4e5da5Sopenharmony_ci%type_image_u32_buffer_0002_r32ui = OpTypeImage %u32 Buffer 0 0 0 2 R32ui
304fd4e5da5Sopenharmony_ci%ptr_Image_u32 = OpTypePointer Image %u32
305fd4e5da5Sopenharmony_ci%ptr_image_u32_buffer_0002_r32ui = OpTypePointer Private %type_image_u32_buffer_0002_r32ui
306fd4e5da5Sopenharmony_ci%private_image_u32_buffer_0002_r32ui = OpVariable %ptr_image_u32_buffer_0002_r32ui Private
307fd4e5da5Sopenharmony_ci
308fd4e5da5Sopenharmony_ci%ptr_Image_u32arr4 = OpTypePointer Image %u32arr4
309fd4e5da5Sopenharmony_ci
310fd4e5da5Sopenharmony_ci%type_image_u32_spd_0002 = OpTypeImage %u32 SubpassData 0 0 0 2 Unknown
311fd4e5da5Sopenharmony_ci%ptr_image_u32_spd_0002 = OpTypePointer Private %type_image_u32_spd_0002
312fd4e5da5Sopenharmony_ci%private_image_u32_spd_0002 = OpVariable %ptr_image_u32_spd_0002 Private
313fd4e5da5Sopenharmony_ci
314fd4e5da5Sopenharmony_ci%type_image_f32_buffer_0002_r32ui = OpTypeImage %f32 Buffer 0 0 0 2 R32ui
315fd4e5da5Sopenharmony_ci%ptr_Image_f32 = OpTypePointer Image %f32
316fd4e5da5Sopenharmony_ci%ptr_image_f32_buffer_0002_r32ui = OpTypePointer Private %type_image_f32_buffer_0002_r32ui
317fd4e5da5Sopenharmony_ci%private_image_f32_buffer_0002_r32ui = OpVariable %ptr_image_f32_buffer_0002_r32ui Private
318fd4e5da5Sopenharmony_ci
319fd4e5da5Sopenharmony_ci%ptr_input_flat_u32 = OpTypePointer Input %u32
320fd4e5da5Sopenharmony_ci%input_flat_u32 = OpVariable %ptr_input_flat_u32 Input
321fd4e5da5Sopenharmony_ci)";
322fd4e5da5Sopenharmony_ci
323fd4e5da5Sopenharmony_ci  if (env == SPV_ENV_UNIVERSAL_1_0) {
324fd4e5da5Sopenharmony_ci    ss << R"(
325fd4e5da5Sopenharmony_ci%type_image_void_2d_0001 = OpTypeImage %void 2D 0 0 0 1 Unknown
326fd4e5da5Sopenharmony_ci%ptr_image_void_2d_0001 = OpTypePointer UniformConstant %type_image_void_2d_0001
327fd4e5da5Sopenharmony_ci%uniform_image_void_2d_0001 = OpVariable %ptr_image_void_2d_0001 UniformConstant
328fd4e5da5Sopenharmony_ci%type_sampled_image_void_2d_0001 = OpTypeSampledImage %type_image_void_2d_0001
329fd4e5da5Sopenharmony_ci
330fd4e5da5Sopenharmony_ci%type_image_void_2d_0002 = OpTypeImage %void 2D 0 0 0 2 Unknown
331fd4e5da5Sopenharmony_ci%ptr_image_void_2d_0002 = OpTypePointer UniformConstant %type_image_void_2d_0002
332fd4e5da5Sopenharmony_ci%uniform_image_void_2d_0002 = OpVariable %ptr_image_void_2d_0002 UniformConstant
333fd4e5da5Sopenharmony_ci
334fd4e5da5Sopenharmony_ci%type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
335fd4e5da5Sopenharmony_ci%ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
336fd4e5da5Sopenharmony_ci%uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
337fd4e5da5Sopenharmony_ci%type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
338fd4e5da5Sopenharmony_ci)";
339fd4e5da5Sopenharmony_ci  }
340fd4e5da5Sopenharmony_ci
341fd4e5da5Sopenharmony_ci  ss << declarations;
342fd4e5da5Sopenharmony_ci
343fd4e5da5Sopenharmony_ci  ss << R"(
344fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
345fd4e5da5Sopenharmony_ci%main_entry = OpLabel
346fd4e5da5Sopenharmony_ci)";
347fd4e5da5Sopenharmony_ci
348fd4e5da5Sopenharmony_ci  ss << body;
349fd4e5da5Sopenharmony_ci
350fd4e5da5Sopenharmony_ci  ss << R"(
351fd4e5da5Sopenharmony_ciOpReturn
352fd4e5da5Sopenharmony_ciOpFunctionEnd)";
353fd4e5da5Sopenharmony_ci
354fd4e5da5Sopenharmony_ci  return ss.str();
355fd4e5da5Sopenharmony_ci}
356fd4e5da5Sopenharmony_ci
357fd4e5da5Sopenharmony_cistd::string GenerateKernelCode(
358fd4e5da5Sopenharmony_ci    const std::string& body,
359fd4e5da5Sopenharmony_ci    const std::string& capabilities_and_extensions = "",
360fd4e5da5Sopenharmony_ci    const std::string& declarations = "") {
361fd4e5da5Sopenharmony_ci  std::ostringstream ss;
362fd4e5da5Sopenharmony_ci  ss << R"(
363fd4e5da5Sopenharmony_ciOpCapability Addresses
364fd4e5da5Sopenharmony_ciOpCapability Kernel
365fd4e5da5Sopenharmony_ciOpCapability Linkage
366fd4e5da5Sopenharmony_ciOpCapability ImageQuery
367fd4e5da5Sopenharmony_ciOpCapability ImageGatherExtended
368fd4e5da5Sopenharmony_ciOpCapability InputAttachment
369fd4e5da5Sopenharmony_ciOpCapability SampledRect
370fd4e5da5Sopenharmony_ci)";
371fd4e5da5Sopenharmony_ci
372fd4e5da5Sopenharmony_ci  ss << capabilities_and_extensions;
373fd4e5da5Sopenharmony_ci  ss << R"(
374fd4e5da5Sopenharmony_ciOpMemoryModel Physical32 OpenCL
375fd4e5da5Sopenharmony_ci%void = OpTypeVoid
376fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
377fd4e5da5Sopenharmony_ci%bool = OpTypeBool
378fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
379fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
380fd4e5da5Sopenharmony_ci%u32vec2 = OpTypeVector %u32 2
381fd4e5da5Sopenharmony_ci%f32vec2 = OpTypeVector %f32 2
382fd4e5da5Sopenharmony_ci%u32vec3 = OpTypeVector %u32 3
383fd4e5da5Sopenharmony_ci%f32vec3 = OpTypeVector %f32 3
384fd4e5da5Sopenharmony_ci%u32vec4 = OpTypeVector %u32 4
385fd4e5da5Sopenharmony_ci%f32vec4 = OpTypeVector %f32 4
386fd4e5da5Sopenharmony_ci
387fd4e5da5Sopenharmony_ci%f32_0 = OpConstant %f32 0
388fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1
389fd4e5da5Sopenharmony_ci%f32_0_5 = OpConstant %f32 0.5
390fd4e5da5Sopenharmony_ci%f32_0_25 = OpConstant %f32 0.25
391fd4e5da5Sopenharmony_ci%f32_0_75 = OpConstant %f32 0.75
392fd4e5da5Sopenharmony_ci
393fd4e5da5Sopenharmony_ci%u32_0 = OpConstant %u32 0
394fd4e5da5Sopenharmony_ci%u32_1 = OpConstant %u32 1
395fd4e5da5Sopenharmony_ci%u32_2 = OpConstant %u32 2
396fd4e5da5Sopenharmony_ci%u32_3 = OpConstant %u32 3
397fd4e5da5Sopenharmony_ci%u32_4 = OpConstant %u32 4
398fd4e5da5Sopenharmony_ci
399fd4e5da5Sopenharmony_ci%u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
400fd4e5da5Sopenharmony_ci%u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
401fd4e5da5Sopenharmony_ci%u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
402fd4e5da5Sopenharmony_ci%u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
403fd4e5da5Sopenharmony_ci%u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
404fd4e5da5Sopenharmony_ci%u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
405fd4e5da5Sopenharmony_ci
406fd4e5da5Sopenharmony_ci%f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
407fd4e5da5Sopenharmony_ci%f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
408fd4e5da5Sopenharmony_ci%f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
409fd4e5da5Sopenharmony_ci%f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
410fd4e5da5Sopenharmony_ci%f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
411fd4e5da5Sopenharmony_ci
412fd4e5da5Sopenharmony_ci%f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
413fd4e5da5Sopenharmony_ci%f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
414fd4e5da5Sopenharmony_ci
415fd4e5da5Sopenharmony_ci%f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
416fd4e5da5Sopenharmony_ci
417fd4e5da5Sopenharmony_ci%type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
418fd4e5da5Sopenharmony_ci%ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
419fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
420fd4e5da5Sopenharmony_ci%type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
421fd4e5da5Sopenharmony_ci
422fd4e5da5Sopenharmony_ci%type_image_f32_2d_0011 = OpTypeImage %f32 2D 0 0 1 1 Unknown
423fd4e5da5Sopenharmony_ci%ptr_image_f32_2d_0011 = OpTypePointer UniformConstant %type_image_f32_2d_0011
424fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0011 = OpVariable %ptr_image_f32_2d_0011 UniformConstant
425fd4e5da5Sopenharmony_ci%type_sampled_image_f32_2d_0011 = OpTypeSampledImage %type_image_f32_2d_0011
426fd4e5da5Sopenharmony_ci
427fd4e5da5Sopenharmony_ci%type_image_f32_3d_0011 = OpTypeImage %f32 3D 0 0 1 1 Unknown
428fd4e5da5Sopenharmony_ci%ptr_image_f32_3d_0011 = OpTypePointer UniformConstant %type_image_f32_3d_0011
429fd4e5da5Sopenharmony_ci%uniform_image_f32_3d_0011 = OpVariable %ptr_image_f32_3d_0011 UniformConstant
430fd4e5da5Sopenharmony_ci%type_sampled_image_f32_3d_0011 = OpTypeSampledImage %type_image_f32_3d_0011
431fd4e5da5Sopenharmony_ci
432fd4e5da5Sopenharmony_ci%type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
433fd4e5da5Sopenharmony_ci%ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
434fd4e5da5Sopenharmony_ci%uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
435fd4e5da5Sopenharmony_ci%type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
436fd4e5da5Sopenharmony_ci
437fd4e5da5Sopenharmony_ci%type_sampler = OpTypeSampler
438fd4e5da5Sopenharmony_ci%ptr_sampler = OpTypePointer UniformConstant %type_sampler
439fd4e5da5Sopenharmony_ci%uniform_sampler = OpVariable %ptr_sampler UniformConstant
440fd4e5da5Sopenharmony_ci)";
441fd4e5da5Sopenharmony_ci
442fd4e5da5Sopenharmony_ci  ss << declarations;
443fd4e5da5Sopenharmony_ci
444fd4e5da5Sopenharmony_ci  ss << R"(
445fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
446fd4e5da5Sopenharmony_ci%main_entry = OpLabel
447fd4e5da5Sopenharmony_ci)";
448fd4e5da5Sopenharmony_ci
449fd4e5da5Sopenharmony_ci  ss << body;
450fd4e5da5Sopenharmony_ci  ss << R"(
451fd4e5da5Sopenharmony_ciOpReturn
452fd4e5da5Sopenharmony_ciOpFunctionEnd)";
453fd4e5da5Sopenharmony_ci
454fd4e5da5Sopenharmony_ci  return ss.str();
455fd4e5da5Sopenharmony_ci}
456fd4e5da5Sopenharmony_ci
457fd4e5da5Sopenharmony_cistd::string GetKernelHeader() {
458fd4e5da5Sopenharmony_ci  return R"(
459fd4e5da5Sopenharmony_ci  OpCapability Kernel
460fd4e5da5Sopenharmony_ci  OpCapability Addresses
461fd4e5da5Sopenharmony_ci  OpCapability Linkage
462fd4e5da5Sopenharmony_ci  OpMemoryModel Physical32 OpenCL
463fd4e5da5Sopenharmony_ci  %void = OpTypeVoid
464fd4e5da5Sopenharmony_ci  %func = OpTypeFunction %void
465fd4e5da5Sopenharmony_ci  %f32 = OpTypeFloat 32
466fd4e5da5Sopenharmony_ci  %u32 = OpTypeInt 32 0
467fd4e5da5Sopenharmony_ci  )";
468fd4e5da5Sopenharmony_ci}
469fd4e5da5Sopenharmony_ci
470fd4e5da5Sopenharmony_cistd::string TrivialMain() {
471fd4e5da5Sopenharmony_ci  return R"(
472fd4e5da5Sopenharmony_ci  %main = OpFunction %void None %func
473fd4e5da5Sopenharmony_ci  %entry = OpLabel
474fd4e5da5Sopenharmony_ci  OpReturn
475fd4e5da5Sopenharmony_ci  OpFunctionEnd
476fd4e5da5Sopenharmony_ci  )";
477fd4e5da5Sopenharmony_ci}
478fd4e5da5Sopenharmony_ci
479fd4e5da5Sopenharmony_cistd::string GetShaderHeader(const std::string& capabilities_and_extensions = "",
480fd4e5da5Sopenharmony_ci                            bool include_entry_point = true) {
481fd4e5da5Sopenharmony_ci  std::ostringstream ss;
482fd4e5da5Sopenharmony_ci  ss << R"(
483fd4e5da5Sopenharmony_ciOpCapability Shader
484fd4e5da5Sopenharmony_ciOpCapability Int64
485fd4e5da5Sopenharmony_ciOpCapability Float64
486fd4e5da5Sopenharmony_ci)";
487fd4e5da5Sopenharmony_ci
488fd4e5da5Sopenharmony_ci  if (!include_entry_point) {
489fd4e5da5Sopenharmony_ci    ss << "OpCapability Linkage\n";
490fd4e5da5Sopenharmony_ci  }
491fd4e5da5Sopenharmony_ci  ss << capabilities_and_extensions;
492fd4e5da5Sopenharmony_ci
493fd4e5da5Sopenharmony_ci  ss << R"(
494fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
495fd4e5da5Sopenharmony_ci)";
496fd4e5da5Sopenharmony_ci
497fd4e5da5Sopenharmony_ci  if (include_entry_point) {
498fd4e5da5Sopenharmony_ci    ss << "OpEntryPoint Fragment %main \"main\"\n";
499fd4e5da5Sopenharmony_ci    ss << "OpExecutionMode %main OriginUpperLeft";
500fd4e5da5Sopenharmony_ci  }
501fd4e5da5Sopenharmony_ci  ss << R"(
502fd4e5da5Sopenharmony_ci%void = OpTypeVoid
503fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
504fd4e5da5Sopenharmony_ci%bool = OpTypeBool
505fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
506fd4e5da5Sopenharmony_ci%f64 = OpTypeFloat 64
507fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
508fd4e5da5Sopenharmony_ci%u64 = OpTypeInt 64 0
509fd4e5da5Sopenharmony_ci%s32 = OpTypeInt 32 1
510fd4e5da5Sopenharmony_ci%s64 = OpTypeInt 64 1
511fd4e5da5Sopenharmony_ci)";
512fd4e5da5Sopenharmony_ci
513fd4e5da5Sopenharmony_ci  return ss.str();
514fd4e5da5Sopenharmony_ci}
515fd4e5da5Sopenharmony_ci
516fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongSampledType) {
517fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader("", false) + R"(
518fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %bool 2D 0 0 0 1 Unknown
519fd4e5da5Sopenharmony_ci)";
520fd4e5da5Sopenharmony_ci
521fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
522fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
523fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
524fd4e5da5Sopenharmony_ci              HasSubstr("Expected Sampled Type to be either void or "
525fd4e5da5Sopenharmony_ci                        "numerical scalar "
526fd4e5da5Sopenharmony_ci                        "type"));
527fd4e5da5Sopenharmony_ci}
528fd4e5da5Sopenharmony_ci
529fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageVoidSampledTypeVulkan) {
530fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
531fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %void 2D 0 0 0 1 Unknown
532fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
533fd4e5da5Sopenharmony_ci%main_lab = OpLabel
534fd4e5da5Sopenharmony_ciOpReturn
535fd4e5da5Sopenharmony_ciOpFunctionEnd
536fd4e5da5Sopenharmony_ci)";
537fd4e5da5Sopenharmony_ci
538fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
539fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
540fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
541fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
542fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
543fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
544fd4e5da5Sopenharmony_ci              HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
545fd4e5da5Sopenharmony_ci                        "or 32-bit float scalar type for Vulkan environment"));
546fd4e5da5Sopenharmony_ci}
547fd4e5da5Sopenharmony_ci
548fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageU32SampledTypeVulkan) {
549fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
550fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %u32 2D 0 0 0 1 Unknown
551fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
552fd4e5da5Sopenharmony_ci%main_lab = OpLabel
553fd4e5da5Sopenharmony_ciOpReturn
554fd4e5da5Sopenharmony_ciOpFunctionEnd
555fd4e5da5Sopenharmony_ci)";
556fd4e5da5Sopenharmony_ci
557fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
558fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
559fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
560fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
561fd4e5da5Sopenharmony_ci}
562fd4e5da5Sopenharmony_ci
563fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageI32SampledTypeVulkan) {
564fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
565fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %s32 2D 0 0 0 1 Unknown
566fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
567fd4e5da5Sopenharmony_ci%main_lab = OpLabel
568fd4e5da5Sopenharmony_ciOpReturn
569fd4e5da5Sopenharmony_ciOpFunctionEnd
570fd4e5da5Sopenharmony_ci)";
571fd4e5da5Sopenharmony_ci
572fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
573fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
574fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
575fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
576fd4e5da5Sopenharmony_ci}
577fd4e5da5Sopenharmony_ci
578fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageI64SampledTypeNoCapabilityVulkan) {
579fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
580fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %s64 2D 0 0 0 1 Unknown
581fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
582fd4e5da5Sopenharmony_ci%main_lab = OpLabel
583fd4e5da5Sopenharmony_ciOpReturn
584fd4e5da5Sopenharmony_ciOpFunctionEnd
585fd4e5da5Sopenharmony_ci)";
586fd4e5da5Sopenharmony_ci
587fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
588fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
589fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
590fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
591fd4e5da5Sopenharmony_ci              HasSubstr("Capability Int64ImageEXT is required when using "
592fd4e5da5Sopenharmony_ci                        "Sampled Type of 64-bit int"));
593fd4e5da5Sopenharmony_ci}
594fd4e5da5Sopenharmony_ci
595fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageI64SampledTypeVulkan) {
596fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader(
597fd4e5da5Sopenharmony_ci                               "OpCapability Int64ImageEXT\nOpExtension "
598fd4e5da5Sopenharmony_ci                               "\"SPV_EXT_shader_image_int64\"\n") +
599fd4e5da5Sopenharmony_ci                           R"(
600fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %s64 2D 0 0 0 1 Unknown
601fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
602fd4e5da5Sopenharmony_ci%main_lab = OpLabel
603fd4e5da5Sopenharmony_ciOpReturn
604fd4e5da5Sopenharmony_ciOpFunctionEnd
605fd4e5da5Sopenharmony_ci)";
606fd4e5da5Sopenharmony_ci
607fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
608fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
609fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
610fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
611fd4e5da5Sopenharmony_ci}
612fd4e5da5Sopenharmony_ci
613fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageU64SampledTypeNoCapabilityVulkan) {
614fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
615fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %u64 2D 0 0 0 1 Unknown
616fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
617fd4e5da5Sopenharmony_ci%main_lab = OpLabel
618fd4e5da5Sopenharmony_ciOpReturn
619fd4e5da5Sopenharmony_ciOpFunctionEnd
620fd4e5da5Sopenharmony_ci)";
621fd4e5da5Sopenharmony_ci
622fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
623fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
624fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
625fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
626fd4e5da5Sopenharmony_ci              HasSubstr("Capability Int64ImageEXT is required when using "
627fd4e5da5Sopenharmony_ci                        "Sampled Type of 64-bit int"));
628fd4e5da5Sopenharmony_ci}
629fd4e5da5Sopenharmony_ci
630fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageU64SampledTypeVulkan) {
631fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader(
632fd4e5da5Sopenharmony_ci                               "OpCapability Int64ImageEXT\nOpExtension "
633fd4e5da5Sopenharmony_ci                               "\"SPV_EXT_shader_image_int64\"\n") +
634fd4e5da5Sopenharmony_ci                           R"(
635fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %u64 2D 0 0 0 1 Unknown
636fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
637fd4e5da5Sopenharmony_ci%main_lab = OpLabel
638fd4e5da5Sopenharmony_ciOpReturn
639fd4e5da5Sopenharmony_ciOpFunctionEnd
640fd4e5da5Sopenharmony_ci)";
641fd4e5da5Sopenharmony_ci
642fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
643fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
644fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
645fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
646fd4e5da5Sopenharmony_ci}
647fd4e5da5Sopenharmony_ci
648fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageF32SampledTypeVulkan) {
649fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
650fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown
651fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
652fd4e5da5Sopenharmony_ci%main_lab = OpLabel
653fd4e5da5Sopenharmony_ciOpReturn
654fd4e5da5Sopenharmony_ciOpFunctionEnd
655fd4e5da5Sopenharmony_ci)";
656fd4e5da5Sopenharmony_ci
657fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
658fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
659fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
660fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
661fd4e5da5Sopenharmony_ci}
662fd4e5da5Sopenharmony_ci
663fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageF64SampledTypeVulkan) {
664fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
665fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f64 2D 0 0 0 1 Unknown
666fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
667fd4e5da5Sopenharmony_ci%main_lab = OpLabel
668fd4e5da5Sopenharmony_ciOpReturn
669fd4e5da5Sopenharmony_ciOpFunctionEnd
670fd4e5da5Sopenharmony_ci)";
671fd4e5da5Sopenharmony_ci
672fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
673fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
674fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
675fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
676fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
677fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
678fd4e5da5Sopenharmony_ci              HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
679fd4e5da5Sopenharmony_ci                        "or 32-bit float scalar type for Vulkan environment"));
680fd4e5da5Sopenharmony_ci}
681fd4e5da5Sopenharmony_ci
682fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageF64SampledTypeWithInt64Vulkan) {
683fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader(
684fd4e5da5Sopenharmony_ci                               "OpCapability Int64ImageEXT\nOpExtension "
685fd4e5da5Sopenharmony_ci                               "\"SPV_EXT_shader_image_int64\"\n") +
686fd4e5da5Sopenharmony_ci                           R"(
687fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f64 2D 0 0 0 1 Unknown
688fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
689fd4e5da5Sopenharmony_ci%main_lab = OpLabel
690fd4e5da5Sopenharmony_ciOpReturn
691fd4e5da5Sopenharmony_ciOpFunctionEnd
692fd4e5da5Sopenharmony_ci)";
693fd4e5da5Sopenharmony_ci
694fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
695fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
696fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
697fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
698fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
699fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
700fd4e5da5Sopenharmony_ci              HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
701fd4e5da5Sopenharmony_ci                        "or 32-bit float scalar type for Vulkan environment"));
702fd4e5da5Sopenharmony_ci}
703fd4e5da5Sopenharmony_ci
704fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongDepth) {
705fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader("", false) + R"(
706fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 2D 3 0 0 1 Unknown
707fd4e5da5Sopenharmony_ci)";
708fd4e5da5Sopenharmony_ci
709fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
710fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
711fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
712fd4e5da5Sopenharmony_ci              HasSubstr("Invalid Depth 3 (must be 0, 1 or 2)"));
713fd4e5da5Sopenharmony_ci}
714fd4e5da5Sopenharmony_ci
715fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongArrayed) {
716fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader("", false) + R"(
717fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 2D 0 2 0 1 Unknown
718fd4e5da5Sopenharmony_ci)";
719fd4e5da5Sopenharmony_ci
720fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
721fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
722fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
723fd4e5da5Sopenharmony_ci              HasSubstr("Invalid Arrayed 2 (must be 0 or 1)"));
724fd4e5da5Sopenharmony_ci}
725fd4e5da5Sopenharmony_ci
726fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongMS) {
727fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader("", false) + R"(
728fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 2D 0 0 2 1 Unknown
729fd4e5da5Sopenharmony_ci)";
730fd4e5da5Sopenharmony_ci
731fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
732fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
733fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
734fd4e5da5Sopenharmony_ci              HasSubstr("Invalid MS 2 (must be 0 or 1)"));
735fd4e5da5Sopenharmony_ci}
736fd4e5da5Sopenharmony_ci
737fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongSampled) {
738fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader("", false) + R"(
739fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 2D 0 0 0 3 Unknown
740fd4e5da5Sopenharmony_ci)";
741fd4e5da5Sopenharmony_ci
742fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
743fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
744fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
745fd4e5da5Sopenharmony_ci              HasSubstr("Invalid Sampled 3 (must be 0, 1 or 2)"));
746fd4e5da5Sopenharmony_ci}
747fd4e5da5Sopenharmony_ci
748fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongSampledForSubpassData) {
749fd4e5da5Sopenharmony_ci  const std::string code =
750fd4e5da5Sopenharmony_ci      GetShaderHeader("OpCapability InputAttachment\n", false) +
751fd4e5da5Sopenharmony_ci      R"(
752fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
753fd4e5da5Sopenharmony_ci)";
754fd4e5da5Sopenharmony_ci
755fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
756fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
757fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
758fd4e5da5Sopenharmony_ci              HasSubstr("Dim SubpassData requires Sampled to be 2"));
759fd4e5da5Sopenharmony_ci}
760fd4e5da5Sopenharmony_ci
761fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongSampledForSubpassDataVulkan) {
762fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
763fd4e5da5Sopenharmony_ci                           R"(
764fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
765fd4e5da5Sopenharmony_ci)" + TrivialMain();
766fd4e5da5Sopenharmony_ci
767fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
768fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
769fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
770fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06214"));
771fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
772fd4e5da5Sopenharmony_ci              HasSubstr("Dim SubpassData requires Sampled to be 2"));
773fd4e5da5Sopenharmony_ci}
774fd4e5da5Sopenharmony_ci
775fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongArrayForSubpassDataVulkan) {
776fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
777fd4e5da5Sopenharmony_ci                           R"(
778fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 SubpassData 0 1 0 2 Unknown
779fd4e5da5Sopenharmony_ci)" + TrivialMain();
780fd4e5da5Sopenharmony_ci
781fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
782fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
783fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
784fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06214"));
785fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
786fd4e5da5Sopenharmony_ci              HasSubstr("Dim SubpassData requires Arrayed to be 0"));
787fd4e5da5Sopenharmony_ci}
788fd4e5da5Sopenharmony_ci
789fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongSampledTypeForTileImageDataEXT) {
790fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader(
791fd4e5da5Sopenharmony_ci                               "OpCapability TileImageColorReadAccessEXT\n"
792fd4e5da5Sopenharmony_ci                               "OpExtension \"SPV_EXT_shader_tile_image\"\n",
793fd4e5da5Sopenharmony_ci                               false) +
794fd4e5da5Sopenharmony_ci                           R"(
795fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %void TileImageDataEXT 0 0 0 2 Unknown
796fd4e5da5Sopenharmony_ci)";
797fd4e5da5Sopenharmony_ci
798fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
799fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
800fd4e5da5Sopenharmony_ci  EXPECT_THAT(
801fd4e5da5Sopenharmony_ci      getDiagnosticString(),
802fd4e5da5Sopenharmony_ci      HasSubstr(
803fd4e5da5Sopenharmony_ci          "Dim TileImageDataEXT requires Sampled Type to be not OpTypeVoid"));
804fd4e5da5Sopenharmony_ci}
805fd4e5da5Sopenharmony_ci
806fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongSampledForTileImageDataEXT) {
807fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader(
808fd4e5da5Sopenharmony_ci                               "OpCapability TileImageColorReadAccessEXT\n"
809fd4e5da5Sopenharmony_ci                               "OpExtension \"SPV_EXT_shader_tile_image\"\n",
810fd4e5da5Sopenharmony_ci                               false) +
811fd4e5da5Sopenharmony_ci                           R"(
812fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 1 Unknown
813fd4e5da5Sopenharmony_ci)";
814fd4e5da5Sopenharmony_ci
815fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
816fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
817fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
818fd4e5da5Sopenharmony_ci              HasSubstr("Dim TileImageDataEXT requires Sampled to be 2"));
819fd4e5da5Sopenharmony_ci}
820fd4e5da5Sopenharmony_ci
821fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongFormatForTileImageDataEXT) {
822fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader(
823fd4e5da5Sopenharmony_ci                               "OpCapability TileImageColorReadAccessEXT\n"
824fd4e5da5Sopenharmony_ci                               "OpExtension \"SPV_EXT_shader_tile_image\"\n",
825fd4e5da5Sopenharmony_ci                               false) +
826fd4e5da5Sopenharmony_ci                           R"(
827fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Rgba32f
828fd4e5da5Sopenharmony_ci)";
829fd4e5da5Sopenharmony_ci
830fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
831fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
832fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
833fd4e5da5Sopenharmony_ci              HasSubstr("Dim TileImageDataEXT requires format Unknown"));
834fd4e5da5Sopenharmony_ci}
835fd4e5da5Sopenharmony_ci
836fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongDepthForTileImageDataEXT) {
837fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader(
838fd4e5da5Sopenharmony_ci                               "OpCapability TileImageColorReadAccessEXT\n"
839fd4e5da5Sopenharmony_ci                               "OpExtension \"SPV_EXT_shader_tile_image\"\n",
840fd4e5da5Sopenharmony_ci                               false) +
841fd4e5da5Sopenharmony_ci                           R"(
842fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 TileImageDataEXT 1 0 0 2 Unknown
843fd4e5da5Sopenharmony_ci)";
844fd4e5da5Sopenharmony_ci
845fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
846fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
847fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
848fd4e5da5Sopenharmony_ci              HasSubstr("Dim TileImageDataEXT requires Depth to be 0"));
849fd4e5da5Sopenharmony_ci}
850fd4e5da5Sopenharmony_ci
851fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongArrayedForTileImageDataEXT) {
852fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader(
853fd4e5da5Sopenharmony_ci                               "OpCapability TileImageColorReadAccessEXT\n"
854fd4e5da5Sopenharmony_ci                               "OpExtension \"SPV_EXT_shader_tile_image\"\n",
855fd4e5da5Sopenharmony_ci                               false) +
856fd4e5da5Sopenharmony_ci                           R"(
857fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 TileImageDataEXT 0 1 0 2 Unknown
858fd4e5da5Sopenharmony_ci)";
859fd4e5da5Sopenharmony_ci
860fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
861fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
862fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
863fd4e5da5Sopenharmony_ci              HasSubstr("Dim TileImageDataEXT requires Arrayed to be 0"));
864fd4e5da5Sopenharmony_ci}
865fd4e5da5Sopenharmony_ci
866fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeSampledImage_TileImageDataEXT_Error) {
867fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader(
868fd4e5da5Sopenharmony_ci                               "OpCapability TileImageColorReadAccessEXT\n"
869fd4e5da5Sopenharmony_ci                               "OpExtension \"SPV_EXT_shader_tile_image\"\n",
870fd4e5da5Sopenharmony_ci                               false) +
871fd4e5da5Sopenharmony_ci                           R"(
872fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
873fd4e5da5Sopenharmony_ci%simg_type = OpTypeSampledImage %img_type
874fd4e5da5Sopenharmony_ci)";
875fd4e5da5Sopenharmony_ci
876fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
877fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
878fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
879fd4e5da5Sopenharmony_ci              HasSubstr("Sampled image type requires an image type with "
880fd4e5da5Sopenharmony_ci                        "\"Sampled\" operand set to 0 or 1"));
881fd4e5da5Sopenharmony_ci}
882fd4e5da5Sopenharmony_ci
883fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerImageDimTileImageDataEXTBad) {
884fd4e5da5Sopenharmony_ci  const std::string body = R"(
885fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %tile_image_u32_tid_0002 %u32_0 %u32_0
886fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
887fd4e5da5Sopenharmony_ci)";
888fd4e5da5Sopenharmony_ci  const std::string decl = R"(
889fd4e5da5Sopenharmony_ci%type_image_u32_tid_0002 = OpTypeImage %u32 TileImageDataEXT 0 0 0 2 Unknown
890fd4e5da5Sopenharmony_ci%ptr_image_u32_tid_0002 = OpTypePointer TileImageEXT %type_image_u32_tid_0002
891fd4e5da5Sopenharmony_ci%tile_image_u32_tid_0002 = OpVariable %ptr_image_u32_tid_0002 TileImageEXT
892fd4e5da5Sopenharmony_ci)";
893fd4e5da5Sopenharmony_ci
894fd4e5da5Sopenharmony_ci  const std::string extra = R"(
895fd4e5da5Sopenharmony_ciOpCapability TileImageColorReadAccessEXT
896fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_tile_image"
897fd4e5da5Sopenharmony_ci)";
898fd4e5da5Sopenharmony_ci
899fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
900fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
901fd4e5da5Sopenharmony_ci                          .c_str());
902fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
903fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
904fd4e5da5Sopenharmony_ci              HasSubstr("Image Dim TileImageDataEXT cannot be used with "
905fd4e5da5Sopenharmony_ci                        "OpImageTexelPointer"));
906fd4e5da5Sopenharmony_ci}
907fd4e5da5Sopenharmony_ci
908fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadTileImageDataEXT) {
909fd4e5da5Sopenharmony_ci  const std::string body = R"(
910fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
911fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec2_01
912fd4e5da5Sopenharmony_ci)";
913fd4e5da5Sopenharmony_ci
914fd4e5da5Sopenharmony_ci  const std::string decl = R"(
915fd4e5da5Sopenharmony_ci%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
916fd4e5da5Sopenharmony_ci%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
917fd4e5da5Sopenharmony_ci%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
918fd4e5da5Sopenharmony_ci)";
919fd4e5da5Sopenharmony_ci
920fd4e5da5Sopenharmony_ci  const std::string extra = R"(
921fd4e5da5Sopenharmony_ciOpCapability StorageImageReadWithoutFormat
922fd4e5da5Sopenharmony_ciOpCapability TileImageColorReadAccessEXT
923fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_tile_image"
924fd4e5da5Sopenharmony_ci)";
925fd4e5da5Sopenharmony_ci
926fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
927fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
928fd4e5da5Sopenharmony_ci                          .c_str());
929fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
930fd4e5da5Sopenharmony_ci  EXPECT_THAT(
931fd4e5da5Sopenharmony_ci      getDiagnosticString(),
932fd4e5da5Sopenharmony_ci      HasSubstr("Image Dim TileImageDataEXT cannot be used with ImageRead"));
933fd4e5da5Sopenharmony_ci}
934fd4e5da5Sopenharmony_ci
935fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteTileImageDataEXT) {
936fd4e5da5Sopenharmony_ci  const std::string body = R"(
937fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
938fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %f32vec4_0000
939fd4e5da5Sopenharmony_ci)";
940fd4e5da5Sopenharmony_ci
941fd4e5da5Sopenharmony_ci  const std::string decl = R"(
942fd4e5da5Sopenharmony_ci%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
943fd4e5da5Sopenharmony_ci%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
944fd4e5da5Sopenharmony_ci%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
945fd4e5da5Sopenharmony_ci)";
946fd4e5da5Sopenharmony_ci
947fd4e5da5Sopenharmony_ci  const std::string extra = R"(
948fd4e5da5Sopenharmony_ciOpCapability TileImageColorReadAccessEXT
949fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_tile_image"
950fd4e5da5Sopenharmony_ci)";
951fd4e5da5Sopenharmony_ci
952fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
953fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
954fd4e5da5Sopenharmony_ci                          .c_str());
955fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
956fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
957fd4e5da5Sopenharmony_ci              HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
958fd4e5da5Sopenharmony_ci}
959fd4e5da5Sopenharmony_ci
960fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryFormatTileImageDataEXT) {
961fd4e5da5Sopenharmony_ci  const std::string body = R"(
962fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
963fd4e5da5Sopenharmony_ci%res1 = OpImageQueryFormat %u32 %img
964fd4e5da5Sopenharmony_ci)";
965fd4e5da5Sopenharmony_ci
966fd4e5da5Sopenharmony_ci  const std::string decl = R"(
967fd4e5da5Sopenharmony_ci%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
968fd4e5da5Sopenharmony_ci%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
969fd4e5da5Sopenharmony_ci%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
970fd4e5da5Sopenharmony_ci)";
971fd4e5da5Sopenharmony_ci
972fd4e5da5Sopenharmony_ci  const std::string extra = R"(
973fd4e5da5Sopenharmony_ciOpCapability TileImageColorReadAccessEXT
974fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_tile_image"
975fd4e5da5Sopenharmony_ci)";
976fd4e5da5Sopenharmony_ci
977fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body, extra, decl).c_str());
978fd4e5da5Sopenharmony_ci
979fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
980fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
981fd4e5da5Sopenharmony_ci              HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
982fd4e5da5Sopenharmony_ci}
983fd4e5da5Sopenharmony_ci
984fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryOrderTileImageDataEXT) {
985fd4e5da5Sopenharmony_ci  const std::string body = R"(
986fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
987fd4e5da5Sopenharmony_ci%res1 = OpImageQueryOrder %u32 %img
988fd4e5da5Sopenharmony_ci)";
989fd4e5da5Sopenharmony_ci
990fd4e5da5Sopenharmony_ci  const std::string decl = R"(
991fd4e5da5Sopenharmony_ci%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
992fd4e5da5Sopenharmony_ci%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
993fd4e5da5Sopenharmony_ci%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
994fd4e5da5Sopenharmony_ci)";
995fd4e5da5Sopenharmony_ci
996fd4e5da5Sopenharmony_ci  const std::string extra = R"(
997fd4e5da5Sopenharmony_ciOpCapability TileImageColorReadAccessEXT
998fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_tile_image"
999fd4e5da5Sopenharmony_ci)";
1000fd4e5da5Sopenharmony_ci
1001fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body, extra, decl).c_str());
1002fd4e5da5Sopenharmony_ci
1003fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1004fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1005fd4e5da5Sopenharmony_ci              HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
1006fd4e5da5Sopenharmony_ci}
1007fd4e5da5Sopenharmony_ci
1008fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseFetchTileImageDataEXT) {
1009fd4e5da5Sopenharmony_ci  const std::string body = R"(
1010fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
1011fd4e5da5Sopenharmony_ci%res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
1012fd4e5da5Sopenharmony_ci)";
1013fd4e5da5Sopenharmony_ci
1014fd4e5da5Sopenharmony_ci  const std::string decl = R"(
1015fd4e5da5Sopenharmony_ci%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
1016fd4e5da5Sopenharmony_ci%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
1017fd4e5da5Sopenharmony_ci%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
1018fd4e5da5Sopenharmony_ci)";
1019fd4e5da5Sopenharmony_ci
1020fd4e5da5Sopenharmony_ci  const std::string extra = R"(
1021fd4e5da5Sopenharmony_ciOpCapability StorageImageReadWithoutFormat
1022fd4e5da5Sopenharmony_ciOpCapability TileImageColorReadAccessEXT
1023fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_tile_image"
1024fd4e5da5Sopenharmony_ci)";
1025fd4e5da5Sopenharmony_ci
1026fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1027fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
1028fd4e5da5Sopenharmony_ci                          .c_str());
1029fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1030fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1031fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled' parameter to be 1"));
1032fd4e5da5Sopenharmony_ci}
1033fd4e5da5Sopenharmony_ci
1034fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadTileImageDataEXT) {
1035fd4e5da5Sopenharmony_ci  const std::string body = R"(
1036fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
1037fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
1038fd4e5da5Sopenharmony_ci)";
1039fd4e5da5Sopenharmony_ci
1040fd4e5da5Sopenharmony_ci  const std::string decl = R"(
1041fd4e5da5Sopenharmony_ci%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
1042fd4e5da5Sopenharmony_ci%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
1043fd4e5da5Sopenharmony_ci%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
1044fd4e5da5Sopenharmony_ci)";
1045fd4e5da5Sopenharmony_ci
1046fd4e5da5Sopenharmony_ci  const std::string extra = R"(
1047fd4e5da5Sopenharmony_ciOpCapability StorageImageReadWithoutFormat
1048fd4e5da5Sopenharmony_ciOpCapability TileImageColorReadAccessEXT
1049fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_tile_image"
1050fd4e5da5Sopenharmony_ci)";
1051fd4e5da5Sopenharmony_ci
1052fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1053fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
1054fd4e5da5Sopenharmony_ci                          .c_str());
1055fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1056fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1057fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1058fd4e5da5Sopenharmony_ci      HasSubstr(
1059fd4e5da5Sopenharmony_ci          "Image Dim TileImageDataEXT cannot be used with ImageSparseRead"));
1060fd4e5da5Sopenharmony_ci}
1061fd4e5da5Sopenharmony_ci
1062fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImage_OpenCL_Sampled0_OK) {
1063fd4e5da5Sopenharmony_ci  const std::string code = GetKernelHeader() + R"(
1064fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
1065fd4e5da5Sopenharmony_ci)";
1066fd4e5da5Sopenharmony_ci
1067fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1068fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1069fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
1070fd4e5da5Sopenharmony_ci}
1071fd4e5da5Sopenharmony_ci
1072fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImage_OpenCL_Sampled1_Invalid) {
1073fd4e5da5Sopenharmony_ci  const std::string code = GetKernelHeader() + R"(
1074fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %void 2D 0 0 0 1 Unknown ReadOnly
1075fd4e5da5Sopenharmony_ci)";
1076fd4e5da5Sopenharmony_ci
1077fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1078fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1079fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1080fd4e5da5Sopenharmony_ci              HasSubstr("Sampled must be 0 in the OpenCL environment."));
1081fd4e5da5Sopenharmony_ci}
1082fd4e5da5Sopenharmony_ci
1083fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImage_OpenCL_Sampled2_Invalid) {
1084fd4e5da5Sopenharmony_ci  const std::string code = GetKernelHeader() + R"(
1085fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %void 2D 0 0 0 2 Unknown ReadOnly
1086fd4e5da5Sopenharmony_ci)";
1087fd4e5da5Sopenharmony_ci
1088fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1089fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1090fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1091fd4e5da5Sopenharmony_ci              HasSubstr("Sampled must be 0 in the OpenCL environment."));
1092fd4e5da5Sopenharmony_ci}
1093fd4e5da5Sopenharmony_ci
1094fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImage_OpenCL_AccessQualifierMissing) {
1095fd4e5da5Sopenharmony_ci  const std::string code = GetKernelHeader() + R"(
1096fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %void 2D 0 0 0 0 Unknown
1097fd4e5da5Sopenharmony_ci)";
1098fd4e5da5Sopenharmony_ci
1099fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1100fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1101fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1102fd4e5da5Sopenharmony_ci              HasSubstr("In the OpenCL environment, the optional Access "
1103fd4e5da5Sopenharmony_ci                        "Qualifier must be present"));
1104fd4e5da5Sopenharmony_ci}
1105fd4e5da5Sopenharmony_ci
1106fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImage_Vulkan_Sampled1_OK) {
1107fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
1108fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown
1109fd4e5da5Sopenharmony_ci)" + TrivialMain();
1110fd4e5da5Sopenharmony_ci
1111fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1112fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1113fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
1114fd4e5da5Sopenharmony_ci}
1115fd4e5da5Sopenharmony_ci
1116fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImage_Vulkan_Sampled2_OK) {
1117fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
1118fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
1119fd4e5da5Sopenharmony_ci)" + TrivialMain();
1120fd4e5da5Sopenharmony_ci
1121fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1122fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1123fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
1124fd4e5da5Sopenharmony_ci}
1125fd4e5da5Sopenharmony_ci
1126fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImage_Vulkan_Sampled0_Invalid) {
1127fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
1128fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 2D 0 0 0 0 Unknown
1129fd4e5da5Sopenharmony_ci)" + TrivialMain();
1130fd4e5da5Sopenharmony_ci
1131fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1132fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1133fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1134fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
1135fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1136fd4e5da5Sopenharmony_ci              HasSubstr("Sampled must be 1 or 2 in the Vulkan environment."));
1137fd4e5da5Sopenharmony_ci}
1138fd4e5da5Sopenharmony_ci
1139fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageWrongFormatForSubpassData) {
1140fd4e5da5Sopenharmony_ci  const std::string code =
1141fd4e5da5Sopenharmony_ci      GetShaderHeader("OpCapability InputAttachment\n", false) +
1142fd4e5da5Sopenharmony_ci      R"(
1143fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 SubpassData 0 0 0 2 Rgba32f
1144fd4e5da5Sopenharmony_ci)";
1145fd4e5da5Sopenharmony_ci
1146fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1147fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1148fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1149fd4e5da5Sopenharmony_ci              HasSubstr("Dim SubpassData requires format Unknown"));
1150fd4e5da5Sopenharmony_ci}
1151fd4e5da5Sopenharmony_ci
1152fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageMultisampleStorageImage_MissingCapability) {
1153fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader("", false) +
1154fd4e5da5Sopenharmony_ci                           R"(
1155fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
1156fd4e5da5Sopenharmony_ci)";
1157fd4e5da5Sopenharmony_ci
1158fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1159fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()) << code;
1160fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1161fd4e5da5Sopenharmony_ci              HasSubstr("Capability StorageImageMultisample is required when "
1162fd4e5da5Sopenharmony_ci                        "using multisampled storage image"));
1163fd4e5da5Sopenharmony_ci}
1164fd4e5da5Sopenharmony_ci
1165fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageMultisampleStorageImage_UsesCapability) {
1166fd4e5da5Sopenharmony_ci  const std::string code =
1167fd4e5da5Sopenharmony_ci      GetShaderHeader("OpCapability StorageImageMultisample\n", false) +
1168fd4e5da5Sopenharmony_ci      R"(
1169fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
1170fd4e5da5Sopenharmony_ci)";
1171fd4e5da5Sopenharmony_ci
1172fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1173fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
1174fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
1175fd4e5da5Sopenharmony_ci}
1176fd4e5da5Sopenharmony_ci
1177fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeImageMultisampleSubpassData_OK) {
1178fd4e5da5Sopenharmony_ci  const std::string code =
1179fd4e5da5Sopenharmony_ci      GetShaderHeader("OpCapability InputAttachment\n", false) +
1180fd4e5da5Sopenharmony_ci      R"(
1181fd4e5da5Sopenharmony_ci%img_type = OpTypeImage %f32 SubpassData 0 0 1 2 Unknown
1182fd4e5da5Sopenharmony_ci)";
1183fd4e5da5Sopenharmony_ci
1184fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1185fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
1186fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
1187fd4e5da5Sopenharmony_ci}
1188fd4e5da5Sopenharmony_ci
1189fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeSampledImage_NotImage_Error) {
1190fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader("", false) + R"(
1191fd4e5da5Sopenharmony_ci%simg_type = OpTypeSampledImage %f32
1192fd4e5da5Sopenharmony_ci)";
1193fd4e5da5Sopenharmony_ci
1194fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1195fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1196fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1197fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image to be of type OpTypeImage"));
1198fd4e5da5Sopenharmony_ci}
1199fd4e5da5Sopenharmony_ci
1200fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeSampledImage_Sampled0_Success) {
1201fd4e5da5Sopenharmony_ci  // This is ok in the OpenCL and universal environments.
1202fd4e5da5Sopenharmony_ci  // Vulkan will reject an OpTypeImage with Sampled=0, checked elsewhere.
1203fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
1204fd4e5da5Sopenharmony_ci%imty = OpTypeImage %f32 2D 0 0 0 0 Unknown
1205fd4e5da5Sopenharmony_ci%simg_type = OpTypeSampledImage %imty
1206fd4e5da5Sopenharmony_ci)" + TrivialMain();
1207fd4e5da5Sopenharmony_ci
1208fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1209fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1210fd4e5da5Sopenharmony_ci  EXPECT_EQ(getDiagnosticString(), "");
1211fd4e5da5Sopenharmony_ci}
1212fd4e5da5Sopenharmony_ci
1213fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeSampledImage_Sampled2_Error) {
1214fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
1215fd4e5da5Sopenharmony_ci%storage_image = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
1216fd4e5da5Sopenharmony_ci%simg_type = OpTypeSampledImage %storage_image
1217fd4e5da5Sopenharmony_ci)" + TrivialMain();
1218fd4e5da5Sopenharmony_ci
1219fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1220fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1221fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1222fd4e5da5Sopenharmony_ci              HasSubstr("Sampled image type requires an image type with "
1223fd4e5da5Sopenharmony_ci                        "\"Sampled\" operand set to 0 or 1"));
1224fd4e5da5Sopenharmony_ci}
1225fd4e5da5Sopenharmony_ci
1226fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeSampledImage_Sampled1_Success) {
1227fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
1228fd4e5da5Sopenharmony_ci%im = OpTypeImage %f32 2D 0 0 0 1 Unknown
1229fd4e5da5Sopenharmony_ci%simg_type = OpTypeSampledImage %im
1230fd4e5da5Sopenharmony_ci)" + TrivialMain();
1231fd4e5da5Sopenharmony_ci
1232fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1233fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1234fd4e5da5Sopenharmony_ci  EXPECT_EQ(getDiagnosticString(), "");
1235fd4e5da5Sopenharmony_ci}
1236fd4e5da5Sopenharmony_ci
1237fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampledImageSuccess) {
1238fd4e5da5Sopenharmony_ci  const std::string body = R"(
1239fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1240fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1241fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1242fd4e5da5Sopenharmony_ci)";
1243fd4e5da5Sopenharmony_ci
1244fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1245fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1246fd4e5da5Sopenharmony_ci}
1247fd4e5da5Sopenharmony_ci
1248fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampledImageVulkanSuccess) {
1249fd4e5da5Sopenharmony_ci  const std::string body = R"(
1250fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1251fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1252fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1253fd4e5da5Sopenharmony_ci)";
1254fd4e5da5Sopenharmony_ci
1255fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
1256fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
1257fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
1258fd4e5da5Sopenharmony_ci}
1259fd4e5da5Sopenharmony_ci
1260fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampledImageWrongResultType) {
1261fd4e5da5Sopenharmony_ci  const std::string body = R"(
1262fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1263fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1264fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_image_f32_2d_0001 %img %sampler
1265fd4e5da5Sopenharmony_ci)";
1266fd4e5da5Sopenharmony_ci
1267fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1268fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1269fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1270fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypeSampledImage"));
1271fd4e5da5Sopenharmony_ci}
1272fd4e5da5Sopenharmony_ci
1273fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampledImageNotImage) {
1274fd4e5da5Sopenharmony_ci  const std::string body = R"(
1275fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1276fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1277fd4e5da5Sopenharmony_ci%simg1 = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1278fd4e5da5Sopenharmony_ci%simg2 = OpSampledImage %type_sampled_image_f32_2d_0001 %simg1 %sampler
1279fd4e5da5Sopenharmony_ci)";
1280fd4e5da5Sopenharmony_ci
1281fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1282fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1283fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1284fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image to be of type OpTypeImage"));
1285fd4e5da5Sopenharmony_ci}
1286fd4e5da5Sopenharmony_ci
1287fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampledImageImageNotForSampling) {
1288fd4e5da5Sopenharmony_ci  const std::string code = GetShaderHeader() + R"(
1289fd4e5da5Sopenharmony_ci%im_ty = OpTypeImage %f32 2D 0 0 0 2 Unknown
1290fd4e5da5Sopenharmony_ci%sampler_ty = OpTypeSampler
1291fd4e5da5Sopenharmony_ci%sampled_image_ty = OpTypeSampledImage %im_ty ; will fail here first!
1292fd4e5da5Sopenharmony_ci
1293fd4e5da5Sopenharmony_ci%ptr_im_ty = OpTypePointer UniformConstant %im_ty
1294fd4e5da5Sopenharmony_ci%var_im = OpVariable %ptr_im_ty UniformConstant
1295fd4e5da5Sopenharmony_ci
1296fd4e5da5Sopenharmony_ci%ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
1297fd4e5da5Sopenharmony_ci%var_sampler = OpVariable %ptr_sampler_ty UniformConstant
1298fd4e5da5Sopenharmony_ci
1299fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
1300fd4e5da5Sopenharmony_ci%entry = OpLabel
1301fd4e5da5Sopenharmony_ci%im = OpLoad %im_ty %var_im
1302fd4e5da5Sopenharmony_ci%sampler = OpLoad %sampler_ty %var_sampler
1303fd4e5da5Sopenharmony_ci%sampled_image = OpSampledImage %sampled_image_ty %im %sampler
1304fd4e5da5Sopenharmony_ciOpReturn
1305fd4e5da5Sopenharmony_ciOpFunctionEnd
1306fd4e5da5Sopenharmony_ci)";
1307fd4e5da5Sopenharmony_ci
1308fd4e5da5Sopenharmony_ci  CompileSuccessfully(code.c_str());
1309fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1310fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1311fd4e5da5Sopenharmony_ci              HasSubstr("Sampled image type requires an image type with "
1312fd4e5da5Sopenharmony_ci                        "\"Sampled\" operand set to 0 or 1"))
1313fd4e5da5Sopenharmony_ci      << code;
1314fd4e5da5Sopenharmony_ci}
1315fd4e5da5Sopenharmony_ci
1316fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampledImageNotSampler) {
1317fd4e5da5Sopenharmony_ci  const std::string body = R"(
1318fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1319fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1320fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %img
1321fd4e5da5Sopenharmony_ci)";
1322fd4e5da5Sopenharmony_ci
1323fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1324fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1325fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1326fd4e5da5Sopenharmony_ci              HasSubstr("Expected Sampler to be of type OpTypeSampler"));
1327fd4e5da5Sopenharmony_ci}
1328fd4e5da5Sopenharmony_ci
1329fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampledImageIsStorage) {
1330fd4e5da5Sopenharmony_ci  const std::string declarations = R"(
1331fd4e5da5Sopenharmony_ci%type_sampled_image_f32_2d_0002 = OpTypeSampledImage %type_image_f32_2d_0002
1332fd4e5da5Sopenharmony_ci)";
1333fd4e5da5Sopenharmony_ci  const std::string body = R"(
1334fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
1335fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1336fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0002 %img %sampler
1337fd4e5da5Sopenharmony_ci)";
1338fd4e5da5Sopenharmony_ci
1339fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "",
1340fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_0, "GLSL450",
1341fd4e5da5Sopenharmony_ci                                         declarations)
1342fd4e5da5Sopenharmony_ci                          .c_str());
1343fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1344fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1345fd4e5da5Sopenharmony_ci              HasSubstr("Sampled image type requires an image type with "
1346fd4e5da5Sopenharmony_ci                        "\"Sampled\" operand set to 0 or 1"));
1347fd4e5da5Sopenharmony_ci}
1348fd4e5da5Sopenharmony_ci
1349fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerSuccess) {
1350fd4e5da5Sopenharmony_ci  const std::string body = R"(
1351fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1352fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1353fd4e5da5Sopenharmony_ci)";
1354fd4e5da5Sopenharmony_ci
1355fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1356fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1357fd4e5da5Sopenharmony_ci}
1358fd4e5da5Sopenharmony_ci
1359fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerResultTypeNotPointer) {
1360fd4e5da5Sopenharmony_ci  const std::string body = R"(
1361fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %type_image_u32_buffer_0002_r32ui %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1362fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1363fd4e5da5Sopenharmony_ci)";
1364fd4e5da5Sopenharmony_ci
1365fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1366fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1367fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1368fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypePointer"));
1369fd4e5da5Sopenharmony_ci}
1370fd4e5da5Sopenharmony_ci
1371fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerResultTypeNotImageClass) {
1372fd4e5da5Sopenharmony_ci  const std::string body = R"(
1373fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1374fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1375fd4e5da5Sopenharmony_ci)";
1376fd4e5da5Sopenharmony_ci
1377fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1378fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1379fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1380fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypePointer whose "
1381fd4e5da5Sopenharmony_ci                        "Storage Class operand is Image"));
1382fd4e5da5Sopenharmony_ci}
1383fd4e5da5Sopenharmony_ci
1384fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerResultTypeNotNumericNorVoid) {
1385fd4e5da5Sopenharmony_ci  const std::string body = R"(
1386fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32arr4 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1387fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1388fd4e5da5Sopenharmony_ci)";
1389fd4e5da5Sopenharmony_ci
1390fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1391fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1392fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1393fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1394fd4e5da5Sopenharmony_ci      HasSubstr("Expected Result Type to be OpTypePointer whose Type operand "
1395fd4e5da5Sopenharmony_ci                "must be a scalar numerical type or OpTypeVoid"));
1396fd4e5da5Sopenharmony_ci}
1397fd4e5da5Sopenharmony_ci
1398fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerImageNotResultTypePointer) {
1399fd4e5da5Sopenharmony_ci  const std::string body = R"(
1400fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %type_image_f32_buffer_0002_r32ui %u32_0 %u32_0
1401fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1402fd4e5da5Sopenharmony_ci)";
1403fd4e5da5Sopenharmony_ci
1404fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1405fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
1406fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1407fd4e5da5Sopenharmony_ci              HasSubstr("Operand '148[%148]' cannot be a "
1408fd4e5da5Sopenharmony_ci                        "type"));
1409fd4e5da5Sopenharmony_ci}
1410fd4e5da5Sopenharmony_ci
1411fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerImageNotImage) {
1412fd4e5da5Sopenharmony_ci  const std::string body = R"(
1413fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_sampler %u32_0 %u32_0
1414fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1415fd4e5da5Sopenharmony_ci)";
1416fd4e5da5Sopenharmony_ci
1417fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1418fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1419fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1420fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1421fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image to be OpTypePointer with Type OpTypeImage"));
1422fd4e5da5Sopenharmony_ci}
1423fd4e5da5Sopenharmony_ci
1424fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerImageSampledNotResultType) {
1425fd4e5da5Sopenharmony_ci  const std::string body = R"(
1426fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_f32_cube_0101 %u32_0 %u32_0
1427fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1428fd4e5da5Sopenharmony_ci)";
1429fd4e5da5Sopenharmony_ci
1430fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1431fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1432fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1433fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as the "
1434fd4e5da5Sopenharmony_ci                        "Type pointed to by Result Type"));
1435fd4e5da5Sopenharmony_ci}
1436fd4e5da5Sopenharmony_ci
1437fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerImageDimSubpassDataBad) {
1438fd4e5da5Sopenharmony_ci  const std::string body = R"(
1439fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_spd_0002 %u32_0 %u32_0
1440fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1441fd4e5da5Sopenharmony_ci)";
1442fd4e5da5Sopenharmony_ci
1443fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1444fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1445fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1446fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1447fd4e5da5Sopenharmony_ci      HasSubstr(
1448fd4e5da5Sopenharmony_ci          "Image Dim SubpassData cannot be used with OpImageTexelPointer"));
1449fd4e5da5Sopenharmony_ci}
1450fd4e5da5Sopenharmony_ci
1451fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerImageCoordTypeBad) {
1452fd4e5da5Sopenharmony_ci  const std::string body = R"(
1453fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32ui %f32_0 %f32_0
1454fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %f32 %texel_ptr %f32_1 %f32_0 %f32_1
1455fd4e5da5Sopenharmony_ci)";
1456fd4e5da5Sopenharmony_ci
1457fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1458fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1459fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1460fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be integer scalar or vector"));
1461fd4e5da5Sopenharmony_ci}
1462fd4e5da5Sopenharmony_ci
1463fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerImageCoordSizeBad) {
1464fd4e5da5Sopenharmony_ci  const std::string body = R"(
1465fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_u32_2d_0002 %u32vec3_012 %u32_0
1466fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1467fd4e5da5Sopenharmony_ci)";
1468fd4e5da5Sopenharmony_ci
1469fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1470fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1471fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1472fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1473fd4e5da5Sopenharmony_ci      HasSubstr("Expected Coordinate to have 2 components, but given 3"));
1474fd4e5da5Sopenharmony_ci}
1475fd4e5da5Sopenharmony_ci
1476fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerSampleNotIntScalar) {
1477fd4e5da5Sopenharmony_ci  const std::string body = R"(
1478fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %f32_0
1479fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1480fd4e5da5Sopenharmony_ci)";
1481fd4e5da5Sopenharmony_ci
1482fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1483fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1484fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1485fd4e5da5Sopenharmony_ci              HasSubstr("Expected Sample to be integer scalar"));
1486fd4e5da5Sopenharmony_ci}
1487fd4e5da5Sopenharmony_ci
1488fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerSampleNotZeroForImageWithMSZero) {
1489fd4e5da5Sopenharmony_ci  const std::string body = R"(
1490fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_1
1491fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1492fd4e5da5Sopenharmony_ci)";
1493fd4e5da5Sopenharmony_ci
1494fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1495fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1496fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1497fd4e5da5Sopenharmony_ci              HasSubstr("Expected Sample for Image with MS 0 to be a valid "
1498fd4e5da5Sopenharmony_ci                        "<id> for the value 0"));
1499fd4e5da5Sopenharmony_ci}
1500fd4e5da5Sopenharmony_ci
1501fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodSuccess) {
1502fd4e5da5Sopenharmony_ci  const std::string body = R"(
1503fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1504fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1505fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1506fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
1507fd4e5da5Sopenharmony_ci%res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0_25
1508fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
1509fd4e5da5Sopenharmony_ci%res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
1510fd4e5da5Sopenharmony_ci%res6 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
1511fd4e5da5Sopenharmony_ci%res7 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
1512fd4e5da5Sopenharmony_ci%res8 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
1513fd4e5da5Sopenharmony_ci)";
1514fd4e5da5Sopenharmony_ci
1515fd4e5da5Sopenharmony_ci  const std::string extra = R"(
1516fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1517fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1518fd4e5da5Sopenharmony_ci)";
1519fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1520fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1521fd4e5da5Sopenharmony_ci                          .c_str());
1522fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1523fd4e5da5Sopenharmony_ci}
1524fd4e5da5Sopenharmony_ci
1525fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodWrongResultType) {
1526fd4e5da5Sopenharmony_ci  const std::string body = R"(
1527fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1528fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1529fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1530fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32 %simg %f32vec2_hh
1531fd4e5da5Sopenharmony_ci)";
1532fd4e5da5Sopenharmony_ci
1533fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1534fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1535fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1536fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float vector type"));
1537fd4e5da5Sopenharmony_ci}
1538fd4e5da5Sopenharmony_ci
1539fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodWrongNumComponentsResultType) {
1540fd4e5da5Sopenharmony_ci  const std::string body = R"(
1541fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1542fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1543fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1544fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec3 %simg %f32vec2_hh
1545fd4e5da5Sopenharmony_ci)";
1546fd4e5da5Sopenharmony_ci
1547fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1548fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1549fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1550fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to have 4 components"));
1551fd4e5da5Sopenharmony_ci}
1552fd4e5da5Sopenharmony_ci
1553fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodNotSampledImage) {
1554fd4e5da5Sopenharmony_ci  const std::string body = R"(
1555fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1556fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %img %f32vec2_hh
1557fd4e5da5Sopenharmony_ci)";
1558fd4e5da5Sopenharmony_ci
1559fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1560fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1561fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1562fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1563fd4e5da5Sopenharmony_ci      HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1564fd4e5da5Sopenharmony_ci}
1565fd4e5da5Sopenharmony_ci
1566fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodMultisampleError) {
1567fd4e5da5Sopenharmony_ci  const std::string body = R"(
1568fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
1569fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1570fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
1571fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
1572fd4e5da5Sopenharmony_ci)";
1573fd4e5da5Sopenharmony_ci
1574fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1575fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1576fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1577fd4e5da5Sopenharmony_ci              HasSubstr("Sampling operation is invalid for multisample image"));
1578fd4e5da5Sopenharmony_ci}
1579fd4e5da5Sopenharmony_ci
1580fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodWrongSampledType) {
1581fd4e5da5Sopenharmony_ci  const std::string body = R"(
1582fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1583fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1584fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1585fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
1586fd4e5da5Sopenharmony_ci)";
1587fd4e5da5Sopenharmony_ci
1588fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1589fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1590fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1591fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
1592fd4e5da5Sopenharmony_ci                        "Result Type components"));
1593fd4e5da5Sopenharmony_ci}
1594fd4e5da5Sopenharmony_ci
1595fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodVoidSampledType) {
1596fd4e5da5Sopenharmony_ci  const std::string body = R"(
1597fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1598fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1599fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1600fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
1601fd4e5da5Sopenharmony_ci)";
1602fd4e5da5Sopenharmony_ci
1603fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1604fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1605fd4e5da5Sopenharmony_ci}
1606fd4e5da5Sopenharmony_ci
1607fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodWrongCoordinateType) {
1608fd4e5da5Sopenharmony_ci  const std::string body = R"(
1609fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1610fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1611fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1612fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %img
1613fd4e5da5Sopenharmony_ci)";
1614fd4e5da5Sopenharmony_ci
1615fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1616fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1617fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1618fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be float scalar or vector"));
1619fd4e5da5Sopenharmony_ci}
1620fd4e5da5Sopenharmony_ci
1621fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodCoordinateSizeTooSmall) {
1622fd4e5da5Sopenharmony_ci  const std::string body = R"(
1623fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1624fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1625fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1626fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32_0_5
1627fd4e5da5Sopenharmony_ci)";
1628fd4e5da5Sopenharmony_ci
1629fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1630fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1631fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1632fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 2 components, "
1633fd4e5da5Sopenharmony_ci                        "but given only 1"));
1634fd4e5da5Sopenharmony_ci}
1635fd4e5da5Sopenharmony_ci
1636fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodSuccessShader) {
1637fd4e5da5Sopenharmony_ci  const std::string body = R"(
1638fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1639fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1640fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1641fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod %f32_1
1642fd4e5da5Sopenharmony_ci%res2 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_10 %f32vec2_01
1643fd4e5da5Sopenharmony_ci%res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
1644fd4e5da5Sopenharmony_ci%res4 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
1645fd4e5da5Sopenharmony_ci%res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset|MinLod %f32vec2_10 %f32vec2_01 %s32vec2_01 %f32_0_5
1646fd4e5da5Sopenharmony_ci%res6 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod|NonPrivateTexelKHR %f32_1
1647fd4e5da5Sopenharmony_ci)";
1648fd4e5da5Sopenharmony_ci
1649fd4e5da5Sopenharmony_ci  const std::string extra = R"(
1650fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1651fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1652fd4e5da5Sopenharmony_ci)";
1653fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1654fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1655fd4e5da5Sopenharmony_ci                          .c_str());
1656fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1657fd4e5da5Sopenharmony_ci}
1658fd4e5da5Sopenharmony_ci
1659fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodSuccessKernel) {
1660fd4e5da5Sopenharmony_ci  const std::string body = R"(
1661fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1662fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1663fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1664fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec4_0123 Lod %f32_1
1665fd4e5da5Sopenharmony_ci%res2 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Grad %f32vec2_10 %f32vec2_01
1666fd4e5da5Sopenharmony_ci%res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %u32vec2_01
1667fd4e5da5Sopenharmony_ci%res4 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Offset %u32vec2_01
1668fd4e5da5Sopenharmony_ci%res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset %f32vec2_10 %f32vec2_01 %u32vec2_01
1669fd4e5da5Sopenharmony_ci)";
1670fd4e5da5Sopenharmony_ci
1671fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
1672fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1673fd4e5da5Sopenharmony_ci}
1674fd4e5da5Sopenharmony_ci
1675fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodSuccessCubeArrayed) {
1676fd4e5da5Sopenharmony_ci  const std::string body = R"(
1677fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1678fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1679fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1680fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec3_hhh
1681fd4e5da5Sopenharmony_ci)";
1682fd4e5da5Sopenharmony_ci
1683fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1684fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1685fd4e5da5Sopenharmony_ci}
1686fd4e5da5Sopenharmony_ci
1687fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodWrongResultType) {
1688fd4e5da5Sopenharmony_ci  const std::string body = R"(
1689fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1690fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1691fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1692fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32 %simg %f32vec2_hh Lod %f32_1
1693fd4e5da5Sopenharmony_ci)";
1694fd4e5da5Sopenharmony_ci
1695fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1696fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1697fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1698fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float vector type"));
1699fd4e5da5Sopenharmony_ci}
1700fd4e5da5Sopenharmony_ci
1701fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodWrongNumComponentsResultType) {
1702fd4e5da5Sopenharmony_ci  const std::string body = R"(
1703fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1704fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1705fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1706fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec3 %simg %f32vec2_hh Lod %f32_1
1707fd4e5da5Sopenharmony_ci)";
1708fd4e5da5Sopenharmony_ci
1709fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1710fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1711fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1712fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to have 4 components"));
1713fd4e5da5Sopenharmony_ci}
1714fd4e5da5Sopenharmony_ci
1715fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodNotSampledImage) {
1716fd4e5da5Sopenharmony_ci  const std::string body = R"(
1717fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1718fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %img %f32vec2_hh Lod %f32_1
1719fd4e5da5Sopenharmony_ci)";
1720fd4e5da5Sopenharmony_ci
1721fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1722fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1723fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1724fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1725fd4e5da5Sopenharmony_ci      HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1726fd4e5da5Sopenharmony_ci}
1727fd4e5da5Sopenharmony_ci
1728fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodMultisampleError) {
1729fd4e5da5Sopenharmony_ci  const std::string body = R"(
1730fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
1731fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1732fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
1733fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_0 %u32_1
1734fd4e5da5Sopenharmony_ci)";
1735fd4e5da5Sopenharmony_ci
1736fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1737fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1738fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1739fd4e5da5Sopenharmony_ci              HasSubstr("Sampling operation is invalid for multisample image"));
1740fd4e5da5Sopenharmony_ci}
1741fd4e5da5Sopenharmony_ci
1742fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodWrongSampledType) {
1743fd4e5da5Sopenharmony_ci  const std::string body = R"(
1744fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1745fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1746fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1747fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
1748fd4e5da5Sopenharmony_ci)";
1749fd4e5da5Sopenharmony_ci
1750fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1751fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1752fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1753fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
1754fd4e5da5Sopenharmony_ci                        "Result Type components"));
1755fd4e5da5Sopenharmony_ci}
1756fd4e5da5Sopenharmony_ci
1757fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodVoidSampledType) {
1758fd4e5da5Sopenharmony_ci  const std::string body = R"(
1759fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1760fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1761fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1762fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
1763fd4e5da5Sopenharmony_ci)";
1764fd4e5da5Sopenharmony_ci
1765fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1766fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1767fd4e5da5Sopenharmony_ci}
1768fd4e5da5Sopenharmony_ci
1769fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodWrongCoordinateType) {
1770fd4e5da5Sopenharmony_ci  const std::string body = R"(
1771fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1772fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1773fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1774fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %img Lod %f32_1
1775fd4e5da5Sopenharmony_ci)";
1776fd4e5da5Sopenharmony_ci
1777fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1778fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1779fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1780fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be float scalar or vector"));
1781fd4e5da5Sopenharmony_ci}
1782fd4e5da5Sopenharmony_ci
1783fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodCoordinateSizeTooSmall) {
1784fd4e5da5Sopenharmony_ci  const std::string body = R"(
1785fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1786fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1787fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1788fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32_0_5 Lod %f32_1
1789fd4e5da5Sopenharmony_ci)";
1790fd4e5da5Sopenharmony_ci
1791fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1792fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1793fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1794fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 2 components, "
1795fd4e5da5Sopenharmony_ci                        "but given only 1"));
1796fd4e5da5Sopenharmony_ci}
1797fd4e5da5Sopenharmony_ci
1798fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodBias) {
1799fd4e5da5Sopenharmony_ci  const std::string body = R"(
1800fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1801fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1802fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1803fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Bias|Lod %f32_1 %f32_1
1804fd4e5da5Sopenharmony_ci)";
1805fd4e5da5Sopenharmony_ci
1806fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1807fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1808fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1809fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1810fd4e5da5Sopenharmony_ci      HasSubstr(
1811fd4e5da5Sopenharmony_ci          "Image Operand Bias can only be used with ImplicitLod opcodes"));
1812fd4e5da5Sopenharmony_ci}
1813fd4e5da5Sopenharmony_ci
1814fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, LodAndGrad) {
1815fd4e5da5Sopenharmony_ci  const std::string body = R"(
1816fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1817fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1818fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1819fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|Grad %f32_1 %f32vec2_hh %f32vec2_hh
1820fd4e5da5Sopenharmony_ci)";
1821fd4e5da5Sopenharmony_ci
1822fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1823fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1824fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1825fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1826fd4e5da5Sopenharmony_ci      HasSubstr(
1827fd4e5da5Sopenharmony_ci          "Image Operand bits Lod and Grad cannot be set at the same time"));
1828fd4e5da5Sopenharmony_ci}
1829fd4e5da5Sopenharmony_ci
1830fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImplicitLodWithLod) {
1831fd4e5da5Sopenharmony_ci  const std::string body = R"(
1832fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1833fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1834fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1835fd4e5da5Sopenharmony_ci%res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_0_5
1836fd4e5da5Sopenharmony_ci)";
1837fd4e5da5Sopenharmony_ci
1838fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1839fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1840fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1841fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1842fd4e5da5Sopenharmony_ci      HasSubstr("Image Operand Lod can only be used with ExplicitLod opcodes "
1843fd4e5da5Sopenharmony_ci                "and OpImageFetch"));
1844fd4e5da5Sopenharmony_ci}
1845fd4e5da5Sopenharmony_ci
1846fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, LodWrongType) {
1847fd4e5da5Sopenharmony_ci  const std::string body = R"(
1848fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1849fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1850fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1851fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32vec2_hh)";
1852fd4e5da5Sopenharmony_ci
1853fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1854fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1855fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1856fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image Operand Lod to be float scalar when "
1857fd4e5da5Sopenharmony_ci                        "used with ExplicitLod"));
1858fd4e5da5Sopenharmony_ci}
1859fd4e5da5Sopenharmony_ci
1860fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, LodWrongDim) {
1861fd4e5da5Sopenharmony_ci  const std::string body = R"(
1862fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1863fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1864fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1865fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32_0)";
1866fd4e5da5Sopenharmony_ci
1867fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1868fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1869fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1870fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand Lod requires 'Dim' parameter to be 1D, "
1871fd4e5da5Sopenharmony_ci                        "2D, 3D or Cube"));
1872fd4e5da5Sopenharmony_ci}
1873fd4e5da5Sopenharmony_ci
1874fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, MinLodIncompatible) {
1875fd4e5da5Sopenharmony_ci  const std::string body = R"(
1876fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1877fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1878fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1879fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|MinLod %f32_0 %f32_0)";
1880fd4e5da5Sopenharmony_ci
1881fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1882fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1883fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1884fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1885fd4e5da5Sopenharmony_ci      HasSubstr(
1886fd4e5da5Sopenharmony_ci          "Image Operand MinLod can only be used with ImplicitLod opcodes or "
1887fd4e5da5Sopenharmony_ci          "together with Image Operand Grad"));
1888fd4e5da5Sopenharmony_ci}
1889fd4e5da5Sopenharmony_ci
1890fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImplicitLodWithGrad) {
1891fd4e5da5Sopenharmony_ci  const std::string body = R"(
1892fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1893fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1894fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1895fd4e5da5Sopenharmony_ci%res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_hh %f32vec2_hh
1896fd4e5da5Sopenharmony_ci)";
1897fd4e5da5Sopenharmony_ci
1898fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1899fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1900fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1901fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1902fd4e5da5Sopenharmony_ci      HasSubstr(
1903fd4e5da5Sopenharmony_ci          "Image Operand Grad can only be used with ExplicitLod opcodes"));
1904fd4e5da5Sopenharmony_ci}
1905fd4e5da5Sopenharmony_ci
1906fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodCubeArrayedSuccess) {
1907fd4e5da5Sopenharmony_ci  const std::string body = R"(
1908fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1909fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1910fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1911fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000
1912fd4e5da5Sopenharmony_ci%res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias %f32_0_25
1913fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %f32_0_5
1914fd4e5da5Sopenharmony_ci%res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias|MinLod %f32_0_25 %f32_0_5
1915fd4e5da5Sopenharmony_ci)";
1916fd4e5da5Sopenharmony_ci
1917fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1918fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1919fd4e5da5Sopenharmony_ci}
1920fd4e5da5Sopenharmony_ci
1921fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodBiasWrongType) {
1922fd4e5da5Sopenharmony_ci  const std::string body = R"(
1923fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1924fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1925fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1926fd4e5da5Sopenharmony_ci%res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %u32_0
1927fd4e5da5Sopenharmony_ci)";
1928fd4e5da5Sopenharmony_ci
1929fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1930fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1931fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1932fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image Operand Bias to be float scalar"));
1933fd4e5da5Sopenharmony_ci}
1934fd4e5da5Sopenharmony_ci
1935fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodBiasWrongDim) {
1936fd4e5da5Sopenharmony_ci  const std::string body = R"(
1937fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1938fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1939fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1940fd4e5da5Sopenharmony_ci%res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0
1941fd4e5da5Sopenharmony_ci)";
1942fd4e5da5Sopenharmony_ci
1943fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1944fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1945fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1946fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand Bias requires 'Dim' parameter to be 1D, "
1947fd4e5da5Sopenharmony_ci                        "2D, 3D or Cube"));
1948fd4e5da5Sopenharmony_ci}
1949fd4e5da5Sopenharmony_ci
1950fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodGradDxWrongType) {
1951fd4e5da5Sopenharmony_ci  const std::string body = R"(
1952fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1953fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1954fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1955fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %s32vec3_012 %f32vec3_hhh
1956fd4e5da5Sopenharmony_ci)";
1957fd4e5da5Sopenharmony_ci
1958fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1959fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1960fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1961fd4e5da5Sopenharmony_ci              HasSubstr("Expected both Image Operand Grad ids to be float "
1962fd4e5da5Sopenharmony_ci                        "scalars or vectors"));
1963fd4e5da5Sopenharmony_ci}
1964fd4e5da5Sopenharmony_ci
1965fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodGradDyWrongType) {
1966fd4e5da5Sopenharmony_ci  const std::string body = R"(
1967fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1968fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1969fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1970fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad  %f32vec3_hhh %s32vec3_012
1971fd4e5da5Sopenharmony_ci)";
1972fd4e5da5Sopenharmony_ci
1973fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1974fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1975fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1976fd4e5da5Sopenharmony_ci              HasSubstr("Expected both Image Operand Grad ids to be float "
1977fd4e5da5Sopenharmony_ci                        "scalars or vectors"));
1978fd4e5da5Sopenharmony_ci}
1979fd4e5da5Sopenharmony_ci
1980fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodGradDxWrongSize) {
1981fd4e5da5Sopenharmony_ci  const std::string body = R"(
1982fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1983fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
1984fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1985fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec2_00 %f32vec3_hhh
1986fd4e5da5Sopenharmony_ci)";
1987fd4e5da5Sopenharmony_ci
1988fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
1989fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1990fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1991fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1992fd4e5da5Sopenharmony_ci      HasSubstr(
1993fd4e5da5Sopenharmony_ci          "Expected Image Operand Grad dx to have 3 components, but given 2"));
1994fd4e5da5Sopenharmony_ci}
1995fd4e5da5Sopenharmony_ci
1996fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleExplicitLodGradDyWrongSize) {
1997fd4e5da5Sopenharmony_ci  const std::string body = R"(
1998fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1999fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2000fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2001fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec2_00
2002fd4e5da5Sopenharmony_ci)";
2003fd4e5da5Sopenharmony_ci
2004fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2005fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2006fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2007fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2008fd4e5da5Sopenharmony_ci      HasSubstr(
2009fd4e5da5Sopenharmony_ci          "Expected Image Operand Grad dy to have 3 components, but given 2"));
2010fd4e5da5Sopenharmony_ci}
2011fd4e5da5Sopenharmony_ci
2012fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodConstOffsetCubeDim) {
2013fd4e5da5Sopenharmony_ci  const std::string body = R"(
2014fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2015fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2016fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2017fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec3_012
2018fd4e5da5Sopenharmony_ci)";
2019fd4e5da5Sopenharmony_ci
2020fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2021fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2022fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2023fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2024fd4e5da5Sopenharmony_ci      HasSubstr(
2025fd4e5da5Sopenharmony_ci          "Image Operand ConstOffset cannot be used with Cube Image 'Dim'"));
2026fd4e5da5Sopenharmony_ci}
2027fd4e5da5Sopenharmony_ci
2028fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongType) {
2029fd4e5da5Sopenharmony_ci  const std::string body = R"(
2030fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2031fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2032fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2033fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %f32vec2_00
2034fd4e5da5Sopenharmony_ci)";
2035fd4e5da5Sopenharmony_ci
2036fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2037fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2038fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2039fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2040fd4e5da5Sopenharmony_ci      HasSubstr(
2041fd4e5da5Sopenharmony_ci          "Expected Image Operand ConstOffset to be int scalar or vector"));
2042fd4e5da5Sopenharmony_ci}
2043fd4e5da5Sopenharmony_ci
2044fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongSize) {
2045fd4e5da5Sopenharmony_ci  const std::string body = R"(
2046fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2047fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2048fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2049fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %s32vec3_012
2050fd4e5da5Sopenharmony_ci)";
2051fd4e5da5Sopenharmony_ci
2052fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2053fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2054fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2055fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image Operand ConstOffset to have 2 "
2056fd4e5da5Sopenharmony_ci                        "components, but given 3"));
2057fd4e5da5Sopenharmony_ci}
2058fd4e5da5Sopenharmony_ci
2059fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodConstOffsetNotConst) {
2060fd4e5da5Sopenharmony_ci  const std::string body = R"(
2061fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2062fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2063fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2064fd4e5da5Sopenharmony_ci%offset = OpSNegate %s32vec3 %s32vec3_012
2065fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %offset
2066fd4e5da5Sopenharmony_ci)";
2067fd4e5da5Sopenharmony_ci
2068fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2069fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2070fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2071fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2072fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image Operand ConstOffset to be a const object"));
2073fd4e5da5Sopenharmony_ci}
2074fd4e5da5Sopenharmony_ci
2075fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodOffsetCubeDim) {
2076fd4e5da5Sopenharmony_ci  const std::string body = R"(
2077fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2078fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2079fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2080fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
2081fd4e5da5Sopenharmony_ci)";
2082fd4e5da5Sopenharmony_ci
2083fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2084fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2085fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2086fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2087fd4e5da5Sopenharmony_ci      HasSubstr("Image Operand Offset cannot be used with Cube Image 'Dim'"));
2088fd4e5da5Sopenharmony_ci}
2089fd4e5da5Sopenharmony_ci
2090fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodOffsetWrongType) {
2091fd4e5da5Sopenharmony_ci  const std::string body = R"(
2092fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2093fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2094fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2095fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %f32vec2_00
2096fd4e5da5Sopenharmony_ci)";
2097fd4e5da5Sopenharmony_ci
2098fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2099fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2100fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2101fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2102fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image Operand Offset to be int scalar or vector"));
2103fd4e5da5Sopenharmony_ci}
2104fd4e5da5Sopenharmony_ci
2105fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodOffsetWrongSize) {
2106fd4e5da5Sopenharmony_ci  const std::string body = R"(
2107fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2108fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2109fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2110fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
2111fd4e5da5Sopenharmony_ci)";
2112fd4e5da5Sopenharmony_ci
2113fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2114fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2115fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2116fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2117fd4e5da5Sopenharmony_ci      HasSubstr(
2118fd4e5da5Sopenharmony_ci          "Expected Image Operand Offset to have 2 components, but given 3"));
2119fd4e5da5Sopenharmony_ci}
2120fd4e5da5Sopenharmony_ci
2121fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongSize) {
2122fd4e5da5Sopenharmony_ci  const std::string body = R"(
2123fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2124fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2125fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2126fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
2127fd4e5da5Sopenharmony_ci)";
2128fd4e5da5Sopenharmony_ci
2129fd4e5da5Sopenharmony_ci  CompileSuccessfully(
2130fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2131fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2132fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2133fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Offset-04663"));
2134fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2135fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand Offset can only be used with "
2136fd4e5da5Sopenharmony_ci                        "OpImage*Gather operations"));
2137fd4e5da5Sopenharmony_ci}
2138fd4e5da5Sopenharmony_ci
2139fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongBeforeLegalization) {
2140fd4e5da5Sopenharmony_ci  const std::string body = R"(
2141fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2142fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2143fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2144fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
2145fd4e5da5Sopenharmony_ci)";
2146fd4e5da5Sopenharmony_ci
2147fd4e5da5Sopenharmony_ci  CompileSuccessfully(
2148fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2149fd4e5da5Sopenharmony_ci  getValidatorOptions()->before_hlsl_legalization = true;
2150fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2151fd4e5da5Sopenharmony_ci}
2152fd4e5da5Sopenharmony_ci
2153fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodMoreThanOneOffset) {
2154fd4e5da5Sopenharmony_ci  const std::string body = R"(
2155fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2156fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2157fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2158fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
2159fd4e5da5Sopenharmony_ci)";
2160fd4e5da5Sopenharmony_ci
2161fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2162fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2163fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2164fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2165fd4e5da5Sopenharmony_ci      HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
2166fd4e5da5Sopenharmony_ci                "cannot be used together"));
2167fd4e5da5Sopenharmony_ci}
2168fd4e5da5Sopenharmony_ci
2169fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodVulkanMoreThanOneOffset) {
2170fd4e5da5Sopenharmony_ci  const std::string body = R"(
2171fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2172fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2173fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2174fd4e5da5Sopenharmony_ci%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
2175fd4e5da5Sopenharmony_ci)";
2176fd4e5da5Sopenharmony_ci
2177fd4e5da5Sopenharmony_ci  CompileSuccessfully(
2178fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2179fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2180fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2181fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2182fd4e5da5Sopenharmony_ci      HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
2183fd4e5da5Sopenharmony_ci                "cannot be used together"));
2184fd4e5da5Sopenharmony_ci}
2185fd4e5da5Sopenharmony_ci
2186fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodMinLodWrongType) {
2187fd4e5da5Sopenharmony_ci  const std::string body = R"(
2188fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2189fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2190fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2191fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %s32_0
2192fd4e5da5Sopenharmony_ci)";
2193fd4e5da5Sopenharmony_ci
2194fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2195fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2196fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2197fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image Operand MinLod to be float scalar"));
2198fd4e5da5Sopenharmony_ci}
2199fd4e5da5Sopenharmony_ci
2200fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImplicitLodMinLodWrongDim) {
2201fd4e5da5Sopenharmony_ci  const std::string body = R"(
2202fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2203fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2204fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
2205fd4e5da5Sopenharmony_ci%res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_25
2206fd4e5da5Sopenharmony_ci)";
2207fd4e5da5Sopenharmony_ci
2208fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2209fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2210fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2211fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand MinLod requires 'Dim' parameter to be "
2212fd4e5da5Sopenharmony_ci                        "1D, 2D, 3D or Cube"));
2213fd4e5da5Sopenharmony_ci}
2214fd4e5da5Sopenharmony_ci
2215fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjExplicitLodSuccess2D) {
2216fd4e5da5Sopenharmony_ci  const std::string body = R"(
2217fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2218fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2219fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2220fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod %f32_1
2221fd4e5da5Sopenharmony_ci%res3 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
2222fd4e5da5Sopenharmony_ci%res4 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
2223fd4e5da5Sopenharmony_ci%res5 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
2224fd4e5da5Sopenharmony_ci%res7 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
2225fd4e5da5Sopenharmony_ci%res8 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod|NonPrivateTexelKHR %f32_1
2226fd4e5da5Sopenharmony_ci)";
2227fd4e5da5Sopenharmony_ci
2228fd4e5da5Sopenharmony_ci  const std::string extra = R"(
2229fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
2230fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
2231fd4e5da5Sopenharmony_ci)";
2232fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2233fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2234fd4e5da5Sopenharmony_ci                          .c_str());
2235fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2236fd4e5da5Sopenharmony_ci}
2237fd4e5da5Sopenharmony_ci
2238fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjExplicitLodSuccessRect) {
2239fd4e5da5Sopenharmony_ci  const std::string body = R"(
2240fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2241fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2242fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
2243fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
2244fd4e5da5Sopenharmony_ci%res2 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
2245fd4e5da5Sopenharmony_ci)";
2246fd4e5da5Sopenharmony_ci
2247fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2248fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2249fd4e5da5Sopenharmony_ci}
2250fd4e5da5Sopenharmony_ci
2251fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjExplicitLodWrongResultType) {
2252fd4e5da5Sopenharmony_ci  const std::string body = R"(
2253fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2254fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2255fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2256fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjExplicitLod %f32 %simg %f32vec3_hhh Lod %f32_1
2257fd4e5da5Sopenharmony_ci)";
2258fd4e5da5Sopenharmony_ci
2259fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2260fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2261fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2262fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float vector type"));
2263fd4e5da5Sopenharmony_ci}
2264fd4e5da5Sopenharmony_ci
2265fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjExplicitLodWrongNumComponentsResultType) {
2266fd4e5da5Sopenharmony_ci  const std::string body = R"(
2267fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2268fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2269fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2270fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjExplicitLod %f32vec3 %simg %f32vec3_hhh Lod %f32_1
2271fd4e5da5Sopenharmony_ci)";
2272fd4e5da5Sopenharmony_ci
2273fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2274fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2275fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2276fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to have 4 components"));
2277fd4e5da5Sopenharmony_ci}
2278fd4e5da5Sopenharmony_ci
2279fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjExplicitLodNotSampledImage) {
2280fd4e5da5Sopenharmony_ci  const std::string body = R"(
2281fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2282fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjExplicitLod %f32vec4 %img %f32vec3_hhh Lod %f32_1
2283fd4e5da5Sopenharmony_ci)";
2284fd4e5da5Sopenharmony_ci
2285fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2286fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2287fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2288fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2289fd4e5da5Sopenharmony_ci      HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2290fd4e5da5Sopenharmony_ci}
2291fd4e5da5Sopenharmony_ci
2292fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjExplicitLodMultisampleError) {
2293fd4e5da5Sopenharmony_ci  const std::string body = R"(
2294fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2295fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2296fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2297fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_1 %u32_1
2298fd4e5da5Sopenharmony_ci)";
2299fd4e5da5Sopenharmony_ci
2300fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2301fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2302fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2303fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'MS' parameter to be 0"));
2304fd4e5da5Sopenharmony_ci}
2305fd4e5da5Sopenharmony_ci
2306fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjExplicitLodWrongSampledType) {
2307fd4e5da5Sopenharmony_ci  const std::string body = R"(
2308fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2309fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2310fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2311fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
2312fd4e5da5Sopenharmony_ci)";
2313fd4e5da5Sopenharmony_ci
2314fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2315fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2316fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2317fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
2318fd4e5da5Sopenharmony_ci                        "Result Type components"));
2319fd4e5da5Sopenharmony_ci}
2320fd4e5da5Sopenharmony_ci
2321fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjExplicitLodVoidSampledType) {
2322fd4e5da5Sopenharmony_ci  const std::string body = R"(
2323fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2324fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2325fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2326fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
2327fd4e5da5Sopenharmony_ci)";
2328fd4e5da5Sopenharmony_ci
2329fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2330fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2331fd4e5da5Sopenharmony_ci}
2332fd4e5da5Sopenharmony_ci
2333fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjExplicitLodWrongCoordinateType) {
2334fd4e5da5Sopenharmony_ci  const std::string body = R"(
2335fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2336fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2337fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2338fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %img Lod %f32_1
2339fd4e5da5Sopenharmony_ci)";
2340fd4e5da5Sopenharmony_ci
2341fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2342fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2343fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2344fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be float scalar or vector"));
2345fd4e5da5Sopenharmony_ci}
2346fd4e5da5Sopenharmony_ci
2347fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjExplicitLodCoordinateSizeTooSmall) {
2348fd4e5da5Sopenharmony_ci  const std::string body = R"(
2349fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2350fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2351fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2352fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_1
2353fd4e5da5Sopenharmony_ci)";
2354fd4e5da5Sopenharmony_ci
2355fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2356fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2357fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2358fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 3 components, "
2359fd4e5da5Sopenharmony_ci                        "but given only 2"));
2360fd4e5da5Sopenharmony_ci}
2361fd4e5da5Sopenharmony_ci
2362fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjImplicitLodSuccess) {
2363fd4e5da5Sopenharmony_ci  const std::string body = R"(
2364fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2365fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2366fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2367fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh
2368fd4e5da5Sopenharmony_ci%res2 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias %f32_0_25
2369fd4e5da5Sopenharmony_ci%res4 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
2370fd4e5da5Sopenharmony_ci%res5 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
2371fd4e5da5Sopenharmony_ci%res6 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh MinLod %f32_0_5
2372fd4e5da5Sopenharmony_ci%res7 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2373fd4e5da5Sopenharmony_ci%res8 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh NonPrivateTexelKHR
2374fd4e5da5Sopenharmony_ci)";
2375fd4e5da5Sopenharmony_ci
2376fd4e5da5Sopenharmony_ci  const std::string extra = R"(
2377fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
2378fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
2379fd4e5da5Sopenharmony_ci)";
2380fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2381fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2382fd4e5da5Sopenharmony_ci                          .c_str());
2383fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2384fd4e5da5Sopenharmony_ci}
2385fd4e5da5Sopenharmony_ci
2386fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjImplicitLodWrongResultType) {
2387fd4e5da5Sopenharmony_ci  const std::string body = R"(
2388fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2389fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2390fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2391fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjImplicitLod %f32 %simg %f32vec3_hhh
2392fd4e5da5Sopenharmony_ci)";
2393fd4e5da5Sopenharmony_ci
2394fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2395fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2396fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2397fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float vector type"));
2398fd4e5da5Sopenharmony_ci}
2399fd4e5da5Sopenharmony_ci
2400fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjImplicitLodWrongNumComponentsResultType) {
2401fd4e5da5Sopenharmony_ci  const std::string body = R"(
2402fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2403fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2404fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2405fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjImplicitLod %f32vec3 %simg %f32vec3_hhh
2406fd4e5da5Sopenharmony_ci)";
2407fd4e5da5Sopenharmony_ci
2408fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2409fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2410fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2411fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to have 4 components"));
2412fd4e5da5Sopenharmony_ci}
2413fd4e5da5Sopenharmony_ci
2414fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjImplicitLodNotSampledImage) {
2415fd4e5da5Sopenharmony_ci  const std::string body = R"(
2416fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2417fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjImplicitLod %f32vec4 %img %f32vec3_hhh
2418fd4e5da5Sopenharmony_ci)";
2419fd4e5da5Sopenharmony_ci
2420fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2421fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2422fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2423fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2424fd4e5da5Sopenharmony_ci      HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2425fd4e5da5Sopenharmony_ci}
2426fd4e5da5Sopenharmony_ci
2427fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjImplicitLodMultisampleError) {
2428fd4e5da5Sopenharmony_ci  const std::string body = R"(
2429fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2430fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2431fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2432fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
2433fd4e5da5Sopenharmony_ci)";
2434fd4e5da5Sopenharmony_ci
2435fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2436fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2437fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2438fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'MS' parameter to be 0"));
2439fd4e5da5Sopenharmony_ci}
2440fd4e5da5Sopenharmony_ci
2441fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjImplicitLodWrongSampledType) {
2442fd4e5da5Sopenharmony_ci  const std::string body = R"(
2443fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2444fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2445fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2446fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
2447fd4e5da5Sopenharmony_ci)";
2448fd4e5da5Sopenharmony_ci
2449fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2450fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2451fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2452fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
2453fd4e5da5Sopenharmony_ci                        "Result Type components"));
2454fd4e5da5Sopenharmony_ci}
2455fd4e5da5Sopenharmony_ci
2456fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjImplicitLodVoidSampledType) {
2457fd4e5da5Sopenharmony_ci  const std::string body = R"(
2458fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2459fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2460fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2461fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
2462fd4e5da5Sopenharmony_ci)";
2463fd4e5da5Sopenharmony_ci
2464fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2465fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2466fd4e5da5Sopenharmony_ci}
2467fd4e5da5Sopenharmony_ci
2468fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjImplicitLodWrongCoordinateType) {
2469fd4e5da5Sopenharmony_ci  const std::string body = R"(
2470fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2471fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2472fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2473fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %img
2474fd4e5da5Sopenharmony_ci)";
2475fd4e5da5Sopenharmony_ci
2476fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2477fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2478fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2479fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be float scalar or vector"));
2480fd4e5da5Sopenharmony_ci}
2481fd4e5da5Sopenharmony_ci
2482fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjImplicitLodCoordinateSizeTooSmall) {
2483fd4e5da5Sopenharmony_ci  const std::string body = R"(
2484fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2485fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2486fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2487fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh
2488fd4e5da5Sopenharmony_ci)";
2489fd4e5da5Sopenharmony_ci
2490fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2491fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2492fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2493fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 3 components, "
2494fd4e5da5Sopenharmony_ci                        "but given only 2"));
2495fd4e5da5Sopenharmony_ci}
2496fd4e5da5Sopenharmony_ci
2497fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefImplicitLodSuccess) {
2498fd4e5da5Sopenharmony_ci  const std::string body = R"(
2499fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2500fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2501fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2502fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1
2503fd4e5da5Sopenharmony_ci%res2 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
2504fd4e5da5Sopenharmony_ci%res4 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
2505fd4e5da5Sopenharmony_ci%res5 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
2506fd4e5da5Sopenharmony_ci%res6 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
2507fd4e5da5Sopenharmony_ci%res7 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2508fd4e5da5Sopenharmony_ci%res8 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
2509fd4e5da5Sopenharmony_ci)";
2510fd4e5da5Sopenharmony_ci
2511fd4e5da5Sopenharmony_ci  const std::string extra = R"(
2512fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
2513fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
2514fd4e5da5Sopenharmony_ci)";
2515fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2516fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2517fd4e5da5Sopenharmony_ci                          .c_str());
2518fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2519fd4e5da5Sopenharmony_ci}
2520fd4e5da5Sopenharmony_ci
2521fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefImplicitLodWrongResultType) {
2522fd4e5da5Sopenharmony_ci  const std::string body = R"(
2523fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2524fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2525fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2526fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefImplicitLod %void %simg %f32vec2_hh %u32_1
2527fd4e5da5Sopenharmony_ci)";
2528fd4e5da5Sopenharmony_ci
2529fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2530fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2531fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2532fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float scalar type"));
2533fd4e5da5Sopenharmony_ci}
2534fd4e5da5Sopenharmony_ci
2535fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefImplicitLodNotSampledImage) {
2536fd4e5da5Sopenharmony_ci  const std::string body = R"(
2537fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2538fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefImplicitLod %u32 %img %f32vec2_hh %u32_1
2539fd4e5da5Sopenharmony_ci)";
2540fd4e5da5Sopenharmony_ci
2541fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2542fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2543fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2544fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2545fd4e5da5Sopenharmony_ci      HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2546fd4e5da5Sopenharmony_ci}
2547fd4e5da5Sopenharmony_ci
2548fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefImplicitLodMultisampleError) {
2549fd4e5da5Sopenharmony_ci  const std::string body = R"(
2550fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2551fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2552fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2553fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
2554fd4e5da5Sopenharmony_ci)";
2555fd4e5da5Sopenharmony_ci
2556fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2557fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2558fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2559fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2560fd4e5da5Sopenharmony_ci      HasSubstr("Dref sampling operation is invalid for multisample image"));
2561fd4e5da5Sopenharmony_ci}
2562fd4e5da5Sopenharmony_ci
2563fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefImplicitLodWrongSampledType) {
2564fd4e5da5Sopenharmony_ci  const std::string body = R"(
2565fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2566fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2567fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2568fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_00 %u32_1
2569fd4e5da5Sopenharmony_ci)";
2570fd4e5da5Sopenharmony_ci
2571fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2572fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2573fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2574fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2575fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2576fd4e5da5Sopenharmony_ci}
2577fd4e5da5Sopenharmony_ci
2578fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefImplicitLodVoidSampledType) {
2579fd4e5da5Sopenharmony_ci  const std::string body = R"(
2580fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2581fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2582fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2583fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %u32_1
2584fd4e5da5Sopenharmony_ci)";
2585fd4e5da5Sopenharmony_ci
2586fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2587fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2588fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2589fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2590fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2591fd4e5da5Sopenharmony_ci}
2592fd4e5da5Sopenharmony_ci
2593fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefImplicitLodWrongCoordinateType) {
2594fd4e5da5Sopenharmony_ci  const std::string body = R"(
2595fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2596fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2597fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2598fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefImplicitLod %u32 %simg %img %u32_1
2599fd4e5da5Sopenharmony_ci)";
2600fd4e5da5Sopenharmony_ci
2601fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2602fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2603fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2604fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be float scalar or vector"));
2605fd4e5da5Sopenharmony_ci}
2606fd4e5da5Sopenharmony_ci
2607fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefImplicitLodCoordinateSizeTooSmall) {
2608fd4e5da5Sopenharmony_ci  const std::string body = R"(
2609fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2610fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2611fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2612fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32_0_5 %f32_0_5
2613fd4e5da5Sopenharmony_ci)";
2614fd4e5da5Sopenharmony_ci
2615fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2616fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2617fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2618fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 2 components, "
2619fd4e5da5Sopenharmony_ci                        "but given only 1"));
2620fd4e5da5Sopenharmony_ci}
2621fd4e5da5Sopenharmony_ci
2622fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefImplicitLodWrongDrefType) {
2623fd4e5da5Sopenharmony_ci  const std::string body = R"(
2624fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2625fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2626fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2627fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %f64_1
2628fd4e5da5Sopenharmony_ci)";
2629fd4e5da5Sopenharmony_ci
2630fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2631fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2632fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2633fd4e5da5Sopenharmony_ci              HasSubstr("Expected Dref to be of 32-bit float type"));
2634fd4e5da5Sopenharmony_ci}
2635fd4e5da5Sopenharmony_ci
2636fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefImplicitLodWrongDimVulkan) {
2637fd4e5da5Sopenharmony_ci  const std::string body = R"(
2638fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_3d_0001 %uniform_image_u32_3d_0001
2639fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2640fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_u32_3d_0001 %img %sampler
2641fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_1
2642fd4e5da5Sopenharmony_ci)";
2643fd4e5da5Sopenharmony_ci
2644fd4e5da5Sopenharmony_ci  CompileSuccessfully(
2645fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2646fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2647fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2648fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpImage-04777"));
2649fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2650fd4e5da5Sopenharmony_ci              HasSubstr("In Vulkan, OpImage*Dref* instructions must not use "
2651fd4e5da5Sopenharmony_ci                        "images with a 3D Dim"));
2652fd4e5da5Sopenharmony_ci}
2653fd4e5da5Sopenharmony_ci
2654fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefExplicitLodSuccess) {
2655fd4e5da5Sopenharmony_ci  const std::string body = R"(
2656fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2657fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2658fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2659fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod %f32_1
2660fd4e5da5Sopenharmony_ci%res3 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad %f32vec3_hhh %f32vec3_hhh
2661fd4e5da5Sopenharmony_ci%res4 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 ConstOffset %s32vec3_012
2662fd4e5da5Sopenharmony_ci%res5 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Offset %s32vec3_012
2663fd4e5da5Sopenharmony_ci%res7 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad|Offset %f32vec3_hhh %f32vec3_hhh %s32vec3_012
2664fd4e5da5Sopenharmony_ci%res8 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod|NonPrivateTexelKHR %f32_1
2665fd4e5da5Sopenharmony_ci)";
2666fd4e5da5Sopenharmony_ci
2667fd4e5da5Sopenharmony_ci  const std::string extra = R"(
2668fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
2669fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
2670fd4e5da5Sopenharmony_ci)";
2671fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2672fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2673fd4e5da5Sopenharmony_ci                          .c_str());
2674fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2675fd4e5da5Sopenharmony_ci}
2676fd4e5da5Sopenharmony_ci
2677fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefExplicitLodWrongResultType) {
2678fd4e5da5Sopenharmony_ci  const std::string body = R"(
2679fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2680fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2681fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2682fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %bool %simg %f32vec3_hhh %s32_1 Lod %f32_1
2683fd4e5da5Sopenharmony_ci)";
2684fd4e5da5Sopenharmony_ci
2685fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2686fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2687fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2688fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float scalar type"));
2689fd4e5da5Sopenharmony_ci}
2690fd4e5da5Sopenharmony_ci
2691fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefExplicitLodNotSampledImage) {
2692fd4e5da5Sopenharmony_ci  const std::string body = R"(
2693fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2694fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %s32 %img %f32vec3_hhh %s32_1 Lod %f32_1
2695fd4e5da5Sopenharmony_ci)";
2696fd4e5da5Sopenharmony_ci
2697fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2698fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2699fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2700fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2701fd4e5da5Sopenharmony_ci      HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2702fd4e5da5Sopenharmony_ci}
2703fd4e5da5Sopenharmony_ci
2704fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefExplicitLodMultisampleError) {
2705fd4e5da5Sopenharmony_ci  const std::string body = R"(
2706fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2707fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2708fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2709fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
2710fd4e5da5Sopenharmony_ci)";
2711fd4e5da5Sopenharmony_ci
2712fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2713fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2714fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2715fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2716fd4e5da5Sopenharmony_ci      HasSubstr("Dref sampling operation is invalid for multisample image"));
2717fd4e5da5Sopenharmony_ci}
2718fd4e5da5Sopenharmony_ci
2719fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefExplicitLodWrongSampledType) {
2720fd4e5da5Sopenharmony_ci  const std::string body = R"(
2721fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2722fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2723fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2724fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec3_hhh %s32_1 Lod %f32_1
2725fd4e5da5Sopenharmony_ci)";
2726fd4e5da5Sopenharmony_ci
2727fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2728fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2729fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2730fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2731fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2732fd4e5da5Sopenharmony_ci}
2733fd4e5da5Sopenharmony_ci
2734fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefExplicitLodVoidSampledType) {
2735fd4e5da5Sopenharmony_ci  const std::string body = R"(
2736fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2737fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2738fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2739fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %u32 %simg %f32vec2_00 %s32_1 Lod %f32_1
2740fd4e5da5Sopenharmony_ci)";
2741fd4e5da5Sopenharmony_ci
2742fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2743fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2744fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2745fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2746fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2747fd4e5da5Sopenharmony_ci}
2748fd4e5da5Sopenharmony_ci
2749fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefExplicitLodWrongCoordinateType) {
2750fd4e5da5Sopenharmony_ci  const std::string body = R"(
2751fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2752fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2753fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2754fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %s32 %simg %img %s32_1 Lod %f32_1
2755fd4e5da5Sopenharmony_ci)";
2756fd4e5da5Sopenharmony_ci
2757fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2758fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2759fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2760fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be float scalar or vector"));
2761fd4e5da5Sopenharmony_ci}
2762fd4e5da5Sopenharmony_ci
2763fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefExplicitLodCoordinateSizeTooSmall) {
2764fd4e5da5Sopenharmony_ci  const std::string body = R"(
2765fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2766fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2767fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2768fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec2_hh %s32_1 Lod %f32_1
2769fd4e5da5Sopenharmony_ci)";
2770fd4e5da5Sopenharmony_ci
2771fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2772fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2773fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2774fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 3 components, "
2775fd4e5da5Sopenharmony_ci                        "but given only 2"));
2776fd4e5da5Sopenharmony_ci}
2777fd4e5da5Sopenharmony_ci
2778fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleDrefExplicitLodWrongDrefType) {
2779fd4e5da5Sopenharmony_ci  const std::string body = R"(
2780fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2781fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2782fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2783fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %u32_1 Lod %f32_1
2784fd4e5da5Sopenharmony_ci)";
2785fd4e5da5Sopenharmony_ci
2786fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2787fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2788fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2789fd4e5da5Sopenharmony_ci              HasSubstr("Expected Dref to be of 32-bit float type"));
2790fd4e5da5Sopenharmony_ci}
2791fd4e5da5Sopenharmony_ci
2792fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefImplicitLodSuccess) {
2793fd4e5da5Sopenharmony_ci  const std::string body = R"(
2794fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2795fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2796fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2797fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5
2798fd4e5da5Sopenharmony_ci%res2 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias %f32_0_25
2799fd4e5da5Sopenharmony_ci%res4 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 ConstOffset %s32vec2_01
2800fd4e5da5Sopenharmony_ci%res5 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Offset %s32vec2_01
2801fd4e5da5Sopenharmony_ci%res6 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 MinLod %f32_0_5
2802fd4e5da5Sopenharmony_ci%res7 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2803fd4e5da5Sopenharmony_ci%res8 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 NonPrivateTexelKHR
2804fd4e5da5Sopenharmony_ci)";
2805fd4e5da5Sopenharmony_ci
2806fd4e5da5Sopenharmony_ci  const std::string extra = R"(
2807fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
2808fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
2809fd4e5da5Sopenharmony_ci)";
2810fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2811fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2812fd4e5da5Sopenharmony_ci                          .c_str());
2813fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2814fd4e5da5Sopenharmony_ci}
2815fd4e5da5Sopenharmony_ci
2816fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefImplicitLodWrongResultType) {
2817fd4e5da5Sopenharmony_ci  const std::string body = R"(
2818fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2819fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2820fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2821fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefImplicitLod %void %simg %f32vec3_hhh %f32_0_5
2822fd4e5da5Sopenharmony_ci)";
2823fd4e5da5Sopenharmony_ci
2824fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2825fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2826fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2827fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float scalar type"));
2828fd4e5da5Sopenharmony_ci}
2829fd4e5da5Sopenharmony_ci
2830fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefImplicitLodNotSampledImage) {
2831fd4e5da5Sopenharmony_ci  const std::string body = R"(
2832fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2833fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefImplicitLod %f32 %img %f32vec3_hhh %f32_0_5
2834fd4e5da5Sopenharmony_ci)";
2835fd4e5da5Sopenharmony_ci
2836fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2837fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2838fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2839fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2840fd4e5da5Sopenharmony_ci      HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2841fd4e5da5Sopenharmony_ci}
2842fd4e5da5Sopenharmony_ci
2843fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefImplicitLodMultisampleError) {
2844fd4e5da5Sopenharmony_ci  const std::string body = R"(
2845fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2846fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2847fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2848fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
2849fd4e5da5Sopenharmony_ci)";
2850fd4e5da5Sopenharmony_ci
2851fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2852fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2853fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2854fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2855fd4e5da5Sopenharmony_ci      HasSubstr("Dref sampling operation is invalid for multisample image"));
2856fd4e5da5Sopenharmony_ci}
2857fd4e5da5Sopenharmony_ci
2858fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefImplicitLodWrongSampledType) {
2859fd4e5da5Sopenharmony_ci  const std::string body = R"(
2860fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2861fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2862fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2863fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2864fd4e5da5Sopenharmony_ci)";
2865fd4e5da5Sopenharmony_ci
2866fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2867fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2868fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2869fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2870fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2871fd4e5da5Sopenharmony_ci}
2872fd4e5da5Sopenharmony_ci
2873fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefImplicitLodVoidSampledType) {
2874fd4e5da5Sopenharmony_ci  const std::string body = R"(
2875fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2876fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2877fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2878fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2879fd4e5da5Sopenharmony_ci)";
2880fd4e5da5Sopenharmony_ci
2881fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2882fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2883fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2884fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2885fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2886fd4e5da5Sopenharmony_ci}
2887fd4e5da5Sopenharmony_ci
2888fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefImplicitLodWrongCoordinateType) {
2889fd4e5da5Sopenharmony_ci  const std::string body = R"(
2890fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2891fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2892fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2893fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %img %f32_0_5
2894fd4e5da5Sopenharmony_ci)";
2895fd4e5da5Sopenharmony_ci
2896fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2897fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2898fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2899fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be float scalar or vector"));
2900fd4e5da5Sopenharmony_ci}
2901fd4e5da5Sopenharmony_ci
2902fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefImplicitLodCoordinateSizeTooSmall) {
2903fd4e5da5Sopenharmony_ci  const std::string body = R"(
2904fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2905fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2906fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2907fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec2_hh %f32_0_5
2908fd4e5da5Sopenharmony_ci)";
2909fd4e5da5Sopenharmony_ci
2910fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2911fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2912fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2913fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 3 components, "
2914fd4e5da5Sopenharmony_ci                        "but given only 2"));
2915fd4e5da5Sopenharmony_ci}
2916fd4e5da5Sopenharmony_ci
2917fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefImplicitLodWrongDrefType) {
2918fd4e5da5Sopenharmony_ci  const std::string body = R"(
2919fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2920fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2921fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2922fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32vec4_0000
2923fd4e5da5Sopenharmony_ci)";
2924fd4e5da5Sopenharmony_ci
2925fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2926fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2927fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2928fd4e5da5Sopenharmony_ci              HasSubstr("Expected Dref to be of 32-bit float type"));
2929fd4e5da5Sopenharmony_ci}
2930fd4e5da5Sopenharmony_ci
2931fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefExplicitLodSuccess) {
2932fd4e5da5Sopenharmony_ci  const std::string body = R"(
2933fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2934fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2935fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2936fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2937fd4e5da5Sopenharmony_ci%res2 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Grad %f32_0_5 %f32_0_5
2938fd4e5da5Sopenharmony_ci%res3 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 ConstOffset %s32_1
2939fd4e5da5Sopenharmony_ci%res4 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Offset %s32_1
2940fd4e5da5Sopenharmony_ci%res5 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Grad|Offset %f32_0_5 %f32_0_5 %s32_1
2941fd4e5da5Sopenharmony_ci%res6 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod|NonPrivateTexelKHR %f32_1
2942fd4e5da5Sopenharmony_ci)";
2943fd4e5da5Sopenharmony_ci
2944fd4e5da5Sopenharmony_ci  const std::string extra = R"(
2945fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
2946fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
2947fd4e5da5Sopenharmony_ci)";
2948fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2949fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2950fd4e5da5Sopenharmony_ci                          .c_str());
2951fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2952fd4e5da5Sopenharmony_ci}
2953fd4e5da5Sopenharmony_ci
2954fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefExplicitLodWrongResultType) {
2955fd4e5da5Sopenharmony_ci  const std::string body = R"(
2956fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2957fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2958fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2959fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefExplicitLod %bool %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2960fd4e5da5Sopenharmony_ci)";
2961fd4e5da5Sopenharmony_ci
2962fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2963fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2964fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2965fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float scalar type"));
2966fd4e5da5Sopenharmony_ci}
2967fd4e5da5Sopenharmony_ci
2968fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefExplicitLodNotSampledImage) {
2969fd4e5da5Sopenharmony_ci  const std::string body = R"(
2970fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2971fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefExplicitLod %f32 %img %f32vec2_hh %f32_0_5 Lod %f32_1
2972fd4e5da5Sopenharmony_ci)";
2973fd4e5da5Sopenharmony_ci
2974fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2975fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2976fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2977fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2978fd4e5da5Sopenharmony_ci      HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2979fd4e5da5Sopenharmony_ci}
2980fd4e5da5Sopenharmony_ci
2981fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefExplicitLodMultisampleError) {
2982fd4e5da5Sopenharmony_ci  const std::string body = R"(
2983fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2984fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
2985fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2986fd4e5da5Sopenharmony_ci%res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
2987fd4e5da5Sopenharmony_ci)";
2988fd4e5da5Sopenharmony_ci
2989fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
2990fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2991fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2992fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2993fd4e5da5Sopenharmony_ci      HasSubstr("Dref sampling operation is invalid for multisample image"));
2994fd4e5da5Sopenharmony_ci}
2995fd4e5da5Sopenharmony_ci
2996fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefExplicitLodWrongSampledType) {
2997fd4e5da5Sopenharmony_ci  const std::string body = R"(
2998fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2999fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3000fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
3001fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
3002fd4e5da5Sopenharmony_ci)";
3003fd4e5da5Sopenharmony_ci
3004fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3005fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3006fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3007fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3008fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
3009fd4e5da5Sopenharmony_ci}
3010fd4e5da5Sopenharmony_ci
3011fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefExplicitLodVoidSampledType) {
3012fd4e5da5Sopenharmony_ci  const std::string body = R"(
3013fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3014fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3015fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
3016fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec3_hhh %f32_0_5 Lod %f32_1
3017fd4e5da5Sopenharmony_ci)";
3018fd4e5da5Sopenharmony_ci
3019fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3020fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3021fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3022fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3023fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
3024fd4e5da5Sopenharmony_ci}
3025fd4e5da5Sopenharmony_ci
3026fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefExplicitLodWrongCoordinateType) {
3027fd4e5da5Sopenharmony_ci  const std::string body = R"(
3028fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
3029fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3030fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
3031fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %img %f32_0_5 Lod %f32_1
3032fd4e5da5Sopenharmony_ci)";
3033fd4e5da5Sopenharmony_ci
3034fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3035fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3036fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3037fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be float scalar or vector"));
3038fd4e5da5Sopenharmony_ci}
3039fd4e5da5Sopenharmony_ci
3040fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleProjDrefExplicitLodCoordinateSizeTooSmall) {
3041fd4e5da5Sopenharmony_ci  const std::string body = R"(
3042fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
3043fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3044fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
3045fd4e5da5Sopenharmony_ci%res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32_0_5 %f32_0_5 Lod %f32_1
3046fd4e5da5Sopenharmony_ci)";
3047fd4e5da5Sopenharmony_ci
3048fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3049fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3050fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3051fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 2 components, "
3052fd4e5da5Sopenharmony_ci                        "but given only 1"));
3053fd4e5da5Sopenharmony_ci}
3054fd4e5da5Sopenharmony_ci
3055fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchSuccess) {
3056fd4e5da5Sopenharmony_ci  const std::string body = R"(
3057fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
3058fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec4 %img %u32vec2_01
3059fd4e5da5Sopenharmony_ci%res2 = OpImageFetch %f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
3060fd4e5da5Sopenharmony_ci)";
3061fd4e5da5Sopenharmony_ci
3062fd4e5da5Sopenharmony_ci  const std::string extra = R"(
3063fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
3064fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
3065fd4e5da5Sopenharmony_ci)";
3066fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3067fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3068fd4e5da5Sopenharmony_ci                          .c_str());
3069fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3070fd4e5da5Sopenharmony_ci}
3071fd4e5da5Sopenharmony_ci
3072fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchMultisampledSuccess) {
3073fd4e5da5Sopenharmony_ci  const std::string body = R"(
3074fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3075fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample %u32_1
3076fd4e5da5Sopenharmony_ci%res2 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample|NonPrivateTexelKHR %u32_1
3077fd4e5da5Sopenharmony_ci)";
3078fd4e5da5Sopenharmony_ci
3079fd4e5da5Sopenharmony_ci  const std::string extra = R"(
3080fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
3081fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
3082fd4e5da5Sopenharmony_ci)";
3083fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3084fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3085fd4e5da5Sopenharmony_ci                          .c_str());
3086fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3087fd4e5da5Sopenharmony_ci}
3088fd4e5da5Sopenharmony_ci
3089fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchWrongResultType) {
3090fd4e5da5Sopenharmony_ci  const std::string body = R"(
3091fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3092fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32 %img %u32vec2_01
3093fd4e5da5Sopenharmony_ci)";
3094fd4e5da5Sopenharmony_ci
3095fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3096fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3097fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3098fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float vector type"));
3099fd4e5da5Sopenharmony_ci}
3100fd4e5da5Sopenharmony_ci
3101fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchWrongNumComponentsResultType) {
3102fd4e5da5Sopenharmony_ci  const std::string body = R"(
3103fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3104fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec3 %img %u32vec2_01
3105fd4e5da5Sopenharmony_ci)";
3106fd4e5da5Sopenharmony_ci
3107fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3108fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3109fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3110fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to have 4 components"));
3111fd4e5da5Sopenharmony_ci}
3112fd4e5da5Sopenharmony_ci
3113fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchNotImage) {
3114fd4e5da5Sopenharmony_ci  const std::string body = R"(
3115fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3116fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3117fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3118fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec4 %sampler %u32vec2_01
3119fd4e5da5Sopenharmony_ci)";
3120fd4e5da5Sopenharmony_ci
3121fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3122fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3123fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3124fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image to be of type OpTypeImage"));
3125fd4e5da5Sopenharmony_ci}
3126fd4e5da5Sopenharmony_ci
3127fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchSampledImageDirectly) {
3128fd4e5da5Sopenharmony_ci  const std::string body = R"(
3129fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3130fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3131fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3132fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec4 %simg %u32vec2_01
3133fd4e5da5Sopenharmony_ci)";
3134fd4e5da5Sopenharmony_ci
3135fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3136fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3137fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3138fd4e5da5Sopenharmony_ci              HasSubstr("OpSampledImage instruction must not appear as operand "
3139fd4e5da5Sopenharmony_ci                        "for OpImageFetch"));
3140fd4e5da5Sopenharmony_ci}
3141fd4e5da5Sopenharmony_ci
3142fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchNotSampled) {
3143fd4e5da5Sopenharmony_ci  const std::string body = R"(
3144fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3145fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %u32vec4 %img %u32vec2_01
3146fd4e5da5Sopenharmony_ci)";
3147fd4e5da5Sopenharmony_ci
3148fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3149fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3150fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3151fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled' parameter to be 1"));
3152fd4e5da5Sopenharmony_ci}
3153fd4e5da5Sopenharmony_ci
3154fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchCube) {
3155fd4e5da5Sopenharmony_ci  const std::string body = R"(
3156fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3157fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec4 %img %u32vec3_012
3158fd4e5da5Sopenharmony_ci)";
3159fd4e5da5Sopenharmony_ci
3160fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3161fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3162fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' cannot be Cube"));
3163fd4e5da5Sopenharmony_ci}
3164fd4e5da5Sopenharmony_ci
3165fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchWrongSampledType) {
3166fd4e5da5Sopenharmony_ci  const std::string body = R"(
3167fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3168fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %u32vec4 %img %u32vec2_01
3169fd4e5da5Sopenharmony_ci)";
3170fd4e5da5Sopenharmony_ci
3171fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3172fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3173fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3174fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
3175fd4e5da5Sopenharmony_ci                        "Result Type components"));
3176fd4e5da5Sopenharmony_ci}
3177fd4e5da5Sopenharmony_ci
3178fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchVoidSampledType) {
3179fd4e5da5Sopenharmony_ci  const std::string body = R"(
3180fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3181fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec4 %img %u32vec2_01
3182fd4e5da5Sopenharmony_ci%res2 = OpImageFetch %u32vec4 %img %u32vec2_01
3183fd4e5da5Sopenharmony_ci%res3 = OpImageFetch %s32vec4 %img %u32vec2_01
3184fd4e5da5Sopenharmony_ci)";
3185fd4e5da5Sopenharmony_ci
3186fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3187fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3188fd4e5da5Sopenharmony_ci}
3189fd4e5da5Sopenharmony_ci
3190fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchWrongCoordinateType) {
3191fd4e5da5Sopenharmony_ci  const std::string body = R"(
3192fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3193fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec4 %img %f32vec2_00
3194fd4e5da5Sopenharmony_ci)";
3195fd4e5da5Sopenharmony_ci
3196fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3197fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3198fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3199fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be int scalar or vector"));
3200fd4e5da5Sopenharmony_ci}
3201fd4e5da5Sopenharmony_ci
3202fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchCoordinateSizeTooSmall) {
3203fd4e5da5Sopenharmony_ci  const std::string body = R"(
3204fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3205fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec4 %img %u32_1
3206fd4e5da5Sopenharmony_ci)";
3207fd4e5da5Sopenharmony_ci
3208fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3209fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3210fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3211fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 2 components, "
3212fd4e5da5Sopenharmony_ci                        "but given only 1"));
3213fd4e5da5Sopenharmony_ci}
3214fd4e5da5Sopenharmony_ci
3215fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchLodNotInt) {
3216fd4e5da5Sopenharmony_ci  const std::string body = R"(
3217fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3218fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Lod %f32_1
3219fd4e5da5Sopenharmony_ci)";
3220fd4e5da5Sopenharmony_ci
3221fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3222fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3223fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3224fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image Operand Lod to be int scalar when used "
3225fd4e5da5Sopenharmony_ci                        "with OpImageFetch"));
3226fd4e5da5Sopenharmony_ci}
3227fd4e5da5Sopenharmony_ci
3228fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, FetchMultisampledMissingSample) {
3229fd4e5da5Sopenharmony_ci  const std::string body = R"(
3230fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3231fd4e5da5Sopenharmony_ci%res1 = OpImageFetch %f32vec4 %img %u32vec2_01
3232fd4e5da5Sopenharmony_ci)";
3233fd4e5da5Sopenharmony_ci
3234fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3235fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions())
3236fd4e5da5Sopenharmony_ci      << GenerateShaderCode(body);
3237fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3238fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand Sample is required for operation on "
3239fd4e5da5Sopenharmony_ci                        "multi-sampled image"))
3240fd4e5da5Sopenharmony_ci      << getDiagnosticString();
3241fd4e5da5Sopenharmony_ci}
3242fd4e5da5Sopenharmony_ci
3243fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherSuccess) {
3244fd4e5da5Sopenharmony_ci  const std::string body = R"(
3245fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3246fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3247fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3248fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1
3249fd4e5da5Sopenharmony_ci%res2 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
3250fd4e5da5Sopenharmony_ci%res3 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
3251fd4e5da5Sopenharmony_ci)";
3252fd4e5da5Sopenharmony_ci
3253fd4e5da5Sopenharmony_ci  const std::string extra = R"(
3254fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
3255fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
3256fd4e5da5Sopenharmony_ci)";
3257fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3258fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3259fd4e5da5Sopenharmony_ci                          .c_str());
3260fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3261fd4e5da5Sopenharmony_ci}
3262fd4e5da5Sopenharmony_ci
3263fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherWrongResultType) {
3264fd4e5da5Sopenharmony_ci  const std::string body = R"(
3265fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3266fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3267fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3268fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32 %simg %f32vec4_0000 %u32_1
3269fd4e5da5Sopenharmony_ci)";
3270fd4e5da5Sopenharmony_ci
3271fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3272fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3273fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3274fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float vector type"));
3275fd4e5da5Sopenharmony_ci}
3276fd4e5da5Sopenharmony_ci
3277fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherWrongNumComponentsResultType) {
3278fd4e5da5Sopenharmony_ci  const std::string body = R"(
3279fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3280fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3281fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3282fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec3 %simg %f32vec4_0000 %u32_1
3283fd4e5da5Sopenharmony_ci)";
3284fd4e5da5Sopenharmony_ci
3285fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3286fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3287fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3288fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to have 4 components"));
3289fd4e5da5Sopenharmony_ci}
3290fd4e5da5Sopenharmony_ci
3291fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherNotSampledImage) {
3292fd4e5da5Sopenharmony_ci  const std::string body = R"(
3293fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3294fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %img %f32vec4_0000 %u32_1
3295fd4e5da5Sopenharmony_ci)";
3296fd4e5da5Sopenharmony_ci
3297fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3298fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3299fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3300fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3301fd4e5da5Sopenharmony_ci      HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
3302fd4e5da5Sopenharmony_ci}
3303fd4e5da5Sopenharmony_ci
3304fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherMultisampleError) {
3305fd4e5da5Sopenharmony_ci  const std::string body = R"(
3306fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3307fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3308fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
3309fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Sample %u32_1
3310fd4e5da5Sopenharmony_ci)";
3311fd4e5da5Sopenharmony_ci
3312fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3313fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3314fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3315fd4e5da5Sopenharmony_ci              HasSubstr("Gather operation is invalid for multisample image"));
3316fd4e5da5Sopenharmony_ci}
3317fd4e5da5Sopenharmony_ci
3318fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherWrongSampledType) {
3319fd4e5da5Sopenharmony_ci  const std::string body = R"(
3320fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3321fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3322fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3323fd4e5da5Sopenharmony_ci%res1 = OpImageGather %u32vec4 %simg %f32vec4_0000 %u32_1
3324fd4e5da5Sopenharmony_ci)";
3325fd4e5da5Sopenharmony_ci
3326fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3327fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3328fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3329fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
3330fd4e5da5Sopenharmony_ci                        "Result Type components"));
3331fd4e5da5Sopenharmony_ci}
3332fd4e5da5Sopenharmony_ci
3333fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherVoidSampledType) {
3334fd4e5da5Sopenharmony_ci  const std::string body = R"(
3335fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3336fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3337fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
3338fd4e5da5Sopenharmony_ci%res1 = OpImageGather %u32vec4 %simg %f32vec2_00 %u32_1
3339fd4e5da5Sopenharmony_ci)";
3340fd4e5da5Sopenharmony_ci
3341fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3342fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3343fd4e5da5Sopenharmony_ci}
3344fd4e5da5Sopenharmony_ci
3345fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherWrongCoordinateType) {
3346fd4e5da5Sopenharmony_ci  const std::string body = R"(
3347fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3348fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3349fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3350fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %u32vec4_0123 %u32_1
3351fd4e5da5Sopenharmony_ci)";
3352fd4e5da5Sopenharmony_ci
3353fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3354fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3355fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3356fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be float scalar or vector"));
3357fd4e5da5Sopenharmony_ci}
3358fd4e5da5Sopenharmony_ci
3359fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherCoordinateSizeTooSmall) {
3360fd4e5da5Sopenharmony_ci  const std::string body = R"(
3361fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3362fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3363fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3364fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32_0_5 %u32_1
3365fd4e5da5Sopenharmony_ci)";
3366fd4e5da5Sopenharmony_ci
3367fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3368fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3369fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3370fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 4 components, "
3371fd4e5da5Sopenharmony_ci                        "but given only 1"));
3372fd4e5da5Sopenharmony_ci}
3373fd4e5da5Sopenharmony_ci
3374fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherWrongComponentType) {
3375fd4e5da5Sopenharmony_ci  const std::string body = R"(
3376fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3377fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3378fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3379fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %f32_1
3380fd4e5da5Sopenharmony_ci)";
3381fd4e5da5Sopenharmony_ci
3382fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3383fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3384fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3385fd4e5da5Sopenharmony_ci              HasSubstr("Expected Component to be 32-bit int scalar"));
3386fd4e5da5Sopenharmony_ci}
3387fd4e5da5Sopenharmony_ci
3388fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherComponentNot32Bit) {
3389fd4e5da5Sopenharmony_ci  const std::string body = R"(
3390fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3391fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3392fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3393fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u64_0
3394fd4e5da5Sopenharmony_ci)";
3395fd4e5da5Sopenharmony_ci
3396fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3397fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3398fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3399fd4e5da5Sopenharmony_ci              HasSubstr("Expected Component to be 32-bit int scalar"));
3400fd4e5da5Sopenharmony_ci}
3401fd4e5da5Sopenharmony_ci
3402fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherComponentSuccessVulkan) {
3403fd4e5da5Sopenharmony_ci  const std::string body = R"(
3404fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3405fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3406fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3407fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_0
3408fd4e5da5Sopenharmony_ci)";
3409fd4e5da5Sopenharmony_ci
3410fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
3411fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3412fd4e5da5Sopenharmony_ci                      env);
3413fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
3414fd4e5da5Sopenharmony_ci}
3415fd4e5da5Sopenharmony_ci
3416fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherComponentNotConstantVulkan) {
3417fd4e5da5Sopenharmony_ci  const std::string body = R"(
3418fd4e5da5Sopenharmony_ci%input_u32 = OpLoad %u32 %input_flat_u32
3419fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3420fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3421fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3422fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %input_u32
3423fd4e5da5Sopenharmony_ci)";
3424fd4e5da5Sopenharmony_ci
3425fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
3426fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3427fd4e5da5Sopenharmony_ci                      env);
3428fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3429fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3430fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpImageGather-04664"));
3431fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3432fd4e5da5Sopenharmony_ci              HasSubstr("Expected Component Operand to be a const object for "
3433fd4e5da5Sopenharmony_ci                        "Vulkan environment"));
3434fd4e5da5Sopenharmony_ci}
3435fd4e5da5Sopenharmony_ci
3436fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherDimCube) {
3437fd4e5da5Sopenharmony_ci  const std::string body = R"(
3438fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3439fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3440fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3441fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
3442fd4e5da5Sopenharmony_ci)";
3443fd4e5da5Sopenharmony_ci
3444fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3445fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3446fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3447fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3448fd4e5da5Sopenharmony_ci      HasSubstr(
3449fd4e5da5Sopenharmony_ci          "Image Operand ConstOffsets cannot be used with Cube Image 'Dim'"));
3450fd4e5da5Sopenharmony_ci}
3451fd4e5da5Sopenharmony_ci
3452fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherConstOffsetsNotArray) {
3453fd4e5da5Sopenharmony_ci  const std::string body = R"(
3454fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3455fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3456fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3457fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %u32vec4_0123
3458fd4e5da5Sopenharmony_ci)";
3459fd4e5da5Sopenharmony_ci
3460fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3461fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3462fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3463fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3464fd4e5da5Sopenharmony_ci      HasSubstr(
3465fd4e5da5Sopenharmony_ci          "Expected Image Operand ConstOffsets to be an array of size 4"));
3466fd4e5da5Sopenharmony_ci}
3467fd4e5da5Sopenharmony_ci
3468fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherConstOffsetsArrayWrongSize) {
3469fd4e5da5Sopenharmony_ci  const std::string body = R"(
3470fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3471fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3472fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3473fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets3x2
3474fd4e5da5Sopenharmony_ci)";
3475fd4e5da5Sopenharmony_ci
3476fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3477fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3478fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3479fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3480fd4e5da5Sopenharmony_ci      HasSubstr(
3481fd4e5da5Sopenharmony_ci          "Expected Image Operand ConstOffsets to be an array of size 4"));
3482fd4e5da5Sopenharmony_ci}
3483fd4e5da5Sopenharmony_ci
3484fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherConstOffsetsArrayNotVector) {
3485fd4e5da5Sopenharmony_ci  const std::string body = R"(
3486fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3487fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3488fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3489fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4xu
3490fd4e5da5Sopenharmony_ci)";
3491fd4e5da5Sopenharmony_ci
3492fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3493fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3494fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3495fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image Operand ConstOffsets array components "
3496fd4e5da5Sopenharmony_ci                        "to be int vectors of size 2"));
3497fd4e5da5Sopenharmony_ci}
3498fd4e5da5Sopenharmony_ci
3499fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherConstOffsetsArrayVectorWrongSize) {
3500fd4e5da5Sopenharmony_ci  const std::string body = R"(
3501fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3502fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3503fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3504fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4x3
3505fd4e5da5Sopenharmony_ci)";
3506fd4e5da5Sopenharmony_ci
3507fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3508fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3509fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3510fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image Operand ConstOffsets array components "
3511fd4e5da5Sopenharmony_ci                        "to be int vectors of size 2"));
3512fd4e5da5Sopenharmony_ci}
3513fd4e5da5Sopenharmony_ci
3514fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherConstOffsetsArrayNotConst) {
3515fd4e5da5Sopenharmony_ci  const std::string body = R"(
3516fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3517fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3518fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3519fd4e5da5Sopenharmony_ci%offsets = OpUndef %u32vec2arr4
3520fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %offsets
3521fd4e5da5Sopenharmony_ci)";
3522fd4e5da5Sopenharmony_ci
3523fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3524fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3525fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3526fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3527fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image Operand ConstOffsets to be a const object"));
3528fd4e5da5Sopenharmony_ci}
3529fd4e5da5Sopenharmony_ci
3530fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, NotGatherWithConstOffsets) {
3531fd4e5da5Sopenharmony_ci  const std::string body = R"(
3532fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3533fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3534fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3535fd4e5da5Sopenharmony_ci%res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffsets %const_offsets
3536fd4e5da5Sopenharmony_ci)";
3537fd4e5da5Sopenharmony_ci
3538fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3539fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3540fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3541fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3542fd4e5da5Sopenharmony_ci      HasSubstr(
3543fd4e5da5Sopenharmony_ci          "Image Operand ConstOffsets can only be used with OpImageGather "
3544fd4e5da5Sopenharmony_ci          "and OpImageDrefGather"));
3545fd4e5da5Sopenharmony_ci}
3546fd4e5da5Sopenharmony_ci
3547fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, DrefGatherSuccess) {
3548fd4e5da5Sopenharmony_ci  const std::string body = R"(
3549fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3550fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3551fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3552fd4e5da5Sopenharmony_ci%res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
3553fd4e5da5Sopenharmony_ci%res2 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 ConstOffsets %const_offsets
3554fd4e5da5Sopenharmony_ci%res3 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 NonPrivateTexelKHR
3555fd4e5da5Sopenharmony_ci)";
3556fd4e5da5Sopenharmony_ci
3557fd4e5da5Sopenharmony_ci  const std::string extra = R"(
3558fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
3559fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
3560fd4e5da5Sopenharmony_ci)";
3561fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3562fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3563fd4e5da5Sopenharmony_ci                          .c_str());
3564fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3565fd4e5da5Sopenharmony_ci}
3566fd4e5da5Sopenharmony_ci
3567fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, DrefGatherMultisampleError) {
3568fd4e5da5Sopenharmony_ci  const std::string body = R"(
3569fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3570fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3571fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
3572fd4e5da5Sopenharmony_ci%res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_1 Sample %u32_1
3573fd4e5da5Sopenharmony_ci)";
3574fd4e5da5Sopenharmony_ci
3575fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3576fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3577fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3578fd4e5da5Sopenharmony_ci              HasSubstr("Gather operation is invalid for multisample image"));
3579fd4e5da5Sopenharmony_ci}
3580fd4e5da5Sopenharmony_ci
3581fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, DrefGatherVoidSampledType) {
3582fd4e5da5Sopenharmony_ci  const std::string body = R"(
3583fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3584fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3585fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
3586fd4e5da5Sopenharmony_ci%res1 = OpImageDrefGather %u32vec4 %simg %f32vec2_00 %f32_0_5
3587fd4e5da5Sopenharmony_ci)";
3588fd4e5da5Sopenharmony_ci
3589fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3590fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3591fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3592fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
3593fd4e5da5Sopenharmony_ci                        "Result Type components"));
3594fd4e5da5Sopenharmony_ci}
3595fd4e5da5Sopenharmony_ci
3596fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, DrefGatherWrongDrefType) {
3597fd4e5da5Sopenharmony_ci  const std::string body = R"(
3598fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3599fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3600fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3601fd4e5da5Sopenharmony_ci%res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %u32_1
3602fd4e5da5Sopenharmony_ci)";
3603fd4e5da5Sopenharmony_ci
3604fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3605fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3606fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3607fd4e5da5Sopenharmony_ci              HasSubstr("Expected Dref to be of 32-bit float type"));
3608fd4e5da5Sopenharmony_ci}
3609fd4e5da5Sopenharmony_ci
3610fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, DrefGatherWrongDimVulkan) {
3611fd4e5da5Sopenharmony_ci  const std::string body = R"(
3612fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_3d_0001 %uniform_image_f32_3d_0001
3613fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3614fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_3d_0001 %img %sampler
3615fd4e5da5Sopenharmony_ci%res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
3616fd4e5da5Sopenharmony_ci)";
3617fd4e5da5Sopenharmony_ci
3618fd4e5da5Sopenharmony_ci  CompileSuccessfully(
3619fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
3620fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3621fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3622fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpImage-04777"));
3623fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3624fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Dim' to be 2D, Cube, or Rect"));
3625fd4e5da5Sopenharmony_ci}
3626fd4e5da5Sopenharmony_ci
3627fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadSuccess1) {
3628fd4e5da5Sopenharmony_ci  const std::string body = R"(
3629fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3630fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01
3631fd4e5da5Sopenharmony_ci)";
3632fd4e5da5Sopenharmony_ci
3633fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3634fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3635fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3636fd4e5da5Sopenharmony_ci}
3637fd4e5da5Sopenharmony_ci
3638fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadSuccess2) {
3639fd4e5da5Sopenharmony_ci  const std::string body = R"(
3640fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3641fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec2_01
3642fd4e5da5Sopenharmony_ci)";
3643fd4e5da5Sopenharmony_ci
3644fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability Image1D\n";
3645fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3646fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3647fd4e5da5Sopenharmony_ci}
3648fd4e5da5Sopenharmony_ci
3649fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadSuccess3) {
3650fd4e5da5Sopenharmony_ci  const std::string body = R"(
3651fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3652fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec3_012
3653fd4e5da5Sopenharmony_ci)";
3654fd4e5da5Sopenharmony_ci
3655fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability ImageCubeArray\n";
3656fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3657fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3658fd4e5da5Sopenharmony_ci}
3659fd4e5da5Sopenharmony_ci
3660fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadSuccess4) {
3661fd4e5da5Sopenharmony_ci  const std::string body = R"(
3662fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3663fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec2_01
3664fd4e5da5Sopenharmony_ci)";
3665fd4e5da5Sopenharmony_ci
3666fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3667fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3668fd4e5da5Sopenharmony_ci}
3669fd4e5da5Sopenharmony_ci
3670fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) {
3671fd4e5da5Sopenharmony_ci  const std::string body = R"(
3672fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3673fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01
3674fd4e5da5Sopenharmony_ci)";
3675fd4e5da5Sopenharmony_ci
3676fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3677fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3678fd4e5da5Sopenharmony_ci}
3679fd4e5da5Sopenharmony_ci
3680fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) {
3681fd4e5da5Sopenharmony_ci  const std::string body = R"(
3682fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3683fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01
3684fd4e5da5Sopenharmony_ci)";
3685fd4e5da5Sopenharmony_ci
3686fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
3687fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3688fd4e5da5Sopenharmony_ci                      env);
3689fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3690fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3691fd4e5da5Sopenharmony_ci              HasSubstr("Capability StorageImageReadWithoutFormat is required "
3692fd4e5da5Sopenharmony_ci                        "to read storage image"));
3693fd4e5da5Sopenharmony_ci}
3694fd4e5da5Sopenharmony_ci
3695fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadNeedCapabilityImage1D) {
3696fd4e5da5Sopenharmony_ci  const std::string body = R"(
3697fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3698fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec2_01
3699fd4e5da5Sopenharmony_ci)";
3700fd4e5da5Sopenharmony_ci
3701fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3702fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3703fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3704fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3705fd4e5da5Sopenharmony_ci      HasSubstr("Capability Image1D is required to access storage image"));
3706fd4e5da5Sopenharmony_ci}
3707fd4e5da5Sopenharmony_ci
3708fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadNeedCapabilityImageCubeArray) {
3709fd4e5da5Sopenharmony_ci  const std::string body = R"(
3710fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3711fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec3_012
3712fd4e5da5Sopenharmony_ci)";
3713fd4e5da5Sopenharmony_ci
3714fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3715fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3716fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3717fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3718fd4e5da5Sopenharmony_ci      HasSubstr(
3719fd4e5da5Sopenharmony_ci          "Capability ImageCubeArray is required to access storage image"));
3720fd4e5da5Sopenharmony_ci}
3721fd4e5da5Sopenharmony_ci
3722fd4e5da5Sopenharmony_ci// TODO(atgoo@github.com) Disabled until the spec is clarified.
3723fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, DISABLED_ReadWrongResultType) {
3724fd4e5da5Sopenharmony_ci  const std::string body = R"(
3725fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3726fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32 %img %u32vec2_01
3727fd4e5da5Sopenharmony_ci)";
3728fd4e5da5Sopenharmony_ci
3729fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3730fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3731fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3732fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3733fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int or float vector type"));
3734fd4e5da5Sopenharmony_ci}
3735fd4e5da5Sopenharmony_ci
3736fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadScalarResultType_Universal) {
3737fd4e5da5Sopenharmony_ci  const std::string body = R"(
3738fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3739fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32 %img %u32vec2_01
3740fd4e5da5Sopenharmony_ci)";
3741fd4e5da5Sopenharmony_ci
3742fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3743fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3744fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
3745fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
3746fd4e5da5Sopenharmony_ci}
3747fd4e5da5Sopenharmony_ci
3748fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadUnusualNumComponentsResultType_Universal) {
3749fd4e5da5Sopenharmony_ci  const std::string body = R"(
3750fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3751fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec3 %img %u32vec2_01
3752fd4e5da5Sopenharmony_ci)";
3753fd4e5da5Sopenharmony_ci
3754fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3755fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3756fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
3757fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
3758fd4e5da5Sopenharmony_ci}
3759fd4e5da5Sopenharmony_ci
3760fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadWrongNumComponentsResultType_Vulkan) {
3761fd4e5da5Sopenharmony_ci  const std::string body = R"(
3762fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3763fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec3 %img %u32vec2_01
3764fd4e5da5Sopenharmony_ci)";
3765fd4e5da5Sopenharmony_ci
3766fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3767fd4e5da5Sopenharmony_ci  CompileSuccessfully(
3768fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_VULKAN_1_0)
3769fd4e5da5Sopenharmony_ci          .c_str());
3770fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3771fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3772fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Result-04780"));
3773fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3774fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to have 4 components"));
3775fd4e5da5Sopenharmony_ci}
3776fd4e5da5Sopenharmony_ci
3777fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadNotImage) {
3778fd4e5da5Sopenharmony_ci  const std::string body = R"(
3779fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3780fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %sampler %u32vec2_01
3781fd4e5da5Sopenharmony_ci)";
3782fd4e5da5Sopenharmony_ci
3783fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3784fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3785fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3786fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3787fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image to be of type OpTypeImage"));
3788fd4e5da5Sopenharmony_ci}
3789fd4e5da5Sopenharmony_ci
3790fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadImageSampled) {
3791fd4e5da5Sopenharmony_ci  const std::string body = R"(
3792fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3793fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec2_01
3794fd4e5da5Sopenharmony_ci)";
3795fd4e5da5Sopenharmony_ci
3796fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3797fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3798fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3799fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3800fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
3801fd4e5da5Sopenharmony_ci}
3802fd4e5da5Sopenharmony_ci
3803fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadWrongSampledType) {
3804fd4e5da5Sopenharmony_ci  const std::string body = R"(
3805fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3806fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec2_01
3807fd4e5da5Sopenharmony_ci)";
3808fd4e5da5Sopenharmony_ci
3809fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3810fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3811fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3812fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3813fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
3814fd4e5da5Sopenharmony_ci                        "Result Type components"));
3815fd4e5da5Sopenharmony_ci}
3816fd4e5da5Sopenharmony_ci
3817fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadVoidSampledType) {
3818fd4e5da5Sopenharmony_ci  const std::string body = R"(
3819fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_void_2d_0002 %uniform_image_void_2d_0002
3820fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec2_01
3821fd4e5da5Sopenharmony_ci%res2 = OpImageRead %u32vec4 %img %u32vec2_01
3822fd4e5da5Sopenharmony_ci%res3 = OpImageRead %s32vec4 %img %u32vec2_01
3823fd4e5da5Sopenharmony_ci)";
3824fd4e5da5Sopenharmony_ci
3825fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3826fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3827fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3828fd4e5da5Sopenharmony_ci}
3829fd4e5da5Sopenharmony_ci
3830fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadWrongCoordinateType) {
3831fd4e5da5Sopenharmony_ci  const std::string body = R"(
3832fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3833fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %f32vec2_00
3834fd4e5da5Sopenharmony_ci)";
3835fd4e5da5Sopenharmony_ci
3836fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3837fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3838fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3839fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3840fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be int scalar or vector"));
3841fd4e5da5Sopenharmony_ci}
3842fd4e5da5Sopenharmony_ci
3843fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadCoordinateSizeTooSmall) {
3844fd4e5da5Sopenharmony_ci  const std::string body = R"(
3845fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3846fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32_1
3847fd4e5da5Sopenharmony_ci)";
3848fd4e5da5Sopenharmony_ci
3849fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3850fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3851fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3852fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3853fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 2 components, "
3854fd4e5da5Sopenharmony_ci                        "but given only 1"));
3855fd4e5da5Sopenharmony_ci}
3856fd4e5da5Sopenharmony_ci
3857fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteSuccess1) {
3858fd4e5da5Sopenharmony_ci  const std::string body = R"(
3859fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3860fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %u32vec4_0123
3861fd4e5da5Sopenharmony_ci)";
3862fd4e5da5Sopenharmony_ci
3863fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3864fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3865fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3866fd4e5da5Sopenharmony_ci}
3867fd4e5da5Sopenharmony_ci
3868fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteSuccess2) {
3869fd4e5da5Sopenharmony_ci  const std::string body = R"(
3870fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3871fd4e5da5Sopenharmony_ciOpImageWrite %img %u32_1 %f32vec4_0000
3872fd4e5da5Sopenharmony_ci)";
3873fd4e5da5Sopenharmony_ci
3874fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability Image1D\n";
3875fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3876fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3877fd4e5da5Sopenharmony_ci}
3878fd4e5da5Sopenharmony_ci
3879fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteSuccess3) {
3880fd4e5da5Sopenharmony_ci  const std::string body = R"(
3881fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3882fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec3_012 %f32vec4_0000
3883fd4e5da5Sopenharmony_ci)";
3884fd4e5da5Sopenharmony_ci
3885fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability ImageCubeArray\n";
3886fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3887fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3888fd4e5da5Sopenharmony_ci}
3889fd4e5da5Sopenharmony_ci
3890fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteSuccess4) {
3891fd4e5da5Sopenharmony_ci  const std::string body = R"(
3892fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
3893fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
3894fd4e5da5Sopenharmony_ci)";
3895fd4e5da5Sopenharmony_ci
3896fd4e5da5Sopenharmony_ci  const std::string extra = R"(
3897fd4e5da5Sopenharmony_ci    OpCapability StorageImageWriteWithoutFormat
3898fd4e5da5Sopenharmony_ci    OpCapability StorageImageMultisample
3899fd4e5da5Sopenharmony_ci    )";
3900fd4e5da5Sopenharmony_ci
3901fd4e5da5Sopenharmony_ci  const std::string declarations = R"(
3902fd4e5da5Sopenharmony_ci%type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
3903fd4e5da5Sopenharmony_ci%ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
3904fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
3905fd4e5da5Sopenharmony_ci    )";
3906fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3907fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_0, "GLSL450",
3908fd4e5da5Sopenharmony_ci                                         declarations)
3909fd4e5da5Sopenharmony_ci                          .c_str());
3910fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3911fd4e5da5Sopenharmony_ci}
3912fd4e5da5Sopenharmony_ci
3913fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteSubpassData) {
3914fd4e5da5Sopenharmony_ci  const std::string body = R"(
3915fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3916fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %f32vec4_0000
3917fd4e5da5Sopenharmony_ci)";
3918fd4e5da5Sopenharmony_ci
3919fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3920fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3921fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3922fd4e5da5Sopenharmony_ci              HasSubstr("Image 'Dim' cannot be SubpassData"));
3923fd4e5da5Sopenharmony_ci}
3924fd4e5da5Sopenharmony_ci
3925fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
3926fd4e5da5Sopenharmony_ci  const std::string body = R"(
3927fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3928fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %u32vec4_0123
3929fd4e5da5Sopenharmony_ci)";
3930fd4e5da5Sopenharmony_ci
3931fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3932fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3933fd4e5da5Sopenharmony_ci}
3934fd4e5da5Sopenharmony_ci
3935fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
3936fd4e5da5Sopenharmony_ci  const std::string body = R"(
3937fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3938fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %u32vec4_0123
3939fd4e5da5Sopenharmony_ci)";
3940fd4e5da5Sopenharmony_ci
3941fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
3942fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3943fd4e5da5Sopenharmony_ci                      env);
3944fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3945fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3946fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3947fd4e5da5Sopenharmony_ci      HasSubstr(
3948fd4e5da5Sopenharmony_ci          "Capability StorageImageWriteWithoutFormat is required to write to "
3949fd4e5da5Sopenharmony_ci          "storage image"));
3950fd4e5da5Sopenharmony_ci}
3951fd4e5da5Sopenharmony_ci
3952fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteNeedCapabilityImage1D) {
3953fd4e5da5Sopenharmony_ci  const std::string body = R"(
3954fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3955fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %f32vec4_0000
3956fd4e5da5Sopenharmony_ci)";
3957fd4e5da5Sopenharmony_ci
3958fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3959fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3960fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3961fd4e5da5Sopenharmony_ci              HasSubstr("Capability Image1D is required to access storage "
3962fd4e5da5Sopenharmony_ci                        "image"));
3963fd4e5da5Sopenharmony_ci}
3964fd4e5da5Sopenharmony_ci
3965fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteNeedCapabilityImageCubeArray) {
3966fd4e5da5Sopenharmony_ci  const std::string body = R"(
3967fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3968fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec3_012 %f32vec4_0000
3969fd4e5da5Sopenharmony_ci)";
3970fd4e5da5Sopenharmony_ci
3971fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3972fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3973fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3974fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3975fd4e5da5Sopenharmony_ci      HasSubstr(
3976fd4e5da5Sopenharmony_ci          "Capability ImageCubeArray is required to access storage image"));
3977fd4e5da5Sopenharmony_ci}
3978fd4e5da5Sopenharmony_ci
3979fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteNotImage) {
3980fd4e5da5Sopenharmony_ci  const std::string body = R"(
3981fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
3982fd4e5da5Sopenharmony_ciOpImageWrite %sampler %u32vec2_01 %f32vec4_0000
3983fd4e5da5Sopenharmony_ci)";
3984fd4e5da5Sopenharmony_ci
3985fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
3986fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3987fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3988fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image to be of type OpTypeImage"));
3989fd4e5da5Sopenharmony_ci}
3990fd4e5da5Sopenharmony_ci
3991fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteImageSampled) {
3992fd4e5da5Sopenharmony_ci  const std::string body = R"(
3993fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3994fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %f32vec4_0000
3995fd4e5da5Sopenharmony_ci)";
3996fd4e5da5Sopenharmony_ci
3997fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3998fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3999fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4000fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4001fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
4002fd4e5da5Sopenharmony_ci}
4003fd4e5da5Sopenharmony_ci
4004fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteWrongCoordinateType) {
4005fd4e5da5Sopenharmony_ci  const std::string body = R"(
4006fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4007fd4e5da5Sopenharmony_ciOpImageWrite %img %f32vec2_00 %u32vec4_0123
4008fd4e5da5Sopenharmony_ci)";
4009fd4e5da5Sopenharmony_ci
4010fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4011fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4012fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4013fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4014fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be int scalar or vector"));
4015fd4e5da5Sopenharmony_ci}
4016fd4e5da5Sopenharmony_ci
4017fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteCoordinateSizeTooSmall) {
4018fd4e5da5Sopenharmony_ci  const std::string body = R"(
4019fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4020fd4e5da5Sopenharmony_ciOpImageWrite %img %u32_1 %u32vec4_0123
4021fd4e5da5Sopenharmony_ci)";
4022fd4e5da5Sopenharmony_ci
4023fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4024fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4025fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4026fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4027fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 2 components, "
4028fd4e5da5Sopenharmony_ci                        "but given only 1"));
4029fd4e5da5Sopenharmony_ci}
4030fd4e5da5Sopenharmony_ci
4031fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteTexelScalarSuccess) {
4032fd4e5da5Sopenharmony_ci  const std::string body = R"(
4033fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4034fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %u32_2
4035fd4e5da5Sopenharmony_ci)";
4036fd4e5da5Sopenharmony_ci
4037fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4038fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4039fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4040fd4e5da5Sopenharmony_ci}
4041fd4e5da5Sopenharmony_ci
4042fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteTexelWrongType) {
4043fd4e5da5Sopenharmony_ci  const std::string body = R"(
4044fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4045fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %img
4046fd4e5da5Sopenharmony_ci)";
4047fd4e5da5Sopenharmony_ci
4048fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4049fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4050fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4051fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4052fd4e5da5Sopenharmony_ci              HasSubstr("Expected Texel to be int or float vector or scalar"));
4053fd4e5da5Sopenharmony_ci}
4054fd4e5da5Sopenharmony_ci
4055fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteTexelNonNumericalType) {
4056fd4e5da5Sopenharmony_ci  const std::string body = R"(
4057fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4058fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %boolvec4_tttt
4059fd4e5da5Sopenharmony_ci)";
4060fd4e5da5Sopenharmony_ci
4061fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4062fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4063fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4064fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4065fd4e5da5Sopenharmony_ci              HasSubstr("Expected Texel to be int or float vector or scalar"));
4066fd4e5da5Sopenharmony_ci}
4067fd4e5da5Sopenharmony_ci
4068fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteTexelWrongComponentType) {
4069fd4e5da5Sopenharmony_ci  const std::string body = R"(
4070fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4071fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %f32vec4_0000
4072fd4e5da5Sopenharmony_ci)";
4073fd4e5da5Sopenharmony_ci
4074fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4075fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4076fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4077fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4078fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4079fd4e5da5Sopenharmony_ci      HasSubstr(
4080fd4e5da5Sopenharmony_ci          "Expected Image 'Sampled Type' to be the same as Texel components"));
4081fd4e5da5Sopenharmony_ci}
4082fd4e5da5Sopenharmony_ci
4083fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteSampleNotInteger) {
4084fd4e5da5Sopenharmony_ci  const std::string body = R"(
4085fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
4086fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1
4087fd4e5da5Sopenharmony_ci)";
4088fd4e5da5Sopenharmony_ci
4089fd4e5da5Sopenharmony_ci  const std::string extra = R"(
4090fd4e5da5Sopenharmony_ci    OpCapability StorageImageWriteWithoutFormat
4091fd4e5da5Sopenharmony_ci    OpCapability StorageImageMultisample
4092fd4e5da5Sopenharmony_ci    )";
4093fd4e5da5Sopenharmony_ci  const std::string declarations = R"(
4094fd4e5da5Sopenharmony_ci%type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
4095fd4e5da5Sopenharmony_ci%ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
4096fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
4097fd4e5da5Sopenharmony_ci    )";
4098fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4099fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_0, "GLSL450",
4100fd4e5da5Sopenharmony_ci                                         declarations)
4101fd4e5da5Sopenharmony_ci                          .c_str());
4102fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4103fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4104fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image Operand Sample to be int scalar"));
4105fd4e5da5Sopenharmony_ci}
4106fd4e5da5Sopenharmony_ci
4107fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteSampleNotMultisampled) {
4108fd4e5da5Sopenharmony_ci  const std::string body = R"(
4109fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4110fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
4111fd4e5da5Sopenharmony_ci)";
4112fd4e5da5Sopenharmony_ci
4113fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4114fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4115fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4116fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4117fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4118fd4e5da5Sopenharmony_ci      HasSubstr("Image Operand Sample requires non-zero 'MS' parameter"));
4119fd4e5da5Sopenharmony_ci}
4120fd4e5da5Sopenharmony_ci
4121fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleWrongOpcode) {
4122fd4e5da5Sopenharmony_ci  const std::string body = R"(
4123fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4124fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4125fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
4126fd4e5da5Sopenharmony_ci%res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Sample %u32_1
4127fd4e5da5Sopenharmony_ci)";
4128fd4e5da5Sopenharmony_ci
4129fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4130fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4131fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4132fd4e5da5Sopenharmony_ci              HasSubstr("Sampling operation is invalid for multisample image"));
4133fd4e5da5Sopenharmony_ci}
4134fd4e5da5Sopenharmony_ci
4135fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImageToImageSuccess) {
4136fd4e5da5Sopenharmony_ci  const std::string body = R"(
4137fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4138fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4139fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4140fd4e5da5Sopenharmony_ci%img2 = OpImage %type_image_f32_2d_0001 %simg
4141fd4e5da5Sopenharmony_ci)";
4142fd4e5da5Sopenharmony_ci
4143fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4144fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4145fd4e5da5Sopenharmony_ci}
4146fd4e5da5Sopenharmony_ci
4147fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImageToImageWrongResultType) {
4148fd4e5da5Sopenharmony_ci  const std::string body = R"(
4149fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4150fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4151fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4152fd4e5da5Sopenharmony_ci%img2 = OpImage %type_sampled_image_f32_2d_0001 %simg
4153fd4e5da5Sopenharmony_ci)";
4154fd4e5da5Sopenharmony_ci
4155fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4156fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4157fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4158fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypeImage"));
4159fd4e5da5Sopenharmony_ci}
4160fd4e5da5Sopenharmony_ci
4161fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImageToImageNotSampledImage) {
4162fd4e5da5Sopenharmony_ci  const std::string body = R"(
4163fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4164fd4e5da5Sopenharmony_ci%img2 = OpImage %type_image_f32_2d_0001 %img
4165fd4e5da5Sopenharmony_ci)";
4166fd4e5da5Sopenharmony_ci
4167fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4168fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4169fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4170fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4171fd4e5da5Sopenharmony_ci      HasSubstr("Expected Sample Image to be of type OpTypeSampleImage"));
4172fd4e5da5Sopenharmony_ci}
4173fd4e5da5Sopenharmony_ci
4174fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SampleImageToImageNotTheSameImageType) {
4175fd4e5da5Sopenharmony_ci  const std::string body = R"(
4176fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4177fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4178fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4179fd4e5da5Sopenharmony_ci%img2 = OpImage %type_image_f32_2d_0002 %simg
4180fd4e5da5Sopenharmony_ci)";
4181fd4e5da5Sopenharmony_ci
4182fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4183fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4184fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4185fd4e5da5Sopenharmony_ci              HasSubstr("Expected Sample Image image type to be equal to "
4186fd4e5da5Sopenharmony_ci                        "Result Type"));
4187fd4e5da5Sopenharmony_ci}
4188fd4e5da5Sopenharmony_ci
4189fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryFormatSuccess) {
4190fd4e5da5Sopenharmony_ci  const std::string body = R"(
4191fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4192fd4e5da5Sopenharmony_ci%res1 = OpImageQueryFormat %u32 %img
4193fd4e5da5Sopenharmony_ci)";
4194fd4e5da5Sopenharmony_ci
4195fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4196fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4197fd4e5da5Sopenharmony_ci}
4198fd4e5da5Sopenharmony_ci
4199fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryFormatWrongResultType) {
4200fd4e5da5Sopenharmony_ci  const std::string body = R"(
4201fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4202fd4e5da5Sopenharmony_ci%res1 = OpImageQueryFormat %bool %img
4203fd4e5da5Sopenharmony_ci)";
4204fd4e5da5Sopenharmony_ci
4205fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4206fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4207fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4208fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int scalar type"));
4209fd4e5da5Sopenharmony_ci}
4210fd4e5da5Sopenharmony_ci
4211fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryFormatNotImage) {
4212fd4e5da5Sopenharmony_ci  const std::string body = R"(
4213fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4214fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4215fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4216fd4e5da5Sopenharmony_ci%res1 = OpImageQueryFormat %u32 %sampler
4217fd4e5da5Sopenharmony_ci)";
4218fd4e5da5Sopenharmony_ci
4219fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4220fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4221fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4222fd4e5da5Sopenharmony_ci              HasSubstr("Expected operand to be of type OpTypeImage"));
4223fd4e5da5Sopenharmony_ci}
4224fd4e5da5Sopenharmony_ci
4225fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryOrderSuccess) {
4226fd4e5da5Sopenharmony_ci  const std::string body = R"(
4227fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4228fd4e5da5Sopenharmony_ci%res1 = OpImageQueryOrder %u32 %img
4229fd4e5da5Sopenharmony_ci)";
4230fd4e5da5Sopenharmony_ci
4231fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4232fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4233fd4e5da5Sopenharmony_ci}
4234fd4e5da5Sopenharmony_ci
4235fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryOrderWrongResultType) {
4236fd4e5da5Sopenharmony_ci  const std::string body = R"(
4237fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4238fd4e5da5Sopenharmony_ci%res1 = OpImageQueryOrder %bool %img
4239fd4e5da5Sopenharmony_ci)";
4240fd4e5da5Sopenharmony_ci
4241fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4242fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4243fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4244fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int scalar type"));
4245fd4e5da5Sopenharmony_ci}
4246fd4e5da5Sopenharmony_ci
4247fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryOrderNotImage) {
4248fd4e5da5Sopenharmony_ci  const std::string body = R"(
4249fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4250fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4251fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4252fd4e5da5Sopenharmony_ci%res1 = OpImageQueryOrder %u32 %sampler
4253fd4e5da5Sopenharmony_ci)";
4254fd4e5da5Sopenharmony_ci
4255fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4256fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4257fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4258fd4e5da5Sopenharmony_ci              HasSubstr("Expected operand to be of type OpTypeImage"));
4259fd4e5da5Sopenharmony_ci}
4260fd4e5da5Sopenharmony_ci
4261fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLodSuccess) {
4262fd4e5da5Sopenharmony_ci  const std::string body = R"(
4263fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4264fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4265fd4e5da5Sopenharmony_ci)";
4266fd4e5da5Sopenharmony_ci
4267fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4268fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4269fd4e5da5Sopenharmony_ci}
4270fd4e5da5Sopenharmony_ci
4271fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLodWrongResultType) {
4272fd4e5da5Sopenharmony_ci  const std::string body = R"(
4273fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4274fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySizeLod %f32vec2 %img %u32_1
4275fd4e5da5Sopenharmony_ci)";
4276fd4e5da5Sopenharmony_ci
4277fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4278fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4279fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4280fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4281fd4e5da5Sopenharmony_ci      HasSubstr("Expected Result Type to be int scalar or vector type"));
4282fd4e5da5Sopenharmony_ci}
4283fd4e5da5Sopenharmony_ci
4284fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLodResultTypeWrongSize) {
4285fd4e5da5Sopenharmony_ci  const std::string body = R"(
4286fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4287fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySizeLod %u32 %img %u32_1
4288fd4e5da5Sopenharmony_ci)";
4289fd4e5da5Sopenharmony_ci
4290fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4291fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4292fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4293fd4e5da5Sopenharmony_ci              HasSubstr("Result Type has 1 components, but 2 expected"));
4294fd4e5da5Sopenharmony_ci}
4295fd4e5da5Sopenharmony_ci
4296fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLodNotImage) {
4297fd4e5da5Sopenharmony_ci  const std::string body = R"(
4298fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4299fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4300fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4301fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySizeLod %u32vec2 %sampler %u32_1
4302fd4e5da5Sopenharmony_ci)";
4303fd4e5da5Sopenharmony_ci
4304fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4305fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4306fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4307fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image to be of type OpTypeImage"));
4308fd4e5da5Sopenharmony_ci}
4309fd4e5da5Sopenharmony_ci
4310fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLodSampledImageDirectly) {
4311fd4e5da5Sopenharmony_ci  const std::string body = R"(
4312fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4313fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4314fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4315fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySizeLod %u32vec2 %simg %u32_1
4316fd4e5da5Sopenharmony_ci)";
4317fd4e5da5Sopenharmony_ci
4318fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4319fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4320fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4321fd4e5da5Sopenharmony_ci              HasSubstr("OpSampledImage instruction must not appear as operand "
4322fd4e5da5Sopenharmony_ci                        "for OpImageQuerySizeLod"));
4323fd4e5da5Sopenharmony_ci}
4324fd4e5da5Sopenharmony_ci
4325fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLodMultisampledError) {
4326fd4e5da5Sopenharmony_ci  const std::string body = R"(
4327fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4328fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4329fd4e5da5Sopenharmony_ci)";
4330fd4e5da5Sopenharmony_ci
4331fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4332fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4333fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 0"));
4334fd4e5da5Sopenharmony_ci}
4335fd4e5da5Sopenharmony_ci
4336fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLodNonSampledUniversalSuccess) {
4337fd4e5da5Sopenharmony_ci  const std::string body = R"(
4338fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4339fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4340fd4e5da5Sopenharmony_ci)";
4341fd4e5da5Sopenharmony_ci
4342fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4343fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4344fd4e5da5Sopenharmony_ci  EXPECT_EQ(getDiagnosticString(), "");
4345fd4e5da5Sopenharmony_ci}
4346fd4e5da5Sopenharmony_ci
4347fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLodVulkanNonSampledError) {
4348fd4e5da5Sopenharmony_ci  // Create a whole shader module.  Avoid Vulkan incompatibility with
4349fd4e5da5Sopenharmony_ci  // SampledRrect images inserted by helper function GenerateShaderCode.
4350fd4e5da5Sopenharmony_ci  const std::string body = R"(
4351fd4e5da5Sopenharmony_ciOpCapability Shader
4352fd4e5da5Sopenharmony_ciOpCapability ImageQuery
4353fd4e5da5Sopenharmony_ciOpMemoryModel Logical Simple
4354fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
4355fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
4356fd4e5da5Sopenharmony_ci
4357fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
4358fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
4359fd4e5da5Sopenharmony_ci%u32_0 = OpConstant %u32 0
4360fd4e5da5Sopenharmony_ci%u32vec2 = OpTypeVector %u32 2
4361fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4362fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
4363fd4e5da5Sopenharmony_ci
4364fd4e5da5Sopenharmony_ci; Test with a storage image.
4365fd4e5da5Sopenharmony_ci%type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4366fd4e5da5Sopenharmony_ci%ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
4367fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
4368fd4e5da5Sopenharmony_ci
4369fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
4370fd4e5da5Sopenharmony_ci%entry = OpLabel
4371fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4372fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySizeLod %u32vec2 %img %u32_0
4373fd4e5da5Sopenharmony_ciOpReturn
4374fd4e5da5Sopenharmony_ciOpFunctionEnd
4375fd4e5da5Sopenharmony_ci)";
4376fd4e5da5Sopenharmony_ci
4377fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
4378fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4379fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4380fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
4381fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4382fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4383fd4e5da5Sopenharmony_ci      HasSubstr(
4384fd4e5da5Sopenharmony_ci          "OpImageQuerySizeLod must only consume an \"Image\" operand whose "
4385fd4e5da5Sopenharmony_ci          "type has its \"Sampled\" operand set to 1"));
4386fd4e5da5Sopenharmony_ci}
4387fd4e5da5Sopenharmony_ci
4388fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLodWrongImageDim) {
4389fd4e5da5Sopenharmony_ci  const std::string body = R"(
4390fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4391fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4392fd4e5da5Sopenharmony_ci)";
4393fd4e5da5Sopenharmony_ci
4394fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4395fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4396fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4397fd4e5da5Sopenharmony_ci              HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4398fd4e5da5Sopenharmony_ci}
4399fd4e5da5Sopenharmony_ci
4400fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLodWrongLodType) {
4401fd4e5da5Sopenharmony_ci  const std::string body = R"(
4402fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4403fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySizeLod %u32vec2 %img %f32_0
4404fd4e5da5Sopenharmony_ci)";
4405fd4e5da5Sopenharmony_ci
4406fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4407fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4408fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4409fd4e5da5Sopenharmony_ci              HasSubstr("Expected Level of Detail to be int scalar"));
4410fd4e5da5Sopenharmony_ci}
4411fd4e5da5Sopenharmony_ci
4412fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeSuccess) {
4413fd4e5da5Sopenharmony_ci  const std::string body = R"(
4414fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4415fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySize %u32vec2 %img
4416fd4e5da5Sopenharmony_ci)";
4417fd4e5da5Sopenharmony_ci
4418fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4419fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4420fd4e5da5Sopenharmony_ci}
4421fd4e5da5Sopenharmony_ci
4422fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeWrongResultType) {
4423fd4e5da5Sopenharmony_ci  const std::string body = R"(
4424fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4425fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySize %f32vec2 %img
4426fd4e5da5Sopenharmony_ci)";
4427fd4e5da5Sopenharmony_ci
4428fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4429fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4430fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4431fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4432fd4e5da5Sopenharmony_ci      HasSubstr("Expected Result Type to be int scalar or vector type"));
4433fd4e5da5Sopenharmony_ci}
4434fd4e5da5Sopenharmony_ci
4435fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeNotImage) {
4436fd4e5da5Sopenharmony_ci  const std::string body = R"(
4437fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4438fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4439fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4440fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySize %u32vec2 %sampler
4441fd4e5da5Sopenharmony_ci)";
4442fd4e5da5Sopenharmony_ci
4443fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4444fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4445fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4446fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image to be of type OpTypeImage"));
4447fd4e5da5Sopenharmony_ci}
4448fd4e5da5Sopenharmony_ci
4449fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeSampledImageDirectly) {
4450fd4e5da5Sopenharmony_ci  const std::string body = R"(
4451fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4452fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4453fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4454fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySize %u32vec2 %simg
4455fd4e5da5Sopenharmony_ci)";
4456fd4e5da5Sopenharmony_ci
4457fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4458fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4459fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4460fd4e5da5Sopenharmony_ci              HasSubstr("OpSampledImage instruction must not appear as operand "
4461fd4e5da5Sopenharmony_ci                        "for OpImageQuerySize"));
4462fd4e5da5Sopenharmony_ci}
4463fd4e5da5Sopenharmony_ci
4464fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeDimSubpassDataBad) {
4465fd4e5da5Sopenharmony_ci  const std::string body = R"(
4466fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
4467fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySize %u32vec2 %img
4468fd4e5da5Sopenharmony_ci)";
4469fd4e5da5Sopenharmony_ci
4470fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4471fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4472fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4473fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4474fd4e5da5Sopenharmony_ci      HasSubstr("Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"));
4475fd4e5da5Sopenharmony_ci}
4476fd4e5da5Sopenharmony_ci
4477fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeWrongSampling) {
4478fd4e5da5Sopenharmony_ci  const std::string body = R"(
4479fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4480fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySize %u32vec2 %img
4481fd4e5da5Sopenharmony_ci)";
4482fd4e5da5Sopenharmony_ci
4483fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4484fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4485fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4486fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4487fd4e5da5Sopenharmony_ci      HasSubstr("Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"));
4488fd4e5da5Sopenharmony_ci}
4489fd4e5da5Sopenharmony_ci
4490fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeWrongNumberOfComponents) {
4491fd4e5da5Sopenharmony_ci  const std::string body = R"(
4492fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
4493fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySize %u32vec2 %img
4494fd4e5da5Sopenharmony_ci)";
4495fd4e5da5Sopenharmony_ci
4496fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4497fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4498fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4499fd4e5da5Sopenharmony_ci              HasSubstr("Result Type has 2 components, but 4 expected"));
4500fd4e5da5Sopenharmony_ci}
4501fd4e5da5Sopenharmony_ci
4502fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodSuccessKernel) {
4503fd4e5da5Sopenharmony_ci  const std::string body = R"(
4504fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4505fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4506fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4507fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4508fd4e5da5Sopenharmony_ci%res2 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
4509fd4e5da5Sopenharmony_ci)";
4510fd4e5da5Sopenharmony_ci
4511fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4512fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4513fd4e5da5Sopenharmony_ci}
4514fd4e5da5Sopenharmony_ci
4515fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodSuccessShader) {
4516fd4e5da5Sopenharmony_ci  const std::string body = R"(
4517fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4518fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4519fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4520fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4521fd4e5da5Sopenharmony_ci)";
4522fd4e5da5Sopenharmony_ci
4523fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4524fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4525fd4e5da5Sopenharmony_ci}
4526fd4e5da5Sopenharmony_ci
4527fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodWrongResultType) {
4528fd4e5da5Sopenharmony_ci  const std::string body = R"(
4529fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4530fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4531fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4532fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %u32vec2 %simg %f32vec2_hh
4533fd4e5da5Sopenharmony_ci)";
4534fd4e5da5Sopenharmony_ci
4535fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4536fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4537fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4538fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be float vector type"));
4539fd4e5da5Sopenharmony_ci}
4540fd4e5da5Sopenharmony_ci
4541fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodResultTypeWrongSize) {
4542fd4e5da5Sopenharmony_ci  const std::string body = R"(
4543fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4544fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4545fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4546fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec3 %simg %f32vec2_hh
4547fd4e5da5Sopenharmony_ci)";
4548fd4e5da5Sopenharmony_ci
4549fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4550fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4551fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4552fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to have 2 components"));
4553fd4e5da5Sopenharmony_ci}
4554fd4e5da5Sopenharmony_ci
4555fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodNotSampledImage) {
4556fd4e5da5Sopenharmony_ci  const std::string body = R"(
4557fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4558fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %img %f32vec2_hh
4559fd4e5da5Sopenharmony_ci)";
4560fd4e5da5Sopenharmony_ci
4561fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4562fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4563fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4564fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4565fd4e5da5Sopenharmony_ci      HasSubstr("Expected Image operand to be of type OpTypeSampledImage"));
4566fd4e5da5Sopenharmony_ci}
4567fd4e5da5Sopenharmony_ci
4568fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodWrongDim) {
4569fd4e5da5Sopenharmony_ci  const std::string body = R"(
4570fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4571fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4572fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
4573fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4574fd4e5da5Sopenharmony_ci)";
4575fd4e5da5Sopenharmony_ci
4576fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4577fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4578fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4579fd4e5da5Sopenharmony_ci              HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4580fd4e5da5Sopenharmony_ci}
4581fd4e5da5Sopenharmony_ci
4582fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodWrongCoordinateType) {
4583fd4e5da5Sopenharmony_ci  const std::string body = R"(
4584fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4585fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4586fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4587fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
4588fd4e5da5Sopenharmony_ci)";
4589fd4e5da5Sopenharmony_ci
4590fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4591fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4592fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4593fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to be float scalar or vector"));
4594fd4e5da5Sopenharmony_ci}
4595fd4e5da5Sopenharmony_ci
4596fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodCoordinateSizeTooSmall) {
4597fd4e5da5Sopenharmony_ci  const std::string body = R"(
4598fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4599fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4600fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4601fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %f32_0
4602fd4e5da5Sopenharmony_ci)";
4603fd4e5da5Sopenharmony_ci
4604fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4605fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4606fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4607fd4e5da5Sopenharmony_ci              HasSubstr("Expected Coordinate to have at least 2 components, "
4608fd4e5da5Sopenharmony_ci                        "but given only 1"));
4609fd4e5da5Sopenharmony_ci}
4610fd4e5da5Sopenharmony_ci
4611fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLevelsSuccess) {
4612fd4e5da5Sopenharmony_ci  const std::string body = R"(
4613fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4614fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLevels %u32 %img
4615fd4e5da5Sopenharmony_ci)";
4616fd4e5da5Sopenharmony_ci
4617fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4618fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4619fd4e5da5Sopenharmony_ci}
4620fd4e5da5Sopenharmony_ci
4621fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLevelsWrongResultType) {
4622fd4e5da5Sopenharmony_ci  const std::string body = R"(
4623fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4624fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLevels %f32 %img
4625fd4e5da5Sopenharmony_ci)";
4626fd4e5da5Sopenharmony_ci
4627fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4628fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4629fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4630fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be int scalar type"));
4631fd4e5da5Sopenharmony_ci}
4632fd4e5da5Sopenharmony_ci
4633fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLevelsNotImage) {
4634fd4e5da5Sopenharmony_ci  const std::string body = R"(
4635fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4636fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4637fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4638fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLevels %u32 %sampler
4639fd4e5da5Sopenharmony_ci)";
4640fd4e5da5Sopenharmony_ci
4641fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4642fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4643fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4644fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image to be of type OpTypeImage"));
4645fd4e5da5Sopenharmony_ci}
4646fd4e5da5Sopenharmony_ci
4647fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLevelsSampledImageDirectly) {
4648fd4e5da5Sopenharmony_ci  const std::string body = R"(
4649fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4650fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4651fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4652fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLevels %u32 %simg
4653fd4e5da5Sopenharmony_ci)";
4654fd4e5da5Sopenharmony_ci
4655fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4656fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4657fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4658fd4e5da5Sopenharmony_ci              HasSubstr("OpSampledImage instruction must not appear as operand "
4659fd4e5da5Sopenharmony_ci                        "for OpImageQueryLevels"));
4660fd4e5da5Sopenharmony_ci}
4661fd4e5da5Sopenharmony_ci
4662fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLevelsWrongDim) {
4663fd4e5da5Sopenharmony_ci  const std::string body = R"(
4664fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4665fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLevels %u32 %img
4666fd4e5da5Sopenharmony_ci)";
4667fd4e5da5Sopenharmony_ci
4668fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4669fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4670fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4671fd4e5da5Sopenharmony_ci              HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4672fd4e5da5Sopenharmony_ci}
4673fd4e5da5Sopenharmony_ci
4674fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLevelsNonSampledUniversalSuccess) {
4675fd4e5da5Sopenharmony_ci  const std::string body = R"(
4676fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4677fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLevels %u32 %img
4678fd4e5da5Sopenharmony_ci)";
4679fd4e5da5Sopenharmony_ci
4680fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
4681fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4682fd4e5da5Sopenharmony_ci  EXPECT_EQ(getDiagnosticString(), "");
4683fd4e5da5Sopenharmony_ci}
4684fd4e5da5Sopenharmony_ci
4685fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySizeLevelsVulkanNonSampledError) {
4686fd4e5da5Sopenharmony_ci  // Create a whole shader module.  Avoid Vulkan incompatibility with
4687fd4e5da5Sopenharmony_ci  // SampledRrect images inserted by helper function GenerateShaderCode.
4688fd4e5da5Sopenharmony_ci  const std::string body = R"(
4689fd4e5da5Sopenharmony_ciOpCapability Shader
4690fd4e5da5Sopenharmony_ciOpCapability ImageQuery
4691fd4e5da5Sopenharmony_ciOpMemoryModel Logical Simple
4692fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
4693fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
4694fd4e5da5Sopenharmony_ci
4695fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
4696fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
4697fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4698fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
4699fd4e5da5Sopenharmony_ci
4700fd4e5da5Sopenharmony_ci; Test with a storage image.
4701fd4e5da5Sopenharmony_ci%type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4702fd4e5da5Sopenharmony_ci%ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
4703fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
4704fd4e5da5Sopenharmony_ci
4705fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
4706fd4e5da5Sopenharmony_ci%entry = OpLabel
4707fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4708fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLevels %u32 %img
4709fd4e5da5Sopenharmony_ciOpReturn
4710fd4e5da5Sopenharmony_ciOpFunctionEnd
4711fd4e5da5Sopenharmony_ci)";
4712fd4e5da5Sopenharmony_ci
4713fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
4714fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4715fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4716fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
4717fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4718fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4719fd4e5da5Sopenharmony_ci      HasSubstr("OpImageQueryLevels must only consume an \"Image\" operand "
4720fd4e5da5Sopenharmony_ci                "whose type has its \"Sampled\" operand set to 1"));
4721fd4e5da5Sopenharmony_ci}
4722fd4e5da5Sopenharmony_ci
4723fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySamplesSuccess) {
4724fd4e5da5Sopenharmony_ci  const std::string body = R"(
4725fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4726fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySamples %u32 %img
4727fd4e5da5Sopenharmony_ci)";
4728fd4e5da5Sopenharmony_ci
4729fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4730fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4731fd4e5da5Sopenharmony_ci}
4732fd4e5da5Sopenharmony_ci
4733fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySamplesNot2D) {
4734fd4e5da5Sopenharmony_ci  const std::string body = R"(
4735fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_3d_0011 %uniform_image_f32_3d_0011
4736fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySamples %u32 %img
4737fd4e5da5Sopenharmony_ci)";
4738fd4e5da5Sopenharmony_ci
4739fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4740fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4741fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' must be 2D"));
4742fd4e5da5Sopenharmony_ci}
4743fd4e5da5Sopenharmony_ci
4744fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QuerySamplesNotMultisampled) {
4745fd4e5da5Sopenharmony_ci  const std::string body = R"(
4746fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4747fd4e5da5Sopenharmony_ci%res1 = OpImageQuerySamples %u32 %img
4748fd4e5da5Sopenharmony_ci)";
4749fd4e5da5Sopenharmony_ci
4750fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateKernelCode(body).c_str());
4751fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4752fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 1"));
4753fd4e5da5Sopenharmony_ci}
4754fd4e5da5Sopenharmony_ci
4755fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodWrongExecutionModel) {
4756fd4e5da5Sopenharmony_ci  const std::string body = R"(
4757fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4758fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4759fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4760fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4761fd4e5da5Sopenharmony_ci)";
4762fd4e5da5Sopenharmony_ci
4763fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4764fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4765fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4766fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4767fd4e5da5Sopenharmony_ci      HasSubstr(
4768fd4e5da5Sopenharmony_ci          "OpImageQueryLod requires Fragment or GLCompute execution model"));
4769fd4e5da5Sopenharmony_ci}
4770fd4e5da5Sopenharmony_ci
4771fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) {
4772fd4e5da5Sopenharmony_ci  const std::string body = R"(
4773fd4e5da5Sopenharmony_ci%call_ret = OpFunctionCall %void %my_func
4774fd4e5da5Sopenharmony_ciOpReturn
4775fd4e5da5Sopenharmony_ciOpFunctionEnd
4776fd4e5da5Sopenharmony_ci%my_func = OpFunction %void None %func
4777fd4e5da5Sopenharmony_ci%my_func_entry = OpLabel
4778fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4779fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4780fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4781fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4782fd4e5da5Sopenharmony_ci)";
4783fd4e5da5Sopenharmony_ci
4784fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4785fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4786fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4787fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4788fd4e5da5Sopenharmony_ci      HasSubstr(
4789fd4e5da5Sopenharmony_ci          "OpImageQueryLod requires Fragment or GLCompute execution model"));
4790fd4e5da5Sopenharmony_ci}
4791fd4e5da5Sopenharmony_ci
4792fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodComputeShaderDerivatives) {
4793fd4e5da5Sopenharmony_ci  const std::string body = R"(
4794fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4795fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4796fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4797fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4798fd4e5da5Sopenharmony_ci)";
4799fd4e5da5Sopenharmony_ci
4800fd4e5da5Sopenharmony_ci  const std::string extra = R"(
4801fd4e5da5Sopenharmony_ciOpCapability ComputeDerivativeGroupLinearNV
4802fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_compute_shader_derivatives"
4803fd4e5da5Sopenharmony_ci)";
4804fd4e5da5Sopenharmony_ci  const std::string mode = R"(
4805fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 8 8 1
4806fd4e5da5Sopenharmony_ciOpExecutionMode %main DerivativeGroupLinearNV
4807fd4e5da5Sopenharmony_ci)";
4808fd4e5da5Sopenharmony_ci  CompileSuccessfully(
4809fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4810fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4811fd4e5da5Sopenharmony_ci}
4812fd4e5da5Sopenharmony_ci
4813fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodUniversalSuccess) {
4814fd4e5da5Sopenharmony_ci  // Create a whole shader module.  Avoid Vulkan incompatibility with
4815fd4e5da5Sopenharmony_ci  // SampledRrect images inserted by helper function GenerateShaderCode.
4816fd4e5da5Sopenharmony_ci  const std::string body = R"(
4817fd4e5da5Sopenharmony_ciOpCapability Shader
4818fd4e5da5Sopenharmony_ciOpCapability ImageQuery
4819fd4e5da5Sopenharmony_ciOpMemoryModel Logical Simple
4820fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
4821fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
4822fd4e5da5Sopenharmony_ci
4823fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_2d_0000 DescriptorSet 0
4824fd4e5da5Sopenharmony_ciOpDecorate %uniform_image_f32_2d_0000 Binding 0
4825fd4e5da5Sopenharmony_ciOpDecorate %sampler DescriptorSet 0
4826fd4e5da5Sopenharmony_ciOpDecorate %sampler Binding 1
4827fd4e5da5Sopenharmony_ci
4828fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
4829fd4e5da5Sopenharmony_ci%f32vec2 = OpTypeVector %f32 2
4830fd4e5da5Sopenharmony_ci%f32vec2_null = OpConstantNull %f32vec2
4831fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
4832fd4e5da5Sopenharmony_ci%u32vec2 = OpTypeVector %u32 2
4833fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4834fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
4835fd4e5da5Sopenharmony_ci
4836fd4e5da5Sopenharmony_ci; Test with an image with sampled = 0
4837fd4e5da5Sopenharmony_ci%type_image_f32_2d_0000 = OpTypeImage %f32 2D 0 0 0 0 Rgba32f
4838fd4e5da5Sopenharmony_ci%ptr_image_f32_2d_0000 = OpTypePointer UniformConstant %type_image_f32_2d_0000
4839fd4e5da5Sopenharmony_ci%uniform_image_f32_2d_0000 = OpVariable %ptr_image_f32_2d_0000 UniformConstant
4840fd4e5da5Sopenharmony_ci%sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0000
4841fd4e5da5Sopenharmony_ci
4842fd4e5da5Sopenharmony_ci%sampler_ty = OpTypeSampler
4843fd4e5da5Sopenharmony_ci%ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
4844fd4e5da5Sopenharmony_ci%sampler = OpVariable %ptr_sampler_ty UniformConstant
4845fd4e5da5Sopenharmony_ci
4846fd4e5da5Sopenharmony_ci
4847fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
4848fd4e5da5Sopenharmony_ci%entry = OpLabel
4849fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0000 %uniform_image_f32_2d_0000
4850fd4e5da5Sopenharmony_ci%s = OpLoad %sampler_ty %sampler
4851fd4e5da5Sopenharmony_ci%simg = OpSampledImage %sampled_image_ty %img %s
4852fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
4853fd4e5da5Sopenharmony_ciOpReturn
4854fd4e5da5Sopenharmony_ciOpFunctionEnd
4855fd4e5da5Sopenharmony_ci)";
4856fd4e5da5Sopenharmony_ci
4857fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
4858fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4859fd4e5da5Sopenharmony_ci}
4860fd4e5da5Sopenharmony_ci
4861fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodVulkanNonSampledError) {
4862fd4e5da5Sopenharmony_ci  // Create a whole shader module.  Avoid Vulkan incompatibility with
4863fd4e5da5Sopenharmony_ci  // SampledRrect images inserted by helper function GenerateShaderCode.
4864fd4e5da5Sopenharmony_ci  const std::string body = R"(
4865fd4e5da5Sopenharmony_ciOpCapability Shader
4866fd4e5da5Sopenharmony_ciOpCapability ImageQuery
4867fd4e5da5Sopenharmony_ciOpMemoryModel Logical Simple
4868fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
4869fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
4870fd4e5da5Sopenharmony_ci
4871fd4e5da5Sopenharmony_ciOpDecorate %sampled_image DescriptorSet 0
4872fd4e5da5Sopenharmony_ciOpDecorate %sampled_image Binding 0
4873fd4e5da5Sopenharmony_ci
4874fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
4875fd4e5da5Sopenharmony_ci%f32vec2 = OpTypeVector %f32 2
4876fd4e5da5Sopenharmony_ci%f32vec2_null = OpConstantNull %f32vec2
4877fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
4878fd4e5da5Sopenharmony_ci%u32vec2 = OpTypeVector %u32 2
4879fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4880fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
4881fd4e5da5Sopenharmony_ci
4882fd4e5da5Sopenharmony_ci; Test with an image with Sampled = 2
4883fd4e5da5Sopenharmony_ci; In Vulkan it Sampled must be 1 or 2, checked in another part of the
4884fd4e5da5Sopenharmony_ci; validation flow.
4885fd4e5da5Sopenharmony_ci%type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4886fd4e5da5Sopenharmony_ci
4887fd4e5da5Sopenharmony_ci; Expect to fail here.
4888fd4e5da5Sopenharmony_ci%sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0002
4889fd4e5da5Sopenharmony_ci%ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
4890fd4e5da5Sopenharmony_ci%sampled_image = OpVariable %ptr_sampled_image_ty UniformConstant
4891fd4e5da5Sopenharmony_ci
4892fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
4893fd4e5da5Sopenharmony_ci%entry = OpLabel
4894fd4e5da5Sopenharmony_ci%simg = OpLoad %sampled_image_ty %sampled_image
4895fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
4896fd4e5da5Sopenharmony_ciOpReturn
4897fd4e5da5Sopenharmony_ciOpFunctionEnd
4898fd4e5da5Sopenharmony_ci)";
4899fd4e5da5Sopenharmony_ci
4900fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
4901fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4902fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4903fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
4904fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4905fd4e5da5Sopenharmony_ci              HasSubstr("Sampled image type requires an image type with "
4906fd4e5da5Sopenharmony_ci                        "\"Sampled\" operand set to 0 or 1"));
4907fd4e5da5Sopenharmony_ci}
4908fd4e5da5Sopenharmony_ci
4909fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QueryLodComputeShaderDerivativesMissingMode) {
4910fd4e5da5Sopenharmony_ci  const std::string body = R"(
4911fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4912fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4913fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4914fd4e5da5Sopenharmony_ci%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4915fd4e5da5Sopenharmony_ci)";
4916fd4e5da5Sopenharmony_ci
4917fd4e5da5Sopenharmony_ci  const std::string extra = R"(
4918fd4e5da5Sopenharmony_ciOpCapability ComputeDerivativeGroupLinearNV
4919fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_compute_shader_derivatives"
4920fd4e5da5Sopenharmony_ci)";
4921fd4e5da5Sopenharmony_ci  const std::string mode = R"(
4922fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 8 8 1
4923fd4e5da5Sopenharmony_ci)";
4924fd4e5da5Sopenharmony_ci  CompileSuccessfully(
4925fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4926fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4927fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4928fd4e5da5Sopenharmony_ci              HasSubstr("OpImageQueryLod requires DerivativeGroupQuadsNV or "
4929fd4e5da5Sopenharmony_ci                        "DerivativeGroupLinearNV execution mode for GLCompute "
4930fd4e5da5Sopenharmony_ci                        "execution model"));
4931fd4e5da5Sopenharmony_ci}
4932fd4e5da5Sopenharmony_ci
4933fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
4934fd4e5da5Sopenharmony_ci  const std::string body = R"(
4935fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4936fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4937fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4938fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4939fd4e5da5Sopenharmony_ci)";
4940fd4e5da5Sopenharmony_ci
4941fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4942fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4943fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4944fd4e5da5Sopenharmony_ci              HasSubstr("ImplicitLod instructions require Fragment or "
4945fd4e5da5Sopenharmony_ci                        "GLCompute execution model"));
4946fd4e5da5Sopenharmony_ci}
4947fd4e5da5Sopenharmony_ci
4948fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImplicitLodComputeShaderDerivatives) {
4949fd4e5da5Sopenharmony_ci  const std::string body = R"(
4950fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4951fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4952fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4953fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4954fd4e5da5Sopenharmony_ci)";
4955fd4e5da5Sopenharmony_ci
4956fd4e5da5Sopenharmony_ci  const std::string extra = R"(
4957fd4e5da5Sopenharmony_ciOpCapability ComputeDerivativeGroupLinearNV
4958fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_compute_shader_derivatives"
4959fd4e5da5Sopenharmony_ci)";
4960fd4e5da5Sopenharmony_ci  const std::string mode = R"(
4961fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 8 8 1
4962fd4e5da5Sopenharmony_ciOpExecutionMode %main DerivativeGroupLinearNV
4963fd4e5da5Sopenharmony_ci)";
4964fd4e5da5Sopenharmony_ci  CompileSuccessfully(
4965fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4966fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4967fd4e5da5Sopenharmony_ci}
4968fd4e5da5Sopenharmony_ci
4969fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImplicitLodComputeShaderDerivativesMissingMode) {
4970fd4e5da5Sopenharmony_ci  const std::string body = R"(
4971fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4972fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
4973fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4974fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4975fd4e5da5Sopenharmony_ci)";
4976fd4e5da5Sopenharmony_ci
4977fd4e5da5Sopenharmony_ci  const std::string extra = R"(
4978fd4e5da5Sopenharmony_ciOpCapability ComputeDerivativeGroupLinearNV
4979fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_compute_shader_derivatives"
4980fd4e5da5Sopenharmony_ci)";
4981fd4e5da5Sopenharmony_ci  const std::string mode = R"(
4982fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 8 8 1
4983fd4e5da5Sopenharmony_ci)";
4984fd4e5da5Sopenharmony_ci  CompileSuccessfully(
4985fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4986fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4987fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4988fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4989fd4e5da5Sopenharmony_ci      HasSubstr("ImplicitLod instructions require DerivativeGroupQuadsNV or "
4990fd4e5da5Sopenharmony_ci                "DerivativeGroupLinearNV execution mode for GLCompute "
4991fd4e5da5Sopenharmony_ci                "execution model"));
4992fd4e5da5Sopenharmony_ci}
4993fd4e5da5Sopenharmony_ci
4994fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
4995fd4e5da5Sopenharmony_ci  const std::string body = R"(
4996fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
4997fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec2_01
4998fd4e5da5Sopenharmony_ci)";
4999fd4e5da5Sopenharmony_ci
5000fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5001fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Vertex").c_str());
5002fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5003fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5004fd4e5da5Sopenharmony_ci              HasSubstr("Dim SubpassData requires Fragment execution model"));
5005fd4e5da5Sopenharmony_ci}
5006fd4e5da5Sopenharmony_ci
5007fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleImplicitLodSuccess) {
5008fd4e5da5Sopenharmony_ci  const std::string body = R"(
5009fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5010fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5011fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5012fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh
5013fd4e5da5Sopenharmony_ci%res2 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Bias %f32_0_25
5014fd4e5da5Sopenharmony_ci%res4 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
5015fd4e5da5Sopenharmony_ci%res5 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
5016fd4e5da5Sopenharmony_ci%res6 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
5017fd4e5da5Sopenharmony_ci%res7 = OpImageSparseSampleImplicitLod %struct_u64_f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
5018fd4e5da5Sopenharmony_ci%res8 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
5019fd4e5da5Sopenharmony_ci)";
5020fd4e5da5Sopenharmony_ci
5021fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5022fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5023fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5024fd4e5da5Sopenharmony_ci)";
5025fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5026fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5027fd4e5da5Sopenharmony_ci                          .c_str());
5028fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5029fd4e5da5Sopenharmony_ci}
5030fd4e5da5Sopenharmony_ci
5031fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotStruct) {
5032fd4e5da5Sopenharmony_ci  const std::string body = R"(
5033fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5034fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5035fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5036fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleImplicitLod %f32 %simg %f32vec2_hh
5037fd4e5da5Sopenharmony_ci)";
5038fd4e5da5Sopenharmony_ci
5039fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5040fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5041fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5042fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypeStruct"));
5043fd4e5da5Sopenharmony_ci}
5044fd4e5da5Sopenharmony_ci
5045fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers1) {
5046fd4e5da5Sopenharmony_ci  const std::string body = R"(
5047fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5048fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5049fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5050fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleImplicitLod %struct_u32 %simg %f32vec2_hh
5051fd4e5da5Sopenharmony_ci)";
5052fd4e5da5Sopenharmony_ci
5053fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5054fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5055fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5056fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an int "
5057fd4e5da5Sopenharmony_ci                        "scalar and a texel"));
5058fd4e5da5Sopenharmony_ci}
5059fd4e5da5Sopenharmony_ci
5060fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers2) {
5061fd4e5da5Sopenharmony_ci  const std::string body = R"(
5062fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5063fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5064fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5065fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4_u32 %simg %f32vec2_hh
5066fd4e5da5Sopenharmony_ci)";
5067fd4e5da5Sopenharmony_ci
5068fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5069fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5070fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5071fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an "
5072fd4e5da5Sopenharmony_ci                        "int scalar and a texel"));
5073fd4e5da5Sopenharmony_ci}
5074fd4e5da5Sopenharmony_ci
5075fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleImplicitLodResultTypeFirstMemberNotInt) {
5076fd4e5da5Sopenharmony_ci  const std::string body = R"(
5077fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5078fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5079fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5080fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleImplicitLod %struct_f32_f32vec4 %simg %f32vec2_hh
5081fd4e5da5Sopenharmony_ci)";
5082fd4e5da5Sopenharmony_ci
5083fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5084fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5085fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5086fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an "
5087fd4e5da5Sopenharmony_ci                        "int scalar and a texel"));
5088fd4e5da5Sopenharmony_ci}
5089fd4e5da5Sopenharmony_ci
5090fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleImplicitLodResultTypeTexelNotVector) {
5091fd4e5da5Sopenharmony_ci  const std::string body = R"(
5092fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5093fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5094fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5095fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleImplicitLod %struct_u32_u32 %simg %f32vec2_hh
5096fd4e5da5Sopenharmony_ci)";
5097fd4e5da5Sopenharmony_ci
5098fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5099fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5100fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5101fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type's second member to be int or "
5102fd4e5da5Sopenharmony_ci                        "float vector type"));
5103fd4e5da5Sopenharmony_ci}
5104fd4e5da5Sopenharmony_ci
5105fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleImplicitLodWrongNumComponentsTexel) {
5106fd4e5da5Sopenharmony_ci  const std::string body = R"(
5107fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5108fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5109fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5110fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec3 %simg %f32vec2_hh
5111fd4e5da5Sopenharmony_ci)";
5112fd4e5da5Sopenharmony_ci
5113fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5114fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5115fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5116fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type's second member to have 4 "
5117fd4e5da5Sopenharmony_ci                        "components"));
5118fd4e5da5Sopenharmony_ci}
5119fd4e5da5Sopenharmony_ci
5120fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleImplicitLodWrongComponentTypeTexel) {
5121fd4e5da5Sopenharmony_ci  const std::string body = R"(
5122fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5123fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5124fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5125fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleImplicitLod %struct_u32_u32vec4 %simg %f32vec2_hh
5126fd4e5da5Sopenharmony_ci)";
5127fd4e5da5Sopenharmony_ci
5128fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5129fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5130fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5131fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
5132fd4e5da5Sopenharmony_ci                        "Result Type's second member components"));
5133fd4e5da5Sopenharmony_ci}
5134fd4e5da5Sopenharmony_ci
5135fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) {
5136fd4e5da5Sopenharmony_ci  const std::string body = R"(
5137fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
5138fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5139fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
5140fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
5141fd4e5da5Sopenharmony_ci%res2 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
5142fd4e5da5Sopenharmony_ci%res4 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
5143fd4e5da5Sopenharmony_ci%res5 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
5144fd4e5da5Sopenharmony_ci%res6 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
5145fd4e5da5Sopenharmony_ci%res7 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
5146fd4e5da5Sopenharmony_ci%res8 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
5147fd4e5da5Sopenharmony_ci)";
5148fd4e5da5Sopenharmony_ci
5149fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5150fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5151fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5152fd4e5da5Sopenharmony_ci)";
5153fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5154fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5155fd4e5da5Sopenharmony_ci                          .c_str());
5156fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5157fd4e5da5Sopenharmony_ci}
5158fd4e5da5Sopenharmony_ci
5159fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotStruct) {
5160fd4e5da5Sopenharmony_ci  const std::string body = R"(
5161fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5162fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5163fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5164fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1
5165fd4e5da5Sopenharmony_ci)";
5166fd4e5da5Sopenharmony_ci
5167fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5168fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5169fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5170fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypeStruct"));
5171fd4e5da5Sopenharmony_ci}
5172fd4e5da5Sopenharmony_ci
5173fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers1) {
5174fd4e5da5Sopenharmony_ci  const std::string body = R"(
5175fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5176fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5177fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5178fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleDrefImplicitLod %struct_u32 %simg %f32vec2_hh %f32_1
5179fd4e5da5Sopenharmony_ci)";
5180fd4e5da5Sopenharmony_ci
5181fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5182fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5183fd4e5da5Sopenharmony_ci  EXPECT_THAT(
5184fd4e5da5Sopenharmony_ci      getDiagnosticString(),
5185fd4e5da5Sopenharmony_ci      HasSubstr("Expected Result Type to be a struct containing an int scalar "
5186fd4e5da5Sopenharmony_ci                "and a texel"));
5187fd4e5da5Sopenharmony_ci}
5188fd4e5da5Sopenharmony_ci
5189fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers2) {
5190fd4e5da5Sopenharmony_ci  const std::string body = R"(
5191fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5192fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5193fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5194fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_f32_u32 %simg %f32vec2_hh %f32_1
5195fd4e5da5Sopenharmony_ci)";
5196fd4e5da5Sopenharmony_ci
5197fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5198fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5199fd4e5da5Sopenharmony_ci  EXPECT_THAT(
5200fd4e5da5Sopenharmony_ci      getDiagnosticString(),
5201fd4e5da5Sopenharmony_ci      HasSubstr("Expected Result Type to be a struct containing an int scalar "
5202fd4e5da5Sopenharmony_ci                "and a texel"));
5203fd4e5da5Sopenharmony_ci}
5204fd4e5da5Sopenharmony_ci
5205fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt) {
5206fd4e5da5Sopenharmony_ci  const std::string body = R"(
5207fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5208fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5209fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5210fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleDrefImplicitLod %struct_f32_f32 %simg %f32vec2_hh %f32_1
5211fd4e5da5Sopenharmony_ci)";
5212fd4e5da5Sopenharmony_ci
5213fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5214fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5215fd4e5da5Sopenharmony_ci  EXPECT_THAT(
5216fd4e5da5Sopenharmony_ci      getDiagnosticString(),
5217fd4e5da5Sopenharmony_ci      HasSubstr("Expected Result Type to be a struct containing an int scalar "
5218fd4e5da5Sopenharmony_ci                "and a texel"));
5219fd4e5da5Sopenharmony_ci}
5220fd4e5da5Sopenharmony_ci
5221fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseSampleDrefImplicitLodDifferentSampledType) {
5222fd4e5da5Sopenharmony_ci  const std::string body = R"(
5223fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5224fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5225fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5226fd4e5da5Sopenharmony_ci%res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
5227fd4e5da5Sopenharmony_ci)";
5228fd4e5da5Sopenharmony_ci
5229fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5230fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5231fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5232fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
5233fd4e5da5Sopenharmony_ci                        "Result Type's second member"));
5234fd4e5da5Sopenharmony_ci}
5235fd4e5da5Sopenharmony_ci
5236fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseFetchSuccess) {
5237fd4e5da5Sopenharmony_ci  const std::string body = R"(
5238fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
5239fd4e5da5Sopenharmony_ci%res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
5240fd4e5da5Sopenharmony_ci%res2 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
5241fd4e5da5Sopenharmony_ci)";
5242fd4e5da5Sopenharmony_ci
5243fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5244fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5245fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5246fd4e5da5Sopenharmony_ci)";
5247fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5248fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5249fd4e5da5Sopenharmony_ci                          .c_str());
5250fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5251fd4e5da5Sopenharmony_ci}
5252fd4e5da5Sopenharmony_ci
5253fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseFetchResultTypeNotStruct) {
5254fd4e5da5Sopenharmony_ci  const std::string body = R"(
5255fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5256fd4e5da5Sopenharmony_ci%res1 = OpImageSparseFetch %f32 %img %u32vec2_01
5257fd4e5da5Sopenharmony_ci)";
5258fd4e5da5Sopenharmony_ci
5259fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5260fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5261fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5262fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypeStruct"));
5263fd4e5da5Sopenharmony_ci}
5264fd4e5da5Sopenharmony_ci
5265fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers1) {
5266fd4e5da5Sopenharmony_ci  const std::string body = R"(
5267fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5268fd4e5da5Sopenharmony_ci%res1 = OpImageSparseFetch %struct_u32 %img %u32vec2_01
5269fd4e5da5Sopenharmony_ci)";
5270fd4e5da5Sopenharmony_ci
5271fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5272fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5273fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5274fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an "
5275fd4e5da5Sopenharmony_ci                        "int scalar and a texel"));
5276fd4e5da5Sopenharmony_ci}
5277fd4e5da5Sopenharmony_ci
5278fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers2) {
5279fd4e5da5Sopenharmony_ci  const std::string body = R"(
5280fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5281fd4e5da5Sopenharmony_ci%res1 = OpImageSparseFetch %struct_u32_f32vec4_u32 %img %u32vec2_01
5282fd4e5da5Sopenharmony_ci)";
5283fd4e5da5Sopenharmony_ci
5284fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5285fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5286fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5287fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an "
5288fd4e5da5Sopenharmony_ci                        "int scalar and a texel"));
5289fd4e5da5Sopenharmony_ci}
5290fd4e5da5Sopenharmony_ci
5291fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseFetchResultTypeFirstMemberNotInt) {
5292fd4e5da5Sopenharmony_ci  const std::string body = R"(
5293fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5294fd4e5da5Sopenharmony_ci%res1 = OpImageSparseFetch %struct_f32_f32vec4 %img %u32vec2_01
5295fd4e5da5Sopenharmony_ci)";
5296fd4e5da5Sopenharmony_ci
5297fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5298fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5299fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5300fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an "
5301fd4e5da5Sopenharmony_ci                        "int scalar and a texel"));
5302fd4e5da5Sopenharmony_ci}
5303fd4e5da5Sopenharmony_ci
5304fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseFetchResultTypeTexelNotVector) {
5305fd4e5da5Sopenharmony_ci  const std::string body = R"(
5306fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5307fd4e5da5Sopenharmony_ci%res1 = OpImageSparseFetch %struct_u32_u32 %img %u32vec2_01
5308fd4e5da5Sopenharmony_ci)";
5309fd4e5da5Sopenharmony_ci
5310fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5311fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5312fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5313fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type's second member to be int or "
5314fd4e5da5Sopenharmony_ci                        "float vector type"));
5315fd4e5da5Sopenharmony_ci}
5316fd4e5da5Sopenharmony_ci
5317fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseFetchWrongNumComponentsTexel) {
5318fd4e5da5Sopenharmony_ci  const std::string body = R"(
5319fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5320fd4e5da5Sopenharmony_ci%res1 = OpImageSparseFetch %struct_u32_f32vec3 %img %u32vec2_01
5321fd4e5da5Sopenharmony_ci)";
5322fd4e5da5Sopenharmony_ci
5323fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5324fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5325fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5326fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type's second member to have 4 "
5327fd4e5da5Sopenharmony_ci                        "components"));
5328fd4e5da5Sopenharmony_ci}
5329fd4e5da5Sopenharmony_ci
5330fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseFetchWrongComponentTypeTexel) {
5331fd4e5da5Sopenharmony_ci  const std::string body = R"(
5332fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5333fd4e5da5Sopenharmony_ci%res1 = OpImageSparseFetch %struct_u32_u32vec4 %img %u32vec2_01
5334fd4e5da5Sopenharmony_ci)";
5335fd4e5da5Sopenharmony_ci
5336fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5337fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5338fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5339fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
5340fd4e5da5Sopenharmony_ci                        "Result Type's second member components"));
5341fd4e5da5Sopenharmony_ci}
5342fd4e5da5Sopenharmony_ci
5343fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadSuccess) {
5344fd4e5da5Sopenharmony_ci  const std::string body = R"(
5345fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5346fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
5347fd4e5da5Sopenharmony_ci)";
5348fd4e5da5Sopenharmony_ci
5349fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5350fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5351fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5352fd4e5da5Sopenharmony_ci}
5353fd4e5da5Sopenharmony_ci
5354fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadResultTypeNotStruct) {
5355fd4e5da5Sopenharmony_ci  const std::string body = R"(
5356fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5357fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %f32 %img %u32vec2_01
5358fd4e5da5Sopenharmony_ci)";
5359fd4e5da5Sopenharmony_ci
5360fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5361fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5362fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5363fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5364fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypeStruct"));
5365fd4e5da5Sopenharmony_ci}
5366fd4e5da5Sopenharmony_ci
5367fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers1) {
5368fd4e5da5Sopenharmony_ci  const std::string body = R"(
5369fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5370fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_u32 %img %u32vec2_01
5371fd4e5da5Sopenharmony_ci)";
5372fd4e5da5Sopenharmony_ci
5373fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5374fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5375fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5376fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5377fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an "
5378fd4e5da5Sopenharmony_ci                        "int scalar and a texel"));
5379fd4e5da5Sopenharmony_ci}
5380fd4e5da5Sopenharmony_ci
5381fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers2) {
5382fd4e5da5Sopenharmony_ci  const std::string body = R"(
5383fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5384fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_u32_f32vec4_u32 %img %u32vec2_01
5385fd4e5da5Sopenharmony_ci)";
5386fd4e5da5Sopenharmony_ci
5387fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5388fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5389fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5390fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5391fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an "
5392fd4e5da5Sopenharmony_ci                        "int scalar and a texel"));
5393fd4e5da5Sopenharmony_ci}
5394fd4e5da5Sopenharmony_ci
5395fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadResultTypeFirstMemberNotInt) {
5396fd4e5da5Sopenharmony_ci  const std::string body = R"(
5397fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5398fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_f32_f32vec4 %img %u32vec2_01
5399fd4e5da5Sopenharmony_ci)";
5400fd4e5da5Sopenharmony_ci
5401fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5402fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5403fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5404fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5405fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an "
5406fd4e5da5Sopenharmony_ci                        "int scalar and a texel"));
5407fd4e5da5Sopenharmony_ci}
5408fd4e5da5Sopenharmony_ci
5409fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadResultTypeTexelWrongType) {
5410fd4e5da5Sopenharmony_ci  const std::string body = R"(
5411fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5412fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_u32_u32arr4 %img %u32vec2_01
5413fd4e5da5Sopenharmony_ci)";
5414fd4e5da5Sopenharmony_ci
5415fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5416fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5417fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5418fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5419fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type's second member to be int or "
5420fd4e5da5Sopenharmony_ci                        "float scalar or vector type"));
5421fd4e5da5Sopenharmony_ci}
5422fd4e5da5Sopenharmony_ci
5423fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadWrongComponentTypeTexel) {
5424fd4e5da5Sopenharmony_ci  const std::string body = R"(
5425fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5426fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_u32_u32vec4 %img %u32vec2_01
5427fd4e5da5Sopenharmony_ci)";
5428fd4e5da5Sopenharmony_ci
5429fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5430fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5431fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5432fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5433fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
5434fd4e5da5Sopenharmony_ci                        "Result Type's second member components"));
5435fd4e5da5Sopenharmony_ci}
5436fd4e5da5Sopenharmony_ci
5437fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadSubpassDataNotAllowed) {
5438fd4e5da5Sopenharmony_ci  const std::string body = R"(
5439fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
5440fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
5441fd4e5da5Sopenharmony_ci)";
5442fd4e5da5Sopenharmony_ci
5443fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5444fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment").c_str());
5445fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5446fd4e5da5Sopenharmony_ci  EXPECT_THAT(
5447fd4e5da5Sopenharmony_ci      getDiagnosticString(),
5448fd4e5da5Sopenharmony_ci      HasSubstr("Image Dim SubpassData cannot be used with ImageSparseRead"));
5449fd4e5da5Sopenharmony_ci}
5450fd4e5da5Sopenharmony_ci
5451fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseGatherSuccess) {
5452fd4e5da5Sopenharmony_ci  const std::string body = R"(
5453fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5454fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5455fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5456fd4e5da5Sopenharmony_ci%res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1
5457fd4e5da5Sopenharmony_ci%res2 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
5458fd4e5da5Sopenharmony_ci)";
5459fd4e5da5Sopenharmony_ci
5460fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5461fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5462fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5463fd4e5da5Sopenharmony_ci)";
5464fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5465fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5466fd4e5da5Sopenharmony_ci                          .c_str());
5467fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5468fd4e5da5Sopenharmony_ci}
5469fd4e5da5Sopenharmony_ci
5470fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseGatherResultTypeNotStruct) {
5471fd4e5da5Sopenharmony_ci  const std::string body = R"(
5472fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5473fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5474fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5475fd4e5da5Sopenharmony_ci%res1 = OpImageSparseGather %f32 %simg %f32vec2_hh %u32_1
5476fd4e5da5Sopenharmony_ci)";
5477fd4e5da5Sopenharmony_ci
5478fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5479fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5480fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5481fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypeStruct"));
5482fd4e5da5Sopenharmony_ci}
5483fd4e5da5Sopenharmony_ci
5484fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers1) {
5485fd4e5da5Sopenharmony_ci  const std::string body = R"(
5486fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5487fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5488fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5489fd4e5da5Sopenharmony_ci%res1 = OpImageSparseGather %struct_u32 %simg %f32vec2_hh %u32_1
5490fd4e5da5Sopenharmony_ci)";
5491fd4e5da5Sopenharmony_ci
5492fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5493fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5494fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5495fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an int "
5496fd4e5da5Sopenharmony_ci                        "scalar and a texel"));
5497fd4e5da5Sopenharmony_ci}
5498fd4e5da5Sopenharmony_ci
5499fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers2) {
5500fd4e5da5Sopenharmony_ci  const std::string body = R"(
5501fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5502fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5503fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5504fd4e5da5Sopenharmony_ci%res1 = OpImageSparseGather %struct_u32_f32vec4_u32 %simg %f32vec2_hh %u32_1
5505fd4e5da5Sopenharmony_ci)";
5506fd4e5da5Sopenharmony_ci
5507fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5508fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5509fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5510fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an int "
5511fd4e5da5Sopenharmony_ci                        "scalar and a texel"));
5512fd4e5da5Sopenharmony_ci}
5513fd4e5da5Sopenharmony_ci
5514fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseGatherResultTypeFirstMemberNotInt) {
5515fd4e5da5Sopenharmony_ci  const std::string body = R"(
5516fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5517fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5518fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5519fd4e5da5Sopenharmony_ci%res1 = OpImageSparseGather %struct_f32_f32vec4 %simg %f32vec2_hh %u32_1
5520fd4e5da5Sopenharmony_ci)";
5521fd4e5da5Sopenharmony_ci
5522fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5523fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5524fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5525fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be a struct containing an "
5526fd4e5da5Sopenharmony_ci                        "int scalar and a texel"));
5527fd4e5da5Sopenharmony_ci}
5528fd4e5da5Sopenharmony_ci
5529fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseGatherResultTypeTexelNotVector) {
5530fd4e5da5Sopenharmony_ci  const std::string body = R"(
5531fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5532fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5533fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5534fd4e5da5Sopenharmony_ci%res1 = OpImageSparseGather %struct_u32_u32 %simg %f32vec2_hh %u32_1
5535fd4e5da5Sopenharmony_ci)";
5536fd4e5da5Sopenharmony_ci
5537fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5538fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5539fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5540fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type's second member to be int or "
5541fd4e5da5Sopenharmony_ci                        "float vector type"));
5542fd4e5da5Sopenharmony_ci}
5543fd4e5da5Sopenharmony_ci
5544fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseGatherWrongNumComponentsTexel) {
5545fd4e5da5Sopenharmony_ci  const std::string body = R"(
5546fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5547fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5548fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5549fd4e5da5Sopenharmony_ci%res1 = OpImageSparseGather %struct_u32_f32vec3 %simg %f32vec2_hh %u32_1
5550fd4e5da5Sopenharmony_ci)";
5551fd4e5da5Sopenharmony_ci
5552fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5553fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5554fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5555fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type's second member to have 4 "
5556fd4e5da5Sopenharmony_ci                        "components"));
5557fd4e5da5Sopenharmony_ci}
5558fd4e5da5Sopenharmony_ci
5559fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseGatherWrongComponentTypeTexel) {
5560fd4e5da5Sopenharmony_ci  const std::string body = R"(
5561fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5562fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5563fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5564fd4e5da5Sopenharmony_ci%res1 = OpImageSparseGather %struct_u32_u32vec4 %simg %f32vec2_hh %u32_1
5565fd4e5da5Sopenharmony_ci)";
5566fd4e5da5Sopenharmony_ci
5567fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5568fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5569fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5570fd4e5da5Sopenharmony_ci              HasSubstr("Expected Image 'Sampled Type' to be the same as "
5571fd4e5da5Sopenharmony_ci                        "Result Type's second member components"));
5572fd4e5da5Sopenharmony_ci}
5573fd4e5da5Sopenharmony_ci
5574fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseTexelsResidentSuccess) {
5575fd4e5da5Sopenharmony_ci  const std::string body = R"(
5576fd4e5da5Sopenharmony_ci%res1 = OpImageSparseTexelsResident %bool %u32_1
5577fd4e5da5Sopenharmony_ci)";
5578fd4e5da5Sopenharmony_ci
5579fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5580fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5581fd4e5da5Sopenharmony_ci}
5582fd4e5da5Sopenharmony_ci
5583fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseTexelsResidentResultTypeNotBool) {
5584fd4e5da5Sopenharmony_ci  const std::string body = R"(
5585fd4e5da5Sopenharmony_ci%res1 = OpImageSparseTexelsResident %u32 %u32_1
5586fd4e5da5Sopenharmony_ci)";
5587fd4e5da5Sopenharmony_ci
5588fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body).c_str());
5589fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5590fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5591fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be bool scalar type"));
5592fd4e5da5Sopenharmony_ci}
5593fd4e5da5Sopenharmony_ci
5594fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageRead) {
5595fd4e5da5Sopenharmony_ci  const std::string body = R"(
5596fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5597fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
5598fd4e5da5Sopenharmony_ci)";
5599fd4e5da5Sopenharmony_ci
5600fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5601fd4e5da5Sopenharmony_ciOpCapability StorageImageReadWithoutFormat
5602fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5603fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5604fd4e5da5Sopenharmony_ci)";
5605fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5606fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5607fd4e5da5Sopenharmony_ci                          .c_str());
5608fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5609fd4e5da5Sopenharmony_ci}
5610fd4e5da5Sopenharmony_ci
5611fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageSparseRead) {
5612fd4e5da5Sopenharmony_ci  const std::string body = R"(
5613fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5614fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
5615fd4e5da5Sopenharmony_ci)";
5616fd4e5da5Sopenharmony_ci
5617fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5618fd4e5da5Sopenharmony_ciOpCapability StorageImageReadWithoutFormat
5619fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5620fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5621fd4e5da5Sopenharmony_ci)";
5622fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5623fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5624fd4e5da5Sopenharmony_ci                          .c_str());
5625fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5626fd4e5da5Sopenharmony_ci}
5627fd4e5da5Sopenharmony_ci
5628fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, MakeTexelVisibleKHRFailureOpcode) {
5629fd4e5da5Sopenharmony_ci  const std::string body = R"(
5630fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5631fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5632fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5633fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5634fd4e5da5Sopenharmony_ci)";
5635fd4e5da5Sopenharmony_ci
5636fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5637fd4e5da5Sopenharmony_ciOpCapability StorageImageReadWithoutFormat
5638fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5639fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5640fd4e5da5Sopenharmony_ci)";
5641fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5642fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5643fd4e5da5Sopenharmony_ci                          .c_str());
5644fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5645fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5646fd4e5da5Sopenharmony_ci  EXPECT_THAT(
5647fd4e5da5Sopenharmony_ci      getDiagnosticString(),
5648fd4e5da5Sopenharmony_ci      HasSubstr("Image Operand MakeTexelVisibleKHR can only be used with "
5649fd4e5da5Sopenharmony_ci                "OpImageRead or OpImageSparseRead: OpImageSampleImplicitLod"));
5650fd4e5da5Sopenharmony_ci}
5651fd4e5da5Sopenharmony_ci
5652fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, MakeTexelVisibleKHRFailureMissingNonPrivate) {
5653fd4e5da5Sopenharmony_ci  const std::string body = R"(
5654fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5655fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR %u32_1
5656fd4e5da5Sopenharmony_ci)";
5657fd4e5da5Sopenharmony_ci
5658fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5659fd4e5da5Sopenharmony_ciOpCapability StorageImageReadWithoutFormat
5660fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5661fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5662fd4e5da5Sopenharmony_ci)";
5663fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5664fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5665fd4e5da5Sopenharmony_ci                          .c_str());
5666fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5667fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5668fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5669fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand MakeTexelVisibleKHR requires "
5670fd4e5da5Sopenharmony_ci                        "NonPrivateTexelKHR is also specified: OpImageRead"));
5671fd4e5da5Sopenharmony_ci}
5672fd4e5da5Sopenharmony_ci
5673fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, MakeTexelAvailableKHRSuccessImageWrite) {
5674fd4e5da5Sopenharmony_ci  const std::string body = R"(
5675fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5676fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2
5677fd4e5da5Sopenharmony_ci)";
5678fd4e5da5Sopenharmony_ci
5679fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5680fd4e5da5Sopenharmony_ciOpCapability StorageImageWriteWithoutFormat
5681fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5682fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5683fd4e5da5Sopenharmony_ci)";
5684fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5685fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5686fd4e5da5Sopenharmony_ci                          .c_str());
5687fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5688fd4e5da5Sopenharmony_ci}
5689fd4e5da5Sopenharmony_ci
5690fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, MakeTexelAvailableKHRFailureOpcode) {
5691fd4e5da5Sopenharmony_ci  const std::string body = R"(
5692fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5693fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
5694fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5695fd4e5da5Sopenharmony_ci%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5696fd4e5da5Sopenharmony_ci)";
5697fd4e5da5Sopenharmony_ci
5698fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5699fd4e5da5Sopenharmony_ciOpCapability StorageImageReadWithoutFormat
5700fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5701fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5702fd4e5da5Sopenharmony_ci)";
5703fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5704fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5705fd4e5da5Sopenharmony_ci                          .c_str());
5706fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5707fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5708fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5709fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand MakeTexelAvailableKHR can only be used "
5710fd4e5da5Sopenharmony_ci                        "with OpImageWrite: OpImageSampleImplicitLod"));
5711fd4e5da5Sopenharmony_ci}
5712fd4e5da5Sopenharmony_ci
5713fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, MakeTexelAvailableKHRFailureMissingNonPrivate) {
5714fd4e5da5Sopenharmony_ci  const std::string body = R"(
5715fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5716fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1
5717fd4e5da5Sopenharmony_ci)";
5718fd4e5da5Sopenharmony_ci
5719fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5720fd4e5da5Sopenharmony_ciOpCapability StorageImageWriteWithoutFormat
5721fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5722fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5723fd4e5da5Sopenharmony_ci)";
5724fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5725fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5726fd4e5da5Sopenharmony_ci                          .c_str());
5727fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5728fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5729fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5730fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand MakeTexelAvailableKHR requires "
5731fd4e5da5Sopenharmony_ci                        "NonPrivateTexelKHR is also specified: OpImageWrite"));
5732fd4e5da5Sopenharmony_ci}
5733fd4e5da5Sopenharmony_ci
5734fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteBad) {
5735fd4e5da5Sopenharmony_ci  const std::string body = R"(
5736fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5737fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5738fd4e5da5Sopenharmony_ci)";
5739fd4e5da5Sopenharmony_ci
5740fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5741fd4e5da5Sopenharmony_ciOpCapability StorageImageWriteWithoutFormat
5742fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5743fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5744fd4e5da5Sopenharmony_ci)";
5745fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5746fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5747fd4e5da5Sopenharmony_ci                          .c_str());
5748fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5749fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5750fd4e5da5Sopenharmony_ci  EXPECT_THAT(
5751fd4e5da5Sopenharmony_ci      getDiagnosticString(),
5752fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
5753fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
5754fd4e5da5Sopenharmony_ci}
5755fd4e5da5Sopenharmony_ci
5756fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteGood) {
5757fd4e5da5Sopenharmony_ci  const std::string body = R"(
5758fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5759fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5760fd4e5da5Sopenharmony_ci)";
5761fd4e5da5Sopenharmony_ci
5762fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5763fd4e5da5Sopenharmony_ciOpCapability StorageImageWriteWithoutFormat
5764fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5765fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
5766fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5767fd4e5da5Sopenharmony_ci)";
5768fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5769fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5770fd4e5da5Sopenharmony_ci                          .c_str());
5771fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5772fd4e5da5Sopenharmony_ci}
5773fd4e5da5Sopenharmony_ci
5774fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadBad) {
5775fd4e5da5Sopenharmony_ci  const std::string body = R"(
5776fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5777fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5778fd4e5da5Sopenharmony_ci)";
5779fd4e5da5Sopenharmony_ci
5780fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5781fd4e5da5Sopenharmony_ciOpCapability StorageImageReadWithoutFormat
5782fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5783fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5784fd4e5da5Sopenharmony_ci)";
5785fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5786fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5787fd4e5da5Sopenharmony_ci                          .c_str());
5788fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5789fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5790fd4e5da5Sopenharmony_ci  EXPECT_THAT(
5791fd4e5da5Sopenharmony_ci      getDiagnosticString(),
5792fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
5793fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
5794fd4e5da5Sopenharmony_ci}
5795fd4e5da5Sopenharmony_ci
5796fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadGood) {
5797fd4e5da5Sopenharmony_ci  const std::string body = R"(
5798fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5799fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5800fd4e5da5Sopenharmony_ci)";
5801fd4e5da5Sopenharmony_ci
5802fd4e5da5Sopenharmony_ci  const std::string extra = R"(
5803fd4e5da5Sopenharmony_ciOpCapability StorageImageReadWithoutFormat
5804fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
5805fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
5806fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
5807fd4e5da5Sopenharmony_ci)";
5808fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5809fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5810fd4e5da5Sopenharmony_ci                          .c_str());
5811fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5812fd4e5da5Sopenharmony_ci}
5813fd4e5da5Sopenharmony_ci
5814fd4e5da5Sopenharmony_ci// This example used to cause a seg fault on OpReturnValue, verifying it doesn't
5815fd4e5da5Sopenharmony_ci// anymore.
5816fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, Issue2463NoSegFault) {
5817fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
5818fd4e5da5Sopenharmony_ci               OpCapability Linkage
5819fd4e5da5Sopenharmony_ci               OpCapability Shader
5820fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
5821fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
5822fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
5823fd4e5da5Sopenharmony_ci          %6 = OpTypeFunction %void
5824fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
5825fd4e5da5Sopenharmony_ci          %8 = OpTypeImage %float 3D 0 0 0 1 Unknown
5826fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
5827fd4e5da5Sopenharmony_ci         %10 = OpTypeSampler
5828fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
5829fd4e5da5Sopenharmony_ci         %12 = OpTypeSampledImage %8
5830fd4e5da5Sopenharmony_ci         %13 = OpTypeFunction %12 %_ptr_UniformConstant_8 %_ptr_UniformConstant_10
5831fd4e5da5Sopenharmony_ci         %23 = OpFunction %12 None %13
5832fd4e5da5Sopenharmony_ci         %24 = OpFunctionParameter %_ptr_UniformConstant_8
5833fd4e5da5Sopenharmony_ci         %25 = OpFunctionParameter %_ptr_UniformConstant_10
5834fd4e5da5Sopenharmony_ci         %26 = OpLabel
5835fd4e5da5Sopenharmony_ci         %27 = OpLoad %8 %24
5836fd4e5da5Sopenharmony_ci         %28 = OpLoad %10 %25
5837fd4e5da5Sopenharmony_ci         %29 = OpSampledImage %12 %27 %28
5838fd4e5da5Sopenharmony_ci               OpReturnValue %29
5839fd4e5da5Sopenharmony_ci               OpFunctionEnd
5840fd4e5da5Sopenharmony_ci)";
5841fd4e5da5Sopenharmony_ci
5842fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
5843fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5844fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5845fd4e5da5Sopenharmony_ci              HasSubstr("OpSampledImage instruction must not appear as operand "
5846fd4e5da5Sopenharmony_ci                        "for OpReturnValue"));
5847fd4e5da5Sopenharmony_ci}
5848fd4e5da5Sopenharmony_ci
5849fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SignExtendV13Bad) {
5850fd4e5da5Sopenharmony_ci  const std::string body = R"(
5851fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5852fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
5853fd4e5da5Sopenharmony_ci)";
5854fd4e5da5Sopenharmony_ci
5855fd4e5da5Sopenharmony_ci  CompileSuccessfully(
5856fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3));
5857fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions());
5858fd4e5da5Sopenharmony_ci  EXPECT_THAT(
5859fd4e5da5Sopenharmony_ci      getDiagnosticString(),
5860fd4e5da5Sopenharmony_ci      HasSubstr("SignExtend(4096) requires SPIR-V version 1.4 or later"));
5861fd4e5da5Sopenharmony_ci}
5862fd4e5da5Sopenharmony_ci
5863fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ZeroExtendV13Bad) {
5864fd4e5da5Sopenharmony_ci  const std::string body = R"(
5865fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5866fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
5867fd4e5da5Sopenharmony_ci)";
5868fd4e5da5Sopenharmony_ci
5869fd4e5da5Sopenharmony_ci  CompileSuccessfully(
5870fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3));
5871fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions());
5872fd4e5da5Sopenharmony_ci  EXPECT_THAT(
5873fd4e5da5Sopenharmony_ci      getDiagnosticString(),
5874fd4e5da5Sopenharmony_ci      HasSubstr("ZeroExtend(8192) requires SPIR-V version 1.4 or later"));
5875fd4e5da5Sopenharmony_ci}
5876fd4e5da5Sopenharmony_ci
5877fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) {
5878fd4e5da5Sopenharmony_ci  // Unsigned int sampled type
5879fd4e5da5Sopenharmony_ci  const std::string body = R"(
5880fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5881fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32 %img %u32vec2_01 SignExtend
5882fd4e5da5Sopenharmony_ci)";
5883fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5884fd4e5da5Sopenharmony_ci
5885fd4e5da5Sopenharmony_ci  CompileSuccessfully(
5886fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5887fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_4);
5888fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5889fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
5890fd4e5da5Sopenharmony_ci}
5891fd4e5da5Sopenharmony_ci
5892fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) {
5893fd4e5da5Sopenharmony_ci  // Signed int sampled type
5894fd4e5da5Sopenharmony_ci  const std::string body = R"(
5895fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5896fd4e5da5Sopenharmony_ci%res1 = OpImageRead %s32 %img %u32vec2_01 SignExtend
5897fd4e5da5Sopenharmony_ci)";
5898fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5899fd4e5da5Sopenharmony_ci
5900fd4e5da5Sopenharmony_ci  CompileSuccessfully(
5901fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5902fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_4);
5903fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5904fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
5905fd4e5da5Sopenharmony_ci}
5906fd4e5da5Sopenharmony_ci
5907fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) {
5908fd4e5da5Sopenharmony_ci  const std::string body = R"(
5909fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5910fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
5911fd4e5da5Sopenharmony_ci)";
5912fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5913fd4e5da5Sopenharmony_ci
5914fd4e5da5Sopenharmony_ci  CompileSuccessfully(
5915fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5916fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_4);
5917fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5918fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
5919fd4e5da5Sopenharmony_ci}
5920fd4e5da5Sopenharmony_ci
5921fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) {
5922fd4e5da5Sopenharmony_ci  const std::string body = R"(
5923fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5924fd4e5da5Sopenharmony_ci%res1 = OpImageRead %s32vec4 %img %u32vec2_01 SignExtend
5925fd4e5da5Sopenharmony_ci)";
5926fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5927fd4e5da5Sopenharmony_ci
5928fd4e5da5Sopenharmony_ci  CompileSuccessfully(
5929fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5930fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_4);
5931fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5932fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
5933fd4e5da5Sopenharmony_ci}
5934fd4e5da5Sopenharmony_ci
5935fd4e5da5Sopenharmony_ci// No negative tests for SignExtend since we don't truly know the
5936fd4e5da5Sopenharmony_ci// texel format.
5937fd4e5da5Sopenharmony_ci
5938fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) {
5939fd4e5da5Sopenharmony_ci  // Unsigned int sampled type
5940fd4e5da5Sopenharmony_ci  const std::string body = R"(
5941fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5942fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32 %img %u32vec2_01 ZeroExtend
5943fd4e5da5Sopenharmony_ci)";
5944fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5945fd4e5da5Sopenharmony_ci
5946fd4e5da5Sopenharmony_ci  CompileSuccessfully(
5947fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5948fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_4);
5949fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5950fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
5951fd4e5da5Sopenharmony_ci}
5952fd4e5da5Sopenharmony_ci
5953fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) {
5954fd4e5da5Sopenharmony_ci  // Zeroed int sampled type
5955fd4e5da5Sopenharmony_ci  const std::string body = R"(
5956fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5957fd4e5da5Sopenharmony_ci%res1 = OpImageRead %s32 %img %u32vec2_01 ZeroExtend
5958fd4e5da5Sopenharmony_ci)";
5959fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5960fd4e5da5Sopenharmony_ci
5961fd4e5da5Sopenharmony_ci  CompileSuccessfully(
5962fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5963fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_4);
5964fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5965fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
5966fd4e5da5Sopenharmony_ci}
5967fd4e5da5Sopenharmony_ci
5968fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) {
5969fd4e5da5Sopenharmony_ci  const std::string body = R"(
5970fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5971fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
5972fd4e5da5Sopenharmony_ci)";
5973fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5974fd4e5da5Sopenharmony_ci
5975fd4e5da5Sopenharmony_ci  CompileSuccessfully(
5976fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5977fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_4);
5978fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5979fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
5980fd4e5da5Sopenharmony_ci}
5981fd4e5da5Sopenharmony_ci
5982fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) {
5983fd4e5da5Sopenharmony_ci  const std::string body = R"(
5984fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5985fd4e5da5Sopenharmony_ci%res1 = OpImageRead %s32vec4 %img %u32vec2_01 ZeroExtend
5986fd4e5da5Sopenharmony_ci)";
5987fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5988fd4e5da5Sopenharmony_ci
5989fd4e5da5Sopenharmony_ci  CompileSuccessfully(
5990fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5991fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_4);
5992fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5993fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
5994fd4e5da5Sopenharmony_ci}
5995fd4e5da5Sopenharmony_ci
5996fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadLodAMDSuccess1) {
5997fd4e5da5Sopenharmony_ci  const std::string body = R"(
5998fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5999fd4e5da5Sopenharmony_ci%res1 = OpImageRead %u32vec4 %img %u32vec2_01 Lod %u32_0
6000fd4e5da5Sopenharmony_ci)";
6001fd4e5da5Sopenharmony_ci
6002fd4e5da5Sopenharmony_ci  const std::string extra =
6003fd4e5da5Sopenharmony_ci      "\nOpCapability StorageImageReadWithoutFormat\n"
6004fd4e5da5Sopenharmony_ci      "OpCapability ImageReadWriteLodAMD\n"
6005fd4e5da5Sopenharmony_ci      "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6006fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6007fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6008fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_1);
6009fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6010fd4e5da5Sopenharmony_ci}
6011fd4e5da5Sopenharmony_ci
6012fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadLodAMDSuccess2) {
6013fd4e5da5Sopenharmony_ci  const std::string body = R"(
6014fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
6015fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec2_01 Lod %u32_0
6016fd4e5da5Sopenharmony_ci)";
6017fd4e5da5Sopenharmony_ci
6018fd4e5da5Sopenharmony_ci  const std::string extra =
6019fd4e5da5Sopenharmony_ci      "\nOpCapability Image1D\n"
6020fd4e5da5Sopenharmony_ci      "OpCapability ImageReadWriteLodAMD\n"
6021fd4e5da5Sopenharmony_ci      "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6022fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6023fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6024fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_1);
6025fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6026fd4e5da5Sopenharmony_ci}
6027fd4e5da5Sopenharmony_ci
6028fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadLodAMDSuccess3) {
6029fd4e5da5Sopenharmony_ci  const std::string body = R"(
6030fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6031fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
6032fd4e5da5Sopenharmony_ci)";
6033fd4e5da5Sopenharmony_ci
6034fd4e5da5Sopenharmony_ci  const std::string extra =
6035fd4e5da5Sopenharmony_ci      "\nOpCapability ImageCubeArray\n"
6036fd4e5da5Sopenharmony_ci      "OpCapability ImageReadWriteLodAMD\n"
6037fd4e5da5Sopenharmony_ci      "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6038fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6039fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6040fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_1);
6041fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6042fd4e5da5Sopenharmony_ci}
6043fd4e5da5Sopenharmony_ci
6044fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ReadLodAMDNeedCapability) {
6045fd4e5da5Sopenharmony_ci  const std::string body = R"(
6046fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6047fd4e5da5Sopenharmony_ci%res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
6048fd4e5da5Sopenharmony_ci)";
6049fd4e5da5Sopenharmony_ci
6050fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability ImageCubeArray\n";
6051fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6052fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6053fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_1);
6054fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA,
6055fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6056fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6057fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand Lod can only be used with ExplicitLod "
6058fd4e5da5Sopenharmony_ci                        "opcodes and OpImageFetch"));
6059fd4e5da5Sopenharmony_ci}
6060fd4e5da5Sopenharmony_ci
6061fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteLodAMDSuccess1) {
6062fd4e5da5Sopenharmony_ci  const std::string body = R"(
6063fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
6064fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec2_01 %u32vec4_0123 Lod %u32_0
6065fd4e5da5Sopenharmony_ci)";
6066fd4e5da5Sopenharmony_ci
6067fd4e5da5Sopenharmony_ci  const std::string extra =
6068fd4e5da5Sopenharmony_ci      "\nOpCapability StorageImageWriteWithoutFormat\n"
6069fd4e5da5Sopenharmony_ci      "OpCapability ImageReadWriteLodAMD\n"
6070fd4e5da5Sopenharmony_ci      "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6071fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6072fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6073fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_1);
6074fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6075fd4e5da5Sopenharmony_ci}
6076fd4e5da5Sopenharmony_ci
6077fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteLodAMDSuccess2) {
6078fd4e5da5Sopenharmony_ci  const std::string body = R"(
6079fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
6080fd4e5da5Sopenharmony_ciOpImageWrite %img %u32_1 %f32vec4_0000 Lod %u32_0
6081fd4e5da5Sopenharmony_ci)";
6082fd4e5da5Sopenharmony_ci
6083fd4e5da5Sopenharmony_ci  const std::string extra =
6084fd4e5da5Sopenharmony_ci      "\nOpCapability Image1D\n"
6085fd4e5da5Sopenharmony_ci      "OpCapability ImageReadWriteLodAMD\n"
6086fd4e5da5Sopenharmony_ci      "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6087fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6088fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6089fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_1);
6090fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6091fd4e5da5Sopenharmony_ci}
6092fd4e5da5Sopenharmony_ci
6093fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteLodAMDSuccess3) {
6094fd4e5da5Sopenharmony_ci  const std::string body = R"(
6095fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6096fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
6097fd4e5da5Sopenharmony_ci)";
6098fd4e5da5Sopenharmony_ci
6099fd4e5da5Sopenharmony_ci  const std::string extra =
6100fd4e5da5Sopenharmony_ci      "\nOpCapability ImageCubeArray\n"
6101fd4e5da5Sopenharmony_ci      "OpCapability ImageReadWriteLodAMD\n"
6102fd4e5da5Sopenharmony_ci      "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6103fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6104fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6105fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_1);
6106fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6107fd4e5da5Sopenharmony_ci}
6108fd4e5da5Sopenharmony_ci
6109fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, WriteLodAMDNeedCapability) {
6110fd4e5da5Sopenharmony_ci  const std::string body = R"(
6111fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6112fd4e5da5Sopenharmony_ciOpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
6113fd4e5da5Sopenharmony_ci)";
6114fd4e5da5Sopenharmony_ci
6115fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability ImageCubeArray\n";
6116fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6117fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6118fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_1);
6119fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA,
6120fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6121fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6122fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand Lod can only be used with ExplicitLod "
6123fd4e5da5Sopenharmony_ci                        "opcodes and OpImageFetch"));
6124fd4e5da5Sopenharmony_ci}
6125fd4e5da5Sopenharmony_ci
6126fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadLodAMDSuccess) {
6127fd4e5da5Sopenharmony_ci  const std::string body = R"(
6128fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
6129fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
6130fd4e5da5Sopenharmony_ci)";
6131fd4e5da5Sopenharmony_ci
6132fd4e5da5Sopenharmony_ci  const std::string extra =
6133fd4e5da5Sopenharmony_ci      "\nOpCapability StorageImageReadWithoutFormat\n"
6134fd4e5da5Sopenharmony_ci      "OpCapability ImageReadWriteLodAMD\n"
6135fd4e5da5Sopenharmony_ci      "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6136fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6137fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6138fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_1);
6139fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6140fd4e5da5Sopenharmony_ci}
6141fd4e5da5Sopenharmony_ci
6142fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseReadLodAMDNeedCapability) {
6143fd4e5da5Sopenharmony_ci  const std::string body = R"(
6144fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
6145fd4e5da5Sopenharmony_ci%res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
6146fd4e5da5Sopenharmony_ci)";
6147fd4e5da5Sopenharmony_ci
6148fd4e5da5Sopenharmony_ci  const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
6149fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6150fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6151fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_1);
6152fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA,
6153fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6154fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6155fd4e5da5Sopenharmony_ci              HasSubstr("Image Operand Lod can only be used with ExplicitLod "
6156fd4e5da5Sopenharmony_ci                        "opcodes and OpImageFetch"));
6157fd4e5da5Sopenharmony_ci}
6158fd4e5da5Sopenharmony_ci
6159fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherBiasAMDSuccess) {
6160fd4e5da5Sopenharmony_ci  const std::string body = R"(
6161fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6162fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
6163fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6164fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
6165fd4e5da5Sopenharmony_ci)";
6166fd4e5da5Sopenharmony_ci
6167fd4e5da5Sopenharmony_ci  const std::string extra = R"(
6168fd4e5da5Sopenharmony_ciOpCapability ImageGatherBiasLodAMD
6169fd4e5da5Sopenharmony_ciOpExtension "SPV_AMD_texture_gather_bias_lod"
6170fd4e5da5Sopenharmony_ci)";
6171fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6172fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6173fd4e5da5Sopenharmony_ci}
6174fd4e5da5Sopenharmony_ci
6175fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, GatherLodAMDSuccess) {
6176fd4e5da5Sopenharmony_ci  const std::string body = R"(
6177fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6178fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
6179fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6180fd4e5da5Sopenharmony_ci%res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
6181fd4e5da5Sopenharmony_ci)";
6182fd4e5da5Sopenharmony_ci
6183fd4e5da5Sopenharmony_ci  const std::string extra = R"(
6184fd4e5da5Sopenharmony_ciOpCapability ImageGatherBiasLodAMD
6185fd4e5da5Sopenharmony_ciOpExtension "SPV_AMD_texture_gather_bias_lod"
6186fd4e5da5Sopenharmony_ci)";
6187fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6188fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6189fd4e5da5Sopenharmony_ci}
6190fd4e5da5Sopenharmony_ci
6191fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseGatherBiasAMDSuccess) {
6192fd4e5da5Sopenharmony_ci  const std::string body = R"(
6193fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6194fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
6195fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6196fd4e5da5Sopenharmony_ci%res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
6197fd4e5da5Sopenharmony_ci)";
6198fd4e5da5Sopenharmony_ci
6199fd4e5da5Sopenharmony_ci  const std::string extra = R"(
6200fd4e5da5Sopenharmony_ciOpCapability ImageGatherBiasLodAMD
6201fd4e5da5Sopenharmony_ciOpExtension "SPV_AMD_texture_gather_bias_lod"
6202fd4e5da5Sopenharmony_ci)";
6203fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6204fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6205fd4e5da5Sopenharmony_ci}
6206fd4e5da5Sopenharmony_ci
6207fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, SparseGatherLodAMDSuccess) {
6208fd4e5da5Sopenharmony_ci  const std::string body = R"(
6209fd4e5da5Sopenharmony_ci%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6210fd4e5da5Sopenharmony_ci%sampler = OpLoad %type_sampler %uniform_sampler
6211fd4e5da5Sopenharmony_ci%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6212fd4e5da5Sopenharmony_ci%res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
6213fd4e5da5Sopenharmony_ci)";
6214fd4e5da5Sopenharmony_ci
6215fd4e5da5Sopenharmony_ci  const std::string extra = R"(
6216fd4e5da5Sopenharmony_ciOpCapability ImageGatherBiasLodAMD
6217fd4e5da5Sopenharmony_ciOpExtension "SPV_AMD_texture_gather_bias_lod"
6218fd4e5da5Sopenharmony_ci)";
6219fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6220fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6221fd4e5da5Sopenharmony_ci}
6222fd4e5da5Sopenharmony_ci
6223fd4e5da5Sopenharmony_ci// No negative tests for ZeroExtend since we don't truly know the
6224fd4e5da5Sopenharmony_ci// texel format.
6225fd4e5da5Sopenharmony_ci
6226fd4e5da5Sopenharmony_ci// Tests for 64-bit images
6227fd4e5da5Sopenharmony_cistatic const std::string capabilities_and_extensions_image64 = R"(
6228fd4e5da5Sopenharmony_ciOpCapability Int64ImageEXT
6229fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_image_int64"
6230fd4e5da5Sopenharmony_ci)";
6231fd4e5da5Sopenharmony_cistatic const std::string capabilities_and_extensions_image64_atomic = R"(
6232fd4e5da5Sopenharmony_ciOpCapability Int64Atomics
6233fd4e5da5Sopenharmony_ciOpCapability Int64ImageEXT
6234fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_image_int64"
6235fd4e5da5Sopenharmony_ci)";
6236fd4e5da5Sopenharmony_cistatic const std::string declarations_image64 = R"(
6237fd4e5da5Sopenharmony_ci%type_image_u64_buffer_0002_r64ui = OpTypeImage %u64 Buffer 0 0 0 2 R64ui
6238fd4e5da5Sopenharmony_ci%ptr_Image_u64 = OpTypePointer Image %u64
6239fd4e5da5Sopenharmony_ci%ptr_image_u64_buffer_0002_r64ui = OpTypePointer Private %type_image_u64_buffer_0002_r64ui
6240fd4e5da5Sopenharmony_ci%private_image_u64_buffer_0002_r64ui = OpVariable %ptr_image_u64_buffer_0002_r64ui Private
6241fd4e5da5Sopenharmony_ci)";
6242fd4e5da5Sopenharmony_cistatic const std::string declarations_image64i = R"(
6243fd4e5da5Sopenharmony_ci%type_image_s64_buffer_0002_r64i = OpTypeImage %s64 Buffer 0 0 0 2 R64i
6244fd4e5da5Sopenharmony_ci%ptr_Image_s64 = OpTypePointer Image %s64
6245fd4e5da5Sopenharmony_ci%ptr_image_s64_buffer_0002_r64i = OpTypePointer Private %type_image_s64_buffer_0002_r64i
6246fd4e5da5Sopenharmony_ci%private_image_s64_buffer_0002_r64i = OpVariable %ptr_image_s64_buffer_0002_r64i Private
6247fd4e5da5Sopenharmony_ci)";
6248fd4e5da5Sopenharmony_ci
6249fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, Image64MissingCapability) {
6250fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode("", "", "Fragment", "",
6251fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6252fd4e5da5Sopenharmony_ci                                         declarations_image64)
6253fd4e5da5Sopenharmony_ci                          .c_str());
6254fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
6255fd4e5da5Sopenharmony_ci}
6256fd4e5da5Sopenharmony_ci
6257fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, Image64MissingExtension) {
6258fd4e5da5Sopenharmony_ci  const std::string extra = R"(
6259fd4e5da5Sopenharmony_ciOpCapability Int64ImageEXT
6260fd4e5da5Sopenharmony_ci)";
6261fd4e5da5Sopenharmony_ci
6262fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode("", extra, "Fragment", "",
6263fd4e5da5Sopenharmony_ci                                         SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6264fd4e5da5Sopenharmony_ci                                         declarations_image64)
6265fd4e5da5Sopenharmony_ci                          .c_str());
6266fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
6267fd4e5da5Sopenharmony_ci}
6268fd4e5da5Sopenharmony_ci
6269fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointer64Success) {
6270fd4e5da5Sopenharmony_ci  const std::string body = R"(
6271fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6272fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6273fd4e5da5Sopenharmony_ci)";
6274fd4e5da5Sopenharmony_ci
6275fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6276fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6277fd4e5da5Sopenharmony_ci                         "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6278fd4e5da5Sopenharmony_ci                         declarations_image64)
6279fd4e5da5Sopenharmony_ci          .c_str());
6280fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6281fd4e5da5Sopenharmony_ci}
6282fd4e5da5Sopenharmony_ci
6283fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotPointer) {
6284fd4e5da5Sopenharmony_ci  const std::string body = R"(
6285fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %type_image_u64_buffer_0002_r64ui %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6286fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6287fd4e5da5Sopenharmony_ci)";
6288fd4e5da5Sopenharmony_ci
6289fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6290fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6291fd4e5da5Sopenharmony_ci                         "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6292fd4e5da5Sopenharmony_ci                         declarations_image64)
6293fd4e5da5Sopenharmony_ci          .c_str());
6294fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6295fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6296fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypePointer"));
6297fd4e5da5Sopenharmony_ci}
6298fd4e5da5Sopenharmony_ci
6299fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotImageClass) {
6300fd4e5da5Sopenharmony_ci  const std::string body = R"(
6301fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6302fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6303fd4e5da5Sopenharmony_ci)";
6304fd4e5da5Sopenharmony_ci
6305fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6306fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6307fd4e5da5Sopenharmony_ci                         "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6308fd4e5da5Sopenharmony_ci                         declarations_image64)
6309fd4e5da5Sopenharmony_ci          .c_str());
6310fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6311fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6312fd4e5da5Sopenharmony_ci              HasSubstr("Expected Result Type to be OpTypePointer whose "
6313fd4e5da5Sopenharmony_ci                        "Storage Class operand is Image"));
6314fd4e5da5Sopenharmony_ci}
6315fd4e5da5Sopenharmony_ci
6316fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointer64SampleNotZeroForImageWithMSZero) {
6317fd4e5da5Sopenharmony_ci  const std::string body = R"(
6318fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_1
6319fd4e5da5Sopenharmony_ci%sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6320fd4e5da5Sopenharmony_ci)";
6321fd4e5da5Sopenharmony_ci
6322fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6323fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6324fd4e5da5Sopenharmony_ci                         "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6325fd4e5da5Sopenharmony_ci                         declarations_image64)
6326fd4e5da5Sopenharmony_ci          .c_str());
6327fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6328fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6329fd4e5da5Sopenharmony_ci              HasSubstr("Expected Sample for Image with MS 0 to be a valid "
6330fd4e5da5Sopenharmony_ci                        "<id> for the value 0"));
6331fd4e5da5Sopenharmony_ci}
6332fd4e5da5Sopenharmony_ci
6333fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerR32uiSuccessVulkan) {
6334fd4e5da5Sopenharmony_ci  const std::string body = R"(
6335fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
6336fd4e5da5Sopenharmony_ci)";
6337fd4e5da5Sopenharmony_ci
6338fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
6339fd4e5da5Sopenharmony_ci  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
6340fd4e5da5Sopenharmony_ci                      env);
6341fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6342fd4e5da5Sopenharmony_ci}
6343fd4e5da5Sopenharmony_ci
6344fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerR32iSuccessVulkan) {
6345fd4e5da5Sopenharmony_ci  const std::string& declarations = R"(
6346fd4e5da5Sopenharmony_ci%type_image_s32_buffer_0002_r32i = OpTypeImage %s32 Buffer 0 0 0 2 R32i
6347fd4e5da5Sopenharmony_ci%ptr_Image_s32 = OpTypePointer Image %s32
6348fd4e5da5Sopenharmony_ci%ptr_image_s32_buffer_0002_r32i = OpTypePointer Private %type_image_s32_buffer_0002_r32i
6349fd4e5da5Sopenharmony_ci%private_image_s32_buffer_0002_r32i = OpVariable %ptr_image_s32_buffer_0002_r32i Private
6350fd4e5da5Sopenharmony_ci)";
6351fd4e5da5Sopenharmony_ci
6352fd4e5da5Sopenharmony_ci  const std::string body = R"(
6353fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_r32i %u32_0 %u32_0
6354fd4e5da5Sopenharmony_ci)";
6355fd4e5da5Sopenharmony_ci
6356fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
6357fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6358fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6359fd4e5da5Sopenharmony_ci          .c_str(),
6360fd4e5da5Sopenharmony_ci      env);
6361fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6362fd4e5da5Sopenharmony_ci}
6363fd4e5da5Sopenharmony_ci
6364fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerR64uiSuccessVulkan) {
6365fd4e5da5Sopenharmony_ci  const std::string body = R"(
6366fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6367fd4e5da5Sopenharmony_ci)";
6368fd4e5da5Sopenharmony_ci
6369fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
6370fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6371fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
6372fd4e5da5Sopenharmony_ci                         "", env, "GLSL450", declarations_image64)
6373fd4e5da5Sopenharmony_ci          .c_str(),
6374fd4e5da5Sopenharmony_ci      env);
6375fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6376fd4e5da5Sopenharmony_ci}
6377fd4e5da5Sopenharmony_ci
6378fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerR64iSuccessVulkan) {
6379fd4e5da5Sopenharmony_ci  const std::string body = R"(
6380fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_s64 %private_image_s64_buffer_0002_r64i %u32_0 %u32_0
6381fd4e5da5Sopenharmony_ci)";
6382fd4e5da5Sopenharmony_ci
6383fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
6384fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6385fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
6386fd4e5da5Sopenharmony_ci                         "", env, "GLSL450", declarations_image64i)
6387fd4e5da5Sopenharmony_ci          .c_str(),
6388fd4e5da5Sopenharmony_ci      env);
6389fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6390fd4e5da5Sopenharmony_ci}
6391fd4e5da5Sopenharmony_ci
6392fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerR32fSuccessVulkan) {
6393fd4e5da5Sopenharmony_ci  const std::string& declarations = R"(
6394fd4e5da5Sopenharmony_ci%type_image_f32_buffer_0002_r32f = OpTypeImage %f32 Buffer 0 0 0 2 R32f
6395fd4e5da5Sopenharmony_ci%ptr_image_f32_buffer_0002_r32f = OpTypePointer Private %type_image_f32_buffer_0002_r32f
6396fd4e5da5Sopenharmony_ci%private_image_f32_buffer_0002_r32f = OpVariable %ptr_image_f32_buffer_0002_r32f Private
6397fd4e5da5Sopenharmony_ci)";
6398fd4e5da5Sopenharmony_ci
6399fd4e5da5Sopenharmony_ci  const std::string body = R"(
6400fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32f %u32_0 %u32_0
6401fd4e5da5Sopenharmony_ci)";
6402fd4e5da5Sopenharmony_ci
6403fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
6404fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6405fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6406fd4e5da5Sopenharmony_ci          .c_str(),
6407fd4e5da5Sopenharmony_ci      env);
6408fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6409fd4e5da5Sopenharmony_ci}
6410fd4e5da5Sopenharmony_ci
6411fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerRgba32iVulkan) {
6412fd4e5da5Sopenharmony_ci  const std::string& declarations = R"(
6413fd4e5da5Sopenharmony_ci%type_image_s32_buffer_0002_rgba32i = OpTypeImage %s32 Buffer 0 0 0 2 Rgba32i
6414fd4e5da5Sopenharmony_ci%ptr_Image_s32 = OpTypePointer Image %s32
6415fd4e5da5Sopenharmony_ci%ptr_image_s32_buffer_0002_rgba32i = OpTypePointer Private %type_image_s32_buffer_0002_rgba32i
6416fd4e5da5Sopenharmony_ci%private_image_s32_buffer_0002_rgba32i = OpVariable %ptr_image_s32_buffer_0002_rgba32i Private
6417fd4e5da5Sopenharmony_ci)";
6418fd4e5da5Sopenharmony_ci
6419fd4e5da5Sopenharmony_ci  const std::string body = R"(
6420fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba32i %u32_0 %u32_0
6421fd4e5da5Sopenharmony_ci)";
6422fd4e5da5Sopenharmony_ci
6423fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
6424fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6425fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6426fd4e5da5Sopenharmony_ci          .c_str(),
6427fd4e5da5Sopenharmony_ci      env);
6428fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
6429fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6430fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
6431fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6432fd4e5da5Sopenharmony_ci              HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
6433fd4e5da5Sopenharmony_ci                        "R32f, R32i, or R32ui for Vulkan environment"));
6434fd4e5da5Sopenharmony_ci}
6435fd4e5da5Sopenharmony_ci
6436fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageTexelPointerRgba16fVulkan) {
6437fd4e5da5Sopenharmony_ci  const std::string& declarations = R"(
6438fd4e5da5Sopenharmony_ci%type_image_s32_buffer_0002_rgba16f = OpTypeImage %s32 Buffer 0 0 0 2 Rgba16f
6439fd4e5da5Sopenharmony_ci%ptr_Image_s32 = OpTypePointer Image %s32
6440fd4e5da5Sopenharmony_ci%ptr_image_s32_buffer_0002_rgba16f = OpTypePointer Private %type_image_s32_buffer_0002_rgba16f
6441fd4e5da5Sopenharmony_ci%private_image_s32_buffer_0002_rgba16f = OpVariable %ptr_image_s32_buffer_0002_rgba16f Private
6442fd4e5da5Sopenharmony_ci)";
6443fd4e5da5Sopenharmony_ci
6444fd4e5da5Sopenharmony_ci  const std::string body = R"(
6445fd4e5da5Sopenharmony_ci%texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba16f %u32_0 %u32_0
6446fd4e5da5Sopenharmony_ci)";
6447fd4e5da5Sopenharmony_ci
6448fd4e5da5Sopenharmony_ci  spv_target_env env = SPV_ENV_VULKAN_1_0;
6449fd4e5da5Sopenharmony_ci  CompileSuccessfully(
6450fd4e5da5Sopenharmony_ci      GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6451fd4e5da5Sopenharmony_ci          .c_str(),
6452fd4e5da5Sopenharmony_ci      env);
6453fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
6454fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6455fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
6456fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6457fd4e5da5Sopenharmony_ci              HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
6458fd4e5da5Sopenharmony_ci                        "R32f, R32i, or R32ui for Vulkan environment"));
6459fd4e5da5Sopenharmony_ci}
6460fd4e5da5Sopenharmony_ci
6461fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageExecutionModeLimitationNoMode) {
6462fd4e5da5Sopenharmony_ci  const std::string text = R"(
6463fd4e5da5Sopenharmony_ciOpCapability Shader
6464fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
6465fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %2 " " %4
6466fd4e5da5Sopenharmony_ci%void = OpTypeVoid
6467fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
6468fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
6469fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
6470fd4e5da5Sopenharmony_ci%12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
6471fd4e5da5Sopenharmony_ci%13 = OpTypeSampledImage %12
6472fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6473fd4e5da5Sopenharmony_ci%5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
6474fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
6475fd4e5da5Sopenharmony_ci%4 = OpVariable %_ptr_Input_v4float Input
6476fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
6477fd4e5da5Sopenharmony_ci%float_1_35631564en19 = OpConstant %float 1.35631564e-19
6478fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %8
6479fd4e5da5Sopenharmony_ci%8224 = OpLabel
6480fd4e5da5Sopenharmony_ci%6 = OpLoad %13 %5
6481fd4e5da5Sopenharmony_ci%19 = OpLoad %v4float %4
6482fd4e5da5Sopenharmony_ci%20 = OpVectorShuffle %v2float %19 %19 0 1
6483fd4e5da5Sopenharmony_ci%21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
6484fd4e5da5Sopenharmony_ci%65312 = OpImageSampleImplicitLod %v4float %6 %21
6485fd4e5da5Sopenharmony_ciOpUnreachable
6486fd4e5da5Sopenharmony_ciOpFunctionEnd
6487fd4e5da5Sopenharmony_ci)";
6488fd4e5da5Sopenharmony_ci
6489fd4e5da5Sopenharmony_ci  CompileSuccessfully(text);
6490fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6491fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6492fd4e5da5Sopenharmony_ci              HasSubstr("ImplicitLod instructions require "
6493fd4e5da5Sopenharmony_ci                        "DerivativeGroupQuadsNV or DerivativeGroupLinearNV "
6494fd4e5da5Sopenharmony_ci                        "execution mode for GLCompute execution model"));
6495fd4e5da5Sopenharmony_ci}
6496fd4e5da5Sopenharmony_ci
6497fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, TypeSampledImageNotBufferPost1p6) {
6498fd4e5da5Sopenharmony_ci  const std::string text = R"(
6499fd4e5da5Sopenharmony_ciOpCapability Shader
6500fd4e5da5Sopenharmony_ciOpCapability Linkage
6501fd4e5da5Sopenharmony_ciOpCapability SampledBuffer
6502fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
6503fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
6504fd4e5da5Sopenharmony_ci%image = OpTypeImage %float Buffer 0 0 0 1 Unknown
6505fd4e5da5Sopenharmony_ci%sampled = OpTypeSampledImage %image
6506fd4e5da5Sopenharmony_ci)";
6507fd4e5da5Sopenharmony_ci
6508fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
6509fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
6510fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
6511fd4e5da5Sopenharmony_ci              HasSubstr("In SPIR-V 1.6 or later, sampled image dimension must "
6512fd4e5da5Sopenharmony_ci                        "not be Buffer"));
6513fd4e5da5Sopenharmony_ci}
6514fd4e5da5Sopenharmony_ci
6515fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, NonTemporalImage) {
6516fd4e5da5Sopenharmony_ci  const std::string text = R"(
6517fd4e5da5Sopenharmony_ciOpCapability Shader
6518fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
6519fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 " " %4 %5
6520fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft
6521fd4e5da5Sopenharmony_ci%void = OpTypeVoid
6522fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
6523fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
6524fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
6525fd4e5da5Sopenharmony_ci%12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
6526fd4e5da5Sopenharmony_ci%13 = OpTypeSampledImage %12
6527fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6528fd4e5da5Sopenharmony_ci%5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
6529fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
6530fd4e5da5Sopenharmony_ci%4 = OpVariable %_ptr_Input_v4float Input
6531fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
6532fd4e5da5Sopenharmony_ci%float_1_35631564en19 = OpConstant %float 1.35631564e-19
6533fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %8
6534fd4e5da5Sopenharmony_ci%8224 = OpLabel
6535fd4e5da5Sopenharmony_ci%6 = OpLoad %13 %5
6536fd4e5da5Sopenharmony_ci%19 = OpLoad %v4float %4
6537fd4e5da5Sopenharmony_ci%20 = OpVectorShuffle %v2float %19 %19 0 1
6538fd4e5da5Sopenharmony_ci%21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
6539fd4e5da5Sopenharmony_ci%65312 = OpImageSampleImplicitLod %v4float %6 %21 Nontemporal
6540fd4e5da5Sopenharmony_ciOpReturn
6541fd4e5da5Sopenharmony_ciOpFunctionEnd
6542fd4e5da5Sopenharmony_ci)";
6543fd4e5da5Sopenharmony_ci
6544fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
6545fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
6546fd4e5da5Sopenharmony_ci}
6547fd4e5da5Sopenharmony_ci
6548fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, NVBindlessSamplerBuiltins) {
6549fd4e5da5Sopenharmony_ci  const std::string text = R"(
6550fd4e5da5Sopenharmony_ci              OpCapability Shader
6551fd4e5da5Sopenharmony_ci              OpCapability Int64
6552fd4e5da5Sopenharmony_ci              OpCapability Image1D
6553fd4e5da5Sopenharmony_ci              OpCapability BindlessTextureNV
6554fd4e5da5Sopenharmony_ci              OpExtension "SPV_NV_bindless_texture"
6555fd4e5da5Sopenharmony_ci         %1 = OpExtInstImport "GLSL.std.450"
6556fd4e5da5Sopenharmony_ci              OpMemoryModel Logical GLSL450
6557fd4e5da5Sopenharmony_ci              OpSamplerImageAddressingModeNV 64
6558fd4e5da5Sopenharmony_ci              OpEntryPoint Fragment %main "main"
6559fd4e5da5Sopenharmony_ci              OpExecutionMode %main OriginUpperLeft
6560fd4e5da5Sopenharmony_ci              OpSource GLSL 450
6561fd4e5da5Sopenharmony_ci              OpName %main "main"
6562fd4e5da5Sopenharmony_ci              OpName %s2D "s2D"
6563fd4e5da5Sopenharmony_ci              OpName %textureHandle "textureHandle"
6564fd4e5da5Sopenharmony_ci              OpName %i1D "i1D"
6565fd4e5da5Sopenharmony_ci              OpName %s "s"
6566fd4e5da5Sopenharmony_ci              OpName %temp "temp"
6567fd4e5da5Sopenharmony_ci      %void = OpTypeVoid
6568fd4e5da5Sopenharmony_ci         %3 = OpTypeFunction %void
6569fd4e5da5Sopenharmony_ci     %float = OpTypeFloat 32
6570fd4e5da5Sopenharmony_ci         %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
6571fd4e5da5Sopenharmony_ci         %8 = OpTypeSampledImage %7
6572fd4e5da5Sopenharmony_ci%_ptr_Function_8 = OpTypePointer Function %8
6573fd4e5da5Sopenharmony_ci     %ulong = OpTypeInt 64 0
6574fd4e5da5Sopenharmony_ci%_ptr_Private_ulong = OpTypePointer Private %ulong
6575fd4e5da5Sopenharmony_ci%textureHandle = OpVariable %_ptr_Private_ulong Private
6576fd4e5da5Sopenharmony_ci        %16 = OpTypeImage %float 1D 0 0 0 2 Rgba32f
6577fd4e5da5Sopenharmony_ci%_ptr_Function_16 = OpTypePointer Function %16
6578fd4e5da5Sopenharmony_ci        %21 = OpTypeSampler
6579fd4e5da5Sopenharmony_ci%_ptr_Function_21 = OpTypePointer Function %21
6580fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong
6581fd4e5da5Sopenharmony_ci      %main = OpFunction %void None %3
6582fd4e5da5Sopenharmony_ci         %5 = OpLabel
6583fd4e5da5Sopenharmony_ci       %s2D = OpVariable %_ptr_Function_8 Function
6584fd4e5da5Sopenharmony_ci       %i1D = OpVariable %_ptr_Function_16 Function
6585fd4e5da5Sopenharmony_ci         %s = OpVariable %_ptr_Function_21 Function
6586fd4e5da5Sopenharmony_ci      %temp = OpVariable %_ptr_Function_ulong Function
6587fd4e5da5Sopenharmony_ci        %14 = OpLoad %ulong %textureHandle
6588fd4e5da5Sopenharmony_ci        %15 = OpConvertUToSampledImageNV %8 %14
6589fd4e5da5Sopenharmony_ci              OpStore %s2D %15
6590fd4e5da5Sopenharmony_ci        %19 = OpLoad %ulong %textureHandle
6591fd4e5da5Sopenharmony_ci        %20 = OpConvertUToImageNV %16 %19
6592fd4e5da5Sopenharmony_ci              OpStore %i1D %20
6593fd4e5da5Sopenharmony_ci        %24 = OpLoad %ulong %textureHandle
6594fd4e5da5Sopenharmony_ci        %25 = OpConvertUToSamplerNV %21 %24
6595fd4e5da5Sopenharmony_ci              OpStore %s %25
6596fd4e5da5Sopenharmony_ci        %28 = OpLoad %8 %s2D
6597fd4e5da5Sopenharmony_ci        %29 = OpConvertSampledImageToUNV %ulong %28
6598fd4e5da5Sopenharmony_ci              OpStore %temp %29
6599fd4e5da5Sopenharmony_ci        %30 = OpLoad %16 %i1D
6600fd4e5da5Sopenharmony_ci        %31 = OpConvertImageToUNV %ulong %30
6601fd4e5da5Sopenharmony_ci              OpStore %temp %31
6602fd4e5da5Sopenharmony_ci        %32 = OpLoad %21 %s
6603fd4e5da5Sopenharmony_ci        %33 = OpConvertSamplerToUNV %ulong %32
6604fd4e5da5Sopenharmony_ci              OpStore %temp %33
6605fd4e5da5Sopenharmony_ci              OpReturn
6606fd4e5da5Sopenharmony_ci              OpFunctionEnd
6607fd4e5da5Sopenharmony_ci)";
6608fd4e5da5Sopenharmony_ci
6609fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6610fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6611fd4e5da5Sopenharmony_ci}
6612fd4e5da5Sopenharmony_ci
6613fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, NVBindlessAddressingMode64) {
6614fd4e5da5Sopenharmony_ci  std::string text = R"(
6615fd4e5da5Sopenharmony_ci         OpCapability Shader
6616fd4e5da5Sopenharmony_ci         OpCapability BindlessTextureNV
6617fd4e5da5Sopenharmony_ci         OpExtension "SPV_NV_bindless_texture"
6618fd4e5da5Sopenharmony_ci         OpMemoryModel Logical GLSL450
6619fd4e5da5Sopenharmony_ci         OpSamplerImageAddressingModeNV 64
6620fd4e5da5Sopenharmony_ci         OpEntryPoint GLCompute %func "main"
6621fd4e5da5Sopenharmony_ci%voidt = OpTypeVoid
6622fd4e5da5Sopenharmony_ci%uintt = OpTypeInt 32 0
6623fd4e5da5Sopenharmony_ci%funct = OpTypeFunction %voidt
6624fd4e5da5Sopenharmony_ci%func  = OpFunction %voidt None %funct
6625fd4e5da5Sopenharmony_ci%entry = OpLabel
6626fd4e5da5Sopenharmony_ci%udef  = OpUndef %uintt
6627fd4e5da5Sopenharmony_ci         OpReturn
6628fd4e5da5Sopenharmony_ci         OpFunctionEnd
6629fd4e5da5Sopenharmony_ci)";
6630fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6631fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6632fd4e5da5Sopenharmony_ci}
6633fd4e5da5Sopenharmony_ci
6634fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, NVBindlessAddressingMode32) {
6635fd4e5da5Sopenharmony_ci  std::string text = R"(
6636fd4e5da5Sopenharmony_ci         OpCapability Shader
6637fd4e5da5Sopenharmony_ci         OpCapability BindlessTextureNV
6638fd4e5da5Sopenharmony_ci         OpExtension "SPV_NV_bindless_texture"
6639fd4e5da5Sopenharmony_ci         OpMemoryModel Logical GLSL450
6640fd4e5da5Sopenharmony_ci         OpSamplerImageAddressingModeNV 32
6641fd4e5da5Sopenharmony_ci         OpEntryPoint GLCompute %func "main"
6642fd4e5da5Sopenharmony_ci%voidt = OpTypeVoid
6643fd4e5da5Sopenharmony_ci%uintt = OpTypeInt 32 0
6644fd4e5da5Sopenharmony_ci%funct = OpTypeFunction %voidt
6645fd4e5da5Sopenharmony_ci%func  = OpFunction %voidt None %funct
6646fd4e5da5Sopenharmony_ci%entry = OpLabel
6647fd4e5da5Sopenharmony_ci%udef  = OpUndef %uintt
6648fd4e5da5Sopenharmony_ci         OpReturn
6649fd4e5da5Sopenharmony_ci         OpFunctionEnd
6650fd4e5da5Sopenharmony_ci)";
6651fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6652fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6653fd4e5da5Sopenharmony_ci}
6654fd4e5da5Sopenharmony_ci
6655fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, NVBindlessInvalidAddressingMode) {
6656fd4e5da5Sopenharmony_ci  std::string text = R"(
6657fd4e5da5Sopenharmony_ci         OpCapability Shader
6658fd4e5da5Sopenharmony_ci         OpCapability BindlessTextureNV
6659fd4e5da5Sopenharmony_ci         OpExtension "SPV_NV_bindless_texture"
6660fd4e5da5Sopenharmony_ci         OpMemoryModel Logical GLSL450
6661fd4e5da5Sopenharmony_ci         OpSamplerImageAddressingModeNV 0
6662fd4e5da5Sopenharmony_ci         OpEntryPoint GLCompute %func "main"
6663fd4e5da5Sopenharmony_ci%voidt = OpTypeVoid
6664fd4e5da5Sopenharmony_ci%uintt = OpTypeInt 32 0
6665fd4e5da5Sopenharmony_ci%funct = OpTypeFunction %voidt
6666fd4e5da5Sopenharmony_ci%func  = OpFunction %voidt None %funct
6667fd4e5da5Sopenharmony_ci%entry = OpLabel
6668fd4e5da5Sopenharmony_ci%udef  = OpUndef %uintt
6669fd4e5da5Sopenharmony_ci         OpReturn
6670fd4e5da5Sopenharmony_ci         OpFunctionEnd
6671fd4e5da5Sopenharmony_ci)";
6672fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6673fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6674fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6675fd4e5da5Sopenharmony_ci  EXPECT_THAT(
6676fd4e5da5Sopenharmony_ci      getDiagnosticString(),
6677fd4e5da5Sopenharmony_ci      HasSubstr("OpSamplerImageAddressingModeNV bitwidth should be 64 or 32"));
6678fd4e5da5Sopenharmony_ci}
6679fd4e5da5Sopenharmony_ci
6680fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationA) {
6681fd4e5da5Sopenharmony_ci  std::string text = R"(
6682fd4e5da5Sopenharmony_ci           OpCapability Shader
6683fd4e5da5Sopenharmony_ci           OpCapability TextureBlockMatchQCOM
6684fd4e5da5Sopenharmony_ci           OpExtension "SPV_QCOM_image_processing"
6685fd4e5da5Sopenharmony_ci      %1 = OpExtInstImport "GLSL.std.450"
6686fd4e5da5Sopenharmony_ci           OpMemoryModel Logical GLSL450
6687fd4e5da5Sopenharmony_ci           OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6688fd4e5da5Sopenharmony_ci           OpExecutionMode %2 OriginUpperLeft
6689fd4e5da5Sopenharmony_ci           OpDecorate %3 Location 0
6690fd4e5da5Sopenharmony_ci           OpDecorate %4 DescriptorSet 0
6691fd4e5da5Sopenharmony_ci           OpDecorate %4 Binding 1
6692fd4e5da5Sopenharmony_ci           OpDecorate %5 DescriptorSet 0
6693fd4e5da5Sopenharmony_ci           OpDecorate %5 Binding 3
6694fd4e5da5Sopenharmony_ci           OpDecorate %6 DescriptorSet 0
6695fd4e5da5Sopenharmony_ci           OpDecorate %6 Binding 2
6696fd4e5da5Sopenharmony_ci           OpDecorate %6 BlockMatchTextureQCOM
6697fd4e5da5Sopenharmony_ci   %void = OpTypeVoid
6698fd4e5da5Sopenharmony_ci      %8 = OpTypeFunction %void
6699fd4e5da5Sopenharmony_ci   %uint = OpTypeInt 32 0
6700fd4e5da5Sopenharmony_ci %v2uint = OpTypeVector %uint 2
6701fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
6702fd4e5da5Sopenharmony_ci  %float = OpTypeFloat 32
6703fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
6704fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
6705fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
6706fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
6707fd4e5da5Sopenharmony_ci    %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6708fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
6709fd4e5da5Sopenharmony_ci     %3 = OpVariable %_ptr_Output_v4float Output
6710fd4e5da5Sopenharmony_ci    %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6711fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6712fd4e5da5Sopenharmony_ci     %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6713fd4e5da5Sopenharmony_ci    %21 = OpTypeSampler
6714fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6715fd4e5da5Sopenharmony_ci    %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6716fd4e5da5Sopenharmony_ci   %23 = OpTypeSampledImage %19
6717fd4e5da5Sopenharmony_ci    %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6718fd4e5da5Sopenharmony_ci    %2 = OpFunction %void None %8
6719fd4e5da5Sopenharmony_ci   %24 = OpLabel
6720fd4e5da5Sopenharmony_ci   %25 = OpVariable %_ptr_Function_v2uint Function
6721fd4e5da5Sopenharmony_ci   %26 = OpLoad %19 %4
6722fd4e5da5Sopenharmony_ci   %27 = OpLoad %21 %5
6723fd4e5da5Sopenharmony_ci   %28 = OpSampledImage %23 %26 %27
6724fd4e5da5Sopenharmony_ci   %29 = OpLoad %v2uint %25
6725fd4e5da5Sopenharmony_ci   %30 = OpLoad %19 %6
6726fd4e5da5Sopenharmony_ci   %31 = OpLoad %21 %5
6727fd4e5da5Sopenharmony_ci   %32 = OpSampledImage %23 %30 %31
6728fd4e5da5Sopenharmony_ci   %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29
6729fd4e5da5Sopenharmony_ci         OpStore %3 %33
6730fd4e5da5Sopenharmony_ci         OpReturn
6731fd4e5da5Sopenharmony_ci         OpFunctionEnd
6732fd4e5da5Sopenharmony_ci)";
6733fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6734fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6735fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6736fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
6737fd4e5da5Sopenharmony_ci}
6738fd4e5da5Sopenharmony_ci
6739fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationB) {
6740fd4e5da5Sopenharmony_ci  std::string text = R"(
6741fd4e5da5Sopenharmony_ci           OpCapability Shader
6742fd4e5da5Sopenharmony_ci           OpCapability TextureBlockMatchQCOM
6743fd4e5da5Sopenharmony_ci           OpExtension "SPV_QCOM_image_processing"
6744fd4e5da5Sopenharmony_ci      %1 = OpExtInstImport "GLSL.std.450"
6745fd4e5da5Sopenharmony_ci           OpMemoryModel Logical GLSL450
6746fd4e5da5Sopenharmony_ci           OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6747fd4e5da5Sopenharmony_ci           OpExecutionMode %2 OriginUpperLeft
6748fd4e5da5Sopenharmony_ci           OpDecorate %3 Location 0
6749fd4e5da5Sopenharmony_ci           OpDecorate %4 DescriptorSet 0
6750fd4e5da5Sopenharmony_ci           OpDecorate %4 Binding 1
6751fd4e5da5Sopenharmony_ci           OpDecorate %5 DescriptorSet 0
6752fd4e5da5Sopenharmony_ci           OpDecorate %5 Binding 3
6753fd4e5da5Sopenharmony_ci           OpDecorate %5 BlockMatchTextureQCOM
6754fd4e5da5Sopenharmony_ci           OpDecorate %6 DescriptorSet 0
6755fd4e5da5Sopenharmony_ci           OpDecorate %6 Binding 2
6756fd4e5da5Sopenharmony_ci   %void = OpTypeVoid
6757fd4e5da5Sopenharmony_ci      %8 = OpTypeFunction %void
6758fd4e5da5Sopenharmony_ci   %uint = OpTypeInt 32 0
6759fd4e5da5Sopenharmony_ci %v2uint = OpTypeVector %uint 2
6760fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
6761fd4e5da5Sopenharmony_ci  %float = OpTypeFloat 32
6762fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
6763fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
6764fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
6765fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
6766fd4e5da5Sopenharmony_ci    %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6767fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
6768fd4e5da5Sopenharmony_ci     %3 = OpVariable %_ptr_Output_v4float Output
6769fd4e5da5Sopenharmony_ci    %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6770fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6771fd4e5da5Sopenharmony_ci     %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6772fd4e5da5Sopenharmony_ci    %21 = OpTypeSampler
6773fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6774fd4e5da5Sopenharmony_ci    %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6775fd4e5da5Sopenharmony_ci   %23 = OpTypeSampledImage %19
6776fd4e5da5Sopenharmony_ci    %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6777fd4e5da5Sopenharmony_ci    %2 = OpFunction %void None %8
6778fd4e5da5Sopenharmony_ci   %24 = OpLabel
6779fd4e5da5Sopenharmony_ci   %25 = OpVariable %_ptr_Function_v2uint Function
6780fd4e5da5Sopenharmony_ci   %26 = OpLoad %19 %4
6781fd4e5da5Sopenharmony_ci   %27 = OpLoad %21 %5
6782fd4e5da5Sopenharmony_ci   %28 = OpSampledImage %23 %26 %27
6783fd4e5da5Sopenharmony_ci   %29 = OpLoad %v2uint %25
6784fd4e5da5Sopenharmony_ci   %30 = OpLoad %19 %6
6785fd4e5da5Sopenharmony_ci   %31 = OpLoad %21 %5
6786fd4e5da5Sopenharmony_ci   %32 = OpSampledImage %23 %30 %31
6787fd4e5da5Sopenharmony_ci   %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29
6788fd4e5da5Sopenharmony_ci         OpStore %3 %33
6789fd4e5da5Sopenharmony_ci         OpReturn
6790fd4e5da5Sopenharmony_ci         OpFunctionEnd
6791fd4e5da5Sopenharmony_ci)";
6792fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6793fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6794fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6795fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
6796fd4e5da5Sopenharmony_ci}
6797fd4e5da5Sopenharmony_ci
6798fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationC) {
6799fd4e5da5Sopenharmony_ci  std::string text = R"(
6800fd4e5da5Sopenharmony_ci               OpCapability Shader
6801fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
6802fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
6803fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
6804fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
6805fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5
6806fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
6807fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
6808fd4e5da5Sopenharmony_ci               OpDecorate %4 DescriptorSet 0
6809fd4e5da5Sopenharmony_ci               OpDecorate %4 Binding 4
6810fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
6811fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 5
6812fd4e5da5Sopenharmony_ci               OpDecorate %5 BlockMatchTextureQCOM
6813fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
6814fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %void
6815fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
6816fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
6817fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
6818fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
6819fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
6820fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
6821fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
6822fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
6823fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
6824fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Output_v4float Output
6825fd4e5da5Sopenharmony_ci         %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
6826fd4e5da5Sopenharmony_ci         %19 = OpTypeSampledImage %18
6827fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6828fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6829fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6830fd4e5da5Sopenharmony_ci         %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
6831fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %7
6832fd4e5da5Sopenharmony_ci         %22 = OpLabel
6833fd4e5da5Sopenharmony_ci         %23 = OpVariable %_ptr_Function_v2uint Function
6834fd4e5da5Sopenharmony_ci         %24 = OpLoad %19 %4
6835fd4e5da5Sopenharmony_ci         %25 = OpLoad %v2uint %23
6836fd4e5da5Sopenharmony_ci         %26 = OpLoad %19 %5
6837fd4e5da5Sopenharmony_ci         %27 = OpLoad %v2uint %23
6838fd4e5da5Sopenharmony_ci         %28 = OpLoad %v2uint %23
6839fd4e5da5Sopenharmony_ci         %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28
6840fd4e5da5Sopenharmony_ci               OpStore %3 %29
6841fd4e5da5Sopenharmony_ci               OpReturn
6842fd4e5da5Sopenharmony_ci               OpFunctionEnd
6843fd4e5da5Sopenharmony_ci)";
6844fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6845fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6846fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6847fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
6848fd4e5da5Sopenharmony_ci}
6849fd4e5da5Sopenharmony_ci
6850fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationD) {
6851fd4e5da5Sopenharmony_ci  std::string text = R"(
6852fd4e5da5Sopenharmony_ci               OpCapability Shader
6853fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
6854fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
6855fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
6856fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
6857fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5
6858fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
6859fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
6860fd4e5da5Sopenharmony_ci               OpDecorate %4 DescriptorSet 0
6861fd4e5da5Sopenharmony_ci               OpDecorate %4 Binding 4
6862fd4e5da5Sopenharmony_ci               OpDecorate %4 BlockMatchTextureQCOM
6863fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
6864fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 5
6865fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
6866fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %void
6867fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
6868fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
6869fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
6870fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
6871fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
6872fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
6873fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
6874fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
6875fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
6876fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Output_v4float Output
6877fd4e5da5Sopenharmony_ci         %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
6878fd4e5da5Sopenharmony_ci         %19 = OpTypeSampledImage %18
6879fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6880fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6881fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6882fd4e5da5Sopenharmony_ci         %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
6883fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %7
6884fd4e5da5Sopenharmony_ci         %22 = OpLabel
6885fd4e5da5Sopenharmony_ci         %23 = OpVariable %_ptr_Function_v2uint Function
6886fd4e5da5Sopenharmony_ci         %24 = OpLoad %19 %4
6887fd4e5da5Sopenharmony_ci         %25 = OpLoad %v2uint %23
6888fd4e5da5Sopenharmony_ci         %26 = OpLoad %19 %5
6889fd4e5da5Sopenharmony_ci         %27 = OpLoad %v2uint %23
6890fd4e5da5Sopenharmony_ci         %28 = OpLoad %v2uint %23
6891fd4e5da5Sopenharmony_ci         %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28
6892fd4e5da5Sopenharmony_ci               OpStore %3 %29
6893fd4e5da5Sopenharmony_ci               OpReturn
6894fd4e5da5Sopenharmony_ci               OpFunctionEnd
6895fd4e5da5Sopenharmony_ci)";
6896fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6897fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6898fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6899fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
6900fd4e5da5Sopenharmony_ci}
6901fd4e5da5Sopenharmony_ci
6902fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationA) {
6903fd4e5da5Sopenharmony_ci  std::string text = R"(
6904fd4e5da5Sopenharmony_ci           OpCapability Shader
6905fd4e5da5Sopenharmony_ci           OpCapability TextureBlockMatchQCOM
6906fd4e5da5Sopenharmony_ci           OpExtension "SPV_QCOM_image_processing"
6907fd4e5da5Sopenharmony_ci      %1 = OpExtInstImport "GLSL.std.450"
6908fd4e5da5Sopenharmony_ci           OpMemoryModel Logical GLSL450
6909fd4e5da5Sopenharmony_ci           OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6910fd4e5da5Sopenharmony_ci           OpExecutionMode %2 OriginUpperLeft
6911fd4e5da5Sopenharmony_ci           OpDecorate %3 Location 0
6912fd4e5da5Sopenharmony_ci           OpDecorate %4 DescriptorSet 0
6913fd4e5da5Sopenharmony_ci           OpDecorate %4 Binding 1
6914fd4e5da5Sopenharmony_ci           OpDecorate %5 DescriptorSet 0
6915fd4e5da5Sopenharmony_ci           OpDecorate %5 Binding 3
6916fd4e5da5Sopenharmony_ci           OpDecorate %6 DescriptorSet 0
6917fd4e5da5Sopenharmony_ci           OpDecorate %6 Binding 2
6918fd4e5da5Sopenharmony_ci           OpDecorate %6 BlockMatchTextureQCOM
6919fd4e5da5Sopenharmony_ci   %void = OpTypeVoid
6920fd4e5da5Sopenharmony_ci      %8 = OpTypeFunction %void
6921fd4e5da5Sopenharmony_ci   %uint = OpTypeInt 32 0
6922fd4e5da5Sopenharmony_ci %v2uint = OpTypeVector %uint 2
6923fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
6924fd4e5da5Sopenharmony_ci  %float = OpTypeFloat 32
6925fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
6926fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
6927fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
6928fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
6929fd4e5da5Sopenharmony_ci    %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6930fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
6931fd4e5da5Sopenharmony_ci     %3 = OpVariable %_ptr_Output_v4float Output
6932fd4e5da5Sopenharmony_ci    %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6933fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6934fd4e5da5Sopenharmony_ci     %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6935fd4e5da5Sopenharmony_ci    %21 = OpTypeSampler
6936fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6937fd4e5da5Sopenharmony_ci    %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6938fd4e5da5Sopenharmony_ci   %23 = OpTypeSampledImage %19
6939fd4e5da5Sopenharmony_ci    %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6940fd4e5da5Sopenharmony_ci    %2 = OpFunction %void None %8
6941fd4e5da5Sopenharmony_ci   %24 = OpLabel
6942fd4e5da5Sopenharmony_ci   %25 = OpVariable %_ptr_Function_v2uint Function
6943fd4e5da5Sopenharmony_ci   %26 = OpLoad %19 %4
6944fd4e5da5Sopenharmony_ci   %27 = OpLoad %21 %5
6945fd4e5da5Sopenharmony_ci   %28 = OpSampledImage %23 %26 %27
6946fd4e5da5Sopenharmony_ci   %29 = OpLoad %v2uint %25
6947fd4e5da5Sopenharmony_ci   %30 = OpLoad %19 %6
6948fd4e5da5Sopenharmony_ci   %31 = OpLoad %21 %5
6949fd4e5da5Sopenharmony_ci   %32 = OpSampledImage %23 %30 %31
6950fd4e5da5Sopenharmony_ci   %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29
6951fd4e5da5Sopenharmony_ci         OpStore %3 %33
6952fd4e5da5Sopenharmony_ci         OpReturn
6953fd4e5da5Sopenharmony_ci         OpFunctionEnd
6954fd4e5da5Sopenharmony_ci)";
6955fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6956fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6957fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6958fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
6959fd4e5da5Sopenharmony_ci}
6960fd4e5da5Sopenharmony_ci
6961fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationB) {
6962fd4e5da5Sopenharmony_ci  std::string text = R"(
6963fd4e5da5Sopenharmony_ci           OpCapability Shader
6964fd4e5da5Sopenharmony_ci           OpCapability TextureBlockMatchQCOM
6965fd4e5da5Sopenharmony_ci           OpExtension "SPV_QCOM_image_processing"
6966fd4e5da5Sopenharmony_ci      %1 = OpExtInstImport "GLSL.std.450"
6967fd4e5da5Sopenharmony_ci           OpMemoryModel Logical GLSL450
6968fd4e5da5Sopenharmony_ci           OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6969fd4e5da5Sopenharmony_ci           OpExecutionMode %2 OriginUpperLeft
6970fd4e5da5Sopenharmony_ci           OpDecorate %3 Location 0
6971fd4e5da5Sopenharmony_ci           OpDecorate %4 DescriptorSet 0
6972fd4e5da5Sopenharmony_ci           OpDecorate %4 Binding 1
6973fd4e5da5Sopenharmony_ci           OpDecorate %5 DescriptorSet 0
6974fd4e5da5Sopenharmony_ci           OpDecorate %5 Binding 3
6975fd4e5da5Sopenharmony_ci           OpDecorate %5 BlockMatchTextureQCOM
6976fd4e5da5Sopenharmony_ci           OpDecorate %6 DescriptorSet 0
6977fd4e5da5Sopenharmony_ci           OpDecorate %6 Binding 2
6978fd4e5da5Sopenharmony_ci   %void = OpTypeVoid
6979fd4e5da5Sopenharmony_ci      %8 = OpTypeFunction %void
6980fd4e5da5Sopenharmony_ci   %uint = OpTypeInt 32 0
6981fd4e5da5Sopenharmony_ci %v2uint = OpTypeVector %uint 2
6982fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
6983fd4e5da5Sopenharmony_ci  %float = OpTypeFloat 32
6984fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
6985fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
6986fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
6987fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
6988fd4e5da5Sopenharmony_ci    %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6989fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
6990fd4e5da5Sopenharmony_ci     %3 = OpVariable %_ptr_Output_v4float Output
6991fd4e5da5Sopenharmony_ci    %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6992fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6993fd4e5da5Sopenharmony_ci     %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6994fd4e5da5Sopenharmony_ci    %21 = OpTypeSampler
6995fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6996fd4e5da5Sopenharmony_ci    %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6997fd4e5da5Sopenharmony_ci   %23 = OpTypeSampledImage %19
6998fd4e5da5Sopenharmony_ci    %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6999fd4e5da5Sopenharmony_ci    %2 = OpFunction %void None %8
7000fd4e5da5Sopenharmony_ci   %24 = OpLabel
7001fd4e5da5Sopenharmony_ci   %25 = OpVariable %_ptr_Function_v2uint Function
7002fd4e5da5Sopenharmony_ci   %26 = OpLoad %19 %4
7003fd4e5da5Sopenharmony_ci   %27 = OpLoad %21 %5
7004fd4e5da5Sopenharmony_ci   %28 = OpSampledImage %23 %26 %27
7005fd4e5da5Sopenharmony_ci   %29 = OpLoad %v2uint %25
7006fd4e5da5Sopenharmony_ci   %30 = OpLoad %19 %6
7007fd4e5da5Sopenharmony_ci   %31 = OpLoad %21 %5
7008fd4e5da5Sopenharmony_ci   %32 = OpSampledImage %23 %30 %31
7009fd4e5da5Sopenharmony_ci   %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29
7010fd4e5da5Sopenharmony_ci         OpStore %3 %33
7011fd4e5da5Sopenharmony_ci         OpReturn
7012fd4e5da5Sopenharmony_ci         OpFunctionEnd
7013fd4e5da5Sopenharmony_ci)";
7014fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7015fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7016fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7017fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
7018fd4e5da5Sopenharmony_ci}
7019fd4e5da5Sopenharmony_ci
7020fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationC) {
7021fd4e5da5Sopenharmony_ci  std::string text = R"(
7022fd4e5da5Sopenharmony_ci               OpCapability Shader
7023fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
7024fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7025fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7026fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7027fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5
7028fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
7029fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
7030fd4e5da5Sopenharmony_ci               OpDecorate %4 DescriptorSet 0
7031fd4e5da5Sopenharmony_ci               OpDecorate %4 Binding 4
7032fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
7033fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 5
7034fd4e5da5Sopenharmony_ci               OpDecorate %5 BlockMatchTextureQCOM
7035fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7036fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %void
7037fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
7038fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
7039fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
7040fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7041fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7042fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7043fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
7044fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
7045fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7046fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Output_v4float Output
7047fd4e5da5Sopenharmony_ci         %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7048fd4e5da5Sopenharmony_ci         %19 = OpTypeSampledImage %18
7049fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7050fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7051fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7052fd4e5da5Sopenharmony_ci         %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
7053fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %7
7054fd4e5da5Sopenharmony_ci         %22 = OpLabel
7055fd4e5da5Sopenharmony_ci         %23 = OpVariable %_ptr_Function_v2uint Function
7056fd4e5da5Sopenharmony_ci         %24 = OpLoad %19 %4
7057fd4e5da5Sopenharmony_ci         %25 = OpLoad %v2uint %23
7058fd4e5da5Sopenharmony_ci         %26 = OpLoad %19 %5
7059fd4e5da5Sopenharmony_ci         %27 = OpLoad %v2uint %23
7060fd4e5da5Sopenharmony_ci         %28 = OpLoad %v2uint %23
7061fd4e5da5Sopenharmony_ci         %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28
7062fd4e5da5Sopenharmony_ci               OpStore %3 %29
7063fd4e5da5Sopenharmony_ci               OpReturn
7064fd4e5da5Sopenharmony_ci               OpFunctionEnd
7065fd4e5da5Sopenharmony_ci)";
7066fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7067fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7068fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7069fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
7070fd4e5da5Sopenharmony_ci}
7071fd4e5da5Sopenharmony_ci
7072fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationD) {
7073fd4e5da5Sopenharmony_ci  std::string text = R"(
7074fd4e5da5Sopenharmony_ci               OpCapability Shader
7075fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
7076fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7077fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7078fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7079fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5
7080fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
7081fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
7082fd4e5da5Sopenharmony_ci               OpDecorate %4 DescriptorSet 0
7083fd4e5da5Sopenharmony_ci               OpDecorate %4 Binding 4
7084fd4e5da5Sopenharmony_ci               OpDecorate %4 BlockMatchTextureQCOM
7085fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
7086fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 5
7087fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7088fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %void
7089fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
7090fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
7091fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
7092fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7093fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7094fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7095fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
7096fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
7097fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7098fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Output_v4float Output
7099fd4e5da5Sopenharmony_ci         %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7100fd4e5da5Sopenharmony_ci         %19 = OpTypeSampledImage %18
7101fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7102fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7103fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7104fd4e5da5Sopenharmony_ci         %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
7105fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %7
7106fd4e5da5Sopenharmony_ci         %22 = OpLabel
7107fd4e5da5Sopenharmony_ci         %23 = OpVariable %_ptr_Function_v2uint Function
7108fd4e5da5Sopenharmony_ci         %24 = OpLoad %19 %4
7109fd4e5da5Sopenharmony_ci         %25 = OpLoad %v2uint %23
7110fd4e5da5Sopenharmony_ci         %26 = OpLoad %19 %5
7111fd4e5da5Sopenharmony_ci         %27 = OpLoad %v2uint %23
7112fd4e5da5Sopenharmony_ci         %28 = OpLoad %v2uint %23
7113fd4e5da5Sopenharmony_ci         %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28
7114fd4e5da5Sopenharmony_ci               OpStore %3 %29
7115fd4e5da5Sopenharmony_ci               OpReturn
7116fd4e5da5Sopenharmony_ci               OpFunctionEnd
7117fd4e5da5Sopenharmony_ci)";
7118fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7119fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7120fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7121fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
7122fd4e5da5Sopenharmony_ci}
7123fd4e5da5Sopenharmony_ci
7124fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationA) {
7125fd4e5da5Sopenharmony_ci  std::string text = R"(
7126fd4e5da5Sopenharmony_ci               OpCapability Shader
7127fd4e5da5Sopenharmony_ci               OpCapability TextureSampleWeightedQCOM
7128fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7129fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7130fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7131fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7
7132fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
7133fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
7134fd4e5da5Sopenharmony_ci               OpDecorate %4 DescriptorSet 0
7135fd4e5da5Sopenharmony_ci               OpDecorate %4 Binding 1
7136fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
7137fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 3
7138fd4e5da5Sopenharmony_ci               OpDecorate %6 Location 0
7139fd4e5da5Sopenharmony_ci               OpDecorate %7 DescriptorSet 0
7140fd4e5da5Sopenharmony_ci               OpDecorate %7 Binding 0
7141fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7142fd4e5da5Sopenharmony_ci          %9 = OpTypeFunction %void
7143fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7144fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7145fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7146fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Output_v4float Output
7147fd4e5da5Sopenharmony_ci         %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
7148fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
7149fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_UniformConstant_13 UniformConstant
7150fd4e5da5Sopenharmony_ci         %15 = OpTypeSampler
7151fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
7152fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_15 UniformConstant
7153fd4e5da5Sopenharmony_ci         %17 = OpTypeSampledImage %13
7154fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7155fd4e5da5Sopenharmony_ci          %6 = OpVariable %_ptr_Input_v4float Input
7156fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7157fd4e5da5Sopenharmony_ci         %20 = OpTypeImage %float 2D 0 1 0 1 Unknown
7158fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7159fd4e5da5Sopenharmony_ci          %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7160fd4e5da5Sopenharmony_ci         %22 = OpTypeSampledImage %20
7161fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
7162fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %9
7163fd4e5da5Sopenharmony_ci         %24 = OpLabel
7164fd4e5da5Sopenharmony_ci         %25 = OpLoad %13 %4
7165fd4e5da5Sopenharmony_ci         %26 = OpLoad %15 %5
7166fd4e5da5Sopenharmony_ci         %27 = OpSampledImage %17 %25 %26
7167fd4e5da5Sopenharmony_ci         %28 = OpLoad %v4float %6
7168fd4e5da5Sopenharmony_ci         %29 = OpVectorShuffle %v2float %28 %28 0 1
7169fd4e5da5Sopenharmony_ci         %30 = OpLoad %20 %7
7170fd4e5da5Sopenharmony_ci         %31 = OpLoad %15 %5
7171fd4e5da5Sopenharmony_ci         %32 = OpSampledImage %22 %30 %31
7172fd4e5da5Sopenharmony_ci         %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32
7173fd4e5da5Sopenharmony_ci               OpStore %3 %33
7174fd4e5da5Sopenharmony_ci               OpReturn
7175fd4e5da5Sopenharmony_ci               OpFunctionEnd
7176fd4e5da5Sopenharmony_ci)";
7177fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7178fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7179fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7180fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
7181fd4e5da5Sopenharmony_ci}
7182fd4e5da5Sopenharmony_ci
7183fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationB) {
7184fd4e5da5Sopenharmony_ci  std::string text = R"(
7185fd4e5da5Sopenharmony_ci               OpCapability Shader
7186fd4e5da5Sopenharmony_ci               OpCapability TextureSampleWeightedQCOM
7187fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7188fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7189fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7190fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7191fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
7192fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
7193fd4e5da5Sopenharmony_ci               OpDecorate %4 Location 0
7194fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
7195fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 4
7196fd4e5da5Sopenharmony_ci               OpDecorate %6 DescriptorSet 0
7197fd4e5da5Sopenharmony_ci               OpDecorate %6 Binding 5
7198fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7199fd4e5da5Sopenharmony_ci          %8 = OpTypeFunction %void
7200fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7201fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7202fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7203fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Output_v4float Output
7204fd4e5da5Sopenharmony_ci         %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
7205fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
7206fd4e5da5Sopenharmony_ci         %14 = OpTypeSampler
7207fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
7208fd4e5da5Sopenharmony_ci         %16 = OpTypeSampledImage %12
7209fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7210fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_Input_v4float Input
7211fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7212fd4e5da5Sopenharmony_ci         %19 = OpTypeImage %float 2D 0 1 0 1 Unknown
7213fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7214fd4e5da5Sopenharmony_ci         %21 = OpTypeSampledImage %19
7215fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
7216fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_16 UniformConstant
7217fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
7218fd4e5da5Sopenharmony_ci          %6 = OpVariable %_ptr_UniformConstant_21 UniformConstant
7219fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %8
7220fd4e5da5Sopenharmony_ci         %24 = OpLabel
7221fd4e5da5Sopenharmony_ci         %25 = OpLoad %16 %5
7222fd4e5da5Sopenharmony_ci         %26 = OpLoad %v4float %4
7223fd4e5da5Sopenharmony_ci         %27 = OpVectorShuffle %v2float %26 %26 0 1
7224fd4e5da5Sopenharmony_ci         %28 = OpLoad %21 %6
7225fd4e5da5Sopenharmony_ci         %29 = OpImageSampleWeightedQCOM %v4float %25 %27 %28
7226fd4e5da5Sopenharmony_ci               OpStore %3 %29
7227fd4e5da5Sopenharmony_ci               OpReturn
7228fd4e5da5Sopenharmony_ci               OpFunctionEnd
7229fd4e5da5Sopenharmony_ci)";
7230fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7231fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7232fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7233fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
7234fd4e5da5Sopenharmony_ci}
7235fd4e5da5Sopenharmony_ci
7236fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseA) {
7237fd4e5da5Sopenharmony_ci  std::string text = R"(
7238fd4e5da5Sopenharmony_ci; SPIR-V
7239fd4e5da5Sopenharmony_ci; Version: 1.0
7240fd4e5da5Sopenharmony_ci; Generator: Khronos Glslang Reference Front End; 11
7241fd4e5da5Sopenharmony_ci; Bound: 79
7242fd4e5da5Sopenharmony_ci; Schema: 0
7243fd4e5da5Sopenharmony_ci               OpCapability Shader
7244fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
7245fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7246fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7247fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7248fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7249fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
7250fd4e5da5Sopenharmony_ci               OpDecorate %100 Location 0
7251fd4e5da5Sopenharmony_ci               OpDecorate %101 Location 0
7252fd4e5da5Sopenharmony_ci               OpDecorate %102 DescriptorSet 0
7253fd4e5da5Sopenharmony_ci               OpDecorate %102 Binding 1
7254fd4e5da5Sopenharmony_ci               OpDecorate %103 DescriptorSet 0
7255fd4e5da5Sopenharmony_ci               OpDecorate %103 Binding 3
7256fd4e5da5Sopenharmony_ci               OpDecorate %104 DescriptorSet 0
7257fd4e5da5Sopenharmony_ci               OpDecorate %104 Binding 2
7258fd4e5da5Sopenharmony_ci               OpDecorate %102 BlockMatchTextureQCOM
7259fd4e5da5Sopenharmony_ci               OpDecorate %104 BlockMatchTextureQCOM
7260fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7261fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
7262fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
7263fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
7264fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
7265fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7266fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7267fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7268fd4e5da5Sopenharmony_ci %100 = OpVariable %_ptr_Input_v4float Input
7269fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7270fd4e5da5Sopenharmony_ci  %101 = OpVariable %_ptr_Output_v4float Output
7271fd4e5da5Sopenharmony_ci         %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7272fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7273fd4e5da5Sopenharmony_ci %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7274fd4e5da5Sopenharmony_ci         %46 = OpTypeSampler
7275fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7276fd4e5da5Sopenharmony_ci       %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7277fd4e5da5Sopenharmony_ci         %50 = OpTypeSampledImage %42
7278fd4e5da5Sopenharmony_ci %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7279fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7280fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
7281fd4e5da5Sopenharmony_ci          %5 = OpLabel
7282fd4e5da5Sopenharmony_ci         %15 = OpVariable %_ptr_Function_v2uint Function
7283fd4e5da5Sopenharmony_ci         %45 = OpLoad %42 %102
7284fd4e5da5Sopenharmony_ci         %49 = OpLoad %46 %103
7285fd4e5da5Sopenharmony_ci         %51 = OpSampledImage %50 %45 %49
7286fd4e5da5Sopenharmony_ci         %52 = OpLoad %v2uint %15
7287fd4e5da5Sopenharmony_ci         %54 = OpLoad %42 %104
7288fd4e5da5Sopenharmony_ci         %55 = OpLoad %46 %103
7289fd4e5da5Sopenharmony_ci         %56 = OpSampledImage %50 %54 %55
7290fd4e5da5Sopenharmony_ci         %57 = OpLoad %v2uint %15
7291fd4e5da5Sopenharmony_ci         %58 = OpLoad %v2uint %15
7292fd4e5da5Sopenharmony_ci         %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58
7293fd4e5da5Sopenharmony_ci               OpStore %101 %59
7294fd4e5da5Sopenharmony_ci         %69 = OpLoad %42 %102
7295fd4e5da5Sopenharmony_ci         %70 = OpLoad %46 %103
7296fd4e5da5Sopenharmony_ci         %71 = OpSampledImage %50 %69 %70
7297fd4e5da5Sopenharmony_ci         %73 = OpLoad %v4float %100
7298fd4e5da5Sopenharmony_ci         %74 = OpVectorShuffle %v2float %73 %73 0 0
7299fd4e5da5Sopenharmony_ci         %75 = OpImageSampleImplicitLod %v4float %71 %74
7300fd4e5da5Sopenharmony_ci               OpStore %101 %75
7301fd4e5da5Sopenharmony_ci               OpReturn
7302fd4e5da5Sopenharmony_ci               OpFunctionEnd
7303fd4e5da5Sopenharmony_ci)";
7304fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7305fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7306fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7307fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7308fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7309fd4e5da5Sopenharmony_ci      HasSubstr("Illegal use of QCOM image processing decorated texture"));
7310fd4e5da5Sopenharmony_ci}
7311fd4e5da5Sopenharmony_ci
7312fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseB) {
7313fd4e5da5Sopenharmony_ci  std::string text = R"(
7314fd4e5da5Sopenharmony_ci; SPIR-V
7315fd4e5da5Sopenharmony_ci; Version: 1.0
7316fd4e5da5Sopenharmony_ci; Generator: Khronos Glslang Reference Front End; 11
7317fd4e5da5Sopenharmony_ci; Bound: 79
7318fd4e5da5Sopenharmony_ci; Schema: 0
7319fd4e5da5Sopenharmony_ci               OpCapability Shader
7320fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
7321fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7322fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7323fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7324fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7325fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
7326fd4e5da5Sopenharmony_ci               OpDecorate %100 Location 0
7327fd4e5da5Sopenharmony_ci               OpDecorate %101 Location 0
7328fd4e5da5Sopenharmony_ci               OpDecorate %102 DescriptorSet 0
7329fd4e5da5Sopenharmony_ci               OpDecorate %102 Binding 1
7330fd4e5da5Sopenharmony_ci               OpDecorate %103 DescriptorSet 0
7331fd4e5da5Sopenharmony_ci               OpDecorate %103 Binding 3
7332fd4e5da5Sopenharmony_ci               OpDecorate %104 DescriptorSet 0
7333fd4e5da5Sopenharmony_ci               OpDecorate %104 Binding 2
7334fd4e5da5Sopenharmony_ci               OpDecorate %102 BlockMatchTextureQCOM
7335fd4e5da5Sopenharmony_ci               OpDecorate %104 BlockMatchTextureQCOM
7336fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7337fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
7338fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
7339fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
7340fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
7341fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7342fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7343fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7344fd4e5da5Sopenharmony_ci %100 = OpVariable %_ptr_Input_v4float Input
7345fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7346fd4e5da5Sopenharmony_ci  %101 = OpVariable %_ptr_Output_v4float Output
7347fd4e5da5Sopenharmony_ci         %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7348fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7349fd4e5da5Sopenharmony_ci %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7350fd4e5da5Sopenharmony_ci         %46 = OpTypeSampler
7351fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7352fd4e5da5Sopenharmony_ci       %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7353fd4e5da5Sopenharmony_ci         %50 = OpTypeSampledImage %42
7354fd4e5da5Sopenharmony_ci %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7355fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7356fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
7357fd4e5da5Sopenharmony_ci          %5 = OpLabel
7358fd4e5da5Sopenharmony_ci         %15 = OpVariable %_ptr_Function_v2uint Function
7359fd4e5da5Sopenharmony_ci         %45 = OpLoad %42 %102
7360fd4e5da5Sopenharmony_ci         %49 = OpLoad %46 %103
7361fd4e5da5Sopenharmony_ci         %51 = OpSampledImage %50 %45 %49
7362fd4e5da5Sopenharmony_ci         %52 = OpLoad %v2uint %15
7363fd4e5da5Sopenharmony_ci         %54 = OpLoad %42 %104
7364fd4e5da5Sopenharmony_ci         %55 = OpLoad %46 %103
7365fd4e5da5Sopenharmony_ci         %56 = OpSampledImage %50 %54 %55
7366fd4e5da5Sopenharmony_ci         %57 = OpLoad %v2uint %15
7367fd4e5da5Sopenharmony_ci         %58 = OpLoad %v2uint %15
7368fd4e5da5Sopenharmony_ci         %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58
7369fd4e5da5Sopenharmony_ci               OpStore %101 %59
7370fd4e5da5Sopenharmony_ci         %69 = OpLoad %42 %104
7371fd4e5da5Sopenharmony_ci         %70 = OpLoad %46 %103
7372fd4e5da5Sopenharmony_ci         %71 = OpSampledImage %50 %69 %70
7373fd4e5da5Sopenharmony_ci         %73 = OpLoad %v4float %100
7374fd4e5da5Sopenharmony_ci         %74 = OpVectorShuffle %v2float %73 %73 0 0
7375fd4e5da5Sopenharmony_ci         %75 = OpImageSampleImplicitLod %v4float %71 %74
7376fd4e5da5Sopenharmony_ci               OpStore %101 %75
7377fd4e5da5Sopenharmony_ci               OpReturn
7378fd4e5da5Sopenharmony_ci               OpFunctionEnd
7379fd4e5da5Sopenharmony_ci)";
7380fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7381fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7382fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7383fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7384fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7385fd4e5da5Sopenharmony_ci      HasSubstr("Illegal use of QCOM image processing decorated texture"));
7386fd4e5da5Sopenharmony_ci}
7387fd4e5da5Sopenharmony_ci
7388fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseC) {
7389fd4e5da5Sopenharmony_ci  std::string text = R"(
7390fd4e5da5Sopenharmony_ci               OpCapability Shader
7391fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
7392fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7393fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7394fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7395fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7396fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
7397fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
7398fd4e5da5Sopenharmony_ci               OpDecorate %4 Location 0
7399fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
7400fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 4
7401fd4e5da5Sopenharmony_ci               OpDecorate %6 DescriptorSet 0
7402fd4e5da5Sopenharmony_ci               OpDecorate %6 Binding 5
7403fd4e5da5Sopenharmony_ci               OpDecorate %5 BlockMatchTextureQCOM
7404fd4e5da5Sopenharmony_ci               OpDecorate %6 BlockMatchTextureQCOM
7405fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7406fd4e5da5Sopenharmony_ci          %8 = OpTypeFunction %void
7407fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
7408fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
7409fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
7410fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7411fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7412fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7413fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Input_v4float Input
7414fd4e5da5Sopenharmony_ci     %uint_4 = OpConstant %uint 4
7415fd4e5da5Sopenharmony_ci         %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7416fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7417fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_Output_v4float Output
7418fd4e5da5Sopenharmony_ci         %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7419fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7420fd4e5da5Sopenharmony_ci         %20 = OpTypeSampledImage %18
7421fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7422fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7423fd4e5da5Sopenharmony_ci          %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7424fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7425fd4e5da5Sopenharmony_ci         %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7426fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %8
7427fd4e5da5Sopenharmony_ci         %24 = OpLabel
7428fd4e5da5Sopenharmony_ci         %25 = OpVariable %_ptr_Function_v2uint Function
7429fd4e5da5Sopenharmony_ci               OpStore %25 %16
7430fd4e5da5Sopenharmony_ci         %26 = OpLoad %20 %5
7431fd4e5da5Sopenharmony_ci         %27 = OpLoad %v2uint %25
7432fd4e5da5Sopenharmony_ci         %28 = OpLoad %20 %6
7433fd4e5da5Sopenharmony_ci         %29 = OpLoad %v2uint %25
7434fd4e5da5Sopenharmony_ci         %30 = OpLoad %v2uint %25
7435fd4e5da5Sopenharmony_ci         %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30
7436fd4e5da5Sopenharmony_ci               OpStore %4 %31
7437fd4e5da5Sopenharmony_ci         %32 = OpLoad %20 %5
7438fd4e5da5Sopenharmony_ci         %33 = OpLoad %v4float %3
7439fd4e5da5Sopenharmony_ci         %34 = OpVectorShuffle %v2float %33 %33 0 2
7440fd4e5da5Sopenharmony_ci         %35 = OpImageSampleImplicitLod %v4float %32 %34
7441fd4e5da5Sopenharmony_ci               OpStore %4 %35
7442fd4e5da5Sopenharmony_ci               OpReturn
7443fd4e5da5Sopenharmony_ci               OpFunctionEnd
7444fd4e5da5Sopenharmony_ci)";
7445fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7446fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7447fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7448fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7449fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7450fd4e5da5Sopenharmony_ci      HasSubstr("Illegal use of QCOM image processing decorated texture"));
7451fd4e5da5Sopenharmony_ci}
7452fd4e5da5Sopenharmony_ci
7453fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseD) {
7454fd4e5da5Sopenharmony_ci  std::string text = R"(
7455fd4e5da5Sopenharmony_ci               OpCapability Shader
7456fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
7457fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7458fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7459fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7460fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7461fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
7462fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
7463fd4e5da5Sopenharmony_ci               OpDecorate %4 Location 0
7464fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
7465fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 4
7466fd4e5da5Sopenharmony_ci               OpDecorate %6 DescriptorSet 0
7467fd4e5da5Sopenharmony_ci               OpDecorate %6 Binding 5
7468fd4e5da5Sopenharmony_ci               OpDecorate %5 BlockMatchTextureQCOM
7469fd4e5da5Sopenharmony_ci               OpDecorate %6 BlockMatchTextureQCOM
7470fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7471fd4e5da5Sopenharmony_ci          %8 = OpTypeFunction %void
7472fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
7473fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
7474fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
7475fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7476fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7477fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7478fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Input_v4float Input
7479fd4e5da5Sopenharmony_ci     %uint_4 = OpConstant %uint 4
7480fd4e5da5Sopenharmony_ci         %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7481fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7482fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_Output_v4float Output
7483fd4e5da5Sopenharmony_ci         %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7484fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7485fd4e5da5Sopenharmony_ci         %20 = OpTypeSampledImage %18
7486fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7487fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7488fd4e5da5Sopenharmony_ci          %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7489fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7490fd4e5da5Sopenharmony_ci         %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7491fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %8
7492fd4e5da5Sopenharmony_ci         %24 = OpLabel
7493fd4e5da5Sopenharmony_ci         %25 = OpVariable %_ptr_Function_v2uint Function
7494fd4e5da5Sopenharmony_ci               OpStore %25 %16
7495fd4e5da5Sopenharmony_ci         %26 = OpLoad %20 %5
7496fd4e5da5Sopenharmony_ci         %27 = OpLoad %v2uint %25
7497fd4e5da5Sopenharmony_ci         %28 = OpLoad %20 %6
7498fd4e5da5Sopenharmony_ci         %29 = OpLoad %v2uint %25
7499fd4e5da5Sopenharmony_ci         %30 = OpLoad %v2uint %25
7500fd4e5da5Sopenharmony_ci         %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30
7501fd4e5da5Sopenharmony_ci               OpStore %4 %31
7502fd4e5da5Sopenharmony_ci         %32 = OpLoad %20 %6
7503fd4e5da5Sopenharmony_ci         %33 = OpLoad %v4float %3
7504fd4e5da5Sopenharmony_ci         %34 = OpVectorShuffle %v2float %33 %33 0 2
7505fd4e5da5Sopenharmony_ci         %35 = OpImageSampleImplicitLod %v4float %32 %34
7506fd4e5da5Sopenharmony_ci               OpStore %4 %35
7507fd4e5da5Sopenharmony_ci               OpReturn
7508fd4e5da5Sopenharmony_ci               OpFunctionEnd
7509fd4e5da5Sopenharmony_ci)";
7510fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7511fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7512fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7513fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7514fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7515fd4e5da5Sopenharmony_ci      HasSubstr("Illegal use of QCOM image processing decorated texture"));
7516fd4e5da5Sopenharmony_ci}
7517fd4e5da5Sopenharmony_ci
7518fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseA) {
7519fd4e5da5Sopenharmony_ci  std::string text = R"(
7520fd4e5da5Sopenharmony_ci; SPIR-V
7521fd4e5da5Sopenharmony_ci; Version: 1.0
7522fd4e5da5Sopenharmony_ci; Generator: Khronos Glslang Reference Front End; 11
7523fd4e5da5Sopenharmony_ci; Bound: 79
7524fd4e5da5Sopenharmony_ci; Schema: 0
7525fd4e5da5Sopenharmony_ci               OpCapability Shader
7526fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
7527fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7528fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7529fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7530fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7531fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
7532fd4e5da5Sopenharmony_ci               OpDecorate %100 Location 0
7533fd4e5da5Sopenharmony_ci               OpDecorate %101 Location 0
7534fd4e5da5Sopenharmony_ci               OpDecorate %102 DescriptorSet 0
7535fd4e5da5Sopenharmony_ci               OpDecorate %102 Binding 1
7536fd4e5da5Sopenharmony_ci               OpDecorate %103 DescriptorSet 0
7537fd4e5da5Sopenharmony_ci               OpDecorate %103 Binding 3
7538fd4e5da5Sopenharmony_ci               OpDecorate %104 DescriptorSet 0
7539fd4e5da5Sopenharmony_ci               OpDecorate %104 Binding 2
7540fd4e5da5Sopenharmony_ci               OpDecorate %102 BlockMatchTextureQCOM
7541fd4e5da5Sopenharmony_ci               OpDecorate %104 BlockMatchTextureQCOM
7542fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7543fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
7544fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
7545fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
7546fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
7547fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7548fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7549fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7550fd4e5da5Sopenharmony_ci %100 = OpVariable %_ptr_Input_v4float Input
7551fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7552fd4e5da5Sopenharmony_ci  %101 = OpVariable %_ptr_Output_v4float Output
7553fd4e5da5Sopenharmony_ci         %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7554fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7555fd4e5da5Sopenharmony_ci %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7556fd4e5da5Sopenharmony_ci         %46 = OpTypeSampler
7557fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7558fd4e5da5Sopenharmony_ci       %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7559fd4e5da5Sopenharmony_ci         %50 = OpTypeSampledImage %42
7560fd4e5da5Sopenharmony_ci %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7561fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7562fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
7563fd4e5da5Sopenharmony_ci          %5 = OpLabel
7564fd4e5da5Sopenharmony_ci         %15 = OpVariable %_ptr_Function_v2uint Function
7565fd4e5da5Sopenharmony_ci         %45 = OpLoad %42 %102
7566fd4e5da5Sopenharmony_ci         %49 = OpLoad %46 %103
7567fd4e5da5Sopenharmony_ci         %51 = OpSampledImage %50 %45 %49
7568fd4e5da5Sopenharmony_ci         %52 = OpLoad %v2uint %15
7569fd4e5da5Sopenharmony_ci         %54 = OpLoad %42 %104
7570fd4e5da5Sopenharmony_ci         %55 = OpLoad %46 %103
7571fd4e5da5Sopenharmony_ci         %56 = OpSampledImage %50 %54 %55
7572fd4e5da5Sopenharmony_ci         %57 = OpLoad %v2uint %15
7573fd4e5da5Sopenharmony_ci         %58 = OpLoad %v2uint %15
7574fd4e5da5Sopenharmony_ci         %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58
7575fd4e5da5Sopenharmony_ci               OpStore %101 %59
7576fd4e5da5Sopenharmony_ci         %69 = OpLoad %42 %102
7577fd4e5da5Sopenharmony_ci         %70 = OpLoad %46 %103
7578fd4e5da5Sopenharmony_ci         %71 = OpSampledImage %50 %69 %70
7579fd4e5da5Sopenharmony_ci         %73 = OpLoad %v4float %100
7580fd4e5da5Sopenharmony_ci         %74 = OpVectorShuffle %v2float %73 %73 0 0
7581fd4e5da5Sopenharmony_ci         %75 = OpImageSampleImplicitLod %v4float %71 %74
7582fd4e5da5Sopenharmony_ci               OpStore %101 %75
7583fd4e5da5Sopenharmony_ci               OpReturn
7584fd4e5da5Sopenharmony_ci               OpFunctionEnd
7585fd4e5da5Sopenharmony_ci)";
7586fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7587fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7588fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7589fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7590fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7591fd4e5da5Sopenharmony_ci      HasSubstr("Illegal use of QCOM image processing decorated texture"));
7592fd4e5da5Sopenharmony_ci}
7593fd4e5da5Sopenharmony_ci
7594fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseB) {
7595fd4e5da5Sopenharmony_ci  std::string text = R"(
7596fd4e5da5Sopenharmony_ci; SPIR-V
7597fd4e5da5Sopenharmony_ci; Version: 1.0
7598fd4e5da5Sopenharmony_ci; Generator: Khronos Glslang Reference Front End; 11
7599fd4e5da5Sopenharmony_ci; Bound: 79
7600fd4e5da5Sopenharmony_ci; Schema: 0
7601fd4e5da5Sopenharmony_ci               OpCapability Shader
7602fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
7603fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7604fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7605fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7606fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7607fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
7608fd4e5da5Sopenharmony_ci               OpDecorate %100 Location 0
7609fd4e5da5Sopenharmony_ci               OpDecorate %101 Location 0
7610fd4e5da5Sopenharmony_ci               OpDecorate %102 DescriptorSet 0
7611fd4e5da5Sopenharmony_ci               OpDecorate %102 Binding 1
7612fd4e5da5Sopenharmony_ci               OpDecorate %103 DescriptorSet 0
7613fd4e5da5Sopenharmony_ci               OpDecorate %103 Binding 3
7614fd4e5da5Sopenharmony_ci               OpDecorate %104 DescriptorSet 0
7615fd4e5da5Sopenharmony_ci               OpDecorate %104 Binding 2
7616fd4e5da5Sopenharmony_ci               OpDecorate %102 BlockMatchTextureQCOM
7617fd4e5da5Sopenharmony_ci               OpDecorate %104 BlockMatchTextureQCOM
7618fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7619fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
7620fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
7621fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
7622fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
7623fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7624fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7625fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7626fd4e5da5Sopenharmony_ci %100 = OpVariable %_ptr_Input_v4float Input
7627fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7628fd4e5da5Sopenharmony_ci  %101 = OpVariable %_ptr_Output_v4float Output
7629fd4e5da5Sopenharmony_ci         %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7630fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7631fd4e5da5Sopenharmony_ci %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7632fd4e5da5Sopenharmony_ci         %46 = OpTypeSampler
7633fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7634fd4e5da5Sopenharmony_ci       %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7635fd4e5da5Sopenharmony_ci         %50 = OpTypeSampledImage %42
7636fd4e5da5Sopenharmony_ci %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7637fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7638fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
7639fd4e5da5Sopenharmony_ci          %5 = OpLabel
7640fd4e5da5Sopenharmony_ci         %15 = OpVariable %_ptr_Function_v2uint Function
7641fd4e5da5Sopenharmony_ci         %45 = OpLoad %42 %102
7642fd4e5da5Sopenharmony_ci         %49 = OpLoad %46 %103
7643fd4e5da5Sopenharmony_ci         %51 = OpSampledImage %50 %45 %49
7644fd4e5da5Sopenharmony_ci         %52 = OpLoad %v2uint %15
7645fd4e5da5Sopenharmony_ci         %54 = OpLoad %42 %104
7646fd4e5da5Sopenharmony_ci         %55 = OpLoad %46 %103
7647fd4e5da5Sopenharmony_ci         %56 = OpSampledImage %50 %54 %55
7648fd4e5da5Sopenharmony_ci         %57 = OpLoad %v2uint %15
7649fd4e5da5Sopenharmony_ci         %58 = OpLoad %v2uint %15
7650fd4e5da5Sopenharmony_ci         %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58
7651fd4e5da5Sopenharmony_ci               OpStore %101 %59
7652fd4e5da5Sopenharmony_ci         %69 = OpLoad %42 %104
7653fd4e5da5Sopenharmony_ci         %70 = OpLoad %46 %103
7654fd4e5da5Sopenharmony_ci         %71 = OpSampledImage %50 %69 %70
7655fd4e5da5Sopenharmony_ci         %73 = OpLoad %v4float %100
7656fd4e5da5Sopenharmony_ci         %74 = OpVectorShuffle %v2float %73 %73 0 0
7657fd4e5da5Sopenharmony_ci         %75 = OpImageSampleImplicitLod %v4float %71 %74
7658fd4e5da5Sopenharmony_ci               OpStore %101 %75
7659fd4e5da5Sopenharmony_ci               OpReturn
7660fd4e5da5Sopenharmony_ci               OpFunctionEnd
7661fd4e5da5Sopenharmony_ci)";
7662fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7663fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7664fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7665fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7666fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7667fd4e5da5Sopenharmony_ci      HasSubstr("Illegal use of QCOM image processing decorated texture"));
7668fd4e5da5Sopenharmony_ci}
7669fd4e5da5Sopenharmony_ci
7670fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseC) {
7671fd4e5da5Sopenharmony_ci  std::string text = R"(
7672fd4e5da5Sopenharmony_ci               OpCapability Shader
7673fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
7674fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7675fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7676fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7677fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7678fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
7679fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
7680fd4e5da5Sopenharmony_ci               OpDecorate %4 Location 0
7681fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
7682fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 4
7683fd4e5da5Sopenharmony_ci               OpDecorate %6 DescriptorSet 0
7684fd4e5da5Sopenharmony_ci               OpDecorate %6 Binding 5
7685fd4e5da5Sopenharmony_ci               OpDecorate %5 BlockMatchTextureQCOM
7686fd4e5da5Sopenharmony_ci               OpDecorate %6 BlockMatchTextureQCOM
7687fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7688fd4e5da5Sopenharmony_ci          %8 = OpTypeFunction %void
7689fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
7690fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
7691fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
7692fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7693fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7694fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7695fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Input_v4float Input
7696fd4e5da5Sopenharmony_ci     %uint_4 = OpConstant %uint 4
7697fd4e5da5Sopenharmony_ci         %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7698fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7699fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_Output_v4float Output
7700fd4e5da5Sopenharmony_ci         %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7701fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7702fd4e5da5Sopenharmony_ci         %20 = OpTypeSampledImage %18
7703fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7704fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7705fd4e5da5Sopenharmony_ci          %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7706fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7707fd4e5da5Sopenharmony_ci         %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7708fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %8
7709fd4e5da5Sopenharmony_ci         %24 = OpLabel
7710fd4e5da5Sopenharmony_ci         %25 = OpVariable %_ptr_Function_v2uint Function
7711fd4e5da5Sopenharmony_ci               OpStore %25 %16
7712fd4e5da5Sopenharmony_ci         %26 = OpLoad %20 %5
7713fd4e5da5Sopenharmony_ci         %27 = OpLoad %v2uint %25
7714fd4e5da5Sopenharmony_ci         %28 = OpLoad %20 %6
7715fd4e5da5Sopenharmony_ci         %29 = OpLoad %v2uint %25
7716fd4e5da5Sopenharmony_ci         %30 = OpLoad %v2uint %25
7717fd4e5da5Sopenharmony_ci         %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30
7718fd4e5da5Sopenharmony_ci               OpStore %4 %31
7719fd4e5da5Sopenharmony_ci         %32 = OpLoad %20 %5
7720fd4e5da5Sopenharmony_ci         %33 = OpLoad %v4float %3
7721fd4e5da5Sopenharmony_ci         %34 = OpVectorShuffle %v2float %33 %33 0 2
7722fd4e5da5Sopenharmony_ci         %35 = OpImageSampleImplicitLod %v4float %32 %34
7723fd4e5da5Sopenharmony_ci               OpStore %4 %35
7724fd4e5da5Sopenharmony_ci               OpReturn
7725fd4e5da5Sopenharmony_ci               OpFunctionEnd
7726fd4e5da5Sopenharmony_ci)";
7727fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7728fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7729fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7730fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7731fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7732fd4e5da5Sopenharmony_ci      HasSubstr("Illegal use of QCOM image processing decorated texture"));
7733fd4e5da5Sopenharmony_ci}
7734fd4e5da5Sopenharmony_ci
7735fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseD) {
7736fd4e5da5Sopenharmony_ci  std::string text = R"(
7737fd4e5da5Sopenharmony_ci               OpCapability Shader
7738fd4e5da5Sopenharmony_ci               OpCapability TextureBlockMatchQCOM
7739fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7740fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7741fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7742fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7743fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
7744fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
7745fd4e5da5Sopenharmony_ci               OpDecorate %4 Location 0
7746fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
7747fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 4
7748fd4e5da5Sopenharmony_ci               OpDecorate %6 DescriptorSet 0
7749fd4e5da5Sopenharmony_ci               OpDecorate %6 Binding 5
7750fd4e5da5Sopenharmony_ci               OpDecorate %5 BlockMatchTextureQCOM
7751fd4e5da5Sopenharmony_ci               OpDecorate %6 BlockMatchTextureQCOM
7752fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7753fd4e5da5Sopenharmony_ci          %8 = OpTypeFunction %void
7754fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
7755fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
7756fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
7757fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7758fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7759fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7760fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Input_v4float Input
7761fd4e5da5Sopenharmony_ci     %uint_4 = OpConstant %uint 4
7762fd4e5da5Sopenharmony_ci         %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7763fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7764fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_Output_v4float Output
7765fd4e5da5Sopenharmony_ci         %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7766fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7767fd4e5da5Sopenharmony_ci         %20 = OpTypeSampledImage %18
7768fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7769fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7770fd4e5da5Sopenharmony_ci          %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7771fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7772fd4e5da5Sopenharmony_ci         %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7773fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %8
7774fd4e5da5Sopenharmony_ci         %24 = OpLabel
7775fd4e5da5Sopenharmony_ci         %25 = OpVariable %_ptr_Function_v2uint Function
7776fd4e5da5Sopenharmony_ci               OpStore %25 %16
7777fd4e5da5Sopenharmony_ci         %26 = OpLoad %20 %5
7778fd4e5da5Sopenharmony_ci         %27 = OpLoad %v2uint %25
7779fd4e5da5Sopenharmony_ci         %28 = OpLoad %20 %6
7780fd4e5da5Sopenharmony_ci         %29 = OpLoad %v2uint %25
7781fd4e5da5Sopenharmony_ci         %30 = OpLoad %v2uint %25
7782fd4e5da5Sopenharmony_ci         %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30
7783fd4e5da5Sopenharmony_ci               OpStore %4 %31
7784fd4e5da5Sopenharmony_ci         %32 = OpLoad %20 %6
7785fd4e5da5Sopenharmony_ci         %33 = OpLoad %v4float %3
7786fd4e5da5Sopenharmony_ci         %34 = OpVectorShuffle %v2float %33 %33 0 2
7787fd4e5da5Sopenharmony_ci         %35 = OpImageSampleImplicitLod %v4float %32 %34
7788fd4e5da5Sopenharmony_ci               OpStore %4 %35
7789fd4e5da5Sopenharmony_ci               OpReturn
7790fd4e5da5Sopenharmony_ci               OpFunctionEnd
7791fd4e5da5Sopenharmony_ci)";
7792fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7793fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7794fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7795fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7796fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7797fd4e5da5Sopenharmony_ci      HasSubstr("Illegal use of QCOM image processing decorated texture"));
7798fd4e5da5Sopenharmony_ci}
7799fd4e5da5Sopenharmony_ci
7800fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseA) {
7801fd4e5da5Sopenharmony_ci  std::string text = R"(
7802fd4e5da5Sopenharmony_ci               OpCapability Shader
7803fd4e5da5Sopenharmony_ci               OpCapability TextureSampleWeightedQCOM
7804fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7805fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7806fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7807fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7808fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
7809fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
7810fd4e5da5Sopenharmony_ci               OpDecorate %4 Location 0
7811fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
7812fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 4
7813fd4e5da5Sopenharmony_ci               OpDecorate %6 DescriptorSet 0
7814fd4e5da5Sopenharmony_ci               OpDecorate %6 Binding 5
7815fd4e5da5Sopenharmony_ci               OpDecorate %6 WeightTextureQCOM
7816fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7817fd4e5da5Sopenharmony_ci          %8 = OpTypeFunction %void
7818fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7819fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7820fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7821fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Output_v4float Output
7822fd4e5da5Sopenharmony_ci         %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
7823fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
7824fd4e5da5Sopenharmony_ci         %14 = OpTypeSampledImage %12
7825fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7826fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_Input_v4float Input
7827fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7828fd4e5da5Sopenharmony_ci         %17 = OpTypeImage %float 2D 0 1 0 1 Unknown
7829fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
7830fd4e5da5Sopenharmony_ci         %19 = OpTypeSampledImage %17
7831fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
7832fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_14 UniformConstant
7833fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7834fd4e5da5Sopenharmony_ci          %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7835fd4e5da5Sopenharmony_ci    %v3float = OpTypeVector %float 3
7836fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %8
7837fd4e5da5Sopenharmony_ci         %23 = OpLabel
7838fd4e5da5Sopenharmony_ci         %24 = OpLoad %v4float %4
7839fd4e5da5Sopenharmony_ci         %25 = OpVectorShuffle %v2float %24 %24 0 1
7840fd4e5da5Sopenharmony_ci         %26 = OpLoad %14 %5
7841fd4e5da5Sopenharmony_ci         %27 = OpLoad %v4float %4
7842fd4e5da5Sopenharmony_ci         %28 = OpVectorShuffle %v2float %27 %27 0 1
7843fd4e5da5Sopenharmony_ci         %29 = OpLoad %19 %6
7844fd4e5da5Sopenharmony_ci         %30 = OpImageSampleWeightedQCOM %v4float %26 %28 %29
7845fd4e5da5Sopenharmony_ci               OpStore %3 %30
7846fd4e5da5Sopenharmony_ci         %31 = OpLoad %19 %6
7847fd4e5da5Sopenharmony_ci         %32 = OpLoad %v4float %4
7848fd4e5da5Sopenharmony_ci         %33 = OpVectorShuffle %v3float %32 %32 0 1 0
7849fd4e5da5Sopenharmony_ci         %34 = OpCompositeExtract %float %33 0
7850fd4e5da5Sopenharmony_ci         %35 = OpCompositeExtract %float %33 1
7851fd4e5da5Sopenharmony_ci         %36 = OpCompositeExtract %float %33 2
7852fd4e5da5Sopenharmony_ci         %37 = OpCompositeConstruct %v3float %34 %35 %36
7853fd4e5da5Sopenharmony_ci         %38 = OpImageSampleImplicitLod %v4float %31 %37
7854fd4e5da5Sopenharmony_ci               OpStore %3 %38
7855fd4e5da5Sopenharmony_ci               OpReturn
7856fd4e5da5Sopenharmony_ci               OpFunctionEnd
7857fd4e5da5Sopenharmony_ci)";
7858fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7859fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7860fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7861fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7862fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7863fd4e5da5Sopenharmony_ci      HasSubstr("Illegal use of QCOM image processing decorated texture"));
7864fd4e5da5Sopenharmony_ci}
7865fd4e5da5Sopenharmony_ci
7866fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseB) {
7867fd4e5da5Sopenharmony_ci  std::string text = R"(
7868fd4e5da5Sopenharmony_ci               OpCapability Shader
7869fd4e5da5Sopenharmony_ci               OpCapability TextureSampleWeightedQCOM
7870fd4e5da5Sopenharmony_ci               OpExtension "SPV_QCOM_image_processing"
7871fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
7872fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7873fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7
7874fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
7875fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
7876fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
7877fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 1
7878fd4e5da5Sopenharmony_ci               OpDecorate %6 DescriptorSet 0
7879fd4e5da5Sopenharmony_ci               OpDecorate %6 Binding 3
7880fd4e5da5Sopenharmony_ci               OpDecorate %4 Location 0
7881fd4e5da5Sopenharmony_ci               OpDecorate %7 DescriptorSet 0
7882fd4e5da5Sopenharmony_ci               OpDecorate %7 Binding 0
7883fd4e5da5Sopenharmony_ci               OpDecorate %7 WeightTextureQCOM
7884fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7885fd4e5da5Sopenharmony_ci          %9 = OpTypeFunction %void
7886fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
7887fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
7888fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
7889fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Output_v4float Output
7890fd4e5da5Sopenharmony_ci         %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
7891fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
7892fd4e5da5Sopenharmony_ci          %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
7893fd4e5da5Sopenharmony_ci         %15 = OpTypeSampler
7894fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
7895fd4e5da5Sopenharmony_ci          %6 = OpVariable %_ptr_UniformConstant_15 UniformConstant
7896fd4e5da5Sopenharmony_ci         %17 = OpTypeSampledImage %13
7897fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
7898fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_Input_v4float Input
7899fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
7900fd4e5da5Sopenharmony_ci         %20 = OpTypeImage %float 2D 0 1 0 1 Unknown
7901fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7902fd4e5da5Sopenharmony_ci          %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7903fd4e5da5Sopenharmony_ci         %22 = OpTypeSampledImage %20
7904fd4e5da5Sopenharmony_ci    %v3float = OpTypeVector %float 3
7905fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %9
7906fd4e5da5Sopenharmony_ci         %24 = OpLabel
7907fd4e5da5Sopenharmony_ci         %25 = OpLoad %13 %5
7908fd4e5da5Sopenharmony_ci         %26 = OpLoad %15 %6
7909fd4e5da5Sopenharmony_ci         %27 = OpSampledImage %17 %25 %26
7910fd4e5da5Sopenharmony_ci         %28 = OpLoad %v4float %4
7911fd4e5da5Sopenharmony_ci         %29 = OpVectorShuffle %v2float %28 %28 0 1
7912fd4e5da5Sopenharmony_ci         %30 = OpLoad %20 %7
7913fd4e5da5Sopenharmony_ci         %31 = OpLoad %15 %6
7914fd4e5da5Sopenharmony_ci         %32 = OpSampledImage %22 %30 %31
7915fd4e5da5Sopenharmony_ci         %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32
7916fd4e5da5Sopenharmony_ci               OpStore %3 %33
7917fd4e5da5Sopenharmony_ci         %34 = OpLoad %20 %7
7918fd4e5da5Sopenharmony_ci         %35 = OpLoad %15 %6
7919fd4e5da5Sopenharmony_ci         %36 = OpSampledImage %22 %34 %35
7920fd4e5da5Sopenharmony_ci         %37 = OpLoad %v4float %4
7921fd4e5da5Sopenharmony_ci         %38 = OpVectorShuffle %v3float %37 %37 0 1 0
7922fd4e5da5Sopenharmony_ci         %39 = OpCompositeExtract %float %38 0
7923fd4e5da5Sopenharmony_ci         %40 = OpCompositeExtract %float %38 1
7924fd4e5da5Sopenharmony_ci         %41 = OpCompositeExtract %float %38 2
7925fd4e5da5Sopenharmony_ci         %42 = OpCompositeConstruct %v3float %39 %40 %41
7926fd4e5da5Sopenharmony_ci         %43 = OpImageSampleImplicitLod %v4float %36 %42
7927fd4e5da5Sopenharmony_ci               OpStore %3 %43
7928fd4e5da5Sopenharmony_ci               OpReturn
7929fd4e5da5Sopenharmony_ci               OpFunctionEnd
7930fd4e5da5Sopenharmony_ci)";
7931fd4e5da5Sopenharmony_ci  CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7932fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7933fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7934fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7935fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7936fd4e5da5Sopenharmony_ci      HasSubstr("Illegal use of QCOM image processing decorated texture"));
7937fd4e5da5Sopenharmony_ci}
7938fd4e5da5Sopenharmony_ci
7939fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageMSArray_ArrayedSampledTypeRequiresCapability) {
7940fd4e5da5Sopenharmony_ci  const std::string code = R"(
7941fd4e5da5Sopenharmony_ci               OpCapability Shader
7942fd4e5da5Sopenharmony_ci               OpCapability StorageImageMultisample
7943fd4e5da5Sopenharmony_ci               OpCapability StorageImageReadWithoutFormat
7944fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7945fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main"
7946fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
7947fd4e5da5Sopenharmony_ci               OpDecorate %var_image DescriptorSet 0
7948fd4e5da5Sopenharmony_ci               OpDecorate %var_image Binding 1
7949fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7950fd4e5da5Sopenharmony_ci       %func = OpTypeFunction %void
7951fd4e5da5Sopenharmony_ci        %f32 = OpTypeFloat 32
7952fd4e5da5Sopenharmony_ci        %u32 = OpTypeInt 32 0
7953fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %u32 2
7954fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %u32 1
7955fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %u32 2
7956fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %f32 4
7957fd4e5da5Sopenharmony_ci    %image = OpTypeImage %f32 2D 2 1 1 2 Unknown
7958fd4e5da5Sopenharmony_ci%ptr_image = OpTypePointer UniformConstant %image
7959fd4e5da5Sopenharmony_ci       %10 = OpConstantComposite %v2uint %uint_1 %uint_2
7960fd4e5da5Sopenharmony_ci%var_image = OpVariable %ptr_image UniformConstant
7961fd4e5da5Sopenharmony_ci     %main = OpFunction %void None %func
7962fd4e5da5Sopenharmony_ci %main_lab = OpLabel
7963fd4e5da5Sopenharmony_ci       %18 = OpLoad %image %var_image
7964fd4e5da5Sopenharmony_ci       %19 = OpImageRead %v4float %18 %10 Sample %uint_2
7965fd4e5da5Sopenharmony_ci             OpReturn
7966fd4e5da5Sopenharmony_ci             OpFunctionEnd
7967fd4e5da5Sopenharmony_ci)";
7968fd4e5da5Sopenharmony_ci
7969fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
7970fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
7971fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
7972fd4e5da5Sopenharmony_ci  EXPECT_THAT(
7973fd4e5da5Sopenharmony_ci      getDiagnosticString(),
7974fd4e5da5Sopenharmony_ci      HasSubstr("Capability ImageMSArray is required to access storage image"));
7975fd4e5da5Sopenharmony_ci}
7976fd4e5da5Sopenharmony_ci
7977fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageMSArray_SampledTypeDoesNotRequireCapability) {
7978fd4e5da5Sopenharmony_ci  const std::string code = R"(
7979fd4e5da5Sopenharmony_ci               OpCapability Shader
7980fd4e5da5Sopenharmony_ci               OpCapability StorageImageMultisample
7981fd4e5da5Sopenharmony_ci               OpCapability StorageImageReadWithoutFormat
7982fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
7983fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main"
7984fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
7985fd4e5da5Sopenharmony_ci               OpDecorate %var_image DescriptorSet 0
7986fd4e5da5Sopenharmony_ci               OpDecorate %var_image Binding 1
7987fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
7988fd4e5da5Sopenharmony_ci       %func = OpTypeFunction %void
7989fd4e5da5Sopenharmony_ci        %f32 = OpTypeFloat 32
7990fd4e5da5Sopenharmony_ci        %u32 = OpTypeInt 32 0
7991fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %u32 2
7992fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %u32 1
7993fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %u32 2
7994fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %f32 4
7995fd4e5da5Sopenharmony_ci    %image = OpTypeImage %f32 2D 2 0 1 2 Unknown
7996fd4e5da5Sopenharmony_ci%ptr_image = OpTypePointer UniformConstant %image
7997fd4e5da5Sopenharmony_ci       %10 = OpConstantComposite %v2uint %uint_1 %uint_2
7998fd4e5da5Sopenharmony_ci%var_image = OpVariable %ptr_image UniformConstant
7999fd4e5da5Sopenharmony_ci     %main = OpFunction %void None %func
8000fd4e5da5Sopenharmony_ci %main_lab = OpLabel
8001fd4e5da5Sopenharmony_ci       %18 = OpLoad %image %var_image
8002fd4e5da5Sopenharmony_ci       %19 = OpImageRead %v4float %18 %10 Sample %uint_2
8003fd4e5da5Sopenharmony_ci             OpReturn
8004fd4e5da5Sopenharmony_ci             OpFunctionEnd
8005fd4e5da5Sopenharmony_ci)";
8006fd4e5da5Sopenharmony_ci
8007fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
8008fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
8009fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
8010fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
8011fd4e5da5Sopenharmony_ci}
8012fd4e5da5Sopenharmony_ci
8013fd4e5da5Sopenharmony_ciTEST_F(ValidateImage, ImageMSArray_ArrayedTypeDoesNotRequireCapability) {
8014fd4e5da5Sopenharmony_ci  const std::string code = R"(
8015fd4e5da5Sopenharmony_ci               OpCapability Shader
8016fd4e5da5Sopenharmony_ci               OpCapability StorageImageReadWithoutFormat
8017fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
8018fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main"
8019fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
8020fd4e5da5Sopenharmony_ci               OpDecorate %var_image DescriptorSet 0
8021fd4e5da5Sopenharmony_ci               OpDecorate %var_image Binding 1
8022fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
8023fd4e5da5Sopenharmony_ci       %func = OpTypeFunction %void
8024fd4e5da5Sopenharmony_ci        %f32 = OpTypeFloat 32
8025fd4e5da5Sopenharmony_ci        %u32 = OpTypeInt 32 0
8026fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %u32 3
8027fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %u32 2
8028fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %u32 1
8029fd4e5da5Sopenharmony_ci     %v3uint = OpTypeVector %u32 3
8030fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %f32 4
8031fd4e5da5Sopenharmony_ci    %image = OpTypeImage %f32 2D 2 1 0 2 Unknown
8032fd4e5da5Sopenharmony_ci%ptr_image = OpTypePointer UniformConstant %image
8033fd4e5da5Sopenharmony_ci       %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
8034fd4e5da5Sopenharmony_ci%var_image = OpVariable %ptr_image UniformConstant
8035fd4e5da5Sopenharmony_ci     %main = OpFunction %void None %func
8036fd4e5da5Sopenharmony_ci %main_lab = OpLabel
8037fd4e5da5Sopenharmony_ci       %18 = OpLoad %image %var_image
8038fd4e5da5Sopenharmony_ci       %19 = OpImageRead %v4float %18 %10
8039fd4e5da5Sopenharmony_ci             OpReturn
8040fd4e5da5Sopenharmony_ci             OpFunctionEnd
8041fd4e5da5Sopenharmony_ci)";
8042fd4e5da5Sopenharmony_ci
8043fd4e5da5Sopenharmony_ci  const spv_target_env env = SPV_ENV_VULKAN_1_0;
8044fd4e5da5Sopenharmony_ci  CompileSuccessfully(code, env);
8045fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
8046fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
8047fd4e5da5Sopenharmony_ci}
8048fd4e5da5Sopenharmony_ci
8049fd4e5da5Sopenharmony_ci}  // namespace
8050fd4e5da5Sopenharmony_ci}  // namespace val
8051fd4e5da5Sopenharmony_ci}  // namespace spvtools
8052