1 // Copyright (c) 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Tests for unique type declaration rules validator.
16 
17 #include <sstream>
18 #include <string>
19 
20 #include "gmock/gmock.h"
21 #include "test/unit_spirv.h"
22 #include "test/val/val_fixtures.h"
23 
24 namespace spvtools {
25 namespace val {
26 namespace {
27 
28 using ::testing::Eq;
29 using ::testing::HasSubstr;
30 using ::testing::Not;
31 
32 using ValidateImage = spvtest::ValidateBase<bool>;
33 
GenerateShaderCode(const std::string & body,const std::string & capabilities_and_extensions="",const std::string & execution_model="Fragment",const std::string & execution_mode="",const spv_target_env env=SPV_ENV_UNIVERSAL_1_0,const std::string & memory_model="GLSL450")34 std::string GenerateShaderCode(
35     const std::string& body,
36     const std::string& capabilities_and_extensions = "",
37     const std::string& execution_model = "Fragment",
38     const std::string& execution_mode = "",
39     const spv_target_env env = SPV_ENV_UNIVERSAL_1_0,
40     const std::string& memory_model = "GLSL450") {
41   std::ostringstream ss;
42   ss << R"(
43 OpCapability Shader
44 OpCapability InputAttachment
45 OpCapability ImageGatherExtended
46 OpCapability MinLod
47 OpCapability Sampled1D
48 OpCapability ImageQuery
49 OpCapability Int64
50 OpCapability Float64
51 OpCapability SparseResidency
52 OpCapability ImageBuffer
53 )";
54 
55   if (env == SPV_ENV_UNIVERSAL_1_0) {
56     ss << "OpCapability SampledRect\n";
57   }
58 
59   // In 1.4, the entry point must list all module-scope variables used.  Just
60   // list all of them.
61   std::string interface_vars = (env != SPV_ENV_UNIVERSAL_1_4) ? "" :
62                                                               R"(
63 %uniform_image_f32_1d_0001
64 %uniform_image_f32_1d_0002_rgba32f
65 %uniform_image_f32_2d_0001
66 %uniform_image_f32_2d_0010
67 %uniform_image_u32_2d_0001
68 %uniform_image_u32_2d_0000
69 %uniform_image_s32_3d_0001
70 %uniform_image_f32_2d_0002
71 %uniform_image_s32_2d_0002
72 %uniform_image_f32_spd_0002
73 %uniform_image_f32_3d_0111
74 %uniform_image_f32_cube_0101
75 %uniform_image_f32_cube_0102_rgba32f
76 %uniform_sampler
77 %private_image_u32_buffer_0002_r32ui
78 %private_image_u32_spd_0002
79 %private_image_f32_buffer_0002_r32ui
80 )";
81 
82   ss << capabilities_and_extensions;
83   ss << "OpMemoryModel Logical " << memory_model << "\n";
84   ss << "OpEntryPoint " << execution_model
85      << " %main \"main\" " + interface_vars + "\n";
86   if (execution_model == "Fragment") {
87     ss << "OpExecutionMode %main OriginUpperLeft\n";
88   }
89   ss << execution_mode;
90 
91   if (env == SPV_ENV_VULKAN_1_0) {
92     ss << R"(
93 OpDecorate %uniform_image_f32_1d_0001 DescriptorSet 0
94 OpDecorate %uniform_image_f32_1d_0001 Binding 0
95 OpDecorate %uniform_image_f32_1d_0002_rgba32f DescriptorSet 0
96 OpDecorate %uniform_image_f32_1d_0002_rgba32f Binding 1
97 OpDecorate %uniform_image_f32_2d_0001 DescriptorSet 0
98 OpDecorate %uniform_image_f32_2d_0001 Binding 2
99 OpDecorate %uniform_image_f32_2d_0010 DescriptorSet 0
100 OpDecorate %uniform_image_f32_2d_0010 Binding 3
101 OpDecorate %uniform_image_u32_2d_0001 DescriptorSet 1
102 OpDecorate %uniform_image_u32_2d_0001 Binding 0
103 OpDecorate %uniform_image_u32_2d_0000 DescriptorSet 1
104 OpDecorate %uniform_image_u32_2d_0000 Binding 1
105 OpDecorate %uniform_image_s32_3d_0001 DescriptorSet 1
106 OpDecorate %uniform_image_s32_3d_0001 Binding 2
107 OpDecorate %uniform_image_f32_2d_0002 DescriptorSet 1
108 OpDecorate %uniform_image_f32_2d_0002 Binding 3
109 OpDecorate %uniform_image_s32_2d_0002 DescriptorSet 1
110 OpDecorate %uniform_image_s32_2d_0002 Binding 4
111 OpDecorate %uniform_image_f32_spd_0002 DescriptorSet 2
112 OpDecorate %uniform_image_f32_spd_0002 Binding 0
113 OpDecorate %uniform_image_f32_3d_0111 DescriptorSet 2
114 OpDecorate %uniform_image_f32_3d_0111 Binding 1
115 OpDecorate %uniform_image_f32_cube_0101 DescriptorSet 2
116 OpDecorate %uniform_image_f32_cube_0101 Binding 2
117 OpDecorate %uniform_image_f32_cube_0102_rgba32f DescriptorSet 2
118 OpDecorate %uniform_image_f32_cube_0102_rgba32f Binding 3
119 OpDecorate %uniform_sampler DescriptorSet 3
120 OpDecorate %uniform_sampler Binding 0
121 )";
122   }
123 
124   ss << R"(
125 %void = OpTypeVoid
126 %func = OpTypeFunction %void
127 %bool = OpTypeBool
128 %f32 = OpTypeFloat 32
129 %f64 = OpTypeFloat 64
130 %u32 = OpTypeInt 32 0
131 %s32 = OpTypeInt 32 1
132 %u64 = OpTypeInt 64 0
133 %s32vec2 = OpTypeVector %s32 2
134 %u32vec2 = OpTypeVector %u32 2
135 %f32vec2 = OpTypeVector %f32 2
136 %u32vec3 = OpTypeVector %u32 3
137 %s32vec3 = OpTypeVector %s32 3
138 %f32vec3 = OpTypeVector %f32 3
139 %u32vec4 = OpTypeVector %u32 4
140 %s32vec4 = OpTypeVector %s32 4
141 %f32vec4 = OpTypeVector %f32 4
142 
143 %f32_0 = OpConstant %f32 0
144 %f32_1 = OpConstant %f32 1
145 %f32_0_5 = OpConstant %f32 0.5
146 %f32_0_25 = OpConstant %f32 0.25
147 %f32_0_75 = OpConstant %f32 0.75
148 
149 %f64_0 = OpConstant %f64 0
150 %f64_1 = OpConstant %f64 1
151 
152 %s32_0 = OpConstant %s32 0
153 %s32_1 = OpConstant %s32 1
154 %s32_2 = OpConstant %s32 2
155 %s32_3 = OpConstant %s32 3
156 %s32_4 = OpConstant %s32 4
157 %s32_m1 = OpConstant %s32 -1
158 
159 %u32_0 = OpConstant %u32 0
160 %u32_1 = OpConstant %u32 1
161 %u32_2 = OpConstant %u32 2
162 %u32_3 = OpConstant %u32 3
163 %u32_4 = OpConstant %u32 4
164 
165 %u64_0 = OpConstant %u64 0
166 
167 %u32vec2arr4 = OpTypeArray %u32vec2 %u32_4
168 %u32vec2arr3 = OpTypeArray %u32vec2 %u32_3
169 %u32arr4 = OpTypeArray %u32 %u32_4
170 %u32vec3arr4 = OpTypeArray %u32vec3 %u32_4
171 
172 %struct_u32_f32vec4 = OpTypeStruct %u32 %f32vec4
173 %struct_u64_f32vec4 = OpTypeStruct %u64 %f32vec4
174 %struct_u32_u32vec4 = OpTypeStruct %u32 %u32vec4
175 %struct_u32_f32vec3 = OpTypeStruct %u32 %f32vec3
176 %struct_f32_f32vec4 = OpTypeStruct %f32 %f32vec4
177 %struct_u32_u32 = OpTypeStruct %u32 %u32
178 %struct_f32_f32 = OpTypeStruct %f32 %f32
179 %struct_u32 = OpTypeStruct %u32
180 %struct_u32_f32_u32 = OpTypeStruct %u32 %f32 %u32
181 %struct_u32_f32vec4_u32 = OpTypeStruct %u32 %f32vec4 %u32
182 %struct_u32_u32arr4 = OpTypeStruct %u32 %u32arr4
183 
184 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
185 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
186 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
187 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
188 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
189 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
190 
191 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
192 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
193 %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
194 %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
195 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
196 %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
197 
198 %f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
199 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
200 %f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
201 %f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
202 %f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
203 
204 %f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
205 %f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
206 
207 %f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
208 
209 %const_offsets = OpConstantComposite %u32vec2arr4 %u32vec2_01 %u32vec2_12 %u32vec2_01 %u32vec2_12
210 %const_offsets3x2 = OpConstantComposite %u32vec2arr3 %u32vec2_01 %u32vec2_12 %u32vec2_01
211 %const_offsets4xu = OpConstantComposite %u32arr4 %u32_0 %u32_0 %u32_0 %u32_0
212 %const_offsets4x3 = OpConstantComposite %u32vec3arr4 %u32vec3_012 %u32vec3_012 %u32vec3_012 %u32vec3_012
213 
214 %type_image_f32_1d_0001 = OpTypeImage %f32 1D 0 0 0 1 Unknown
215 %ptr_image_f32_1d_0001 = OpTypePointer UniformConstant %type_image_f32_1d_0001
216 %uniform_image_f32_1d_0001 = OpVariable %ptr_image_f32_1d_0001 UniformConstant
217 %type_sampled_image_f32_1d_0001 = OpTypeSampledImage %type_image_f32_1d_0001
218 
219 %type_image_f32_1d_0002_rgba32f = OpTypeImage %f32 1D 0 0 0 2 Rgba32f
220 %ptr_image_f32_1d_0002_rgba32f = OpTypePointer UniformConstant %type_image_f32_1d_0002_rgba32f
221 %uniform_image_f32_1d_0002_rgba32f = OpVariable %ptr_image_f32_1d_0002_rgba32f UniformConstant
222 %type_sampled_image_f32_1d_0002_rgba32f = OpTypeSampledImage %type_image_f32_1d_0002_rgba32f
223 
224 %type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
225 %ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
226 %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
227 %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
228 
229 %type_image_f32_2d_0010 = OpTypeImage %f32 2D 0 0 1 0 Unknown
230 %ptr_image_f32_2d_0010 = OpTypePointer UniformConstant %type_image_f32_2d_0010
231 %uniform_image_f32_2d_0010 = OpVariable %ptr_image_f32_2d_0010 UniformConstant
232 %type_sampled_image_f32_2d_0010 = OpTypeSampledImage %type_image_f32_2d_0010
233 
234 %type_image_u32_2d_0001 = OpTypeImage %u32 2D 0 0 0 1 Unknown
235 %ptr_image_u32_2d_0001 = OpTypePointer UniformConstant %type_image_u32_2d_0001
236 %uniform_image_u32_2d_0001 = OpVariable %ptr_image_u32_2d_0001 UniformConstant
237 %type_sampled_image_u32_2d_0001 = OpTypeSampledImage %type_image_u32_2d_0001
238 
239 %type_image_u32_2d_0000 = OpTypeImage %u32 2D 0 0 0 0 Unknown
240 %ptr_image_u32_2d_0000 = OpTypePointer UniformConstant %type_image_u32_2d_0000
241 %uniform_image_u32_2d_0000 = OpVariable %ptr_image_u32_2d_0000 UniformConstant
242 %type_sampled_image_u32_2d_0000 = OpTypeSampledImage %type_image_u32_2d_0000
243 
244 %type_image_s32_3d_0001 = OpTypeImage %s32 3D 0 0 0 1 Unknown
245 %ptr_image_s32_3d_0001 = OpTypePointer UniformConstant %type_image_s32_3d_0001
246 %uniform_image_s32_3d_0001 = OpVariable %ptr_image_s32_3d_0001 UniformConstant
247 %type_sampled_image_s32_3d_0001 = OpTypeSampledImage %type_image_s32_3d_0001
248 
249 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Unknown
250 %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
251 %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
252 %type_sampled_image_f32_2d_0002 = OpTypeSampledImage %type_image_f32_2d_0002
253 
254 %type_image_s32_2d_0002 = OpTypeImage %s32 2D 0 0 0 2 Unknown
255 %ptr_image_s32_2d_0002 = OpTypePointer UniformConstant %type_image_s32_2d_0002
256 %uniform_image_s32_2d_0002 = OpVariable %ptr_image_s32_2d_0002 UniformConstant
257 %type_sampled_image_s32_2d_0002 = OpTypeSampledImage %type_image_s32_2d_0002
258 
259 %type_image_f32_spd_0002 = OpTypeImage %f32 SubpassData 0 0 0 2 Unknown
260 %ptr_image_f32_spd_0002 = OpTypePointer UniformConstant %type_image_f32_spd_0002
261 %uniform_image_f32_spd_0002 = OpVariable %ptr_image_f32_spd_0002 UniformConstant
262 %type_sampled_image_f32_spd_0002 = OpTypeSampledImage %type_image_f32_spd_0002
263 
264 %type_image_f32_3d_0111 = OpTypeImage %f32 3D 0 1 1 1 Unknown
265 %ptr_image_f32_3d_0111 = OpTypePointer UniformConstant %type_image_f32_3d_0111
266 %uniform_image_f32_3d_0111 = OpVariable %ptr_image_f32_3d_0111 UniformConstant
267 %type_sampled_image_f32_3d_0111 = OpTypeSampledImage %type_image_f32_3d_0111
268 
269 %type_image_f32_cube_0101 = OpTypeImage %f32 Cube 0 1 0 1 Unknown
270 %ptr_image_f32_cube_0101 = OpTypePointer UniformConstant %type_image_f32_cube_0101
271 %uniform_image_f32_cube_0101 = OpVariable %ptr_image_f32_cube_0101 UniformConstant
272 %type_sampled_image_f32_cube_0101 = OpTypeSampledImage %type_image_f32_cube_0101
273 
274 %type_image_f32_cube_0102_rgba32f = OpTypeImage %f32 Cube 0 1 0 2 Rgba32f
275 %ptr_image_f32_cube_0102_rgba32f = OpTypePointer UniformConstant %type_image_f32_cube_0102_rgba32f
276 %uniform_image_f32_cube_0102_rgba32f = OpVariable %ptr_image_f32_cube_0102_rgba32f UniformConstant
277 %type_sampled_image_f32_cube_0102_rgba32f = OpTypeSampledImage %type_image_f32_cube_0102_rgba32f
278 
279 %type_sampler = OpTypeSampler
280 %ptr_sampler = OpTypePointer UniformConstant %type_sampler
281 %uniform_sampler = OpVariable %ptr_sampler UniformConstant
282 
283 %type_image_u32_buffer_0002_r32ui = OpTypeImage %u32 Buffer 0 0 0 2 R32ui
284 %ptr_Image_u32 = OpTypePointer Image %u32
285 %ptr_image_u32_buffer_0002_r32ui = OpTypePointer Private %type_image_u32_buffer_0002_r32ui
286 %private_image_u32_buffer_0002_r32ui = OpVariable %ptr_image_u32_buffer_0002_r32ui Private
287 
288 %ptr_Image_u32arr4 = OpTypePointer Image %u32arr4
289 
290 %type_image_u32_spd_0002 = OpTypeImage %u32 SubpassData 0 0 0 2 Unknown
291 %ptr_image_u32_spd_0002 = OpTypePointer Private %type_image_u32_spd_0002
292 %private_image_u32_spd_0002 = OpVariable %ptr_image_u32_spd_0002 Private
293 
294 %type_image_f32_buffer_0002_r32ui = OpTypeImage %f32 Buffer 0 0 0 2 R32ui
295 %ptr_Image_f32 = OpTypePointer Image %f32
296 %ptr_image_f32_buffer_0002_r32ui = OpTypePointer Private %type_image_f32_buffer_0002_r32ui
297 %private_image_f32_buffer_0002_r32ui = OpVariable %ptr_image_f32_buffer_0002_r32ui Private
298 )";
299 
300   if (env == SPV_ENV_UNIVERSAL_1_0) {
301     ss << R"(
302 %type_image_void_2d_0001 = OpTypeImage %void 2D 0 0 0 1 Unknown
303 %ptr_image_void_2d_0001 = OpTypePointer UniformConstant %type_image_void_2d_0001
304 %uniform_image_void_2d_0001 = OpVariable %ptr_image_void_2d_0001 UniformConstant
305 %type_sampled_image_void_2d_0001 = OpTypeSampledImage %type_image_void_2d_0001
306 
307 %type_image_void_2d_0002 = OpTypeImage %void 2D 0 0 0 2 Unknown
308 %ptr_image_void_2d_0002 = OpTypePointer UniformConstant %type_image_void_2d_0002
309 %uniform_image_void_2d_0002 = OpVariable %ptr_image_void_2d_0002 UniformConstant
310 %type_sampled_image_void_2d_0002 = OpTypeSampledImage %type_image_void_2d_0002
311 
312 %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
313 %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
314 %uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
315 %type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
316 )";
317   }
318 
319   ss << R"(
320 %main = OpFunction %void None %func
321 %main_entry = OpLabel
322 )";
323 
324   ss << body;
325 
326   ss << R"(
327 OpReturn
328 OpFunctionEnd)";
329 
330   return ss.str();
331 }
332 
GenerateKernelCode(const std::string & body,const std::string & capabilities_and_extensions="")333 std::string GenerateKernelCode(
334     const std::string& body,
335     const std::string& capabilities_and_extensions = "") {
336   std::ostringstream ss;
337   ss << R"(
338 OpCapability Addresses
339 OpCapability Kernel
340 OpCapability Linkage
341 OpCapability ImageQuery
342 OpCapability ImageGatherExtended
343 OpCapability InputAttachment
344 OpCapability SampledRect
345 )";
346 
347   ss << capabilities_and_extensions;
348   ss << R"(
349 OpMemoryModel Physical32 OpenCL
350 %void = OpTypeVoid
351 %func = OpTypeFunction %void
352 %bool = OpTypeBool
353 %f32 = OpTypeFloat 32
354 %u32 = OpTypeInt 32 0
355 %u32vec2 = OpTypeVector %u32 2
356 %f32vec2 = OpTypeVector %f32 2
357 %u32vec3 = OpTypeVector %u32 3
358 %f32vec3 = OpTypeVector %f32 3
359 %u32vec4 = OpTypeVector %u32 4
360 %f32vec4 = OpTypeVector %f32 4
361 
362 %f32_0 = OpConstant %f32 0
363 %f32_1 = OpConstant %f32 1
364 %f32_0_5 = OpConstant %f32 0.5
365 %f32_0_25 = OpConstant %f32 0.25
366 %f32_0_75 = OpConstant %f32 0.75
367 
368 %u32_0 = OpConstant %u32 0
369 %u32_1 = OpConstant %u32 1
370 %u32_2 = OpConstant %u32 2
371 %u32_3 = OpConstant %u32 3
372 %u32_4 = OpConstant %u32 4
373 
374 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
375 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
376 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
377 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
378 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
379 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
380 
381 %f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
382 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
383 %f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
384 %f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
385 %f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
386 
387 %f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
388 %f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
389 
390 %f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
391 
392 %type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
393 %ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
394 %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
395 %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
396 
397 %type_image_f32_2d_0010 = OpTypeImage %f32 2D 0 0 1 0 Unknown
398 %ptr_image_f32_2d_0010 = OpTypePointer UniformConstant %type_image_f32_2d_0010
399 %uniform_image_f32_2d_0010 = OpVariable %ptr_image_f32_2d_0010 UniformConstant
400 %type_sampled_image_f32_2d_0010 = OpTypeSampledImage %type_image_f32_2d_0010
401 
402 %type_image_f32_3d_0010 = OpTypeImage %f32 3D 0 0 1 0 Unknown
403 %ptr_image_f32_3d_0010 = OpTypePointer UniformConstant %type_image_f32_3d_0010
404 %uniform_image_f32_3d_0010 = OpVariable %ptr_image_f32_3d_0010 UniformConstant
405 %type_sampled_image_f32_3d_0010 = OpTypeSampledImage %type_image_f32_3d_0010
406 
407 %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
408 %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
409 %uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
410 %type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
411 
412 %type_sampler = OpTypeSampler
413 %ptr_sampler = OpTypePointer UniformConstant %type_sampler
414 %uniform_sampler = OpVariable %ptr_sampler UniformConstant
415 
416 %main = OpFunction %void None %func
417 %main_entry = OpLabel
418 )";
419 
420   ss << body;
421   ss << R"(
422 OpReturn
423 OpFunctionEnd)";
424 
425   return ss.str();
426 }
427 
GetShaderHeader(const std::string & capabilities_and_extensions="",bool include_entry_point=true)428 std::string GetShaderHeader(const std::string& capabilities_and_extensions = "",
429                             bool include_entry_point = true) {
430   std::ostringstream ss;
431   ss << R"(
432 OpCapability Shader
433 OpCapability Int64
434 )";
435 
436   ss << capabilities_and_extensions;
437   if (!include_entry_point) {
438     ss << "OpCapability Linkage";
439   }
440 
441   ss << R"(
442 OpMemoryModel Logical GLSL450
443 )";
444 
445   if (include_entry_point) {
446     ss << "OpEntryPoint Fragment %main \"main\"\n";
447     ss << "OpExecutionMode %main OriginUpperLeft";
448   }
449   ss << R"(
450 %void = OpTypeVoid
451 %func = OpTypeFunction %void
452 %bool = OpTypeBool
453 %f32 = OpTypeFloat 32
454 %u32 = OpTypeInt 32 0
455 %u64 = OpTypeInt 64 0
456 %s32 = OpTypeInt 32 1
457 )";
458 
459   return ss.str();
460 }
461 
TEST_F(ValidateImage,TypeImageWrongSampledType)462 TEST_F(ValidateImage, TypeImageWrongSampledType) {
463   const std::string code = GetShaderHeader("", false) + R"(
464 %img_type = OpTypeImage %bool 2D 0 0 0 1 Unknown
465 )";
466 
467   CompileSuccessfully(code.c_str());
468   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
469   EXPECT_THAT(getDiagnosticString(),
470               HasSubstr("Expected Sampled Type to be either void or "
471                         "numerical scalar "
472                         "type"));
473 }
474 
TEST_F(ValidateImage,TypeImageVoidSampledTypeVulkan)475 TEST_F(ValidateImage, TypeImageVoidSampledTypeVulkan) {
476   const std::string code = GetShaderHeader() + R"(
477 %img_type = OpTypeImage %void 2D 0 0 0 1 Unknown
478 %void_func = OpTypeFunction %void
479 %main = OpFunction %void None %void_func
480 %main_lab = OpLabel
481 OpReturn
482 OpFunctionEnd
483 )";
484 
485   const spv_target_env env = SPV_ENV_VULKAN_1_0;
486   CompileSuccessfully(code, env);
487   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
488   EXPECT_THAT(getDiagnosticString(),
489               HasSubstr("Expected Sampled Type to be a 32-bit int "
490                         "or float scalar type for Vulkan environment"));
491 }
492 
TEST_F(ValidateImage,TypeImageU64SampledTypeVulkan)493 TEST_F(ValidateImage, TypeImageU64SampledTypeVulkan) {
494   const std::string code = GetShaderHeader() + R"(
495 %img_type = OpTypeImage %u64 2D 0 0 0 1 Unknown
496 %void_func = OpTypeFunction %void
497 %main = OpFunction %void None %void_func
498 %main_lab = OpLabel
499 OpReturn
500 OpFunctionEnd
501 )";
502 
503   const spv_target_env env = SPV_ENV_VULKAN_1_0;
504   CompileSuccessfully(code, env);
505   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
506   EXPECT_THAT(getDiagnosticString(),
507               HasSubstr("Expected Sampled Type to be a 32-bit int "
508                         "or float scalar type for Vulkan environment"));
509 }
510 
TEST_F(ValidateImage,TypeImageWrongDepth)511 TEST_F(ValidateImage, TypeImageWrongDepth) {
512   const std::string code = GetShaderHeader("", false) + R"(
513 %img_type = OpTypeImage %f32 2D 3 0 0 1 Unknown
514 )";
515 
516   CompileSuccessfully(code.c_str());
517   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
518   EXPECT_THAT(getDiagnosticString(),
519               HasSubstr("Invalid Depth 3 (must be 0, 1 or 2)"));
520 }
521 
TEST_F(ValidateImage,TypeImageWrongArrayed)522 TEST_F(ValidateImage, TypeImageWrongArrayed) {
523   const std::string code = GetShaderHeader("", false) + R"(
524 %img_type = OpTypeImage %f32 2D 0 2 0 1 Unknown
525 )";
526 
527   CompileSuccessfully(code.c_str());
528   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
529   EXPECT_THAT(getDiagnosticString(),
530               HasSubstr("Invalid Arrayed 2 (must be 0 or 1)"));
531 }
532 
TEST_F(ValidateImage,TypeImageWrongMS)533 TEST_F(ValidateImage, TypeImageWrongMS) {
534   const std::string code = GetShaderHeader("", false) + R"(
535 %img_type = OpTypeImage %f32 2D 0 0 2 1 Unknown
536 )";
537 
538   CompileSuccessfully(code.c_str());
539   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
540   EXPECT_THAT(getDiagnosticString(),
541               HasSubstr("Invalid MS 2 (must be 0 or 1)"));
542 }
543 
TEST_F(ValidateImage,TypeImageWrongSampled)544 TEST_F(ValidateImage, TypeImageWrongSampled) {
545   const std::string code = GetShaderHeader("", false) + R"(
546 %img_type = OpTypeImage %f32 2D 0 0 0 3 Unknown
547 )";
548 
549   CompileSuccessfully(code.c_str());
550   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
551   EXPECT_THAT(getDiagnosticString(),
552               HasSubstr("Invalid Sampled 3 (must be 0, 1 or 2)"));
553 }
554 
TEST_F(ValidateImage,TypeImageWrongSampledForSubpassData)555 TEST_F(ValidateImage, TypeImageWrongSampledForSubpassData) {
556   const std::string code =
557       GetShaderHeader("OpCapability InputAttachment\n", false) +
558       R"(
559 %img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
560 )";
561 
562   CompileSuccessfully(code.c_str());
563   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
564   EXPECT_THAT(getDiagnosticString(),
565               HasSubstr("Dim SubpassData requires Sampled to be 2"));
566 }
567 
TEST_F(ValidateImage,TypeImageWrongFormatForSubpassData)568 TEST_F(ValidateImage, TypeImageWrongFormatForSubpassData) {
569   const std::string code =
570       GetShaderHeader("OpCapability InputAttachment\n", false) +
571       R"(
572 %img_type = OpTypeImage %f32 SubpassData 0 0 0 2 Rgba32f
573 )";
574 
575   CompileSuccessfully(code.c_str());
576   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
577   EXPECT_THAT(getDiagnosticString(),
578               HasSubstr("Dim SubpassData requires format Unknown"));
579 }
580 
TEST_F(ValidateImage,TypeSampledImageNotImage)581 TEST_F(ValidateImage, TypeSampledImageNotImage) {
582   const std::string code = GetShaderHeader("", false) + R"(
583 %simg_type = OpTypeSampledImage %f32
584 )";
585 
586   CompileSuccessfully(code.c_str());
587   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
588   EXPECT_THAT(getDiagnosticString(),
589               HasSubstr("Expected Image to be of type OpTypeImage"));
590 }
591 
TEST_F(ValidateImage,SampledImageSuccess)592 TEST_F(ValidateImage, SampledImageSuccess) {
593   const std::string body = R"(
594 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
595 %sampler = OpLoad %type_sampler %uniform_sampler
596 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
597 )";
598 
599   CompileSuccessfully(GenerateShaderCode(body).c_str());
600   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
601 }
602 
TEST_F(ValidateImage,SampledImageVulkanSuccess)603 TEST_F(ValidateImage, SampledImageVulkanSuccess) {
604   const std::string body = R"(
605 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
606 %sampler = OpLoad %type_sampler %uniform_sampler
607 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
608 )";
609 
610   const spv_target_env env = SPV_ENV_VULKAN_1_0;
611   CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
612   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
613 }
614 
TEST_F(ValidateImage,SampledImageWrongResultType)615 TEST_F(ValidateImage, SampledImageWrongResultType) {
616   const std::string body = R"(
617 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
618 %sampler = OpLoad %type_sampler %uniform_sampler
619 %simg = OpSampledImage %type_image_f32_2d_0001 %img %sampler
620 )";
621 
622   CompileSuccessfully(GenerateShaderCode(body).c_str());
623   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
624   EXPECT_THAT(getDiagnosticString(),
625               HasSubstr("Expected Result Type to be OpTypeSampledImage"));
626 }
627 
TEST_F(ValidateImage,SampledImageNotImage)628 TEST_F(ValidateImage, SampledImageNotImage) {
629   const std::string body = R"(
630 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
631 %sampler = OpLoad %type_sampler %uniform_sampler
632 %simg1 = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
633 %simg2 = OpSampledImage %type_sampled_image_f32_2d_0001 %simg1 %sampler
634 )";
635 
636   CompileSuccessfully(GenerateShaderCode(body).c_str());
637   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
638   EXPECT_THAT(getDiagnosticString(),
639               HasSubstr("Expected Image to be of type OpTypeImage"));
640 }
641 
TEST_F(ValidateImage,SampledImageImageNotForSampling)642 TEST_F(ValidateImage, SampledImageImageNotForSampling) {
643   const std::string body = R"(
644 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
645 %sampler = OpLoad %type_sampler %uniform_sampler
646 %simg = OpSampledImage %type_sampled_image_f32_2d_0002 %img %sampler
647 )";
648 
649   CompileSuccessfully(GenerateShaderCode(body).c_str());
650   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
651   EXPECT_THAT(getDiagnosticString(),
652               HasSubstr("Expected Image 'Sampled' parameter to be 0 or 1"));
653 }
654 
TEST_F(ValidateImage,SampledImageVulkanUnknownSampled)655 TEST_F(ValidateImage, SampledImageVulkanUnknownSampled) {
656   const std::string body = R"(
657 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
658 %sampler = OpLoad %type_sampler %uniform_sampler
659 %simg = OpSampledImage %type_sampled_image_u32_2d_0000 %img %sampler
660 )";
661 
662   const spv_target_env env = SPV_ENV_VULKAN_1_0;
663   CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
664   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
665   EXPECT_THAT(getDiagnosticString(),
666               HasSubstr("Expected Image 'Sampled' parameter to "
667                         "be 1 for Vulkan environment."));
668 }
669 
TEST_F(ValidateImage,SampledImageNotSampler)670 TEST_F(ValidateImage, SampledImageNotSampler) {
671   const std::string body = R"(
672 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
673 %sampler = OpLoad %type_sampler %uniform_sampler
674 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %img
675 )";
676 
677   CompileSuccessfully(GenerateShaderCode(body).c_str());
678   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
679   EXPECT_THAT(getDiagnosticString(),
680               HasSubstr("Expected Sampler to be of type OpTypeSampler"));
681 }
682 
TEST_F(ValidateImage,ImageTexelPointerSuccess)683 TEST_F(ValidateImage, ImageTexelPointerSuccess) {
684   const std::string body = R"(
685 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
686 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
687 )";
688 
689   CompileSuccessfully(GenerateShaderCode(body).c_str());
690   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
691 }
692 
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotPointer)693 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotPointer) {
694   const std::string body = R"(
695 %texel_ptr = OpImageTexelPointer %type_image_u32_buffer_0002_r32ui %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
696 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
697 )";
698 
699   CompileSuccessfully(GenerateShaderCode(body).c_str());
700   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
701   EXPECT_THAT(getDiagnosticString(),
702               HasSubstr("Expected Result Type to be OpTypePointer"));
703 }
704 
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotImageClass)705 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotImageClass) {
706   const std::string body = R"(
707 %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
708 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
709 )";
710 
711   CompileSuccessfully(GenerateShaderCode(body).c_str());
712   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
713   EXPECT_THAT(getDiagnosticString(),
714               HasSubstr("Expected Result Type to be OpTypePointer whose "
715                         "Storage Class operand is Image"));
716 }
717 
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotNumericNorVoid)718 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotNumericNorVoid) {
719   const std::string body = R"(
720 %texel_ptr = OpImageTexelPointer %ptr_Image_u32arr4 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
721 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
722 )";
723 
724   CompileSuccessfully(GenerateShaderCode(body).c_str());
725   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
726   EXPECT_THAT(
727       getDiagnosticString(),
728       HasSubstr("Expected Result Type to be OpTypePointer whose Type operand "
729                 "must be a scalar numerical type or OpTypeVoid"));
730 }
731 
TEST_F(ValidateImage,ImageTexelPointerImageNotResultTypePointer)732 TEST_F(ValidateImage, ImageTexelPointerImageNotResultTypePointer) {
733   const std::string body = R"(
734 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %type_image_f32_buffer_0002_r32ui %u32_0 %u32_0
735 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
736 )";
737 
738   CompileSuccessfully(GenerateShaderCode(body).c_str());
739   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
740   EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 140[%140] cannot be a "
741                                                "type"));
742 }
743 
TEST_F(ValidateImage,ImageTexelPointerImageNotImage)744 TEST_F(ValidateImage, ImageTexelPointerImageNotImage) {
745   const std::string body = R"(
746 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_sampler %u32_0 %u32_0
747 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
748 )";
749 
750   CompileSuccessfully(GenerateShaderCode(body).c_str());
751   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
752   EXPECT_THAT(
753       getDiagnosticString(),
754       HasSubstr("Expected Image to be OpTypePointer with Type OpTypeImage"));
755 }
756 
TEST_F(ValidateImage,ImageTexelPointerImageSampledNotResultType)757 TEST_F(ValidateImage, ImageTexelPointerImageSampledNotResultType) {
758   const std::string body = R"(
759 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_f32_cube_0101 %u32_0 %u32_0
760 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
761 )";
762 
763   CompileSuccessfully(GenerateShaderCode(body).c_str());
764   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
765   EXPECT_THAT(getDiagnosticString(),
766               HasSubstr("Expected Image 'Sampled Type' to be the same as the "
767                         "Type pointed to by Result Type"));
768 }
769 
TEST_F(ValidateImage,ImageTexelPointerImageDimSubpassDataBad)770 TEST_F(ValidateImage, ImageTexelPointerImageDimSubpassDataBad) {
771   const std::string body = R"(
772 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_spd_0002 %u32_0 %u32_0
773 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
774 )";
775 
776   CompileSuccessfully(GenerateShaderCode(body).c_str());
777   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
778   EXPECT_THAT(
779       getDiagnosticString(),
780       HasSubstr(
781           "Image Dim SubpassData cannot be used with OpImageTexelPointer"));
782 }
783 
TEST_F(ValidateImage,ImageTexelPointerImageCoordTypeBad)784 TEST_F(ValidateImage, ImageTexelPointerImageCoordTypeBad) {
785   const std::string body = R"(
786 %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32ui %f32_0 %f32_0
787 %sum = OpAtomicIAdd %f32 %texel_ptr %f32_1 %f32_0 %f32_1
788 )";
789 
790   CompileSuccessfully(GenerateShaderCode(body).c_str());
791   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
792   EXPECT_THAT(getDiagnosticString(),
793               HasSubstr("Expected Coordinate to be integer scalar or vector"));
794 }
795 
TEST_F(ValidateImage,ImageTexelPointerImageCoordSizeBad)796 TEST_F(ValidateImage, ImageTexelPointerImageCoordSizeBad) {
797   const std::string body = R"(
798 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_u32_2d_0000 %u32vec3_012 %u32_0
799 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
800 )";
801 
802   CompileSuccessfully(GenerateShaderCode(body).c_str());
803   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
804   EXPECT_THAT(
805       getDiagnosticString(),
806       HasSubstr("Expected Coordinate to have 2 components, but given 3"));
807 }
808 
TEST_F(ValidateImage,ImageTexelPointerSampleNotIntScalar)809 TEST_F(ValidateImage, ImageTexelPointerSampleNotIntScalar) {
810   const std::string body = R"(
811 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %f32_0
812 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
813 )";
814 
815   CompileSuccessfully(GenerateShaderCode(body).c_str());
816   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
817   EXPECT_THAT(getDiagnosticString(),
818               HasSubstr("Expected Sample to be integer scalar"));
819 }
820 
TEST_F(ValidateImage,ImageTexelPointerSampleNotZeroForImageWithMSZero)821 TEST_F(ValidateImage, ImageTexelPointerSampleNotZeroForImageWithMSZero) {
822   const std::string body = R"(
823 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_1
824 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
825 )";
826 
827   CompileSuccessfully(GenerateShaderCode(body).c_str());
828   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
829   EXPECT_THAT(getDiagnosticString(),
830               HasSubstr("Expected Sample for Image with MS 0 to be a valid "
831                         "<id> for the value 0"));
832 }
833 
TEST_F(ValidateImage,SampleImplicitLodSuccess)834 TEST_F(ValidateImage, SampleImplicitLodSuccess) {
835   const std::string body = R"(
836 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
837 %sampler = OpLoad %type_sampler %uniform_sampler
838 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
839 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
840 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0_25
841 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
842 %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
843 %res6 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
844 %res7 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
845 %res8 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
846 )";
847 
848   const std::string extra = R"(
849 OpCapability VulkanMemoryModelKHR
850 OpExtension "SPV_KHR_vulkan_memory_model"
851 )";
852   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
853                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
854                           .c_str());
855   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
856 }
857 
TEST_F(ValidateImage,SampleImplicitLodWrongResultType)858 TEST_F(ValidateImage, SampleImplicitLodWrongResultType) {
859   const std::string body = R"(
860 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
861 %sampler = OpLoad %type_sampler %uniform_sampler
862 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
863 %res1 = OpImageSampleImplicitLod %f32 %simg %f32vec2_hh
864 )";
865 
866   CompileSuccessfully(GenerateShaderCode(body).c_str());
867   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
868   EXPECT_THAT(getDiagnosticString(),
869               HasSubstr("Expected Result Type to be int or float vector type"));
870 }
871 
TEST_F(ValidateImage,SampleImplicitLodWrongNumComponentsResultType)872 TEST_F(ValidateImage, SampleImplicitLodWrongNumComponentsResultType) {
873   const std::string body = R"(
874 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
875 %sampler = OpLoad %type_sampler %uniform_sampler
876 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
877 %res1 = OpImageSampleImplicitLod %f32vec3 %simg %f32vec2_hh
878 )";
879 
880   CompileSuccessfully(GenerateShaderCode(body).c_str());
881   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
882   EXPECT_THAT(getDiagnosticString(),
883               HasSubstr("Expected Result Type to have 4 components"));
884 }
885 
TEST_F(ValidateImage,SampleImplicitLodNotSampledImage)886 TEST_F(ValidateImage, SampleImplicitLodNotSampledImage) {
887   const std::string body = R"(
888 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
889 %res1 = OpImageSampleImplicitLod %f32vec4 %img %f32vec2_hh
890 )";
891 
892   CompileSuccessfully(GenerateShaderCode(body).c_str());
893   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
894   EXPECT_THAT(
895       getDiagnosticString(),
896       HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
897 }
898 
TEST_F(ValidateImage,SampleImplicitLodWrongSampledType)899 TEST_F(ValidateImage, SampleImplicitLodWrongSampledType) {
900   const std::string body = R"(
901 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
902 %sampler = OpLoad %type_sampler %uniform_sampler
903 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
904 %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
905 )";
906 
907   CompileSuccessfully(GenerateShaderCode(body).c_str());
908   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
909   EXPECT_THAT(getDiagnosticString(),
910               HasSubstr("Expected Image 'Sampled Type' to be the same as "
911                         "Result Type components"));
912 }
913 
TEST_F(ValidateImage,SampleImplicitLodVoidSampledType)914 TEST_F(ValidateImage, SampleImplicitLodVoidSampledType) {
915   const std::string body = R"(
916 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
917 %sampler = OpLoad %type_sampler %uniform_sampler
918 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
919 %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
920 )";
921 
922   CompileSuccessfully(GenerateShaderCode(body).c_str());
923   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
924 }
925 
TEST_F(ValidateImage,SampleImplicitLodWrongCoordinateType)926 TEST_F(ValidateImage, SampleImplicitLodWrongCoordinateType) {
927   const std::string body = R"(
928 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
929 %sampler = OpLoad %type_sampler %uniform_sampler
930 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
931 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %img
932 )";
933 
934   CompileSuccessfully(GenerateShaderCode(body).c_str());
935   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
936   EXPECT_THAT(getDiagnosticString(),
937               HasSubstr("Expected Coordinate to be float scalar or vector"));
938 }
939 
TEST_F(ValidateImage,SampleImplicitLodCoordinateSizeTooSmall)940 TEST_F(ValidateImage, SampleImplicitLodCoordinateSizeTooSmall) {
941   const std::string body = R"(
942 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
943 %sampler = OpLoad %type_sampler %uniform_sampler
944 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
945 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32_0_5
946 )";
947 
948   CompileSuccessfully(GenerateShaderCode(body).c_str());
949   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
950   EXPECT_THAT(getDiagnosticString(),
951               HasSubstr("Expected Coordinate to have at least 2 components, "
952                         "but given only 1"));
953 }
954 
TEST_F(ValidateImage,SampleExplicitLodSuccessShader)955 TEST_F(ValidateImage, SampleExplicitLodSuccessShader) {
956   const std::string body = R"(
957 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
958 %sampler = OpLoad %type_sampler %uniform_sampler
959 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
960 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod %f32_1
961 %res2 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_10 %f32vec2_01
962 %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
963 %res4 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
964 %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset|MinLod %f32vec2_10 %f32vec2_01 %s32vec2_01 %f32_0_5
965 %res6 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod|NonPrivateTexelKHR %f32_1
966 )";
967 
968   const std::string extra = R"(
969 OpCapability VulkanMemoryModelKHR
970 OpExtension "SPV_KHR_vulkan_memory_model"
971 )";
972   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
973                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
974                           .c_str());
975   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
976 }
977 
TEST_F(ValidateImage,SampleExplicitLodSuccessKernel)978 TEST_F(ValidateImage, SampleExplicitLodSuccessKernel) {
979   const std::string body = R"(
980 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
981 %sampler = OpLoad %type_sampler %uniform_sampler
982 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
983 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec4_0123 Lod %f32_1
984 %res2 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Grad %f32vec2_10 %f32vec2_01
985 %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %u32vec2_01
986 %res4 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Offset %u32vec2_01
987 %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset %f32vec2_10 %f32vec2_01 %u32vec2_01
988 )";
989 
990   CompileSuccessfully(GenerateKernelCode(body).c_str());
991   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
992 }
993 
TEST_F(ValidateImage,SampleExplicitLodSuccessCubeArrayed)994 TEST_F(ValidateImage, SampleExplicitLodSuccessCubeArrayed) {
995   const std::string body = R"(
996 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
997 %sampler = OpLoad %type_sampler %uniform_sampler
998 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
999 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec3_hhh
1000 )";
1001 
1002   CompileSuccessfully(GenerateShaderCode(body).c_str());
1003   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1004 }
1005 
TEST_F(ValidateImage,SampleExplicitLodWrongResultType)1006 TEST_F(ValidateImage, SampleExplicitLodWrongResultType) {
1007   const std::string body = R"(
1008 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1009 %sampler = OpLoad %type_sampler %uniform_sampler
1010 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1011 %res1 = OpImageSampleExplicitLod %f32 %simg %f32vec2_hh Lod %f32_1
1012 )";
1013 
1014   CompileSuccessfully(GenerateShaderCode(body).c_str());
1015   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1016   EXPECT_THAT(getDiagnosticString(),
1017               HasSubstr("Expected Result Type to be int or float vector type"));
1018 }
1019 
TEST_F(ValidateImage,SampleExplicitLodWrongNumComponentsResultType)1020 TEST_F(ValidateImage, SampleExplicitLodWrongNumComponentsResultType) {
1021   const std::string body = R"(
1022 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1023 %sampler = OpLoad %type_sampler %uniform_sampler
1024 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1025 %res1 = OpImageSampleExplicitLod %f32vec3 %simg %f32vec2_hh Lod %f32_1
1026 )";
1027 
1028   CompileSuccessfully(GenerateShaderCode(body).c_str());
1029   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1030   EXPECT_THAT(getDiagnosticString(),
1031               HasSubstr("Expected Result Type to have 4 components"));
1032 }
1033 
TEST_F(ValidateImage,SampleExplicitLodNotSampledImage)1034 TEST_F(ValidateImage, SampleExplicitLodNotSampledImage) {
1035   const std::string body = R"(
1036 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1037 %res1 = OpImageSampleExplicitLod %f32vec4 %img %f32vec2_hh Lod %f32_1
1038 )";
1039 
1040   CompileSuccessfully(GenerateShaderCode(body).c_str());
1041   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1042   EXPECT_THAT(
1043       getDiagnosticString(),
1044       HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1045 }
1046 
TEST_F(ValidateImage,SampleExplicitLodWrongSampledType)1047 TEST_F(ValidateImage, SampleExplicitLodWrongSampledType) {
1048   const std::string body = R"(
1049 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1050 %sampler = OpLoad %type_sampler %uniform_sampler
1051 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1052 %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
1053 )";
1054 
1055   CompileSuccessfully(GenerateShaderCode(body).c_str());
1056   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1057   EXPECT_THAT(getDiagnosticString(),
1058               HasSubstr("Expected Image 'Sampled Type' to be the same as "
1059                         "Result Type components"));
1060 }
1061 
TEST_F(ValidateImage,SampleExplicitLodVoidSampledType)1062 TEST_F(ValidateImage, SampleExplicitLodVoidSampledType) {
1063   const std::string body = R"(
1064 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1065 %sampler = OpLoad %type_sampler %uniform_sampler
1066 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1067 %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
1068 )";
1069 
1070   CompileSuccessfully(GenerateShaderCode(body).c_str());
1071   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1072 }
1073 
TEST_F(ValidateImage,SampleExplicitLodWrongCoordinateType)1074 TEST_F(ValidateImage, SampleExplicitLodWrongCoordinateType) {
1075   const std::string body = R"(
1076 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1077 %sampler = OpLoad %type_sampler %uniform_sampler
1078 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1079 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %img Lod %f32_1
1080 )";
1081 
1082   CompileSuccessfully(GenerateShaderCode(body).c_str());
1083   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1084   EXPECT_THAT(getDiagnosticString(),
1085               HasSubstr("Expected Coordinate to be float scalar or vector"));
1086 }
1087 
TEST_F(ValidateImage,SampleExplicitLodCoordinateSizeTooSmall)1088 TEST_F(ValidateImage, SampleExplicitLodCoordinateSizeTooSmall) {
1089   const std::string body = R"(
1090 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1091 %sampler = OpLoad %type_sampler %uniform_sampler
1092 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1093 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32_0_5 Lod %f32_1
1094 )";
1095 
1096   CompileSuccessfully(GenerateShaderCode(body).c_str());
1097   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1098   EXPECT_THAT(getDiagnosticString(),
1099               HasSubstr("Expected Coordinate to have at least 2 components, "
1100                         "but given only 1"));
1101 }
1102 
TEST_F(ValidateImage,SampleExplicitLodBias)1103 TEST_F(ValidateImage, SampleExplicitLodBias) {
1104   const std::string body = R"(
1105 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1106 %sampler = OpLoad %type_sampler %uniform_sampler
1107 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1108 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Bias|Lod %f32_1 %f32_1
1109 )";
1110 
1111   CompileSuccessfully(GenerateShaderCode(body).c_str());
1112   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1113   EXPECT_THAT(
1114       getDiagnosticString(),
1115       HasSubstr(
1116           "Image Operand Bias can only be used with ImplicitLod opcodes"));
1117 }
1118 
TEST_F(ValidateImage,LodAndGrad)1119 TEST_F(ValidateImage, LodAndGrad) {
1120   const std::string body = R"(
1121 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1122 %sampler = OpLoad %type_sampler %uniform_sampler
1123 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1124 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|Grad %f32_1 %f32vec2_hh %f32vec2_hh
1125 )";
1126 
1127   CompileSuccessfully(GenerateShaderCode(body).c_str());
1128   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1129   EXPECT_THAT(
1130       getDiagnosticString(),
1131       HasSubstr(
1132           "Image Operand bits Lod and Grad cannot be set at the same time"));
1133 }
1134 
TEST_F(ValidateImage,ImplicitLodWithLod)1135 TEST_F(ValidateImage, ImplicitLodWithLod) {
1136   const std::string body = R"(
1137 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1138 %sampler = OpLoad %type_sampler %uniform_sampler
1139 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1140 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_0_5
1141 )";
1142 
1143   CompileSuccessfully(GenerateShaderCode(body).c_str());
1144   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1145   EXPECT_THAT(
1146       getDiagnosticString(),
1147       HasSubstr("Image Operand Lod can only be used with ExplicitLod opcodes "
1148                 "and OpImageFetch"));
1149 }
1150 
TEST_F(ValidateImage,LodWrongType)1151 TEST_F(ValidateImage, LodWrongType) {
1152   const std::string body = R"(
1153 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1154 %sampler = OpLoad %type_sampler %uniform_sampler
1155 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1156 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32vec2_hh)";
1157 
1158   CompileSuccessfully(GenerateShaderCode(body).c_str());
1159   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1160   EXPECT_THAT(getDiagnosticString(),
1161               HasSubstr("Expected Image Operand Lod to be float scalar when "
1162                         "used with ExplicitLod"));
1163 }
1164 
TEST_F(ValidateImage,LodWrongDim)1165 TEST_F(ValidateImage, LodWrongDim) {
1166   const std::string body = R"(
1167 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1168 %sampler = OpLoad %type_sampler %uniform_sampler
1169 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1170 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32_0)";
1171 
1172   CompileSuccessfully(GenerateShaderCode(body).c_str());
1173   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1174   EXPECT_THAT(getDiagnosticString(),
1175               HasSubstr("Image Operand Lod requires 'Dim' parameter to be 1D, "
1176                         "2D, 3D or Cube"));
1177 }
1178 
TEST_F(ValidateImage,LodMultisampled)1179 TEST_F(ValidateImage, LodMultisampled) {
1180   const std::string body = R"(
1181 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
1182 %sampler = OpLoad %type_sampler %uniform_sampler
1183 %simg = OpSampledImage %type_sampled_image_f32_2d_0010 %img %sampler
1184 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32_0)";
1185 
1186   CompileSuccessfully(GenerateShaderCode(body).c_str());
1187   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1188   EXPECT_THAT(getDiagnosticString(),
1189               HasSubstr("Image Operand Lod requires 'MS' parameter to be 0"));
1190 }
1191 
TEST_F(ValidateImage,MinLodIncompatible)1192 TEST_F(ValidateImage, MinLodIncompatible) {
1193   const std::string body = R"(
1194 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1195 %sampler = OpLoad %type_sampler %uniform_sampler
1196 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1197 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|MinLod %f32_0 %f32_0)";
1198 
1199   CompileSuccessfully(GenerateShaderCode(body).c_str());
1200   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1201   EXPECT_THAT(
1202       getDiagnosticString(),
1203       HasSubstr(
1204           "Image Operand MinLod can only be used with ImplicitLod opcodes or "
1205           "together with Image Operand Grad"));
1206 }
1207 
TEST_F(ValidateImage,ImplicitLodWithGrad)1208 TEST_F(ValidateImage, ImplicitLodWithGrad) {
1209   const std::string body = R"(
1210 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1211 %sampler = OpLoad %type_sampler %uniform_sampler
1212 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1213 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_hh %f32vec2_hh
1214 )";
1215 
1216   CompileSuccessfully(GenerateShaderCode(body).c_str());
1217   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1218   EXPECT_THAT(
1219       getDiagnosticString(),
1220       HasSubstr(
1221           "Image Operand Grad can only be used with ExplicitLod opcodes"));
1222 }
1223 
TEST_F(ValidateImage,SampleImplicitLod3DArrayedMultisampledSuccess)1224 TEST_F(ValidateImage, SampleImplicitLod3DArrayedMultisampledSuccess) {
1225   const std::string body = R"(
1226 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1227 %sampler = OpLoad %type_sampler %uniform_sampler
1228 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1229 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000
1230 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec3_012
1231 %res3 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
1232 )";
1233 
1234   CompileSuccessfully(GenerateShaderCode(body).c_str());
1235   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1236 }
1237 
TEST_F(ValidateImage,SampleImplicitLodCubeArrayedSuccess)1238 TEST_F(ValidateImage, SampleImplicitLodCubeArrayedSuccess) {
1239   const std::string body = R"(
1240 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1241 %sampler = OpLoad %type_sampler %uniform_sampler
1242 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1243 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000
1244 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias %f32_0_25
1245 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %f32_0_5
1246 %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias|MinLod %f32_0_25 %f32_0_5
1247 )";
1248 
1249   CompileSuccessfully(GenerateShaderCode(body).c_str());
1250   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1251 }
1252 
TEST_F(ValidateImage,SampleImplicitLodBiasWrongType)1253 TEST_F(ValidateImage, SampleImplicitLodBiasWrongType) {
1254   const std::string body = R"(
1255 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1256 %sampler = OpLoad %type_sampler %uniform_sampler
1257 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1258 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %u32_0
1259 )";
1260 
1261   CompileSuccessfully(GenerateShaderCode(body).c_str());
1262   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1263   EXPECT_THAT(getDiagnosticString(),
1264               HasSubstr("Expected Image Operand Bias to be float scalar"));
1265 }
1266 
TEST_F(ValidateImage,SampleImplicitLodBiasWrongDim)1267 TEST_F(ValidateImage, SampleImplicitLodBiasWrongDim) {
1268   const std::string body = R"(
1269 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1270 %sampler = OpLoad %type_sampler %uniform_sampler
1271 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1272 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0
1273 )";
1274 
1275   CompileSuccessfully(GenerateShaderCode(body).c_str());
1276   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1277   EXPECT_THAT(getDiagnosticString(),
1278               HasSubstr("Image Operand Bias requires 'Dim' parameter to be 1D, "
1279                         "2D, 3D or Cube"));
1280 }
1281 
TEST_F(ValidateImage,SampleImplicitLodBiasMultisampled)1282 TEST_F(ValidateImage, SampleImplicitLodBiasMultisampled) {
1283   const std::string body = R"(
1284 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1285 %sampler = OpLoad %type_sampler %uniform_sampler
1286 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1287 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias %f32_0_25
1288 )";
1289 
1290   CompileSuccessfully(GenerateShaderCode(body).c_str());
1291   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1292   EXPECT_THAT(getDiagnosticString(),
1293               HasSubstr("Image Operand Bias requires 'MS' parameter to be 0"));
1294 }
1295 
TEST_F(ValidateImage,SampleExplicitLodGradDxWrongType)1296 TEST_F(ValidateImage, SampleExplicitLodGradDxWrongType) {
1297   const std::string body = R"(
1298 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1299 %sampler = OpLoad %type_sampler %uniform_sampler
1300 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1301 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %s32vec3_012 %f32vec3_hhh
1302 )";
1303 
1304   CompileSuccessfully(GenerateShaderCode(body).c_str());
1305   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1306   EXPECT_THAT(getDiagnosticString(),
1307               HasSubstr("Expected both Image Operand Grad ids to be float "
1308                         "scalars or vectors"));
1309 }
1310 
TEST_F(ValidateImage,SampleExplicitLodGradDyWrongType)1311 TEST_F(ValidateImage, SampleExplicitLodGradDyWrongType) {
1312   const std::string body = R"(
1313 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1314 %sampler = OpLoad %type_sampler %uniform_sampler
1315 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1316 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad  %f32vec3_hhh %s32vec3_012
1317 )";
1318 
1319   CompileSuccessfully(GenerateShaderCode(body).c_str());
1320   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1321   EXPECT_THAT(getDiagnosticString(),
1322               HasSubstr("Expected both Image Operand Grad ids to be float "
1323                         "scalars or vectors"));
1324 }
1325 
TEST_F(ValidateImage,SampleExplicitLodGradDxWrongSize)1326 TEST_F(ValidateImage, SampleExplicitLodGradDxWrongSize) {
1327   const std::string body = R"(
1328 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1329 %sampler = OpLoad %type_sampler %uniform_sampler
1330 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1331 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec2_00 %f32vec3_hhh
1332 )";
1333 
1334   CompileSuccessfully(GenerateShaderCode(body).c_str());
1335   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1336   EXPECT_THAT(
1337       getDiagnosticString(),
1338       HasSubstr(
1339           "Expected Image Operand Grad dx to have 3 components, but given 2"));
1340 }
1341 
TEST_F(ValidateImage,SampleExplicitLodGradDyWrongSize)1342 TEST_F(ValidateImage, SampleExplicitLodGradDyWrongSize) {
1343   const std::string body = R"(
1344 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1345 %sampler = OpLoad %type_sampler %uniform_sampler
1346 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1347 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec2_00
1348 )";
1349 
1350   CompileSuccessfully(GenerateShaderCode(body).c_str());
1351   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1352   EXPECT_THAT(
1353       getDiagnosticString(),
1354       HasSubstr(
1355           "Expected Image Operand Grad dy to have 3 components, but given 2"));
1356 }
1357 
TEST_F(ValidateImage,SampleExplicitLodGradMultisampled)1358 TEST_F(ValidateImage, SampleExplicitLodGradMultisampled) {
1359   const std::string body = R"(
1360 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1361 %sampler = OpLoad %type_sampler %uniform_sampler
1362 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1363 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_000 %f32vec3_000
1364 )";
1365 
1366   CompileSuccessfully(GenerateShaderCode(body).c_str());
1367   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1368   EXPECT_THAT(getDiagnosticString(),
1369               HasSubstr("Image Operand Grad requires 'MS' parameter to be 0"));
1370 }
1371 
TEST_F(ValidateImage,SampleImplicitLodConstOffsetCubeDim)1372 TEST_F(ValidateImage, SampleImplicitLodConstOffsetCubeDim) {
1373   const std::string body = R"(
1374 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1375 %sampler = OpLoad %type_sampler %uniform_sampler
1376 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1377 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec3_012
1378 )";
1379 
1380   CompileSuccessfully(GenerateShaderCode(body).c_str());
1381   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1382   EXPECT_THAT(
1383       getDiagnosticString(),
1384       HasSubstr(
1385           "Image Operand ConstOffset cannot be used with Cube Image 'Dim'"));
1386 }
1387 
TEST_F(ValidateImage,SampleImplicitLodConstOffsetWrongType)1388 TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongType) {
1389   const std::string body = R"(
1390 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1391 %sampler = OpLoad %type_sampler %uniform_sampler
1392 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1393 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %f32vec3_000
1394 )";
1395 
1396   CompileSuccessfully(GenerateShaderCode(body).c_str());
1397   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1398   EXPECT_THAT(
1399       getDiagnosticString(),
1400       HasSubstr(
1401           "Expected Image Operand ConstOffset to be int scalar or vector"));
1402 }
1403 
TEST_F(ValidateImage,SampleImplicitLodConstOffsetWrongSize)1404 TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongSize) {
1405   const std::string body = R"(
1406 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1407 %sampler = OpLoad %type_sampler %uniform_sampler
1408 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1409 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec2_01
1410 )";
1411 
1412   CompileSuccessfully(GenerateShaderCode(body).c_str());
1413   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1414   EXPECT_THAT(getDiagnosticString(),
1415               HasSubstr("Expected Image Operand ConstOffset to have 3 "
1416                         "components, but given 2"));
1417 }
1418 
TEST_F(ValidateImage,SampleImplicitLodConstOffsetNotConst)1419 TEST_F(ValidateImage, SampleImplicitLodConstOffsetNotConst) {
1420   const std::string body = R"(
1421 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1422 %sampler = OpLoad %type_sampler %uniform_sampler
1423 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1424 %offset = OpSNegate %s32vec3 %s32vec3_012
1425 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %offset
1426 )";
1427 
1428   CompileSuccessfully(GenerateShaderCode(body).c_str());
1429   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1430   EXPECT_THAT(
1431       getDiagnosticString(),
1432       HasSubstr("Expected Image Operand ConstOffset to be a const object"));
1433 }
1434 
TEST_F(ValidateImage,SampleImplicitLodOffsetCubeDim)1435 TEST_F(ValidateImage, SampleImplicitLodOffsetCubeDim) {
1436   const std::string body = R"(
1437 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1438 %sampler = OpLoad %type_sampler %uniform_sampler
1439 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1440 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
1441 )";
1442 
1443   CompileSuccessfully(GenerateShaderCode(body).c_str());
1444   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1445   EXPECT_THAT(
1446       getDiagnosticString(),
1447       HasSubstr("Image Operand Offset cannot be used with Cube Image 'Dim'"));
1448 }
1449 
TEST_F(ValidateImage,SampleImplicitLodOffsetWrongType)1450 TEST_F(ValidateImage, SampleImplicitLodOffsetWrongType) {
1451   const std::string body = R"(
1452 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1453 %sampler = OpLoad %type_sampler %uniform_sampler
1454 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1455 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %f32vec3_000
1456 )";
1457 
1458   CompileSuccessfully(GenerateShaderCode(body).c_str());
1459   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1460   EXPECT_THAT(
1461       getDiagnosticString(),
1462       HasSubstr("Expected Image Operand Offset to be int scalar or vector"));
1463 }
1464 
TEST_F(ValidateImage,SampleImplicitLodOffsetWrongSize)1465 TEST_F(ValidateImage, SampleImplicitLodOffsetWrongSize) {
1466   const std::string body = R"(
1467 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1468 %sampler = OpLoad %type_sampler %uniform_sampler
1469 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1470 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
1471 )";
1472 
1473   CompileSuccessfully(GenerateShaderCode(body).c_str());
1474   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1475   EXPECT_THAT(
1476       getDiagnosticString(),
1477       HasSubstr(
1478           "Expected Image Operand Offset to have 3 components, but given 2"));
1479 }
1480 
TEST_F(ValidateImage,SampleImplicitLodMoreThanOneOffset)1481 TEST_F(ValidateImage, SampleImplicitLodMoreThanOneOffset) {
1482   const std::string body = R"(
1483 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1484 %sampler = OpLoad %type_sampler %uniform_sampler
1485 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1486 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec3_012 %s32vec3_012
1487 )";
1488 
1489   CompileSuccessfully(GenerateShaderCode(body).c_str());
1490   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1491   EXPECT_THAT(getDiagnosticString(),
1492               HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets "
1493                         "cannot be used together"));
1494 }
1495 
TEST_F(ValidateImage,SampleImplicitLodMinLodWrongType)1496 TEST_F(ValidateImage, SampleImplicitLodMinLodWrongType) {
1497   const std::string body = R"(
1498 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1499 %sampler = OpLoad %type_sampler %uniform_sampler
1500 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1501 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %s32_0
1502 )";
1503 
1504   CompileSuccessfully(GenerateShaderCode(body).c_str());
1505   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1506   EXPECT_THAT(getDiagnosticString(),
1507               HasSubstr("Expected Image Operand MinLod to be float scalar"));
1508 }
1509 
TEST_F(ValidateImage,SampleImplicitLodMinLodWrongDim)1510 TEST_F(ValidateImage, SampleImplicitLodMinLodWrongDim) {
1511   const std::string body = R"(
1512 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1513 %sampler = OpLoad %type_sampler %uniform_sampler
1514 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1515 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_25
1516 )";
1517 
1518   CompileSuccessfully(GenerateShaderCode(body).c_str());
1519   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1520   EXPECT_THAT(getDiagnosticString(),
1521               HasSubstr("Image Operand MinLod requires 'Dim' parameter to be "
1522                         "1D, 2D, 3D or Cube"));
1523 }
1524 
TEST_F(ValidateImage,SampleImplicitLodMinLodMultisampled)1525 TEST_F(ValidateImage, SampleImplicitLodMinLodMultisampled) {
1526   const std::string body = R"(
1527 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1528 %sampler = OpLoad %type_sampler %uniform_sampler
1529 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1530 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %f32_0_25
1531 )";
1532 
1533   CompileSuccessfully(GenerateShaderCode(body).c_str());
1534   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1535   EXPECT_THAT(
1536       getDiagnosticString(),
1537       HasSubstr("Image Operand MinLod requires 'MS' parameter to be 0"));
1538 }
1539 
TEST_F(ValidateImage,SampleProjExplicitLodSuccess2D)1540 TEST_F(ValidateImage, SampleProjExplicitLodSuccess2D) {
1541   const std::string body = R"(
1542 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1543 %sampler = OpLoad %type_sampler %uniform_sampler
1544 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1545 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod %f32_1
1546 %res3 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
1547 %res4 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
1548 %res5 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
1549 %res7 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
1550 %res8 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod|NonPrivateTexelKHR %f32_1
1551 )";
1552 
1553   const std::string extra = R"(
1554 OpCapability VulkanMemoryModelKHR
1555 OpExtension "SPV_KHR_vulkan_memory_model"
1556 )";
1557   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1558                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1559                           .c_str());
1560   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1561 }
1562 
TEST_F(ValidateImage,SampleProjExplicitLodSuccessRect)1563 TEST_F(ValidateImage, SampleProjExplicitLodSuccessRect) {
1564   const std::string body = R"(
1565 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1566 %sampler = OpLoad %type_sampler %uniform_sampler
1567 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1568 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
1569 %res2 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
1570 )";
1571 
1572   CompileSuccessfully(GenerateShaderCode(body).c_str());
1573   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1574 }
1575 
TEST_F(ValidateImage,SampleProjExplicitLodWrongResultType)1576 TEST_F(ValidateImage, SampleProjExplicitLodWrongResultType) {
1577   const std::string body = R"(
1578 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1579 %sampler = OpLoad %type_sampler %uniform_sampler
1580 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1581 %res1 = OpImageSampleProjExplicitLod %f32 %simg %f32vec3_hhh Lod %f32_1
1582 )";
1583 
1584   CompileSuccessfully(GenerateShaderCode(body).c_str());
1585   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1586   EXPECT_THAT(getDiagnosticString(),
1587               HasSubstr("Expected Result Type to be int or float vector type"));
1588 }
1589 
TEST_F(ValidateImage,SampleProjExplicitLodWrongNumComponentsResultType)1590 TEST_F(ValidateImage, SampleProjExplicitLodWrongNumComponentsResultType) {
1591   const std::string body = R"(
1592 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1593 %sampler = OpLoad %type_sampler %uniform_sampler
1594 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1595 %res1 = OpImageSampleProjExplicitLod %f32vec3 %simg %f32vec3_hhh Lod %f32_1
1596 )";
1597 
1598   CompileSuccessfully(GenerateShaderCode(body).c_str());
1599   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1600   EXPECT_THAT(getDiagnosticString(),
1601               HasSubstr("Expected Result Type to have 4 components"));
1602 }
1603 
TEST_F(ValidateImage,SampleProjExplicitLodNotSampledImage)1604 TEST_F(ValidateImage, SampleProjExplicitLodNotSampledImage) {
1605   const std::string body = R"(
1606 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1607 %res1 = OpImageSampleProjExplicitLod %f32vec4 %img %f32vec3_hhh Lod %f32_1
1608 )";
1609 
1610   CompileSuccessfully(GenerateShaderCode(body).c_str());
1611   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1612   EXPECT_THAT(
1613       getDiagnosticString(),
1614       HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1615 }
1616 
TEST_F(ValidateImage,SampleProjExplicitLodWrongSampledType)1617 TEST_F(ValidateImage, SampleProjExplicitLodWrongSampledType) {
1618   const std::string body = R"(
1619 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1620 %sampler = OpLoad %type_sampler %uniform_sampler
1621 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1622 %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
1623 )";
1624 
1625   CompileSuccessfully(GenerateShaderCode(body).c_str());
1626   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1627   EXPECT_THAT(getDiagnosticString(),
1628               HasSubstr("Expected Image 'Sampled Type' to be the same as "
1629                         "Result Type components"));
1630 }
1631 
TEST_F(ValidateImage,SampleProjExplicitLodVoidSampledType)1632 TEST_F(ValidateImage, SampleProjExplicitLodVoidSampledType) {
1633   const std::string body = R"(
1634 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1635 %sampler = OpLoad %type_sampler %uniform_sampler
1636 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1637 %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
1638 )";
1639 
1640   CompileSuccessfully(GenerateShaderCode(body).c_str());
1641   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1642 }
1643 
TEST_F(ValidateImage,SampleProjExplicitLodWrongCoordinateType)1644 TEST_F(ValidateImage, SampleProjExplicitLodWrongCoordinateType) {
1645   const std::string body = R"(
1646 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1647 %sampler = OpLoad %type_sampler %uniform_sampler
1648 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1649 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %img Lod %f32_1
1650 )";
1651 
1652   CompileSuccessfully(GenerateShaderCode(body).c_str());
1653   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1654   EXPECT_THAT(getDiagnosticString(),
1655               HasSubstr("Expected Coordinate to be float scalar or vector"));
1656 }
1657 
TEST_F(ValidateImage,SampleProjExplicitLodCoordinateSizeTooSmall)1658 TEST_F(ValidateImage, SampleProjExplicitLodCoordinateSizeTooSmall) {
1659   const std::string body = R"(
1660 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1661 %sampler = OpLoad %type_sampler %uniform_sampler
1662 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1663 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_1
1664 )";
1665 
1666   CompileSuccessfully(GenerateShaderCode(body).c_str());
1667   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1668   EXPECT_THAT(getDiagnosticString(),
1669               HasSubstr("Expected Coordinate to have at least 3 components, "
1670                         "but given only 2"));
1671 }
1672 
TEST_F(ValidateImage,SampleProjImplicitLodSuccess)1673 TEST_F(ValidateImage, SampleProjImplicitLodSuccess) {
1674   const std::string body = R"(
1675 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1676 %sampler = OpLoad %type_sampler %uniform_sampler
1677 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1678 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh
1679 %res2 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias %f32_0_25
1680 %res4 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
1681 %res5 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
1682 %res6 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh MinLod %f32_0_5
1683 %res7 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
1684 %res8 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh NonPrivateTexelKHR
1685 )";
1686 
1687   const std::string extra = R"(
1688 OpCapability VulkanMemoryModelKHR
1689 OpExtension "SPV_KHR_vulkan_memory_model"
1690 )";
1691   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1692                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1693                           .c_str());
1694   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1695 }
1696 
TEST_F(ValidateImage,SampleProjImplicitLodWrongResultType)1697 TEST_F(ValidateImage, SampleProjImplicitLodWrongResultType) {
1698   const std::string body = R"(
1699 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1700 %sampler = OpLoad %type_sampler %uniform_sampler
1701 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1702 %res1 = OpImageSampleProjImplicitLod %f32 %simg %f32vec3_hhh
1703 )";
1704 
1705   CompileSuccessfully(GenerateShaderCode(body).c_str());
1706   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1707   EXPECT_THAT(getDiagnosticString(),
1708               HasSubstr("Expected Result Type to be int or float vector type"));
1709 }
1710 
TEST_F(ValidateImage,SampleProjImplicitLodWrongNumComponentsResultType)1711 TEST_F(ValidateImage, SampleProjImplicitLodWrongNumComponentsResultType) {
1712   const std::string body = R"(
1713 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1714 %sampler = OpLoad %type_sampler %uniform_sampler
1715 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1716 %res1 = OpImageSampleProjImplicitLod %f32vec3 %simg %f32vec3_hhh
1717 )";
1718 
1719   CompileSuccessfully(GenerateShaderCode(body).c_str());
1720   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1721   EXPECT_THAT(getDiagnosticString(),
1722               HasSubstr("Expected Result Type to have 4 components"));
1723 }
1724 
TEST_F(ValidateImage,SampleProjImplicitLodNotSampledImage)1725 TEST_F(ValidateImage, SampleProjImplicitLodNotSampledImage) {
1726   const std::string body = R"(
1727 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1728 %res1 = OpImageSampleProjImplicitLod %f32vec4 %img %f32vec3_hhh
1729 )";
1730 
1731   CompileSuccessfully(GenerateShaderCode(body).c_str());
1732   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1733   EXPECT_THAT(
1734       getDiagnosticString(),
1735       HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1736 }
1737 
TEST_F(ValidateImage,SampleProjImplicitLodWrongSampledType)1738 TEST_F(ValidateImage, SampleProjImplicitLodWrongSampledType) {
1739   const std::string body = R"(
1740 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1741 %sampler = OpLoad %type_sampler %uniform_sampler
1742 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1743 %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
1744 )";
1745 
1746   CompileSuccessfully(GenerateShaderCode(body).c_str());
1747   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1748   EXPECT_THAT(getDiagnosticString(),
1749               HasSubstr("Expected Image 'Sampled Type' to be the same as "
1750                         "Result Type components"));
1751 }
1752 
TEST_F(ValidateImage,SampleProjImplicitLodVoidSampledType)1753 TEST_F(ValidateImage, SampleProjImplicitLodVoidSampledType) {
1754   const std::string body = R"(
1755 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1756 %sampler = OpLoad %type_sampler %uniform_sampler
1757 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1758 %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
1759 )";
1760 
1761   CompileSuccessfully(GenerateShaderCode(body).c_str());
1762   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1763 }
1764 
TEST_F(ValidateImage,SampleProjImplicitLodWrongCoordinateType)1765 TEST_F(ValidateImage, SampleProjImplicitLodWrongCoordinateType) {
1766   const std::string body = R"(
1767 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1768 %sampler = OpLoad %type_sampler %uniform_sampler
1769 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1770 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %img
1771 )";
1772 
1773   CompileSuccessfully(GenerateShaderCode(body).c_str());
1774   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1775   EXPECT_THAT(getDiagnosticString(),
1776               HasSubstr("Expected Coordinate to be float scalar or vector"));
1777 }
1778 
TEST_F(ValidateImage,SampleProjImplicitLodCoordinateSizeTooSmall)1779 TEST_F(ValidateImage, SampleProjImplicitLodCoordinateSizeTooSmall) {
1780   const std::string body = R"(
1781 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1782 %sampler = OpLoad %type_sampler %uniform_sampler
1783 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1784 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh
1785 )";
1786 
1787   CompileSuccessfully(GenerateShaderCode(body).c_str());
1788   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1789   EXPECT_THAT(getDiagnosticString(),
1790               HasSubstr("Expected Coordinate to have at least 3 components, "
1791                         "but given only 2"));
1792 }
1793 
TEST_F(ValidateImage,SampleDrefImplicitLodSuccess)1794 TEST_F(ValidateImage, SampleDrefImplicitLodSuccess) {
1795   const std::string body = R"(
1796 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
1797 %sampler = OpLoad %type_sampler %uniform_sampler
1798 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
1799 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1
1800 %res2 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
1801 %res4 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
1802 %res5 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
1803 %res6 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
1804 %res7 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
1805 %res8 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
1806 )";
1807 
1808   const std::string extra = R"(
1809 OpCapability VulkanMemoryModelKHR
1810 OpExtension "SPV_KHR_vulkan_memory_model"
1811 )";
1812   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1813                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1814                           .c_str());
1815   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1816 }
1817 
TEST_F(ValidateImage,SampleDrefImplicitLodWrongResultType)1818 TEST_F(ValidateImage, SampleDrefImplicitLodWrongResultType) {
1819   const std::string body = R"(
1820 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1821 %sampler = OpLoad %type_sampler %uniform_sampler
1822 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1823 %res1 = OpImageSampleDrefImplicitLod %void %simg %f32vec2_hh %u32_1
1824 )";
1825 
1826   CompileSuccessfully(GenerateShaderCode(body).c_str());
1827   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1828   EXPECT_THAT(getDiagnosticString(),
1829               HasSubstr("Expected Result Type to be int or float scalar type"));
1830 }
1831 
TEST_F(ValidateImage,SampleDrefImplicitLodNotSampledImage)1832 TEST_F(ValidateImage, SampleDrefImplicitLodNotSampledImage) {
1833   const std::string body = R"(
1834 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
1835 %res1 = OpImageSampleDrefImplicitLod %u32 %img %f32vec2_hh %u32_1
1836 )";
1837 
1838   CompileSuccessfully(GenerateShaderCode(body).c_str());
1839   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1840   EXPECT_THAT(
1841       getDiagnosticString(),
1842       HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1843 }
1844 
TEST_F(ValidateImage,SampleDrefImplicitLodWrongSampledType)1845 TEST_F(ValidateImage, SampleDrefImplicitLodWrongSampledType) {
1846   const std::string body = R"(
1847 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
1848 %sampler = OpLoad %type_sampler %uniform_sampler
1849 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
1850 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_00 %u32_1
1851 )";
1852 
1853   CompileSuccessfully(GenerateShaderCode(body).c_str());
1854   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1855   EXPECT_THAT(
1856       getDiagnosticString(),
1857       HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
1858 }
1859 
TEST_F(ValidateImage,SampleDrefImplicitLodVoidSampledType)1860 TEST_F(ValidateImage, SampleDrefImplicitLodVoidSampledType) {
1861   const std::string body = R"(
1862 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1863 %sampler = OpLoad %type_sampler %uniform_sampler
1864 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1865 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %u32_1
1866 )";
1867 
1868   CompileSuccessfully(GenerateShaderCode(body).c_str());
1869   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1870   EXPECT_THAT(
1871       getDiagnosticString(),
1872       HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
1873 }
1874 
TEST_F(ValidateImage,SampleDrefImplicitLodWrongCoordinateType)1875 TEST_F(ValidateImage, SampleDrefImplicitLodWrongCoordinateType) {
1876   const std::string body = R"(
1877 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
1878 %sampler = OpLoad %type_sampler %uniform_sampler
1879 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
1880 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %img %u32_1
1881 )";
1882 
1883   CompileSuccessfully(GenerateShaderCode(body).c_str());
1884   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1885   EXPECT_THAT(getDiagnosticString(),
1886               HasSubstr("Expected Coordinate to be float scalar or vector"));
1887 }
1888 
TEST_F(ValidateImage,SampleDrefImplicitLodCoordinateSizeTooSmall)1889 TEST_F(ValidateImage, SampleDrefImplicitLodCoordinateSizeTooSmall) {
1890   const std::string body = R"(
1891 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1892 %sampler = OpLoad %type_sampler %uniform_sampler
1893 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1894 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32_0_5 %f32_0_5
1895 )";
1896 
1897   CompileSuccessfully(GenerateShaderCode(body).c_str());
1898   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1899   EXPECT_THAT(getDiagnosticString(),
1900               HasSubstr("Expected Coordinate to have at least 2 components, "
1901                         "but given only 1"));
1902 }
1903 
TEST_F(ValidateImage,SampleDrefImplicitLodWrongDrefType)1904 TEST_F(ValidateImage, SampleDrefImplicitLodWrongDrefType) {
1905   const std::string body = R"(
1906 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
1907 %sampler = OpLoad %type_sampler %uniform_sampler
1908 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
1909 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %f64_1
1910 )";
1911 
1912   CompileSuccessfully(GenerateShaderCode(body).c_str());
1913   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1914   EXPECT_THAT(getDiagnosticString(),
1915               HasSubstr("Expected Dref to be of 32-bit float type"));
1916 }
1917 
TEST_F(ValidateImage,SampleDrefExplicitLodSuccess)1918 TEST_F(ValidateImage, SampleDrefExplicitLodSuccess) {
1919   const std::string body = R"(
1920 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
1921 %sampler = OpLoad %type_sampler %uniform_sampler
1922 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
1923 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod %f32_1
1924 %res3 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad %f32vec3_hhh %f32vec3_hhh
1925 %res4 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 ConstOffset %s32vec3_012
1926 %res5 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Offset %s32vec3_012
1927 %res7 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad|Offset %f32vec3_hhh %f32vec3_hhh %s32vec3_012
1928 %res8 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod|NonPrivateTexelKHR %f32_1
1929 )";
1930 
1931   const std::string extra = R"(
1932 OpCapability VulkanMemoryModelKHR
1933 OpExtension "SPV_KHR_vulkan_memory_model"
1934 )";
1935   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1936                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1937                           .c_str());
1938   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1939 }
1940 
TEST_F(ValidateImage,SampleDrefExplicitLodWrongResultType)1941 TEST_F(ValidateImage, SampleDrefExplicitLodWrongResultType) {
1942   const std::string body = R"(
1943 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
1944 %sampler = OpLoad %type_sampler %uniform_sampler
1945 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
1946 %res1 = OpImageSampleDrefExplicitLod %bool %simg %f32vec3_hhh %s32_1 Lod %f32_1
1947 )";
1948 
1949   CompileSuccessfully(GenerateShaderCode(body).c_str());
1950   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1951   EXPECT_THAT(getDiagnosticString(),
1952               HasSubstr("Expected Result Type to be int or float scalar type"));
1953 }
1954 
TEST_F(ValidateImage,SampleDrefExplicitLodNotSampledImage)1955 TEST_F(ValidateImage, SampleDrefExplicitLodNotSampledImage) {
1956   const std::string body = R"(
1957 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
1958 %res1 = OpImageSampleDrefExplicitLod %s32 %img %f32vec3_hhh %s32_1 Lod %f32_1
1959 )";
1960 
1961   CompileSuccessfully(GenerateShaderCode(body).c_str());
1962   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1963   EXPECT_THAT(
1964       getDiagnosticString(),
1965       HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1966 }
1967 
TEST_F(ValidateImage,SampleDrefExplicitLodWrongSampledType)1968 TEST_F(ValidateImage, SampleDrefExplicitLodWrongSampledType) {
1969   const std::string body = R"(
1970 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
1971 %sampler = OpLoad %type_sampler %uniform_sampler
1972 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
1973 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec3_hhh %s32_1 Lod %f32_1
1974 )";
1975 
1976   CompileSuccessfully(GenerateShaderCode(body).c_str());
1977   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1978   EXPECT_THAT(
1979       getDiagnosticString(),
1980       HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
1981 }
1982 
TEST_F(ValidateImage,SampleDrefExplicitLodVoidSampledType)1983 TEST_F(ValidateImage, SampleDrefExplicitLodVoidSampledType) {
1984   const std::string body = R"(
1985 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1986 %sampler = OpLoad %type_sampler %uniform_sampler
1987 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1988 %res1 = OpImageSampleDrefExplicitLod %u32 %simg %f32vec2_00 %s32_1 Lod %f32_1
1989 )";
1990 
1991   CompileSuccessfully(GenerateShaderCode(body).c_str());
1992   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1993   EXPECT_THAT(
1994       getDiagnosticString(),
1995       HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
1996 }
1997 
TEST_F(ValidateImage,SampleDrefExplicitLodWrongCoordinateType)1998 TEST_F(ValidateImage, SampleDrefExplicitLodWrongCoordinateType) {
1999   const std::string body = R"(
2000 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2001 %sampler = OpLoad %type_sampler %uniform_sampler
2002 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2003 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %img %s32_1 Lod %f32_1
2004 )";
2005 
2006   CompileSuccessfully(GenerateShaderCode(body).c_str());
2007   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2008   EXPECT_THAT(getDiagnosticString(),
2009               HasSubstr("Expected Coordinate to be float scalar or vector"));
2010 }
2011 
TEST_F(ValidateImage,SampleDrefExplicitLodCoordinateSizeTooSmall)2012 TEST_F(ValidateImage, SampleDrefExplicitLodCoordinateSizeTooSmall) {
2013   const std::string body = R"(
2014 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2015 %sampler = OpLoad %type_sampler %uniform_sampler
2016 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2017 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec2_hh %s32_1 Lod %f32_1
2018 )";
2019 
2020   CompileSuccessfully(GenerateShaderCode(body).c_str());
2021   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2022   EXPECT_THAT(getDiagnosticString(),
2023               HasSubstr("Expected Coordinate to have at least 3 components, "
2024                         "but given only 2"));
2025 }
2026 
TEST_F(ValidateImage,SampleDrefExplicitLodWrongDrefType)2027 TEST_F(ValidateImage, SampleDrefExplicitLodWrongDrefType) {
2028   const std::string body = R"(
2029 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2030 %sampler = OpLoad %type_sampler %uniform_sampler
2031 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2032 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %u32_1 Lod %f32_1
2033 )";
2034 
2035   CompileSuccessfully(GenerateShaderCode(body).c_str());
2036   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2037   EXPECT_THAT(getDiagnosticString(),
2038               HasSubstr("Expected Dref to be of 32-bit float type"));
2039 }
2040 
TEST_F(ValidateImage,SampleProjDrefImplicitLodSuccess)2041 TEST_F(ValidateImage, SampleProjDrefImplicitLodSuccess) {
2042   const std::string body = R"(
2043 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2044 %sampler = OpLoad %type_sampler %uniform_sampler
2045 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2046 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5
2047 %res2 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias %f32_0_25
2048 %res4 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 ConstOffset %s32vec2_01
2049 %res5 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Offset %s32vec2_01
2050 %res6 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 MinLod %f32_0_5
2051 %res7 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2052 %res8 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 NonPrivateTexelKHR
2053 )";
2054 
2055   const std::string extra = R"(
2056 OpCapability VulkanMemoryModelKHR
2057 OpExtension "SPV_KHR_vulkan_memory_model"
2058 )";
2059   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2060                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2061                           .c_str());
2062   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2063 }
2064 
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongResultType)2065 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongResultType) {
2066   const std::string body = R"(
2067 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2068 %sampler = OpLoad %type_sampler %uniform_sampler
2069 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2070 %res1 = OpImageSampleProjDrefImplicitLod %void %simg %f32vec3_hhh %f32_0_5
2071 )";
2072 
2073   CompileSuccessfully(GenerateShaderCode(body).c_str());
2074   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2075   EXPECT_THAT(getDiagnosticString(),
2076               HasSubstr("Expected Result Type to be int or float scalar type"));
2077 }
2078 
TEST_F(ValidateImage,SampleProjDrefImplicitLodNotSampledImage)2079 TEST_F(ValidateImage, SampleProjDrefImplicitLodNotSampledImage) {
2080   const std::string body = R"(
2081 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2082 %res1 = OpImageSampleProjDrefImplicitLod %f32 %img %f32vec3_hhh %f32_0_5
2083 )";
2084 
2085   CompileSuccessfully(GenerateShaderCode(body).c_str());
2086   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2087   EXPECT_THAT(
2088       getDiagnosticString(),
2089       HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2090 }
2091 
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongSampledType)2092 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongSampledType) {
2093   const std::string body = R"(
2094 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2095 %sampler = OpLoad %type_sampler %uniform_sampler
2096 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2097 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2098 )";
2099 
2100   CompileSuccessfully(GenerateShaderCode(body).c_str());
2101   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2102   EXPECT_THAT(
2103       getDiagnosticString(),
2104       HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2105 }
2106 
TEST_F(ValidateImage,SampleProjDrefImplicitLodVoidSampledType)2107 TEST_F(ValidateImage, SampleProjDrefImplicitLodVoidSampledType) {
2108   const std::string body = R"(
2109 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2110 %sampler = OpLoad %type_sampler %uniform_sampler
2111 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2112 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2113 )";
2114 
2115   CompileSuccessfully(GenerateShaderCode(body).c_str());
2116   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2117   EXPECT_THAT(
2118       getDiagnosticString(),
2119       HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2120 }
2121 
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongCoordinateType)2122 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongCoordinateType) {
2123   const std::string body = R"(
2124 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2125 %sampler = OpLoad %type_sampler %uniform_sampler
2126 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2127 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %img %f32_0_5
2128 )";
2129 
2130   CompileSuccessfully(GenerateShaderCode(body).c_str());
2131   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2132   EXPECT_THAT(getDiagnosticString(),
2133               HasSubstr("Expected Coordinate to be float scalar or vector"));
2134 }
2135 
TEST_F(ValidateImage,SampleProjDrefImplicitLodCoordinateSizeTooSmall)2136 TEST_F(ValidateImage, SampleProjDrefImplicitLodCoordinateSizeTooSmall) {
2137   const std::string body = R"(
2138 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2139 %sampler = OpLoad %type_sampler %uniform_sampler
2140 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2141 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec2_hh %f32_0_5
2142 )";
2143 
2144   CompileSuccessfully(GenerateShaderCode(body).c_str());
2145   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2146   EXPECT_THAT(getDiagnosticString(),
2147               HasSubstr("Expected Coordinate to have at least 3 components, "
2148                         "but given only 2"));
2149 }
2150 
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongDrefType)2151 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongDrefType) {
2152   const std::string body = R"(
2153 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2154 %sampler = OpLoad %type_sampler %uniform_sampler
2155 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2156 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32vec4_0000
2157 )";
2158 
2159   CompileSuccessfully(GenerateShaderCode(body).c_str());
2160   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2161   EXPECT_THAT(getDiagnosticString(),
2162               HasSubstr("Expected Dref to be of 32-bit float type"));
2163 }
2164 
TEST_F(ValidateImage,SampleProjDrefExplicitLodSuccess)2165 TEST_F(ValidateImage, SampleProjDrefExplicitLodSuccess) {
2166   const std::string body = R"(
2167 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2168 %sampler = OpLoad %type_sampler %uniform_sampler
2169 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2170 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2171 %res2 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Grad %f32_0_5 %f32_0_5
2172 %res3 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 ConstOffset %s32_1
2173 %res4 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Offset %s32_1
2174 %res5 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Grad|Offset %f32_0_5 %f32_0_5 %s32_1
2175 %res6 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod|NonPrivateTexelKHR %f32_1
2176 )";
2177 
2178   const std::string extra = R"(
2179 OpCapability VulkanMemoryModelKHR
2180 OpExtension "SPV_KHR_vulkan_memory_model"
2181 )";
2182   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2183                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2184                           .c_str());
2185   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2186 }
2187 
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongResultType)2188 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongResultType) {
2189   const std::string body = R"(
2190 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2191 %sampler = OpLoad %type_sampler %uniform_sampler
2192 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2193 %res1 = OpImageSampleProjDrefExplicitLod %bool %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2194 )";
2195 
2196   CompileSuccessfully(GenerateShaderCode(body).c_str());
2197   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2198   EXPECT_THAT(getDiagnosticString(),
2199               HasSubstr("Expected Result Type to be int or float scalar type"));
2200 }
2201 
TEST_F(ValidateImage,SampleProjDrefExplicitLodNotSampledImage)2202 TEST_F(ValidateImage, SampleProjDrefExplicitLodNotSampledImage) {
2203   const std::string body = R"(
2204 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2205 %res1 = OpImageSampleProjDrefExplicitLod %f32 %img %f32vec2_hh %f32_0_5 Lod %f32_1
2206 )";
2207 
2208   CompileSuccessfully(GenerateShaderCode(body).c_str());
2209   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2210   EXPECT_THAT(
2211       getDiagnosticString(),
2212       HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2213 }
2214 
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongSampledType)2215 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongSampledType) {
2216   const std::string body = R"(
2217 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2218 %sampler = OpLoad %type_sampler %uniform_sampler
2219 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2220 %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2221 )";
2222 
2223   CompileSuccessfully(GenerateShaderCode(body).c_str());
2224   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2225   EXPECT_THAT(
2226       getDiagnosticString(),
2227       HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2228 }
2229 
TEST_F(ValidateImage,SampleProjDrefExplicitLodVoidSampledType)2230 TEST_F(ValidateImage, SampleProjDrefExplicitLodVoidSampledType) {
2231   const std::string body = R"(
2232 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2233 %sampler = OpLoad %type_sampler %uniform_sampler
2234 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2235 %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec3_hhh %f32_0_5 Lod %f32_1
2236 )";
2237 
2238   CompileSuccessfully(GenerateShaderCode(body).c_str());
2239   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2240   EXPECT_THAT(
2241       getDiagnosticString(),
2242       HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2243 }
2244 
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongCoordinateType)2245 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongCoordinateType) {
2246   const std::string body = R"(
2247 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2248 %sampler = OpLoad %type_sampler %uniform_sampler
2249 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2250 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %img %f32_0_5 Lod %f32_1
2251 )";
2252 
2253   CompileSuccessfully(GenerateShaderCode(body).c_str());
2254   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2255   EXPECT_THAT(getDiagnosticString(),
2256               HasSubstr("Expected Coordinate to be float scalar or vector"));
2257 }
2258 
TEST_F(ValidateImage,SampleProjDrefExplicitLodCoordinateSizeTooSmall)2259 TEST_F(ValidateImage, SampleProjDrefExplicitLodCoordinateSizeTooSmall) {
2260   const std::string body = R"(
2261 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2262 %sampler = OpLoad %type_sampler %uniform_sampler
2263 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2264 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32_0_5 %f32_0_5 Lod %f32_1
2265 )";
2266 
2267   CompileSuccessfully(GenerateShaderCode(body).c_str());
2268   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2269   EXPECT_THAT(getDiagnosticString(),
2270               HasSubstr("Expected Coordinate to have at least 2 components, "
2271                         "but given only 1"));
2272 }
2273 
TEST_F(ValidateImage,FetchSuccess)2274 TEST_F(ValidateImage, FetchSuccess) {
2275   const std::string body = R"(
2276 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2277 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
2278 %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
2279 )";
2280 
2281   const std::string extra = R"(
2282 OpCapability VulkanMemoryModelKHR
2283 OpExtension "SPV_KHR_vulkan_memory_model"
2284 )";
2285   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2286                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2287                           .c_str());
2288   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2289 }
2290 
TEST_F(ValidateImage,FetchWrongResultType)2291 TEST_F(ValidateImage, FetchWrongResultType) {
2292   const std::string body = R"(
2293 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2294 %res1 = OpImageFetch %f32 %img %u32vec2_01
2295 )";
2296 
2297   CompileSuccessfully(GenerateShaderCode(body).c_str());
2298   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2299   EXPECT_THAT(getDiagnosticString(),
2300               HasSubstr("Expected Result Type to be int or float vector type"));
2301 }
2302 
TEST_F(ValidateImage,FetchWrongNumComponentsResultType)2303 TEST_F(ValidateImage, FetchWrongNumComponentsResultType) {
2304   const std::string body = R"(
2305 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2306 %res1 = OpImageFetch %f32vec3 %img %u32vec2_01
2307 )";
2308 
2309   CompileSuccessfully(GenerateShaderCode(body).c_str());
2310   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2311   EXPECT_THAT(getDiagnosticString(),
2312               HasSubstr("Expected Result Type to have 4 components"));
2313 }
2314 
TEST_F(ValidateImage,FetchNotImage)2315 TEST_F(ValidateImage, FetchNotImage) {
2316   const std::string body = R"(
2317 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2318 %sampler = OpLoad %type_sampler %uniform_sampler
2319 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2320 %res1 = OpImageFetch %f32vec4 %sampler %u32vec2_01
2321 )";
2322 
2323   CompileSuccessfully(GenerateShaderCode(body).c_str());
2324   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2325   EXPECT_THAT(getDiagnosticString(),
2326               HasSubstr("Expected Image to be of type OpTypeImage"));
2327 }
2328 
TEST_F(ValidateImage,FetchSampledImageDirectly)2329 TEST_F(ValidateImage, FetchSampledImageDirectly) {
2330   const std::string body = R"(
2331 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2332 %sampler = OpLoad %type_sampler %uniform_sampler
2333 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2334 %res1 = OpImageFetch %f32vec4 %simg %u32vec2_01
2335 )";
2336 
2337   CompileSuccessfully(GenerateShaderCode(body).c_str());
2338   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
2339   EXPECT_THAT(getDiagnosticString(),
2340               HasSubstr("OpSampledImage instruction must not appear as operand "
2341                         "for OpImageFetch"));
2342 }
2343 
TEST_F(ValidateImage,FetchNotSampled)2344 TEST_F(ValidateImage, FetchNotSampled) {
2345   const std::string body = R"(
2346 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2347 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
2348 )";
2349 
2350   CompileSuccessfully(GenerateShaderCode(body).c_str());
2351   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2352   EXPECT_THAT(getDiagnosticString(),
2353               HasSubstr("Expected Image 'Sampled' parameter to be 1"));
2354 }
2355 
TEST_F(ValidateImage,FetchCube)2356 TEST_F(ValidateImage, FetchCube) {
2357   const std::string body = R"(
2358 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2359 %res1 = OpImageFetch %f32vec4 %img %u32vec3_012
2360 )";
2361 
2362   CompileSuccessfully(GenerateShaderCode(body).c_str());
2363   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2364   EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' cannot be Cube"));
2365 }
2366 
TEST_F(ValidateImage,FetchWrongSampledType)2367 TEST_F(ValidateImage, FetchWrongSampledType) {
2368   const std::string body = R"(
2369 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2370 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
2371 )";
2372 
2373   CompileSuccessfully(GenerateShaderCode(body).c_str());
2374   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2375   EXPECT_THAT(getDiagnosticString(),
2376               HasSubstr("Expected Image 'Sampled Type' to be the same as "
2377                         "Result Type components"));
2378 }
2379 
TEST_F(ValidateImage,FetchVoidSampledType)2380 TEST_F(ValidateImage, FetchVoidSampledType) {
2381   const std::string body = R"(
2382 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2383 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
2384 %res2 = OpImageFetch %u32vec4 %img %u32vec2_01
2385 %res3 = OpImageFetch %s32vec4 %img %u32vec2_01
2386 )";
2387 
2388   CompileSuccessfully(GenerateShaderCode(body).c_str());
2389   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2390 }
2391 
TEST_F(ValidateImage,FetchWrongCoordinateType)2392 TEST_F(ValidateImage, FetchWrongCoordinateType) {
2393   const std::string body = R"(
2394 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2395 %res1 = OpImageFetch %f32vec4 %img %f32vec2_00
2396 )";
2397 
2398   CompileSuccessfully(GenerateShaderCode(body).c_str());
2399   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2400   EXPECT_THAT(getDiagnosticString(),
2401               HasSubstr("Expected Coordinate to be int scalar or vector"));
2402 }
2403 
TEST_F(ValidateImage,FetchCoordinateSizeTooSmall)2404 TEST_F(ValidateImage, FetchCoordinateSizeTooSmall) {
2405   const std::string body = R"(
2406 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2407 %res1 = OpImageFetch %f32vec4 %img %u32_1
2408 )";
2409 
2410   CompileSuccessfully(GenerateShaderCode(body).c_str());
2411   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2412   EXPECT_THAT(getDiagnosticString(),
2413               HasSubstr("Expected Coordinate to have at least 2 components, "
2414                         "but given only 1"));
2415 }
2416 
TEST_F(ValidateImage,FetchLodNotInt)2417 TEST_F(ValidateImage, FetchLodNotInt) {
2418   const std::string body = R"(
2419 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2420 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Lod %f32_1
2421 )";
2422 
2423   CompileSuccessfully(GenerateShaderCode(body).c_str());
2424   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2425   EXPECT_THAT(getDiagnosticString(),
2426               HasSubstr("Expected Image Operand Lod to be int scalar when used "
2427                         "with OpImageFetch"));
2428 }
2429 
TEST_F(ValidateImage,GatherSuccess)2430 TEST_F(ValidateImage, GatherSuccess) {
2431   const std::string body = R"(
2432 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2433 %sampler = OpLoad %type_sampler %uniform_sampler
2434 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2435 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1
2436 %res2 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
2437 %res3 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
2438 )";
2439 
2440   const std::string extra = R"(
2441 OpCapability VulkanMemoryModelKHR
2442 OpExtension "SPV_KHR_vulkan_memory_model"
2443 )";
2444   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2445                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2446                           .c_str());
2447   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2448 }
2449 
TEST_F(ValidateImage,GatherWrongResultType)2450 TEST_F(ValidateImage, GatherWrongResultType) {
2451   const std::string body = R"(
2452 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2453 %sampler = OpLoad %type_sampler %uniform_sampler
2454 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2455 %res1 = OpImageGather %f32 %simg %f32vec4_0000 %u32_1
2456 )";
2457 
2458   CompileSuccessfully(GenerateShaderCode(body).c_str());
2459   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2460   EXPECT_THAT(getDiagnosticString(),
2461               HasSubstr("Expected Result Type to be int or float vector type"));
2462 }
2463 
TEST_F(ValidateImage,GatherWrongNumComponentsResultType)2464 TEST_F(ValidateImage, GatherWrongNumComponentsResultType) {
2465   const std::string body = R"(
2466 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2467 %sampler = OpLoad %type_sampler %uniform_sampler
2468 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2469 %res1 = OpImageGather %f32vec3 %simg %f32vec4_0000 %u32_1
2470 )";
2471 
2472   CompileSuccessfully(GenerateShaderCode(body).c_str());
2473   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2474   EXPECT_THAT(getDiagnosticString(),
2475               HasSubstr("Expected Result Type to have 4 components"));
2476 }
2477 
TEST_F(ValidateImage,GatherNotSampledImage)2478 TEST_F(ValidateImage, GatherNotSampledImage) {
2479   const std::string body = R"(
2480 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2481 %res1 = OpImageGather %f32vec4 %img %f32vec4_0000 %u32_1
2482 )";
2483 
2484   CompileSuccessfully(GenerateShaderCode(body).c_str());
2485   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2486   EXPECT_THAT(
2487       getDiagnosticString(),
2488       HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2489 }
2490 
TEST_F(ValidateImage,GatherWrongSampledType)2491 TEST_F(ValidateImage, GatherWrongSampledType) {
2492   const std::string body = R"(
2493 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2494 %sampler = OpLoad %type_sampler %uniform_sampler
2495 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2496 %res1 = OpImageGather %u32vec4 %simg %f32vec4_0000 %u32_1
2497 )";
2498 
2499   CompileSuccessfully(GenerateShaderCode(body).c_str());
2500   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2501   EXPECT_THAT(getDiagnosticString(),
2502               HasSubstr("Expected Image 'Sampled Type' to be the same as "
2503                         "Result Type components"));
2504 }
2505 
TEST_F(ValidateImage,GatherVoidSampledType)2506 TEST_F(ValidateImage, GatherVoidSampledType) {
2507   const std::string body = R"(
2508 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2509 %sampler = OpLoad %type_sampler %uniform_sampler
2510 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2511 %res1 = OpImageGather %u32vec4 %simg %f32vec2_00 %u32_1
2512 )";
2513 
2514   CompileSuccessfully(GenerateShaderCode(body).c_str());
2515   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2516 }
2517 
TEST_F(ValidateImage,GatherWrongCoordinateType)2518 TEST_F(ValidateImage, GatherWrongCoordinateType) {
2519   const std::string body = R"(
2520 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2521 %sampler = OpLoad %type_sampler %uniform_sampler
2522 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2523 %res1 = OpImageGather %f32vec4 %simg %u32vec4_0123 %u32_1
2524 )";
2525 
2526   CompileSuccessfully(GenerateShaderCode(body).c_str());
2527   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2528   EXPECT_THAT(getDiagnosticString(),
2529               HasSubstr("Expected Coordinate to be float scalar or vector"));
2530 }
2531 
TEST_F(ValidateImage,GatherCoordinateSizeTooSmall)2532 TEST_F(ValidateImage, GatherCoordinateSizeTooSmall) {
2533   const std::string body = R"(
2534 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2535 %sampler = OpLoad %type_sampler %uniform_sampler
2536 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2537 %res1 = OpImageGather %f32vec4 %simg %f32_0_5 %u32_1
2538 )";
2539 
2540   CompileSuccessfully(GenerateShaderCode(body).c_str());
2541   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2542   EXPECT_THAT(getDiagnosticString(),
2543               HasSubstr("Expected Coordinate to have at least 4 components, "
2544                         "but given only 1"));
2545 }
2546 
TEST_F(ValidateImage,GatherWrongComponentType)2547 TEST_F(ValidateImage, GatherWrongComponentType) {
2548   const std::string body = R"(
2549 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2550 %sampler = OpLoad %type_sampler %uniform_sampler
2551 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2552 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %f32_1
2553 )";
2554 
2555   CompileSuccessfully(GenerateShaderCode(body).c_str());
2556   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2557   EXPECT_THAT(getDiagnosticString(),
2558               HasSubstr("Expected Component to be 32-bit int scalar"));
2559 }
2560 
TEST_F(ValidateImage,GatherComponentNot32Bit)2561 TEST_F(ValidateImage, GatherComponentNot32Bit) {
2562   const std::string body = R"(
2563 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2564 %sampler = OpLoad %type_sampler %uniform_sampler
2565 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2566 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u64_0
2567 )";
2568 
2569   CompileSuccessfully(GenerateShaderCode(body).c_str());
2570   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2571   EXPECT_THAT(getDiagnosticString(),
2572               HasSubstr("Expected Component to be 32-bit int scalar"));
2573 }
2574 
TEST_F(ValidateImage,GatherDimCube)2575 TEST_F(ValidateImage, GatherDimCube) {
2576   const std::string body = R"(
2577 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2578 %sampler = OpLoad %type_sampler %uniform_sampler
2579 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2580 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
2581 )";
2582 
2583   CompileSuccessfully(GenerateShaderCode(body).c_str());
2584   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2585   EXPECT_THAT(
2586       getDiagnosticString(),
2587       HasSubstr(
2588           "Image Operand ConstOffsets cannot be used with Cube Image 'Dim'"));
2589 }
2590 
TEST_F(ValidateImage,GatherConstOffsetsNotArray)2591 TEST_F(ValidateImage, GatherConstOffsetsNotArray) {
2592   const std::string body = R"(
2593 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2594 %sampler = OpLoad %type_sampler %uniform_sampler
2595 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2596 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %u32vec4_0123
2597 )";
2598 
2599   CompileSuccessfully(GenerateShaderCode(body).c_str());
2600   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2601   EXPECT_THAT(
2602       getDiagnosticString(),
2603       HasSubstr(
2604           "Expected Image Operand ConstOffsets to be an array of size 4"));
2605 }
2606 
TEST_F(ValidateImage,GatherConstOffsetsArrayWrongSize)2607 TEST_F(ValidateImage, GatherConstOffsetsArrayWrongSize) {
2608   const std::string body = R"(
2609 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2610 %sampler = OpLoad %type_sampler %uniform_sampler
2611 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2612 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets3x2
2613 )";
2614 
2615   CompileSuccessfully(GenerateShaderCode(body).c_str());
2616   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2617   EXPECT_THAT(
2618       getDiagnosticString(),
2619       HasSubstr(
2620           "Expected Image Operand ConstOffsets to be an array of size 4"));
2621 }
2622 
TEST_F(ValidateImage,GatherConstOffsetsArrayNotVector)2623 TEST_F(ValidateImage, GatherConstOffsetsArrayNotVector) {
2624   const std::string body = R"(
2625 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2626 %sampler = OpLoad %type_sampler %uniform_sampler
2627 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2628 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4xu
2629 )";
2630 
2631   CompileSuccessfully(GenerateShaderCode(body).c_str());
2632   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2633   EXPECT_THAT(getDiagnosticString(),
2634               HasSubstr("Expected Image Operand ConstOffsets array componenets "
2635                         "to be int vectors of size 2"));
2636 }
2637 
TEST_F(ValidateImage,GatherConstOffsetsArrayVectorWrongSize)2638 TEST_F(ValidateImage, GatherConstOffsetsArrayVectorWrongSize) {
2639   const std::string body = R"(
2640 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2641 %sampler = OpLoad %type_sampler %uniform_sampler
2642 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2643 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4x3
2644 )";
2645 
2646   CompileSuccessfully(GenerateShaderCode(body).c_str());
2647   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2648   EXPECT_THAT(getDiagnosticString(),
2649               HasSubstr("Expected Image Operand ConstOffsets array componenets "
2650                         "to be int vectors of size 2"));
2651 }
2652 
TEST_F(ValidateImage,GatherConstOffsetsArrayNotConst)2653 TEST_F(ValidateImage, GatherConstOffsetsArrayNotConst) {
2654   const std::string body = R"(
2655 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2656 %sampler = OpLoad %type_sampler %uniform_sampler
2657 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2658 %offsets = OpUndef %u32vec2arr4
2659 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %offsets
2660 )";
2661 
2662   CompileSuccessfully(GenerateShaderCode(body).c_str());
2663   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2664   EXPECT_THAT(
2665       getDiagnosticString(),
2666       HasSubstr("Expected Image Operand ConstOffsets to be a const object"));
2667 }
2668 
TEST_F(ValidateImage,NotGatherWithConstOffsets)2669 TEST_F(ValidateImage, NotGatherWithConstOffsets) {
2670   const std::string body = R"(
2671 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2672 %sampler = OpLoad %type_sampler %uniform_sampler
2673 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2674 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffsets %const_offsets
2675 )";
2676 
2677   CompileSuccessfully(GenerateShaderCode(body).c_str());
2678   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2679   EXPECT_THAT(
2680       getDiagnosticString(),
2681       HasSubstr(
2682           "Image Operand ConstOffsets can only be used with OpImageGather "
2683           "and OpImageDrefGather"));
2684 }
2685 
TEST_F(ValidateImage,DrefGatherSuccess)2686 TEST_F(ValidateImage, DrefGatherSuccess) {
2687   const std::string body = R"(
2688 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2689 %sampler = OpLoad %type_sampler %uniform_sampler
2690 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2691 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
2692 %res2 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 ConstOffsets %const_offsets
2693 %res3 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 NonPrivateTexelKHR
2694 )";
2695 
2696   const std::string extra = R"(
2697 OpCapability VulkanMemoryModelKHR
2698 OpExtension "SPV_KHR_vulkan_memory_model"
2699 )";
2700   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2701                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2702                           .c_str());
2703   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2704 }
2705 
TEST_F(ValidateImage,DrefGatherVoidSampledType)2706 TEST_F(ValidateImage, DrefGatherVoidSampledType) {
2707   const std::string body = R"(
2708 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2709 %sampler = OpLoad %type_sampler %uniform_sampler
2710 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2711 %res1 = OpImageDrefGather %u32vec4 %simg %f32vec2_00 %f32_0_5
2712 )";
2713 
2714   CompileSuccessfully(GenerateShaderCode(body).c_str());
2715   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2716   EXPECT_THAT(getDiagnosticString(),
2717               HasSubstr("Expected Image 'Sampled Type' to be the same as "
2718                         "Result Type components"));
2719 }
2720 
TEST_F(ValidateImage,DrefGatherWrongDrefType)2721 TEST_F(ValidateImage, DrefGatherWrongDrefType) {
2722   const std::string body = R"(
2723 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2724 %sampler = OpLoad %type_sampler %uniform_sampler
2725 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2726 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %u32_1
2727 )";
2728 
2729   CompileSuccessfully(GenerateShaderCode(body).c_str());
2730   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2731   EXPECT_THAT(getDiagnosticString(),
2732               HasSubstr("Expected Dref to be of 32-bit float type"));
2733 }
2734 
TEST_F(ValidateImage,ReadSuccess1)2735 TEST_F(ValidateImage, ReadSuccess1) {
2736   const std::string body = R"(
2737 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2738 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
2739 )";
2740 
2741   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2742   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2743   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2744 }
2745 
TEST_F(ValidateImage,ReadSuccess2)2746 TEST_F(ValidateImage, ReadSuccess2) {
2747   const std::string body = R"(
2748 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
2749 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2750 )";
2751 
2752   const std::string extra = "\nOpCapability Image1D\n";
2753   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2754   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2755 }
2756 
TEST_F(ValidateImage,ReadSuccess3)2757 TEST_F(ValidateImage, ReadSuccess3) {
2758   const std::string body = R"(
2759 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
2760 %res1 = OpImageRead %f32vec4 %img %u32vec3_012
2761 )";
2762 
2763   const std::string extra = "\nOpCapability ImageCubeArray\n";
2764   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2765   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2766 }
2767 
TEST_F(ValidateImage,ReadSuccess4)2768 TEST_F(ValidateImage, ReadSuccess4) {
2769   const std::string body = R"(
2770 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
2771 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2772 )";
2773 
2774   CompileSuccessfully(GenerateShaderCode(body).c_str());
2775   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2776 }
2777 
TEST_F(ValidateImage,ReadNeedCapabilityStorageImageReadWithoutFormat)2778 TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) {
2779   const std::string body = R"(
2780 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2781 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
2782 )";
2783 
2784   CompileSuccessfully(GenerateShaderCode(body).c_str());
2785   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2786 }
2787 
TEST_F(ValidateImage,ReadNeedCapabilityStorageImageReadWithoutFormatVulkan)2788 TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) {
2789   const std::string body = R"(
2790 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2791 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
2792 )";
2793 
2794   spv_target_env env = SPV_ENV_VULKAN_1_0;
2795   CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
2796                       env);
2797   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
2798   EXPECT_THAT(getDiagnosticString(),
2799               HasSubstr("Capability StorageImageReadWithoutFormat is required "
2800                         "to read storage image"));
2801 }
2802 
TEST_F(ValidateImage,ReadNeedCapabilityImage1D)2803 TEST_F(ValidateImage, ReadNeedCapabilityImage1D) {
2804   const std::string body = R"(
2805 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
2806 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2807 )";
2808 
2809   CompileSuccessfully(GenerateShaderCode(body).c_str());
2810   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2811   EXPECT_THAT(
2812       getDiagnosticString(),
2813       HasSubstr("Capability Image1D is required to access storage image"));
2814 }
2815 
TEST_F(ValidateImage,ReadNeedCapabilityImageCubeArray)2816 TEST_F(ValidateImage, ReadNeedCapabilityImageCubeArray) {
2817   const std::string body = R"(
2818 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
2819 %res1 = OpImageRead %f32vec4 %img %u32vec3_012
2820 )";
2821 
2822   CompileSuccessfully(GenerateShaderCode(body).c_str());
2823   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2824   EXPECT_THAT(
2825       getDiagnosticString(),
2826       HasSubstr(
2827           "Capability ImageCubeArray is required to access storage image"));
2828 }
2829 
2830 // TODO(atgoo@github.com) Disabled until the spec is clarified.
TEST_F(ValidateImage,DISABLED_ReadWrongResultType)2831 TEST_F(ValidateImage, DISABLED_ReadWrongResultType) {
2832   const std::string body = R"(
2833 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2834 %res1 = OpImageRead %f32 %img %u32vec2_01
2835 )";
2836 
2837   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2838   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2839   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2840   EXPECT_THAT(getDiagnosticString(),
2841               HasSubstr("Expected Result Type to be int or float vector type"));
2842 }
2843 
2844 // TODO(atgoo@github.com) Disabled until the spec is clarified.
TEST_F(ValidateImage,DISABLED_ReadWrongNumComponentsResultType)2845 TEST_F(ValidateImage, DISABLED_ReadWrongNumComponentsResultType) {
2846   const std::string body = R"(
2847 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2848 %res1 = OpImageRead %f32vec3 %img %u32vec2_01
2849 )";
2850 
2851   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2852   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2853   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2854   EXPECT_THAT(getDiagnosticString(),
2855               HasSubstr("Expected Result Type to have 4 components"));
2856 }
2857 
TEST_F(ValidateImage,ReadNotImage)2858 TEST_F(ValidateImage, ReadNotImage) {
2859   const std::string body = R"(
2860 %sampler = OpLoad %type_sampler %uniform_sampler
2861 %res1 = OpImageRead %f32vec4 %sampler %u32vec2_01
2862 )";
2863 
2864   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2865   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2866   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2867   EXPECT_THAT(getDiagnosticString(),
2868               HasSubstr("Expected Image to be of type OpTypeImage"));
2869 }
2870 
TEST_F(ValidateImage,ReadImageSampled)2871 TEST_F(ValidateImage, ReadImageSampled) {
2872   const std::string body = R"(
2873 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2874 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2875 )";
2876 
2877   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2878   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2879   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2880   EXPECT_THAT(getDiagnosticString(),
2881               HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
2882 }
2883 
TEST_F(ValidateImage,ReadWrongSampledType)2884 TEST_F(ValidateImage, ReadWrongSampledType) {
2885   const std::string body = R"(
2886 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2887 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2888 )";
2889 
2890   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2891   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2892   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2893   EXPECT_THAT(getDiagnosticString(),
2894               HasSubstr("Expected Image 'Sampled Type' to be the same as "
2895                         "Result Type components"));
2896 }
2897 
TEST_F(ValidateImage,ReadVoidSampledType)2898 TEST_F(ValidateImage, ReadVoidSampledType) {
2899   const std::string body = R"(
2900 %img = OpLoad %type_image_void_2d_0002 %uniform_image_void_2d_0002
2901 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2902 %res2 = OpImageRead %u32vec4 %img %u32vec2_01
2903 %res3 = OpImageRead %s32vec4 %img %u32vec2_01
2904 )";
2905 
2906   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2907   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2908   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2909 }
2910 
TEST_F(ValidateImage,ReadWrongCoordinateType)2911 TEST_F(ValidateImage, ReadWrongCoordinateType) {
2912   const std::string body = R"(
2913 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2914 %res1 = OpImageRead %u32vec4 %img %f32vec2_00
2915 )";
2916 
2917   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2918   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2919   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2920   EXPECT_THAT(getDiagnosticString(),
2921               HasSubstr("Expected Coordinate to be int scalar or vector"));
2922 }
2923 
TEST_F(ValidateImage,ReadCoordinateSizeTooSmall)2924 TEST_F(ValidateImage, ReadCoordinateSizeTooSmall) {
2925   const std::string body = R"(
2926 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2927 %res1 = OpImageRead %u32vec4 %img %u32_1
2928 )";
2929 
2930   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2931   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2932   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2933   EXPECT_THAT(getDiagnosticString(),
2934               HasSubstr("Expected Coordinate to have at least 2 components, "
2935                         "but given only 1"));
2936 }
2937 
TEST_F(ValidateImage,WriteSuccess1)2938 TEST_F(ValidateImage, WriteSuccess1) {
2939   const std::string body = R"(
2940 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2941 OpImageWrite %img %u32vec2_01 %u32vec4_0123
2942 )";
2943 
2944   const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
2945   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2946   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2947 }
2948 
TEST_F(ValidateImage,WriteSuccess2)2949 TEST_F(ValidateImage, WriteSuccess2) {
2950   const std::string body = R"(
2951 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
2952 OpImageWrite %img %u32_1 %f32vec4_0000
2953 )";
2954 
2955   const std::string extra = "\nOpCapability Image1D\n";
2956   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2957   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2958 }
2959 
TEST_F(ValidateImage,WriteSuccess3)2960 TEST_F(ValidateImage, WriteSuccess3) {
2961   const std::string body = R"(
2962 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
2963 OpImageWrite %img %u32vec3_012 %f32vec4_0000
2964 )";
2965 
2966   const std::string extra = "\nOpCapability ImageCubeArray\n";
2967   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2968   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2969 }
2970 
TEST_F(ValidateImage,WriteSuccess4)2971 TEST_F(ValidateImage, WriteSuccess4) {
2972   const std::string body = R"(
2973 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
2974 ;TODO(atgoo@github.com) Is it legal to write to MS image without sample index?
2975 OpImageWrite %img %u32vec2_01 %f32vec4_0000
2976 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
2977 )";
2978 
2979   const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
2980   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2981   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2982 }
2983 
TEST_F(ValidateImage,WriteSubpassData)2984 TEST_F(ValidateImage, WriteSubpassData) {
2985   const std::string body = R"(
2986 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
2987 OpImageWrite %img %u32vec2_01 %f32vec4_0000
2988 )";
2989 
2990   CompileSuccessfully(GenerateShaderCode(body).c_str());
2991   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2992   EXPECT_THAT(getDiagnosticString(),
2993               HasSubstr("Image 'Dim' cannot be SubpassData"));
2994 }
2995 
TEST_F(ValidateImage,WriteNeedCapabilityStorageImageWriteWithoutFormat)2996 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
2997   const std::string body = R"(
2998 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2999 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3000 )";
3001 
3002   CompileSuccessfully(GenerateShaderCode(body).c_str());
3003   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3004 }
3005 
TEST_F(ValidateImage,WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan)3006 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
3007   const std::string body = R"(
3008 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3009 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3010 )";
3011 
3012   spv_target_env env = SPV_ENV_VULKAN_1_0;
3013   CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3014                       env);
3015   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3016   EXPECT_THAT(
3017       getDiagnosticString(),
3018       HasSubstr(
3019           "Capability StorageImageWriteWithoutFormat is required to write to "
3020           "storage image"));
3021 }
3022 
TEST_F(ValidateImage,WriteNeedCapabilityImage1D)3023 TEST_F(ValidateImage, WriteNeedCapabilityImage1D) {
3024   const std::string body = R"(
3025 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3026 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3027 )";
3028 
3029   CompileSuccessfully(GenerateShaderCode(body).c_str());
3030   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3031   EXPECT_THAT(getDiagnosticString(),
3032               HasSubstr("Capability Image1D is required to access storage "
3033                         "image"));
3034 }
3035 
TEST_F(ValidateImage,WriteNeedCapabilityImageCubeArray)3036 TEST_F(ValidateImage, WriteNeedCapabilityImageCubeArray) {
3037   const std::string body = R"(
3038 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3039 OpImageWrite %img %u32vec3_012 %f32vec4_0000
3040 )";
3041 
3042   CompileSuccessfully(GenerateShaderCode(body).c_str());
3043   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3044   EXPECT_THAT(
3045       getDiagnosticString(),
3046       HasSubstr(
3047           "Capability ImageCubeArray is required to access storage image"));
3048 }
3049 
TEST_F(ValidateImage,WriteNotImage)3050 TEST_F(ValidateImage, WriteNotImage) {
3051   const std::string body = R"(
3052 %sampler = OpLoad %type_sampler %uniform_sampler
3053 OpImageWrite %sampler %u32vec2_01 %f32vec4_0000
3054 )";
3055 
3056   CompileSuccessfully(GenerateShaderCode(body).c_str());
3057   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3058   EXPECT_THAT(getDiagnosticString(),
3059               HasSubstr("Expected Image to be of type OpTypeImage"));
3060 }
3061 
TEST_F(ValidateImage,WriteImageSampled)3062 TEST_F(ValidateImage, WriteImageSampled) {
3063   const std::string body = R"(
3064 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3065 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3066 )";
3067 
3068   const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3069   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3070   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3071   EXPECT_THAT(getDiagnosticString(),
3072               HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
3073 }
3074 
TEST_F(ValidateImage,WriteWrongCoordinateType)3075 TEST_F(ValidateImage, WriteWrongCoordinateType) {
3076   const std::string body = R"(
3077 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3078 OpImageWrite %img %f32vec2_00 %u32vec4_0123
3079 )";
3080 
3081   const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3082   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3083   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3084   EXPECT_THAT(getDiagnosticString(),
3085               HasSubstr("Expected Coordinate to be int scalar or vector"));
3086 }
3087 
TEST_F(ValidateImage,WriteCoordinateSizeTooSmall)3088 TEST_F(ValidateImage, WriteCoordinateSizeTooSmall) {
3089   const std::string body = R"(
3090 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3091 OpImageWrite %img %u32_1 %u32vec4_0123
3092 )";
3093 
3094   const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3095   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3096   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3097   EXPECT_THAT(getDiagnosticString(),
3098               HasSubstr("Expected Coordinate to have at least 2 components, "
3099                         "but given only 1"));
3100 }
3101 
TEST_F(ValidateImage,WriteTexelWrongType)3102 TEST_F(ValidateImage, WriteTexelWrongType) {
3103   const std::string body = R"(
3104 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3105 OpImageWrite %img %u32vec2_01 %img
3106 )";
3107 
3108   const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3109   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3110   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3111   EXPECT_THAT(getDiagnosticString(),
3112               HasSubstr("Expected Texel to be int or float vector or scalar"));
3113 }
3114 
TEST_F(ValidateImage,DISABLED_WriteTexelNotVector4)3115 TEST_F(ValidateImage, DISABLED_WriteTexelNotVector4) {
3116   const std::string body = R"(
3117 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3118 OpImageWrite %img %u32vec2_01 %u32vec3_012
3119 )";
3120 
3121   const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3122   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3123   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3124   EXPECT_THAT(getDiagnosticString(),
3125               HasSubstr("Expected Texel to have 4 components"));
3126 }
3127 
TEST_F(ValidateImage,WriteTexelWrongComponentType)3128 TEST_F(ValidateImage, WriteTexelWrongComponentType) {
3129   const std::string body = R"(
3130 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3131 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3132 )";
3133 
3134   const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3135   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3136   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3137   EXPECT_THAT(
3138       getDiagnosticString(),
3139       HasSubstr(
3140           "Expected Image 'Sampled Type' to be the same as Texel components"));
3141 }
3142 
TEST_F(ValidateImage,WriteSampleNotInteger)3143 TEST_F(ValidateImage, WriteSampleNotInteger) {
3144   const std::string body = R"(
3145 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3146 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1
3147 )";
3148 
3149   const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3150   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3151   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3152   EXPECT_THAT(getDiagnosticString(),
3153               HasSubstr("Expected Image Operand Sample to be int scalar"));
3154 }
3155 
TEST_F(ValidateImage,SampleNotMultisampled)3156 TEST_F(ValidateImage, SampleNotMultisampled) {
3157   const std::string body = R"(
3158 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
3159 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
3160 )";
3161 
3162   const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3163   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3164   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3165   EXPECT_THAT(
3166       getDiagnosticString(),
3167       HasSubstr("Image Operand Sample requires non-zero 'MS' parameter"));
3168 }
3169 
TEST_F(ValidateImage,SampleWrongOpcode)3170 TEST_F(ValidateImage, SampleWrongOpcode) {
3171   const std::string body = R"(
3172 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3173 %sampler = OpLoad %type_sampler %uniform_sampler
3174 %simg = OpSampledImage %type_sampled_image_f32_2d_0010 %img %sampler
3175 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Sample %u32_1
3176 )";
3177 
3178   CompileSuccessfully(GenerateShaderCode(body).c_str());
3179   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3180   EXPECT_THAT(getDiagnosticString(),
3181               HasSubstr("Image Operand Sample can only be used with "
3182                         "OpImageFetch, OpImageRead, OpImageWrite, "
3183                         "OpImageSparseFetch and OpImageSparseRead"));
3184 }
3185 
TEST_F(ValidateImage,SampleImageToImageSuccess)3186 TEST_F(ValidateImage, SampleImageToImageSuccess) {
3187   const std::string body = R"(
3188 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3189 %sampler = OpLoad %type_sampler %uniform_sampler
3190 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3191 %img2 = OpImage %type_image_f32_2d_0001 %simg
3192 )";
3193 
3194   CompileSuccessfully(GenerateShaderCode(body).c_str());
3195   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3196 }
3197 
TEST_F(ValidateImage,SampleImageToImageWrongResultType)3198 TEST_F(ValidateImage, SampleImageToImageWrongResultType) {
3199   const std::string body = R"(
3200 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3201 %sampler = OpLoad %type_sampler %uniform_sampler
3202 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3203 %img2 = OpImage %type_sampled_image_f32_2d_0001 %simg
3204 )";
3205 
3206   CompileSuccessfully(GenerateShaderCode(body).c_str());
3207   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3208   EXPECT_THAT(getDiagnosticString(),
3209               HasSubstr("Expected Result Type to be OpTypeImage"));
3210 }
3211 
TEST_F(ValidateImage,SampleImageToImageNotSampledImage)3212 TEST_F(ValidateImage, SampleImageToImageNotSampledImage) {
3213   const std::string body = R"(
3214 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3215 %img2 = OpImage %type_image_f32_2d_0001 %img
3216 )";
3217 
3218   CompileSuccessfully(GenerateShaderCode(body).c_str());
3219   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3220   EXPECT_THAT(
3221       getDiagnosticString(),
3222       HasSubstr("Expected Sample Image to be of type OpTypeSampleImage"));
3223 }
3224 
TEST_F(ValidateImage,SampleImageToImageNotTheSameImageType)3225 TEST_F(ValidateImage, SampleImageToImageNotTheSameImageType) {
3226   const std::string body = R"(
3227 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3228 %sampler = OpLoad %type_sampler %uniform_sampler
3229 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3230 %img2 = OpImage %type_image_f32_2d_0002 %simg
3231 )";
3232 
3233   CompileSuccessfully(GenerateShaderCode(body).c_str());
3234   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3235   EXPECT_THAT(getDiagnosticString(),
3236               HasSubstr("Expected Sample Image image type to be equal to "
3237                         "Result Type"));
3238 }
3239 
TEST_F(ValidateImage,QueryFormatSuccess)3240 TEST_F(ValidateImage, QueryFormatSuccess) {
3241   const std::string body = R"(
3242 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3243 %res1 = OpImageQueryFormat %u32 %img
3244 )";
3245 
3246   CompileSuccessfully(GenerateKernelCode(body).c_str());
3247   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3248 }
3249 
TEST_F(ValidateImage,QueryFormatWrongResultType)3250 TEST_F(ValidateImage, QueryFormatWrongResultType) {
3251   const std::string body = R"(
3252 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3253 %res1 = OpImageQueryFormat %bool %img
3254 )";
3255 
3256   CompileSuccessfully(GenerateKernelCode(body).c_str());
3257   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3258   EXPECT_THAT(getDiagnosticString(),
3259               HasSubstr("Expected Result Type to be int scalar type"));
3260 }
3261 
TEST_F(ValidateImage,QueryFormatNotImage)3262 TEST_F(ValidateImage, QueryFormatNotImage) {
3263   const std::string body = R"(
3264 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3265 %sampler = OpLoad %type_sampler %uniform_sampler
3266 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3267 %res1 = OpImageQueryFormat %u32 %sampler
3268 )";
3269 
3270   CompileSuccessfully(GenerateKernelCode(body).c_str());
3271   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3272   EXPECT_THAT(getDiagnosticString(),
3273               HasSubstr("Expected operand to be of type OpTypeImage"));
3274 }
3275 
TEST_F(ValidateImage,QueryOrderSuccess)3276 TEST_F(ValidateImage, QueryOrderSuccess) {
3277   const std::string body = R"(
3278 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3279 %res1 = OpImageQueryOrder %u32 %img
3280 )";
3281 
3282   CompileSuccessfully(GenerateKernelCode(body).c_str());
3283   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3284 }
3285 
TEST_F(ValidateImage,QueryOrderWrongResultType)3286 TEST_F(ValidateImage, QueryOrderWrongResultType) {
3287   const std::string body = R"(
3288 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3289 %res1 = OpImageQueryOrder %bool %img
3290 )";
3291 
3292   CompileSuccessfully(GenerateKernelCode(body).c_str());
3293   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3294   EXPECT_THAT(getDiagnosticString(),
3295               HasSubstr("Expected Result Type to be int scalar type"));
3296 }
3297 
TEST_F(ValidateImage,QueryOrderNotImage)3298 TEST_F(ValidateImage, QueryOrderNotImage) {
3299   const std::string body = R"(
3300 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3301 %sampler = OpLoad %type_sampler %uniform_sampler
3302 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3303 %res1 = OpImageQueryOrder %u32 %sampler
3304 )";
3305 
3306   CompileSuccessfully(GenerateKernelCode(body).c_str());
3307   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3308   EXPECT_THAT(getDiagnosticString(),
3309               HasSubstr("Expected operand to be of type OpTypeImage"));
3310 }
3311 
TEST_F(ValidateImage,QuerySizeLodSuccess)3312 TEST_F(ValidateImage, QuerySizeLodSuccess) {
3313   const std::string body = R"(
3314 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3315 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
3316 )";
3317 
3318   CompileSuccessfully(GenerateKernelCode(body).c_str());
3319   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3320 }
3321 
TEST_F(ValidateImage,QuerySizeLodWrongResultType)3322 TEST_F(ValidateImage, QuerySizeLodWrongResultType) {
3323   const std::string body = R"(
3324 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3325 %res1 = OpImageQuerySizeLod %f32vec2 %img %u32_1
3326 )";
3327 
3328   CompileSuccessfully(GenerateKernelCode(body).c_str());
3329   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3330   EXPECT_THAT(
3331       getDiagnosticString(),
3332       HasSubstr("Expected Result Type to be int scalar or vector type"));
3333 }
3334 
TEST_F(ValidateImage,QuerySizeLodResultTypeWrongSize)3335 TEST_F(ValidateImage, QuerySizeLodResultTypeWrongSize) {
3336   const std::string body = R"(
3337 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3338 %res1 = OpImageQuerySizeLod %u32 %img %u32_1
3339 )";
3340 
3341   CompileSuccessfully(GenerateKernelCode(body).c_str());
3342   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3343   EXPECT_THAT(getDiagnosticString(),
3344               HasSubstr("Result Type has 1 components, but 2 expected"));
3345 }
3346 
TEST_F(ValidateImage,QuerySizeLodNotImage)3347 TEST_F(ValidateImage, QuerySizeLodNotImage) {
3348   const std::string body = R"(
3349 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3350 %sampler = OpLoad %type_sampler %uniform_sampler
3351 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3352 %res1 = OpImageQuerySizeLod %u32vec2 %sampler %u32_1
3353 )";
3354 
3355   CompileSuccessfully(GenerateKernelCode(body).c_str());
3356   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3357   EXPECT_THAT(getDiagnosticString(),
3358               HasSubstr("Expected Image to be of type OpTypeImage"));
3359 }
3360 
TEST_F(ValidateImage,QuerySizeLodSampledImageDirectly)3361 TEST_F(ValidateImage, QuerySizeLodSampledImageDirectly) {
3362   const std::string body = R"(
3363 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3364 %sampler = OpLoad %type_sampler %uniform_sampler
3365 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3366 %res1 = OpImageQuerySizeLod %u32vec2 %simg %u32_1
3367 )";
3368 
3369   CompileSuccessfully(GenerateShaderCode(body).c_str());
3370   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3371   EXPECT_THAT(getDiagnosticString(),
3372               HasSubstr("OpSampledImage instruction must not appear as operand "
3373                         "for OpImageQuerySizeLod"));
3374 }
3375 
TEST_F(ValidateImage,QuerySizeLodWrongImageDim)3376 TEST_F(ValidateImage, QuerySizeLodWrongImageDim) {
3377   const std::string body = R"(
3378 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3379 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
3380 )";
3381 
3382   CompileSuccessfully(GenerateKernelCode(body).c_str());
3383   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3384   EXPECT_THAT(getDiagnosticString(),
3385               HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
3386 }
3387 
TEST_F(ValidateImage,QuerySizeLodMultisampled)3388 TEST_F(ValidateImage, QuerySizeLodMultisampled) {
3389   const std::string body = R"(
3390 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3391 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
3392 )";
3393 
3394   CompileSuccessfully(GenerateKernelCode(body).c_str());
3395   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3396   EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 0"));
3397 }
3398 
TEST_F(ValidateImage,QuerySizeLodWrongLodType)3399 TEST_F(ValidateImage, QuerySizeLodWrongLodType) {
3400   const std::string body = R"(
3401 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3402 %res1 = OpImageQuerySizeLod %u32vec2 %img %f32_0
3403 )";
3404 
3405   CompileSuccessfully(GenerateKernelCode(body).c_str());
3406   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3407   EXPECT_THAT(getDiagnosticString(),
3408               HasSubstr("Expected Level of Detail to be int scalar"));
3409 }
3410 
TEST_F(ValidateImage,QuerySizeSuccess)3411 TEST_F(ValidateImage, QuerySizeSuccess) {
3412   const std::string body = R"(
3413 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3414 %res1 = OpImageQuerySize %u32vec2 %img
3415 )";
3416 
3417   CompileSuccessfully(GenerateKernelCode(body).c_str());
3418   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3419 }
3420 
TEST_F(ValidateImage,QuerySizeWrongResultType)3421 TEST_F(ValidateImage, QuerySizeWrongResultType) {
3422   const std::string body = R"(
3423 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3424 %res1 = OpImageQuerySize %f32vec2 %img
3425 )";
3426 
3427   CompileSuccessfully(GenerateKernelCode(body).c_str());
3428   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3429   EXPECT_THAT(
3430       getDiagnosticString(),
3431       HasSubstr("Expected Result Type to be int scalar or vector type"));
3432 }
3433 
TEST_F(ValidateImage,QuerySizeNotImage)3434 TEST_F(ValidateImage, QuerySizeNotImage) {
3435   const std::string body = R"(
3436 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3437 %sampler = OpLoad %type_sampler %uniform_sampler
3438 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3439 %res1 = OpImageQuerySize %u32vec2 %sampler
3440 )";
3441 
3442   CompileSuccessfully(GenerateKernelCode(body).c_str());
3443   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3444   EXPECT_THAT(getDiagnosticString(),
3445               HasSubstr("Expected Image to be of type OpTypeImage"));
3446 }
3447 
TEST_F(ValidateImage,QuerySizeSampledImageDirectly)3448 TEST_F(ValidateImage, QuerySizeSampledImageDirectly) {
3449   const std::string body = R"(
3450 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3451 %sampler = OpLoad %type_sampler %uniform_sampler
3452 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3453 %res1 = OpImageQuerySize %u32vec2 %simg
3454 )";
3455 
3456   CompileSuccessfully(GenerateShaderCode(body).c_str());
3457   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3458   EXPECT_THAT(getDiagnosticString(),
3459               HasSubstr("OpSampledImage instruction must not appear as operand "
3460                         "for OpImageQuerySize"));
3461 }
3462 
TEST_F(ValidateImage,QuerySizeDimSubpassDataBad)3463 TEST_F(ValidateImage, QuerySizeDimSubpassDataBad) {
3464   const std::string body = R"(
3465 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3466 %res1 = OpImageQuerySize %u32vec2 %img
3467 )";
3468 
3469   CompileSuccessfully(GenerateShaderCode(body).c_str());
3470   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3471   EXPECT_THAT(
3472       getDiagnosticString(),
3473       HasSubstr("Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"));
3474 }
3475 
TEST_F(ValidateImage,QuerySizeWrongSampling)3476 TEST_F(ValidateImage, QuerySizeWrongSampling) {
3477   const std::string body = R"(
3478 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3479 %res1 = OpImageQuerySize %u32vec2 %img
3480 )";
3481 
3482   CompileSuccessfully(GenerateKernelCode(body).c_str());
3483   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3484   EXPECT_THAT(
3485       getDiagnosticString(),
3486       HasSubstr("Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"));
3487 }
3488 
TEST_F(ValidateImage,QuerySizeWrongNumberOfComponents)3489 TEST_F(ValidateImage, QuerySizeWrongNumberOfComponents) {
3490   const std::string body = R"(
3491 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
3492 %res1 = OpImageQuerySize %u32vec2 %img
3493 )";
3494 
3495   CompileSuccessfully(GenerateShaderCode(body).c_str());
3496   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3497   EXPECT_THAT(getDiagnosticString(),
3498               HasSubstr("Result Type has 2 components, but 4 expected"));
3499 }
3500 
TEST_F(ValidateImage,QueryLodSuccessKernel)3501 TEST_F(ValidateImage, QueryLodSuccessKernel) {
3502   const std::string body = R"(
3503 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3504 %sampler = OpLoad %type_sampler %uniform_sampler
3505 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3506 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3507 %res2 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
3508 )";
3509 
3510   CompileSuccessfully(GenerateKernelCode(body).c_str());
3511   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3512 }
3513 
TEST_F(ValidateImage,QueryLodSuccessShader)3514 TEST_F(ValidateImage, QueryLodSuccessShader) {
3515   const std::string body = R"(
3516 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3517 %sampler = OpLoad %type_sampler %uniform_sampler
3518 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3519 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3520 )";
3521 
3522   CompileSuccessfully(GenerateShaderCode(body).c_str());
3523   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3524 }
3525 
TEST_F(ValidateImage,QueryLodWrongResultType)3526 TEST_F(ValidateImage, QueryLodWrongResultType) {
3527   const std::string body = R"(
3528 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3529 %sampler = OpLoad %type_sampler %uniform_sampler
3530 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3531 %res1 = OpImageQueryLod %u32vec2 %simg %f32vec2_hh
3532 )";
3533 
3534   CompileSuccessfully(GenerateKernelCode(body).c_str());
3535   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3536   EXPECT_THAT(getDiagnosticString(),
3537               HasSubstr("Expected Result Type to be float vector type"));
3538 }
3539 
TEST_F(ValidateImage,QueryLodResultTypeWrongSize)3540 TEST_F(ValidateImage, QueryLodResultTypeWrongSize) {
3541   const std::string body = R"(
3542 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3543 %sampler = OpLoad %type_sampler %uniform_sampler
3544 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3545 %res1 = OpImageQueryLod %f32vec3 %simg %f32vec2_hh
3546 )";
3547 
3548   CompileSuccessfully(GenerateKernelCode(body).c_str());
3549   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3550   EXPECT_THAT(getDiagnosticString(),
3551               HasSubstr("Expected Result Type to have 2 components"));
3552 }
3553 
TEST_F(ValidateImage,QueryLodNotSampledImage)3554 TEST_F(ValidateImage, QueryLodNotSampledImage) {
3555   const std::string body = R"(
3556 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3557 %res1 = OpImageQueryLod %f32vec2 %img %f32vec2_hh
3558 )";
3559 
3560   CompileSuccessfully(GenerateKernelCode(body).c_str());
3561   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3562   EXPECT_THAT(
3563       getDiagnosticString(),
3564       HasSubstr("Expected Image operand to be of type OpTypeSampledImage"));
3565 }
3566 
TEST_F(ValidateImage,QueryLodWrongDim)3567 TEST_F(ValidateImage, QueryLodWrongDim) {
3568   const std::string body = R"(
3569 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3570 %sampler = OpLoad %type_sampler %uniform_sampler
3571 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
3572 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3573 )";
3574 
3575   CompileSuccessfully(GenerateKernelCode(body).c_str());
3576   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3577   EXPECT_THAT(getDiagnosticString(),
3578               HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
3579 }
3580 
TEST_F(ValidateImage,QueryLodWrongCoordinateType)3581 TEST_F(ValidateImage, QueryLodWrongCoordinateType) {
3582   const std::string body = R"(
3583 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3584 %sampler = OpLoad %type_sampler %uniform_sampler
3585 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3586 %res1 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
3587 )";
3588 
3589   CompileSuccessfully(GenerateShaderCode(body).c_str());
3590   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3591   EXPECT_THAT(getDiagnosticString(),
3592               HasSubstr("Expected Coordinate to be float scalar or vector"));
3593 }
3594 
TEST_F(ValidateImage,QueryLodCoordinateSizeTooSmall)3595 TEST_F(ValidateImage, QueryLodCoordinateSizeTooSmall) {
3596   const std::string body = R"(
3597 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3598 %sampler = OpLoad %type_sampler %uniform_sampler
3599 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3600 %res1 = OpImageQueryLod %f32vec2 %simg %f32_0
3601 )";
3602 
3603   CompileSuccessfully(GenerateShaderCode(body).c_str());
3604   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3605   EXPECT_THAT(getDiagnosticString(),
3606               HasSubstr("Expected Coordinate to have at least 2 components, "
3607                         "but given only 1"));
3608 }
3609 
TEST_F(ValidateImage,QueryLevelsSuccess)3610 TEST_F(ValidateImage, QueryLevelsSuccess) {
3611   const std::string body = R"(
3612 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3613 %res1 = OpImageQueryLevels %u32 %img
3614 )";
3615 
3616   CompileSuccessfully(GenerateKernelCode(body).c_str());
3617   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3618 }
3619 
TEST_F(ValidateImage,QueryLevelsWrongResultType)3620 TEST_F(ValidateImage, QueryLevelsWrongResultType) {
3621   const std::string body = R"(
3622 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3623 %res1 = OpImageQueryLevels %f32 %img
3624 )";
3625 
3626   CompileSuccessfully(GenerateKernelCode(body).c_str());
3627   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3628   EXPECT_THAT(getDiagnosticString(),
3629               HasSubstr("Expected Result Type to be int scalar type"));
3630 }
3631 
TEST_F(ValidateImage,QueryLevelsNotImage)3632 TEST_F(ValidateImage, QueryLevelsNotImage) {
3633   const std::string body = R"(
3634 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3635 %sampler = OpLoad %type_sampler %uniform_sampler
3636 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3637 %res1 = OpImageQueryLevels %u32 %sampler
3638 )";
3639 
3640   CompileSuccessfully(GenerateKernelCode(body).c_str());
3641   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3642   EXPECT_THAT(getDiagnosticString(),
3643               HasSubstr("Expected Image to be of type OpTypeImage"));
3644 }
3645 
TEST_F(ValidateImage,QueryLevelsSampledImageDirectly)3646 TEST_F(ValidateImage, QueryLevelsSampledImageDirectly) {
3647   const std::string body = R"(
3648 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3649 %sampler = OpLoad %type_sampler %uniform_sampler
3650 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3651 %res1 = OpImageQueryLevels %u32 %simg
3652 )";
3653 
3654   CompileSuccessfully(GenerateShaderCode(body).c_str());
3655   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3656   EXPECT_THAT(getDiagnosticString(),
3657               HasSubstr("OpSampledImage instruction must not appear as operand "
3658                         "for OpImageQueryLevels"));
3659 }
3660 
TEST_F(ValidateImage,QueryLevelsWrongDim)3661 TEST_F(ValidateImage, QueryLevelsWrongDim) {
3662   const std::string body = R"(
3663 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3664 %res1 = OpImageQueryLevels %u32 %img
3665 )";
3666 
3667   CompileSuccessfully(GenerateKernelCode(body).c_str());
3668   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3669   EXPECT_THAT(getDiagnosticString(),
3670               HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
3671 }
3672 
TEST_F(ValidateImage,QuerySamplesSuccess)3673 TEST_F(ValidateImage, QuerySamplesSuccess) {
3674   const std::string body = R"(
3675 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3676 %res1 = OpImageQuerySamples %u32 %img
3677 )";
3678 
3679   CompileSuccessfully(GenerateKernelCode(body).c_str());
3680   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3681 }
3682 
TEST_F(ValidateImage,QuerySamplesNot2D)3683 TEST_F(ValidateImage, QuerySamplesNot2D) {
3684   const std::string body = R"(
3685 %img = OpLoad %type_image_f32_3d_0010 %uniform_image_f32_3d_0010
3686 %res1 = OpImageQuerySamples %u32 %img
3687 )";
3688 
3689   CompileSuccessfully(GenerateKernelCode(body).c_str());
3690   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3691   EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' must be 2D"));
3692 }
3693 
TEST_F(ValidateImage,QuerySamplesNotMultisampled)3694 TEST_F(ValidateImage, QuerySamplesNotMultisampled) {
3695   const std::string body = R"(
3696 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3697 %res1 = OpImageQuerySamples %u32 %img
3698 )";
3699 
3700   CompileSuccessfully(GenerateKernelCode(body).c_str());
3701   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3702   EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 1"));
3703 }
3704 
TEST_F(ValidateImage,QueryLodWrongExecutionModel)3705 TEST_F(ValidateImage, QueryLodWrongExecutionModel) {
3706   const std::string body = R"(
3707 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3708 %sampler = OpLoad %type_sampler %uniform_sampler
3709 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3710 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3711 )";
3712 
3713   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
3714   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3715   EXPECT_THAT(
3716       getDiagnosticString(),
3717       HasSubstr(
3718           "OpImageQueryLod requires Fragment or GLCompute execution model"));
3719 }
3720 
TEST_F(ValidateImage,QueryLodWrongExecutionModelWithFunc)3721 TEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) {
3722   const std::string body = R"(
3723 %call_ret = OpFunctionCall %void %my_func
3724 OpReturn
3725 OpFunctionEnd
3726 %my_func = OpFunction %void None %func
3727 %my_func_entry = OpLabel
3728 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3729 %sampler = OpLoad %type_sampler %uniform_sampler
3730 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3731 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3732 )";
3733 
3734   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
3735   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3736   EXPECT_THAT(
3737       getDiagnosticString(),
3738       HasSubstr(
3739           "OpImageQueryLod requires Fragment or GLCompute execution model"));
3740 }
3741 
TEST_F(ValidateImage,QueryLodComputeShaderDerivatives)3742 TEST_F(ValidateImage, QueryLodComputeShaderDerivatives) {
3743   const std::string body = R"(
3744 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3745 %sampler = OpLoad %type_sampler %uniform_sampler
3746 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3747 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3748 )";
3749 
3750   const std::string extra = R"(
3751 OpCapability ComputeDerivativeGroupLinearNV
3752 OpExtension "SPV_NV_compute_shader_derivatives"
3753 )";
3754   const std::string mode = R"(
3755 OpExecutionMode %main LocalSize 8 8 1
3756 OpExecutionMode %main DerivativeGroupLinearNV
3757 )";
3758   CompileSuccessfully(
3759       GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
3760   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3761 }
3762 
TEST_F(ValidateImage,QueryLodComputeShaderDerivativesMissingMode)3763 TEST_F(ValidateImage, QueryLodComputeShaderDerivativesMissingMode) {
3764   const std::string body = R"(
3765 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3766 %sampler = OpLoad %type_sampler %uniform_sampler
3767 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3768 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3769 )";
3770 
3771   const std::string extra = R"(
3772 OpCapability ComputeDerivativeGroupLinearNV
3773 OpExtension "SPV_NV_compute_shader_derivatives"
3774 )";
3775   const std::string mode = R"(
3776 OpExecutionMode %main LocalSize 8 8 1
3777 )";
3778   CompileSuccessfully(
3779       GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
3780   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3781   EXPECT_THAT(getDiagnosticString(),
3782               HasSubstr("OpImageQueryLod requires DerivativeGroupQuadsNV or "
3783                         "DerivativeGroupLinearNV execution mode for GLCompute "
3784                         "execution model"));
3785 }
3786 
TEST_F(ValidateImage,ImplicitLodWrongExecutionModel)3787 TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
3788   const std::string body = R"(
3789 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3790 %sampler = OpLoad %type_sampler %uniform_sampler
3791 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3792 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
3793 )";
3794 
3795   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
3796   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3797   EXPECT_THAT(getDiagnosticString(),
3798               HasSubstr("ImplicitLod instructions require Fragment or "
3799                         "GLCompute execution model"));
3800 }
3801 
TEST_F(ValidateImage,ImplicitLodComputeShaderDerivatives)3802 TEST_F(ValidateImage, ImplicitLodComputeShaderDerivatives) {
3803   const std::string body = R"(
3804 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3805 %sampler = OpLoad %type_sampler %uniform_sampler
3806 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3807 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
3808 )";
3809 
3810   const std::string extra = R"(
3811 OpCapability ComputeDerivativeGroupLinearNV
3812 OpExtension "SPV_NV_compute_shader_derivatives"
3813 )";
3814   const std::string mode = R"(
3815 OpExecutionMode %main LocalSize 8 8 1
3816 OpExecutionMode %main DerivativeGroupLinearNV
3817 )";
3818   CompileSuccessfully(
3819       GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
3820   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3821 }
3822 
TEST_F(ValidateImage,ImplicitLodComputeShaderDerivativesMissingMode)3823 TEST_F(ValidateImage, ImplicitLodComputeShaderDerivativesMissingMode) {
3824   const std::string body = R"(
3825 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3826 %sampler = OpLoad %type_sampler %uniform_sampler
3827 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3828 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
3829 )";
3830 
3831   const std::string extra = R"(
3832 OpCapability ComputeDerivativeGroupLinearNV
3833 OpExtension "SPV_NV_compute_shader_derivatives"
3834 )";
3835   const std::string mode = R"(
3836 OpExecutionMode %main LocalSize 8 8 1
3837 )";
3838   CompileSuccessfully(
3839       GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
3840   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3841   EXPECT_THAT(
3842       getDiagnosticString(),
3843       HasSubstr("ImplicitLod instructions require DerivativeGroupQuadsNV or "
3844                 "DerivativeGroupLinearNV execution mode for GLCompute "
3845                 "execution model"));
3846 }
3847 
TEST_F(ValidateImage,ReadSubpassDataWrongExecutionModel)3848 TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
3849   const std::string body = R"(
3850 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3851 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3852 )";
3853 
3854   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3855   CompileSuccessfully(GenerateShaderCode(body, extra, "Vertex").c_str());
3856   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3857   EXPECT_THAT(getDiagnosticString(),
3858               HasSubstr("Dim SubpassData requires Fragment execution model"));
3859 }
3860 
TEST_F(ValidateImage,SparseSampleImplicitLodSuccess)3861 TEST_F(ValidateImage, SparseSampleImplicitLodSuccess) {
3862   const std::string body = R"(
3863 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3864 %sampler = OpLoad %type_sampler %uniform_sampler
3865 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3866 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh
3867 %res2 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Bias %f32_0_25
3868 %res4 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
3869 %res5 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
3870 %res6 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
3871 %res7 = OpImageSparseSampleImplicitLod %struct_u64_f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
3872 %res8 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
3873 )";
3874 
3875   const std::string extra = R"(
3876 OpCapability VulkanMemoryModelKHR
3877 OpExtension "SPV_KHR_vulkan_memory_model"
3878 )";
3879   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3880                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3881                           .c_str());
3882   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3883 }
3884 
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotStruct)3885 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotStruct) {
3886   const std::string body = R"(
3887 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3888 %sampler = OpLoad %type_sampler %uniform_sampler
3889 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3890 %res1 = OpImageSparseSampleImplicitLod %f32 %simg %f32vec2_hh
3891 )";
3892 
3893   CompileSuccessfully(GenerateShaderCode(body).c_str());
3894   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3895   EXPECT_THAT(getDiagnosticString(),
3896               HasSubstr("Expected Result Type to be OpTypeStruct"));
3897 }
3898 
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotTwoMembers1)3899 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers1) {
3900   const std::string body = R"(
3901 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3902 %sampler = OpLoad %type_sampler %uniform_sampler
3903 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3904 %res1 = OpImageSparseSampleImplicitLod %struct_u32 %simg %f32vec2_hh
3905 )";
3906 
3907   CompileSuccessfully(GenerateShaderCode(body).c_str());
3908   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3909   EXPECT_THAT(getDiagnosticString(),
3910               HasSubstr("Expected Result Type to be a struct containing an int "
3911                         "scalar and a texel"));
3912 }
3913 
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotTwoMembers2)3914 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers2) {
3915   const std::string body = R"(
3916 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3917 %sampler = OpLoad %type_sampler %uniform_sampler
3918 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3919 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4_u32 %simg %f32vec2_hh
3920 )";
3921 
3922   CompileSuccessfully(GenerateShaderCode(body).c_str());
3923   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3924   EXPECT_THAT(getDiagnosticString(),
3925               HasSubstr("Expected Result Type to be a struct containing an "
3926                         "int scalar and a texel"));
3927 }
3928 
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeFirstMemberNotInt)3929 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeFirstMemberNotInt) {
3930   const std::string body = R"(
3931 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3932 %sampler = OpLoad %type_sampler %uniform_sampler
3933 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3934 %res1 = OpImageSparseSampleImplicitLod %struct_f32_f32vec4 %simg %f32vec2_hh
3935 )";
3936 
3937   CompileSuccessfully(GenerateShaderCode(body).c_str());
3938   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3939   EXPECT_THAT(getDiagnosticString(),
3940               HasSubstr("Expected Result Type to be a struct containing an "
3941                         "int scalar and a texel"));
3942 }
3943 
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeTexelNotVector)3944 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeTexelNotVector) {
3945   const std::string body = R"(
3946 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3947 %sampler = OpLoad %type_sampler %uniform_sampler
3948 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3949 %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32 %simg %f32vec2_hh
3950 )";
3951 
3952   CompileSuccessfully(GenerateShaderCode(body).c_str());
3953   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3954   EXPECT_THAT(getDiagnosticString(),
3955               HasSubstr("Expected Result Type's second member to be int or "
3956                         "float vector type"));
3957 }
3958 
TEST_F(ValidateImage,SparseSampleImplicitLodWrongNumComponentsTexel)3959 TEST_F(ValidateImage, SparseSampleImplicitLodWrongNumComponentsTexel) {
3960   const std::string body = R"(
3961 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3962 %sampler = OpLoad %type_sampler %uniform_sampler
3963 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3964 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec3 %simg %f32vec2_hh
3965 )";
3966 
3967   CompileSuccessfully(GenerateShaderCode(body).c_str());
3968   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3969   EXPECT_THAT(getDiagnosticString(),
3970               HasSubstr("Expected Result Type's second member to have 4 "
3971                         "components"));
3972 }
3973 
TEST_F(ValidateImage,SparseSampleImplicitLodWrongComponentTypeTexel)3974 TEST_F(ValidateImage, SparseSampleImplicitLodWrongComponentTypeTexel) {
3975   const std::string body = R"(
3976 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3977 %sampler = OpLoad %type_sampler %uniform_sampler
3978 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3979 %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32vec4 %simg %f32vec2_hh
3980 )";
3981 
3982   CompileSuccessfully(GenerateShaderCode(body).c_str());
3983   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3984   EXPECT_THAT(getDiagnosticString(),
3985               HasSubstr("Expected Image 'Sampled Type' to be the same as "
3986                         "Result Type's second member components"));
3987 }
3988 
TEST_F(ValidateImage,SparseSampleDrefImplicitLodSuccess)3989 TEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) {
3990   const std::string body = R"(
3991 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
3992 %sampler = OpLoad %type_sampler %uniform_sampler
3993 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
3994 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
3995 %res2 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
3996 %res4 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
3997 %res5 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
3998 %res6 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
3999 %res7 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
4000 %res8 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
4001 )";
4002 
4003   const std::string extra = R"(
4004 OpCapability VulkanMemoryModelKHR
4005 OpExtension "SPV_KHR_vulkan_memory_model"
4006 )";
4007   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4008                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4009                           .c_str());
4010   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4011 }
4012 
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotStruct)4013 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotStruct) {
4014   const std::string body = R"(
4015 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4016 %sampler = OpLoad %type_sampler %uniform_sampler
4017 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4018 %res1 = OpImageSparseSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1
4019 )";
4020 
4021   CompileSuccessfully(GenerateShaderCode(body).c_str());
4022   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4023   EXPECT_THAT(getDiagnosticString(),
4024               HasSubstr("Expected Result Type to be OpTypeStruct"));
4025 }
4026 
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotTwoMembers1)4027 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers1) {
4028   const std::string body = R"(
4029 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4030 %sampler = OpLoad %type_sampler %uniform_sampler
4031 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4032 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32 %simg %f32vec2_hh %f32_1
4033 )";
4034 
4035   CompileSuccessfully(GenerateShaderCode(body).c_str());
4036   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4037   EXPECT_THAT(
4038       getDiagnosticString(),
4039       HasSubstr("Expected Result Type to be a struct containing an int scalar "
4040                 "and a texel"));
4041 }
4042 
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotTwoMembers2)4043 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers2) {
4044   const std::string body = R"(
4045 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4046 %sampler = OpLoad %type_sampler %uniform_sampler
4047 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4048 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_f32_u32 %simg %f32vec2_hh %f32_1
4049 )";
4050 
4051   CompileSuccessfully(GenerateShaderCode(body).c_str());
4052   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4053   EXPECT_THAT(
4054       getDiagnosticString(),
4055       HasSubstr("Expected Result Type to be a struct containing an int scalar "
4056                 "and a texel"));
4057 }
4058 
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt)4059 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt) {
4060   const std::string body = R"(
4061 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4062 %sampler = OpLoad %type_sampler %uniform_sampler
4063 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4064 %res1 = OpImageSparseSampleDrefImplicitLod %struct_f32_f32 %simg %f32vec2_hh %f32_1
4065 )";
4066 
4067   CompileSuccessfully(GenerateShaderCode(body).c_str());
4068   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4069   EXPECT_THAT(
4070       getDiagnosticString(),
4071       HasSubstr("Expected Result Type to be a struct containing an int scalar "
4072                 "and a texel"));
4073 }
4074 
TEST_F(ValidateImage,SparseSampleDrefImplicitLodDifferentSampledType)4075 TEST_F(ValidateImage, SparseSampleDrefImplicitLodDifferentSampledType) {
4076   const std::string body = R"(
4077 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4078 %sampler = OpLoad %type_sampler %uniform_sampler
4079 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4080 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
4081 )";
4082 
4083   CompileSuccessfully(GenerateShaderCode(body).c_str());
4084   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4085   EXPECT_THAT(getDiagnosticString(),
4086               HasSubstr("Expected Image 'Sampled Type' to be the same as "
4087                         "Result Type's second member"));
4088 }
4089 
TEST_F(ValidateImage,SparseFetchSuccess)4090 TEST_F(ValidateImage, SparseFetchSuccess) {
4091   const std::string body = R"(
4092 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
4093 %res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
4094 %res2 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
4095 )";
4096 
4097   const std::string extra = R"(
4098 OpCapability VulkanMemoryModelKHR
4099 OpExtension "SPV_KHR_vulkan_memory_model"
4100 )";
4101   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4102                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4103                           .c_str());
4104   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4105 }
4106 
TEST_F(ValidateImage,SparseFetchResultTypeNotStruct)4107 TEST_F(ValidateImage, SparseFetchResultTypeNotStruct) {
4108   const std::string body = R"(
4109 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4110 %res1 = OpImageSparseFetch %f32 %img %u32vec2_01
4111 )";
4112 
4113   CompileSuccessfully(GenerateShaderCode(body).c_str());
4114   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4115   EXPECT_THAT(getDiagnosticString(),
4116               HasSubstr("Expected Result Type to be OpTypeStruct"));
4117 }
4118 
TEST_F(ValidateImage,SparseFetchResultTypeNotTwoMembers1)4119 TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers1) {
4120   const std::string body = R"(
4121 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4122 %res1 = OpImageSparseFetch %struct_u32 %img %u32vec2_01
4123 )";
4124 
4125   CompileSuccessfully(GenerateShaderCode(body).c_str());
4126   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4127   EXPECT_THAT(getDiagnosticString(),
4128               HasSubstr("Expected Result Type to be a struct containing an "
4129                         "int scalar and a texel"));
4130 }
4131 
TEST_F(ValidateImage,SparseFetchResultTypeNotTwoMembers2)4132 TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers2) {
4133   const std::string body = R"(
4134 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4135 %res1 = OpImageSparseFetch %struct_u32_f32vec4_u32 %img %u32vec2_01
4136 )";
4137 
4138   CompileSuccessfully(GenerateShaderCode(body).c_str());
4139   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4140   EXPECT_THAT(getDiagnosticString(),
4141               HasSubstr("Expected Result Type to be a struct containing an "
4142                         "int scalar and a texel"));
4143 }
4144 
TEST_F(ValidateImage,SparseFetchResultTypeFirstMemberNotInt)4145 TEST_F(ValidateImage, SparseFetchResultTypeFirstMemberNotInt) {
4146   const std::string body = R"(
4147 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4148 %res1 = OpImageSparseFetch %struct_f32_f32vec4 %img %u32vec2_01
4149 )";
4150 
4151   CompileSuccessfully(GenerateShaderCode(body).c_str());
4152   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4153   EXPECT_THAT(getDiagnosticString(),
4154               HasSubstr("Expected Result Type to be a struct containing an "
4155                         "int scalar and a texel"));
4156 }
4157 
TEST_F(ValidateImage,SparseFetchResultTypeTexelNotVector)4158 TEST_F(ValidateImage, SparseFetchResultTypeTexelNotVector) {
4159   const std::string body = R"(
4160 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4161 %res1 = OpImageSparseFetch %struct_u32_u32 %img %u32vec2_01
4162 )";
4163 
4164   CompileSuccessfully(GenerateShaderCode(body).c_str());
4165   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4166   EXPECT_THAT(getDiagnosticString(),
4167               HasSubstr("Expected Result Type's second member to be int or "
4168                         "float vector type"));
4169 }
4170 
TEST_F(ValidateImage,SparseFetchWrongNumComponentsTexel)4171 TEST_F(ValidateImage, SparseFetchWrongNumComponentsTexel) {
4172   const std::string body = R"(
4173 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4174 %res1 = OpImageSparseFetch %struct_u32_f32vec3 %img %u32vec2_01
4175 )";
4176 
4177   CompileSuccessfully(GenerateShaderCode(body).c_str());
4178   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4179   EXPECT_THAT(getDiagnosticString(),
4180               HasSubstr("Expected Result Type's second member to have 4 "
4181                         "components"));
4182 }
4183 
TEST_F(ValidateImage,SparseFetchWrongComponentTypeTexel)4184 TEST_F(ValidateImage, SparseFetchWrongComponentTypeTexel) {
4185   const std::string body = R"(
4186 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4187 %res1 = OpImageSparseFetch %struct_u32_u32vec4 %img %u32vec2_01
4188 )";
4189 
4190   CompileSuccessfully(GenerateShaderCode(body).c_str());
4191   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4192   EXPECT_THAT(getDiagnosticString(),
4193               HasSubstr("Expected Image 'Sampled Type' to be the same as "
4194                         "Result Type's second member components"));
4195 }
4196 
TEST_F(ValidateImage,SparseReadSuccess)4197 TEST_F(ValidateImage, SparseReadSuccess) {
4198   const std::string body = R"(
4199 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4200 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
4201 )";
4202 
4203   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4204   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4205   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4206 }
4207 
TEST_F(ValidateImage,SparseReadResultTypeNotStruct)4208 TEST_F(ValidateImage, SparseReadResultTypeNotStruct) {
4209   const std::string body = R"(
4210 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4211 %res1 = OpImageSparseRead %f32 %img %u32vec2_01
4212 )";
4213 
4214   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4215   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4216   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4217   EXPECT_THAT(getDiagnosticString(),
4218               HasSubstr("Expected Result Type to be OpTypeStruct"));
4219 }
4220 
TEST_F(ValidateImage,SparseReadResultTypeNotTwoMembers1)4221 TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers1) {
4222   const std::string body = R"(
4223 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4224 %res1 = OpImageSparseRead %struct_u32 %img %u32vec2_01
4225 )";
4226 
4227   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4228   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4229   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4230   EXPECT_THAT(getDiagnosticString(),
4231               HasSubstr("Expected Result Type to be a struct containing an "
4232                         "int scalar and a texel"));
4233 }
4234 
TEST_F(ValidateImage,SparseReadResultTypeNotTwoMembers2)4235 TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers2) {
4236   const std::string body = R"(
4237 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4238 %res1 = OpImageSparseRead %struct_u32_f32vec4_u32 %img %u32vec2_01
4239 )";
4240 
4241   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4242   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4243   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4244   EXPECT_THAT(getDiagnosticString(),
4245               HasSubstr("Expected Result Type to be a struct containing an "
4246                         "int scalar and a texel"));
4247 }
4248 
TEST_F(ValidateImage,SparseReadResultTypeFirstMemberNotInt)4249 TEST_F(ValidateImage, SparseReadResultTypeFirstMemberNotInt) {
4250   const std::string body = R"(
4251 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4252 %res1 = OpImageSparseRead %struct_f32_f32vec4 %img %u32vec2_01
4253 )";
4254 
4255   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4256   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4257   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4258   EXPECT_THAT(getDiagnosticString(),
4259               HasSubstr("Expected Result Type to be a struct containing an "
4260                         "int scalar and a texel"));
4261 }
4262 
TEST_F(ValidateImage,SparseReadResultTypeTexelWrongType)4263 TEST_F(ValidateImage, SparseReadResultTypeTexelWrongType) {
4264   const std::string body = R"(
4265 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4266 %res1 = OpImageSparseRead %struct_u32_u32arr4 %img %u32vec2_01
4267 )";
4268 
4269   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4270   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4271   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4272   EXPECT_THAT(getDiagnosticString(),
4273               HasSubstr("Expected Result Type's second member to be int or "
4274                         "float scalar or vector type"));
4275 }
4276 
TEST_F(ValidateImage,SparseReadWrongComponentTypeTexel)4277 TEST_F(ValidateImage, SparseReadWrongComponentTypeTexel) {
4278   const std::string body = R"(
4279 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4280 %res1 = OpImageSparseRead %struct_u32_u32vec4 %img %u32vec2_01
4281 )";
4282 
4283   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4284   CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4285   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4286   EXPECT_THAT(getDiagnosticString(),
4287               HasSubstr("Expected Image 'Sampled Type' to be the same as "
4288                         "Result Type's second member components"));
4289 }
4290 
TEST_F(ValidateImage,SparseReadSubpassDataNotAllowed)4291 TEST_F(ValidateImage, SparseReadSubpassDataNotAllowed) {
4292   const std::string body = R"(
4293 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
4294 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
4295 )";
4296 
4297   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4298   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment").c_str());
4299   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4300   EXPECT_THAT(
4301       getDiagnosticString(),
4302       HasSubstr("Image Dim SubpassData cannot be used with ImageSparseRead"));
4303 }
4304 
TEST_F(ValidateImage,SparseGatherSuccess)4305 TEST_F(ValidateImage, SparseGatherSuccess) {
4306   const std::string body = R"(
4307 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4308 %sampler = OpLoad %type_sampler %uniform_sampler
4309 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4310 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1
4311 %res2 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
4312 )";
4313 
4314   const std::string extra = R"(
4315 OpCapability VulkanMemoryModelKHR
4316 OpExtension "SPV_KHR_vulkan_memory_model"
4317 )";
4318   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4319                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4320                           .c_str());
4321   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4322 }
4323 
TEST_F(ValidateImage,SparseGatherResultTypeNotStruct)4324 TEST_F(ValidateImage, SparseGatherResultTypeNotStruct) {
4325   const std::string body = R"(
4326 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4327 %sampler = OpLoad %type_sampler %uniform_sampler
4328 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4329 %res1 = OpImageSparseGather %f32 %simg %f32vec2_hh %u32_1
4330 )";
4331 
4332   CompileSuccessfully(GenerateShaderCode(body).c_str());
4333   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4334   EXPECT_THAT(getDiagnosticString(),
4335               HasSubstr("Expected Result Type to be OpTypeStruct"));
4336 }
4337 
TEST_F(ValidateImage,SparseGatherResultTypeNotTwoMembers1)4338 TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers1) {
4339   const std::string body = R"(
4340 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4341 %sampler = OpLoad %type_sampler %uniform_sampler
4342 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4343 %res1 = OpImageSparseGather %struct_u32 %simg %f32vec2_hh %u32_1
4344 )";
4345 
4346   CompileSuccessfully(GenerateShaderCode(body).c_str());
4347   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4348   EXPECT_THAT(getDiagnosticString(),
4349               HasSubstr("Expected Result Type to be a struct containing an int "
4350                         "scalar and a texel"));
4351 }
4352 
TEST_F(ValidateImage,SparseGatherResultTypeNotTwoMembers2)4353 TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers2) {
4354   const std::string body = R"(
4355 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4356 %sampler = OpLoad %type_sampler %uniform_sampler
4357 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4358 %res1 = OpImageSparseGather %struct_u32_f32vec4_u32 %simg %f32vec2_hh %u32_1
4359 )";
4360 
4361   CompileSuccessfully(GenerateShaderCode(body).c_str());
4362   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4363   EXPECT_THAT(getDiagnosticString(),
4364               HasSubstr("Expected Result Type to be a struct containing an int "
4365                         "scalar and a texel"));
4366 }
4367 
TEST_F(ValidateImage,SparseGatherResultTypeFirstMemberNotInt)4368 TEST_F(ValidateImage, SparseGatherResultTypeFirstMemberNotInt) {
4369   const std::string body = R"(
4370 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4371 %sampler = OpLoad %type_sampler %uniform_sampler
4372 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4373 %res1 = OpImageSparseGather %struct_f32_f32vec4 %simg %f32vec2_hh %u32_1
4374 )";
4375 
4376   CompileSuccessfully(GenerateShaderCode(body).c_str());
4377   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4378   EXPECT_THAT(getDiagnosticString(),
4379               HasSubstr("Expected Result Type to be a struct containing an "
4380                         "int scalar and a texel"));
4381 }
4382 
TEST_F(ValidateImage,SparseGatherResultTypeTexelNotVector)4383 TEST_F(ValidateImage, SparseGatherResultTypeTexelNotVector) {
4384   const std::string body = R"(
4385 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4386 %sampler = OpLoad %type_sampler %uniform_sampler
4387 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4388 %res1 = OpImageSparseGather %struct_u32_u32 %simg %f32vec2_hh %u32_1
4389 )";
4390 
4391   CompileSuccessfully(GenerateShaderCode(body).c_str());
4392   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4393   EXPECT_THAT(getDiagnosticString(),
4394               HasSubstr("Expected Result Type's second member to be int or "
4395                         "float vector type"));
4396 }
4397 
TEST_F(ValidateImage,SparseGatherWrongNumComponentsTexel)4398 TEST_F(ValidateImage, SparseGatherWrongNumComponentsTexel) {
4399   const std::string body = R"(
4400 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4401 %sampler = OpLoad %type_sampler %uniform_sampler
4402 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4403 %res1 = OpImageSparseGather %struct_u32_f32vec3 %simg %f32vec2_hh %u32_1
4404 )";
4405 
4406   CompileSuccessfully(GenerateShaderCode(body).c_str());
4407   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4408   EXPECT_THAT(getDiagnosticString(),
4409               HasSubstr("Expected Result Type's second member to have 4 "
4410                         "components"));
4411 }
4412 
TEST_F(ValidateImage,SparseGatherWrongComponentTypeTexel)4413 TEST_F(ValidateImage, SparseGatherWrongComponentTypeTexel) {
4414   const std::string body = R"(
4415 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4416 %sampler = OpLoad %type_sampler %uniform_sampler
4417 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4418 %res1 = OpImageSparseGather %struct_u32_u32vec4 %simg %f32vec2_hh %u32_1
4419 )";
4420 
4421   CompileSuccessfully(GenerateShaderCode(body).c_str());
4422   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4423   EXPECT_THAT(getDiagnosticString(),
4424               HasSubstr("Expected Image 'Sampled Type' to be the same as "
4425                         "Result Type's second member components"));
4426 }
4427 
TEST_F(ValidateImage,SparseTexelsResidentSuccess)4428 TEST_F(ValidateImage, SparseTexelsResidentSuccess) {
4429   const std::string body = R"(
4430 %res1 = OpImageSparseTexelsResident %bool %u32_1
4431 )";
4432 
4433   CompileSuccessfully(GenerateShaderCode(body).c_str());
4434   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4435 }
4436 
TEST_F(ValidateImage,SparseTexelsResidentResultTypeNotBool)4437 TEST_F(ValidateImage, SparseTexelsResidentResultTypeNotBool) {
4438   const std::string body = R"(
4439 %res1 = OpImageSparseTexelsResident %u32 %u32_1
4440 )";
4441 
4442   CompileSuccessfully(GenerateShaderCode(body).c_str());
4443   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4444   EXPECT_THAT(getDiagnosticString(),
4445               HasSubstr("Expected Result Type to be bool scalar type"));
4446 }
4447 
TEST_F(ValidateImage,MakeTexelVisibleKHRSuccessImageRead)4448 TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageRead) {
4449   const std::string body = R"(
4450 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4451 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
4452 )";
4453 
4454   const std::string extra = R"(
4455 OpCapability StorageImageReadWithoutFormat
4456 OpCapability VulkanMemoryModelKHR
4457 OpExtension "SPV_KHR_vulkan_memory_model"
4458 )";
4459   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4460                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4461                           .c_str());
4462   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4463 }
4464 
TEST_F(ValidateImage,MakeTexelVisibleKHRSuccessImageSparseRead)4465 TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageSparseRead) {
4466   const std::string body = R"(
4467 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4468 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
4469 )";
4470 
4471   const std::string extra = R"(
4472 OpCapability StorageImageReadWithoutFormat
4473 OpCapability VulkanMemoryModelKHR
4474 OpExtension "SPV_KHR_vulkan_memory_model"
4475 )";
4476   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4477                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4478                           .c_str());
4479   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4480 }
4481 
TEST_F(ValidateImage,MakeTexelVisibleKHRFailureOpcode)4482 TEST_F(ValidateImage, MakeTexelVisibleKHRFailureOpcode) {
4483   const std::string body = R"(
4484 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4485 %sampler = OpLoad %type_sampler %uniform_sampler
4486 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4487 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
4488 )";
4489 
4490   const std::string extra = R"(
4491 OpCapability StorageImageReadWithoutFormat
4492 OpCapability VulkanMemoryModelKHR
4493 OpExtension "SPV_KHR_vulkan_memory_model"
4494 )";
4495   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4496                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4497                           .c_str());
4498   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4499             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4500   EXPECT_THAT(
4501       getDiagnosticString(),
4502       HasSubstr("Image Operand MakeTexelVisibleKHR can only be used with "
4503                 "OpImageRead or OpImageSparseRead: OpImageSampleImplicitLod"));
4504 }
4505 
TEST_F(ValidateImage,MakeTexelVisibleKHRFailureMissingNonPrivate)4506 TEST_F(ValidateImage, MakeTexelVisibleKHRFailureMissingNonPrivate) {
4507   const std::string body = R"(
4508 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4509 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR %u32_1
4510 )";
4511 
4512   const std::string extra = R"(
4513 OpCapability StorageImageReadWithoutFormat
4514 OpCapability VulkanMemoryModelKHR
4515 OpExtension "SPV_KHR_vulkan_memory_model"
4516 )";
4517   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4518                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4519                           .c_str());
4520   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4521             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4522   EXPECT_THAT(getDiagnosticString(),
4523               HasSubstr("Image Operand MakeTexelVisibleKHR requires "
4524                         "NonPrivateTexelKHR is also specified: OpImageRead"));
4525 }
4526 
TEST_F(ValidateImage,MakeTexelAvailableKHRSuccessImageWrite)4527 TEST_F(ValidateImage, MakeTexelAvailableKHRSuccessImageWrite) {
4528   const std::string body = R"(
4529 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4530 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2
4531 )";
4532 
4533   const std::string extra = R"(
4534 OpCapability StorageImageWriteWithoutFormat
4535 OpCapability VulkanMemoryModelKHR
4536 OpExtension "SPV_KHR_vulkan_memory_model"
4537 )";
4538   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4539                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4540                           .c_str());
4541   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4542 }
4543 
TEST_F(ValidateImage,MakeTexelAvailableKHRFailureOpcode)4544 TEST_F(ValidateImage, MakeTexelAvailableKHRFailureOpcode) {
4545   const std::string body = R"(
4546 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4547 %sampler = OpLoad %type_sampler %uniform_sampler
4548 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4549 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
4550 )";
4551 
4552   const std::string extra = R"(
4553 OpCapability StorageImageReadWithoutFormat
4554 OpCapability VulkanMemoryModelKHR
4555 OpExtension "SPV_KHR_vulkan_memory_model"
4556 )";
4557   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4558                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4559                           .c_str());
4560   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4561             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4562   EXPECT_THAT(getDiagnosticString(),
4563               HasSubstr("Image Operand MakeTexelAvailableKHR can only be used "
4564                         "with OpImageWrite: OpImageSampleImplicitLod"));
4565 }
4566 
TEST_F(ValidateImage,MakeTexelAvailableKHRFailureMissingNonPrivate)4567 TEST_F(ValidateImage, MakeTexelAvailableKHRFailureMissingNonPrivate) {
4568   const std::string body = R"(
4569 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4570 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1
4571 )";
4572 
4573   const std::string extra = R"(
4574 OpCapability StorageImageWriteWithoutFormat
4575 OpCapability VulkanMemoryModelKHR
4576 OpExtension "SPV_KHR_vulkan_memory_model"
4577 )";
4578   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4579                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4580                           .c_str());
4581   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4582             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4583   EXPECT_THAT(getDiagnosticString(),
4584               HasSubstr("Image Operand MakeTexelAvailableKHR requires "
4585                         "NonPrivateTexelKHR is also specified: OpImageWrite"));
4586 }
4587 
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageWriteBad)4588 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteBad) {
4589   const std::string body = R"(
4590 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4591 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
4592 )";
4593 
4594   const std::string extra = R"(
4595 OpCapability StorageImageWriteWithoutFormat
4596 OpCapability VulkanMemoryModelKHR
4597 OpExtension "SPV_KHR_vulkan_memory_model"
4598 )";
4599   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4600                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4601                           .c_str());
4602   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4603             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4604   EXPECT_THAT(
4605       getDiagnosticString(),
4606       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
4607                 "VulkanMemoryModelDeviceScopeKHR capability"));
4608 }
4609 
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageWriteGood)4610 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteGood) {
4611   const std::string body = R"(
4612 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4613 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
4614 )";
4615 
4616   const std::string extra = R"(
4617 OpCapability StorageImageWriteWithoutFormat
4618 OpCapability VulkanMemoryModelKHR
4619 OpCapability VulkanMemoryModelDeviceScopeKHR
4620 OpExtension "SPV_KHR_vulkan_memory_model"
4621 )";
4622   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4623                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4624                           .c_str());
4625   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4626 }
4627 
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageReadBad)4628 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadBad) {
4629   const std::string body = R"(
4630 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4631 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
4632 )";
4633 
4634   const std::string extra = R"(
4635 OpCapability StorageImageReadWithoutFormat
4636 OpCapability VulkanMemoryModelKHR
4637 OpExtension "SPV_KHR_vulkan_memory_model"
4638 )";
4639   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4640                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4641                           .c_str());
4642   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4643             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4644   EXPECT_THAT(
4645       getDiagnosticString(),
4646       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
4647                 "VulkanMemoryModelDeviceScopeKHR capability"));
4648 }
4649 
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageReadGood)4650 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadGood) {
4651   const std::string body = R"(
4652 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4653 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
4654 )";
4655 
4656   const std::string extra = R"(
4657 OpCapability StorageImageReadWithoutFormat
4658 OpCapability VulkanMemoryModelKHR
4659 OpCapability VulkanMemoryModelDeviceScopeKHR
4660 OpExtension "SPV_KHR_vulkan_memory_model"
4661 )";
4662   CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4663                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4664                           .c_str());
4665   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4666 }
4667 
4668 // This example used to cause a seg fault on OpReturnValue, verifying it doesn't
4669 // anymore.
TEST_F(ValidateImage,Issue2463NoSegFault)4670 TEST_F(ValidateImage, Issue2463NoSegFault) {
4671   const std::string spirv = R"(
4672                OpCapability Linkage
4673                OpCapability Shader
4674           %1 = OpExtInstImport "GLSL.std.450"
4675                OpMemoryModel Logical GLSL450
4676        %void = OpTypeVoid
4677           %6 = OpTypeFunction %void
4678       %float = OpTypeFloat 32
4679           %8 = OpTypeImage %float 3D 0 0 0 1 Unknown
4680 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
4681          %10 = OpTypeSampler
4682 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
4683          %12 = OpTypeSampledImage %8
4684          %13 = OpTypeFunction %12 %_ptr_UniformConstant_8 %_ptr_UniformConstant_10
4685          %23 = OpFunction %12 None %13
4686          %24 = OpFunctionParameter %_ptr_UniformConstant_8
4687          %25 = OpFunctionParameter %_ptr_UniformConstant_10
4688          %26 = OpLabel
4689          %27 = OpLoad %8 %24
4690          %28 = OpLoad %10 %25
4691          %29 = OpSampledImage %12 %27 %28
4692                OpReturnValue %29
4693                OpFunctionEnd
4694 )";
4695 
4696   CompileSuccessfully(spirv);
4697   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4698   EXPECT_THAT(getDiagnosticString(),
4699               HasSubstr("OpSampledImage instruction must not appear as operand "
4700                         "for OpReturnValue"));
4701 }
4702 
TEST_F(ValidateImage,SignExtendV13Bad)4703 TEST_F(ValidateImage, SignExtendV13Bad) {
4704   const std::string body = R"(
4705 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4706 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
4707 )";
4708 
4709   EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
4710                                                 SPV_ENV_UNIVERSAL_1_3)),
4711               HasSubstr("Invalid image operand 'SignExtend'"));
4712 }
4713 
TEST_F(ValidateImage,ZeroExtendV13Bad)4714 TEST_F(ValidateImage, ZeroExtendV13Bad) {
4715   const std::string body = R"(
4716 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4717 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
4718 )";
4719 
4720   EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
4721                                                 SPV_ENV_UNIVERSAL_1_3)),
4722               HasSubstr("Invalid image operand 'ZeroExtend'"));
4723 }
4724 
TEST_F(ValidateImage,SignExtendScalarUIntTexelV14Good)4725 TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) {
4726   // Unsigned int sampled type
4727   const std::string body = R"(
4728 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4729 %res1 = OpImageRead %u32 %img %u32vec2_01 SignExtend
4730 )";
4731   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4732 
4733   CompileSuccessfully(
4734       GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4735       SPV_ENV_UNIVERSAL_1_4);
4736   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4737   EXPECT_THAT(getDiagnosticString(), Eq(""));
4738 }
4739 
TEST_F(ValidateImage,SignExtendScalarSIntTexelV14Good)4740 TEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) {
4741   // Signed int sampled type
4742   const std::string body = R"(
4743 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
4744 %res1 = OpImageRead %s32 %img %u32vec2_01 SignExtend
4745 )";
4746   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4747 
4748   CompileSuccessfully(
4749       GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4750       SPV_ENV_UNIVERSAL_1_4);
4751   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4752   EXPECT_THAT(getDiagnosticString(), Eq(""));
4753 }
4754 
TEST_F(ValidateImage,SignExtendScalarVectorUIntTexelV14Good)4755 TEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) {
4756   const std::string body = R"(
4757 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4758 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
4759 )";
4760   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4761 
4762   CompileSuccessfully(
4763       GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4764       SPV_ENV_UNIVERSAL_1_4);
4765   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4766   EXPECT_THAT(getDiagnosticString(), Eq(""));
4767 }
4768 
TEST_F(ValidateImage,SignExtendVectorSIntTexelV14Good)4769 TEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) {
4770   const std::string body = R"(
4771 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
4772 %res1 = OpImageRead %s32vec4 %img %u32vec2_01 SignExtend
4773 )";
4774   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4775 
4776   CompileSuccessfully(
4777       GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4778       SPV_ENV_UNIVERSAL_1_4);
4779   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4780   EXPECT_THAT(getDiagnosticString(), Eq(""));
4781 }
4782 
4783 // No negative tests for SignExtend since we don't truly know the
4784 // texel format.
4785 
TEST_F(ValidateImage,ZeroExtendScalarUIntTexelV14Good)4786 TEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) {
4787   // Unsigned int sampled type
4788   const std::string body = R"(
4789 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4790 %res1 = OpImageRead %u32 %img %u32vec2_01 ZeroExtend
4791 )";
4792   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4793 
4794   CompileSuccessfully(
4795       GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4796       SPV_ENV_UNIVERSAL_1_4);
4797   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4798   EXPECT_THAT(getDiagnosticString(), Eq(""));
4799 }
4800 
TEST_F(ValidateImage,ZeroExtendScalarSIntTexelV14Good)4801 TEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) {
4802   // Zeroed int sampled type
4803   const std::string body = R"(
4804 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
4805 %res1 = OpImageRead %s32 %img %u32vec2_01 ZeroExtend
4806 )";
4807   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4808 
4809   CompileSuccessfully(
4810       GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4811       SPV_ENV_UNIVERSAL_1_4);
4812   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4813   EXPECT_THAT(getDiagnosticString(), Eq(""));
4814 }
4815 
TEST_F(ValidateImage,ZeroExtendScalarVectorUIntTexelV14Good)4816 TEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) {
4817   const std::string body = R"(
4818 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4819 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
4820 )";
4821   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4822 
4823   CompileSuccessfully(
4824       GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4825       SPV_ENV_UNIVERSAL_1_4);
4826   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4827   EXPECT_THAT(getDiagnosticString(), Eq(""));
4828 }
4829 
TEST_F(ValidateImage,ZeroExtendVectorSIntTexelV14Good)4830 TEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) {
4831   const std::string body = R"(
4832 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
4833 %res1 = OpImageRead %s32vec4 %img %u32vec2_01 ZeroExtend
4834 )";
4835   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4836 
4837   CompileSuccessfully(
4838       GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4839       SPV_ENV_UNIVERSAL_1_4);
4840   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4841   EXPECT_THAT(getDiagnosticString(), Eq(""));
4842 }
4843 
4844 // No negative tests for ZeroExtend since we don't truly know the
4845 // texel format.
4846 
4847 }  // namespace
4848 }  // namespace val
4849 }  // namespace spvtools
4850