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,SampleImplicitLodVulkanOffsetWrongBeforeLegalization)1794 TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongBeforeLegalization) {
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 Offset %s32vec2_01
1800 )";
1801
1802 CompileSuccessfully(
1803 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
1804 getValidatorOptions()->before_hlsl_legalization = true;
1805 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1806 }
1807
TEST_F(ValidateImage,SampleImplicitLodMoreThanOneOffset)1808 TEST_F(ValidateImage, SampleImplicitLodMoreThanOneOffset) {
1809 const std::string body = R"(
1810 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1811 %sampler = OpLoad %type_sampler %uniform_sampler
1812 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1813 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
1814 )";
1815
1816 CompileSuccessfully(GenerateShaderCode(body).c_str());
1817 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1818 EXPECT_THAT(
1819 getDiagnosticString(),
1820 HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
1821 "cannot be used together"));
1822 }
1823
TEST_F(ValidateImage,SampleImplicitLodVulkanMoreThanOneOffset)1824 TEST_F(ValidateImage, SampleImplicitLodVulkanMoreThanOneOffset) {
1825 const std::string body = R"(
1826 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1827 %sampler = OpLoad %type_sampler %uniform_sampler
1828 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1829 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
1830 )";
1831
1832 CompileSuccessfully(
1833 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
1834 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1835 EXPECT_THAT(getDiagnosticString(),
1836 AnyVUID("VUID-StandaloneSpirv-Offset-04662"));
1837 EXPECT_THAT(
1838 getDiagnosticString(),
1839 HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
1840 "cannot be used together"));
1841 }
1842
TEST_F(ValidateImage,SampleImplicitLodMinLodWrongType)1843 TEST_F(ValidateImage, SampleImplicitLodMinLodWrongType) {
1844 const std::string body = R"(
1845 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1846 %sampler = OpLoad %type_sampler %uniform_sampler
1847 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1848 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %s32_0
1849 )";
1850
1851 CompileSuccessfully(GenerateShaderCode(body).c_str());
1852 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1853 EXPECT_THAT(getDiagnosticString(),
1854 HasSubstr("Expected Image Operand MinLod to be float scalar"));
1855 }
1856
TEST_F(ValidateImage,SampleImplicitLodMinLodWrongDim)1857 TEST_F(ValidateImage, SampleImplicitLodMinLodWrongDim) {
1858 const std::string body = R"(
1859 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1860 %sampler = OpLoad %type_sampler %uniform_sampler
1861 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1862 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_25
1863 )";
1864
1865 CompileSuccessfully(GenerateShaderCode(body).c_str());
1866 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1867 EXPECT_THAT(getDiagnosticString(),
1868 HasSubstr("Image Operand MinLod requires 'Dim' parameter to be "
1869 "1D, 2D, 3D or Cube"));
1870 }
1871
TEST_F(ValidateImage,SampleProjExplicitLodSuccess2D)1872 TEST_F(ValidateImage, SampleProjExplicitLodSuccess2D) {
1873 const std::string body = R"(
1874 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1875 %sampler = OpLoad %type_sampler %uniform_sampler
1876 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1877 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod %f32_1
1878 %res3 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
1879 %res4 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
1880 %res5 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
1881 %res7 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
1882 %res8 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod|NonPrivateTexelKHR %f32_1
1883 )";
1884
1885 const std::string extra = R"(
1886 OpCapability VulkanMemoryModelKHR
1887 OpExtension "SPV_KHR_vulkan_memory_model"
1888 )";
1889 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1890 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1891 .c_str());
1892 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1893 }
1894
TEST_F(ValidateImage,SampleProjExplicitLodSuccessRect)1895 TEST_F(ValidateImage, SampleProjExplicitLodSuccessRect) {
1896 const std::string body = R"(
1897 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1898 %sampler = OpLoad %type_sampler %uniform_sampler
1899 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1900 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
1901 %res2 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
1902 )";
1903
1904 CompileSuccessfully(GenerateShaderCode(body).c_str());
1905 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1906 }
1907
TEST_F(ValidateImage,SampleProjExplicitLodWrongResultType)1908 TEST_F(ValidateImage, SampleProjExplicitLodWrongResultType) {
1909 const std::string body = R"(
1910 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1911 %sampler = OpLoad %type_sampler %uniform_sampler
1912 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1913 %res1 = OpImageSampleProjExplicitLod %f32 %simg %f32vec3_hhh Lod %f32_1
1914 )";
1915
1916 CompileSuccessfully(GenerateShaderCode(body).c_str());
1917 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1918 EXPECT_THAT(getDiagnosticString(),
1919 HasSubstr("Expected Result Type to be int or float vector type"));
1920 }
1921
TEST_F(ValidateImage,SampleProjExplicitLodWrongNumComponentsResultType)1922 TEST_F(ValidateImage, SampleProjExplicitLodWrongNumComponentsResultType) {
1923 const std::string body = R"(
1924 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1925 %sampler = OpLoad %type_sampler %uniform_sampler
1926 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1927 %res1 = OpImageSampleProjExplicitLod %f32vec3 %simg %f32vec3_hhh Lod %f32_1
1928 )";
1929
1930 CompileSuccessfully(GenerateShaderCode(body).c_str());
1931 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1932 EXPECT_THAT(getDiagnosticString(),
1933 HasSubstr("Expected Result Type to have 4 components"));
1934 }
1935
TEST_F(ValidateImage,SampleProjExplicitLodNotSampledImage)1936 TEST_F(ValidateImage, SampleProjExplicitLodNotSampledImage) {
1937 const std::string body = R"(
1938 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1939 %res1 = OpImageSampleProjExplicitLod %f32vec4 %img %f32vec3_hhh Lod %f32_1
1940 )";
1941
1942 CompileSuccessfully(GenerateShaderCode(body).c_str());
1943 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1944 EXPECT_THAT(
1945 getDiagnosticString(),
1946 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1947 }
1948
TEST_F(ValidateImage,SampleProjExplicitLodMultisampleError)1949 TEST_F(ValidateImage, SampleProjExplicitLodMultisampleError) {
1950 const std::string body = R"(
1951 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
1952 %sampler = OpLoad %type_sampler %uniform_sampler
1953 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
1954 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_1 %u32_1
1955 )";
1956
1957 CompileSuccessfully(GenerateShaderCode(body).c_str());
1958 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1959 EXPECT_THAT(getDiagnosticString(),
1960 HasSubstr("Expected Image 'MS' parameter to be 0"));
1961 }
1962
TEST_F(ValidateImage,SampleProjExplicitLodWrongSampledType)1963 TEST_F(ValidateImage, SampleProjExplicitLodWrongSampledType) {
1964 const std::string body = R"(
1965 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1966 %sampler = OpLoad %type_sampler %uniform_sampler
1967 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1968 %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
1969 )";
1970
1971 CompileSuccessfully(GenerateShaderCode(body).c_str());
1972 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1973 EXPECT_THAT(getDiagnosticString(),
1974 HasSubstr("Expected Image 'Sampled Type' to be the same as "
1975 "Result Type components"));
1976 }
1977
TEST_F(ValidateImage,SampleProjExplicitLodVoidSampledType)1978 TEST_F(ValidateImage, SampleProjExplicitLodVoidSampledType) {
1979 const std::string body = R"(
1980 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1981 %sampler = OpLoad %type_sampler %uniform_sampler
1982 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1983 %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
1984 )";
1985
1986 CompileSuccessfully(GenerateShaderCode(body).c_str());
1987 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1988 }
1989
TEST_F(ValidateImage,SampleProjExplicitLodWrongCoordinateType)1990 TEST_F(ValidateImage, SampleProjExplicitLodWrongCoordinateType) {
1991 const std::string body = R"(
1992 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1993 %sampler = OpLoad %type_sampler %uniform_sampler
1994 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1995 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %img Lod %f32_1
1996 )";
1997
1998 CompileSuccessfully(GenerateShaderCode(body).c_str());
1999 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2000 EXPECT_THAT(getDiagnosticString(),
2001 HasSubstr("Expected Coordinate to be float scalar or vector"));
2002 }
2003
TEST_F(ValidateImage,SampleProjExplicitLodCoordinateSizeTooSmall)2004 TEST_F(ValidateImage, SampleProjExplicitLodCoordinateSizeTooSmall) {
2005 const std::string body = R"(
2006 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2007 %sampler = OpLoad %type_sampler %uniform_sampler
2008 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2009 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_1
2010 )";
2011
2012 CompileSuccessfully(GenerateShaderCode(body).c_str());
2013 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2014 EXPECT_THAT(getDiagnosticString(),
2015 HasSubstr("Expected Coordinate to have at least 3 components, "
2016 "but given only 2"));
2017 }
2018
TEST_F(ValidateImage,SampleProjImplicitLodSuccess)2019 TEST_F(ValidateImage, SampleProjImplicitLodSuccess) {
2020 const std::string body = R"(
2021 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2022 %sampler = OpLoad %type_sampler %uniform_sampler
2023 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2024 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh
2025 %res2 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias %f32_0_25
2026 %res4 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
2027 %res5 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
2028 %res6 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh MinLod %f32_0_5
2029 %res7 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2030 %res8 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh NonPrivateTexelKHR
2031 )";
2032
2033 const std::string extra = R"(
2034 OpCapability VulkanMemoryModelKHR
2035 OpExtension "SPV_KHR_vulkan_memory_model"
2036 )";
2037 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2038 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2039 .c_str());
2040 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2041 }
2042
TEST_F(ValidateImage,SampleProjImplicitLodWrongResultType)2043 TEST_F(ValidateImage, SampleProjImplicitLodWrongResultType) {
2044 const std::string body = R"(
2045 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2046 %sampler = OpLoad %type_sampler %uniform_sampler
2047 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2048 %res1 = OpImageSampleProjImplicitLod %f32 %simg %f32vec3_hhh
2049 )";
2050
2051 CompileSuccessfully(GenerateShaderCode(body).c_str());
2052 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2053 EXPECT_THAT(getDiagnosticString(),
2054 HasSubstr("Expected Result Type to be int or float vector type"));
2055 }
2056
TEST_F(ValidateImage,SampleProjImplicitLodWrongNumComponentsResultType)2057 TEST_F(ValidateImage, SampleProjImplicitLodWrongNumComponentsResultType) {
2058 const std::string body = R"(
2059 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2060 %sampler = OpLoad %type_sampler %uniform_sampler
2061 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2062 %res1 = OpImageSampleProjImplicitLod %f32vec3 %simg %f32vec3_hhh
2063 )";
2064
2065 CompileSuccessfully(GenerateShaderCode(body).c_str());
2066 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2067 EXPECT_THAT(getDiagnosticString(),
2068 HasSubstr("Expected Result Type to have 4 components"));
2069 }
2070
TEST_F(ValidateImage,SampleProjImplicitLodNotSampledImage)2071 TEST_F(ValidateImage, SampleProjImplicitLodNotSampledImage) {
2072 const std::string body = R"(
2073 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2074 %res1 = OpImageSampleProjImplicitLod %f32vec4 %img %f32vec3_hhh
2075 )";
2076
2077 CompileSuccessfully(GenerateShaderCode(body).c_str());
2078 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2079 EXPECT_THAT(
2080 getDiagnosticString(),
2081 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2082 }
2083
TEST_F(ValidateImage,SampleProjImplicitLodMultisampleError)2084 TEST_F(ValidateImage, SampleProjImplicitLodMultisampleError) {
2085 const std::string body = R"(
2086 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2087 %sampler = OpLoad %type_sampler %uniform_sampler
2088 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2089 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
2090 )";
2091
2092 CompileSuccessfully(GenerateShaderCode(body).c_str());
2093 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2094 EXPECT_THAT(getDiagnosticString(),
2095 HasSubstr("Expected Image 'MS' parameter to be 0"));
2096 }
2097
TEST_F(ValidateImage,SampleProjImplicitLodWrongSampledType)2098 TEST_F(ValidateImage, SampleProjImplicitLodWrongSampledType) {
2099 const std::string body = R"(
2100 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2101 %sampler = OpLoad %type_sampler %uniform_sampler
2102 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2103 %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
2104 )";
2105
2106 CompileSuccessfully(GenerateShaderCode(body).c_str());
2107 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2108 EXPECT_THAT(getDiagnosticString(),
2109 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2110 "Result Type components"));
2111 }
2112
TEST_F(ValidateImage,SampleProjImplicitLodVoidSampledType)2113 TEST_F(ValidateImage, SampleProjImplicitLodVoidSampledType) {
2114 const std::string body = R"(
2115 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2116 %sampler = OpLoad %type_sampler %uniform_sampler
2117 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2118 %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
2119 )";
2120
2121 CompileSuccessfully(GenerateShaderCode(body).c_str());
2122 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2123 }
2124
TEST_F(ValidateImage,SampleProjImplicitLodWrongCoordinateType)2125 TEST_F(ValidateImage, SampleProjImplicitLodWrongCoordinateType) {
2126 const std::string body = R"(
2127 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2128 %sampler = OpLoad %type_sampler %uniform_sampler
2129 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2130 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %img
2131 )";
2132
2133 CompileSuccessfully(GenerateShaderCode(body).c_str());
2134 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2135 EXPECT_THAT(getDiagnosticString(),
2136 HasSubstr("Expected Coordinate to be float scalar or vector"));
2137 }
2138
TEST_F(ValidateImage,SampleProjImplicitLodCoordinateSizeTooSmall)2139 TEST_F(ValidateImage, SampleProjImplicitLodCoordinateSizeTooSmall) {
2140 const std::string body = R"(
2141 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2142 %sampler = OpLoad %type_sampler %uniform_sampler
2143 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2144 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh
2145 )";
2146
2147 CompileSuccessfully(GenerateShaderCode(body).c_str());
2148 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2149 EXPECT_THAT(getDiagnosticString(),
2150 HasSubstr("Expected Coordinate to have at least 3 components, "
2151 "but given only 2"));
2152 }
2153
TEST_F(ValidateImage,SampleDrefImplicitLodSuccess)2154 TEST_F(ValidateImage, SampleDrefImplicitLodSuccess) {
2155 const std::string body = R"(
2156 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2157 %sampler = OpLoad %type_sampler %uniform_sampler
2158 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2159 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1
2160 %res2 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
2161 %res4 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
2162 %res5 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
2163 %res6 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
2164 %res7 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2165 %res8 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
2166 )";
2167
2168 const std::string extra = R"(
2169 OpCapability VulkanMemoryModelKHR
2170 OpExtension "SPV_KHR_vulkan_memory_model"
2171 )";
2172 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2173 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2174 .c_str());
2175 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2176 }
2177
TEST_F(ValidateImage,SampleDrefImplicitLodWrongResultType)2178 TEST_F(ValidateImage, SampleDrefImplicitLodWrongResultType) {
2179 const std::string body = R"(
2180 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2181 %sampler = OpLoad %type_sampler %uniform_sampler
2182 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2183 %res1 = OpImageSampleDrefImplicitLod %void %simg %f32vec2_hh %u32_1
2184 )";
2185
2186 CompileSuccessfully(GenerateShaderCode(body).c_str());
2187 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2188 EXPECT_THAT(getDiagnosticString(),
2189 HasSubstr("Expected Result Type to be int or float scalar type"));
2190 }
2191
TEST_F(ValidateImage,SampleDrefImplicitLodNotSampledImage)2192 TEST_F(ValidateImage, SampleDrefImplicitLodNotSampledImage) {
2193 const std::string body = R"(
2194 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2195 %res1 = OpImageSampleDrefImplicitLod %u32 %img %f32vec2_hh %u32_1
2196 )";
2197
2198 CompileSuccessfully(GenerateShaderCode(body).c_str());
2199 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2200 EXPECT_THAT(
2201 getDiagnosticString(),
2202 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2203 }
2204
TEST_F(ValidateImage,SampleDrefImplicitLodMultisampleError)2205 TEST_F(ValidateImage, SampleDrefImplicitLodMultisampleError) {
2206 const std::string body = R"(
2207 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2208 %sampler = OpLoad %type_sampler %uniform_sampler
2209 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2210 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
2211 )";
2212
2213 CompileSuccessfully(GenerateShaderCode(body).c_str());
2214 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2215 EXPECT_THAT(
2216 getDiagnosticString(),
2217 HasSubstr("Dref sampling operation is invalid for multisample image"));
2218 }
2219
TEST_F(ValidateImage,SampleDrefImplicitLodWrongSampledType)2220 TEST_F(ValidateImage, SampleDrefImplicitLodWrongSampledType) {
2221 const std::string body = R"(
2222 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2223 %sampler = OpLoad %type_sampler %uniform_sampler
2224 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2225 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_00 %u32_1
2226 )";
2227
2228 CompileSuccessfully(GenerateShaderCode(body).c_str());
2229 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2230 EXPECT_THAT(
2231 getDiagnosticString(),
2232 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2233 }
2234
TEST_F(ValidateImage,SampleDrefImplicitLodVoidSampledType)2235 TEST_F(ValidateImage, SampleDrefImplicitLodVoidSampledType) {
2236 const std::string body = R"(
2237 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2238 %sampler = OpLoad %type_sampler %uniform_sampler
2239 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2240 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %u32_1
2241 )";
2242
2243 CompileSuccessfully(GenerateShaderCode(body).c_str());
2244 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2245 EXPECT_THAT(
2246 getDiagnosticString(),
2247 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2248 }
2249
TEST_F(ValidateImage,SampleDrefImplicitLodWrongCoordinateType)2250 TEST_F(ValidateImage, SampleDrefImplicitLodWrongCoordinateType) {
2251 const std::string body = R"(
2252 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2253 %sampler = OpLoad %type_sampler %uniform_sampler
2254 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2255 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %img %u32_1
2256 )";
2257
2258 CompileSuccessfully(GenerateShaderCode(body).c_str());
2259 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2260 EXPECT_THAT(getDiagnosticString(),
2261 HasSubstr("Expected Coordinate to be float scalar or vector"));
2262 }
2263
TEST_F(ValidateImage,SampleDrefImplicitLodCoordinateSizeTooSmall)2264 TEST_F(ValidateImage, SampleDrefImplicitLodCoordinateSizeTooSmall) {
2265 const std::string body = R"(
2266 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2267 %sampler = OpLoad %type_sampler %uniform_sampler
2268 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2269 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32_0_5 %f32_0_5
2270 )";
2271
2272 CompileSuccessfully(GenerateShaderCode(body).c_str());
2273 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2274 EXPECT_THAT(getDiagnosticString(),
2275 HasSubstr("Expected Coordinate to have at least 2 components, "
2276 "but given only 1"));
2277 }
2278
TEST_F(ValidateImage,SampleDrefImplicitLodWrongDrefType)2279 TEST_F(ValidateImage, SampleDrefImplicitLodWrongDrefType) {
2280 const std::string body = R"(
2281 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2282 %sampler = OpLoad %type_sampler %uniform_sampler
2283 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2284 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %f64_1
2285 )";
2286
2287 CompileSuccessfully(GenerateShaderCode(body).c_str());
2288 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2289 EXPECT_THAT(getDiagnosticString(),
2290 HasSubstr("Expected Dref to be of 32-bit float type"));
2291 }
2292
TEST_F(ValidateImage,SampleDrefExplicitLodSuccess)2293 TEST_F(ValidateImage, SampleDrefExplicitLodSuccess) {
2294 const std::string body = R"(
2295 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2296 %sampler = OpLoad %type_sampler %uniform_sampler
2297 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2298 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod %f32_1
2299 %res3 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad %f32vec3_hhh %f32vec3_hhh
2300 %res4 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 ConstOffset %s32vec3_012
2301 %res5 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Offset %s32vec3_012
2302 %res7 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad|Offset %f32vec3_hhh %f32vec3_hhh %s32vec3_012
2303 %res8 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod|NonPrivateTexelKHR %f32_1
2304 )";
2305
2306 const std::string extra = R"(
2307 OpCapability VulkanMemoryModelKHR
2308 OpExtension "SPV_KHR_vulkan_memory_model"
2309 )";
2310 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2311 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2312 .c_str());
2313 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2314 }
2315
TEST_F(ValidateImage,SampleDrefExplicitLodWrongResultType)2316 TEST_F(ValidateImage, SampleDrefExplicitLodWrongResultType) {
2317 const std::string body = R"(
2318 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2319 %sampler = OpLoad %type_sampler %uniform_sampler
2320 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2321 %res1 = OpImageSampleDrefExplicitLod %bool %simg %f32vec3_hhh %s32_1 Lod %f32_1
2322 )";
2323
2324 CompileSuccessfully(GenerateShaderCode(body).c_str());
2325 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2326 EXPECT_THAT(getDiagnosticString(),
2327 HasSubstr("Expected Result Type to be int or float scalar type"));
2328 }
2329
TEST_F(ValidateImage,SampleDrefExplicitLodNotSampledImage)2330 TEST_F(ValidateImage, SampleDrefExplicitLodNotSampledImage) {
2331 const std::string body = R"(
2332 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2333 %res1 = OpImageSampleDrefExplicitLod %s32 %img %f32vec3_hhh %s32_1 Lod %f32_1
2334 )";
2335
2336 CompileSuccessfully(GenerateShaderCode(body).c_str());
2337 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2338 EXPECT_THAT(
2339 getDiagnosticString(),
2340 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2341 }
2342
TEST_F(ValidateImage,SampleDrefExplicitLodMultisampleError)2343 TEST_F(ValidateImage, SampleDrefExplicitLodMultisampleError) {
2344 const std::string body = R"(
2345 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2346 %sampler = OpLoad %type_sampler %uniform_sampler
2347 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2348 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
2349 )";
2350
2351 CompileSuccessfully(GenerateShaderCode(body).c_str());
2352 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2353 EXPECT_THAT(
2354 getDiagnosticString(),
2355 HasSubstr("Dref sampling operation is invalid for multisample image"));
2356 }
2357
TEST_F(ValidateImage,SampleDrefExplicitLodWrongSampledType)2358 TEST_F(ValidateImage, SampleDrefExplicitLodWrongSampledType) {
2359 const std::string body = R"(
2360 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2361 %sampler = OpLoad %type_sampler %uniform_sampler
2362 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2363 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec3_hhh %s32_1 Lod %f32_1
2364 )";
2365
2366 CompileSuccessfully(GenerateShaderCode(body).c_str());
2367 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2368 EXPECT_THAT(
2369 getDiagnosticString(),
2370 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2371 }
2372
TEST_F(ValidateImage,SampleDrefExplicitLodVoidSampledType)2373 TEST_F(ValidateImage, SampleDrefExplicitLodVoidSampledType) {
2374 const std::string body = R"(
2375 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2376 %sampler = OpLoad %type_sampler %uniform_sampler
2377 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2378 %res1 = OpImageSampleDrefExplicitLod %u32 %simg %f32vec2_00 %s32_1 Lod %f32_1
2379 )";
2380
2381 CompileSuccessfully(GenerateShaderCode(body).c_str());
2382 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2383 EXPECT_THAT(
2384 getDiagnosticString(),
2385 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2386 }
2387
TEST_F(ValidateImage,SampleDrefExplicitLodWrongCoordinateType)2388 TEST_F(ValidateImage, SampleDrefExplicitLodWrongCoordinateType) {
2389 const std::string body = R"(
2390 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2391 %sampler = OpLoad %type_sampler %uniform_sampler
2392 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2393 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %img %s32_1 Lod %f32_1
2394 )";
2395
2396 CompileSuccessfully(GenerateShaderCode(body).c_str());
2397 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2398 EXPECT_THAT(getDiagnosticString(),
2399 HasSubstr("Expected Coordinate to be float scalar or vector"));
2400 }
2401
TEST_F(ValidateImage,SampleDrefExplicitLodCoordinateSizeTooSmall)2402 TEST_F(ValidateImage, SampleDrefExplicitLodCoordinateSizeTooSmall) {
2403 const std::string body = R"(
2404 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2405 %sampler = OpLoad %type_sampler %uniform_sampler
2406 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2407 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec2_hh %s32_1 Lod %f32_1
2408 )";
2409
2410 CompileSuccessfully(GenerateShaderCode(body).c_str());
2411 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2412 EXPECT_THAT(getDiagnosticString(),
2413 HasSubstr("Expected Coordinate to have at least 3 components, "
2414 "but given only 2"));
2415 }
2416
TEST_F(ValidateImage,SampleDrefExplicitLodWrongDrefType)2417 TEST_F(ValidateImage, SampleDrefExplicitLodWrongDrefType) {
2418 const std::string body = R"(
2419 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2420 %sampler = OpLoad %type_sampler %uniform_sampler
2421 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2422 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %u32_1 Lod %f32_1
2423 )";
2424
2425 CompileSuccessfully(GenerateShaderCode(body).c_str());
2426 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2427 EXPECT_THAT(getDiagnosticString(),
2428 HasSubstr("Expected Dref to be of 32-bit float type"));
2429 }
2430
TEST_F(ValidateImage,SampleProjDrefImplicitLodSuccess)2431 TEST_F(ValidateImage, SampleProjDrefImplicitLodSuccess) {
2432 const std::string body = R"(
2433 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2434 %sampler = OpLoad %type_sampler %uniform_sampler
2435 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2436 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5
2437 %res2 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias %f32_0_25
2438 %res4 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 ConstOffset %s32vec2_01
2439 %res5 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Offset %s32vec2_01
2440 %res6 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 MinLod %f32_0_5
2441 %res7 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2442 %res8 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 NonPrivateTexelKHR
2443 )";
2444
2445 const std::string extra = R"(
2446 OpCapability VulkanMemoryModelKHR
2447 OpExtension "SPV_KHR_vulkan_memory_model"
2448 )";
2449 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2450 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2451 .c_str());
2452 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2453 }
2454
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongResultType)2455 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongResultType) {
2456 const std::string body = R"(
2457 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2458 %sampler = OpLoad %type_sampler %uniform_sampler
2459 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2460 %res1 = OpImageSampleProjDrefImplicitLod %void %simg %f32vec3_hhh %f32_0_5
2461 )";
2462
2463 CompileSuccessfully(GenerateShaderCode(body).c_str());
2464 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2465 EXPECT_THAT(getDiagnosticString(),
2466 HasSubstr("Expected Result Type to be int or float scalar type"));
2467 }
2468
TEST_F(ValidateImage,SampleProjDrefImplicitLodNotSampledImage)2469 TEST_F(ValidateImage, SampleProjDrefImplicitLodNotSampledImage) {
2470 const std::string body = R"(
2471 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2472 %res1 = OpImageSampleProjDrefImplicitLod %f32 %img %f32vec3_hhh %f32_0_5
2473 )";
2474
2475 CompileSuccessfully(GenerateShaderCode(body).c_str());
2476 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2477 EXPECT_THAT(
2478 getDiagnosticString(),
2479 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2480 }
2481
TEST_F(ValidateImage,SampleProjDrefImplicitLodMultisampleError)2482 TEST_F(ValidateImage, SampleProjDrefImplicitLodMultisampleError) {
2483 const std::string body = R"(
2484 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2485 %sampler = OpLoad %type_sampler %uniform_sampler
2486 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2487 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
2488 )";
2489
2490 CompileSuccessfully(GenerateShaderCode(body).c_str());
2491 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2492 EXPECT_THAT(
2493 getDiagnosticString(),
2494 HasSubstr("Dref sampling operation is invalid for multisample image"));
2495 }
2496
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongSampledType)2497 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongSampledType) {
2498 const std::string body = R"(
2499 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2500 %sampler = OpLoad %type_sampler %uniform_sampler
2501 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2502 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2503 )";
2504
2505 CompileSuccessfully(GenerateShaderCode(body).c_str());
2506 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2507 EXPECT_THAT(
2508 getDiagnosticString(),
2509 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2510 }
2511
TEST_F(ValidateImage,SampleProjDrefImplicitLodVoidSampledType)2512 TEST_F(ValidateImage, SampleProjDrefImplicitLodVoidSampledType) {
2513 const std::string body = R"(
2514 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2515 %sampler = OpLoad %type_sampler %uniform_sampler
2516 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2517 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2518 )";
2519
2520 CompileSuccessfully(GenerateShaderCode(body).c_str());
2521 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2522 EXPECT_THAT(
2523 getDiagnosticString(),
2524 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2525 }
2526
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongCoordinateType)2527 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongCoordinateType) {
2528 const std::string body = R"(
2529 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2530 %sampler = OpLoad %type_sampler %uniform_sampler
2531 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2532 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %img %f32_0_5
2533 )";
2534
2535 CompileSuccessfully(GenerateShaderCode(body).c_str());
2536 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2537 EXPECT_THAT(getDiagnosticString(),
2538 HasSubstr("Expected Coordinate to be float scalar or vector"));
2539 }
2540
TEST_F(ValidateImage,SampleProjDrefImplicitLodCoordinateSizeTooSmall)2541 TEST_F(ValidateImage, SampleProjDrefImplicitLodCoordinateSizeTooSmall) {
2542 const std::string body = R"(
2543 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2544 %sampler = OpLoad %type_sampler %uniform_sampler
2545 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2546 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec2_hh %f32_0_5
2547 )";
2548
2549 CompileSuccessfully(GenerateShaderCode(body).c_str());
2550 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2551 EXPECT_THAT(getDiagnosticString(),
2552 HasSubstr("Expected Coordinate to have at least 3 components, "
2553 "but given only 2"));
2554 }
2555
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongDrefType)2556 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongDrefType) {
2557 const std::string body = R"(
2558 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2559 %sampler = OpLoad %type_sampler %uniform_sampler
2560 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2561 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32vec4_0000
2562 )";
2563
2564 CompileSuccessfully(GenerateShaderCode(body).c_str());
2565 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2566 EXPECT_THAT(getDiagnosticString(),
2567 HasSubstr("Expected Dref to be of 32-bit float type"));
2568 }
2569
TEST_F(ValidateImage,SampleProjDrefExplicitLodSuccess)2570 TEST_F(ValidateImage, SampleProjDrefExplicitLodSuccess) {
2571 const std::string body = R"(
2572 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2573 %sampler = OpLoad %type_sampler %uniform_sampler
2574 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2575 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2576 %res2 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Grad %f32_0_5 %f32_0_5
2577 %res3 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 ConstOffset %s32_1
2578 %res4 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Offset %s32_1
2579 %res5 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Grad|Offset %f32_0_5 %f32_0_5 %s32_1
2580 %res6 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod|NonPrivateTexelKHR %f32_1
2581 )";
2582
2583 const std::string extra = R"(
2584 OpCapability VulkanMemoryModelKHR
2585 OpExtension "SPV_KHR_vulkan_memory_model"
2586 )";
2587 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2588 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2589 .c_str());
2590 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2591 }
2592
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongResultType)2593 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongResultType) {
2594 const std::string body = R"(
2595 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2596 %sampler = OpLoad %type_sampler %uniform_sampler
2597 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2598 %res1 = OpImageSampleProjDrefExplicitLod %bool %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2599 )";
2600
2601 CompileSuccessfully(GenerateShaderCode(body).c_str());
2602 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2603 EXPECT_THAT(getDiagnosticString(),
2604 HasSubstr("Expected Result Type to be int or float scalar type"));
2605 }
2606
TEST_F(ValidateImage,SampleProjDrefExplicitLodNotSampledImage)2607 TEST_F(ValidateImage, SampleProjDrefExplicitLodNotSampledImage) {
2608 const std::string body = R"(
2609 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2610 %res1 = OpImageSampleProjDrefExplicitLod %f32 %img %f32vec2_hh %f32_0_5 Lod %f32_1
2611 )";
2612
2613 CompileSuccessfully(GenerateShaderCode(body).c_str());
2614 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2615 EXPECT_THAT(
2616 getDiagnosticString(),
2617 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2618 }
2619
TEST_F(ValidateImage,SampleProjDrefExplicitLodMultisampleError)2620 TEST_F(ValidateImage, SampleProjDrefExplicitLodMultisampleError) {
2621 const std::string body = R"(
2622 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2623 %sampler = OpLoad %type_sampler %uniform_sampler
2624 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2625 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
2626 )";
2627
2628 CompileSuccessfully(GenerateShaderCode(body).c_str());
2629 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2630 EXPECT_THAT(
2631 getDiagnosticString(),
2632 HasSubstr("Dref sampling operation is invalid for multisample image"));
2633 }
2634
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongSampledType)2635 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongSampledType) {
2636 const std::string body = R"(
2637 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2638 %sampler = OpLoad %type_sampler %uniform_sampler
2639 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2640 %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2641 )";
2642
2643 CompileSuccessfully(GenerateShaderCode(body).c_str());
2644 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2645 EXPECT_THAT(
2646 getDiagnosticString(),
2647 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2648 }
2649
TEST_F(ValidateImage,SampleProjDrefExplicitLodVoidSampledType)2650 TEST_F(ValidateImage, SampleProjDrefExplicitLodVoidSampledType) {
2651 const std::string body = R"(
2652 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2653 %sampler = OpLoad %type_sampler %uniform_sampler
2654 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2655 %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec3_hhh %f32_0_5 Lod %f32_1
2656 )";
2657
2658 CompileSuccessfully(GenerateShaderCode(body).c_str());
2659 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2660 EXPECT_THAT(
2661 getDiagnosticString(),
2662 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2663 }
2664
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongCoordinateType)2665 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongCoordinateType) {
2666 const std::string body = R"(
2667 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2668 %sampler = OpLoad %type_sampler %uniform_sampler
2669 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2670 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %img %f32_0_5 Lod %f32_1
2671 )";
2672
2673 CompileSuccessfully(GenerateShaderCode(body).c_str());
2674 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2675 EXPECT_THAT(getDiagnosticString(),
2676 HasSubstr("Expected Coordinate to be float scalar or vector"));
2677 }
2678
TEST_F(ValidateImage,SampleProjDrefExplicitLodCoordinateSizeTooSmall)2679 TEST_F(ValidateImage, SampleProjDrefExplicitLodCoordinateSizeTooSmall) {
2680 const std::string body = R"(
2681 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2682 %sampler = OpLoad %type_sampler %uniform_sampler
2683 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2684 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32_0_5 %f32_0_5 Lod %f32_1
2685 )";
2686
2687 CompileSuccessfully(GenerateShaderCode(body).c_str());
2688 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2689 EXPECT_THAT(getDiagnosticString(),
2690 HasSubstr("Expected Coordinate to have at least 2 components, "
2691 "but given only 1"));
2692 }
2693
TEST_F(ValidateImage,FetchSuccess)2694 TEST_F(ValidateImage, FetchSuccess) {
2695 const std::string body = R"(
2696 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2697 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
2698 %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
2699 )";
2700
2701 const std::string extra = R"(
2702 OpCapability VulkanMemoryModelKHR
2703 OpExtension "SPV_KHR_vulkan_memory_model"
2704 )";
2705 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2706 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2707 .c_str());
2708 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2709 }
2710
TEST_F(ValidateImage,FetchMultisampledSuccess)2711 TEST_F(ValidateImage, FetchMultisampledSuccess) {
2712 const std::string body = R"(
2713 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2714 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample %u32_1
2715 %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample|NonPrivateTexelKHR %u32_1
2716 )";
2717
2718 const std::string extra = R"(
2719 OpCapability VulkanMemoryModelKHR
2720 OpExtension "SPV_KHR_vulkan_memory_model"
2721 )";
2722 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2723 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2724 .c_str());
2725 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2726 }
2727
TEST_F(ValidateImage,FetchWrongResultType)2728 TEST_F(ValidateImage, FetchWrongResultType) {
2729 const std::string body = R"(
2730 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2731 %res1 = OpImageFetch %f32 %img %u32vec2_01
2732 )";
2733
2734 CompileSuccessfully(GenerateShaderCode(body).c_str());
2735 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2736 EXPECT_THAT(getDiagnosticString(),
2737 HasSubstr("Expected Result Type to be int or float vector type"));
2738 }
2739
TEST_F(ValidateImage,FetchWrongNumComponentsResultType)2740 TEST_F(ValidateImage, FetchWrongNumComponentsResultType) {
2741 const std::string body = R"(
2742 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2743 %res1 = OpImageFetch %f32vec3 %img %u32vec2_01
2744 )";
2745
2746 CompileSuccessfully(GenerateShaderCode(body).c_str());
2747 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2748 EXPECT_THAT(getDiagnosticString(),
2749 HasSubstr("Expected Result Type to have 4 components"));
2750 }
2751
TEST_F(ValidateImage,FetchNotImage)2752 TEST_F(ValidateImage, FetchNotImage) {
2753 const std::string body = R"(
2754 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2755 %sampler = OpLoad %type_sampler %uniform_sampler
2756 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2757 %res1 = OpImageFetch %f32vec4 %sampler %u32vec2_01
2758 )";
2759
2760 CompileSuccessfully(GenerateShaderCode(body).c_str());
2761 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2762 EXPECT_THAT(getDiagnosticString(),
2763 HasSubstr("Expected Image to be of type OpTypeImage"));
2764 }
2765
TEST_F(ValidateImage,FetchSampledImageDirectly)2766 TEST_F(ValidateImage, FetchSampledImageDirectly) {
2767 const std::string body = R"(
2768 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2769 %sampler = OpLoad %type_sampler %uniform_sampler
2770 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2771 %res1 = OpImageFetch %f32vec4 %simg %u32vec2_01
2772 )";
2773
2774 CompileSuccessfully(GenerateShaderCode(body).c_str());
2775 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
2776 EXPECT_THAT(getDiagnosticString(),
2777 HasSubstr("OpSampledImage instruction must not appear as operand "
2778 "for OpImageFetch"));
2779 }
2780
TEST_F(ValidateImage,FetchNotSampled)2781 TEST_F(ValidateImage, FetchNotSampled) {
2782 const std::string body = R"(
2783 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
2784 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
2785 )";
2786
2787 CompileSuccessfully(GenerateShaderCode(body).c_str());
2788 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2789 EXPECT_THAT(getDiagnosticString(),
2790 HasSubstr("Expected Image 'Sampled' parameter to be 1"));
2791 }
2792
TEST_F(ValidateImage,FetchCube)2793 TEST_F(ValidateImage, FetchCube) {
2794 const std::string body = R"(
2795 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2796 %res1 = OpImageFetch %f32vec4 %img %u32vec3_012
2797 )";
2798
2799 CompileSuccessfully(GenerateShaderCode(body).c_str());
2800 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2801 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' cannot be Cube"));
2802 }
2803
TEST_F(ValidateImage,FetchWrongSampledType)2804 TEST_F(ValidateImage, FetchWrongSampledType) {
2805 const std::string body = R"(
2806 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2807 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
2808 )";
2809
2810 CompileSuccessfully(GenerateShaderCode(body).c_str());
2811 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2812 EXPECT_THAT(getDiagnosticString(),
2813 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2814 "Result Type components"));
2815 }
2816
TEST_F(ValidateImage,FetchVoidSampledType)2817 TEST_F(ValidateImage, FetchVoidSampledType) {
2818 const std::string body = R"(
2819 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2820 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
2821 %res2 = OpImageFetch %u32vec4 %img %u32vec2_01
2822 %res3 = OpImageFetch %s32vec4 %img %u32vec2_01
2823 )";
2824
2825 CompileSuccessfully(GenerateShaderCode(body).c_str());
2826 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2827 }
2828
TEST_F(ValidateImage,FetchWrongCoordinateType)2829 TEST_F(ValidateImage, FetchWrongCoordinateType) {
2830 const std::string body = R"(
2831 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2832 %res1 = OpImageFetch %f32vec4 %img %f32vec2_00
2833 )";
2834
2835 CompileSuccessfully(GenerateShaderCode(body).c_str());
2836 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2837 EXPECT_THAT(getDiagnosticString(),
2838 HasSubstr("Expected Coordinate to be int scalar or vector"));
2839 }
2840
TEST_F(ValidateImage,FetchCoordinateSizeTooSmall)2841 TEST_F(ValidateImage, FetchCoordinateSizeTooSmall) {
2842 const std::string body = R"(
2843 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2844 %res1 = OpImageFetch %f32vec4 %img %u32_1
2845 )";
2846
2847 CompileSuccessfully(GenerateShaderCode(body).c_str());
2848 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2849 EXPECT_THAT(getDiagnosticString(),
2850 HasSubstr("Expected Coordinate to have at least 2 components, "
2851 "but given only 1"));
2852 }
2853
TEST_F(ValidateImage,FetchLodNotInt)2854 TEST_F(ValidateImage, FetchLodNotInt) {
2855 const std::string body = R"(
2856 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2857 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Lod %f32_1
2858 )";
2859
2860 CompileSuccessfully(GenerateShaderCode(body).c_str());
2861 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2862 EXPECT_THAT(getDiagnosticString(),
2863 HasSubstr("Expected Image Operand Lod to be int scalar when used "
2864 "with OpImageFetch"));
2865 }
2866
TEST_F(ValidateImage,FetchMultisampledMissingSample)2867 TEST_F(ValidateImage, FetchMultisampledMissingSample) {
2868 const std::string body = R"(
2869 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2870 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
2871 )";
2872
2873 CompileSuccessfully(GenerateShaderCode(body).c_str());
2874 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions())
2875 << GenerateShaderCode(body);
2876 EXPECT_THAT(getDiagnosticString(),
2877 HasSubstr("Image Operand Sample is required for operation on "
2878 "multi-sampled image"))
2879 << getDiagnosticString();
2880 }
2881
TEST_F(ValidateImage,GatherSuccess)2882 TEST_F(ValidateImage, GatherSuccess) {
2883 const std::string body = R"(
2884 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2885 %sampler = OpLoad %type_sampler %uniform_sampler
2886 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2887 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1
2888 %res2 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
2889 %res3 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
2890 )";
2891
2892 const std::string extra = R"(
2893 OpCapability VulkanMemoryModelKHR
2894 OpExtension "SPV_KHR_vulkan_memory_model"
2895 )";
2896 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2897 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2898 .c_str());
2899 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2900 }
2901
TEST_F(ValidateImage,GatherWrongResultType)2902 TEST_F(ValidateImage, GatherWrongResultType) {
2903 const std::string body = R"(
2904 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2905 %sampler = OpLoad %type_sampler %uniform_sampler
2906 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2907 %res1 = OpImageGather %f32 %simg %f32vec4_0000 %u32_1
2908 )";
2909
2910 CompileSuccessfully(GenerateShaderCode(body).c_str());
2911 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2912 EXPECT_THAT(getDiagnosticString(),
2913 HasSubstr("Expected Result Type to be int or float vector type"));
2914 }
2915
TEST_F(ValidateImage,GatherWrongNumComponentsResultType)2916 TEST_F(ValidateImage, GatherWrongNumComponentsResultType) {
2917 const std::string body = R"(
2918 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2919 %sampler = OpLoad %type_sampler %uniform_sampler
2920 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2921 %res1 = OpImageGather %f32vec3 %simg %f32vec4_0000 %u32_1
2922 )";
2923
2924 CompileSuccessfully(GenerateShaderCode(body).c_str());
2925 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2926 EXPECT_THAT(getDiagnosticString(),
2927 HasSubstr("Expected Result Type to have 4 components"));
2928 }
2929
TEST_F(ValidateImage,GatherNotSampledImage)2930 TEST_F(ValidateImage, GatherNotSampledImage) {
2931 const std::string body = R"(
2932 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2933 %res1 = OpImageGather %f32vec4 %img %f32vec4_0000 %u32_1
2934 )";
2935
2936 CompileSuccessfully(GenerateShaderCode(body).c_str());
2937 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2938 EXPECT_THAT(
2939 getDiagnosticString(),
2940 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2941 }
2942
TEST_F(ValidateImage,GatherMultisampleError)2943 TEST_F(ValidateImage, GatherMultisampleError) {
2944 const std::string body = R"(
2945 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2946 %sampler = OpLoad %type_sampler %uniform_sampler
2947 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2948 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Sample %u32_1
2949 )";
2950
2951 CompileSuccessfully(GenerateShaderCode(body).c_str());
2952 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2953 EXPECT_THAT(getDiagnosticString(),
2954 HasSubstr("Gather operation is invalid for multisample image"));
2955 }
2956
TEST_F(ValidateImage,GatherWrongSampledType)2957 TEST_F(ValidateImage, GatherWrongSampledType) {
2958 const std::string body = R"(
2959 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2960 %sampler = OpLoad %type_sampler %uniform_sampler
2961 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2962 %res1 = OpImageGather %u32vec4 %simg %f32vec4_0000 %u32_1
2963 )";
2964
2965 CompileSuccessfully(GenerateShaderCode(body).c_str());
2966 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2967 EXPECT_THAT(getDiagnosticString(),
2968 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2969 "Result Type components"));
2970 }
2971
TEST_F(ValidateImage,GatherVoidSampledType)2972 TEST_F(ValidateImage, GatherVoidSampledType) {
2973 const std::string body = R"(
2974 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2975 %sampler = OpLoad %type_sampler %uniform_sampler
2976 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2977 %res1 = OpImageGather %u32vec4 %simg %f32vec2_00 %u32_1
2978 )";
2979
2980 CompileSuccessfully(GenerateShaderCode(body).c_str());
2981 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2982 }
2983
TEST_F(ValidateImage,GatherWrongCoordinateType)2984 TEST_F(ValidateImage, GatherWrongCoordinateType) {
2985 const std::string body = R"(
2986 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2987 %sampler = OpLoad %type_sampler %uniform_sampler
2988 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2989 %res1 = OpImageGather %f32vec4 %simg %u32vec4_0123 %u32_1
2990 )";
2991
2992 CompileSuccessfully(GenerateShaderCode(body).c_str());
2993 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2994 EXPECT_THAT(getDiagnosticString(),
2995 HasSubstr("Expected Coordinate to be float scalar or vector"));
2996 }
2997
TEST_F(ValidateImage,GatherCoordinateSizeTooSmall)2998 TEST_F(ValidateImage, GatherCoordinateSizeTooSmall) {
2999 const std::string body = R"(
3000 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3001 %sampler = OpLoad %type_sampler %uniform_sampler
3002 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3003 %res1 = OpImageGather %f32vec4 %simg %f32_0_5 %u32_1
3004 )";
3005
3006 CompileSuccessfully(GenerateShaderCode(body).c_str());
3007 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3008 EXPECT_THAT(getDiagnosticString(),
3009 HasSubstr("Expected Coordinate to have at least 4 components, "
3010 "but given only 1"));
3011 }
3012
TEST_F(ValidateImage,GatherWrongComponentType)3013 TEST_F(ValidateImage, GatherWrongComponentType) {
3014 const std::string body = R"(
3015 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3016 %sampler = OpLoad %type_sampler %uniform_sampler
3017 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3018 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %f32_1
3019 )";
3020
3021 CompileSuccessfully(GenerateShaderCode(body).c_str());
3022 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3023 EXPECT_THAT(getDiagnosticString(),
3024 HasSubstr("Expected Component to be 32-bit int scalar"));
3025 }
3026
TEST_F(ValidateImage,GatherComponentNot32Bit)3027 TEST_F(ValidateImage, GatherComponentNot32Bit) {
3028 const std::string body = R"(
3029 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3030 %sampler = OpLoad %type_sampler %uniform_sampler
3031 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3032 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u64_0
3033 )";
3034
3035 CompileSuccessfully(GenerateShaderCode(body).c_str());
3036 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3037 EXPECT_THAT(getDiagnosticString(),
3038 HasSubstr("Expected Component to be 32-bit int scalar"));
3039 }
3040
TEST_F(ValidateImage,GatherComponentSuccessVulkan)3041 TEST_F(ValidateImage, GatherComponentSuccessVulkan) {
3042 const std::string body = R"(
3043 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3044 %sampler = OpLoad %type_sampler %uniform_sampler
3045 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3046 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_0
3047 )";
3048
3049 spv_target_env env = SPV_ENV_VULKAN_1_0;
3050 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3051 env);
3052 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
3053 }
3054
TEST_F(ValidateImage,GatherComponentNotConstantVulkan)3055 TEST_F(ValidateImage, GatherComponentNotConstantVulkan) {
3056 const std::string body = R"(
3057 %input_u32 = OpLoad %u32 %input_flat_u32
3058 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3059 %sampler = OpLoad %type_sampler %uniform_sampler
3060 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3061 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %input_u32
3062 )";
3063
3064 spv_target_env env = SPV_ENV_VULKAN_1_0;
3065 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3066 env);
3067 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3068 EXPECT_THAT(getDiagnosticString(),
3069 AnyVUID("VUID-StandaloneSpirv-OpImageGather-04664"));
3070 EXPECT_THAT(getDiagnosticString(),
3071 HasSubstr("Expected Component Operand to be a const object for "
3072 "Vulkan environment"));
3073 }
3074
TEST_F(ValidateImage,GatherDimCube)3075 TEST_F(ValidateImage, GatherDimCube) {
3076 const std::string body = R"(
3077 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3078 %sampler = OpLoad %type_sampler %uniform_sampler
3079 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3080 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
3081 )";
3082
3083 CompileSuccessfully(GenerateShaderCode(body).c_str());
3084 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3085 EXPECT_THAT(
3086 getDiagnosticString(),
3087 HasSubstr(
3088 "Image Operand ConstOffsets cannot be used with Cube Image 'Dim'"));
3089 }
3090
TEST_F(ValidateImage,GatherConstOffsetsNotArray)3091 TEST_F(ValidateImage, GatherConstOffsetsNotArray) {
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 %u32vec4_0123
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,GatherConstOffsetsArrayWrongSize)3107 TEST_F(ValidateImage, GatherConstOffsetsArrayWrongSize) {
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_offsets3x2
3113 )";
3114
3115 CompileSuccessfully(GenerateShaderCode(body).c_str());
3116 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3117 EXPECT_THAT(
3118 getDiagnosticString(),
3119 HasSubstr(
3120 "Expected Image Operand ConstOffsets to be an array of size 4"));
3121 }
3122
TEST_F(ValidateImage,GatherConstOffsetsArrayNotVector)3123 TEST_F(ValidateImage, GatherConstOffsetsArrayNotVector) {
3124 const std::string body = R"(
3125 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3126 %sampler = OpLoad %type_sampler %uniform_sampler
3127 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3128 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4xu
3129 )";
3130
3131 CompileSuccessfully(GenerateShaderCode(body).c_str());
3132 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3133 EXPECT_THAT(getDiagnosticString(),
3134 HasSubstr("Expected Image Operand ConstOffsets array componenets "
3135 "to be int vectors of size 2"));
3136 }
3137
TEST_F(ValidateImage,GatherConstOffsetsArrayVectorWrongSize)3138 TEST_F(ValidateImage, GatherConstOffsetsArrayVectorWrongSize) {
3139 const std::string body = R"(
3140 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3141 %sampler = OpLoad %type_sampler %uniform_sampler
3142 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3143 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4x3
3144 )";
3145
3146 CompileSuccessfully(GenerateShaderCode(body).c_str());
3147 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3148 EXPECT_THAT(getDiagnosticString(),
3149 HasSubstr("Expected Image Operand ConstOffsets array componenets "
3150 "to be int vectors of size 2"));
3151 }
3152
TEST_F(ValidateImage,GatherConstOffsetsArrayNotConst)3153 TEST_F(ValidateImage, GatherConstOffsetsArrayNotConst) {
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 %offsets = OpUndef %u32vec2arr4
3159 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %offsets
3160 )";
3161
3162 CompileSuccessfully(GenerateShaderCode(body).c_str());
3163 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3164 EXPECT_THAT(
3165 getDiagnosticString(),
3166 HasSubstr("Expected Image Operand ConstOffsets to be a const object"));
3167 }
3168
TEST_F(ValidateImage,NotGatherWithConstOffsets)3169 TEST_F(ValidateImage, NotGatherWithConstOffsets) {
3170 const std::string body = R"(
3171 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3172 %sampler = OpLoad %type_sampler %uniform_sampler
3173 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3174 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffsets %const_offsets
3175 )";
3176
3177 CompileSuccessfully(GenerateShaderCode(body).c_str());
3178 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3179 EXPECT_THAT(
3180 getDiagnosticString(),
3181 HasSubstr(
3182 "Image Operand ConstOffsets can only be used with OpImageGather "
3183 "and OpImageDrefGather"));
3184 }
3185
TEST_F(ValidateImage,DrefGatherSuccess)3186 TEST_F(ValidateImage, DrefGatherSuccess) {
3187 const std::string body = R"(
3188 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3189 %sampler = OpLoad %type_sampler %uniform_sampler
3190 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3191 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
3192 %res2 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 ConstOffsets %const_offsets
3193 %res3 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 NonPrivateTexelKHR
3194 )";
3195
3196 const std::string extra = R"(
3197 OpCapability VulkanMemoryModelKHR
3198 OpExtension "SPV_KHR_vulkan_memory_model"
3199 )";
3200 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3201 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3202 .c_str());
3203 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3204 }
3205
TEST_F(ValidateImage,DrefGatherMultisampleError)3206 TEST_F(ValidateImage, DrefGatherMultisampleError) {
3207 const std::string body = R"(
3208 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3209 %sampler = OpLoad %type_sampler %uniform_sampler
3210 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
3211 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_1 Sample %u32_1
3212 )";
3213
3214 CompileSuccessfully(GenerateShaderCode(body).c_str());
3215 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3216 EXPECT_THAT(getDiagnosticString(),
3217 HasSubstr("Gather operation is invalid for multisample image"));
3218 }
3219
TEST_F(ValidateImage,DrefGatherVoidSampledType)3220 TEST_F(ValidateImage, DrefGatherVoidSampledType) {
3221 const std::string body = R"(
3222 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3223 %sampler = OpLoad %type_sampler %uniform_sampler
3224 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
3225 %res1 = OpImageDrefGather %u32vec4 %simg %f32vec2_00 %f32_0_5
3226 )";
3227
3228 CompileSuccessfully(GenerateShaderCode(body).c_str());
3229 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3230 EXPECT_THAT(getDiagnosticString(),
3231 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3232 "Result Type components"));
3233 }
3234
TEST_F(ValidateImage,DrefGatherWrongDrefType)3235 TEST_F(ValidateImage, DrefGatherWrongDrefType) {
3236 const std::string body = R"(
3237 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3238 %sampler = OpLoad %type_sampler %uniform_sampler
3239 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3240 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %u32_1
3241 )";
3242
3243 CompileSuccessfully(GenerateShaderCode(body).c_str());
3244 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3245 EXPECT_THAT(getDiagnosticString(),
3246 HasSubstr("Expected Dref to be of 32-bit float type"));
3247 }
3248
TEST_F(ValidateImage,ReadSuccess1)3249 TEST_F(ValidateImage, ReadSuccess1) {
3250 const std::string body = R"(
3251 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3252 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
3253 )";
3254
3255 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3256 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3257 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3258 }
3259
TEST_F(ValidateImage,ReadSuccess2)3260 TEST_F(ValidateImage, ReadSuccess2) {
3261 const std::string body = R"(
3262 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3263 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3264 )";
3265
3266 const std::string extra = "\nOpCapability Image1D\n";
3267 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3268 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3269 }
3270
TEST_F(ValidateImage,ReadSuccess3)3271 TEST_F(ValidateImage, ReadSuccess3) {
3272 const std::string body = R"(
3273 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3274 %res1 = OpImageRead %f32vec4 %img %u32vec3_012
3275 )";
3276
3277 const std::string extra = "\nOpCapability ImageCubeArray\n";
3278 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3279 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3280 }
3281
TEST_F(ValidateImage,ReadSuccess4)3282 TEST_F(ValidateImage, ReadSuccess4) {
3283 const std::string body = R"(
3284 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3285 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3286 )";
3287
3288 CompileSuccessfully(GenerateShaderCode(body).c_str());
3289 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3290 }
3291
TEST_F(ValidateImage,ReadNeedCapabilityStorageImageReadWithoutFormat)3292 TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) {
3293 const std::string body = R"(
3294 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3295 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
3296 )";
3297
3298 CompileSuccessfully(GenerateShaderCode(body).c_str());
3299 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3300 }
3301
TEST_F(ValidateImage,ReadNeedCapabilityStorageImageReadWithoutFormatVulkan)3302 TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) {
3303 const std::string body = R"(
3304 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3305 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
3306 )";
3307
3308 spv_target_env env = SPV_ENV_VULKAN_1_0;
3309 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3310 env);
3311 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3312 EXPECT_THAT(getDiagnosticString(),
3313 HasSubstr("Capability StorageImageReadWithoutFormat is required "
3314 "to read storage image"));
3315 }
3316
TEST_F(ValidateImage,ReadNeedCapabilityImage1D)3317 TEST_F(ValidateImage, ReadNeedCapabilityImage1D) {
3318 const std::string body = R"(
3319 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3320 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3321 )";
3322
3323 CompileSuccessfully(GenerateShaderCode(body).c_str());
3324 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3325 EXPECT_THAT(
3326 getDiagnosticString(),
3327 HasSubstr("Capability Image1D is required to access storage image"));
3328 }
3329
TEST_F(ValidateImage,ReadNeedCapabilityImageCubeArray)3330 TEST_F(ValidateImage, ReadNeedCapabilityImageCubeArray) {
3331 const std::string body = R"(
3332 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3333 %res1 = OpImageRead %f32vec4 %img %u32vec3_012
3334 )";
3335
3336 CompileSuccessfully(GenerateShaderCode(body).c_str());
3337 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3338 EXPECT_THAT(
3339 getDiagnosticString(),
3340 HasSubstr(
3341 "Capability ImageCubeArray is required to access storage image"));
3342 }
3343
3344 // TODO(atgoo@github.com) Disabled until the spec is clarified.
TEST_F(ValidateImage,DISABLED_ReadWrongResultType)3345 TEST_F(ValidateImage, DISABLED_ReadWrongResultType) {
3346 const std::string body = R"(
3347 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3348 %res1 = OpImageRead %f32 %img %u32vec2_01
3349 )";
3350
3351 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3352 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3353 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3354 EXPECT_THAT(getDiagnosticString(),
3355 HasSubstr("Expected Result Type to be int or float vector type"));
3356 }
3357
TEST_F(ValidateImage,ReadScalarResultType_Universal)3358 TEST_F(ValidateImage, ReadScalarResultType_Universal) {
3359 const std::string body = R"(
3360 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3361 %res1 = OpImageRead %u32 %img %u32vec2_01
3362 )";
3363
3364 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3365 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3366 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
3367 EXPECT_THAT(getDiagnosticString(), Eq(""));
3368 }
3369
TEST_F(ValidateImage,ReadUnusualNumComponentsResultType_Universal)3370 TEST_F(ValidateImage, ReadUnusualNumComponentsResultType_Universal) {
3371 const std::string body = R"(
3372 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3373 %res1 = OpImageRead %u32vec3 %img %u32vec2_01
3374 )";
3375
3376 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3377 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3378 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
3379 EXPECT_THAT(getDiagnosticString(), Eq(""));
3380 }
3381
TEST_F(ValidateImage,ReadWrongNumComponentsResultType_Vulkan)3382 TEST_F(ValidateImage, ReadWrongNumComponentsResultType_Vulkan) {
3383 const std::string body = R"(
3384 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3385 %res1 = OpImageRead %u32vec3 %img %u32vec2_01
3386 )";
3387
3388 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3389 CompileSuccessfully(
3390 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_VULKAN_1_0)
3391 .c_str());
3392 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3393 EXPECT_THAT(getDiagnosticString(),
3394 AnyVUID("VUID-StandaloneSpirv-Result-04780"));
3395 EXPECT_THAT(getDiagnosticString(),
3396 HasSubstr("Expected Result Type to have 4 components"));
3397 }
3398
TEST_F(ValidateImage,ReadNotImage)3399 TEST_F(ValidateImage, ReadNotImage) {
3400 const std::string body = R"(
3401 %sampler = OpLoad %type_sampler %uniform_sampler
3402 %res1 = OpImageRead %f32vec4 %sampler %u32vec2_01
3403 )";
3404
3405 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3406 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3407 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3408 EXPECT_THAT(getDiagnosticString(),
3409 HasSubstr("Expected Image to be of type OpTypeImage"));
3410 }
3411
TEST_F(ValidateImage,ReadImageSampled)3412 TEST_F(ValidateImage, ReadImageSampled) {
3413 const std::string body = R"(
3414 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3415 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3416 )";
3417
3418 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3419 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3420 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3421 EXPECT_THAT(getDiagnosticString(),
3422 HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
3423 }
3424
TEST_F(ValidateImage,ReadWrongSampledType)3425 TEST_F(ValidateImage, ReadWrongSampledType) {
3426 const std::string body = R"(
3427 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3428 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3429 )";
3430
3431 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3432 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3433 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3434 EXPECT_THAT(getDiagnosticString(),
3435 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3436 "Result Type components"));
3437 }
3438
TEST_F(ValidateImage,ReadVoidSampledType)3439 TEST_F(ValidateImage, ReadVoidSampledType) {
3440 const std::string body = R"(
3441 %img = OpLoad %type_image_void_2d_0002 %uniform_image_void_2d_0002
3442 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3443 %res2 = OpImageRead %u32vec4 %img %u32vec2_01
3444 %res3 = OpImageRead %s32vec4 %img %u32vec2_01
3445 )";
3446
3447 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3448 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3449 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3450 }
3451
TEST_F(ValidateImage,ReadWrongCoordinateType)3452 TEST_F(ValidateImage, ReadWrongCoordinateType) {
3453 const std::string body = R"(
3454 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3455 %res1 = OpImageRead %u32vec4 %img %f32vec2_00
3456 )";
3457
3458 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3459 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3460 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3461 EXPECT_THAT(getDiagnosticString(),
3462 HasSubstr("Expected Coordinate to be int scalar or vector"));
3463 }
3464
TEST_F(ValidateImage,ReadCoordinateSizeTooSmall)3465 TEST_F(ValidateImage, ReadCoordinateSizeTooSmall) {
3466 const std::string body = R"(
3467 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3468 %res1 = OpImageRead %u32vec4 %img %u32_1
3469 )";
3470
3471 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3472 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3473 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3474 EXPECT_THAT(getDiagnosticString(),
3475 HasSubstr("Expected Coordinate to have at least 2 components, "
3476 "but given only 1"));
3477 }
3478
TEST_F(ValidateImage,WriteSuccess1)3479 TEST_F(ValidateImage, WriteSuccess1) {
3480 const std::string body = R"(
3481 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3482 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3483 )";
3484
3485 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3486 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3487 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3488 }
3489
TEST_F(ValidateImage,WriteSuccess2)3490 TEST_F(ValidateImage, WriteSuccess2) {
3491 const std::string body = R"(
3492 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3493 OpImageWrite %img %u32_1 %f32vec4_0000
3494 )";
3495
3496 const std::string extra = "\nOpCapability Image1D\n";
3497 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3498 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3499 }
3500
TEST_F(ValidateImage,WriteSuccess3)3501 TEST_F(ValidateImage, WriteSuccess3) {
3502 const std::string body = R"(
3503 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3504 OpImageWrite %img %u32vec3_012 %f32vec4_0000
3505 )";
3506
3507 const std::string extra = "\nOpCapability ImageCubeArray\n";
3508 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3509 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3510 }
3511
TEST_F(ValidateImage,WriteSuccess4)3512 TEST_F(ValidateImage, WriteSuccess4) {
3513 const std::string body = R"(
3514 %img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
3515 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
3516 )";
3517
3518 const std::string extra = R"(
3519 OpCapability StorageImageWriteWithoutFormat
3520 OpCapability StorageImageMultisample
3521 )";
3522
3523 const std::string declarations = R"(
3524 %type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
3525 %ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
3526 %uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
3527 )";
3528 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3529 SPV_ENV_UNIVERSAL_1_0, "GLSL450",
3530 declarations)
3531 .c_str());
3532 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3533 }
3534
TEST_F(ValidateImage,WriteSubpassData)3535 TEST_F(ValidateImage, WriteSubpassData) {
3536 const std::string body = R"(
3537 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3538 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3539 )";
3540
3541 CompileSuccessfully(GenerateShaderCode(body).c_str());
3542 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3543 EXPECT_THAT(getDiagnosticString(),
3544 HasSubstr("Image 'Dim' cannot be SubpassData"));
3545 }
3546
TEST_F(ValidateImage,WriteNeedCapabilityStorageImageWriteWithoutFormat)3547 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
3548 const std::string body = R"(
3549 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3550 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3551 )";
3552
3553 CompileSuccessfully(GenerateShaderCode(body).c_str());
3554 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3555 }
3556
TEST_F(ValidateImage,WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan)3557 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
3558 const std::string body = R"(
3559 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3560 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3561 )";
3562
3563 spv_target_env env = SPV_ENV_VULKAN_1_0;
3564 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3565 env);
3566 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3567 EXPECT_THAT(
3568 getDiagnosticString(),
3569 HasSubstr(
3570 "Capability StorageImageWriteWithoutFormat is required to write to "
3571 "storage image"));
3572 }
3573
TEST_F(ValidateImage,WriteNeedCapabilityImage1D)3574 TEST_F(ValidateImage, WriteNeedCapabilityImage1D) {
3575 const std::string body = R"(
3576 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3577 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3578 )";
3579
3580 CompileSuccessfully(GenerateShaderCode(body).c_str());
3581 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3582 EXPECT_THAT(getDiagnosticString(),
3583 HasSubstr("Capability Image1D is required to access storage "
3584 "image"));
3585 }
3586
TEST_F(ValidateImage,WriteNeedCapabilityImageCubeArray)3587 TEST_F(ValidateImage, WriteNeedCapabilityImageCubeArray) {
3588 const std::string body = R"(
3589 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3590 OpImageWrite %img %u32vec3_012 %f32vec4_0000
3591 )";
3592
3593 CompileSuccessfully(GenerateShaderCode(body).c_str());
3594 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3595 EXPECT_THAT(
3596 getDiagnosticString(),
3597 HasSubstr(
3598 "Capability ImageCubeArray is required to access storage image"));
3599 }
3600
TEST_F(ValidateImage,WriteNotImage)3601 TEST_F(ValidateImage, WriteNotImage) {
3602 const std::string body = R"(
3603 %sampler = OpLoad %type_sampler %uniform_sampler
3604 OpImageWrite %sampler %u32vec2_01 %f32vec4_0000
3605 )";
3606
3607 CompileSuccessfully(GenerateShaderCode(body).c_str());
3608 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3609 EXPECT_THAT(getDiagnosticString(),
3610 HasSubstr("Expected Image to be of type OpTypeImage"));
3611 }
3612
TEST_F(ValidateImage,WriteImageSampled)3613 TEST_F(ValidateImage, WriteImageSampled) {
3614 const std::string body = R"(
3615 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3616 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3617 )";
3618
3619 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3620 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3621 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3622 EXPECT_THAT(getDiagnosticString(),
3623 HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
3624 }
3625
TEST_F(ValidateImage,WriteWrongCoordinateType)3626 TEST_F(ValidateImage, WriteWrongCoordinateType) {
3627 const std::string body = R"(
3628 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3629 OpImageWrite %img %f32vec2_00 %u32vec4_0123
3630 )";
3631
3632 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3633 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3634 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3635 EXPECT_THAT(getDiagnosticString(),
3636 HasSubstr("Expected Coordinate to be int scalar or vector"));
3637 }
3638
TEST_F(ValidateImage,WriteCoordinateSizeTooSmall)3639 TEST_F(ValidateImage, WriteCoordinateSizeTooSmall) {
3640 const std::string body = R"(
3641 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3642 OpImageWrite %img %u32_1 %u32vec4_0123
3643 )";
3644
3645 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3646 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3647 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3648 EXPECT_THAT(getDiagnosticString(),
3649 HasSubstr("Expected Coordinate to have at least 2 components, "
3650 "but given only 1"));
3651 }
3652
TEST_F(ValidateImage,WriteTexelWrongType)3653 TEST_F(ValidateImage, WriteTexelWrongType) {
3654 const std::string body = R"(
3655 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3656 OpImageWrite %img %u32vec2_01 %img
3657 )";
3658
3659 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3660 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3661 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3662 EXPECT_THAT(getDiagnosticString(),
3663 HasSubstr("Expected Texel to be int or float vector or scalar"));
3664 }
3665
TEST_F(ValidateImage,DISABLED_WriteTexelNotVector4)3666 TEST_F(ValidateImage, DISABLED_WriteTexelNotVector4) {
3667 const std::string body = R"(
3668 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3669 OpImageWrite %img %u32vec2_01 %u32vec3_012
3670 )";
3671
3672 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3673 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3674 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3675 EXPECT_THAT(getDiagnosticString(),
3676 HasSubstr("Expected Texel to have 4 components"));
3677 }
3678
TEST_F(ValidateImage,WriteTexelWrongComponentType)3679 TEST_F(ValidateImage, WriteTexelWrongComponentType) {
3680 const std::string body = R"(
3681 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3682 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3683 )";
3684
3685 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3686 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3687 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3688 EXPECT_THAT(
3689 getDiagnosticString(),
3690 HasSubstr(
3691 "Expected Image 'Sampled Type' to be the same as Texel components"));
3692 }
3693
TEST_F(ValidateImage,WriteSampleNotInteger)3694 TEST_F(ValidateImage, WriteSampleNotInteger) {
3695 const std::string body = R"(
3696 %img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
3697 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1
3698 )";
3699
3700 const std::string extra = R"(
3701 OpCapability StorageImageWriteWithoutFormat
3702 OpCapability StorageImageMultisample
3703 )";
3704 const std::string declarations = R"(
3705 %type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
3706 %ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
3707 %uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
3708 )";
3709 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3710 SPV_ENV_UNIVERSAL_1_0, "GLSL450",
3711 declarations)
3712 .c_str());
3713 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3714 EXPECT_THAT(getDiagnosticString(),
3715 HasSubstr("Expected Image Operand Sample to be int scalar"));
3716 }
3717
TEST_F(ValidateImage,WriteSampleNotMultisampled)3718 TEST_F(ValidateImage, WriteSampleNotMultisampled) {
3719 const std::string body = R"(
3720 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
3721 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
3722 )";
3723
3724 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3725 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3726 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3727 EXPECT_THAT(
3728 getDiagnosticString(),
3729 HasSubstr("Image Operand Sample requires non-zero 'MS' parameter"));
3730 }
3731
TEST_F(ValidateImage,SampleWrongOpcode)3732 TEST_F(ValidateImage, SampleWrongOpcode) {
3733 const std::string body = R"(
3734 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3735 %sampler = OpLoad %type_sampler %uniform_sampler
3736 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
3737 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Sample %u32_1
3738 )";
3739
3740 CompileSuccessfully(GenerateShaderCode(body).c_str());
3741 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3742 EXPECT_THAT(getDiagnosticString(),
3743 HasSubstr("Sampling operation is invalid for multisample image"));
3744 }
3745
TEST_F(ValidateImage,SampleImageToImageSuccess)3746 TEST_F(ValidateImage, SampleImageToImageSuccess) {
3747 const std::string body = R"(
3748 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3749 %sampler = OpLoad %type_sampler %uniform_sampler
3750 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3751 %img2 = OpImage %type_image_f32_2d_0001 %simg
3752 )";
3753
3754 CompileSuccessfully(GenerateShaderCode(body).c_str());
3755 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3756 }
3757
TEST_F(ValidateImage,SampleImageToImageWrongResultType)3758 TEST_F(ValidateImage, SampleImageToImageWrongResultType) {
3759 const std::string body = R"(
3760 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3761 %sampler = OpLoad %type_sampler %uniform_sampler
3762 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3763 %img2 = OpImage %type_sampled_image_f32_2d_0001 %simg
3764 )";
3765
3766 CompileSuccessfully(GenerateShaderCode(body).c_str());
3767 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3768 EXPECT_THAT(getDiagnosticString(),
3769 HasSubstr("Expected Result Type to be OpTypeImage"));
3770 }
3771
TEST_F(ValidateImage,SampleImageToImageNotSampledImage)3772 TEST_F(ValidateImage, SampleImageToImageNotSampledImage) {
3773 const std::string body = R"(
3774 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3775 %img2 = OpImage %type_image_f32_2d_0001 %img
3776 )";
3777
3778 CompileSuccessfully(GenerateShaderCode(body).c_str());
3779 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3780 EXPECT_THAT(
3781 getDiagnosticString(),
3782 HasSubstr("Expected Sample Image to be of type OpTypeSampleImage"));
3783 }
3784
TEST_F(ValidateImage,SampleImageToImageNotTheSameImageType)3785 TEST_F(ValidateImage, SampleImageToImageNotTheSameImageType) {
3786 const std::string body = R"(
3787 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3788 %sampler = OpLoad %type_sampler %uniform_sampler
3789 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3790 %img2 = OpImage %type_image_f32_2d_0002 %simg
3791 )";
3792
3793 CompileSuccessfully(GenerateShaderCode(body).c_str());
3794 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3795 EXPECT_THAT(getDiagnosticString(),
3796 HasSubstr("Expected Sample Image image type to be equal to "
3797 "Result Type"));
3798 }
3799
TEST_F(ValidateImage,QueryFormatSuccess)3800 TEST_F(ValidateImage, QueryFormatSuccess) {
3801 const std::string body = R"(
3802 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3803 %res1 = OpImageQueryFormat %u32 %img
3804 )";
3805
3806 CompileSuccessfully(GenerateKernelCode(body).c_str());
3807 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3808 }
3809
TEST_F(ValidateImage,QueryFormatWrongResultType)3810 TEST_F(ValidateImage, QueryFormatWrongResultType) {
3811 const std::string body = R"(
3812 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3813 %res1 = OpImageQueryFormat %bool %img
3814 )";
3815
3816 CompileSuccessfully(GenerateKernelCode(body).c_str());
3817 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3818 EXPECT_THAT(getDiagnosticString(),
3819 HasSubstr("Expected Result Type to be int scalar type"));
3820 }
3821
TEST_F(ValidateImage,QueryFormatNotImage)3822 TEST_F(ValidateImage, QueryFormatNotImage) {
3823 const std::string body = R"(
3824 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3825 %sampler = OpLoad %type_sampler %uniform_sampler
3826 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3827 %res1 = OpImageQueryFormat %u32 %sampler
3828 )";
3829
3830 CompileSuccessfully(GenerateKernelCode(body).c_str());
3831 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3832 EXPECT_THAT(getDiagnosticString(),
3833 HasSubstr("Expected operand to be of type OpTypeImage"));
3834 }
3835
TEST_F(ValidateImage,QueryOrderSuccess)3836 TEST_F(ValidateImage, QueryOrderSuccess) {
3837 const std::string body = R"(
3838 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3839 %res1 = OpImageQueryOrder %u32 %img
3840 )";
3841
3842 CompileSuccessfully(GenerateKernelCode(body).c_str());
3843 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3844 }
3845
TEST_F(ValidateImage,QueryOrderWrongResultType)3846 TEST_F(ValidateImage, QueryOrderWrongResultType) {
3847 const std::string body = R"(
3848 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3849 %res1 = OpImageQueryOrder %bool %img
3850 )";
3851
3852 CompileSuccessfully(GenerateKernelCode(body).c_str());
3853 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3854 EXPECT_THAT(getDiagnosticString(),
3855 HasSubstr("Expected Result Type to be int scalar type"));
3856 }
3857
TEST_F(ValidateImage,QueryOrderNotImage)3858 TEST_F(ValidateImage, QueryOrderNotImage) {
3859 const std::string body = R"(
3860 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3861 %sampler = OpLoad %type_sampler %uniform_sampler
3862 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3863 %res1 = OpImageQueryOrder %u32 %sampler
3864 )";
3865
3866 CompileSuccessfully(GenerateKernelCode(body).c_str());
3867 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3868 EXPECT_THAT(getDiagnosticString(),
3869 HasSubstr("Expected operand to be of type OpTypeImage"));
3870 }
3871
TEST_F(ValidateImage,QuerySizeLodSuccess)3872 TEST_F(ValidateImage, QuerySizeLodSuccess) {
3873 const std::string body = R"(
3874 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3875 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
3876 )";
3877
3878 CompileSuccessfully(GenerateKernelCode(body).c_str());
3879 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3880 }
3881
TEST_F(ValidateImage,QuerySizeLodWrongResultType)3882 TEST_F(ValidateImage, QuerySizeLodWrongResultType) {
3883 const std::string body = R"(
3884 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3885 %res1 = OpImageQuerySizeLod %f32vec2 %img %u32_1
3886 )";
3887
3888 CompileSuccessfully(GenerateKernelCode(body).c_str());
3889 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3890 EXPECT_THAT(
3891 getDiagnosticString(),
3892 HasSubstr("Expected Result Type to be int scalar or vector type"));
3893 }
3894
TEST_F(ValidateImage,QuerySizeLodResultTypeWrongSize)3895 TEST_F(ValidateImage, QuerySizeLodResultTypeWrongSize) {
3896 const std::string body = R"(
3897 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3898 %res1 = OpImageQuerySizeLod %u32 %img %u32_1
3899 )";
3900
3901 CompileSuccessfully(GenerateKernelCode(body).c_str());
3902 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3903 EXPECT_THAT(getDiagnosticString(),
3904 HasSubstr("Result Type has 1 components, but 2 expected"));
3905 }
3906
TEST_F(ValidateImage,QuerySizeLodNotImage)3907 TEST_F(ValidateImage, QuerySizeLodNotImage) {
3908 const std::string body = R"(
3909 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3910 %sampler = OpLoad %type_sampler %uniform_sampler
3911 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3912 %res1 = OpImageQuerySizeLod %u32vec2 %sampler %u32_1
3913 )";
3914
3915 CompileSuccessfully(GenerateKernelCode(body).c_str());
3916 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3917 EXPECT_THAT(getDiagnosticString(),
3918 HasSubstr("Expected Image to be of type OpTypeImage"));
3919 }
3920
TEST_F(ValidateImage,QuerySizeLodSampledImageDirectly)3921 TEST_F(ValidateImage, QuerySizeLodSampledImageDirectly) {
3922 const std::string body = R"(
3923 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3924 %sampler = OpLoad %type_sampler %uniform_sampler
3925 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3926 %res1 = OpImageQuerySizeLod %u32vec2 %simg %u32_1
3927 )";
3928
3929 CompileSuccessfully(GenerateShaderCode(body).c_str());
3930 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3931 EXPECT_THAT(getDiagnosticString(),
3932 HasSubstr("OpSampledImage instruction must not appear as operand "
3933 "for OpImageQuerySizeLod"));
3934 }
3935
TEST_F(ValidateImage,QuerySizeLodMultisampledError)3936 TEST_F(ValidateImage, QuerySizeLodMultisampledError) {
3937 const std::string body = R"(
3938 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3939 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
3940 )";
3941
3942 CompileSuccessfully(GenerateKernelCode(body).c_str());
3943 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3944 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 0"));
3945 }
3946
TEST_F(ValidateImage,QuerySizeLodNonSampledUniversalSuccess)3947 TEST_F(ValidateImage, QuerySizeLodNonSampledUniversalSuccess) {
3948 const std::string body = R"(
3949 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
3950 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
3951 )";
3952
3953 CompileSuccessfully(GenerateShaderCode(body).c_str());
3954 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3955 EXPECT_EQ(getDiagnosticString(), "");
3956 }
3957
TEST_F(ValidateImage,QuerySizeLodVulkanNonSampledError)3958 TEST_F(ValidateImage, QuerySizeLodVulkanNonSampledError) {
3959 // Create a whole shader module. Avoid Vulkan incompatibility with
3960 // SampledRrect images inserted by helper function GenerateShaderCode.
3961 const std::string body = R"(
3962 OpCapability Shader
3963 OpCapability ImageQuery
3964 OpMemoryModel Logical Simple
3965 OpEntryPoint Fragment %main "main"
3966 OpExecutionMode %main OriginUpperLeft
3967
3968 %f32 = OpTypeFloat 32
3969 %u32 = OpTypeInt 32 0
3970 %u32_0 = OpConstant %u32 0
3971 %u32vec2 = OpTypeVector %u32 2
3972 %void = OpTypeVoid
3973 %voidfn = OpTypeFunction %void
3974
3975 ; Test with a storage image.
3976 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
3977 %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
3978 %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
3979
3980 %main = OpFunction %void None %voidfn
3981 %entry = OpLabel
3982 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
3983 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_0
3984 OpReturn
3985 OpFunctionEnd
3986 )";
3987
3988 CompileSuccessfully(body.c_str());
3989 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3990 EXPECT_THAT(getDiagnosticString(),
3991 AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
3992 EXPECT_THAT(
3993 getDiagnosticString(),
3994 HasSubstr(
3995 "OpImageQuerySizeLod must only consume an \"Image\" operand whose "
3996 "type has its \"Sampled\" operand set to 1"));
3997 }
3998
TEST_F(ValidateImage,QuerySizeLodWrongImageDim)3999 TEST_F(ValidateImage, QuerySizeLodWrongImageDim) {
4000 const std::string body = R"(
4001 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4002 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4003 )";
4004
4005 CompileSuccessfully(GenerateKernelCode(body).c_str());
4006 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4007 EXPECT_THAT(getDiagnosticString(),
4008 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4009 }
4010
TEST_F(ValidateImage,QuerySizeLodWrongLodType)4011 TEST_F(ValidateImage, QuerySizeLodWrongLodType) {
4012 const std::string body = R"(
4013 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4014 %res1 = OpImageQuerySizeLod %u32vec2 %img %f32_0
4015 )";
4016
4017 CompileSuccessfully(GenerateKernelCode(body).c_str());
4018 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4019 EXPECT_THAT(getDiagnosticString(),
4020 HasSubstr("Expected Level of Detail to be int scalar"));
4021 }
4022
TEST_F(ValidateImage,QuerySizeSuccess)4023 TEST_F(ValidateImage, QuerySizeSuccess) {
4024 const std::string body = R"(
4025 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4026 %res1 = OpImageQuerySize %u32vec2 %img
4027 )";
4028
4029 CompileSuccessfully(GenerateKernelCode(body).c_str());
4030 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4031 }
4032
TEST_F(ValidateImage,QuerySizeWrongResultType)4033 TEST_F(ValidateImage, QuerySizeWrongResultType) {
4034 const std::string body = R"(
4035 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4036 %res1 = OpImageQuerySize %f32vec2 %img
4037 )";
4038
4039 CompileSuccessfully(GenerateKernelCode(body).c_str());
4040 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4041 EXPECT_THAT(
4042 getDiagnosticString(),
4043 HasSubstr("Expected Result Type to be int scalar or vector type"));
4044 }
4045
TEST_F(ValidateImage,QuerySizeNotImage)4046 TEST_F(ValidateImage, QuerySizeNotImage) {
4047 const std::string body = R"(
4048 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4049 %sampler = OpLoad %type_sampler %uniform_sampler
4050 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4051 %res1 = OpImageQuerySize %u32vec2 %sampler
4052 )";
4053
4054 CompileSuccessfully(GenerateKernelCode(body).c_str());
4055 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4056 EXPECT_THAT(getDiagnosticString(),
4057 HasSubstr("Expected Image to be of type OpTypeImage"));
4058 }
4059
TEST_F(ValidateImage,QuerySizeSampledImageDirectly)4060 TEST_F(ValidateImage, QuerySizeSampledImageDirectly) {
4061 const std::string body = R"(
4062 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4063 %sampler = OpLoad %type_sampler %uniform_sampler
4064 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4065 %res1 = OpImageQuerySize %u32vec2 %simg
4066 )";
4067
4068 CompileSuccessfully(GenerateShaderCode(body).c_str());
4069 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4070 EXPECT_THAT(getDiagnosticString(),
4071 HasSubstr("OpSampledImage instruction must not appear as operand "
4072 "for OpImageQuerySize"));
4073 }
4074
TEST_F(ValidateImage,QuerySizeDimSubpassDataBad)4075 TEST_F(ValidateImage, QuerySizeDimSubpassDataBad) {
4076 const std::string body = R"(
4077 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
4078 %res1 = OpImageQuerySize %u32vec2 %img
4079 )";
4080
4081 CompileSuccessfully(GenerateShaderCode(body).c_str());
4082 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4083 EXPECT_THAT(
4084 getDiagnosticString(),
4085 HasSubstr("Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"));
4086 }
4087
TEST_F(ValidateImage,QuerySizeWrongSampling)4088 TEST_F(ValidateImage, QuerySizeWrongSampling) {
4089 const std::string body = R"(
4090 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4091 %res1 = OpImageQuerySize %u32vec2 %img
4092 )";
4093
4094 CompileSuccessfully(GenerateKernelCode(body).c_str());
4095 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4096 EXPECT_THAT(
4097 getDiagnosticString(),
4098 HasSubstr("Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"));
4099 }
4100
TEST_F(ValidateImage,QuerySizeWrongNumberOfComponents)4101 TEST_F(ValidateImage, QuerySizeWrongNumberOfComponents) {
4102 const std::string body = R"(
4103 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
4104 %res1 = OpImageQuerySize %u32vec2 %img
4105 )";
4106
4107 CompileSuccessfully(GenerateShaderCode(body).c_str());
4108 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4109 EXPECT_THAT(getDiagnosticString(),
4110 HasSubstr("Result Type has 2 components, but 4 expected"));
4111 }
4112
TEST_F(ValidateImage,QueryLodSuccessKernel)4113 TEST_F(ValidateImage, QueryLodSuccessKernel) {
4114 const std::string body = R"(
4115 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4116 %sampler = OpLoad %type_sampler %uniform_sampler
4117 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4118 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4119 %res2 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
4120 )";
4121
4122 CompileSuccessfully(GenerateKernelCode(body).c_str());
4123 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4124 }
4125
TEST_F(ValidateImage,QueryLodSuccessShader)4126 TEST_F(ValidateImage, QueryLodSuccessShader) {
4127 const std::string body = R"(
4128 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4129 %sampler = OpLoad %type_sampler %uniform_sampler
4130 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4131 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4132 )";
4133
4134 CompileSuccessfully(GenerateShaderCode(body).c_str());
4135 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4136 }
4137
TEST_F(ValidateImage,QueryLodWrongResultType)4138 TEST_F(ValidateImage, QueryLodWrongResultType) {
4139 const std::string body = R"(
4140 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4141 %sampler = OpLoad %type_sampler %uniform_sampler
4142 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4143 %res1 = OpImageQueryLod %u32vec2 %simg %f32vec2_hh
4144 )";
4145
4146 CompileSuccessfully(GenerateKernelCode(body).c_str());
4147 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4148 EXPECT_THAT(getDiagnosticString(),
4149 HasSubstr("Expected Result Type to be float vector type"));
4150 }
4151
TEST_F(ValidateImage,QueryLodResultTypeWrongSize)4152 TEST_F(ValidateImage, QueryLodResultTypeWrongSize) {
4153 const std::string body = R"(
4154 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4155 %sampler = OpLoad %type_sampler %uniform_sampler
4156 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4157 %res1 = OpImageQueryLod %f32vec3 %simg %f32vec2_hh
4158 )";
4159
4160 CompileSuccessfully(GenerateKernelCode(body).c_str());
4161 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4162 EXPECT_THAT(getDiagnosticString(),
4163 HasSubstr("Expected Result Type to have 2 components"));
4164 }
4165
TEST_F(ValidateImage,QueryLodNotSampledImage)4166 TEST_F(ValidateImage, QueryLodNotSampledImage) {
4167 const std::string body = R"(
4168 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4169 %res1 = OpImageQueryLod %f32vec2 %img %f32vec2_hh
4170 )";
4171
4172 CompileSuccessfully(GenerateKernelCode(body).c_str());
4173 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4174 EXPECT_THAT(
4175 getDiagnosticString(),
4176 HasSubstr("Expected Image operand to be of type OpTypeSampledImage"));
4177 }
4178
TEST_F(ValidateImage,QueryLodWrongDim)4179 TEST_F(ValidateImage, QueryLodWrongDim) {
4180 const std::string body = R"(
4181 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4182 %sampler = OpLoad %type_sampler %uniform_sampler
4183 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
4184 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4185 )";
4186
4187 CompileSuccessfully(GenerateKernelCode(body).c_str());
4188 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4189 EXPECT_THAT(getDiagnosticString(),
4190 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4191 }
4192
TEST_F(ValidateImage,QueryLodWrongCoordinateType)4193 TEST_F(ValidateImage, QueryLodWrongCoordinateType) {
4194 const std::string body = R"(
4195 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4196 %sampler = OpLoad %type_sampler %uniform_sampler
4197 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4198 %res1 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
4199 )";
4200
4201 CompileSuccessfully(GenerateShaderCode(body).c_str());
4202 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4203 EXPECT_THAT(getDiagnosticString(),
4204 HasSubstr("Expected Coordinate to be float scalar or vector"));
4205 }
4206
TEST_F(ValidateImage,QueryLodCoordinateSizeTooSmall)4207 TEST_F(ValidateImage, QueryLodCoordinateSizeTooSmall) {
4208 const std::string body = R"(
4209 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4210 %sampler = OpLoad %type_sampler %uniform_sampler
4211 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4212 %res1 = OpImageQueryLod %f32vec2 %simg %f32_0
4213 )";
4214
4215 CompileSuccessfully(GenerateShaderCode(body).c_str());
4216 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4217 EXPECT_THAT(getDiagnosticString(),
4218 HasSubstr("Expected Coordinate to have at least 2 components, "
4219 "but given only 1"));
4220 }
4221
TEST_F(ValidateImage,QueryLevelsSuccess)4222 TEST_F(ValidateImage, QueryLevelsSuccess) {
4223 const std::string body = R"(
4224 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4225 %res1 = OpImageQueryLevels %u32 %img
4226 )";
4227
4228 CompileSuccessfully(GenerateKernelCode(body).c_str());
4229 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4230 }
4231
TEST_F(ValidateImage,QueryLevelsWrongResultType)4232 TEST_F(ValidateImage, QueryLevelsWrongResultType) {
4233 const std::string body = R"(
4234 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4235 %res1 = OpImageQueryLevels %f32 %img
4236 )";
4237
4238 CompileSuccessfully(GenerateKernelCode(body).c_str());
4239 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4240 EXPECT_THAT(getDiagnosticString(),
4241 HasSubstr("Expected Result Type to be int scalar type"));
4242 }
4243
TEST_F(ValidateImage,QueryLevelsNotImage)4244 TEST_F(ValidateImage, QueryLevelsNotImage) {
4245 const std::string body = R"(
4246 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4247 %sampler = OpLoad %type_sampler %uniform_sampler
4248 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4249 %res1 = OpImageQueryLevels %u32 %sampler
4250 )";
4251
4252 CompileSuccessfully(GenerateKernelCode(body).c_str());
4253 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4254 EXPECT_THAT(getDiagnosticString(),
4255 HasSubstr("Expected Image to be of type OpTypeImage"));
4256 }
4257
TEST_F(ValidateImage,QueryLevelsSampledImageDirectly)4258 TEST_F(ValidateImage, QueryLevelsSampledImageDirectly) {
4259 const std::string body = R"(
4260 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4261 %sampler = OpLoad %type_sampler %uniform_sampler
4262 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4263 %res1 = OpImageQueryLevels %u32 %simg
4264 )";
4265
4266 CompileSuccessfully(GenerateShaderCode(body).c_str());
4267 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4268 EXPECT_THAT(getDiagnosticString(),
4269 HasSubstr("OpSampledImage instruction must not appear as operand "
4270 "for OpImageQueryLevels"));
4271 }
4272
TEST_F(ValidateImage,QueryLevelsWrongDim)4273 TEST_F(ValidateImage, QueryLevelsWrongDim) {
4274 const std::string body = R"(
4275 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4276 %res1 = OpImageQueryLevels %u32 %img
4277 )";
4278
4279 CompileSuccessfully(GenerateKernelCode(body).c_str());
4280 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4281 EXPECT_THAT(getDiagnosticString(),
4282 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4283 }
4284
TEST_F(ValidateImage,QuerySizeLevelsNonSampledUniversalSuccess)4285 TEST_F(ValidateImage, QuerySizeLevelsNonSampledUniversalSuccess) {
4286 const std::string body = R"(
4287 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4288 %res1 = OpImageQueryLevels %u32 %img
4289 )";
4290
4291 CompileSuccessfully(GenerateShaderCode(body).c_str());
4292 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4293 EXPECT_EQ(getDiagnosticString(), "");
4294 }
4295
TEST_F(ValidateImage,QuerySizeLevelsVulkanNonSampledError)4296 TEST_F(ValidateImage, QuerySizeLevelsVulkanNonSampledError) {
4297 // Create a whole shader module. Avoid Vulkan incompatibility with
4298 // SampledRrect images inserted by helper function GenerateShaderCode.
4299 const std::string body = R"(
4300 OpCapability Shader
4301 OpCapability ImageQuery
4302 OpMemoryModel Logical Simple
4303 OpEntryPoint Fragment %main "main"
4304 OpExecutionMode %main OriginUpperLeft
4305
4306 %f32 = OpTypeFloat 32
4307 %u32 = OpTypeInt 32 0
4308 %void = OpTypeVoid
4309 %voidfn = OpTypeFunction %void
4310
4311 ; Test with a storage image.
4312 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4313 %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
4314 %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
4315
4316 %main = OpFunction %void None %voidfn
4317 %entry = OpLabel
4318 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4319 %res1 = OpImageQueryLevels %u32 %img
4320 OpReturn
4321 OpFunctionEnd
4322 )";
4323
4324 CompileSuccessfully(body.c_str());
4325 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4326 EXPECT_THAT(getDiagnosticString(),
4327 AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
4328 EXPECT_THAT(
4329 getDiagnosticString(),
4330 HasSubstr("OpImageQueryLevels must only consume an \"Image\" operand "
4331 "whose type has its \"Sampled\" operand set to 1"));
4332 }
4333
TEST_F(ValidateImage,QuerySamplesSuccess)4334 TEST_F(ValidateImage, QuerySamplesSuccess) {
4335 const std::string body = R"(
4336 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4337 %res1 = OpImageQuerySamples %u32 %img
4338 )";
4339
4340 CompileSuccessfully(GenerateKernelCode(body).c_str());
4341 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4342 }
4343
TEST_F(ValidateImage,QuerySamplesNot2D)4344 TEST_F(ValidateImage, QuerySamplesNot2D) {
4345 const std::string body = R"(
4346 %img = OpLoad %type_image_f32_3d_0011 %uniform_image_f32_3d_0011
4347 %res1 = OpImageQuerySamples %u32 %img
4348 )";
4349
4350 CompileSuccessfully(GenerateKernelCode(body).c_str());
4351 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4352 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' must be 2D"));
4353 }
4354
TEST_F(ValidateImage,QuerySamplesNotMultisampled)4355 TEST_F(ValidateImage, QuerySamplesNotMultisampled) {
4356 const std::string body = R"(
4357 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4358 %res1 = OpImageQuerySamples %u32 %img
4359 )";
4360
4361 CompileSuccessfully(GenerateKernelCode(body).c_str());
4362 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4363 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 1"));
4364 }
4365
TEST_F(ValidateImage,QueryLodWrongExecutionModel)4366 TEST_F(ValidateImage, QueryLodWrongExecutionModel) {
4367 const std::string body = R"(
4368 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4369 %sampler = OpLoad %type_sampler %uniform_sampler
4370 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4371 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4372 )";
4373
4374 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4375 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4376 EXPECT_THAT(
4377 getDiagnosticString(),
4378 HasSubstr(
4379 "OpImageQueryLod requires Fragment or GLCompute execution model"));
4380 }
4381
TEST_F(ValidateImage,QueryLodWrongExecutionModelWithFunc)4382 TEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) {
4383 const std::string body = R"(
4384 %call_ret = OpFunctionCall %void %my_func
4385 OpReturn
4386 OpFunctionEnd
4387 %my_func = OpFunction %void None %func
4388 %my_func_entry = OpLabel
4389 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4390 %sampler = OpLoad %type_sampler %uniform_sampler
4391 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4392 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4393 )";
4394
4395 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4396 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4397 EXPECT_THAT(
4398 getDiagnosticString(),
4399 HasSubstr(
4400 "OpImageQueryLod requires Fragment or GLCompute execution model"));
4401 }
4402
TEST_F(ValidateImage,QueryLodComputeShaderDerivatives)4403 TEST_F(ValidateImage, QueryLodComputeShaderDerivatives) {
4404 const std::string body = R"(
4405 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4406 %sampler = OpLoad %type_sampler %uniform_sampler
4407 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4408 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4409 )";
4410
4411 const std::string extra = R"(
4412 OpCapability ComputeDerivativeGroupLinearNV
4413 OpExtension "SPV_NV_compute_shader_derivatives"
4414 )";
4415 const std::string mode = R"(
4416 OpExecutionMode %main LocalSize 8 8 1
4417 OpExecutionMode %main DerivativeGroupLinearNV
4418 )";
4419 CompileSuccessfully(
4420 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4421 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4422 }
4423
TEST_F(ValidateImage,QueryLodUniversalSuccess)4424 TEST_F(ValidateImage, QueryLodUniversalSuccess) {
4425 // Create a whole shader module. Avoid Vulkan incompatibility with
4426 // SampledRrect images inserted by helper function GenerateShaderCode.
4427 const std::string body = R"(
4428 OpCapability Shader
4429 OpCapability ImageQuery
4430 OpMemoryModel Logical Simple
4431 OpEntryPoint Fragment %main "main"
4432 OpExecutionMode %main OriginUpperLeft
4433
4434 OpDecorate %uniform_image_f32_2d_0000 DescriptorSet 0
4435 OpDecorate %uniform_image_f32_2d_0000 Binding 0
4436 OpDecorate %sampler DescriptorSet 0
4437 OpDecorate %sampler Binding 1
4438
4439 %f32 = OpTypeFloat 32
4440 %f32vec2 = OpTypeVector %f32 2
4441 %f32vec2_null = OpConstantNull %f32vec2
4442 %u32 = OpTypeInt 32 0
4443 %u32vec2 = OpTypeVector %u32 2
4444 %void = OpTypeVoid
4445 %voidfn = OpTypeFunction %void
4446
4447 ; Test with an image with sampled = 0
4448 %type_image_f32_2d_0000 = OpTypeImage %f32 2D 0 0 0 0 Rgba32f
4449 %ptr_image_f32_2d_0000 = OpTypePointer UniformConstant %type_image_f32_2d_0000
4450 %uniform_image_f32_2d_0000 = OpVariable %ptr_image_f32_2d_0000 UniformConstant
4451 %sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0000
4452
4453 %sampler_ty = OpTypeSampler
4454 %ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
4455 %sampler = OpVariable %ptr_sampler_ty UniformConstant
4456
4457
4458 %main = OpFunction %void None %voidfn
4459 %entry = OpLabel
4460 %img = OpLoad %type_image_f32_2d_0000 %uniform_image_f32_2d_0000
4461 %s = OpLoad %sampler_ty %sampler
4462 %simg = OpSampledImage %sampled_image_ty %img %s
4463 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
4464 OpReturn
4465 OpFunctionEnd
4466 )";
4467
4468 CompileSuccessfully(body.c_str());
4469 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4470 }
4471
TEST_F(ValidateImage,QueryLodVulkanNonSampledError)4472 TEST_F(ValidateImage, QueryLodVulkanNonSampledError) {
4473 // Create a whole shader module. Avoid Vulkan incompatibility with
4474 // SampledRrect images inserted by helper function GenerateShaderCode.
4475 const std::string body = R"(
4476 OpCapability Shader
4477 OpCapability ImageQuery
4478 OpMemoryModel Logical Simple
4479 OpEntryPoint Fragment %main "main"
4480 OpExecutionMode %main OriginUpperLeft
4481
4482 OpDecorate %sampled_image DescriptorSet 0
4483 OpDecorate %sampled_image Binding 0
4484
4485 %f32 = OpTypeFloat 32
4486 %f32vec2 = OpTypeVector %f32 2
4487 %f32vec2_null = OpConstantNull %f32vec2
4488 %u32 = OpTypeInt 32 0
4489 %u32vec2 = OpTypeVector %u32 2
4490 %void = OpTypeVoid
4491 %voidfn = OpTypeFunction %void
4492
4493 ; Test with an image with Sampled = 2
4494 ; In Vulkan it Sampled must be 1 or 2, checked in another part of the
4495 ; validation flow.
4496 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4497
4498 ; Expect to fail here.
4499 %sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0002
4500 %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
4501 %sampled_image = OpVariable %ptr_sampled_image_ty UniformConstant
4502
4503 %main = OpFunction %void None %voidfn
4504 %entry = OpLabel
4505 %simg = OpLoad %sampled_image_ty %sampled_image
4506 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
4507 OpReturn
4508 OpFunctionEnd
4509 )";
4510
4511 CompileSuccessfully(body.c_str());
4512 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4513 EXPECT_THAT(getDiagnosticString(),
4514 AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
4515 EXPECT_THAT(getDiagnosticString(),
4516 HasSubstr("Sampled image type requires an image type with "
4517 "\"Sampled\" operand set to 0 or 1"));
4518 }
4519
TEST_F(ValidateImage,QueryLodComputeShaderDerivativesMissingMode)4520 TEST_F(ValidateImage, QueryLodComputeShaderDerivativesMissingMode) {
4521 const std::string body = R"(
4522 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4523 %sampler = OpLoad %type_sampler %uniform_sampler
4524 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4525 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4526 )";
4527
4528 const std::string extra = R"(
4529 OpCapability ComputeDerivativeGroupLinearNV
4530 OpExtension "SPV_NV_compute_shader_derivatives"
4531 )";
4532 const std::string mode = R"(
4533 OpExecutionMode %main LocalSize 8 8 1
4534 )";
4535 CompileSuccessfully(
4536 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4537 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4538 EXPECT_THAT(getDiagnosticString(),
4539 HasSubstr("OpImageQueryLod requires DerivativeGroupQuadsNV or "
4540 "DerivativeGroupLinearNV execution mode for GLCompute "
4541 "execution model"));
4542 }
4543
TEST_F(ValidateImage,ImplicitLodWrongExecutionModel)4544 TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
4545 const std::string body = R"(
4546 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4547 %sampler = OpLoad %type_sampler %uniform_sampler
4548 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4549 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4550 )";
4551
4552 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4553 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4554 EXPECT_THAT(getDiagnosticString(),
4555 HasSubstr("ImplicitLod instructions require Fragment or "
4556 "GLCompute execution model"));
4557 }
4558
TEST_F(ValidateImage,ImplicitLodComputeShaderDerivatives)4559 TEST_F(ValidateImage, ImplicitLodComputeShaderDerivatives) {
4560 const std::string body = R"(
4561 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4562 %sampler = OpLoad %type_sampler %uniform_sampler
4563 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4564 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4565 )";
4566
4567 const std::string extra = R"(
4568 OpCapability ComputeDerivativeGroupLinearNV
4569 OpExtension "SPV_NV_compute_shader_derivatives"
4570 )";
4571 const std::string mode = R"(
4572 OpExecutionMode %main LocalSize 8 8 1
4573 OpExecutionMode %main DerivativeGroupLinearNV
4574 )";
4575 CompileSuccessfully(
4576 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4577 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4578 }
4579
TEST_F(ValidateImage,ImplicitLodComputeShaderDerivativesMissingMode)4580 TEST_F(ValidateImage, ImplicitLodComputeShaderDerivativesMissingMode) {
4581 const std::string body = R"(
4582 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4583 %sampler = OpLoad %type_sampler %uniform_sampler
4584 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4585 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4586 )";
4587
4588 const std::string extra = R"(
4589 OpCapability ComputeDerivativeGroupLinearNV
4590 OpExtension "SPV_NV_compute_shader_derivatives"
4591 )";
4592 const std::string mode = R"(
4593 OpExecutionMode %main LocalSize 8 8 1
4594 )";
4595 CompileSuccessfully(
4596 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4597 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4598 EXPECT_THAT(
4599 getDiagnosticString(),
4600 HasSubstr("ImplicitLod instructions require DerivativeGroupQuadsNV or "
4601 "DerivativeGroupLinearNV execution mode for GLCompute "
4602 "execution model"));
4603 }
4604
TEST_F(ValidateImage,ReadSubpassDataWrongExecutionModel)4605 TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
4606 const std::string body = R"(
4607 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
4608 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
4609 )";
4610
4611 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4612 CompileSuccessfully(GenerateShaderCode(body, extra, "Vertex").c_str());
4613 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4614 EXPECT_THAT(getDiagnosticString(),
4615 HasSubstr("Dim SubpassData requires Fragment execution model"));
4616 }
4617
TEST_F(ValidateImage,SparseSampleImplicitLodSuccess)4618 TEST_F(ValidateImage, SparseSampleImplicitLodSuccess) {
4619 const std::string body = R"(
4620 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4621 %sampler = OpLoad %type_sampler %uniform_sampler
4622 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4623 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh
4624 %res2 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Bias %f32_0_25
4625 %res4 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
4626 %res5 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
4627 %res6 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
4628 %res7 = OpImageSparseSampleImplicitLod %struct_u64_f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
4629 %res8 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
4630 )";
4631
4632 const std::string extra = R"(
4633 OpCapability VulkanMemoryModelKHR
4634 OpExtension "SPV_KHR_vulkan_memory_model"
4635 )";
4636 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4637 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4638 .c_str());
4639 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4640 }
4641
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotStruct)4642 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotStruct) {
4643 const std::string body = R"(
4644 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4645 %sampler = OpLoad %type_sampler %uniform_sampler
4646 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4647 %res1 = OpImageSparseSampleImplicitLod %f32 %simg %f32vec2_hh
4648 )";
4649
4650 CompileSuccessfully(GenerateShaderCode(body).c_str());
4651 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4652 EXPECT_THAT(getDiagnosticString(),
4653 HasSubstr("Expected Result Type to be OpTypeStruct"));
4654 }
4655
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotTwoMembers1)4656 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers1) {
4657 const std::string body = R"(
4658 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4659 %sampler = OpLoad %type_sampler %uniform_sampler
4660 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4661 %res1 = OpImageSparseSampleImplicitLod %struct_u32 %simg %f32vec2_hh
4662 )";
4663
4664 CompileSuccessfully(GenerateShaderCode(body).c_str());
4665 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4666 EXPECT_THAT(getDiagnosticString(),
4667 HasSubstr("Expected Result Type to be a struct containing an int "
4668 "scalar and a texel"));
4669 }
4670
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotTwoMembers2)4671 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers2) {
4672 const std::string body = R"(
4673 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4674 %sampler = OpLoad %type_sampler %uniform_sampler
4675 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4676 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4_u32 %simg %f32vec2_hh
4677 )";
4678
4679 CompileSuccessfully(GenerateShaderCode(body).c_str());
4680 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4681 EXPECT_THAT(getDiagnosticString(),
4682 HasSubstr("Expected Result Type to be a struct containing an "
4683 "int scalar and a texel"));
4684 }
4685
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeFirstMemberNotInt)4686 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeFirstMemberNotInt) {
4687 const std::string body = R"(
4688 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4689 %sampler = OpLoad %type_sampler %uniform_sampler
4690 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4691 %res1 = OpImageSparseSampleImplicitLod %struct_f32_f32vec4 %simg %f32vec2_hh
4692 )";
4693
4694 CompileSuccessfully(GenerateShaderCode(body).c_str());
4695 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4696 EXPECT_THAT(getDiagnosticString(),
4697 HasSubstr("Expected Result Type to be a struct containing an "
4698 "int scalar and a texel"));
4699 }
4700
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeTexelNotVector)4701 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeTexelNotVector) {
4702 const std::string body = R"(
4703 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4704 %sampler = OpLoad %type_sampler %uniform_sampler
4705 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4706 %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32 %simg %f32vec2_hh
4707 )";
4708
4709 CompileSuccessfully(GenerateShaderCode(body).c_str());
4710 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4711 EXPECT_THAT(getDiagnosticString(),
4712 HasSubstr("Expected Result Type's second member to be int or "
4713 "float vector type"));
4714 }
4715
TEST_F(ValidateImage,SparseSampleImplicitLodWrongNumComponentsTexel)4716 TEST_F(ValidateImage, SparseSampleImplicitLodWrongNumComponentsTexel) {
4717 const std::string body = R"(
4718 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4719 %sampler = OpLoad %type_sampler %uniform_sampler
4720 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4721 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec3 %simg %f32vec2_hh
4722 )";
4723
4724 CompileSuccessfully(GenerateShaderCode(body).c_str());
4725 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4726 EXPECT_THAT(getDiagnosticString(),
4727 HasSubstr("Expected Result Type's second member to have 4 "
4728 "components"));
4729 }
4730
TEST_F(ValidateImage,SparseSampleImplicitLodWrongComponentTypeTexel)4731 TEST_F(ValidateImage, SparseSampleImplicitLodWrongComponentTypeTexel) {
4732 const std::string body = R"(
4733 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4734 %sampler = OpLoad %type_sampler %uniform_sampler
4735 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4736 %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32vec4 %simg %f32vec2_hh
4737 )";
4738
4739 CompileSuccessfully(GenerateShaderCode(body).c_str());
4740 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4741 EXPECT_THAT(getDiagnosticString(),
4742 HasSubstr("Expected Image 'Sampled Type' to be the same as "
4743 "Result Type's second member components"));
4744 }
4745
TEST_F(ValidateImage,SparseSampleDrefImplicitLodSuccess)4746 TEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) {
4747 const std::string body = R"(
4748 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
4749 %sampler = OpLoad %type_sampler %uniform_sampler
4750 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
4751 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
4752 %res2 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
4753 %res4 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
4754 %res5 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
4755 %res6 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
4756 %res7 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
4757 %res8 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
4758 )";
4759
4760 const std::string extra = R"(
4761 OpCapability VulkanMemoryModelKHR
4762 OpExtension "SPV_KHR_vulkan_memory_model"
4763 )";
4764 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4765 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4766 .c_str());
4767 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4768 }
4769
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotStruct)4770 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotStruct) {
4771 const std::string body = R"(
4772 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4773 %sampler = OpLoad %type_sampler %uniform_sampler
4774 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4775 %res1 = OpImageSparseSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1
4776 )";
4777
4778 CompileSuccessfully(GenerateShaderCode(body).c_str());
4779 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4780 EXPECT_THAT(getDiagnosticString(),
4781 HasSubstr("Expected Result Type to be OpTypeStruct"));
4782 }
4783
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotTwoMembers1)4784 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers1) {
4785 const std::string body = R"(
4786 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4787 %sampler = OpLoad %type_sampler %uniform_sampler
4788 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4789 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32 %simg %f32vec2_hh %f32_1
4790 )";
4791
4792 CompileSuccessfully(GenerateShaderCode(body).c_str());
4793 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4794 EXPECT_THAT(
4795 getDiagnosticString(),
4796 HasSubstr("Expected Result Type to be a struct containing an int scalar "
4797 "and a texel"));
4798 }
4799
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotTwoMembers2)4800 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers2) {
4801 const std::string body = R"(
4802 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4803 %sampler = OpLoad %type_sampler %uniform_sampler
4804 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4805 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_f32_u32 %simg %f32vec2_hh %f32_1
4806 )";
4807
4808 CompileSuccessfully(GenerateShaderCode(body).c_str());
4809 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4810 EXPECT_THAT(
4811 getDiagnosticString(),
4812 HasSubstr("Expected Result Type to be a struct containing an int scalar "
4813 "and a texel"));
4814 }
4815
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt)4816 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt) {
4817 const std::string body = R"(
4818 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4819 %sampler = OpLoad %type_sampler %uniform_sampler
4820 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4821 %res1 = OpImageSparseSampleDrefImplicitLod %struct_f32_f32 %simg %f32vec2_hh %f32_1
4822 )";
4823
4824 CompileSuccessfully(GenerateShaderCode(body).c_str());
4825 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4826 EXPECT_THAT(
4827 getDiagnosticString(),
4828 HasSubstr("Expected Result Type to be a struct containing an int scalar "
4829 "and a texel"));
4830 }
4831
TEST_F(ValidateImage,SparseSampleDrefImplicitLodDifferentSampledType)4832 TEST_F(ValidateImage, SparseSampleDrefImplicitLodDifferentSampledType) {
4833 const std::string body = R"(
4834 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4835 %sampler = OpLoad %type_sampler %uniform_sampler
4836 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4837 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
4838 )";
4839
4840 CompileSuccessfully(GenerateShaderCode(body).c_str());
4841 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4842 EXPECT_THAT(getDiagnosticString(),
4843 HasSubstr("Expected Image 'Sampled Type' to be the same as "
4844 "Result Type's second member"));
4845 }
4846
TEST_F(ValidateImage,SparseFetchSuccess)4847 TEST_F(ValidateImage, SparseFetchSuccess) {
4848 const std::string body = R"(
4849 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
4850 %res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
4851 %res2 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
4852 )";
4853
4854 const std::string extra = R"(
4855 OpCapability VulkanMemoryModelKHR
4856 OpExtension "SPV_KHR_vulkan_memory_model"
4857 )";
4858 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4859 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4860 .c_str());
4861 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4862 }
4863
TEST_F(ValidateImage,SparseFetchResultTypeNotStruct)4864 TEST_F(ValidateImage, SparseFetchResultTypeNotStruct) {
4865 const std::string body = R"(
4866 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4867 %res1 = OpImageSparseFetch %f32 %img %u32vec2_01
4868 )";
4869
4870 CompileSuccessfully(GenerateShaderCode(body).c_str());
4871 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4872 EXPECT_THAT(getDiagnosticString(),
4873 HasSubstr("Expected Result Type to be OpTypeStruct"));
4874 }
4875
TEST_F(ValidateImage,SparseFetchResultTypeNotTwoMembers1)4876 TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers1) {
4877 const std::string body = R"(
4878 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4879 %res1 = OpImageSparseFetch %struct_u32 %img %u32vec2_01
4880 )";
4881
4882 CompileSuccessfully(GenerateShaderCode(body).c_str());
4883 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4884 EXPECT_THAT(getDiagnosticString(),
4885 HasSubstr("Expected Result Type to be a struct containing an "
4886 "int scalar and a texel"));
4887 }
4888
TEST_F(ValidateImage,SparseFetchResultTypeNotTwoMembers2)4889 TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers2) {
4890 const std::string body = R"(
4891 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4892 %res1 = OpImageSparseFetch %struct_u32_f32vec4_u32 %img %u32vec2_01
4893 )";
4894
4895 CompileSuccessfully(GenerateShaderCode(body).c_str());
4896 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4897 EXPECT_THAT(getDiagnosticString(),
4898 HasSubstr("Expected Result Type to be a struct containing an "
4899 "int scalar and a texel"));
4900 }
4901
TEST_F(ValidateImage,SparseFetchResultTypeFirstMemberNotInt)4902 TEST_F(ValidateImage, SparseFetchResultTypeFirstMemberNotInt) {
4903 const std::string body = R"(
4904 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4905 %res1 = OpImageSparseFetch %struct_f32_f32vec4 %img %u32vec2_01
4906 )";
4907
4908 CompileSuccessfully(GenerateShaderCode(body).c_str());
4909 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4910 EXPECT_THAT(getDiagnosticString(),
4911 HasSubstr("Expected Result Type to be a struct containing an "
4912 "int scalar and a texel"));
4913 }
4914
TEST_F(ValidateImage,SparseFetchResultTypeTexelNotVector)4915 TEST_F(ValidateImage, SparseFetchResultTypeTexelNotVector) {
4916 const std::string body = R"(
4917 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4918 %res1 = OpImageSparseFetch %struct_u32_u32 %img %u32vec2_01
4919 )";
4920
4921 CompileSuccessfully(GenerateShaderCode(body).c_str());
4922 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4923 EXPECT_THAT(getDiagnosticString(),
4924 HasSubstr("Expected Result Type's second member to be int or "
4925 "float vector type"));
4926 }
4927
TEST_F(ValidateImage,SparseFetchWrongNumComponentsTexel)4928 TEST_F(ValidateImage, SparseFetchWrongNumComponentsTexel) {
4929 const std::string body = R"(
4930 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4931 %res1 = OpImageSparseFetch %struct_u32_f32vec3 %img %u32vec2_01
4932 )";
4933
4934 CompileSuccessfully(GenerateShaderCode(body).c_str());
4935 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4936 EXPECT_THAT(getDiagnosticString(),
4937 HasSubstr("Expected Result Type's second member to have 4 "
4938 "components"));
4939 }
4940
TEST_F(ValidateImage,SparseFetchWrongComponentTypeTexel)4941 TEST_F(ValidateImage, SparseFetchWrongComponentTypeTexel) {
4942 const std::string body = R"(
4943 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4944 %res1 = OpImageSparseFetch %struct_u32_u32vec4 %img %u32vec2_01
4945 )";
4946
4947 CompileSuccessfully(GenerateShaderCode(body).c_str());
4948 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4949 EXPECT_THAT(getDiagnosticString(),
4950 HasSubstr("Expected Image 'Sampled Type' to be the same as "
4951 "Result Type's second member components"));
4952 }
4953
TEST_F(ValidateImage,SparseReadSuccess)4954 TEST_F(ValidateImage, SparseReadSuccess) {
4955 const std::string body = R"(
4956 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4957 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
4958 )";
4959
4960 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4961 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4962 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4963 }
4964
TEST_F(ValidateImage,SparseReadResultTypeNotStruct)4965 TEST_F(ValidateImage, SparseReadResultTypeNotStruct) {
4966 const std::string body = R"(
4967 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4968 %res1 = OpImageSparseRead %f32 %img %u32vec2_01
4969 )";
4970
4971 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4972 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4973 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4974 EXPECT_THAT(getDiagnosticString(),
4975 HasSubstr("Expected Result Type to be OpTypeStruct"));
4976 }
4977
TEST_F(ValidateImage,SparseReadResultTypeNotTwoMembers1)4978 TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers1) {
4979 const std::string body = R"(
4980 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4981 %res1 = OpImageSparseRead %struct_u32 %img %u32vec2_01
4982 )";
4983
4984 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4985 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4986 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4987 EXPECT_THAT(getDiagnosticString(),
4988 HasSubstr("Expected Result Type to be a struct containing an "
4989 "int scalar and a texel"));
4990 }
4991
TEST_F(ValidateImage,SparseReadResultTypeNotTwoMembers2)4992 TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers2) {
4993 const std::string body = R"(
4994 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4995 %res1 = OpImageSparseRead %struct_u32_f32vec4_u32 %img %u32vec2_01
4996 )";
4997
4998 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4999 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5000 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5001 EXPECT_THAT(getDiagnosticString(),
5002 HasSubstr("Expected Result Type to be a struct containing an "
5003 "int scalar and a texel"));
5004 }
5005
TEST_F(ValidateImage,SparseReadResultTypeFirstMemberNotInt)5006 TEST_F(ValidateImage, SparseReadResultTypeFirstMemberNotInt) {
5007 const std::string body = R"(
5008 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5009 %res1 = OpImageSparseRead %struct_f32_f32vec4 %img %u32vec2_01
5010 )";
5011
5012 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5013 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5014 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5015 EXPECT_THAT(getDiagnosticString(),
5016 HasSubstr("Expected Result Type to be a struct containing an "
5017 "int scalar and a texel"));
5018 }
5019
TEST_F(ValidateImage,SparseReadResultTypeTexelWrongType)5020 TEST_F(ValidateImage, SparseReadResultTypeTexelWrongType) {
5021 const std::string body = R"(
5022 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5023 %res1 = OpImageSparseRead %struct_u32_u32arr4 %img %u32vec2_01
5024 )";
5025
5026 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5027 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5028 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5029 EXPECT_THAT(getDiagnosticString(),
5030 HasSubstr("Expected Result Type's second member to be int or "
5031 "float scalar or vector type"));
5032 }
5033
TEST_F(ValidateImage,SparseReadWrongComponentTypeTexel)5034 TEST_F(ValidateImage, SparseReadWrongComponentTypeTexel) {
5035 const std::string body = R"(
5036 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5037 %res1 = OpImageSparseRead %struct_u32_u32vec4 %img %u32vec2_01
5038 )";
5039
5040 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5041 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5042 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5043 EXPECT_THAT(getDiagnosticString(),
5044 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5045 "Result Type's second member components"));
5046 }
5047
TEST_F(ValidateImage,SparseReadSubpassDataNotAllowed)5048 TEST_F(ValidateImage, SparseReadSubpassDataNotAllowed) {
5049 const std::string body = R"(
5050 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
5051 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
5052 )";
5053
5054 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5055 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment").c_str());
5056 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5057 EXPECT_THAT(
5058 getDiagnosticString(),
5059 HasSubstr("Image Dim SubpassData cannot be used with ImageSparseRead"));
5060 }
5061
TEST_F(ValidateImage,SparseGatherSuccess)5062 TEST_F(ValidateImage, SparseGatherSuccess) {
5063 const std::string body = R"(
5064 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5065 %sampler = OpLoad %type_sampler %uniform_sampler
5066 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5067 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1
5068 %res2 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
5069 )";
5070
5071 const std::string extra = R"(
5072 OpCapability VulkanMemoryModelKHR
5073 OpExtension "SPV_KHR_vulkan_memory_model"
5074 )";
5075 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5076 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5077 .c_str());
5078 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5079 }
5080
TEST_F(ValidateImage,SparseGatherResultTypeNotStruct)5081 TEST_F(ValidateImage, SparseGatherResultTypeNotStruct) {
5082 const std::string body = R"(
5083 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5084 %sampler = OpLoad %type_sampler %uniform_sampler
5085 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5086 %res1 = OpImageSparseGather %f32 %simg %f32vec2_hh %u32_1
5087 )";
5088
5089 CompileSuccessfully(GenerateShaderCode(body).c_str());
5090 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5091 EXPECT_THAT(getDiagnosticString(),
5092 HasSubstr("Expected Result Type to be OpTypeStruct"));
5093 }
5094
TEST_F(ValidateImage,SparseGatherResultTypeNotTwoMembers1)5095 TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers1) {
5096 const std::string body = R"(
5097 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5098 %sampler = OpLoad %type_sampler %uniform_sampler
5099 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5100 %res1 = OpImageSparseGather %struct_u32 %simg %f32vec2_hh %u32_1
5101 )";
5102
5103 CompileSuccessfully(GenerateShaderCode(body).c_str());
5104 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5105 EXPECT_THAT(getDiagnosticString(),
5106 HasSubstr("Expected Result Type to be a struct containing an int "
5107 "scalar and a texel"));
5108 }
5109
TEST_F(ValidateImage,SparseGatherResultTypeNotTwoMembers2)5110 TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers2) {
5111 const std::string body = R"(
5112 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5113 %sampler = OpLoad %type_sampler %uniform_sampler
5114 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5115 %res1 = OpImageSparseGather %struct_u32_f32vec4_u32 %simg %f32vec2_hh %u32_1
5116 )";
5117
5118 CompileSuccessfully(GenerateShaderCode(body).c_str());
5119 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5120 EXPECT_THAT(getDiagnosticString(),
5121 HasSubstr("Expected Result Type to be a struct containing an int "
5122 "scalar and a texel"));
5123 }
5124
TEST_F(ValidateImage,SparseGatherResultTypeFirstMemberNotInt)5125 TEST_F(ValidateImage, SparseGatherResultTypeFirstMemberNotInt) {
5126 const std::string body = R"(
5127 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5128 %sampler = OpLoad %type_sampler %uniform_sampler
5129 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5130 %res1 = OpImageSparseGather %struct_f32_f32vec4 %simg %f32vec2_hh %u32_1
5131 )";
5132
5133 CompileSuccessfully(GenerateShaderCode(body).c_str());
5134 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5135 EXPECT_THAT(getDiagnosticString(),
5136 HasSubstr("Expected Result Type to be a struct containing an "
5137 "int scalar and a texel"));
5138 }
5139
TEST_F(ValidateImage,SparseGatherResultTypeTexelNotVector)5140 TEST_F(ValidateImage, SparseGatherResultTypeTexelNotVector) {
5141 const std::string body = R"(
5142 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5143 %sampler = OpLoad %type_sampler %uniform_sampler
5144 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5145 %res1 = OpImageSparseGather %struct_u32_u32 %simg %f32vec2_hh %u32_1
5146 )";
5147
5148 CompileSuccessfully(GenerateShaderCode(body).c_str());
5149 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5150 EXPECT_THAT(getDiagnosticString(),
5151 HasSubstr("Expected Result Type's second member to be int or "
5152 "float vector type"));
5153 }
5154
TEST_F(ValidateImage,SparseGatherWrongNumComponentsTexel)5155 TEST_F(ValidateImage, SparseGatherWrongNumComponentsTexel) {
5156 const std::string body = R"(
5157 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5158 %sampler = OpLoad %type_sampler %uniform_sampler
5159 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5160 %res1 = OpImageSparseGather %struct_u32_f32vec3 %simg %f32vec2_hh %u32_1
5161 )";
5162
5163 CompileSuccessfully(GenerateShaderCode(body).c_str());
5164 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5165 EXPECT_THAT(getDiagnosticString(),
5166 HasSubstr("Expected Result Type's second member to have 4 "
5167 "components"));
5168 }
5169
TEST_F(ValidateImage,SparseGatherWrongComponentTypeTexel)5170 TEST_F(ValidateImage, SparseGatherWrongComponentTypeTexel) {
5171 const std::string body = R"(
5172 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5173 %sampler = OpLoad %type_sampler %uniform_sampler
5174 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5175 %res1 = OpImageSparseGather %struct_u32_u32vec4 %simg %f32vec2_hh %u32_1
5176 )";
5177
5178 CompileSuccessfully(GenerateShaderCode(body).c_str());
5179 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5180 EXPECT_THAT(getDiagnosticString(),
5181 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5182 "Result Type's second member components"));
5183 }
5184
TEST_F(ValidateImage,SparseTexelsResidentSuccess)5185 TEST_F(ValidateImage, SparseTexelsResidentSuccess) {
5186 const std::string body = R"(
5187 %res1 = OpImageSparseTexelsResident %bool %u32_1
5188 )";
5189
5190 CompileSuccessfully(GenerateShaderCode(body).c_str());
5191 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5192 }
5193
TEST_F(ValidateImage,SparseTexelsResidentResultTypeNotBool)5194 TEST_F(ValidateImage, SparseTexelsResidentResultTypeNotBool) {
5195 const std::string body = R"(
5196 %res1 = OpImageSparseTexelsResident %u32 %u32_1
5197 )";
5198
5199 CompileSuccessfully(GenerateShaderCode(body).c_str());
5200 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5201 EXPECT_THAT(getDiagnosticString(),
5202 HasSubstr("Expected Result Type to be bool scalar type"));
5203 }
5204
TEST_F(ValidateImage,MakeTexelVisibleKHRSuccessImageRead)5205 TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageRead) {
5206 const std::string body = R"(
5207 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5208 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
5209 )";
5210
5211 const std::string extra = R"(
5212 OpCapability StorageImageReadWithoutFormat
5213 OpCapability VulkanMemoryModelKHR
5214 OpExtension "SPV_KHR_vulkan_memory_model"
5215 )";
5216 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5217 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5218 .c_str());
5219 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5220 }
5221
TEST_F(ValidateImage,MakeTexelVisibleKHRSuccessImageSparseRead)5222 TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageSparseRead) {
5223 const std::string body = R"(
5224 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5225 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
5226 )";
5227
5228 const std::string extra = R"(
5229 OpCapability StorageImageReadWithoutFormat
5230 OpCapability VulkanMemoryModelKHR
5231 OpExtension "SPV_KHR_vulkan_memory_model"
5232 )";
5233 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5234 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5235 .c_str());
5236 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5237 }
5238
TEST_F(ValidateImage,MakeTexelVisibleKHRFailureOpcode)5239 TEST_F(ValidateImage, MakeTexelVisibleKHRFailureOpcode) {
5240 const std::string body = R"(
5241 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5242 %sampler = OpLoad %type_sampler %uniform_sampler
5243 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5244 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5245 )";
5246
5247 const std::string extra = R"(
5248 OpCapability StorageImageReadWithoutFormat
5249 OpCapability VulkanMemoryModelKHR
5250 OpExtension "SPV_KHR_vulkan_memory_model"
5251 )";
5252 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5253 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5254 .c_str());
5255 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5256 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5257 EXPECT_THAT(
5258 getDiagnosticString(),
5259 HasSubstr("Image Operand MakeTexelVisibleKHR can only be used with "
5260 "OpImageRead or OpImageSparseRead: OpImageSampleImplicitLod"));
5261 }
5262
TEST_F(ValidateImage,MakeTexelVisibleKHRFailureMissingNonPrivate)5263 TEST_F(ValidateImage, MakeTexelVisibleKHRFailureMissingNonPrivate) {
5264 const std::string body = R"(
5265 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5266 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR %u32_1
5267 )";
5268
5269 const std::string extra = R"(
5270 OpCapability StorageImageReadWithoutFormat
5271 OpCapability VulkanMemoryModelKHR
5272 OpExtension "SPV_KHR_vulkan_memory_model"
5273 )";
5274 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5275 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5276 .c_str());
5277 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5278 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5279 EXPECT_THAT(getDiagnosticString(),
5280 HasSubstr("Image Operand MakeTexelVisibleKHR requires "
5281 "NonPrivateTexelKHR is also specified: OpImageRead"));
5282 }
5283
TEST_F(ValidateImage,MakeTexelAvailableKHRSuccessImageWrite)5284 TEST_F(ValidateImage, MakeTexelAvailableKHRSuccessImageWrite) {
5285 const std::string body = R"(
5286 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5287 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2
5288 )";
5289
5290 const std::string extra = R"(
5291 OpCapability StorageImageWriteWithoutFormat
5292 OpCapability VulkanMemoryModelKHR
5293 OpExtension "SPV_KHR_vulkan_memory_model"
5294 )";
5295 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5296 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5297 .c_str());
5298 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5299 }
5300
TEST_F(ValidateImage,MakeTexelAvailableKHRFailureOpcode)5301 TEST_F(ValidateImage, MakeTexelAvailableKHRFailureOpcode) {
5302 const std::string body = R"(
5303 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5304 %sampler = OpLoad %type_sampler %uniform_sampler
5305 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5306 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5307 )";
5308
5309 const std::string extra = R"(
5310 OpCapability StorageImageReadWithoutFormat
5311 OpCapability VulkanMemoryModelKHR
5312 OpExtension "SPV_KHR_vulkan_memory_model"
5313 )";
5314 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5315 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5316 .c_str());
5317 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5318 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5319 EXPECT_THAT(getDiagnosticString(),
5320 HasSubstr("Image Operand MakeTexelAvailableKHR can only be used "
5321 "with OpImageWrite: OpImageSampleImplicitLod"));
5322 }
5323
TEST_F(ValidateImage,MakeTexelAvailableKHRFailureMissingNonPrivate)5324 TEST_F(ValidateImage, MakeTexelAvailableKHRFailureMissingNonPrivate) {
5325 const std::string body = R"(
5326 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5327 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1
5328 )";
5329
5330 const std::string extra = R"(
5331 OpCapability StorageImageWriteWithoutFormat
5332 OpCapability VulkanMemoryModelKHR
5333 OpExtension "SPV_KHR_vulkan_memory_model"
5334 )";
5335 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5336 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5337 .c_str());
5338 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5339 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5340 EXPECT_THAT(getDiagnosticString(),
5341 HasSubstr("Image Operand MakeTexelAvailableKHR requires "
5342 "NonPrivateTexelKHR is also specified: OpImageWrite"));
5343 }
5344
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageWriteBad)5345 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteBad) {
5346 const std::string body = R"(
5347 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5348 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5349 )";
5350
5351 const std::string extra = R"(
5352 OpCapability StorageImageWriteWithoutFormat
5353 OpCapability VulkanMemoryModelKHR
5354 OpExtension "SPV_KHR_vulkan_memory_model"
5355 )";
5356 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5357 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5358 .c_str());
5359 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5360 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5361 EXPECT_THAT(
5362 getDiagnosticString(),
5363 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
5364 "VulkanMemoryModelDeviceScopeKHR capability"));
5365 }
5366
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageWriteGood)5367 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteGood) {
5368 const std::string body = R"(
5369 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5370 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5371 )";
5372
5373 const std::string extra = R"(
5374 OpCapability StorageImageWriteWithoutFormat
5375 OpCapability VulkanMemoryModelKHR
5376 OpCapability VulkanMemoryModelDeviceScopeKHR
5377 OpExtension "SPV_KHR_vulkan_memory_model"
5378 )";
5379 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5380 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5381 .c_str());
5382 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5383 }
5384
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageReadBad)5385 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadBad) {
5386 const std::string body = R"(
5387 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5388 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5389 )";
5390
5391 const std::string extra = R"(
5392 OpCapability StorageImageReadWithoutFormat
5393 OpCapability VulkanMemoryModelKHR
5394 OpExtension "SPV_KHR_vulkan_memory_model"
5395 )";
5396 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5397 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5398 .c_str());
5399 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5400 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5401 EXPECT_THAT(
5402 getDiagnosticString(),
5403 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
5404 "VulkanMemoryModelDeviceScopeKHR capability"));
5405 }
5406
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageReadGood)5407 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadGood) {
5408 const std::string body = R"(
5409 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5410 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5411 )";
5412
5413 const std::string extra = R"(
5414 OpCapability StorageImageReadWithoutFormat
5415 OpCapability VulkanMemoryModelKHR
5416 OpCapability VulkanMemoryModelDeviceScopeKHR
5417 OpExtension "SPV_KHR_vulkan_memory_model"
5418 )";
5419 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5420 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5421 .c_str());
5422 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5423 }
5424
5425 // This example used to cause a seg fault on OpReturnValue, verifying it doesn't
5426 // anymore.
TEST_F(ValidateImage,Issue2463NoSegFault)5427 TEST_F(ValidateImage, Issue2463NoSegFault) {
5428 const std::string spirv = R"(
5429 OpCapability Linkage
5430 OpCapability Shader
5431 %1 = OpExtInstImport "GLSL.std.450"
5432 OpMemoryModel Logical GLSL450
5433 %void = OpTypeVoid
5434 %6 = OpTypeFunction %void
5435 %float = OpTypeFloat 32
5436 %8 = OpTypeImage %float 3D 0 0 0 1 Unknown
5437 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
5438 %10 = OpTypeSampler
5439 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
5440 %12 = OpTypeSampledImage %8
5441 %13 = OpTypeFunction %12 %_ptr_UniformConstant_8 %_ptr_UniformConstant_10
5442 %23 = OpFunction %12 None %13
5443 %24 = OpFunctionParameter %_ptr_UniformConstant_8
5444 %25 = OpFunctionParameter %_ptr_UniformConstant_10
5445 %26 = OpLabel
5446 %27 = OpLoad %8 %24
5447 %28 = OpLoad %10 %25
5448 %29 = OpSampledImage %12 %27 %28
5449 OpReturnValue %29
5450 OpFunctionEnd
5451 )";
5452
5453 CompileSuccessfully(spirv);
5454 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5455 EXPECT_THAT(getDiagnosticString(),
5456 HasSubstr("OpSampledImage instruction must not appear as operand "
5457 "for OpReturnValue"));
5458 }
5459
TEST_F(ValidateImage,SignExtendV13Bad)5460 TEST_F(ValidateImage, SignExtendV13Bad) {
5461 const std::string body = R"(
5462 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5463 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
5464 )";
5465
5466 EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
5467 SPV_ENV_UNIVERSAL_1_3)),
5468 HasSubstr("Invalid image operand 'SignExtend'"));
5469 }
5470
TEST_F(ValidateImage,ZeroExtendV13Bad)5471 TEST_F(ValidateImage, ZeroExtendV13Bad) {
5472 const std::string body = R"(
5473 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5474 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
5475 )";
5476
5477 EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
5478 SPV_ENV_UNIVERSAL_1_3)),
5479 HasSubstr("Invalid image operand 'ZeroExtend'"));
5480 }
5481
TEST_F(ValidateImage,SignExtendScalarUIntTexelV14Good)5482 TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) {
5483 // Unsigned int sampled type
5484 const std::string body = R"(
5485 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5486 %res1 = OpImageRead %u32 %img %u32vec2_01 SignExtend
5487 )";
5488 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5489
5490 CompileSuccessfully(
5491 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5492 SPV_ENV_UNIVERSAL_1_4);
5493 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5494 EXPECT_THAT(getDiagnosticString(), Eq(""));
5495 }
5496
TEST_F(ValidateImage,SignExtendScalarSIntTexelV14Good)5497 TEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) {
5498 // Signed int sampled type
5499 const std::string body = R"(
5500 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5501 %res1 = OpImageRead %s32 %img %u32vec2_01 SignExtend
5502 )";
5503 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5504
5505 CompileSuccessfully(
5506 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5507 SPV_ENV_UNIVERSAL_1_4);
5508 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5509 EXPECT_THAT(getDiagnosticString(), Eq(""));
5510 }
5511
TEST_F(ValidateImage,SignExtendScalarVectorUIntTexelV14Good)5512 TEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) {
5513 const std::string body = R"(
5514 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5515 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
5516 )";
5517 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5518
5519 CompileSuccessfully(
5520 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5521 SPV_ENV_UNIVERSAL_1_4);
5522 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5523 EXPECT_THAT(getDiagnosticString(), Eq(""));
5524 }
5525
TEST_F(ValidateImage,SignExtendVectorSIntTexelV14Good)5526 TEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) {
5527 const std::string body = R"(
5528 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5529 %res1 = OpImageRead %s32vec4 %img %u32vec2_01 SignExtend
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
5540 // No negative tests for SignExtend since we don't truly know the
5541 // texel format.
5542
TEST_F(ValidateImage,ZeroExtendScalarUIntTexelV14Good)5543 TEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) {
5544 // Unsigned int sampled type
5545 const std::string body = R"(
5546 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5547 %res1 = OpImageRead %u32 %img %u32vec2_01 ZeroExtend
5548 )";
5549 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5550
5551 CompileSuccessfully(
5552 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5553 SPV_ENV_UNIVERSAL_1_4);
5554 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5555 EXPECT_THAT(getDiagnosticString(), Eq(""));
5556 }
5557
TEST_F(ValidateImage,ZeroExtendScalarSIntTexelV14Good)5558 TEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) {
5559 // Zeroed int sampled type
5560 const std::string body = R"(
5561 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5562 %res1 = OpImageRead %s32 %img %u32vec2_01 ZeroExtend
5563 )";
5564 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5565
5566 CompileSuccessfully(
5567 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5568 SPV_ENV_UNIVERSAL_1_4);
5569 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5570 EXPECT_THAT(getDiagnosticString(), Eq(""));
5571 }
5572
TEST_F(ValidateImage,ZeroExtendScalarVectorUIntTexelV14Good)5573 TEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) {
5574 const std::string body = R"(
5575 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5576 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
5577 )";
5578 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5579
5580 CompileSuccessfully(
5581 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5582 SPV_ENV_UNIVERSAL_1_4);
5583 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5584 EXPECT_THAT(getDiagnosticString(), Eq(""));
5585 }
5586
TEST_F(ValidateImage,ZeroExtendVectorSIntTexelV14Good)5587 TEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) {
5588 const std::string body = R"(
5589 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5590 %res1 = OpImageRead %s32vec4 %img %u32vec2_01 ZeroExtend
5591 )";
5592 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5593
5594 CompileSuccessfully(
5595 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5596 SPV_ENV_UNIVERSAL_1_4);
5597 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5598 EXPECT_THAT(getDiagnosticString(), Eq(""));
5599 }
5600
TEST_F(ValidateImage,ReadLodAMDSuccess1)5601 TEST_F(ValidateImage, ReadLodAMDSuccess1) {
5602 const std::string body = R"(
5603 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5604 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 Lod %u32_0
5605 )";
5606
5607 const std::string extra =
5608 "\nOpCapability StorageImageReadWithoutFormat\n"
5609 "OpCapability ImageReadWriteLodAMD\n"
5610 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
5611 CompileSuccessfully(
5612 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
5613 SPV_ENV_UNIVERSAL_1_1);
5614 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
5615 }
5616
TEST_F(ValidateImage,ReadLodAMDSuccess2)5617 TEST_F(ValidateImage, ReadLodAMDSuccess2) {
5618 const std::string body = R"(
5619 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
5620 %res1 = OpImageRead %f32vec4 %img %u32vec2_01 Lod %u32_0
5621 )";
5622
5623 const std::string extra =
5624 "\nOpCapability Image1D\n"
5625 "OpCapability ImageReadWriteLodAMD\n"
5626 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
5627 CompileSuccessfully(
5628 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
5629 SPV_ENV_UNIVERSAL_1_1);
5630 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
5631 }
5632
TEST_F(ValidateImage,ReadLodAMDSuccess3)5633 TEST_F(ValidateImage, ReadLodAMDSuccess3) {
5634 const std::string body = R"(
5635 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
5636 %res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
5637 )";
5638
5639 const std::string extra =
5640 "\nOpCapability ImageCubeArray\n"
5641 "OpCapability ImageReadWriteLodAMD\n"
5642 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
5643 CompileSuccessfully(
5644 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
5645 SPV_ENV_UNIVERSAL_1_1);
5646 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
5647 }
5648
TEST_F(ValidateImage,ReadLodAMDNeedCapability)5649 TEST_F(ValidateImage, ReadLodAMDNeedCapability) {
5650 const std::string body = R"(
5651 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
5652 %res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
5653 )";
5654
5655 const std::string extra = "\nOpCapability ImageCubeArray\n";
5656 CompileSuccessfully(
5657 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
5658 SPV_ENV_UNIVERSAL_1_1);
5659 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5660 ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
5661 EXPECT_THAT(getDiagnosticString(),
5662 HasSubstr("Image Operand Lod can only be used with ExplicitLod "
5663 "opcodes and OpImageFetch"));
5664 }
5665
TEST_F(ValidateImage,WriteLodAMDSuccess1)5666 TEST_F(ValidateImage, WriteLodAMDSuccess1) {
5667 const std::string body = R"(
5668 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5669 OpImageWrite %img %u32vec2_01 %u32vec4_0123 Lod %u32_0
5670 )";
5671
5672 const std::string extra =
5673 "\nOpCapability StorageImageWriteWithoutFormat\n"
5674 "OpCapability ImageReadWriteLodAMD\n"
5675 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
5676 CompileSuccessfully(
5677 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
5678 SPV_ENV_UNIVERSAL_1_1);
5679 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
5680 }
5681
TEST_F(ValidateImage,WriteLodAMDSuccess2)5682 TEST_F(ValidateImage, WriteLodAMDSuccess2) {
5683 const std::string body = R"(
5684 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
5685 OpImageWrite %img %u32_1 %f32vec4_0000 Lod %u32_0
5686 )";
5687
5688 const std::string extra =
5689 "\nOpCapability Image1D\n"
5690 "OpCapability ImageReadWriteLodAMD\n"
5691 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
5692 CompileSuccessfully(
5693 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
5694 SPV_ENV_UNIVERSAL_1_1);
5695 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
5696 }
5697
TEST_F(ValidateImage,WriteLodAMDSuccess3)5698 TEST_F(ValidateImage, WriteLodAMDSuccess3) {
5699 const std::string body = R"(
5700 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
5701 OpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
5702 )";
5703
5704 const std::string extra =
5705 "\nOpCapability ImageCubeArray\n"
5706 "OpCapability ImageReadWriteLodAMD\n"
5707 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
5708 CompileSuccessfully(
5709 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
5710 SPV_ENV_UNIVERSAL_1_1);
5711 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
5712 }
5713
TEST_F(ValidateImage,WriteLodAMDNeedCapability)5714 TEST_F(ValidateImage, WriteLodAMDNeedCapability) {
5715 const std::string body = R"(
5716 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
5717 OpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
5718 )";
5719
5720 const std::string extra = "\nOpCapability ImageCubeArray\n";
5721 CompileSuccessfully(
5722 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
5723 SPV_ENV_UNIVERSAL_1_1);
5724 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5725 ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
5726 EXPECT_THAT(getDiagnosticString(),
5727 HasSubstr("Image Operand Lod can only be used with ExplicitLod "
5728 "opcodes and OpImageFetch"));
5729 }
5730
TEST_F(ValidateImage,SparseReadLodAMDSuccess)5731 TEST_F(ValidateImage, SparseReadLodAMDSuccess) {
5732 const std::string body = R"(
5733 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5734 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
5735 )";
5736
5737 const std::string extra =
5738 "\nOpCapability StorageImageReadWithoutFormat\n"
5739 "OpCapability ImageReadWriteLodAMD\n"
5740 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
5741 CompileSuccessfully(
5742 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
5743 SPV_ENV_UNIVERSAL_1_1);
5744 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
5745 }
5746
TEST_F(ValidateImage,SparseReadLodAMDNeedCapability)5747 TEST_F(ValidateImage, SparseReadLodAMDNeedCapability) {
5748 const std::string body = R"(
5749 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5750 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
5751 )";
5752
5753 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5754 CompileSuccessfully(
5755 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
5756 SPV_ENV_UNIVERSAL_1_1);
5757 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5758 ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
5759 EXPECT_THAT(getDiagnosticString(),
5760 HasSubstr("Image Operand Lod can only be used with ExplicitLod "
5761 "opcodes and OpImageFetch"));
5762 }
5763
TEST_F(ValidateImage,GatherBiasAMDSuccess)5764 TEST_F(ValidateImage, GatherBiasAMDSuccess) {
5765 const std::string body = R"(
5766 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5767 %sampler = OpLoad %type_sampler %uniform_sampler
5768 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5769 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
5770 )";
5771
5772 const std::string extra = R"(
5773 OpCapability ImageGatherBiasLodAMD
5774 OpExtension "SPV_AMD_texture_gather_bias_lod"
5775 )";
5776 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5777 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5778 }
5779
TEST_F(ValidateImage,GatherLodAMDSuccess)5780 TEST_F(ValidateImage, GatherLodAMDSuccess) {
5781 const std::string body = R"(
5782 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5783 %sampler = OpLoad %type_sampler %uniform_sampler
5784 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5785 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
5786 )";
5787
5788 const std::string extra = R"(
5789 OpCapability ImageGatherBiasLodAMD
5790 OpExtension "SPV_AMD_texture_gather_bias_lod"
5791 )";
5792 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5793 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5794 }
5795
TEST_F(ValidateImage,SparseGatherBiasAMDSuccess)5796 TEST_F(ValidateImage, SparseGatherBiasAMDSuccess) {
5797 const std::string body = R"(
5798 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5799 %sampler = OpLoad %type_sampler %uniform_sampler
5800 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5801 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
5802 )";
5803
5804 const std::string extra = R"(
5805 OpCapability ImageGatherBiasLodAMD
5806 OpExtension "SPV_AMD_texture_gather_bias_lod"
5807 )";
5808 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5809 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5810 }
5811
TEST_F(ValidateImage,SparseGatherLodAMDSuccess)5812 TEST_F(ValidateImage, SparseGatherLodAMDSuccess) {
5813 const std::string body = R"(
5814 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5815 %sampler = OpLoad %type_sampler %uniform_sampler
5816 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5817 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
5818 )";
5819
5820 const std::string extra = R"(
5821 OpCapability ImageGatherBiasLodAMD
5822 OpExtension "SPV_AMD_texture_gather_bias_lod"
5823 )";
5824 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5825 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5826 }
5827
5828 // No negative tests for ZeroExtend since we don't truly know the
5829 // texel format.
5830
5831 // Tests for 64-bit images
5832 static const std::string capabilities_and_extensions_image64 = R"(
5833 OpCapability Int64ImageEXT
5834 OpExtension "SPV_EXT_shader_image_int64"
5835 )";
5836 static const std::string capabilities_and_extensions_image64_atomic = R"(
5837 OpCapability Int64Atomics
5838 OpCapability Int64ImageEXT
5839 OpExtension "SPV_EXT_shader_image_int64"
5840 )";
5841 static const std::string declarations_image64 = R"(
5842 %type_image_u64_buffer_0002_r64ui = OpTypeImage %u64 Buffer 0 0 0 2 R64ui
5843 %ptr_Image_u64 = OpTypePointer Image %u64
5844 %ptr_image_u64_buffer_0002_r64ui = OpTypePointer Private %type_image_u64_buffer_0002_r64ui
5845 %private_image_u64_buffer_0002_r64ui = OpVariable %ptr_image_u64_buffer_0002_r64ui Private
5846 )";
5847 static const std::string declarations_image64i = R"(
5848 %type_image_s64_buffer_0002_r64i = OpTypeImage %s64 Buffer 0 0 0 2 R64i
5849 %ptr_Image_s64 = OpTypePointer Image %s64
5850 %ptr_image_s64_buffer_0002_r64i = OpTypePointer Private %type_image_s64_buffer_0002_r64i
5851 %private_image_s64_buffer_0002_r64i = OpVariable %ptr_image_s64_buffer_0002_r64i Private
5852 )";
5853
TEST_F(ValidateImage,Image64MissingCapability)5854 TEST_F(ValidateImage, Image64MissingCapability) {
5855 CompileSuccessfully(GenerateShaderCode("", "", "Fragment", "",
5856 SPV_ENV_UNIVERSAL_1_3, "GLSL450",
5857 declarations_image64)
5858 .c_str());
5859 ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
5860 }
5861
TEST_F(ValidateImage,Image64MissingExtension)5862 TEST_F(ValidateImage, Image64MissingExtension) {
5863 const std::string extra = R"(
5864 OpCapability Int64ImageEXT
5865 )";
5866
5867 CompileSuccessfully(GenerateShaderCode("", extra, "Fragment", "",
5868 SPV_ENV_UNIVERSAL_1_3, "GLSL450",
5869 declarations_image64)
5870 .c_str());
5871 ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
5872 }
5873
TEST_F(ValidateImage,ImageTexelPointer64Success)5874 TEST_F(ValidateImage, ImageTexelPointer64Success) {
5875 const std::string body = R"(
5876 %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
5877 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
5878 )";
5879
5880 CompileSuccessfully(
5881 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
5882 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
5883 declarations_image64)
5884 .c_str());
5885 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5886 }
5887
TEST_F(ValidateImage,ImageTexelPointer64ResultTypeNotPointer)5888 TEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotPointer) {
5889 const std::string body = R"(
5890 %texel_ptr = OpImageTexelPointer %type_image_u64_buffer_0002_r64ui %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
5891 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
5892 )";
5893
5894 CompileSuccessfully(
5895 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
5896 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
5897 declarations_image64)
5898 .c_str());
5899 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5900 EXPECT_THAT(getDiagnosticString(),
5901 HasSubstr("Expected Result Type to be OpTypePointer"));
5902 }
5903
TEST_F(ValidateImage,ImageTexelPointer64ResultTypeNotImageClass)5904 TEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotImageClass) {
5905 const std::string body = R"(
5906 %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
5907 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
5908 )";
5909
5910 CompileSuccessfully(
5911 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
5912 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
5913 declarations_image64)
5914 .c_str());
5915 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5916 EXPECT_THAT(getDiagnosticString(),
5917 HasSubstr("Expected Result Type to be OpTypePointer whose "
5918 "Storage Class operand is Image"));
5919 }
5920
TEST_F(ValidateImage,ImageTexelPointer64SampleNotZeroForImageWithMSZero)5921 TEST_F(ValidateImage, ImageTexelPointer64SampleNotZeroForImageWithMSZero) {
5922 const std::string body = R"(
5923 %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_1
5924 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
5925 )";
5926
5927 CompileSuccessfully(
5928 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
5929 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
5930 declarations_image64)
5931 .c_str());
5932 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5933 EXPECT_THAT(getDiagnosticString(),
5934 HasSubstr("Expected Sample for Image with MS 0 to be a valid "
5935 "<id> for the value 0"));
5936 }
5937
TEST_F(ValidateImage,ImageTexelPointerR32uiSuccessVulkan)5938 TEST_F(ValidateImage, ImageTexelPointerR32uiSuccessVulkan) {
5939 const std::string body = R"(
5940 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
5941 )";
5942
5943 spv_target_env env = SPV_ENV_VULKAN_1_0;
5944 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
5945 env);
5946 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
5947 }
5948
TEST_F(ValidateImage,ImageTexelPointerR32iSuccessVulkan)5949 TEST_F(ValidateImage, ImageTexelPointerR32iSuccessVulkan) {
5950 const std::string& declarations = R"(
5951 %type_image_s32_buffer_0002_r32i = OpTypeImage %s32 Buffer 0 0 0 2 R32i
5952 %ptr_Image_s32 = OpTypePointer Image %s32
5953 %ptr_image_s32_buffer_0002_r32i = OpTypePointer Private %type_image_s32_buffer_0002_r32i
5954 %private_image_s32_buffer_0002_r32i = OpVariable %ptr_image_s32_buffer_0002_r32i Private
5955 )";
5956
5957 const std::string body = R"(
5958 %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_r32i %u32_0 %u32_0
5959 )";
5960
5961 spv_target_env env = SPV_ENV_VULKAN_1_0;
5962 CompileSuccessfully(
5963 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
5964 .c_str(),
5965 env);
5966 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
5967 }
5968
TEST_F(ValidateImage,ImageTexelPointerR64uiSuccessVulkan)5969 TEST_F(ValidateImage, ImageTexelPointerR64uiSuccessVulkan) {
5970 const std::string body = R"(
5971 %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
5972 )";
5973
5974 spv_target_env env = SPV_ENV_VULKAN_1_0;
5975 CompileSuccessfully(
5976 GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
5977 "", env, "GLSL450", declarations_image64)
5978 .c_str(),
5979 env);
5980 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
5981 }
5982
TEST_F(ValidateImage,ImageTexelPointerR64iSuccessVulkan)5983 TEST_F(ValidateImage, ImageTexelPointerR64iSuccessVulkan) {
5984 const std::string body = R"(
5985 %texel_ptr = OpImageTexelPointer %ptr_Image_s64 %private_image_s64_buffer_0002_r64i %u32_0 %u32_0
5986 )";
5987
5988 spv_target_env env = SPV_ENV_VULKAN_1_0;
5989 CompileSuccessfully(
5990 GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
5991 "", env, "GLSL450", declarations_image64i)
5992 .c_str(),
5993 env);
5994 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
5995 }
5996
TEST_F(ValidateImage,ImageTexelPointerR32fSuccessVulkan)5997 TEST_F(ValidateImage, ImageTexelPointerR32fSuccessVulkan) {
5998 const std::string& declarations = R"(
5999 %type_image_f32_buffer_0002_r32f = OpTypeImage %f32 Buffer 0 0 0 2 R32f
6000 %ptr_image_f32_buffer_0002_r32f = OpTypePointer Private %type_image_f32_buffer_0002_r32f
6001 %private_image_f32_buffer_0002_r32f = OpVariable %ptr_image_f32_buffer_0002_r32f Private
6002 )";
6003
6004 const std::string body = R"(
6005 %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32f %u32_0 %u32_0
6006 )";
6007
6008 spv_target_env env = SPV_ENV_VULKAN_1_0;
6009 CompileSuccessfully(
6010 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6011 .c_str(),
6012 env);
6013 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6014 }
6015
TEST_F(ValidateImage,ImageTexelPointerRgba32iVulkan)6016 TEST_F(ValidateImage, ImageTexelPointerRgba32iVulkan) {
6017 const std::string& declarations = R"(
6018 %type_image_s32_buffer_0002_rgba32i = OpTypeImage %s32 Buffer 0 0 0 2 Rgba32i
6019 %ptr_Image_s32 = OpTypePointer Image %s32
6020 %ptr_image_s32_buffer_0002_rgba32i = OpTypePointer Private %type_image_s32_buffer_0002_rgba32i
6021 %private_image_s32_buffer_0002_rgba32i = OpVariable %ptr_image_s32_buffer_0002_rgba32i Private
6022 )";
6023
6024 const std::string body = R"(
6025 %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba32i %u32_0 %u32_0
6026 )";
6027
6028 spv_target_env env = SPV_ENV_VULKAN_1_0;
6029 CompileSuccessfully(
6030 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6031 .c_str(),
6032 env);
6033 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
6034 EXPECT_THAT(getDiagnosticString(),
6035 AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
6036 EXPECT_THAT(getDiagnosticString(),
6037 HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
6038 "R32f, R32i, or R32ui for Vulkan environment"));
6039 }
6040
TEST_F(ValidateImage,ImageTexelPointerRgba16fVulkan)6041 TEST_F(ValidateImage, ImageTexelPointerRgba16fVulkan) {
6042 const std::string& declarations = R"(
6043 %type_image_s32_buffer_0002_rgba16f = OpTypeImage %s32 Buffer 0 0 0 2 Rgba16f
6044 %ptr_Image_s32 = OpTypePointer Image %s32
6045 %ptr_image_s32_buffer_0002_rgba16f = OpTypePointer Private %type_image_s32_buffer_0002_rgba16f
6046 %private_image_s32_buffer_0002_rgba16f = OpVariable %ptr_image_s32_buffer_0002_rgba16f Private
6047 )";
6048
6049 const std::string body = R"(
6050 %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba16f %u32_0 %u32_0
6051 )";
6052
6053 spv_target_env env = SPV_ENV_VULKAN_1_0;
6054 CompileSuccessfully(
6055 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6056 .c_str(),
6057 env);
6058 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
6059 EXPECT_THAT(getDiagnosticString(),
6060 AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
6061 EXPECT_THAT(getDiagnosticString(),
6062 HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
6063 "R32f, R32i, or R32ui for Vulkan environment"));
6064 }
6065
TEST_F(ValidateImage,ImageExecutionModeLimitationNoMode)6066 TEST_F(ValidateImage, ImageExecutionModeLimitationNoMode) {
6067 const std::string text = R"(
6068 OpCapability Shader
6069 OpMemoryModel Logical GLSL450
6070 OpEntryPoint GLCompute %2 " " %4
6071 %void = OpTypeVoid
6072 %8 = OpTypeFunction %void
6073 %float = OpTypeFloat 32
6074 %v4float = OpTypeVector %float 4
6075 %12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
6076 %13 = OpTypeSampledImage %12
6077 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6078 %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
6079 %_ptr_Input_v4float = OpTypePointer Input %v4float
6080 %4 = OpVariable %_ptr_Input_v4float Input
6081 %v2float = OpTypeVector %float 2
6082 %float_1_35631564en19 = OpConstant %float 1.35631564e-19
6083 %2 = OpFunction %void None %8
6084 %8224 = OpLabel
6085 %6 = OpLoad %13 %5
6086 %19 = OpLoad %v4float %4
6087 %20 = OpVectorShuffle %v2float %19 %19 0 1
6088 %21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
6089 %65312 = OpImageSampleImplicitLod %v4float %6 %21
6090 OpUnreachable
6091 OpFunctionEnd
6092 )";
6093
6094 CompileSuccessfully(text);
6095 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6096 EXPECT_THAT(getDiagnosticString(),
6097 HasSubstr("ImplicitLod instructions require "
6098 "DerivativeGroupQuadsNV or DerivativeGroupLinearNV "
6099 "execution mode for GLCompute execution model"));
6100 }
6101
6102 } // namespace
6103 } // namespace val
6104 } // namespace spvtools
6105