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