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