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