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