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 %boolvec4 = OpTypeVector %bool 4
153
154 %f32_0 = OpConstant %f32 0
155 %f32_1 = OpConstant %f32 1
156 %f32_0_5 = OpConstant %f32 0.5
157 %f32_0_25 = OpConstant %f32 0.25
158 %f32_0_75 = OpConstant %f32 0.75
159
160 %f64_0 = OpConstant %f64 0
161 %f64_1 = OpConstant %f64 1
162
163 %s32_0 = OpConstant %s32 0
164 %s32_1 = OpConstant %s32 1
165 %s32_2 = OpConstant %s32 2
166 %s32_3 = OpConstant %s32 3
167 %s32_4 = OpConstant %s32 4
168 %s32_m1 = OpConstant %s32 -1
169
170 %u32_0 = OpConstant %u32 0
171 %u32_1 = OpConstant %u32 1
172 %u32_2 = OpConstant %u32 2
173 %u32_3 = OpConstant %u32 3
174 %u32_4 = OpConstant %u32 4
175
176 %u64_0 = OpConstant %u64 0
177 %u64_1 = OpConstant %u64 1
178
179 %bool_t = OpConstantTrue %bool
180
181 %u32vec2arr4 = OpTypeArray %u32vec2 %u32_4
182 %u32vec2arr3 = OpTypeArray %u32vec2 %u32_3
183 %u32arr4 = OpTypeArray %u32 %u32_4
184 %u32vec3arr4 = OpTypeArray %u32vec3 %u32_4
185
186 %struct_u32_f32vec4 = OpTypeStruct %u32 %f32vec4
187 %struct_u64_f32vec4 = OpTypeStruct %u64 %f32vec4
188 %struct_u32_u32vec4 = OpTypeStruct %u32 %u32vec4
189 %struct_u32_f32vec3 = OpTypeStruct %u32 %f32vec3
190 %struct_f32_f32vec4 = OpTypeStruct %f32 %f32vec4
191 %struct_u32_u32 = OpTypeStruct %u32 %u32
192 %struct_f32_f32 = OpTypeStruct %f32 %f32
193 %struct_u32 = OpTypeStruct %u32
194 %struct_u32_f32_u32 = OpTypeStruct %u32 %f32 %u32
195 %struct_u32_f32vec4_u32 = OpTypeStruct %u32 %f32vec4 %u32
196 %struct_u32_u32arr4 = OpTypeStruct %u32 %u32arr4
197
198 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
199 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
200 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
201 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
202 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
203 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
204
205 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
206 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
207 %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
208 %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
209 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
210 %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
211
212 %f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
213 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
214 %f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
215 %f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
216 %f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
217
218 %f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
219 %f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
220
221 %f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
222
223 %boolvec4_tttt = OpConstantComposite %boolvec4 %bool_t %bool_t %bool_t %bool_t
224
225 %const_offsets = OpConstantComposite %u32vec2arr4 %u32vec2_01 %u32vec2_12 %u32vec2_01 %u32vec2_12
226 %const_offsets3x2 = OpConstantComposite %u32vec2arr3 %u32vec2_01 %u32vec2_12 %u32vec2_01
227 %const_offsets4xu = OpConstantComposite %u32arr4 %u32_0 %u32_0 %u32_0 %u32_0
228 %const_offsets4x3 = OpConstantComposite %u32vec3arr4 %u32vec3_012 %u32vec3_012 %u32vec3_012 %u32vec3_012
229
230 %type_image_f32_1d_0001 = OpTypeImage %f32 1D 0 0 0 1 Unknown
231 %ptr_image_f32_1d_0001 = OpTypePointer UniformConstant %type_image_f32_1d_0001
232 %uniform_image_f32_1d_0001 = OpVariable %ptr_image_f32_1d_0001 UniformConstant
233 %type_sampled_image_f32_1d_0001 = OpTypeSampledImage %type_image_f32_1d_0001
234
235 %type_image_f32_1d_0002_rgba32f = OpTypeImage %f32 1D 0 0 0 2 Rgba32f
236 %ptr_image_f32_1d_0002_rgba32f = OpTypePointer UniformConstant %type_image_f32_1d_0002_rgba32f
237 %uniform_image_f32_1d_0002_rgba32f = OpVariable %ptr_image_f32_1d_0002_rgba32f UniformConstant
238
239 %type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
240 %ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
241 %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
242 %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
243
244 %type_image_f32_2d_0011 = OpTypeImage %f32 2D 0 0 1 1 Unknown
245 %ptr_image_f32_2d_0011 = OpTypePointer UniformConstant %type_image_f32_2d_0011
246 %uniform_image_f32_2d_0011 = OpVariable %ptr_image_f32_2d_0011 UniformConstant
247 %type_sampled_image_f32_2d_0011 = OpTypeSampledImage %type_image_f32_2d_0011
248
249 %type_image_u32_2d_0001 = OpTypeImage %u32 2D 0 0 0 1 Unknown
250 %ptr_image_u32_2d_0001 = OpTypePointer UniformConstant %type_image_u32_2d_0001
251 %uniform_image_u32_2d_0001 = OpVariable %ptr_image_u32_2d_0001 UniformConstant
252 %type_sampled_image_u32_2d_0001 = OpTypeSampledImage %type_image_u32_2d_0001
253
254 %type_image_u32_3d_0001 = OpTypeImage %u32 3D 0 0 0 1 Unknown
255 %ptr_image_u32_3d_0001 = OpTypePointer UniformConstant %type_image_u32_3d_0001
256 %uniform_image_u32_3d_0001 = OpVariable %ptr_image_u32_3d_0001 UniformConstant
257 %type_sampled_image_u32_3d_0001 = OpTypeSampledImage %type_image_u32_3d_0001
258
259 %type_image_u32_2d_0002 = OpTypeImage %u32 2D 0 0 0 2 Unknown
260 %ptr_image_u32_2d_0002 = OpTypePointer UniformConstant %type_image_u32_2d_0002
261 %uniform_image_u32_2d_0002 = OpVariable %ptr_image_u32_2d_0002 UniformConstant
262
263 %type_image_s32_3d_0001 = OpTypeImage %s32 3D 0 0 0 1 Unknown
264 %ptr_image_s32_3d_0001 = OpTypePointer UniformConstant %type_image_s32_3d_0001
265 %uniform_image_s32_3d_0001 = OpVariable %ptr_image_s32_3d_0001 UniformConstant
266 %type_sampled_image_s32_3d_0001 = OpTypeSampledImage %type_image_s32_3d_0001
267
268 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Unknown
269 %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
270 %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
271
272 %type_image_s32_2d_0002 = OpTypeImage %s32 2D 0 0 0 2 Unknown
273 %ptr_image_s32_2d_0002 = OpTypePointer UniformConstant %type_image_s32_2d_0002
274 %uniform_image_s32_2d_0002 = OpVariable %ptr_image_s32_2d_0002 UniformConstant
275
276 %type_image_f32_spd_0002 = OpTypeImage %f32 SubpassData 0 0 0 2 Unknown
277 %ptr_image_f32_spd_0002 = OpTypePointer UniformConstant %type_image_f32_spd_0002
278 %uniform_image_f32_spd_0002 = OpVariable %ptr_image_f32_spd_0002 UniformConstant
279
280 %type_image_f32_3d_0111 = OpTypeImage %f32 3D 0 1 1 1 Unknown
281 %ptr_image_f32_3d_0111 = OpTypePointer UniformConstant %type_image_f32_3d_0111
282 %uniform_image_f32_3d_0111 = OpVariable %ptr_image_f32_3d_0111 UniformConstant
283 %type_sampled_image_f32_3d_0111 = OpTypeSampledImage %type_image_f32_3d_0111
284
285 %type_image_f32_3d_0001 = OpTypeImage %f32 3D 0 0 0 1 Unknown
286 %ptr_image_f32_3d_0001 = OpTypePointer UniformConstant %type_image_f32_3d_0001
287 %uniform_image_f32_3d_0001 = OpVariable %ptr_image_f32_3d_0001 UniformConstant
288 %type_sampled_image_f32_3d_0001 = OpTypeSampledImage %type_image_f32_3d_0001
289
290 %type_image_f32_cube_0101 = OpTypeImage %f32 Cube 0 1 0 1 Unknown
291 %ptr_image_f32_cube_0101 = OpTypePointer UniformConstant %type_image_f32_cube_0101
292 %uniform_image_f32_cube_0101 = OpVariable %ptr_image_f32_cube_0101 UniformConstant
293 %type_sampled_image_f32_cube_0101 = OpTypeSampledImage %type_image_f32_cube_0101
294
295 %type_image_f32_cube_0102_rgba32f = OpTypeImage %f32 Cube 0 1 0 2 Rgba32f
296 %ptr_image_f32_cube_0102_rgba32f = OpTypePointer UniformConstant %type_image_f32_cube_0102_rgba32f
297 %uniform_image_f32_cube_0102_rgba32f = OpVariable %ptr_image_f32_cube_0102_rgba32f UniformConstant
298
299 %type_sampler = OpTypeSampler
300 %ptr_sampler = OpTypePointer UniformConstant %type_sampler
301 %uniform_sampler = OpVariable %ptr_sampler UniformConstant
302
303 %type_image_u32_buffer_0002_r32ui = OpTypeImage %u32 Buffer 0 0 0 2 R32ui
304 %ptr_Image_u32 = OpTypePointer Image %u32
305 %ptr_image_u32_buffer_0002_r32ui = OpTypePointer Private %type_image_u32_buffer_0002_r32ui
306 %private_image_u32_buffer_0002_r32ui = OpVariable %ptr_image_u32_buffer_0002_r32ui Private
307
308 %ptr_Image_u32arr4 = OpTypePointer Image %u32arr4
309
310 %type_image_u32_spd_0002 = OpTypeImage %u32 SubpassData 0 0 0 2 Unknown
311 %ptr_image_u32_spd_0002 = OpTypePointer Private %type_image_u32_spd_0002
312 %private_image_u32_spd_0002 = OpVariable %ptr_image_u32_spd_0002 Private
313
314 %type_image_f32_buffer_0002_r32ui = OpTypeImage %f32 Buffer 0 0 0 2 R32ui
315 %ptr_Image_f32 = OpTypePointer Image %f32
316 %ptr_image_f32_buffer_0002_r32ui = OpTypePointer Private %type_image_f32_buffer_0002_r32ui
317 %private_image_f32_buffer_0002_r32ui = OpVariable %ptr_image_f32_buffer_0002_r32ui Private
318
319 %ptr_input_flat_u32 = OpTypePointer Input %u32
320 %input_flat_u32 = OpVariable %ptr_input_flat_u32 Input
321 )";
322
323 if (env == SPV_ENV_UNIVERSAL_1_0) {
324 ss << R"(
325 %type_image_void_2d_0001 = OpTypeImage %void 2D 0 0 0 1 Unknown
326 %ptr_image_void_2d_0001 = OpTypePointer UniformConstant %type_image_void_2d_0001
327 %uniform_image_void_2d_0001 = OpVariable %ptr_image_void_2d_0001 UniformConstant
328 %type_sampled_image_void_2d_0001 = OpTypeSampledImage %type_image_void_2d_0001
329
330 %type_image_void_2d_0002 = OpTypeImage %void 2D 0 0 0 2 Unknown
331 %ptr_image_void_2d_0002 = OpTypePointer UniformConstant %type_image_void_2d_0002
332 %uniform_image_void_2d_0002 = OpVariable %ptr_image_void_2d_0002 UniformConstant
333
334 %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
335 %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
336 %uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
337 %type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
338 )";
339 }
340
341 ss << declarations;
342
343 ss << R"(
344 %main = OpFunction %void None %func
345 %main_entry = OpLabel
346 )";
347
348 ss << body;
349
350 ss << R"(
351 OpReturn
352 OpFunctionEnd)";
353
354 return ss.str();
355 }
356
GenerateKernelCode(const std::string & body,const std::string & capabilities_and_extensions="",const std::string & declarations="")357 std::string GenerateKernelCode(
358 const std::string& body,
359 const std::string& capabilities_and_extensions = "",
360 const std::string& declarations = "") {
361 std::ostringstream ss;
362 ss << R"(
363 OpCapability Addresses
364 OpCapability Kernel
365 OpCapability Linkage
366 OpCapability ImageQuery
367 OpCapability ImageGatherExtended
368 OpCapability InputAttachment
369 OpCapability SampledRect
370 )";
371
372 ss << capabilities_and_extensions;
373 ss << R"(
374 OpMemoryModel Physical32 OpenCL
375 %void = OpTypeVoid
376 %func = OpTypeFunction %void
377 %bool = OpTypeBool
378 %f32 = OpTypeFloat 32
379 %u32 = OpTypeInt 32 0
380 %u32vec2 = OpTypeVector %u32 2
381 %f32vec2 = OpTypeVector %f32 2
382 %u32vec3 = OpTypeVector %u32 3
383 %f32vec3 = OpTypeVector %f32 3
384 %u32vec4 = OpTypeVector %u32 4
385 %f32vec4 = OpTypeVector %f32 4
386
387 %f32_0 = OpConstant %f32 0
388 %f32_1 = OpConstant %f32 1
389 %f32_0_5 = OpConstant %f32 0.5
390 %f32_0_25 = OpConstant %f32 0.25
391 %f32_0_75 = OpConstant %f32 0.75
392
393 %u32_0 = OpConstant %u32 0
394 %u32_1 = OpConstant %u32 1
395 %u32_2 = OpConstant %u32 2
396 %u32_3 = OpConstant %u32 3
397 %u32_4 = OpConstant %u32 4
398
399 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
400 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
401 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
402 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
403 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
404 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
405
406 %f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
407 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
408 %f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
409 %f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
410 %f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
411
412 %f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
413 %f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
414
415 %f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
416
417 %type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
418 %ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
419 %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
420 %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
421
422 %type_image_f32_2d_0011 = OpTypeImage %f32 2D 0 0 1 1 Unknown
423 %ptr_image_f32_2d_0011 = OpTypePointer UniformConstant %type_image_f32_2d_0011
424 %uniform_image_f32_2d_0011 = OpVariable %ptr_image_f32_2d_0011 UniformConstant
425 %type_sampled_image_f32_2d_0011 = OpTypeSampledImage %type_image_f32_2d_0011
426
427 %type_image_f32_3d_0011 = OpTypeImage %f32 3D 0 0 1 1 Unknown
428 %ptr_image_f32_3d_0011 = OpTypePointer UniformConstant %type_image_f32_3d_0011
429 %uniform_image_f32_3d_0011 = OpVariable %ptr_image_f32_3d_0011 UniformConstant
430 %type_sampled_image_f32_3d_0011 = OpTypeSampledImage %type_image_f32_3d_0011
431
432 %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
433 %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
434 %uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
435 %type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
436
437 %type_sampler = OpTypeSampler
438 %ptr_sampler = OpTypePointer UniformConstant %type_sampler
439 %uniform_sampler = OpVariable %ptr_sampler UniformConstant
440 )";
441
442 ss << declarations;
443
444 ss << R"(
445 %main = OpFunction %void None %func
446 %main_entry = OpLabel
447 )";
448
449 ss << body;
450 ss << R"(
451 OpReturn
452 OpFunctionEnd)";
453
454 return ss.str();
455 }
456
GetKernelHeader()457 std::string GetKernelHeader() {
458 return R"(
459 OpCapability Kernel
460 OpCapability Addresses
461 OpCapability Linkage
462 OpMemoryModel Physical32 OpenCL
463 %void = OpTypeVoid
464 %func = OpTypeFunction %void
465 %f32 = OpTypeFloat 32
466 %u32 = OpTypeInt 32 0
467 )";
468 }
469
TrivialMain()470 std::string TrivialMain() {
471 return R"(
472 %main = OpFunction %void None %func
473 %entry = OpLabel
474 OpReturn
475 OpFunctionEnd
476 )";
477 }
478
GetShaderHeader(const std::string & capabilities_and_extensions="",bool include_entry_point=true)479 std::string GetShaderHeader(const std::string& capabilities_and_extensions = "",
480 bool include_entry_point = true) {
481 std::ostringstream ss;
482 ss << R"(
483 OpCapability Shader
484 OpCapability Int64
485 OpCapability Float64
486 )";
487
488 if (!include_entry_point) {
489 ss << "OpCapability Linkage\n";
490 }
491 ss << capabilities_and_extensions;
492
493 ss << R"(
494 OpMemoryModel Logical GLSL450
495 )";
496
497 if (include_entry_point) {
498 ss << "OpEntryPoint Fragment %main \"main\"\n";
499 ss << "OpExecutionMode %main OriginUpperLeft";
500 }
501 ss << R"(
502 %void = OpTypeVoid
503 %func = OpTypeFunction %void
504 %bool = OpTypeBool
505 %f32 = OpTypeFloat 32
506 %f64 = OpTypeFloat 64
507 %u32 = OpTypeInt 32 0
508 %u64 = OpTypeInt 64 0
509 %s32 = OpTypeInt 32 1
510 %s64 = OpTypeInt 64 1
511 )";
512
513 return ss.str();
514 }
515
TEST_F(ValidateImage,TypeImageWrongSampledType)516 TEST_F(ValidateImage, TypeImageWrongSampledType) {
517 const std::string code = GetShaderHeader("", false) + R"(
518 %img_type = OpTypeImage %bool 2D 0 0 0 1 Unknown
519 )";
520
521 CompileSuccessfully(code.c_str());
522 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
523 EXPECT_THAT(getDiagnosticString(),
524 HasSubstr("Expected Sampled Type to be either void or "
525 "numerical scalar "
526 "type"));
527 }
528
TEST_F(ValidateImage,TypeImageVoidSampledTypeVulkan)529 TEST_F(ValidateImage, TypeImageVoidSampledTypeVulkan) {
530 const std::string code = GetShaderHeader() + R"(
531 %img_type = OpTypeImage %void 2D 0 0 0 1 Unknown
532 %main = OpFunction %void None %func
533 %main_lab = OpLabel
534 OpReturn
535 OpFunctionEnd
536 )";
537
538 const spv_target_env env = SPV_ENV_VULKAN_1_0;
539 CompileSuccessfully(code, env);
540 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
541 EXPECT_THAT(getDiagnosticString(),
542 AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
543 EXPECT_THAT(getDiagnosticString(),
544 HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
545 "or 32-bit float scalar type for Vulkan environment"));
546 }
547
TEST_F(ValidateImage,TypeImageU32SampledTypeVulkan)548 TEST_F(ValidateImage, TypeImageU32SampledTypeVulkan) {
549 const std::string code = GetShaderHeader() + R"(
550 %img_type = OpTypeImage %u32 2D 0 0 0 1 Unknown
551 %main = OpFunction %void None %func
552 %main_lab = OpLabel
553 OpReturn
554 OpFunctionEnd
555 )";
556
557 const spv_target_env env = SPV_ENV_VULKAN_1_0;
558 CompileSuccessfully(code, env);
559 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
560 EXPECT_THAT(getDiagnosticString(), Eq(""));
561 }
562
TEST_F(ValidateImage,TypeImageI32SampledTypeVulkan)563 TEST_F(ValidateImage, TypeImageI32SampledTypeVulkan) {
564 const std::string code = GetShaderHeader() + R"(
565 %img_type = OpTypeImage %s32 2D 0 0 0 1 Unknown
566 %main = OpFunction %void None %func
567 %main_lab = OpLabel
568 OpReturn
569 OpFunctionEnd
570 )";
571
572 const spv_target_env env = SPV_ENV_VULKAN_1_0;
573 CompileSuccessfully(code, env);
574 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
575 EXPECT_THAT(getDiagnosticString(), Eq(""));
576 }
577
TEST_F(ValidateImage,TypeImageI64SampledTypeNoCapabilityVulkan)578 TEST_F(ValidateImage, TypeImageI64SampledTypeNoCapabilityVulkan) {
579 const std::string code = GetShaderHeader() + R"(
580 %img_type = OpTypeImage %s64 2D 0 0 0 1 Unknown
581 %main = OpFunction %void None %func
582 %main_lab = OpLabel
583 OpReturn
584 OpFunctionEnd
585 )";
586
587 const spv_target_env env = SPV_ENV_VULKAN_1_0;
588 CompileSuccessfully(code, env);
589 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
590 EXPECT_THAT(getDiagnosticString(),
591 HasSubstr("Capability Int64ImageEXT is required when using "
592 "Sampled Type of 64-bit int"));
593 }
594
TEST_F(ValidateImage,TypeImageI64SampledTypeVulkan)595 TEST_F(ValidateImage, TypeImageI64SampledTypeVulkan) {
596 const std::string code = GetShaderHeader(
597 "OpCapability Int64ImageEXT\nOpExtension "
598 "\"SPV_EXT_shader_image_int64\"\n") +
599 R"(
600 %img_type = OpTypeImage %s64 2D 0 0 0 1 Unknown
601 %main = OpFunction %void None %func
602 %main_lab = OpLabel
603 OpReturn
604 OpFunctionEnd
605 )";
606
607 const spv_target_env env = SPV_ENV_VULKAN_1_0;
608 CompileSuccessfully(code, env);
609 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
610 EXPECT_THAT(getDiagnosticString(), Eq(""));
611 }
612
TEST_F(ValidateImage,TypeImageU64SampledTypeNoCapabilityVulkan)613 TEST_F(ValidateImage, TypeImageU64SampledTypeNoCapabilityVulkan) {
614 const std::string code = GetShaderHeader() + R"(
615 %img_type = OpTypeImage %u64 2D 0 0 0 1 Unknown
616 %main = OpFunction %void None %func
617 %main_lab = OpLabel
618 OpReturn
619 OpFunctionEnd
620 )";
621
622 const spv_target_env env = SPV_ENV_VULKAN_1_0;
623 CompileSuccessfully(code, env);
624 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
625 EXPECT_THAT(getDiagnosticString(),
626 HasSubstr("Capability Int64ImageEXT is required when using "
627 "Sampled Type of 64-bit int"));
628 }
629
TEST_F(ValidateImage,TypeImageU64SampledTypeVulkan)630 TEST_F(ValidateImage, TypeImageU64SampledTypeVulkan) {
631 const std::string code = GetShaderHeader(
632 "OpCapability Int64ImageEXT\nOpExtension "
633 "\"SPV_EXT_shader_image_int64\"\n") +
634 R"(
635 %img_type = OpTypeImage %u64 2D 0 0 0 1 Unknown
636 %main = OpFunction %void None %func
637 %main_lab = OpLabel
638 OpReturn
639 OpFunctionEnd
640 )";
641
642 const spv_target_env env = SPV_ENV_VULKAN_1_0;
643 CompileSuccessfully(code, env);
644 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
645 EXPECT_THAT(getDiagnosticString(), Eq(""));
646 }
647
TEST_F(ValidateImage,TypeImageF32SampledTypeVulkan)648 TEST_F(ValidateImage, TypeImageF32SampledTypeVulkan) {
649 const std::string code = GetShaderHeader() + R"(
650 %img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown
651 %main = OpFunction %void None %func
652 %main_lab = OpLabel
653 OpReturn
654 OpFunctionEnd
655 )";
656
657 const spv_target_env env = SPV_ENV_VULKAN_1_0;
658 CompileSuccessfully(code, env);
659 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
660 EXPECT_THAT(getDiagnosticString(), Eq(""));
661 }
662
TEST_F(ValidateImage,TypeImageF64SampledTypeVulkan)663 TEST_F(ValidateImage, TypeImageF64SampledTypeVulkan) {
664 const std::string code = GetShaderHeader() + R"(
665 %img_type = OpTypeImage %f64 2D 0 0 0 1 Unknown
666 %main = OpFunction %void None %func
667 %main_lab = OpLabel
668 OpReturn
669 OpFunctionEnd
670 )";
671
672 const spv_target_env env = SPV_ENV_VULKAN_1_0;
673 CompileSuccessfully(code, env);
674 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
675 EXPECT_THAT(getDiagnosticString(),
676 AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
677 EXPECT_THAT(getDiagnosticString(),
678 HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
679 "or 32-bit float scalar type for Vulkan environment"));
680 }
681
TEST_F(ValidateImage,TypeImageF64SampledTypeWithInt64Vulkan)682 TEST_F(ValidateImage, TypeImageF64SampledTypeWithInt64Vulkan) {
683 const std::string code = GetShaderHeader(
684 "OpCapability Int64ImageEXT\nOpExtension "
685 "\"SPV_EXT_shader_image_int64\"\n") +
686 R"(
687 %img_type = OpTypeImage %f64 2D 0 0 0 1 Unknown
688 %main = OpFunction %void None %func
689 %main_lab = OpLabel
690 OpReturn
691 OpFunctionEnd
692 )";
693
694 const spv_target_env env = SPV_ENV_VULKAN_1_0;
695 CompileSuccessfully(code, env);
696 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
697 EXPECT_THAT(getDiagnosticString(),
698 AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04656"));
699 EXPECT_THAT(getDiagnosticString(),
700 HasSubstr("Expected Sampled Type to be a 32-bit int, 64-bit int "
701 "or 32-bit float scalar type for Vulkan environment"));
702 }
703
TEST_F(ValidateImage,TypeImageWrongDepth)704 TEST_F(ValidateImage, TypeImageWrongDepth) {
705 const std::string code = GetShaderHeader("", false) + R"(
706 %img_type = OpTypeImage %f32 2D 3 0 0 1 Unknown
707 )";
708
709 CompileSuccessfully(code.c_str());
710 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
711 EXPECT_THAT(getDiagnosticString(),
712 HasSubstr("Invalid Depth 3 (must be 0, 1 or 2)"));
713 }
714
TEST_F(ValidateImage,TypeImageWrongArrayed)715 TEST_F(ValidateImage, TypeImageWrongArrayed) {
716 const std::string code = GetShaderHeader("", false) + R"(
717 %img_type = OpTypeImage %f32 2D 0 2 0 1 Unknown
718 )";
719
720 CompileSuccessfully(code.c_str());
721 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
722 EXPECT_THAT(getDiagnosticString(),
723 HasSubstr("Invalid Arrayed 2 (must be 0 or 1)"));
724 }
725
TEST_F(ValidateImage,TypeImageWrongMS)726 TEST_F(ValidateImage, TypeImageWrongMS) {
727 const std::string code = GetShaderHeader("", false) + R"(
728 %img_type = OpTypeImage %f32 2D 0 0 2 1 Unknown
729 )";
730
731 CompileSuccessfully(code.c_str());
732 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
733 EXPECT_THAT(getDiagnosticString(),
734 HasSubstr("Invalid MS 2 (must be 0 or 1)"));
735 }
736
TEST_F(ValidateImage,TypeImageWrongSampled)737 TEST_F(ValidateImage, TypeImageWrongSampled) {
738 const std::string code = GetShaderHeader("", false) + R"(
739 %img_type = OpTypeImage %f32 2D 0 0 0 3 Unknown
740 )";
741
742 CompileSuccessfully(code.c_str());
743 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
744 EXPECT_THAT(getDiagnosticString(),
745 HasSubstr("Invalid Sampled 3 (must be 0, 1 or 2)"));
746 }
747
TEST_F(ValidateImage,TypeImageWrongSampledForSubpassData)748 TEST_F(ValidateImage, TypeImageWrongSampledForSubpassData) {
749 const std::string code =
750 GetShaderHeader("OpCapability InputAttachment\n", false) +
751 R"(
752 %img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
753 )";
754
755 CompileSuccessfully(code.c_str());
756 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
757 EXPECT_THAT(getDiagnosticString(),
758 HasSubstr("Dim SubpassData requires Sampled to be 2"));
759 }
760
TEST_F(ValidateImage,TypeImageWrongSampledForSubpassDataVulkan)761 TEST_F(ValidateImage, TypeImageWrongSampledForSubpassDataVulkan) {
762 const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
763 R"(
764 %img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
765 )" + TrivialMain();
766
767 CompileSuccessfully(code.c_str());
768 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
769 EXPECT_THAT(getDiagnosticString(),
770 AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06214"));
771 EXPECT_THAT(getDiagnosticString(),
772 HasSubstr("Dim SubpassData requires Sampled to be 2"));
773 }
774
TEST_F(ValidateImage,TypeImageWrongArrayForSubpassDataVulkan)775 TEST_F(ValidateImage, TypeImageWrongArrayForSubpassDataVulkan) {
776 const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
777 R"(
778 %img_type = OpTypeImage %f32 SubpassData 0 1 0 2 Unknown
779 )" + TrivialMain();
780
781 CompileSuccessfully(code.c_str());
782 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
783 EXPECT_THAT(getDiagnosticString(),
784 AnyVUID("VUID-StandaloneSpirv-OpTypeImage-06214"));
785 EXPECT_THAT(getDiagnosticString(),
786 HasSubstr("Dim SubpassData requires Arrayed to be 0"));
787 }
788
TEST_F(ValidateImage,TypeImageWrongSampledTypeForTileImageDataEXT)789 TEST_F(ValidateImage, TypeImageWrongSampledTypeForTileImageDataEXT) {
790 const std::string code = GetShaderHeader(
791 "OpCapability TileImageColorReadAccessEXT\n"
792 "OpExtension \"SPV_EXT_shader_tile_image\"\n",
793 false) +
794 R"(
795 %img_type = OpTypeImage %void TileImageDataEXT 0 0 0 2 Unknown
796 )";
797
798 CompileSuccessfully(code.c_str());
799 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
800 EXPECT_THAT(
801 getDiagnosticString(),
802 HasSubstr(
803 "Dim TileImageDataEXT requires Sampled Type to be not OpTypeVoid"));
804 }
805
TEST_F(ValidateImage,TypeImageWrongSampledForTileImageDataEXT)806 TEST_F(ValidateImage, TypeImageWrongSampledForTileImageDataEXT) {
807 const std::string code = GetShaderHeader(
808 "OpCapability TileImageColorReadAccessEXT\n"
809 "OpExtension \"SPV_EXT_shader_tile_image\"\n",
810 false) +
811 R"(
812 %img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 1 Unknown
813 )";
814
815 CompileSuccessfully(code.c_str());
816 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
817 EXPECT_THAT(getDiagnosticString(),
818 HasSubstr("Dim TileImageDataEXT requires Sampled to be 2"));
819 }
820
TEST_F(ValidateImage,TypeImageWrongFormatForTileImageDataEXT)821 TEST_F(ValidateImage, TypeImageWrongFormatForTileImageDataEXT) {
822 const std::string code = GetShaderHeader(
823 "OpCapability TileImageColorReadAccessEXT\n"
824 "OpExtension \"SPV_EXT_shader_tile_image\"\n",
825 false) +
826 R"(
827 %img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Rgba32f
828 )";
829
830 CompileSuccessfully(code.c_str());
831 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
832 EXPECT_THAT(getDiagnosticString(),
833 HasSubstr("Dim TileImageDataEXT requires format Unknown"));
834 }
835
TEST_F(ValidateImage,TypeImageWrongDepthForTileImageDataEXT)836 TEST_F(ValidateImage, TypeImageWrongDepthForTileImageDataEXT) {
837 const std::string code = GetShaderHeader(
838 "OpCapability TileImageColorReadAccessEXT\n"
839 "OpExtension \"SPV_EXT_shader_tile_image\"\n",
840 false) +
841 R"(
842 %img_type = OpTypeImage %f32 TileImageDataEXT 1 0 0 2 Unknown
843 )";
844
845 CompileSuccessfully(code.c_str());
846 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
847 EXPECT_THAT(getDiagnosticString(),
848 HasSubstr("Dim TileImageDataEXT requires Depth to be 0"));
849 }
850
TEST_F(ValidateImage,TypeImageWrongArrayedForTileImageDataEXT)851 TEST_F(ValidateImage, TypeImageWrongArrayedForTileImageDataEXT) {
852 const std::string code = GetShaderHeader(
853 "OpCapability TileImageColorReadAccessEXT\n"
854 "OpExtension \"SPV_EXT_shader_tile_image\"\n",
855 false) +
856 R"(
857 %img_type = OpTypeImage %f32 TileImageDataEXT 0 1 0 2 Unknown
858 )";
859
860 CompileSuccessfully(code.c_str());
861 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
862 EXPECT_THAT(getDiagnosticString(),
863 HasSubstr("Dim TileImageDataEXT requires Arrayed to be 0"));
864 }
865
TEST_F(ValidateImage,TypeSampledImage_TileImageDataEXT_Error)866 TEST_F(ValidateImage, TypeSampledImage_TileImageDataEXT_Error) {
867 const std::string code = GetShaderHeader(
868 "OpCapability TileImageColorReadAccessEXT\n"
869 "OpExtension \"SPV_EXT_shader_tile_image\"\n",
870 false) +
871 R"(
872 %img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
873 %simg_type = OpTypeSampledImage %img_type
874 )";
875
876 CompileSuccessfully(code.c_str());
877 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
878 EXPECT_THAT(getDiagnosticString(),
879 HasSubstr("Sampled image type requires an image type with "
880 "\"Sampled\" operand set to 0 or 1"));
881 }
882
TEST_F(ValidateImage,ImageTexelPointerImageDimTileImageDataEXTBad)883 TEST_F(ValidateImage, ImageTexelPointerImageDimTileImageDataEXTBad) {
884 const std::string body = R"(
885 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %tile_image_u32_tid_0002 %u32_0 %u32_0
886 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
887 )";
888 const std::string decl = R"(
889 %type_image_u32_tid_0002 = OpTypeImage %u32 TileImageDataEXT 0 0 0 2 Unknown
890 %ptr_image_u32_tid_0002 = OpTypePointer TileImageEXT %type_image_u32_tid_0002
891 %tile_image_u32_tid_0002 = OpVariable %ptr_image_u32_tid_0002 TileImageEXT
892 )";
893
894 const std::string extra = R"(
895 OpCapability TileImageColorReadAccessEXT
896 OpExtension "SPV_EXT_shader_tile_image"
897 )";
898
899 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
900 SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
901 .c_str());
902 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
903 EXPECT_THAT(getDiagnosticString(),
904 HasSubstr("Image Dim TileImageDataEXT cannot be used with "
905 "OpImageTexelPointer"));
906 }
907
TEST_F(ValidateImage,ReadTileImageDataEXT)908 TEST_F(ValidateImage, ReadTileImageDataEXT) {
909 const std::string body = R"(
910 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
911 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
912 )";
913
914 const std::string decl = R"(
915 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
916 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
917 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
918 )";
919
920 const std::string extra = R"(
921 OpCapability StorageImageReadWithoutFormat
922 OpCapability TileImageColorReadAccessEXT
923 OpExtension "SPV_EXT_shader_tile_image"
924 )";
925
926 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
927 SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
928 .c_str());
929 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
930 EXPECT_THAT(
931 getDiagnosticString(),
932 HasSubstr("Image Dim TileImageDataEXT cannot be used with ImageRead"));
933 }
934
TEST_F(ValidateImage,WriteTileImageDataEXT)935 TEST_F(ValidateImage, WriteTileImageDataEXT) {
936 const std::string body = R"(
937 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
938 OpImageWrite %img %u32vec2_01 %f32vec4_0000
939 )";
940
941 const std::string decl = R"(
942 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
943 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
944 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
945 )";
946
947 const std::string extra = R"(
948 OpCapability TileImageColorReadAccessEXT
949 OpExtension "SPV_EXT_shader_tile_image"
950 )";
951
952 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
953 SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
954 .c_str());
955 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
956 EXPECT_THAT(getDiagnosticString(),
957 HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
958 }
959
TEST_F(ValidateImage,QueryFormatTileImageDataEXT)960 TEST_F(ValidateImage, QueryFormatTileImageDataEXT) {
961 const std::string body = R"(
962 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
963 %res1 = OpImageQueryFormat %u32 %img
964 )";
965
966 const std::string decl = R"(
967 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
968 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
969 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
970 )";
971
972 const std::string extra = R"(
973 OpCapability TileImageColorReadAccessEXT
974 OpExtension "SPV_EXT_shader_tile_image"
975 )";
976
977 CompileSuccessfully(GenerateKernelCode(body, extra, decl).c_str());
978
979 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
980 EXPECT_THAT(getDiagnosticString(),
981 HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
982 }
983
TEST_F(ValidateImage,QueryOrderTileImageDataEXT)984 TEST_F(ValidateImage, QueryOrderTileImageDataEXT) {
985 const std::string body = R"(
986 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
987 %res1 = OpImageQueryOrder %u32 %img
988 )";
989
990 const std::string decl = R"(
991 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
992 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
993 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
994 )";
995
996 const std::string extra = R"(
997 OpCapability TileImageColorReadAccessEXT
998 OpExtension "SPV_EXT_shader_tile_image"
999 )";
1000
1001 CompileSuccessfully(GenerateKernelCode(body, extra, decl).c_str());
1002
1003 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1004 EXPECT_THAT(getDiagnosticString(),
1005 HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
1006 }
1007
TEST_F(ValidateImage,SparseFetchTileImageDataEXT)1008 TEST_F(ValidateImage, SparseFetchTileImageDataEXT) {
1009 const std::string body = R"(
1010 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
1011 %res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
1012 )";
1013
1014 const std::string decl = R"(
1015 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
1016 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
1017 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
1018 )";
1019
1020 const std::string extra = R"(
1021 OpCapability StorageImageReadWithoutFormat
1022 OpCapability TileImageColorReadAccessEXT
1023 OpExtension "SPV_EXT_shader_tile_image"
1024 )";
1025
1026 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1027 SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
1028 .c_str());
1029 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1030 EXPECT_THAT(getDiagnosticString(),
1031 HasSubstr("Expected Image 'Sampled' parameter to be 1"));
1032 }
1033
TEST_F(ValidateImage,SparseReadTileImageDataEXT)1034 TEST_F(ValidateImage, SparseReadTileImageDataEXT) {
1035 const std::string body = R"(
1036 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
1037 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
1038 )";
1039
1040 const std::string decl = R"(
1041 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
1042 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
1043 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
1044 )";
1045
1046 const std::string extra = R"(
1047 OpCapability StorageImageReadWithoutFormat
1048 OpCapability TileImageColorReadAccessEXT
1049 OpExtension "SPV_EXT_shader_tile_image"
1050 )";
1051
1052 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1053 SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
1054 .c_str());
1055 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1056 EXPECT_THAT(
1057 getDiagnosticString(),
1058 HasSubstr(
1059 "Image Dim TileImageDataEXT cannot be used with ImageSparseRead"));
1060 }
1061
TEST_F(ValidateImage,TypeImage_OpenCL_Sampled0_OK)1062 TEST_F(ValidateImage, TypeImage_OpenCL_Sampled0_OK) {
1063 const std::string code = GetKernelHeader() + R"(
1064 %img_type = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
1065 )";
1066
1067 CompileSuccessfully(code.c_str());
1068 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1069 EXPECT_THAT(getDiagnosticString(), Eq(""));
1070 }
1071
TEST_F(ValidateImage,TypeImage_OpenCL_Sampled1_Invalid)1072 TEST_F(ValidateImage, TypeImage_OpenCL_Sampled1_Invalid) {
1073 const std::string code = GetKernelHeader() + R"(
1074 %img_type = OpTypeImage %void 2D 0 0 0 1 Unknown ReadOnly
1075 )";
1076
1077 CompileSuccessfully(code.c_str());
1078 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1079 EXPECT_THAT(getDiagnosticString(),
1080 HasSubstr("Sampled must be 0 in the OpenCL environment."));
1081 }
1082
TEST_F(ValidateImage,TypeImage_OpenCL_Sampled2_Invalid)1083 TEST_F(ValidateImage, TypeImage_OpenCL_Sampled2_Invalid) {
1084 const std::string code = GetKernelHeader() + R"(
1085 %img_type = OpTypeImage %void 2D 0 0 0 2 Unknown ReadOnly
1086 )";
1087
1088 CompileSuccessfully(code.c_str());
1089 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1090 EXPECT_THAT(getDiagnosticString(),
1091 HasSubstr("Sampled must be 0 in the OpenCL environment."));
1092 }
1093
TEST_F(ValidateImage,TypeImage_OpenCL_AccessQualifierMissing)1094 TEST_F(ValidateImage, TypeImage_OpenCL_AccessQualifierMissing) {
1095 const std::string code = GetKernelHeader() + R"(
1096 %img_type = OpTypeImage %void 2D 0 0 0 0 Unknown
1097 )";
1098
1099 CompileSuccessfully(code.c_str());
1100 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1101 EXPECT_THAT(getDiagnosticString(),
1102 HasSubstr("In the OpenCL environment, the optional Access "
1103 "Qualifier must be present"));
1104 }
1105
TEST_F(ValidateImage,TypeImage_Vulkan_Sampled1_OK)1106 TEST_F(ValidateImage, TypeImage_Vulkan_Sampled1_OK) {
1107 const std::string code = GetShaderHeader() + R"(
1108 %img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown
1109 )" + TrivialMain();
1110
1111 CompileSuccessfully(code.c_str());
1112 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1113 EXPECT_THAT(getDiagnosticString(), Eq(""));
1114 }
1115
TEST_F(ValidateImage,TypeImage_Vulkan_Sampled2_OK)1116 TEST_F(ValidateImage, TypeImage_Vulkan_Sampled2_OK) {
1117 const std::string code = GetShaderHeader() + R"(
1118 %img_type = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
1119 )" + TrivialMain();
1120
1121 CompileSuccessfully(code.c_str());
1122 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1123 EXPECT_THAT(getDiagnosticString(), Eq(""));
1124 }
1125
TEST_F(ValidateImage,TypeImage_Vulkan_Sampled0_Invalid)1126 TEST_F(ValidateImage, TypeImage_Vulkan_Sampled0_Invalid) {
1127 const std::string code = GetShaderHeader() + R"(
1128 %img_type = OpTypeImage %f32 2D 0 0 0 0 Unknown
1129 )" + TrivialMain();
1130
1131 CompileSuccessfully(code.c_str());
1132 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1133 EXPECT_THAT(getDiagnosticString(),
1134 AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
1135 EXPECT_THAT(getDiagnosticString(),
1136 HasSubstr("Sampled must be 1 or 2 in the Vulkan environment."));
1137 }
1138
TEST_F(ValidateImage,TypeImageWrongFormatForSubpassData)1139 TEST_F(ValidateImage, TypeImageWrongFormatForSubpassData) {
1140 const std::string code =
1141 GetShaderHeader("OpCapability InputAttachment\n", false) +
1142 R"(
1143 %img_type = OpTypeImage %f32 SubpassData 0 0 0 2 Rgba32f
1144 )";
1145
1146 CompileSuccessfully(code.c_str());
1147 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1148 EXPECT_THAT(getDiagnosticString(),
1149 HasSubstr("Dim SubpassData requires format Unknown"));
1150 }
1151
TEST_F(ValidateImage,TypeImageMultisampleStorageImage_MissingCapability)1152 TEST_F(ValidateImage, TypeImageMultisampleStorageImage_MissingCapability) {
1153 const std::string code = GetShaderHeader("", false) +
1154 R"(
1155 %img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
1156 )";
1157
1158 CompileSuccessfully(code.c_str());
1159 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()) << code;
1160 EXPECT_THAT(getDiagnosticString(),
1161 HasSubstr("Capability StorageImageMultisample is required when "
1162 "using multisampled storage image"));
1163 }
1164
TEST_F(ValidateImage,TypeImageMultisampleStorageImage_UsesCapability)1165 TEST_F(ValidateImage, TypeImageMultisampleStorageImage_UsesCapability) {
1166 const std::string code =
1167 GetShaderHeader("OpCapability StorageImageMultisample\n", false) +
1168 R"(
1169 %img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
1170 )";
1171
1172 CompileSuccessfully(code.c_str());
1173 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
1174 EXPECT_THAT(getDiagnosticString(), Eq(""));
1175 }
1176
TEST_F(ValidateImage,TypeImageMultisampleSubpassData_OK)1177 TEST_F(ValidateImage, TypeImageMultisampleSubpassData_OK) {
1178 const std::string code =
1179 GetShaderHeader("OpCapability InputAttachment\n", false) +
1180 R"(
1181 %img_type = OpTypeImage %f32 SubpassData 0 0 1 2 Unknown
1182 )";
1183
1184 CompileSuccessfully(code.c_str());
1185 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
1186 EXPECT_THAT(getDiagnosticString(), Eq(""));
1187 }
1188
TEST_F(ValidateImage,TypeSampledImage_NotImage_Error)1189 TEST_F(ValidateImage, TypeSampledImage_NotImage_Error) {
1190 const std::string code = GetShaderHeader("", false) + R"(
1191 %simg_type = OpTypeSampledImage %f32
1192 )";
1193
1194 CompileSuccessfully(code.c_str());
1195 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1196 EXPECT_THAT(getDiagnosticString(),
1197 HasSubstr("Expected Image to be of type OpTypeImage"));
1198 }
1199
TEST_F(ValidateImage,TypeSampledImage_Sampled0_Success)1200 TEST_F(ValidateImage, TypeSampledImage_Sampled0_Success) {
1201 // This is ok in the OpenCL and universal environments.
1202 // Vulkan will reject an OpTypeImage with Sampled=0, checked elsewhere.
1203 const std::string code = GetShaderHeader() + R"(
1204 %imty = OpTypeImage %f32 2D 0 0 0 0 Unknown
1205 %simg_type = OpTypeSampledImage %imty
1206 )" + TrivialMain();
1207
1208 CompileSuccessfully(code.c_str());
1209 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1210 EXPECT_EQ(getDiagnosticString(), "");
1211 }
1212
TEST_F(ValidateImage,TypeSampledImage_Sampled2_Error)1213 TEST_F(ValidateImage, TypeSampledImage_Sampled2_Error) {
1214 const std::string code = GetShaderHeader() + R"(
1215 %storage_image = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
1216 %simg_type = OpTypeSampledImage %storage_image
1217 )" + TrivialMain();
1218
1219 CompileSuccessfully(code.c_str());
1220 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1221 EXPECT_THAT(getDiagnosticString(),
1222 HasSubstr("Sampled image type requires an image type with "
1223 "\"Sampled\" operand set to 0 or 1"));
1224 }
1225
TEST_F(ValidateImage,TypeSampledImage_Sampled1_Success)1226 TEST_F(ValidateImage, TypeSampledImage_Sampled1_Success) {
1227 const std::string code = GetShaderHeader() + R"(
1228 %im = OpTypeImage %f32 2D 0 0 0 1 Unknown
1229 %simg_type = OpTypeSampledImage %im
1230 )" + TrivialMain();
1231
1232 CompileSuccessfully(code.c_str());
1233 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1234 EXPECT_EQ(getDiagnosticString(), "");
1235 }
1236
TEST_F(ValidateImage,SampledImageSuccess)1237 TEST_F(ValidateImage, SampledImageSuccess) {
1238 const std::string body = R"(
1239 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1240 %sampler = OpLoad %type_sampler %uniform_sampler
1241 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1242 )";
1243
1244 CompileSuccessfully(GenerateShaderCode(body).c_str());
1245 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1246 }
1247
TEST_F(ValidateImage,SampledImageVulkanSuccess)1248 TEST_F(ValidateImage, SampledImageVulkanSuccess) {
1249 const std::string body = R"(
1250 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1251 %sampler = OpLoad %type_sampler %uniform_sampler
1252 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1253 )";
1254
1255 const spv_target_env env = SPV_ENV_VULKAN_1_0;
1256 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
1257 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
1258 }
1259
TEST_F(ValidateImage,SampledImageWrongResultType)1260 TEST_F(ValidateImage, SampledImageWrongResultType) {
1261 const std::string body = R"(
1262 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1263 %sampler = OpLoad %type_sampler %uniform_sampler
1264 %simg = OpSampledImage %type_image_f32_2d_0001 %img %sampler
1265 )";
1266
1267 CompileSuccessfully(GenerateShaderCode(body).c_str());
1268 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1269 EXPECT_THAT(getDiagnosticString(),
1270 HasSubstr("Expected Result Type to be OpTypeSampledImage"));
1271 }
1272
TEST_F(ValidateImage,SampledImageNotImage)1273 TEST_F(ValidateImage, SampledImageNotImage) {
1274 const std::string body = R"(
1275 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1276 %sampler = OpLoad %type_sampler %uniform_sampler
1277 %simg1 = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1278 %simg2 = OpSampledImage %type_sampled_image_f32_2d_0001 %simg1 %sampler
1279 )";
1280
1281 CompileSuccessfully(GenerateShaderCode(body).c_str());
1282 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1283 EXPECT_THAT(getDiagnosticString(),
1284 HasSubstr("Expected Image to be of type OpTypeImage"));
1285 }
1286
TEST_F(ValidateImage,SampledImageImageNotForSampling)1287 TEST_F(ValidateImage, SampledImageImageNotForSampling) {
1288 const std::string code = GetShaderHeader() + R"(
1289 %im_ty = OpTypeImage %f32 2D 0 0 0 2 Unknown
1290 %sampler_ty = OpTypeSampler
1291 %sampled_image_ty = OpTypeSampledImage %im_ty ; will fail here first!
1292
1293 %ptr_im_ty = OpTypePointer UniformConstant %im_ty
1294 %var_im = OpVariable %ptr_im_ty UniformConstant
1295
1296 %ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
1297 %var_sampler = OpVariable %ptr_sampler_ty UniformConstant
1298
1299 %main = OpFunction %void None %func
1300 %entry = OpLabel
1301 %im = OpLoad %im_ty %var_im
1302 %sampler = OpLoad %sampler_ty %var_sampler
1303 %sampled_image = OpSampledImage %sampled_image_ty %im %sampler
1304 OpReturn
1305 OpFunctionEnd
1306 )";
1307
1308 CompileSuccessfully(code.c_str());
1309 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1310 EXPECT_THAT(getDiagnosticString(),
1311 HasSubstr("Sampled image type requires an image type with "
1312 "\"Sampled\" operand set to 0 or 1"))
1313 << code;
1314 }
1315
TEST_F(ValidateImage,SampledImageNotSampler)1316 TEST_F(ValidateImage, SampledImageNotSampler) {
1317 const std::string body = R"(
1318 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1319 %sampler = OpLoad %type_sampler %uniform_sampler
1320 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %img
1321 )";
1322
1323 CompileSuccessfully(GenerateShaderCode(body).c_str());
1324 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1325 EXPECT_THAT(getDiagnosticString(),
1326 HasSubstr("Expected Sampler to be of type OpTypeSampler"));
1327 }
1328
TEST_F(ValidateImage,SampledImageIsStorage)1329 TEST_F(ValidateImage, SampledImageIsStorage) {
1330 const std::string declarations = R"(
1331 %type_sampled_image_f32_2d_0002 = OpTypeSampledImage %type_image_f32_2d_0002
1332 )";
1333 const std::string body = R"(
1334 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
1335 %sampler = OpLoad %type_sampler %uniform_sampler
1336 %simg = OpSampledImage %type_sampled_image_f32_2d_0002 %img %sampler
1337 )";
1338
1339 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "",
1340 SPV_ENV_UNIVERSAL_1_0, "GLSL450",
1341 declarations)
1342 .c_str());
1343 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1344 EXPECT_THAT(getDiagnosticString(),
1345 HasSubstr("Sampled image type requires an image type with "
1346 "\"Sampled\" operand set to 0 or 1"));
1347 }
1348
TEST_F(ValidateImage,ImageTexelPointerSuccess)1349 TEST_F(ValidateImage, ImageTexelPointerSuccess) {
1350 const std::string body = R"(
1351 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1352 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1353 )";
1354
1355 CompileSuccessfully(GenerateShaderCode(body).c_str());
1356 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1357 }
1358
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotPointer)1359 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotPointer) {
1360 const std::string body = R"(
1361 %texel_ptr = OpImageTexelPointer %type_image_u32_buffer_0002_r32ui %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1362 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1363 )";
1364
1365 CompileSuccessfully(GenerateShaderCode(body).c_str());
1366 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1367 EXPECT_THAT(getDiagnosticString(),
1368 HasSubstr("Expected Result Type to be OpTypePointer"));
1369 }
1370
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotImageClass)1371 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotImageClass) {
1372 const std::string body = R"(
1373 %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1374 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1375 )";
1376
1377 CompileSuccessfully(GenerateShaderCode(body).c_str());
1378 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1379 EXPECT_THAT(getDiagnosticString(),
1380 HasSubstr("Expected Result Type to be OpTypePointer whose "
1381 "Storage Class operand is Image"));
1382 }
1383
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotNumericNorVoid)1384 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotNumericNorVoid) {
1385 const std::string body = R"(
1386 %texel_ptr = OpImageTexelPointer %ptr_Image_u32arr4 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1387 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1388 )";
1389
1390 CompileSuccessfully(GenerateShaderCode(body).c_str());
1391 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1392 EXPECT_THAT(
1393 getDiagnosticString(),
1394 HasSubstr("Expected Result Type to be OpTypePointer whose Type operand "
1395 "must be a scalar numerical type or OpTypeVoid"));
1396 }
1397
TEST_F(ValidateImage,ImageTexelPointerImageNotResultTypePointer)1398 TEST_F(ValidateImage, ImageTexelPointerImageNotResultTypePointer) {
1399 const std::string body = R"(
1400 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %type_image_f32_buffer_0002_r32ui %u32_0 %u32_0
1401 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1402 )";
1403
1404 CompileSuccessfully(GenerateShaderCode(body).c_str());
1405 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
1406 EXPECT_THAT(getDiagnosticString(),
1407 HasSubstr("Operand '148[%148]' cannot be a "
1408 "type"));
1409 }
1410
TEST_F(ValidateImage,ImageTexelPointerImageNotImage)1411 TEST_F(ValidateImage, ImageTexelPointerImageNotImage) {
1412 const std::string body = R"(
1413 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_sampler %u32_0 %u32_0
1414 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1415 )";
1416
1417 CompileSuccessfully(GenerateShaderCode(body).c_str());
1418 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1419 EXPECT_THAT(
1420 getDiagnosticString(),
1421 HasSubstr("Expected Image to be OpTypePointer with Type OpTypeImage"));
1422 }
1423
TEST_F(ValidateImage,ImageTexelPointerImageSampledNotResultType)1424 TEST_F(ValidateImage, ImageTexelPointerImageSampledNotResultType) {
1425 const std::string body = R"(
1426 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_f32_cube_0101 %u32_0 %u32_0
1427 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1428 )";
1429
1430 CompileSuccessfully(GenerateShaderCode(body).c_str());
1431 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1432 EXPECT_THAT(getDiagnosticString(),
1433 HasSubstr("Expected Image 'Sampled Type' to be the same as the "
1434 "Type pointed to by Result Type"));
1435 }
1436
TEST_F(ValidateImage,ImageTexelPointerImageDimSubpassDataBad)1437 TEST_F(ValidateImage, ImageTexelPointerImageDimSubpassDataBad) {
1438 const std::string body = R"(
1439 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_spd_0002 %u32_0 %u32_0
1440 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1441 )";
1442
1443 CompileSuccessfully(GenerateShaderCode(body).c_str());
1444 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1445 EXPECT_THAT(
1446 getDiagnosticString(),
1447 HasSubstr(
1448 "Image Dim SubpassData cannot be used with OpImageTexelPointer"));
1449 }
1450
TEST_F(ValidateImage,ImageTexelPointerImageCoordTypeBad)1451 TEST_F(ValidateImage, ImageTexelPointerImageCoordTypeBad) {
1452 const std::string body = R"(
1453 %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32ui %f32_0 %f32_0
1454 %sum = OpAtomicIAdd %f32 %texel_ptr %f32_1 %f32_0 %f32_1
1455 )";
1456
1457 CompileSuccessfully(GenerateShaderCode(body).c_str());
1458 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1459 EXPECT_THAT(getDiagnosticString(),
1460 HasSubstr("Expected Coordinate to be integer scalar or vector"));
1461 }
1462
TEST_F(ValidateImage,ImageTexelPointerImageCoordSizeBad)1463 TEST_F(ValidateImage, ImageTexelPointerImageCoordSizeBad) {
1464 const std::string body = R"(
1465 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_u32_2d_0002 %u32vec3_012 %u32_0
1466 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1467 )";
1468
1469 CompileSuccessfully(GenerateShaderCode(body).c_str());
1470 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1471 EXPECT_THAT(
1472 getDiagnosticString(),
1473 HasSubstr("Expected Coordinate to have 2 components, but given 3"));
1474 }
1475
TEST_F(ValidateImage,ImageTexelPointerSampleNotIntScalar)1476 TEST_F(ValidateImage, ImageTexelPointerSampleNotIntScalar) {
1477 const std::string body = R"(
1478 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %f32_0
1479 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1480 )";
1481
1482 CompileSuccessfully(GenerateShaderCode(body).c_str());
1483 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1484 EXPECT_THAT(getDiagnosticString(),
1485 HasSubstr("Expected Sample to be integer scalar"));
1486 }
1487
TEST_F(ValidateImage,ImageTexelPointerSampleNotZeroForImageWithMSZero)1488 TEST_F(ValidateImage, ImageTexelPointerSampleNotZeroForImageWithMSZero) {
1489 const std::string body = R"(
1490 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_1
1491 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1492 )";
1493
1494 CompileSuccessfully(GenerateShaderCode(body).c_str());
1495 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1496 EXPECT_THAT(getDiagnosticString(),
1497 HasSubstr("Expected Sample for Image with MS 0 to be a valid "
1498 "<id> for the value 0"));
1499 }
1500
TEST_F(ValidateImage,SampleImplicitLodSuccess)1501 TEST_F(ValidateImage, SampleImplicitLodSuccess) {
1502 const std::string body = R"(
1503 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1504 %sampler = OpLoad %type_sampler %uniform_sampler
1505 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1506 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
1507 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0_25
1508 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
1509 %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
1510 %res6 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
1511 %res7 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
1512 %res8 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
1513 )";
1514
1515 const std::string extra = R"(
1516 OpCapability VulkanMemoryModelKHR
1517 OpExtension "SPV_KHR_vulkan_memory_model"
1518 )";
1519 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1520 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1521 .c_str());
1522 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1523 }
1524
TEST_F(ValidateImage,SampleImplicitLodWrongResultType)1525 TEST_F(ValidateImage, SampleImplicitLodWrongResultType) {
1526 const std::string body = R"(
1527 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1528 %sampler = OpLoad %type_sampler %uniform_sampler
1529 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1530 %res1 = OpImageSampleImplicitLod %f32 %simg %f32vec2_hh
1531 )";
1532
1533 CompileSuccessfully(GenerateShaderCode(body).c_str());
1534 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1535 EXPECT_THAT(getDiagnosticString(),
1536 HasSubstr("Expected Result Type to be int or float vector type"));
1537 }
1538
TEST_F(ValidateImage,SampleImplicitLodWrongNumComponentsResultType)1539 TEST_F(ValidateImage, SampleImplicitLodWrongNumComponentsResultType) {
1540 const std::string body = R"(
1541 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1542 %sampler = OpLoad %type_sampler %uniform_sampler
1543 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1544 %res1 = OpImageSampleImplicitLod %f32vec3 %simg %f32vec2_hh
1545 )";
1546
1547 CompileSuccessfully(GenerateShaderCode(body).c_str());
1548 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1549 EXPECT_THAT(getDiagnosticString(),
1550 HasSubstr("Expected Result Type to have 4 components"));
1551 }
1552
TEST_F(ValidateImage,SampleImplicitLodNotSampledImage)1553 TEST_F(ValidateImage, SampleImplicitLodNotSampledImage) {
1554 const std::string body = R"(
1555 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1556 %res1 = OpImageSampleImplicitLod %f32vec4 %img %f32vec2_hh
1557 )";
1558
1559 CompileSuccessfully(GenerateShaderCode(body).c_str());
1560 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1561 EXPECT_THAT(
1562 getDiagnosticString(),
1563 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1564 }
1565
TEST_F(ValidateImage,SampleImplicitLodMultisampleError)1566 TEST_F(ValidateImage, SampleImplicitLodMultisampleError) {
1567 const std::string body = R"(
1568 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
1569 %sampler = OpLoad %type_sampler %uniform_sampler
1570 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
1571 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
1572 )";
1573
1574 CompileSuccessfully(GenerateShaderCode(body).c_str());
1575 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1576 EXPECT_THAT(getDiagnosticString(),
1577 HasSubstr("Sampling operation is invalid for multisample image"));
1578 }
1579
TEST_F(ValidateImage,SampleImplicitLodWrongSampledType)1580 TEST_F(ValidateImage, SampleImplicitLodWrongSampledType) {
1581 const std::string body = R"(
1582 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1583 %sampler = OpLoad %type_sampler %uniform_sampler
1584 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1585 %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
1586 )";
1587
1588 CompileSuccessfully(GenerateShaderCode(body).c_str());
1589 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1590 EXPECT_THAT(getDiagnosticString(),
1591 HasSubstr("Expected Image 'Sampled Type' to be the same as "
1592 "Result Type components"));
1593 }
1594
TEST_F(ValidateImage,SampleImplicitLodVoidSampledType)1595 TEST_F(ValidateImage, SampleImplicitLodVoidSampledType) {
1596 const std::string body = R"(
1597 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1598 %sampler = OpLoad %type_sampler %uniform_sampler
1599 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1600 %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
1601 )";
1602
1603 CompileSuccessfully(GenerateShaderCode(body).c_str());
1604 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1605 }
1606
TEST_F(ValidateImage,SampleImplicitLodWrongCoordinateType)1607 TEST_F(ValidateImage, SampleImplicitLodWrongCoordinateType) {
1608 const std::string body = R"(
1609 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1610 %sampler = OpLoad %type_sampler %uniform_sampler
1611 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1612 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %img
1613 )";
1614
1615 CompileSuccessfully(GenerateShaderCode(body).c_str());
1616 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1617 EXPECT_THAT(getDiagnosticString(),
1618 HasSubstr("Expected Coordinate to be float scalar or vector"));
1619 }
1620
TEST_F(ValidateImage,SampleImplicitLodCoordinateSizeTooSmall)1621 TEST_F(ValidateImage, SampleImplicitLodCoordinateSizeTooSmall) {
1622 const std::string body = R"(
1623 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1624 %sampler = OpLoad %type_sampler %uniform_sampler
1625 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1626 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32_0_5
1627 )";
1628
1629 CompileSuccessfully(GenerateShaderCode(body).c_str());
1630 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1631 EXPECT_THAT(getDiagnosticString(),
1632 HasSubstr("Expected Coordinate to have at least 2 components, "
1633 "but given only 1"));
1634 }
1635
TEST_F(ValidateImage,SampleExplicitLodSuccessShader)1636 TEST_F(ValidateImage, SampleExplicitLodSuccessShader) {
1637 const std::string body = R"(
1638 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1639 %sampler = OpLoad %type_sampler %uniform_sampler
1640 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1641 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod %f32_1
1642 %res2 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_10 %f32vec2_01
1643 %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
1644 %res4 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
1645 %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset|MinLod %f32vec2_10 %f32vec2_01 %s32vec2_01 %f32_0_5
1646 %res6 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod|NonPrivateTexelKHR %f32_1
1647 )";
1648
1649 const std::string extra = R"(
1650 OpCapability VulkanMemoryModelKHR
1651 OpExtension "SPV_KHR_vulkan_memory_model"
1652 )";
1653 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1654 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1655 .c_str());
1656 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1657 }
1658
TEST_F(ValidateImage,SampleExplicitLodSuccessKernel)1659 TEST_F(ValidateImage, SampleExplicitLodSuccessKernel) {
1660 const std::string body = R"(
1661 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1662 %sampler = OpLoad %type_sampler %uniform_sampler
1663 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1664 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec4_0123 Lod %f32_1
1665 %res2 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Grad %f32vec2_10 %f32vec2_01
1666 %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %u32vec2_01
1667 %res4 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Offset %u32vec2_01
1668 %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset %f32vec2_10 %f32vec2_01 %u32vec2_01
1669 )";
1670
1671 CompileSuccessfully(GenerateKernelCode(body).c_str());
1672 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1673 }
1674
TEST_F(ValidateImage,SampleExplicitLodSuccessCubeArrayed)1675 TEST_F(ValidateImage, SampleExplicitLodSuccessCubeArrayed) {
1676 const std::string body = R"(
1677 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1678 %sampler = OpLoad %type_sampler %uniform_sampler
1679 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1680 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec3_hhh
1681 )";
1682
1683 CompileSuccessfully(GenerateShaderCode(body).c_str());
1684 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1685 }
1686
TEST_F(ValidateImage,SampleExplicitLodWrongResultType)1687 TEST_F(ValidateImage, SampleExplicitLodWrongResultType) {
1688 const std::string body = R"(
1689 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1690 %sampler = OpLoad %type_sampler %uniform_sampler
1691 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1692 %res1 = OpImageSampleExplicitLod %f32 %simg %f32vec2_hh Lod %f32_1
1693 )";
1694
1695 CompileSuccessfully(GenerateShaderCode(body).c_str());
1696 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1697 EXPECT_THAT(getDiagnosticString(),
1698 HasSubstr("Expected Result Type to be int or float vector type"));
1699 }
1700
TEST_F(ValidateImage,SampleExplicitLodWrongNumComponentsResultType)1701 TEST_F(ValidateImage, SampleExplicitLodWrongNumComponentsResultType) {
1702 const std::string body = R"(
1703 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1704 %sampler = OpLoad %type_sampler %uniform_sampler
1705 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1706 %res1 = OpImageSampleExplicitLod %f32vec3 %simg %f32vec2_hh Lod %f32_1
1707 )";
1708
1709 CompileSuccessfully(GenerateShaderCode(body).c_str());
1710 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1711 EXPECT_THAT(getDiagnosticString(),
1712 HasSubstr("Expected Result Type to have 4 components"));
1713 }
1714
TEST_F(ValidateImage,SampleExplicitLodNotSampledImage)1715 TEST_F(ValidateImage, SampleExplicitLodNotSampledImage) {
1716 const std::string body = R"(
1717 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1718 %res1 = OpImageSampleExplicitLod %f32vec4 %img %f32vec2_hh Lod %f32_1
1719 )";
1720
1721 CompileSuccessfully(GenerateShaderCode(body).c_str());
1722 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1723 EXPECT_THAT(
1724 getDiagnosticString(),
1725 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1726 }
1727
TEST_F(ValidateImage,SampleExplicitLodMultisampleError)1728 TEST_F(ValidateImage, SampleExplicitLodMultisampleError) {
1729 const std::string body = R"(
1730 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
1731 %sampler = OpLoad %type_sampler %uniform_sampler
1732 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
1733 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_0 %u32_1
1734 )";
1735
1736 CompileSuccessfully(GenerateShaderCode(body).c_str());
1737 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1738 EXPECT_THAT(getDiagnosticString(),
1739 HasSubstr("Sampling operation is invalid for multisample image"));
1740 }
1741
TEST_F(ValidateImage,SampleExplicitLodWrongSampledType)1742 TEST_F(ValidateImage, SampleExplicitLodWrongSampledType) {
1743 const std::string body = R"(
1744 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1745 %sampler = OpLoad %type_sampler %uniform_sampler
1746 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1747 %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
1748 )";
1749
1750 CompileSuccessfully(GenerateShaderCode(body).c_str());
1751 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1752 EXPECT_THAT(getDiagnosticString(),
1753 HasSubstr("Expected Image 'Sampled Type' to be the same as "
1754 "Result Type components"));
1755 }
1756
TEST_F(ValidateImage,SampleExplicitLodVoidSampledType)1757 TEST_F(ValidateImage, SampleExplicitLodVoidSampledType) {
1758 const std::string body = R"(
1759 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1760 %sampler = OpLoad %type_sampler %uniform_sampler
1761 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1762 %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
1763 )";
1764
1765 CompileSuccessfully(GenerateShaderCode(body).c_str());
1766 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1767 }
1768
TEST_F(ValidateImage,SampleExplicitLodWrongCoordinateType)1769 TEST_F(ValidateImage, SampleExplicitLodWrongCoordinateType) {
1770 const std::string body = R"(
1771 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1772 %sampler = OpLoad %type_sampler %uniform_sampler
1773 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1774 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %img Lod %f32_1
1775 )";
1776
1777 CompileSuccessfully(GenerateShaderCode(body).c_str());
1778 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1779 EXPECT_THAT(getDiagnosticString(),
1780 HasSubstr("Expected Coordinate to be float scalar or vector"));
1781 }
1782
TEST_F(ValidateImage,SampleExplicitLodCoordinateSizeTooSmall)1783 TEST_F(ValidateImage, SampleExplicitLodCoordinateSizeTooSmall) {
1784 const std::string body = R"(
1785 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1786 %sampler = OpLoad %type_sampler %uniform_sampler
1787 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1788 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32_0_5 Lod %f32_1
1789 )";
1790
1791 CompileSuccessfully(GenerateShaderCode(body).c_str());
1792 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1793 EXPECT_THAT(getDiagnosticString(),
1794 HasSubstr("Expected Coordinate to have at least 2 components, "
1795 "but given only 1"));
1796 }
1797
TEST_F(ValidateImage,SampleExplicitLodBias)1798 TEST_F(ValidateImage, SampleExplicitLodBias) {
1799 const std::string body = R"(
1800 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1801 %sampler = OpLoad %type_sampler %uniform_sampler
1802 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1803 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Bias|Lod %f32_1 %f32_1
1804 )";
1805
1806 CompileSuccessfully(GenerateShaderCode(body).c_str());
1807 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1808 EXPECT_THAT(
1809 getDiagnosticString(),
1810 HasSubstr(
1811 "Image Operand Bias can only be used with ImplicitLod opcodes"));
1812 }
1813
TEST_F(ValidateImage,LodAndGrad)1814 TEST_F(ValidateImage, LodAndGrad) {
1815 const std::string body = R"(
1816 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1817 %sampler = OpLoad %type_sampler %uniform_sampler
1818 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1819 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|Grad %f32_1 %f32vec2_hh %f32vec2_hh
1820 )";
1821
1822 CompileSuccessfully(GenerateShaderCode(body).c_str());
1823 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1824 EXPECT_THAT(
1825 getDiagnosticString(),
1826 HasSubstr(
1827 "Image Operand bits Lod and Grad cannot be set at the same time"));
1828 }
1829
TEST_F(ValidateImage,ImplicitLodWithLod)1830 TEST_F(ValidateImage, ImplicitLodWithLod) {
1831 const std::string body = R"(
1832 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1833 %sampler = OpLoad %type_sampler %uniform_sampler
1834 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1835 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_0_5
1836 )";
1837
1838 CompileSuccessfully(GenerateShaderCode(body).c_str());
1839 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1840 EXPECT_THAT(
1841 getDiagnosticString(),
1842 HasSubstr("Image Operand Lod can only be used with ExplicitLod opcodes "
1843 "and OpImageFetch"));
1844 }
1845
TEST_F(ValidateImage,LodWrongType)1846 TEST_F(ValidateImage, LodWrongType) {
1847 const std::string body = R"(
1848 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1849 %sampler = OpLoad %type_sampler %uniform_sampler
1850 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1851 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32vec2_hh)";
1852
1853 CompileSuccessfully(GenerateShaderCode(body).c_str());
1854 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1855 EXPECT_THAT(getDiagnosticString(),
1856 HasSubstr("Expected Image Operand Lod to be float scalar when "
1857 "used with ExplicitLod"));
1858 }
1859
TEST_F(ValidateImage,LodWrongDim)1860 TEST_F(ValidateImage, LodWrongDim) {
1861 const std::string body = R"(
1862 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1863 %sampler = OpLoad %type_sampler %uniform_sampler
1864 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1865 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32_0)";
1866
1867 CompileSuccessfully(GenerateShaderCode(body).c_str());
1868 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1869 EXPECT_THAT(getDiagnosticString(),
1870 HasSubstr("Image Operand Lod requires 'Dim' parameter to be 1D, "
1871 "2D, 3D or Cube"));
1872 }
1873
TEST_F(ValidateImage,MinLodIncompatible)1874 TEST_F(ValidateImage, MinLodIncompatible) {
1875 const std::string body = R"(
1876 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1877 %sampler = OpLoad %type_sampler %uniform_sampler
1878 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1879 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|MinLod %f32_0 %f32_0)";
1880
1881 CompileSuccessfully(GenerateShaderCode(body).c_str());
1882 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1883 EXPECT_THAT(
1884 getDiagnosticString(),
1885 HasSubstr(
1886 "Image Operand MinLod can only be used with ImplicitLod opcodes or "
1887 "together with Image Operand Grad"));
1888 }
1889
TEST_F(ValidateImage,ImplicitLodWithGrad)1890 TEST_F(ValidateImage, ImplicitLodWithGrad) {
1891 const std::string body = R"(
1892 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1893 %sampler = OpLoad %type_sampler %uniform_sampler
1894 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1895 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_hh %f32vec2_hh
1896 )";
1897
1898 CompileSuccessfully(GenerateShaderCode(body).c_str());
1899 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1900 EXPECT_THAT(
1901 getDiagnosticString(),
1902 HasSubstr(
1903 "Image Operand Grad can only be used with ExplicitLod opcodes"));
1904 }
1905
TEST_F(ValidateImage,SampleImplicitLodCubeArrayedSuccess)1906 TEST_F(ValidateImage, SampleImplicitLodCubeArrayedSuccess) {
1907 const std::string body = R"(
1908 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1909 %sampler = OpLoad %type_sampler %uniform_sampler
1910 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1911 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000
1912 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias %f32_0_25
1913 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %f32_0_5
1914 %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias|MinLod %f32_0_25 %f32_0_5
1915 )";
1916
1917 CompileSuccessfully(GenerateShaderCode(body).c_str());
1918 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1919 }
1920
TEST_F(ValidateImage,SampleImplicitLodBiasWrongType)1921 TEST_F(ValidateImage, SampleImplicitLodBiasWrongType) {
1922 const std::string body = R"(
1923 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1924 %sampler = OpLoad %type_sampler %uniform_sampler
1925 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1926 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %u32_0
1927 )";
1928
1929 CompileSuccessfully(GenerateShaderCode(body).c_str());
1930 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1931 EXPECT_THAT(getDiagnosticString(),
1932 HasSubstr("Expected Image Operand Bias to be float scalar"));
1933 }
1934
TEST_F(ValidateImage,SampleImplicitLodBiasWrongDim)1935 TEST_F(ValidateImage, SampleImplicitLodBiasWrongDim) {
1936 const std::string body = R"(
1937 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1938 %sampler = OpLoad %type_sampler %uniform_sampler
1939 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1940 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0
1941 )";
1942
1943 CompileSuccessfully(GenerateShaderCode(body).c_str());
1944 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1945 EXPECT_THAT(getDiagnosticString(),
1946 HasSubstr("Image Operand Bias requires 'Dim' parameter to be 1D, "
1947 "2D, 3D or Cube"));
1948 }
1949
TEST_F(ValidateImage,SampleExplicitLodGradDxWrongType)1950 TEST_F(ValidateImage, SampleExplicitLodGradDxWrongType) {
1951 const std::string body = R"(
1952 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1953 %sampler = OpLoad %type_sampler %uniform_sampler
1954 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1955 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %s32vec3_012 %f32vec3_hhh
1956 )";
1957
1958 CompileSuccessfully(GenerateShaderCode(body).c_str());
1959 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1960 EXPECT_THAT(getDiagnosticString(),
1961 HasSubstr("Expected both Image Operand Grad ids to be float "
1962 "scalars or vectors"));
1963 }
1964
TEST_F(ValidateImage,SampleExplicitLodGradDyWrongType)1965 TEST_F(ValidateImage, SampleExplicitLodGradDyWrongType) {
1966 const std::string body = R"(
1967 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1968 %sampler = OpLoad %type_sampler %uniform_sampler
1969 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1970 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %s32vec3_012
1971 )";
1972
1973 CompileSuccessfully(GenerateShaderCode(body).c_str());
1974 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1975 EXPECT_THAT(getDiagnosticString(),
1976 HasSubstr("Expected both Image Operand Grad ids to be float "
1977 "scalars or vectors"));
1978 }
1979
TEST_F(ValidateImage,SampleExplicitLodGradDxWrongSize)1980 TEST_F(ValidateImage, SampleExplicitLodGradDxWrongSize) {
1981 const std::string body = R"(
1982 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1983 %sampler = OpLoad %type_sampler %uniform_sampler
1984 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1985 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec2_00 %f32vec3_hhh
1986 )";
1987
1988 CompileSuccessfully(GenerateShaderCode(body).c_str());
1989 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1990 EXPECT_THAT(
1991 getDiagnosticString(),
1992 HasSubstr(
1993 "Expected Image Operand Grad dx to have 3 components, but given 2"));
1994 }
1995
TEST_F(ValidateImage,SampleExplicitLodGradDyWrongSize)1996 TEST_F(ValidateImage, SampleExplicitLodGradDyWrongSize) {
1997 const std::string body = R"(
1998 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1999 %sampler = OpLoad %type_sampler %uniform_sampler
2000 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2001 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec2_00
2002 )";
2003
2004 CompileSuccessfully(GenerateShaderCode(body).c_str());
2005 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2006 EXPECT_THAT(
2007 getDiagnosticString(),
2008 HasSubstr(
2009 "Expected Image Operand Grad dy to have 3 components, but given 2"));
2010 }
2011
TEST_F(ValidateImage,SampleImplicitLodConstOffsetCubeDim)2012 TEST_F(ValidateImage, SampleImplicitLodConstOffsetCubeDim) {
2013 const std::string body = R"(
2014 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2015 %sampler = OpLoad %type_sampler %uniform_sampler
2016 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2017 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec3_012
2018 )";
2019
2020 CompileSuccessfully(GenerateShaderCode(body).c_str());
2021 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2022 EXPECT_THAT(
2023 getDiagnosticString(),
2024 HasSubstr(
2025 "Image Operand ConstOffset cannot be used with Cube Image 'Dim'"));
2026 }
2027
TEST_F(ValidateImage,SampleImplicitLodConstOffsetWrongType)2028 TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongType) {
2029 const std::string body = R"(
2030 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2031 %sampler = OpLoad %type_sampler %uniform_sampler
2032 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2033 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %f32vec2_00
2034 )";
2035
2036 CompileSuccessfully(GenerateShaderCode(body).c_str());
2037 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2038 EXPECT_THAT(
2039 getDiagnosticString(),
2040 HasSubstr(
2041 "Expected Image Operand ConstOffset to be int scalar or vector"));
2042 }
2043
TEST_F(ValidateImage,SampleImplicitLodConstOffsetWrongSize)2044 TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongSize) {
2045 const std::string body = R"(
2046 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2047 %sampler = OpLoad %type_sampler %uniform_sampler
2048 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2049 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %s32vec3_012
2050 )";
2051
2052 CompileSuccessfully(GenerateShaderCode(body).c_str());
2053 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2054 EXPECT_THAT(getDiagnosticString(),
2055 HasSubstr("Expected Image Operand ConstOffset to have 2 "
2056 "components, but given 3"));
2057 }
2058
TEST_F(ValidateImage,SampleImplicitLodConstOffsetNotConst)2059 TEST_F(ValidateImage, SampleImplicitLodConstOffsetNotConst) {
2060 const std::string body = R"(
2061 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2062 %sampler = OpLoad %type_sampler %uniform_sampler
2063 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2064 %offset = OpSNegate %s32vec3 %s32vec3_012
2065 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %offset
2066 )";
2067
2068 CompileSuccessfully(GenerateShaderCode(body).c_str());
2069 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2070 EXPECT_THAT(
2071 getDiagnosticString(),
2072 HasSubstr("Expected Image Operand ConstOffset to be a const object"));
2073 }
2074
TEST_F(ValidateImage,SampleImplicitLodOffsetCubeDim)2075 TEST_F(ValidateImage, SampleImplicitLodOffsetCubeDim) {
2076 const std::string body = R"(
2077 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2078 %sampler = OpLoad %type_sampler %uniform_sampler
2079 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2080 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
2081 )";
2082
2083 CompileSuccessfully(GenerateShaderCode(body).c_str());
2084 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2085 EXPECT_THAT(
2086 getDiagnosticString(),
2087 HasSubstr("Image Operand Offset cannot be used with Cube Image 'Dim'"));
2088 }
2089
TEST_F(ValidateImage,SampleImplicitLodOffsetWrongType)2090 TEST_F(ValidateImage, SampleImplicitLodOffsetWrongType) {
2091 const std::string body = R"(
2092 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2093 %sampler = OpLoad %type_sampler %uniform_sampler
2094 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2095 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %f32vec2_00
2096 )";
2097
2098 CompileSuccessfully(GenerateShaderCode(body).c_str());
2099 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2100 EXPECT_THAT(
2101 getDiagnosticString(),
2102 HasSubstr("Expected Image Operand Offset to be int scalar or vector"));
2103 }
2104
TEST_F(ValidateImage,SampleImplicitLodOffsetWrongSize)2105 TEST_F(ValidateImage, SampleImplicitLodOffsetWrongSize) {
2106 const std::string body = R"(
2107 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2108 %sampler = OpLoad %type_sampler %uniform_sampler
2109 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2110 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
2111 )";
2112
2113 CompileSuccessfully(GenerateShaderCode(body).c_str());
2114 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2115 EXPECT_THAT(
2116 getDiagnosticString(),
2117 HasSubstr(
2118 "Expected Image Operand Offset to have 2 components, but given 3"));
2119 }
2120
TEST_F(ValidateImage,SampleImplicitLodVulkanOffsetWrongSize)2121 TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongSize) {
2122 const std::string body = R"(
2123 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2124 %sampler = OpLoad %type_sampler %uniform_sampler
2125 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2126 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
2127 )";
2128
2129 CompileSuccessfully(
2130 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2131 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2132 EXPECT_THAT(getDiagnosticString(),
2133 AnyVUID("VUID-StandaloneSpirv-Offset-04663"));
2134 EXPECT_THAT(getDiagnosticString(),
2135 HasSubstr("Image Operand Offset can only be used with "
2136 "OpImage*Gather operations"));
2137 }
2138
TEST_F(ValidateImage,SampleImplicitLodVulkanOffsetWrongBeforeLegalization)2139 TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongBeforeLegalization) {
2140 const std::string body = R"(
2141 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2142 %sampler = OpLoad %type_sampler %uniform_sampler
2143 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2144 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
2145 )";
2146
2147 CompileSuccessfully(
2148 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2149 getValidatorOptions()->before_hlsl_legalization = true;
2150 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2151 }
2152
TEST_F(ValidateImage,SampleImplicitLodMoreThanOneOffset)2153 TEST_F(ValidateImage, SampleImplicitLodMoreThanOneOffset) {
2154 const std::string body = R"(
2155 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2156 %sampler = OpLoad %type_sampler %uniform_sampler
2157 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2158 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
2159 )";
2160
2161 CompileSuccessfully(GenerateShaderCode(body).c_str());
2162 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2163 EXPECT_THAT(
2164 getDiagnosticString(),
2165 HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
2166 "cannot be used together"));
2167 }
2168
TEST_F(ValidateImage,SampleImplicitLodVulkanMoreThanOneOffset)2169 TEST_F(ValidateImage, SampleImplicitLodVulkanMoreThanOneOffset) {
2170 const std::string body = R"(
2171 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2172 %sampler = OpLoad %type_sampler %uniform_sampler
2173 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2174 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
2175 )";
2176
2177 CompileSuccessfully(
2178 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2179 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2180 EXPECT_THAT(
2181 getDiagnosticString(),
2182 HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
2183 "cannot be used together"));
2184 }
2185
TEST_F(ValidateImage,SampleImplicitLodMinLodWrongType)2186 TEST_F(ValidateImage, SampleImplicitLodMinLodWrongType) {
2187 const std::string body = R"(
2188 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2189 %sampler = OpLoad %type_sampler %uniform_sampler
2190 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2191 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %s32_0
2192 )";
2193
2194 CompileSuccessfully(GenerateShaderCode(body).c_str());
2195 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2196 EXPECT_THAT(getDiagnosticString(),
2197 HasSubstr("Expected Image Operand MinLod to be float scalar"));
2198 }
2199
TEST_F(ValidateImage,SampleImplicitLodMinLodWrongDim)2200 TEST_F(ValidateImage, SampleImplicitLodMinLodWrongDim) {
2201 const std::string body = R"(
2202 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2203 %sampler = OpLoad %type_sampler %uniform_sampler
2204 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
2205 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_25
2206 )";
2207
2208 CompileSuccessfully(GenerateShaderCode(body).c_str());
2209 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2210 EXPECT_THAT(getDiagnosticString(),
2211 HasSubstr("Image Operand MinLod requires 'Dim' parameter to be "
2212 "1D, 2D, 3D or Cube"));
2213 }
2214
TEST_F(ValidateImage,SampleProjExplicitLodSuccess2D)2215 TEST_F(ValidateImage, SampleProjExplicitLodSuccess2D) {
2216 const std::string body = R"(
2217 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2218 %sampler = OpLoad %type_sampler %uniform_sampler
2219 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2220 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod %f32_1
2221 %res3 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
2222 %res4 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
2223 %res5 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
2224 %res7 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
2225 %res8 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod|NonPrivateTexelKHR %f32_1
2226 )";
2227
2228 const std::string extra = R"(
2229 OpCapability VulkanMemoryModelKHR
2230 OpExtension "SPV_KHR_vulkan_memory_model"
2231 )";
2232 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2233 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2234 .c_str());
2235 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2236 }
2237
TEST_F(ValidateImage,SampleProjExplicitLodSuccessRect)2238 TEST_F(ValidateImage, SampleProjExplicitLodSuccessRect) {
2239 const std::string body = R"(
2240 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2241 %sampler = OpLoad %type_sampler %uniform_sampler
2242 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
2243 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
2244 %res2 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
2245 )";
2246
2247 CompileSuccessfully(GenerateShaderCode(body).c_str());
2248 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2249 }
2250
TEST_F(ValidateImage,SampleProjExplicitLodWrongResultType)2251 TEST_F(ValidateImage, SampleProjExplicitLodWrongResultType) {
2252 const std::string body = R"(
2253 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2254 %sampler = OpLoad %type_sampler %uniform_sampler
2255 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2256 %res1 = OpImageSampleProjExplicitLod %f32 %simg %f32vec3_hhh Lod %f32_1
2257 )";
2258
2259 CompileSuccessfully(GenerateShaderCode(body).c_str());
2260 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2261 EXPECT_THAT(getDiagnosticString(),
2262 HasSubstr("Expected Result Type to be int or float vector type"));
2263 }
2264
TEST_F(ValidateImage,SampleProjExplicitLodWrongNumComponentsResultType)2265 TEST_F(ValidateImage, SampleProjExplicitLodWrongNumComponentsResultType) {
2266 const std::string body = R"(
2267 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2268 %sampler = OpLoad %type_sampler %uniform_sampler
2269 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2270 %res1 = OpImageSampleProjExplicitLod %f32vec3 %simg %f32vec3_hhh Lod %f32_1
2271 )";
2272
2273 CompileSuccessfully(GenerateShaderCode(body).c_str());
2274 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2275 EXPECT_THAT(getDiagnosticString(),
2276 HasSubstr("Expected Result Type to have 4 components"));
2277 }
2278
TEST_F(ValidateImage,SampleProjExplicitLodNotSampledImage)2279 TEST_F(ValidateImage, SampleProjExplicitLodNotSampledImage) {
2280 const std::string body = R"(
2281 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2282 %res1 = OpImageSampleProjExplicitLod %f32vec4 %img %f32vec3_hhh Lod %f32_1
2283 )";
2284
2285 CompileSuccessfully(GenerateShaderCode(body).c_str());
2286 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2287 EXPECT_THAT(
2288 getDiagnosticString(),
2289 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2290 }
2291
TEST_F(ValidateImage,SampleProjExplicitLodMultisampleError)2292 TEST_F(ValidateImage, SampleProjExplicitLodMultisampleError) {
2293 const std::string body = R"(
2294 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2295 %sampler = OpLoad %type_sampler %uniform_sampler
2296 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2297 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_1 %u32_1
2298 )";
2299
2300 CompileSuccessfully(GenerateShaderCode(body).c_str());
2301 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2302 EXPECT_THAT(getDiagnosticString(),
2303 HasSubstr("Expected Image 'MS' parameter to be 0"));
2304 }
2305
TEST_F(ValidateImage,SampleProjExplicitLodWrongSampledType)2306 TEST_F(ValidateImage, SampleProjExplicitLodWrongSampledType) {
2307 const std::string body = R"(
2308 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2309 %sampler = OpLoad %type_sampler %uniform_sampler
2310 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2311 %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
2312 )";
2313
2314 CompileSuccessfully(GenerateShaderCode(body).c_str());
2315 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2316 EXPECT_THAT(getDiagnosticString(),
2317 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2318 "Result Type components"));
2319 }
2320
TEST_F(ValidateImage,SampleProjExplicitLodVoidSampledType)2321 TEST_F(ValidateImage, SampleProjExplicitLodVoidSampledType) {
2322 const std::string body = R"(
2323 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2324 %sampler = OpLoad %type_sampler %uniform_sampler
2325 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2326 %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
2327 )";
2328
2329 CompileSuccessfully(GenerateShaderCode(body).c_str());
2330 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2331 }
2332
TEST_F(ValidateImage,SampleProjExplicitLodWrongCoordinateType)2333 TEST_F(ValidateImage, SampleProjExplicitLodWrongCoordinateType) {
2334 const std::string body = R"(
2335 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2336 %sampler = OpLoad %type_sampler %uniform_sampler
2337 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2338 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %img Lod %f32_1
2339 )";
2340
2341 CompileSuccessfully(GenerateShaderCode(body).c_str());
2342 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2343 EXPECT_THAT(getDiagnosticString(),
2344 HasSubstr("Expected Coordinate to be float scalar or vector"));
2345 }
2346
TEST_F(ValidateImage,SampleProjExplicitLodCoordinateSizeTooSmall)2347 TEST_F(ValidateImage, SampleProjExplicitLodCoordinateSizeTooSmall) {
2348 const std::string body = R"(
2349 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2350 %sampler = OpLoad %type_sampler %uniform_sampler
2351 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2352 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_1
2353 )";
2354
2355 CompileSuccessfully(GenerateShaderCode(body).c_str());
2356 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2357 EXPECT_THAT(getDiagnosticString(),
2358 HasSubstr("Expected Coordinate to have at least 3 components, "
2359 "but given only 2"));
2360 }
2361
TEST_F(ValidateImage,SampleProjImplicitLodSuccess)2362 TEST_F(ValidateImage, SampleProjImplicitLodSuccess) {
2363 const std::string body = R"(
2364 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2365 %sampler = OpLoad %type_sampler %uniform_sampler
2366 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2367 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh
2368 %res2 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias %f32_0_25
2369 %res4 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
2370 %res5 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
2371 %res6 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh MinLod %f32_0_5
2372 %res7 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2373 %res8 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh NonPrivateTexelKHR
2374 )";
2375
2376 const std::string extra = R"(
2377 OpCapability VulkanMemoryModelKHR
2378 OpExtension "SPV_KHR_vulkan_memory_model"
2379 )";
2380 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2381 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2382 .c_str());
2383 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2384 }
2385
TEST_F(ValidateImage,SampleProjImplicitLodWrongResultType)2386 TEST_F(ValidateImage, SampleProjImplicitLodWrongResultType) {
2387 const std::string body = R"(
2388 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2389 %sampler = OpLoad %type_sampler %uniform_sampler
2390 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2391 %res1 = OpImageSampleProjImplicitLod %f32 %simg %f32vec3_hhh
2392 )";
2393
2394 CompileSuccessfully(GenerateShaderCode(body).c_str());
2395 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2396 EXPECT_THAT(getDiagnosticString(),
2397 HasSubstr("Expected Result Type to be int or float vector type"));
2398 }
2399
TEST_F(ValidateImage,SampleProjImplicitLodWrongNumComponentsResultType)2400 TEST_F(ValidateImage, SampleProjImplicitLodWrongNumComponentsResultType) {
2401 const std::string body = R"(
2402 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2403 %sampler = OpLoad %type_sampler %uniform_sampler
2404 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2405 %res1 = OpImageSampleProjImplicitLod %f32vec3 %simg %f32vec3_hhh
2406 )";
2407
2408 CompileSuccessfully(GenerateShaderCode(body).c_str());
2409 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2410 EXPECT_THAT(getDiagnosticString(),
2411 HasSubstr("Expected Result Type to have 4 components"));
2412 }
2413
TEST_F(ValidateImage,SampleProjImplicitLodNotSampledImage)2414 TEST_F(ValidateImage, SampleProjImplicitLodNotSampledImage) {
2415 const std::string body = R"(
2416 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2417 %res1 = OpImageSampleProjImplicitLod %f32vec4 %img %f32vec3_hhh
2418 )";
2419
2420 CompileSuccessfully(GenerateShaderCode(body).c_str());
2421 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2422 EXPECT_THAT(
2423 getDiagnosticString(),
2424 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2425 }
2426
TEST_F(ValidateImage,SampleProjImplicitLodMultisampleError)2427 TEST_F(ValidateImage, SampleProjImplicitLodMultisampleError) {
2428 const std::string body = R"(
2429 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2430 %sampler = OpLoad %type_sampler %uniform_sampler
2431 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2432 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
2433 )";
2434
2435 CompileSuccessfully(GenerateShaderCode(body).c_str());
2436 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2437 EXPECT_THAT(getDiagnosticString(),
2438 HasSubstr("Expected Image 'MS' parameter to be 0"));
2439 }
2440
TEST_F(ValidateImage,SampleProjImplicitLodWrongSampledType)2441 TEST_F(ValidateImage, SampleProjImplicitLodWrongSampledType) {
2442 const std::string body = R"(
2443 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2444 %sampler = OpLoad %type_sampler %uniform_sampler
2445 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2446 %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
2447 )";
2448
2449 CompileSuccessfully(GenerateShaderCode(body).c_str());
2450 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2451 EXPECT_THAT(getDiagnosticString(),
2452 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2453 "Result Type components"));
2454 }
2455
TEST_F(ValidateImage,SampleProjImplicitLodVoidSampledType)2456 TEST_F(ValidateImage, SampleProjImplicitLodVoidSampledType) {
2457 const std::string body = R"(
2458 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2459 %sampler = OpLoad %type_sampler %uniform_sampler
2460 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2461 %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
2462 )";
2463
2464 CompileSuccessfully(GenerateShaderCode(body).c_str());
2465 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2466 }
2467
TEST_F(ValidateImage,SampleProjImplicitLodWrongCoordinateType)2468 TEST_F(ValidateImage, SampleProjImplicitLodWrongCoordinateType) {
2469 const std::string body = R"(
2470 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2471 %sampler = OpLoad %type_sampler %uniform_sampler
2472 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2473 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %img
2474 )";
2475
2476 CompileSuccessfully(GenerateShaderCode(body).c_str());
2477 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2478 EXPECT_THAT(getDiagnosticString(),
2479 HasSubstr("Expected Coordinate to be float scalar or vector"));
2480 }
2481
TEST_F(ValidateImage,SampleProjImplicitLodCoordinateSizeTooSmall)2482 TEST_F(ValidateImage, SampleProjImplicitLodCoordinateSizeTooSmall) {
2483 const std::string body = R"(
2484 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2485 %sampler = OpLoad %type_sampler %uniform_sampler
2486 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2487 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh
2488 )";
2489
2490 CompileSuccessfully(GenerateShaderCode(body).c_str());
2491 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2492 EXPECT_THAT(getDiagnosticString(),
2493 HasSubstr("Expected Coordinate to have at least 3 components, "
2494 "but given only 2"));
2495 }
2496
TEST_F(ValidateImage,SampleDrefImplicitLodSuccess)2497 TEST_F(ValidateImage, SampleDrefImplicitLodSuccess) {
2498 const std::string body = R"(
2499 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2500 %sampler = OpLoad %type_sampler %uniform_sampler
2501 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2502 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1
2503 %res2 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
2504 %res4 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
2505 %res5 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
2506 %res6 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
2507 %res7 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2508 %res8 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
2509 )";
2510
2511 const std::string extra = R"(
2512 OpCapability VulkanMemoryModelKHR
2513 OpExtension "SPV_KHR_vulkan_memory_model"
2514 )";
2515 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2516 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2517 .c_str());
2518 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2519 }
2520
TEST_F(ValidateImage,SampleDrefImplicitLodWrongResultType)2521 TEST_F(ValidateImage, SampleDrefImplicitLodWrongResultType) {
2522 const std::string body = R"(
2523 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2524 %sampler = OpLoad %type_sampler %uniform_sampler
2525 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2526 %res1 = OpImageSampleDrefImplicitLod %void %simg %f32vec2_hh %u32_1
2527 )";
2528
2529 CompileSuccessfully(GenerateShaderCode(body).c_str());
2530 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2531 EXPECT_THAT(getDiagnosticString(),
2532 HasSubstr("Expected Result Type to be int or float scalar type"));
2533 }
2534
TEST_F(ValidateImage,SampleDrefImplicitLodNotSampledImage)2535 TEST_F(ValidateImage, SampleDrefImplicitLodNotSampledImage) {
2536 const std::string body = R"(
2537 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2538 %res1 = OpImageSampleDrefImplicitLod %u32 %img %f32vec2_hh %u32_1
2539 )";
2540
2541 CompileSuccessfully(GenerateShaderCode(body).c_str());
2542 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2543 EXPECT_THAT(
2544 getDiagnosticString(),
2545 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2546 }
2547
TEST_F(ValidateImage,SampleDrefImplicitLodMultisampleError)2548 TEST_F(ValidateImage, SampleDrefImplicitLodMultisampleError) {
2549 const std::string body = R"(
2550 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2551 %sampler = OpLoad %type_sampler %uniform_sampler
2552 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2553 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
2554 )";
2555
2556 CompileSuccessfully(GenerateShaderCode(body).c_str());
2557 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2558 EXPECT_THAT(
2559 getDiagnosticString(),
2560 HasSubstr("Dref sampling operation is invalid for multisample image"));
2561 }
2562
TEST_F(ValidateImage,SampleDrefImplicitLodWrongSampledType)2563 TEST_F(ValidateImage, SampleDrefImplicitLodWrongSampledType) {
2564 const std::string body = R"(
2565 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2566 %sampler = OpLoad %type_sampler %uniform_sampler
2567 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2568 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_00 %u32_1
2569 )";
2570
2571 CompileSuccessfully(GenerateShaderCode(body).c_str());
2572 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2573 EXPECT_THAT(
2574 getDiagnosticString(),
2575 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2576 }
2577
TEST_F(ValidateImage,SampleDrefImplicitLodVoidSampledType)2578 TEST_F(ValidateImage, SampleDrefImplicitLodVoidSampledType) {
2579 const std::string body = R"(
2580 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2581 %sampler = OpLoad %type_sampler %uniform_sampler
2582 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2583 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %u32_1
2584 )";
2585
2586 CompileSuccessfully(GenerateShaderCode(body).c_str());
2587 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2588 EXPECT_THAT(
2589 getDiagnosticString(),
2590 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2591 }
2592
TEST_F(ValidateImage,SampleDrefImplicitLodWrongCoordinateType)2593 TEST_F(ValidateImage, SampleDrefImplicitLodWrongCoordinateType) {
2594 const std::string body = R"(
2595 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2596 %sampler = OpLoad %type_sampler %uniform_sampler
2597 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2598 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %img %u32_1
2599 )";
2600
2601 CompileSuccessfully(GenerateShaderCode(body).c_str());
2602 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2603 EXPECT_THAT(getDiagnosticString(),
2604 HasSubstr("Expected Coordinate to be float scalar or vector"));
2605 }
2606
TEST_F(ValidateImage,SampleDrefImplicitLodCoordinateSizeTooSmall)2607 TEST_F(ValidateImage, SampleDrefImplicitLodCoordinateSizeTooSmall) {
2608 const std::string body = R"(
2609 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2610 %sampler = OpLoad %type_sampler %uniform_sampler
2611 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2612 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32_0_5 %f32_0_5
2613 )";
2614
2615 CompileSuccessfully(GenerateShaderCode(body).c_str());
2616 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2617 EXPECT_THAT(getDiagnosticString(),
2618 HasSubstr("Expected Coordinate to have at least 2 components, "
2619 "but given only 1"));
2620 }
2621
TEST_F(ValidateImage,SampleDrefImplicitLodWrongDrefType)2622 TEST_F(ValidateImage, SampleDrefImplicitLodWrongDrefType) {
2623 const std::string body = R"(
2624 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2625 %sampler = OpLoad %type_sampler %uniform_sampler
2626 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2627 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %f64_1
2628 )";
2629
2630 CompileSuccessfully(GenerateShaderCode(body).c_str());
2631 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2632 EXPECT_THAT(getDiagnosticString(),
2633 HasSubstr("Expected Dref to be of 32-bit float type"));
2634 }
2635
TEST_F(ValidateImage,SampleDrefImplicitLodWrongDimVulkan)2636 TEST_F(ValidateImage, SampleDrefImplicitLodWrongDimVulkan) {
2637 const std::string body = R"(
2638 %img = OpLoad %type_image_u32_3d_0001 %uniform_image_u32_3d_0001
2639 %sampler = OpLoad %type_sampler %uniform_sampler
2640 %simg = OpSampledImage %type_sampled_image_u32_3d_0001 %img %sampler
2641 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_1
2642 )";
2643
2644 CompileSuccessfully(
2645 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2646 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2647 EXPECT_THAT(getDiagnosticString(),
2648 AnyVUID("VUID-StandaloneSpirv-OpImage-04777"));
2649 EXPECT_THAT(getDiagnosticString(),
2650 HasSubstr("In Vulkan, OpImage*Dref* instructions must not use "
2651 "images with a 3D Dim"));
2652 }
2653
TEST_F(ValidateImage,SampleDrefExplicitLodSuccess)2654 TEST_F(ValidateImage, SampleDrefExplicitLodSuccess) {
2655 const std::string body = R"(
2656 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2657 %sampler = OpLoad %type_sampler %uniform_sampler
2658 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2659 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod %f32_1
2660 %res3 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad %f32vec3_hhh %f32vec3_hhh
2661 %res4 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 ConstOffset %s32vec3_012
2662 %res5 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Offset %s32vec3_012
2663 %res7 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad|Offset %f32vec3_hhh %f32vec3_hhh %s32vec3_012
2664 %res8 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod|NonPrivateTexelKHR %f32_1
2665 )";
2666
2667 const std::string extra = R"(
2668 OpCapability VulkanMemoryModelKHR
2669 OpExtension "SPV_KHR_vulkan_memory_model"
2670 )";
2671 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2672 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2673 .c_str());
2674 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2675 }
2676
TEST_F(ValidateImage,SampleDrefExplicitLodWrongResultType)2677 TEST_F(ValidateImage, SampleDrefExplicitLodWrongResultType) {
2678 const std::string body = R"(
2679 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2680 %sampler = OpLoad %type_sampler %uniform_sampler
2681 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2682 %res1 = OpImageSampleDrefExplicitLod %bool %simg %f32vec3_hhh %s32_1 Lod %f32_1
2683 )";
2684
2685 CompileSuccessfully(GenerateShaderCode(body).c_str());
2686 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2687 EXPECT_THAT(getDiagnosticString(),
2688 HasSubstr("Expected Result Type to be int or float scalar type"));
2689 }
2690
TEST_F(ValidateImage,SampleDrefExplicitLodNotSampledImage)2691 TEST_F(ValidateImage, SampleDrefExplicitLodNotSampledImage) {
2692 const std::string body = R"(
2693 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2694 %res1 = OpImageSampleDrefExplicitLod %s32 %img %f32vec3_hhh %s32_1 Lod %f32_1
2695 )";
2696
2697 CompileSuccessfully(GenerateShaderCode(body).c_str());
2698 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2699 EXPECT_THAT(
2700 getDiagnosticString(),
2701 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2702 }
2703
TEST_F(ValidateImage,SampleDrefExplicitLodMultisampleError)2704 TEST_F(ValidateImage, SampleDrefExplicitLodMultisampleError) {
2705 const std::string body = R"(
2706 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2707 %sampler = OpLoad %type_sampler %uniform_sampler
2708 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2709 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
2710 )";
2711
2712 CompileSuccessfully(GenerateShaderCode(body).c_str());
2713 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2714 EXPECT_THAT(
2715 getDiagnosticString(),
2716 HasSubstr("Dref sampling operation is invalid for multisample image"));
2717 }
2718
TEST_F(ValidateImage,SampleDrefExplicitLodWrongSampledType)2719 TEST_F(ValidateImage, SampleDrefExplicitLodWrongSampledType) {
2720 const std::string body = R"(
2721 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2722 %sampler = OpLoad %type_sampler %uniform_sampler
2723 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2724 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec3_hhh %s32_1 Lod %f32_1
2725 )";
2726
2727 CompileSuccessfully(GenerateShaderCode(body).c_str());
2728 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2729 EXPECT_THAT(
2730 getDiagnosticString(),
2731 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2732 }
2733
TEST_F(ValidateImage,SampleDrefExplicitLodVoidSampledType)2734 TEST_F(ValidateImage, SampleDrefExplicitLodVoidSampledType) {
2735 const std::string body = R"(
2736 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2737 %sampler = OpLoad %type_sampler %uniform_sampler
2738 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2739 %res1 = OpImageSampleDrefExplicitLod %u32 %simg %f32vec2_00 %s32_1 Lod %f32_1
2740 )";
2741
2742 CompileSuccessfully(GenerateShaderCode(body).c_str());
2743 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2744 EXPECT_THAT(
2745 getDiagnosticString(),
2746 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2747 }
2748
TEST_F(ValidateImage,SampleDrefExplicitLodWrongCoordinateType)2749 TEST_F(ValidateImage, SampleDrefExplicitLodWrongCoordinateType) {
2750 const std::string body = R"(
2751 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2752 %sampler = OpLoad %type_sampler %uniform_sampler
2753 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2754 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %img %s32_1 Lod %f32_1
2755 )";
2756
2757 CompileSuccessfully(GenerateShaderCode(body).c_str());
2758 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2759 EXPECT_THAT(getDiagnosticString(),
2760 HasSubstr("Expected Coordinate to be float scalar or vector"));
2761 }
2762
TEST_F(ValidateImage,SampleDrefExplicitLodCoordinateSizeTooSmall)2763 TEST_F(ValidateImage, SampleDrefExplicitLodCoordinateSizeTooSmall) {
2764 const std::string body = R"(
2765 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2766 %sampler = OpLoad %type_sampler %uniform_sampler
2767 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2768 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec2_hh %s32_1 Lod %f32_1
2769 )";
2770
2771 CompileSuccessfully(GenerateShaderCode(body).c_str());
2772 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2773 EXPECT_THAT(getDiagnosticString(),
2774 HasSubstr("Expected Coordinate to have at least 3 components, "
2775 "but given only 2"));
2776 }
2777
TEST_F(ValidateImage,SampleDrefExplicitLodWrongDrefType)2778 TEST_F(ValidateImage, SampleDrefExplicitLodWrongDrefType) {
2779 const std::string body = R"(
2780 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2781 %sampler = OpLoad %type_sampler %uniform_sampler
2782 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2783 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %u32_1 Lod %f32_1
2784 )";
2785
2786 CompileSuccessfully(GenerateShaderCode(body).c_str());
2787 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2788 EXPECT_THAT(getDiagnosticString(),
2789 HasSubstr("Expected Dref to be of 32-bit float type"));
2790 }
2791
TEST_F(ValidateImage,SampleProjDrefImplicitLodSuccess)2792 TEST_F(ValidateImage, SampleProjDrefImplicitLodSuccess) {
2793 const std::string body = R"(
2794 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2795 %sampler = OpLoad %type_sampler %uniform_sampler
2796 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2797 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5
2798 %res2 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias %f32_0_25
2799 %res4 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 ConstOffset %s32vec2_01
2800 %res5 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Offset %s32vec2_01
2801 %res6 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 MinLod %f32_0_5
2802 %res7 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2803 %res8 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 NonPrivateTexelKHR
2804 )";
2805
2806 const std::string extra = R"(
2807 OpCapability VulkanMemoryModelKHR
2808 OpExtension "SPV_KHR_vulkan_memory_model"
2809 )";
2810 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2811 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2812 .c_str());
2813 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2814 }
2815
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongResultType)2816 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongResultType) {
2817 const std::string body = R"(
2818 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2819 %sampler = OpLoad %type_sampler %uniform_sampler
2820 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2821 %res1 = OpImageSampleProjDrefImplicitLod %void %simg %f32vec3_hhh %f32_0_5
2822 )";
2823
2824 CompileSuccessfully(GenerateShaderCode(body).c_str());
2825 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2826 EXPECT_THAT(getDiagnosticString(),
2827 HasSubstr("Expected Result Type to be int or float scalar type"));
2828 }
2829
TEST_F(ValidateImage,SampleProjDrefImplicitLodNotSampledImage)2830 TEST_F(ValidateImage, SampleProjDrefImplicitLodNotSampledImage) {
2831 const std::string body = R"(
2832 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2833 %res1 = OpImageSampleProjDrefImplicitLod %f32 %img %f32vec3_hhh %f32_0_5
2834 )";
2835
2836 CompileSuccessfully(GenerateShaderCode(body).c_str());
2837 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2838 EXPECT_THAT(
2839 getDiagnosticString(),
2840 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2841 }
2842
TEST_F(ValidateImage,SampleProjDrefImplicitLodMultisampleError)2843 TEST_F(ValidateImage, SampleProjDrefImplicitLodMultisampleError) {
2844 const std::string body = R"(
2845 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2846 %sampler = OpLoad %type_sampler %uniform_sampler
2847 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2848 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
2849 )";
2850
2851 CompileSuccessfully(GenerateShaderCode(body).c_str());
2852 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2853 EXPECT_THAT(
2854 getDiagnosticString(),
2855 HasSubstr("Dref sampling operation is invalid for multisample image"));
2856 }
2857
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongSampledType)2858 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongSampledType) {
2859 const std::string body = R"(
2860 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2861 %sampler = OpLoad %type_sampler %uniform_sampler
2862 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2863 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2864 )";
2865
2866 CompileSuccessfully(GenerateShaderCode(body).c_str());
2867 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2868 EXPECT_THAT(
2869 getDiagnosticString(),
2870 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2871 }
2872
TEST_F(ValidateImage,SampleProjDrefImplicitLodVoidSampledType)2873 TEST_F(ValidateImage, SampleProjDrefImplicitLodVoidSampledType) {
2874 const std::string body = R"(
2875 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2876 %sampler = OpLoad %type_sampler %uniform_sampler
2877 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2878 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2879 )";
2880
2881 CompileSuccessfully(GenerateShaderCode(body).c_str());
2882 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2883 EXPECT_THAT(
2884 getDiagnosticString(),
2885 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2886 }
2887
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongCoordinateType)2888 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongCoordinateType) {
2889 const std::string body = R"(
2890 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2891 %sampler = OpLoad %type_sampler %uniform_sampler
2892 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2893 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %img %f32_0_5
2894 )";
2895
2896 CompileSuccessfully(GenerateShaderCode(body).c_str());
2897 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2898 EXPECT_THAT(getDiagnosticString(),
2899 HasSubstr("Expected Coordinate to be float scalar or vector"));
2900 }
2901
TEST_F(ValidateImage,SampleProjDrefImplicitLodCoordinateSizeTooSmall)2902 TEST_F(ValidateImage, SampleProjDrefImplicitLodCoordinateSizeTooSmall) {
2903 const std::string body = R"(
2904 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2905 %sampler = OpLoad %type_sampler %uniform_sampler
2906 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2907 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec2_hh %f32_0_5
2908 )";
2909
2910 CompileSuccessfully(GenerateShaderCode(body).c_str());
2911 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2912 EXPECT_THAT(getDiagnosticString(),
2913 HasSubstr("Expected Coordinate to have at least 3 components, "
2914 "but given only 2"));
2915 }
2916
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongDrefType)2917 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongDrefType) {
2918 const std::string body = R"(
2919 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2920 %sampler = OpLoad %type_sampler %uniform_sampler
2921 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2922 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32vec4_0000
2923 )";
2924
2925 CompileSuccessfully(GenerateShaderCode(body).c_str());
2926 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2927 EXPECT_THAT(getDiagnosticString(),
2928 HasSubstr("Expected Dref to be of 32-bit float type"));
2929 }
2930
TEST_F(ValidateImage,SampleProjDrefExplicitLodSuccess)2931 TEST_F(ValidateImage, SampleProjDrefExplicitLodSuccess) {
2932 const std::string body = R"(
2933 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2934 %sampler = OpLoad %type_sampler %uniform_sampler
2935 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2936 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2937 %res2 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Grad %f32_0_5 %f32_0_5
2938 %res3 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 ConstOffset %s32_1
2939 %res4 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Offset %s32_1
2940 %res5 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Grad|Offset %f32_0_5 %f32_0_5 %s32_1
2941 %res6 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod|NonPrivateTexelKHR %f32_1
2942 )";
2943
2944 const std::string extra = R"(
2945 OpCapability VulkanMemoryModelKHR
2946 OpExtension "SPV_KHR_vulkan_memory_model"
2947 )";
2948 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2949 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2950 .c_str());
2951 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2952 }
2953
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongResultType)2954 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongResultType) {
2955 const std::string body = R"(
2956 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2957 %sampler = OpLoad %type_sampler %uniform_sampler
2958 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2959 %res1 = OpImageSampleProjDrefExplicitLod %bool %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2960 )";
2961
2962 CompileSuccessfully(GenerateShaderCode(body).c_str());
2963 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2964 EXPECT_THAT(getDiagnosticString(),
2965 HasSubstr("Expected Result Type to be int or float scalar type"));
2966 }
2967
TEST_F(ValidateImage,SampleProjDrefExplicitLodNotSampledImage)2968 TEST_F(ValidateImage, SampleProjDrefExplicitLodNotSampledImage) {
2969 const std::string body = R"(
2970 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2971 %res1 = OpImageSampleProjDrefExplicitLod %f32 %img %f32vec2_hh %f32_0_5 Lod %f32_1
2972 )";
2973
2974 CompileSuccessfully(GenerateShaderCode(body).c_str());
2975 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2976 EXPECT_THAT(
2977 getDiagnosticString(),
2978 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2979 }
2980
TEST_F(ValidateImage,SampleProjDrefExplicitLodMultisampleError)2981 TEST_F(ValidateImage, SampleProjDrefExplicitLodMultisampleError) {
2982 const std::string body = R"(
2983 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2984 %sampler = OpLoad %type_sampler %uniform_sampler
2985 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2986 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
2987 )";
2988
2989 CompileSuccessfully(GenerateShaderCode(body).c_str());
2990 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2991 EXPECT_THAT(
2992 getDiagnosticString(),
2993 HasSubstr("Dref sampling operation is invalid for multisample image"));
2994 }
2995
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongSampledType)2996 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongSampledType) {
2997 const std::string body = R"(
2998 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2999 %sampler = OpLoad %type_sampler %uniform_sampler
3000 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
3001 %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
3002 )";
3003
3004 CompileSuccessfully(GenerateShaderCode(body).c_str());
3005 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3006 EXPECT_THAT(
3007 getDiagnosticString(),
3008 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
3009 }
3010
TEST_F(ValidateImage,SampleProjDrefExplicitLodVoidSampledType)3011 TEST_F(ValidateImage, SampleProjDrefExplicitLodVoidSampledType) {
3012 const std::string body = R"(
3013 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3014 %sampler = OpLoad %type_sampler %uniform_sampler
3015 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
3016 %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec3_hhh %f32_0_5 Lod %f32_1
3017 )";
3018
3019 CompileSuccessfully(GenerateShaderCode(body).c_str());
3020 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3021 EXPECT_THAT(
3022 getDiagnosticString(),
3023 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
3024 }
3025
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongCoordinateType)3026 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongCoordinateType) {
3027 const std::string body = R"(
3028 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
3029 %sampler = OpLoad %type_sampler %uniform_sampler
3030 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
3031 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %img %f32_0_5 Lod %f32_1
3032 )";
3033
3034 CompileSuccessfully(GenerateShaderCode(body).c_str());
3035 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3036 EXPECT_THAT(getDiagnosticString(),
3037 HasSubstr("Expected Coordinate to be float scalar or vector"));
3038 }
3039
TEST_F(ValidateImage,SampleProjDrefExplicitLodCoordinateSizeTooSmall)3040 TEST_F(ValidateImage, SampleProjDrefExplicitLodCoordinateSizeTooSmall) {
3041 const std::string body = R"(
3042 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
3043 %sampler = OpLoad %type_sampler %uniform_sampler
3044 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
3045 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32_0_5 %f32_0_5 Lod %f32_1
3046 )";
3047
3048 CompileSuccessfully(GenerateShaderCode(body).c_str());
3049 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3050 EXPECT_THAT(getDiagnosticString(),
3051 HasSubstr("Expected Coordinate to have at least 2 components, "
3052 "but given only 1"));
3053 }
3054
TEST_F(ValidateImage,FetchSuccess)3055 TEST_F(ValidateImage, FetchSuccess) {
3056 const std::string body = R"(
3057 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
3058 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
3059 %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
3060 )";
3061
3062 const std::string extra = R"(
3063 OpCapability VulkanMemoryModelKHR
3064 OpExtension "SPV_KHR_vulkan_memory_model"
3065 )";
3066 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3067 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3068 .c_str());
3069 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3070 }
3071
TEST_F(ValidateImage,FetchMultisampledSuccess)3072 TEST_F(ValidateImage, FetchMultisampledSuccess) {
3073 const std::string body = R"(
3074 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3075 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample %u32_1
3076 %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample|NonPrivateTexelKHR %u32_1
3077 )";
3078
3079 const std::string extra = R"(
3080 OpCapability VulkanMemoryModelKHR
3081 OpExtension "SPV_KHR_vulkan_memory_model"
3082 )";
3083 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3084 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3085 .c_str());
3086 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3087 }
3088
TEST_F(ValidateImage,FetchWrongResultType)3089 TEST_F(ValidateImage, FetchWrongResultType) {
3090 const std::string body = R"(
3091 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3092 %res1 = OpImageFetch %f32 %img %u32vec2_01
3093 )";
3094
3095 CompileSuccessfully(GenerateShaderCode(body).c_str());
3096 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3097 EXPECT_THAT(getDiagnosticString(),
3098 HasSubstr("Expected Result Type to be int or float vector type"));
3099 }
3100
TEST_F(ValidateImage,FetchWrongNumComponentsResultType)3101 TEST_F(ValidateImage, FetchWrongNumComponentsResultType) {
3102 const std::string body = R"(
3103 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3104 %res1 = OpImageFetch %f32vec3 %img %u32vec2_01
3105 )";
3106
3107 CompileSuccessfully(GenerateShaderCode(body).c_str());
3108 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3109 EXPECT_THAT(getDiagnosticString(),
3110 HasSubstr("Expected Result Type to have 4 components"));
3111 }
3112
TEST_F(ValidateImage,FetchNotImage)3113 TEST_F(ValidateImage, FetchNotImage) {
3114 const std::string body = R"(
3115 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3116 %sampler = OpLoad %type_sampler %uniform_sampler
3117 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3118 %res1 = OpImageFetch %f32vec4 %sampler %u32vec2_01
3119 )";
3120
3121 CompileSuccessfully(GenerateShaderCode(body).c_str());
3122 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3123 EXPECT_THAT(getDiagnosticString(),
3124 HasSubstr("Expected Image to be of type OpTypeImage"));
3125 }
3126
TEST_F(ValidateImage,FetchSampledImageDirectly)3127 TEST_F(ValidateImage, FetchSampledImageDirectly) {
3128 const std::string body = R"(
3129 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3130 %sampler = OpLoad %type_sampler %uniform_sampler
3131 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3132 %res1 = OpImageFetch %f32vec4 %simg %u32vec2_01
3133 )";
3134
3135 CompileSuccessfully(GenerateShaderCode(body).c_str());
3136 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3137 EXPECT_THAT(getDiagnosticString(),
3138 HasSubstr("OpSampledImage instruction must not appear as operand "
3139 "for OpImageFetch"));
3140 }
3141
TEST_F(ValidateImage,FetchNotSampled)3142 TEST_F(ValidateImage, FetchNotSampled) {
3143 const std::string body = R"(
3144 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3145 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
3146 )";
3147
3148 CompileSuccessfully(GenerateShaderCode(body).c_str());
3149 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3150 EXPECT_THAT(getDiagnosticString(),
3151 HasSubstr("Expected Image 'Sampled' parameter to be 1"));
3152 }
3153
TEST_F(ValidateImage,FetchCube)3154 TEST_F(ValidateImage, FetchCube) {
3155 const std::string body = R"(
3156 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3157 %res1 = OpImageFetch %f32vec4 %img %u32vec3_012
3158 )";
3159
3160 CompileSuccessfully(GenerateShaderCode(body).c_str());
3161 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3162 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' cannot be Cube"));
3163 }
3164
TEST_F(ValidateImage,FetchWrongSampledType)3165 TEST_F(ValidateImage, FetchWrongSampledType) {
3166 const std::string body = R"(
3167 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3168 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
3169 )";
3170
3171 CompileSuccessfully(GenerateShaderCode(body).c_str());
3172 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3173 EXPECT_THAT(getDiagnosticString(),
3174 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3175 "Result Type components"));
3176 }
3177
TEST_F(ValidateImage,FetchVoidSampledType)3178 TEST_F(ValidateImage, FetchVoidSampledType) {
3179 const std::string body = R"(
3180 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3181 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
3182 %res2 = OpImageFetch %u32vec4 %img %u32vec2_01
3183 %res3 = OpImageFetch %s32vec4 %img %u32vec2_01
3184 )";
3185
3186 CompileSuccessfully(GenerateShaderCode(body).c_str());
3187 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3188 }
3189
TEST_F(ValidateImage,FetchWrongCoordinateType)3190 TEST_F(ValidateImage, FetchWrongCoordinateType) {
3191 const std::string body = R"(
3192 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3193 %res1 = OpImageFetch %f32vec4 %img %f32vec2_00
3194 )";
3195
3196 CompileSuccessfully(GenerateShaderCode(body).c_str());
3197 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3198 EXPECT_THAT(getDiagnosticString(),
3199 HasSubstr("Expected Coordinate to be int scalar or vector"));
3200 }
3201
TEST_F(ValidateImage,FetchCoordinateSizeTooSmall)3202 TEST_F(ValidateImage, FetchCoordinateSizeTooSmall) {
3203 const std::string body = R"(
3204 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3205 %res1 = OpImageFetch %f32vec4 %img %u32_1
3206 )";
3207
3208 CompileSuccessfully(GenerateShaderCode(body).c_str());
3209 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3210 EXPECT_THAT(getDiagnosticString(),
3211 HasSubstr("Expected Coordinate to have at least 2 components, "
3212 "but given only 1"));
3213 }
3214
TEST_F(ValidateImage,FetchLodNotInt)3215 TEST_F(ValidateImage, FetchLodNotInt) {
3216 const std::string body = R"(
3217 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3218 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Lod %f32_1
3219 )";
3220
3221 CompileSuccessfully(GenerateShaderCode(body).c_str());
3222 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3223 EXPECT_THAT(getDiagnosticString(),
3224 HasSubstr("Expected Image Operand Lod to be int scalar when used "
3225 "with OpImageFetch"));
3226 }
3227
TEST_F(ValidateImage,FetchMultisampledMissingSample)3228 TEST_F(ValidateImage, FetchMultisampledMissingSample) {
3229 const std::string body = R"(
3230 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3231 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
3232 )";
3233
3234 CompileSuccessfully(GenerateShaderCode(body).c_str());
3235 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions())
3236 << GenerateShaderCode(body);
3237 EXPECT_THAT(getDiagnosticString(),
3238 HasSubstr("Image Operand Sample is required for operation on "
3239 "multi-sampled image"))
3240 << getDiagnosticString();
3241 }
3242
TEST_F(ValidateImage,GatherSuccess)3243 TEST_F(ValidateImage, GatherSuccess) {
3244 const std::string body = R"(
3245 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3246 %sampler = OpLoad %type_sampler %uniform_sampler
3247 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3248 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1
3249 %res2 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
3250 %res3 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
3251 )";
3252
3253 const std::string extra = R"(
3254 OpCapability VulkanMemoryModelKHR
3255 OpExtension "SPV_KHR_vulkan_memory_model"
3256 )";
3257 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3258 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3259 .c_str());
3260 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3261 }
3262
TEST_F(ValidateImage,GatherWrongResultType)3263 TEST_F(ValidateImage, GatherWrongResultType) {
3264 const std::string body = R"(
3265 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3266 %sampler = OpLoad %type_sampler %uniform_sampler
3267 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3268 %res1 = OpImageGather %f32 %simg %f32vec4_0000 %u32_1
3269 )";
3270
3271 CompileSuccessfully(GenerateShaderCode(body).c_str());
3272 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3273 EXPECT_THAT(getDiagnosticString(),
3274 HasSubstr("Expected Result Type to be int or float vector type"));
3275 }
3276
TEST_F(ValidateImage,GatherWrongNumComponentsResultType)3277 TEST_F(ValidateImage, GatherWrongNumComponentsResultType) {
3278 const std::string body = R"(
3279 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3280 %sampler = OpLoad %type_sampler %uniform_sampler
3281 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3282 %res1 = OpImageGather %f32vec3 %simg %f32vec4_0000 %u32_1
3283 )";
3284
3285 CompileSuccessfully(GenerateShaderCode(body).c_str());
3286 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3287 EXPECT_THAT(getDiagnosticString(),
3288 HasSubstr("Expected Result Type to have 4 components"));
3289 }
3290
TEST_F(ValidateImage,GatherNotSampledImage)3291 TEST_F(ValidateImage, GatherNotSampledImage) {
3292 const std::string body = R"(
3293 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3294 %res1 = OpImageGather %f32vec4 %img %f32vec4_0000 %u32_1
3295 )";
3296
3297 CompileSuccessfully(GenerateShaderCode(body).c_str());
3298 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3299 EXPECT_THAT(
3300 getDiagnosticString(),
3301 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
3302 }
3303
TEST_F(ValidateImage,GatherMultisampleError)3304 TEST_F(ValidateImage, GatherMultisampleError) {
3305 const std::string body = R"(
3306 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3307 %sampler = OpLoad %type_sampler %uniform_sampler
3308 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
3309 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Sample %u32_1
3310 )";
3311
3312 CompileSuccessfully(GenerateShaderCode(body).c_str());
3313 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3314 EXPECT_THAT(getDiagnosticString(),
3315 HasSubstr("Gather operation is invalid for multisample image"));
3316 }
3317
TEST_F(ValidateImage,GatherWrongSampledType)3318 TEST_F(ValidateImage, GatherWrongSampledType) {
3319 const std::string body = R"(
3320 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3321 %sampler = OpLoad %type_sampler %uniform_sampler
3322 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3323 %res1 = OpImageGather %u32vec4 %simg %f32vec4_0000 %u32_1
3324 )";
3325
3326 CompileSuccessfully(GenerateShaderCode(body).c_str());
3327 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3328 EXPECT_THAT(getDiagnosticString(),
3329 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3330 "Result Type components"));
3331 }
3332
TEST_F(ValidateImage,GatherVoidSampledType)3333 TEST_F(ValidateImage, GatherVoidSampledType) {
3334 const std::string body = R"(
3335 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3336 %sampler = OpLoad %type_sampler %uniform_sampler
3337 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
3338 %res1 = OpImageGather %u32vec4 %simg %f32vec2_00 %u32_1
3339 )";
3340
3341 CompileSuccessfully(GenerateShaderCode(body).c_str());
3342 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3343 }
3344
TEST_F(ValidateImage,GatherWrongCoordinateType)3345 TEST_F(ValidateImage, GatherWrongCoordinateType) {
3346 const std::string body = R"(
3347 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3348 %sampler = OpLoad %type_sampler %uniform_sampler
3349 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3350 %res1 = OpImageGather %f32vec4 %simg %u32vec4_0123 %u32_1
3351 )";
3352
3353 CompileSuccessfully(GenerateShaderCode(body).c_str());
3354 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3355 EXPECT_THAT(getDiagnosticString(),
3356 HasSubstr("Expected Coordinate to be float scalar or vector"));
3357 }
3358
TEST_F(ValidateImage,GatherCoordinateSizeTooSmall)3359 TEST_F(ValidateImage, GatherCoordinateSizeTooSmall) {
3360 const std::string body = R"(
3361 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3362 %sampler = OpLoad %type_sampler %uniform_sampler
3363 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3364 %res1 = OpImageGather %f32vec4 %simg %f32_0_5 %u32_1
3365 )";
3366
3367 CompileSuccessfully(GenerateShaderCode(body).c_str());
3368 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3369 EXPECT_THAT(getDiagnosticString(),
3370 HasSubstr("Expected Coordinate to have at least 4 components, "
3371 "but given only 1"));
3372 }
3373
TEST_F(ValidateImage,GatherWrongComponentType)3374 TEST_F(ValidateImage, GatherWrongComponentType) {
3375 const std::string body = R"(
3376 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3377 %sampler = OpLoad %type_sampler %uniform_sampler
3378 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3379 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %f32_1
3380 )";
3381
3382 CompileSuccessfully(GenerateShaderCode(body).c_str());
3383 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3384 EXPECT_THAT(getDiagnosticString(),
3385 HasSubstr("Expected Component to be 32-bit int scalar"));
3386 }
3387
TEST_F(ValidateImage,GatherComponentNot32Bit)3388 TEST_F(ValidateImage, GatherComponentNot32Bit) {
3389 const std::string body = R"(
3390 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3391 %sampler = OpLoad %type_sampler %uniform_sampler
3392 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3393 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u64_0
3394 )";
3395
3396 CompileSuccessfully(GenerateShaderCode(body).c_str());
3397 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3398 EXPECT_THAT(getDiagnosticString(),
3399 HasSubstr("Expected Component to be 32-bit int scalar"));
3400 }
3401
TEST_F(ValidateImage,GatherComponentSuccessVulkan)3402 TEST_F(ValidateImage, GatherComponentSuccessVulkan) {
3403 const std::string body = R"(
3404 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3405 %sampler = OpLoad %type_sampler %uniform_sampler
3406 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3407 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_0
3408 )";
3409
3410 spv_target_env env = SPV_ENV_VULKAN_1_0;
3411 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3412 env);
3413 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
3414 }
3415
TEST_F(ValidateImage,GatherComponentNotConstantVulkan)3416 TEST_F(ValidateImage, GatherComponentNotConstantVulkan) {
3417 const std::string body = R"(
3418 %input_u32 = OpLoad %u32 %input_flat_u32
3419 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3420 %sampler = OpLoad %type_sampler %uniform_sampler
3421 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3422 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %input_u32
3423 )";
3424
3425 spv_target_env env = SPV_ENV_VULKAN_1_0;
3426 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3427 env);
3428 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3429 EXPECT_THAT(getDiagnosticString(),
3430 AnyVUID("VUID-StandaloneSpirv-OpImageGather-04664"));
3431 EXPECT_THAT(getDiagnosticString(),
3432 HasSubstr("Expected Component Operand to be a const object for "
3433 "Vulkan environment"));
3434 }
3435
TEST_F(ValidateImage,GatherDimCube)3436 TEST_F(ValidateImage, GatherDimCube) {
3437 const std::string body = R"(
3438 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3439 %sampler = OpLoad %type_sampler %uniform_sampler
3440 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3441 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
3442 )";
3443
3444 CompileSuccessfully(GenerateShaderCode(body).c_str());
3445 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3446 EXPECT_THAT(
3447 getDiagnosticString(),
3448 HasSubstr(
3449 "Image Operand ConstOffsets cannot be used with Cube Image 'Dim'"));
3450 }
3451
TEST_F(ValidateImage,GatherConstOffsetsNotArray)3452 TEST_F(ValidateImage, GatherConstOffsetsNotArray) {
3453 const std::string body = R"(
3454 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3455 %sampler = OpLoad %type_sampler %uniform_sampler
3456 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3457 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %u32vec4_0123
3458 )";
3459
3460 CompileSuccessfully(GenerateShaderCode(body).c_str());
3461 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3462 EXPECT_THAT(
3463 getDiagnosticString(),
3464 HasSubstr(
3465 "Expected Image Operand ConstOffsets to be an array of size 4"));
3466 }
3467
TEST_F(ValidateImage,GatherConstOffsetsArrayWrongSize)3468 TEST_F(ValidateImage, GatherConstOffsetsArrayWrongSize) {
3469 const std::string body = R"(
3470 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3471 %sampler = OpLoad %type_sampler %uniform_sampler
3472 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3473 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets3x2
3474 )";
3475
3476 CompileSuccessfully(GenerateShaderCode(body).c_str());
3477 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3478 EXPECT_THAT(
3479 getDiagnosticString(),
3480 HasSubstr(
3481 "Expected Image Operand ConstOffsets to be an array of size 4"));
3482 }
3483
TEST_F(ValidateImage,GatherConstOffsetsArrayNotVector)3484 TEST_F(ValidateImage, GatherConstOffsetsArrayNotVector) {
3485 const std::string body = R"(
3486 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3487 %sampler = OpLoad %type_sampler %uniform_sampler
3488 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3489 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4xu
3490 )";
3491
3492 CompileSuccessfully(GenerateShaderCode(body).c_str());
3493 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3494 EXPECT_THAT(getDiagnosticString(),
3495 HasSubstr("Expected Image Operand ConstOffsets array components "
3496 "to be int vectors of size 2"));
3497 }
3498
TEST_F(ValidateImage,GatherConstOffsetsArrayVectorWrongSize)3499 TEST_F(ValidateImage, GatherConstOffsetsArrayVectorWrongSize) {
3500 const std::string body = R"(
3501 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3502 %sampler = OpLoad %type_sampler %uniform_sampler
3503 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3504 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4x3
3505 )";
3506
3507 CompileSuccessfully(GenerateShaderCode(body).c_str());
3508 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3509 EXPECT_THAT(getDiagnosticString(),
3510 HasSubstr("Expected Image Operand ConstOffsets array components "
3511 "to be int vectors of size 2"));
3512 }
3513
TEST_F(ValidateImage,GatherConstOffsetsArrayNotConst)3514 TEST_F(ValidateImage, GatherConstOffsetsArrayNotConst) {
3515 const std::string body = R"(
3516 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3517 %sampler = OpLoad %type_sampler %uniform_sampler
3518 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3519 %offsets = OpUndef %u32vec2arr4
3520 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %offsets
3521 )";
3522
3523 CompileSuccessfully(GenerateShaderCode(body).c_str());
3524 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3525 EXPECT_THAT(
3526 getDiagnosticString(),
3527 HasSubstr("Expected Image Operand ConstOffsets to be a const object"));
3528 }
3529
TEST_F(ValidateImage,NotGatherWithConstOffsets)3530 TEST_F(ValidateImage, NotGatherWithConstOffsets) {
3531 const std::string body = R"(
3532 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3533 %sampler = OpLoad %type_sampler %uniform_sampler
3534 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3535 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffsets %const_offsets
3536 )";
3537
3538 CompileSuccessfully(GenerateShaderCode(body).c_str());
3539 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3540 EXPECT_THAT(
3541 getDiagnosticString(),
3542 HasSubstr(
3543 "Image Operand ConstOffsets can only be used with OpImageGather "
3544 "and OpImageDrefGather"));
3545 }
3546
TEST_F(ValidateImage,DrefGatherSuccess)3547 TEST_F(ValidateImage, DrefGatherSuccess) {
3548 const std::string body = R"(
3549 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3550 %sampler = OpLoad %type_sampler %uniform_sampler
3551 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3552 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
3553 %res2 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 ConstOffsets %const_offsets
3554 %res3 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 NonPrivateTexelKHR
3555 )";
3556
3557 const std::string extra = R"(
3558 OpCapability VulkanMemoryModelKHR
3559 OpExtension "SPV_KHR_vulkan_memory_model"
3560 )";
3561 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3562 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3563 .c_str());
3564 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3565 }
3566
TEST_F(ValidateImage,DrefGatherMultisampleError)3567 TEST_F(ValidateImage, DrefGatherMultisampleError) {
3568 const std::string body = R"(
3569 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3570 %sampler = OpLoad %type_sampler %uniform_sampler
3571 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
3572 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_1 Sample %u32_1
3573 )";
3574
3575 CompileSuccessfully(GenerateShaderCode(body).c_str());
3576 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3577 EXPECT_THAT(getDiagnosticString(),
3578 HasSubstr("Gather operation is invalid for multisample image"));
3579 }
3580
TEST_F(ValidateImage,DrefGatherVoidSampledType)3581 TEST_F(ValidateImage, DrefGatherVoidSampledType) {
3582 const std::string body = R"(
3583 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3584 %sampler = OpLoad %type_sampler %uniform_sampler
3585 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
3586 %res1 = OpImageDrefGather %u32vec4 %simg %f32vec2_00 %f32_0_5
3587 )";
3588
3589 CompileSuccessfully(GenerateShaderCode(body).c_str());
3590 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3591 EXPECT_THAT(getDiagnosticString(),
3592 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3593 "Result Type components"));
3594 }
3595
TEST_F(ValidateImage,DrefGatherWrongDrefType)3596 TEST_F(ValidateImage, DrefGatherWrongDrefType) {
3597 const std::string body = R"(
3598 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3599 %sampler = OpLoad %type_sampler %uniform_sampler
3600 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3601 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %u32_1
3602 )";
3603
3604 CompileSuccessfully(GenerateShaderCode(body).c_str());
3605 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3606 EXPECT_THAT(getDiagnosticString(),
3607 HasSubstr("Expected Dref to be of 32-bit float type"));
3608 }
3609
TEST_F(ValidateImage,DrefGatherWrongDimVulkan)3610 TEST_F(ValidateImage, DrefGatherWrongDimVulkan) {
3611 const std::string body = R"(
3612 %img = OpLoad %type_image_f32_3d_0001 %uniform_image_f32_3d_0001
3613 %sampler = OpLoad %type_sampler %uniform_sampler
3614 %simg = OpSampledImage %type_sampled_image_f32_3d_0001 %img %sampler
3615 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
3616 )";
3617
3618 CompileSuccessfully(
3619 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
3620 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3621 EXPECT_THAT(getDiagnosticString(),
3622 AnyVUID("VUID-StandaloneSpirv-OpImage-04777"));
3623 EXPECT_THAT(getDiagnosticString(),
3624 HasSubstr("Expected Image 'Dim' to be 2D, Cube, or Rect"));
3625 }
3626
TEST_F(ValidateImage,ReadSuccess1)3627 TEST_F(ValidateImage, ReadSuccess1) {
3628 const std::string body = R"(
3629 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3630 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
3631 )";
3632
3633 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3634 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3635 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3636 }
3637
TEST_F(ValidateImage,ReadSuccess2)3638 TEST_F(ValidateImage, ReadSuccess2) {
3639 const std::string body = R"(
3640 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3641 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3642 )";
3643
3644 const std::string extra = "\nOpCapability Image1D\n";
3645 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3646 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3647 }
3648
TEST_F(ValidateImage,ReadSuccess3)3649 TEST_F(ValidateImage, ReadSuccess3) {
3650 const std::string body = R"(
3651 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3652 %res1 = OpImageRead %f32vec4 %img %u32vec3_012
3653 )";
3654
3655 const std::string extra = "\nOpCapability ImageCubeArray\n";
3656 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3657 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3658 }
3659
TEST_F(ValidateImage,ReadSuccess4)3660 TEST_F(ValidateImage, ReadSuccess4) {
3661 const std::string body = R"(
3662 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3663 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3664 )";
3665
3666 CompileSuccessfully(GenerateShaderCode(body).c_str());
3667 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3668 }
3669
TEST_F(ValidateImage,ReadNeedCapabilityStorageImageReadWithoutFormat)3670 TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) {
3671 const std::string body = R"(
3672 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3673 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
3674 )";
3675
3676 CompileSuccessfully(GenerateShaderCode(body).c_str());
3677 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3678 }
3679
TEST_F(ValidateImage,ReadNeedCapabilityStorageImageReadWithoutFormatVulkan)3680 TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) {
3681 const std::string body = R"(
3682 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3683 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
3684 )";
3685
3686 spv_target_env env = SPV_ENV_VULKAN_1_0;
3687 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3688 env);
3689 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3690 EXPECT_THAT(getDiagnosticString(),
3691 HasSubstr("Capability StorageImageReadWithoutFormat is required "
3692 "to read storage image"));
3693 }
3694
TEST_F(ValidateImage,ReadNeedCapabilityImage1D)3695 TEST_F(ValidateImage, ReadNeedCapabilityImage1D) {
3696 const std::string body = R"(
3697 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3698 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3699 )";
3700
3701 CompileSuccessfully(GenerateShaderCode(body).c_str());
3702 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3703 EXPECT_THAT(
3704 getDiagnosticString(),
3705 HasSubstr("Capability Image1D is required to access storage image"));
3706 }
3707
TEST_F(ValidateImage,ReadNeedCapabilityImageCubeArray)3708 TEST_F(ValidateImage, ReadNeedCapabilityImageCubeArray) {
3709 const std::string body = R"(
3710 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3711 %res1 = OpImageRead %f32vec4 %img %u32vec3_012
3712 )";
3713
3714 CompileSuccessfully(GenerateShaderCode(body).c_str());
3715 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3716 EXPECT_THAT(
3717 getDiagnosticString(),
3718 HasSubstr(
3719 "Capability ImageCubeArray is required to access storage image"));
3720 }
3721
3722 // TODO([email protected]) Disabled until the spec is clarified.
TEST_F(ValidateImage,DISABLED_ReadWrongResultType)3723 TEST_F(ValidateImage, DISABLED_ReadWrongResultType) {
3724 const std::string body = R"(
3725 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3726 %res1 = OpImageRead %f32 %img %u32vec2_01
3727 )";
3728
3729 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3730 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3731 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3732 EXPECT_THAT(getDiagnosticString(),
3733 HasSubstr("Expected Result Type to be int or float vector type"));
3734 }
3735
TEST_F(ValidateImage,ReadScalarResultType_Universal)3736 TEST_F(ValidateImage, ReadScalarResultType_Universal) {
3737 const std::string body = R"(
3738 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3739 %res1 = OpImageRead %u32 %img %u32vec2_01
3740 )";
3741
3742 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3743 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3744 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
3745 EXPECT_THAT(getDiagnosticString(), Eq(""));
3746 }
3747
TEST_F(ValidateImage,ReadUnusualNumComponentsResultType_Universal)3748 TEST_F(ValidateImage, ReadUnusualNumComponentsResultType_Universal) {
3749 const std::string body = R"(
3750 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3751 %res1 = OpImageRead %u32vec3 %img %u32vec2_01
3752 )";
3753
3754 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3755 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3756 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
3757 EXPECT_THAT(getDiagnosticString(), Eq(""));
3758 }
3759
TEST_F(ValidateImage,ReadWrongNumComponentsResultType_Vulkan)3760 TEST_F(ValidateImage, ReadWrongNumComponentsResultType_Vulkan) {
3761 const std::string body = R"(
3762 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3763 %res1 = OpImageRead %u32vec3 %img %u32vec2_01
3764 )";
3765
3766 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3767 CompileSuccessfully(
3768 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_VULKAN_1_0)
3769 .c_str());
3770 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3771 EXPECT_THAT(getDiagnosticString(),
3772 AnyVUID("VUID-StandaloneSpirv-Result-04780"));
3773 EXPECT_THAT(getDiagnosticString(),
3774 HasSubstr("Expected Result Type to have 4 components"));
3775 }
3776
TEST_F(ValidateImage,ReadNotImage)3777 TEST_F(ValidateImage, ReadNotImage) {
3778 const std::string body = R"(
3779 %sampler = OpLoad %type_sampler %uniform_sampler
3780 %res1 = OpImageRead %f32vec4 %sampler %u32vec2_01
3781 )";
3782
3783 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3784 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3785 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3786 EXPECT_THAT(getDiagnosticString(),
3787 HasSubstr("Expected Image to be of type OpTypeImage"));
3788 }
3789
TEST_F(ValidateImage,ReadImageSampled)3790 TEST_F(ValidateImage, ReadImageSampled) {
3791 const std::string body = R"(
3792 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3793 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3794 )";
3795
3796 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3797 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3798 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3799 EXPECT_THAT(getDiagnosticString(),
3800 HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
3801 }
3802
TEST_F(ValidateImage,ReadWrongSampledType)3803 TEST_F(ValidateImage, ReadWrongSampledType) {
3804 const std::string body = R"(
3805 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3806 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3807 )";
3808
3809 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3810 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3811 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3812 EXPECT_THAT(getDiagnosticString(),
3813 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3814 "Result Type components"));
3815 }
3816
TEST_F(ValidateImage,ReadVoidSampledType)3817 TEST_F(ValidateImage, ReadVoidSampledType) {
3818 const std::string body = R"(
3819 %img = OpLoad %type_image_void_2d_0002 %uniform_image_void_2d_0002
3820 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3821 %res2 = OpImageRead %u32vec4 %img %u32vec2_01
3822 %res3 = OpImageRead %s32vec4 %img %u32vec2_01
3823 )";
3824
3825 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3826 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3827 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3828 }
3829
TEST_F(ValidateImage,ReadWrongCoordinateType)3830 TEST_F(ValidateImage, ReadWrongCoordinateType) {
3831 const std::string body = R"(
3832 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3833 %res1 = OpImageRead %u32vec4 %img %f32vec2_00
3834 )";
3835
3836 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3837 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3838 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3839 EXPECT_THAT(getDiagnosticString(),
3840 HasSubstr("Expected Coordinate to be int scalar or vector"));
3841 }
3842
TEST_F(ValidateImage,ReadCoordinateSizeTooSmall)3843 TEST_F(ValidateImage, ReadCoordinateSizeTooSmall) {
3844 const std::string body = R"(
3845 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3846 %res1 = OpImageRead %u32vec4 %img %u32_1
3847 )";
3848
3849 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3850 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3851 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3852 EXPECT_THAT(getDiagnosticString(),
3853 HasSubstr("Expected Coordinate to have at least 2 components, "
3854 "but given only 1"));
3855 }
3856
TEST_F(ValidateImage,WriteSuccess1)3857 TEST_F(ValidateImage, WriteSuccess1) {
3858 const std::string body = R"(
3859 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3860 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3861 )";
3862
3863 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3864 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3865 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3866 }
3867
TEST_F(ValidateImage,WriteSuccess2)3868 TEST_F(ValidateImage, WriteSuccess2) {
3869 const std::string body = R"(
3870 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3871 OpImageWrite %img %u32_1 %f32vec4_0000
3872 )";
3873
3874 const std::string extra = "\nOpCapability Image1D\n";
3875 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3876 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3877 }
3878
TEST_F(ValidateImage,WriteSuccess3)3879 TEST_F(ValidateImage, WriteSuccess3) {
3880 const std::string body = R"(
3881 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3882 OpImageWrite %img %u32vec3_012 %f32vec4_0000
3883 )";
3884
3885 const std::string extra = "\nOpCapability ImageCubeArray\n";
3886 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3887 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3888 }
3889
TEST_F(ValidateImage,WriteSuccess4)3890 TEST_F(ValidateImage, WriteSuccess4) {
3891 const std::string body = R"(
3892 %img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
3893 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
3894 )";
3895
3896 const std::string extra = R"(
3897 OpCapability StorageImageWriteWithoutFormat
3898 OpCapability StorageImageMultisample
3899 )";
3900
3901 const std::string declarations = R"(
3902 %type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
3903 %ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
3904 %uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
3905 )";
3906 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3907 SPV_ENV_UNIVERSAL_1_0, "GLSL450",
3908 declarations)
3909 .c_str());
3910 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3911 }
3912
TEST_F(ValidateImage,WriteSubpassData)3913 TEST_F(ValidateImage, WriteSubpassData) {
3914 const std::string body = R"(
3915 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3916 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3917 )";
3918
3919 CompileSuccessfully(GenerateShaderCode(body).c_str());
3920 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3921 EXPECT_THAT(getDiagnosticString(),
3922 HasSubstr("Image 'Dim' cannot be SubpassData"));
3923 }
3924
TEST_F(ValidateImage,WriteNeedCapabilityStorageImageWriteWithoutFormat)3925 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
3926 const std::string body = R"(
3927 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3928 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3929 )";
3930
3931 CompileSuccessfully(GenerateShaderCode(body).c_str());
3932 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3933 }
3934
TEST_F(ValidateImage,WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan)3935 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
3936 const std::string body = R"(
3937 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3938 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3939 )";
3940
3941 spv_target_env env = SPV_ENV_VULKAN_1_0;
3942 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3943 env);
3944 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3945 EXPECT_THAT(
3946 getDiagnosticString(),
3947 HasSubstr(
3948 "Capability StorageImageWriteWithoutFormat is required to write to "
3949 "storage image"));
3950 }
3951
TEST_F(ValidateImage,WriteNeedCapabilityImage1D)3952 TEST_F(ValidateImage, WriteNeedCapabilityImage1D) {
3953 const std::string body = R"(
3954 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3955 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3956 )";
3957
3958 CompileSuccessfully(GenerateShaderCode(body).c_str());
3959 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3960 EXPECT_THAT(getDiagnosticString(),
3961 HasSubstr("Capability Image1D is required to access storage "
3962 "image"));
3963 }
3964
TEST_F(ValidateImage,WriteNeedCapabilityImageCubeArray)3965 TEST_F(ValidateImage, WriteNeedCapabilityImageCubeArray) {
3966 const std::string body = R"(
3967 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3968 OpImageWrite %img %u32vec3_012 %f32vec4_0000
3969 )";
3970
3971 CompileSuccessfully(GenerateShaderCode(body).c_str());
3972 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3973 EXPECT_THAT(
3974 getDiagnosticString(),
3975 HasSubstr(
3976 "Capability ImageCubeArray is required to access storage image"));
3977 }
3978
TEST_F(ValidateImage,WriteNotImage)3979 TEST_F(ValidateImage, WriteNotImage) {
3980 const std::string body = R"(
3981 %sampler = OpLoad %type_sampler %uniform_sampler
3982 OpImageWrite %sampler %u32vec2_01 %f32vec4_0000
3983 )";
3984
3985 CompileSuccessfully(GenerateShaderCode(body).c_str());
3986 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3987 EXPECT_THAT(getDiagnosticString(),
3988 HasSubstr("Expected Image to be of type OpTypeImage"));
3989 }
3990
TEST_F(ValidateImage,WriteImageSampled)3991 TEST_F(ValidateImage, WriteImageSampled) {
3992 const std::string body = R"(
3993 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3994 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3995 )";
3996
3997 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3998 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3999 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4000 EXPECT_THAT(getDiagnosticString(),
4001 HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
4002 }
4003
TEST_F(ValidateImage,WriteWrongCoordinateType)4004 TEST_F(ValidateImage, WriteWrongCoordinateType) {
4005 const std::string body = R"(
4006 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4007 OpImageWrite %img %f32vec2_00 %u32vec4_0123
4008 )";
4009
4010 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4011 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4012 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4013 EXPECT_THAT(getDiagnosticString(),
4014 HasSubstr("Expected Coordinate to be int scalar or vector"));
4015 }
4016
TEST_F(ValidateImage,WriteCoordinateSizeTooSmall)4017 TEST_F(ValidateImage, WriteCoordinateSizeTooSmall) {
4018 const std::string body = R"(
4019 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4020 OpImageWrite %img %u32_1 %u32vec4_0123
4021 )";
4022
4023 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4024 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4025 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4026 EXPECT_THAT(getDiagnosticString(),
4027 HasSubstr("Expected Coordinate to have at least 2 components, "
4028 "but given only 1"));
4029 }
4030
TEST_F(ValidateImage,WriteTexelScalarSuccess)4031 TEST_F(ValidateImage, WriteTexelScalarSuccess) {
4032 const std::string body = R"(
4033 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4034 OpImageWrite %img %u32vec2_01 %u32_2
4035 )";
4036
4037 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4038 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4039 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4040 }
4041
TEST_F(ValidateImage,WriteTexelWrongType)4042 TEST_F(ValidateImage, WriteTexelWrongType) {
4043 const std::string body = R"(
4044 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4045 OpImageWrite %img %u32vec2_01 %img
4046 )";
4047
4048 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4049 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4050 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4051 EXPECT_THAT(getDiagnosticString(),
4052 HasSubstr("Expected Texel to be int or float vector or scalar"));
4053 }
4054
TEST_F(ValidateImage,WriteTexelNonNumericalType)4055 TEST_F(ValidateImage, WriteTexelNonNumericalType) {
4056 const std::string body = R"(
4057 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4058 OpImageWrite %img %u32vec2_01 %boolvec4_tttt
4059 )";
4060
4061 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4062 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4063 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4064 EXPECT_THAT(getDiagnosticString(),
4065 HasSubstr("Expected Texel to be int or float vector or scalar"));
4066 }
4067
TEST_F(ValidateImage,WriteTexelWrongComponentType)4068 TEST_F(ValidateImage, WriteTexelWrongComponentType) {
4069 const std::string body = R"(
4070 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4071 OpImageWrite %img %u32vec2_01 %f32vec4_0000
4072 )";
4073
4074 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4075 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4076 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4077 EXPECT_THAT(
4078 getDiagnosticString(),
4079 HasSubstr(
4080 "Expected Image 'Sampled Type' to be the same as Texel components"));
4081 }
4082
TEST_F(ValidateImage,WriteSampleNotInteger)4083 TEST_F(ValidateImage, WriteSampleNotInteger) {
4084 const std::string body = R"(
4085 %img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
4086 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1
4087 )";
4088
4089 const std::string extra = R"(
4090 OpCapability StorageImageWriteWithoutFormat
4091 OpCapability StorageImageMultisample
4092 )";
4093 const std::string declarations = R"(
4094 %type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
4095 %ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
4096 %uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
4097 )";
4098 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4099 SPV_ENV_UNIVERSAL_1_0, "GLSL450",
4100 declarations)
4101 .c_str());
4102 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4103 EXPECT_THAT(getDiagnosticString(),
4104 HasSubstr("Expected Image Operand Sample to be int scalar"));
4105 }
4106
TEST_F(ValidateImage,WriteSampleNotMultisampled)4107 TEST_F(ValidateImage, WriteSampleNotMultisampled) {
4108 const std::string body = R"(
4109 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4110 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
4111 )";
4112
4113 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4114 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4115 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4116 EXPECT_THAT(
4117 getDiagnosticString(),
4118 HasSubstr("Image Operand Sample requires non-zero 'MS' parameter"));
4119 }
4120
TEST_F(ValidateImage,SampleWrongOpcode)4121 TEST_F(ValidateImage, SampleWrongOpcode) {
4122 const std::string body = R"(
4123 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4124 %sampler = OpLoad %type_sampler %uniform_sampler
4125 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
4126 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Sample %u32_1
4127 )";
4128
4129 CompileSuccessfully(GenerateShaderCode(body).c_str());
4130 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4131 EXPECT_THAT(getDiagnosticString(),
4132 HasSubstr("Sampling operation is invalid for multisample image"));
4133 }
4134
TEST_F(ValidateImage,SampleImageToImageSuccess)4135 TEST_F(ValidateImage, SampleImageToImageSuccess) {
4136 const std::string body = R"(
4137 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4138 %sampler = OpLoad %type_sampler %uniform_sampler
4139 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4140 %img2 = OpImage %type_image_f32_2d_0001 %simg
4141 )";
4142
4143 CompileSuccessfully(GenerateShaderCode(body).c_str());
4144 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4145 }
4146
TEST_F(ValidateImage,SampleImageToImageWrongResultType)4147 TEST_F(ValidateImage, SampleImageToImageWrongResultType) {
4148 const std::string body = R"(
4149 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4150 %sampler = OpLoad %type_sampler %uniform_sampler
4151 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4152 %img2 = OpImage %type_sampled_image_f32_2d_0001 %simg
4153 )";
4154
4155 CompileSuccessfully(GenerateShaderCode(body).c_str());
4156 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4157 EXPECT_THAT(getDiagnosticString(),
4158 HasSubstr("Expected Result Type to be OpTypeImage"));
4159 }
4160
TEST_F(ValidateImage,SampleImageToImageNotSampledImage)4161 TEST_F(ValidateImage, SampleImageToImageNotSampledImage) {
4162 const std::string body = R"(
4163 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4164 %img2 = OpImage %type_image_f32_2d_0001 %img
4165 )";
4166
4167 CompileSuccessfully(GenerateShaderCode(body).c_str());
4168 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4169 EXPECT_THAT(
4170 getDiagnosticString(),
4171 HasSubstr("Expected Sample Image to be of type OpTypeSampleImage"));
4172 }
4173
TEST_F(ValidateImage,SampleImageToImageNotTheSameImageType)4174 TEST_F(ValidateImage, SampleImageToImageNotTheSameImageType) {
4175 const std::string body = R"(
4176 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4177 %sampler = OpLoad %type_sampler %uniform_sampler
4178 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4179 %img2 = OpImage %type_image_f32_2d_0002 %simg
4180 )";
4181
4182 CompileSuccessfully(GenerateShaderCode(body).c_str());
4183 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4184 EXPECT_THAT(getDiagnosticString(),
4185 HasSubstr("Expected Sample Image image type to be equal to "
4186 "Result Type"));
4187 }
4188
TEST_F(ValidateImage,QueryFormatSuccess)4189 TEST_F(ValidateImage, QueryFormatSuccess) {
4190 const std::string body = R"(
4191 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4192 %res1 = OpImageQueryFormat %u32 %img
4193 )";
4194
4195 CompileSuccessfully(GenerateKernelCode(body).c_str());
4196 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4197 }
4198
TEST_F(ValidateImage,QueryFormatWrongResultType)4199 TEST_F(ValidateImage, QueryFormatWrongResultType) {
4200 const std::string body = R"(
4201 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4202 %res1 = OpImageQueryFormat %bool %img
4203 )";
4204
4205 CompileSuccessfully(GenerateKernelCode(body).c_str());
4206 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4207 EXPECT_THAT(getDiagnosticString(),
4208 HasSubstr("Expected Result Type to be int scalar type"));
4209 }
4210
TEST_F(ValidateImage,QueryFormatNotImage)4211 TEST_F(ValidateImage, QueryFormatNotImage) {
4212 const std::string body = R"(
4213 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4214 %sampler = OpLoad %type_sampler %uniform_sampler
4215 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4216 %res1 = OpImageQueryFormat %u32 %sampler
4217 )";
4218
4219 CompileSuccessfully(GenerateKernelCode(body).c_str());
4220 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4221 EXPECT_THAT(getDiagnosticString(),
4222 HasSubstr("Expected operand to be of type OpTypeImage"));
4223 }
4224
TEST_F(ValidateImage,QueryOrderSuccess)4225 TEST_F(ValidateImage, QueryOrderSuccess) {
4226 const std::string body = R"(
4227 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4228 %res1 = OpImageQueryOrder %u32 %img
4229 )";
4230
4231 CompileSuccessfully(GenerateKernelCode(body).c_str());
4232 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4233 }
4234
TEST_F(ValidateImage,QueryOrderWrongResultType)4235 TEST_F(ValidateImage, QueryOrderWrongResultType) {
4236 const std::string body = R"(
4237 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4238 %res1 = OpImageQueryOrder %bool %img
4239 )";
4240
4241 CompileSuccessfully(GenerateKernelCode(body).c_str());
4242 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4243 EXPECT_THAT(getDiagnosticString(),
4244 HasSubstr("Expected Result Type to be int scalar type"));
4245 }
4246
TEST_F(ValidateImage,QueryOrderNotImage)4247 TEST_F(ValidateImage, QueryOrderNotImage) {
4248 const std::string body = R"(
4249 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4250 %sampler = OpLoad %type_sampler %uniform_sampler
4251 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4252 %res1 = OpImageQueryOrder %u32 %sampler
4253 )";
4254
4255 CompileSuccessfully(GenerateKernelCode(body).c_str());
4256 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4257 EXPECT_THAT(getDiagnosticString(),
4258 HasSubstr("Expected operand to be of type OpTypeImage"));
4259 }
4260
TEST_F(ValidateImage,QuerySizeLodSuccess)4261 TEST_F(ValidateImage, QuerySizeLodSuccess) {
4262 const std::string body = R"(
4263 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4264 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4265 )";
4266
4267 CompileSuccessfully(GenerateKernelCode(body).c_str());
4268 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4269 }
4270
TEST_F(ValidateImage,QuerySizeLodWrongResultType)4271 TEST_F(ValidateImage, QuerySizeLodWrongResultType) {
4272 const std::string body = R"(
4273 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4274 %res1 = OpImageQuerySizeLod %f32vec2 %img %u32_1
4275 )";
4276
4277 CompileSuccessfully(GenerateKernelCode(body).c_str());
4278 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4279 EXPECT_THAT(
4280 getDiagnosticString(),
4281 HasSubstr("Expected Result Type to be int scalar or vector type"));
4282 }
4283
TEST_F(ValidateImage,QuerySizeLodResultTypeWrongSize)4284 TEST_F(ValidateImage, QuerySizeLodResultTypeWrongSize) {
4285 const std::string body = R"(
4286 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4287 %res1 = OpImageQuerySizeLod %u32 %img %u32_1
4288 )";
4289
4290 CompileSuccessfully(GenerateKernelCode(body).c_str());
4291 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4292 EXPECT_THAT(getDiagnosticString(),
4293 HasSubstr("Result Type has 1 components, but 2 expected"));
4294 }
4295
TEST_F(ValidateImage,QuerySizeLodNotImage)4296 TEST_F(ValidateImage, QuerySizeLodNotImage) {
4297 const std::string body = R"(
4298 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4299 %sampler = OpLoad %type_sampler %uniform_sampler
4300 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4301 %res1 = OpImageQuerySizeLod %u32vec2 %sampler %u32_1
4302 )";
4303
4304 CompileSuccessfully(GenerateKernelCode(body).c_str());
4305 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4306 EXPECT_THAT(getDiagnosticString(),
4307 HasSubstr("Expected Image to be of type OpTypeImage"));
4308 }
4309
TEST_F(ValidateImage,QuerySizeLodSampledImageDirectly)4310 TEST_F(ValidateImage, QuerySizeLodSampledImageDirectly) {
4311 const std::string body = R"(
4312 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4313 %sampler = OpLoad %type_sampler %uniform_sampler
4314 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4315 %res1 = OpImageQuerySizeLod %u32vec2 %simg %u32_1
4316 )";
4317
4318 CompileSuccessfully(GenerateShaderCode(body).c_str());
4319 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4320 EXPECT_THAT(getDiagnosticString(),
4321 HasSubstr("OpSampledImage instruction must not appear as operand "
4322 "for OpImageQuerySizeLod"));
4323 }
4324
TEST_F(ValidateImage,QuerySizeLodMultisampledError)4325 TEST_F(ValidateImage, QuerySizeLodMultisampledError) {
4326 const std::string body = R"(
4327 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4328 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4329 )";
4330
4331 CompileSuccessfully(GenerateKernelCode(body).c_str());
4332 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4333 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 0"));
4334 }
4335
TEST_F(ValidateImage,QuerySizeLodNonSampledUniversalSuccess)4336 TEST_F(ValidateImage, QuerySizeLodNonSampledUniversalSuccess) {
4337 const std::string body = R"(
4338 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4339 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4340 )";
4341
4342 CompileSuccessfully(GenerateShaderCode(body).c_str());
4343 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4344 EXPECT_EQ(getDiagnosticString(), "");
4345 }
4346
TEST_F(ValidateImage,QuerySizeLodVulkanNonSampledError)4347 TEST_F(ValidateImage, QuerySizeLodVulkanNonSampledError) {
4348 // Create a whole shader module. Avoid Vulkan incompatibility with
4349 // SampledRrect images inserted by helper function GenerateShaderCode.
4350 const std::string body = R"(
4351 OpCapability Shader
4352 OpCapability ImageQuery
4353 OpMemoryModel Logical Simple
4354 OpEntryPoint Fragment %main "main"
4355 OpExecutionMode %main OriginUpperLeft
4356
4357 %f32 = OpTypeFloat 32
4358 %u32 = OpTypeInt 32 0
4359 %u32_0 = OpConstant %u32 0
4360 %u32vec2 = OpTypeVector %u32 2
4361 %void = OpTypeVoid
4362 %voidfn = OpTypeFunction %void
4363
4364 ; Test with a storage image.
4365 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4366 %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
4367 %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
4368
4369 %main = OpFunction %void None %voidfn
4370 %entry = OpLabel
4371 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4372 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_0
4373 OpReturn
4374 OpFunctionEnd
4375 )";
4376
4377 CompileSuccessfully(body.c_str());
4378 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4379 EXPECT_THAT(getDiagnosticString(),
4380 AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
4381 EXPECT_THAT(
4382 getDiagnosticString(),
4383 HasSubstr(
4384 "OpImageQuerySizeLod must only consume an \"Image\" operand whose "
4385 "type has its \"Sampled\" operand set to 1"));
4386 }
4387
TEST_F(ValidateImage,QuerySizeLodWrongImageDim)4388 TEST_F(ValidateImage, QuerySizeLodWrongImageDim) {
4389 const std::string body = R"(
4390 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4391 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4392 )";
4393
4394 CompileSuccessfully(GenerateKernelCode(body).c_str());
4395 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4396 EXPECT_THAT(getDiagnosticString(),
4397 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4398 }
4399
TEST_F(ValidateImage,QuerySizeLodWrongLodType)4400 TEST_F(ValidateImage, QuerySizeLodWrongLodType) {
4401 const std::string body = R"(
4402 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4403 %res1 = OpImageQuerySizeLod %u32vec2 %img %f32_0
4404 )";
4405
4406 CompileSuccessfully(GenerateKernelCode(body).c_str());
4407 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4408 EXPECT_THAT(getDiagnosticString(),
4409 HasSubstr("Expected Level of Detail to be int scalar"));
4410 }
4411
TEST_F(ValidateImage,QuerySizeSuccess)4412 TEST_F(ValidateImage, QuerySizeSuccess) {
4413 const std::string body = R"(
4414 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4415 %res1 = OpImageQuerySize %u32vec2 %img
4416 )";
4417
4418 CompileSuccessfully(GenerateKernelCode(body).c_str());
4419 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4420 }
4421
TEST_F(ValidateImage,QuerySizeWrongResultType)4422 TEST_F(ValidateImage, QuerySizeWrongResultType) {
4423 const std::string body = R"(
4424 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4425 %res1 = OpImageQuerySize %f32vec2 %img
4426 )";
4427
4428 CompileSuccessfully(GenerateKernelCode(body).c_str());
4429 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4430 EXPECT_THAT(
4431 getDiagnosticString(),
4432 HasSubstr("Expected Result Type to be int scalar or vector type"));
4433 }
4434
TEST_F(ValidateImage,QuerySizeNotImage)4435 TEST_F(ValidateImage, QuerySizeNotImage) {
4436 const std::string body = R"(
4437 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4438 %sampler = OpLoad %type_sampler %uniform_sampler
4439 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4440 %res1 = OpImageQuerySize %u32vec2 %sampler
4441 )";
4442
4443 CompileSuccessfully(GenerateKernelCode(body).c_str());
4444 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4445 EXPECT_THAT(getDiagnosticString(),
4446 HasSubstr("Expected Image to be of type OpTypeImage"));
4447 }
4448
TEST_F(ValidateImage,QuerySizeSampledImageDirectly)4449 TEST_F(ValidateImage, QuerySizeSampledImageDirectly) {
4450 const std::string body = R"(
4451 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4452 %sampler = OpLoad %type_sampler %uniform_sampler
4453 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4454 %res1 = OpImageQuerySize %u32vec2 %simg
4455 )";
4456
4457 CompileSuccessfully(GenerateShaderCode(body).c_str());
4458 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4459 EXPECT_THAT(getDiagnosticString(),
4460 HasSubstr("OpSampledImage instruction must not appear as operand "
4461 "for OpImageQuerySize"));
4462 }
4463
TEST_F(ValidateImage,QuerySizeDimSubpassDataBad)4464 TEST_F(ValidateImage, QuerySizeDimSubpassDataBad) {
4465 const std::string body = R"(
4466 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
4467 %res1 = OpImageQuerySize %u32vec2 %img
4468 )";
4469
4470 CompileSuccessfully(GenerateShaderCode(body).c_str());
4471 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4472 EXPECT_THAT(
4473 getDiagnosticString(),
4474 HasSubstr("Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"));
4475 }
4476
TEST_F(ValidateImage,QuerySizeWrongSampling)4477 TEST_F(ValidateImage, QuerySizeWrongSampling) {
4478 const std::string body = R"(
4479 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4480 %res1 = OpImageQuerySize %u32vec2 %img
4481 )";
4482
4483 CompileSuccessfully(GenerateKernelCode(body).c_str());
4484 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4485 EXPECT_THAT(
4486 getDiagnosticString(),
4487 HasSubstr("Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"));
4488 }
4489
TEST_F(ValidateImage,QuerySizeWrongNumberOfComponents)4490 TEST_F(ValidateImage, QuerySizeWrongNumberOfComponents) {
4491 const std::string body = R"(
4492 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
4493 %res1 = OpImageQuerySize %u32vec2 %img
4494 )";
4495
4496 CompileSuccessfully(GenerateShaderCode(body).c_str());
4497 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4498 EXPECT_THAT(getDiagnosticString(),
4499 HasSubstr("Result Type has 2 components, but 4 expected"));
4500 }
4501
TEST_F(ValidateImage,QueryLodSuccessKernel)4502 TEST_F(ValidateImage, QueryLodSuccessKernel) {
4503 const std::string body = R"(
4504 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4505 %sampler = OpLoad %type_sampler %uniform_sampler
4506 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4507 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4508 %res2 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
4509 )";
4510
4511 CompileSuccessfully(GenerateKernelCode(body).c_str());
4512 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4513 }
4514
TEST_F(ValidateImage,QueryLodSuccessShader)4515 TEST_F(ValidateImage, QueryLodSuccessShader) {
4516 const std::string body = R"(
4517 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4518 %sampler = OpLoad %type_sampler %uniform_sampler
4519 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4520 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4521 )";
4522
4523 CompileSuccessfully(GenerateShaderCode(body).c_str());
4524 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4525 }
4526
TEST_F(ValidateImage,QueryLodWrongResultType)4527 TEST_F(ValidateImage, QueryLodWrongResultType) {
4528 const std::string body = R"(
4529 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4530 %sampler = OpLoad %type_sampler %uniform_sampler
4531 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4532 %res1 = OpImageQueryLod %u32vec2 %simg %f32vec2_hh
4533 )";
4534
4535 CompileSuccessfully(GenerateKernelCode(body).c_str());
4536 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4537 EXPECT_THAT(getDiagnosticString(),
4538 HasSubstr("Expected Result Type to be float vector type"));
4539 }
4540
TEST_F(ValidateImage,QueryLodResultTypeWrongSize)4541 TEST_F(ValidateImage, QueryLodResultTypeWrongSize) {
4542 const std::string body = R"(
4543 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4544 %sampler = OpLoad %type_sampler %uniform_sampler
4545 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4546 %res1 = OpImageQueryLod %f32vec3 %simg %f32vec2_hh
4547 )";
4548
4549 CompileSuccessfully(GenerateKernelCode(body).c_str());
4550 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4551 EXPECT_THAT(getDiagnosticString(),
4552 HasSubstr("Expected Result Type to have 2 components"));
4553 }
4554
TEST_F(ValidateImage,QueryLodNotSampledImage)4555 TEST_F(ValidateImage, QueryLodNotSampledImage) {
4556 const std::string body = R"(
4557 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4558 %res1 = OpImageQueryLod %f32vec2 %img %f32vec2_hh
4559 )";
4560
4561 CompileSuccessfully(GenerateKernelCode(body).c_str());
4562 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4563 EXPECT_THAT(
4564 getDiagnosticString(),
4565 HasSubstr("Expected Image operand to be of type OpTypeSampledImage"));
4566 }
4567
TEST_F(ValidateImage,QueryLodWrongDim)4568 TEST_F(ValidateImage, QueryLodWrongDim) {
4569 const std::string body = R"(
4570 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4571 %sampler = OpLoad %type_sampler %uniform_sampler
4572 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
4573 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4574 )";
4575
4576 CompileSuccessfully(GenerateKernelCode(body).c_str());
4577 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4578 EXPECT_THAT(getDiagnosticString(),
4579 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4580 }
4581
TEST_F(ValidateImage,QueryLodWrongCoordinateType)4582 TEST_F(ValidateImage, QueryLodWrongCoordinateType) {
4583 const std::string body = R"(
4584 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4585 %sampler = OpLoad %type_sampler %uniform_sampler
4586 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4587 %res1 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
4588 )";
4589
4590 CompileSuccessfully(GenerateShaderCode(body).c_str());
4591 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4592 EXPECT_THAT(getDiagnosticString(),
4593 HasSubstr("Expected Coordinate to be float scalar or vector"));
4594 }
4595
TEST_F(ValidateImage,QueryLodCoordinateSizeTooSmall)4596 TEST_F(ValidateImage, QueryLodCoordinateSizeTooSmall) {
4597 const std::string body = R"(
4598 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4599 %sampler = OpLoad %type_sampler %uniform_sampler
4600 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4601 %res1 = OpImageQueryLod %f32vec2 %simg %f32_0
4602 )";
4603
4604 CompileSuccessfully(GenerateShaderCode(body).c_str());
4605 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4606 EXPECT_THAT(getDiagnosticString(),
4607 HasSubstr("Expected Coordinate to have at least 2 components, "
4608 "but given only 1"));
4609 }
4610
TEST_F(ValidateImage,QueryLevelsSuccess)4611 TEST_F(ValidateImage, QueryLevelsSuccess) {
4612 const std::string body = R"(
4613 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4614 %res1 = OpImageQueryLevels %u32 %img
4615 )";
4616
4617 CompileSuccessfully(GenerateKernelCode(body).c_str());
4618 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4619 }
4620
TEST_F(ValidateImage,QueryLevelsWrongResultType)4621 TEST_F(ValidateImage, QueryLevelsWrongResultType) {
4622 const std::string body = R"(
4623 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4624 %res1 = OpImageQueryLevels %f32 %img
4625 )";
4626
4627 CompileSuccessfully(GenerateKernelCode(body).c_str());
4628 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4629 EXPECT_THAT(getDiagnosticString(),
4630 HasSubstr("Expected Result Type to be int scalar type"));
4631 }
4632
TEST_F(ValidateImage,QueryLevelsNotImage)4633 TEST_F(ValidateImage, QueryLevelsNotImage) {
4634 const std::string body = R"(
4635 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4636 %sampler = OpLoad %type_sampler %uniform_sampler
4637 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4638 %res1 = OpImageQueryLevels %u32 %sampler
4639 )";
4640
4641 CompileSuccessfully(GenerateKernelCode(body).c_str());
4642 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4643 EXPECT_THAT(getDiagnosticString(),
4644 HasSubstr("Expected Image to be of type OpTypeImage"));
4645 }
4646
TEST_F(ValidateImage,QueryLevelsSampledImageDirectly)4647 TEST_F(ValidateImage, QueryLevelsSampledImageDirectly) {
4648 const std::string body = R"(
4649 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4650 %sampler = OpLoad %type_sampler %uniform_sampler
4651 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4652 %res1 = OpImageQueryLevels %u32 %simg
4653 )";
4654
4655 CompileSuccessfully(GenerateShaderCode(body).c_str());
4656 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4657 EXPECT_THAT(getDiagnosticString(),
4658 HasSubstr("OpSampledImage instruction must not appear as operand "
4659 "for OpImageQueryLevels"));
4660 }
4661
TEST_F(ValidateImage,QueryLevelsWrongDim)4662 TEST_F(ValidateImage, QueryLevelsWrongDim) {
4663 const std::string body = R"(
4664 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4665 %res1 = OpImageQueryLevels %u32 %img
4666 )";
4667
4668 CompileSuccessfully(GenerateKernelCode(body).c_str());
4669 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4670 EXPECT_THAT(getDiagnosticString(),
4671 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4672 }
4673
TEST_F(ValidateImage,QuerySizeLevelsNonSampledUniversalSuccess)4674 TEST_F(ValidateImage, QuerySizeLevelsNonSampledUniversalSuccess) {
4675 const std::string body = R"(
4676 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4677 %res1 = OpImageQueryLevels %u32 %img
4678 )";
4679
4680 CompileSuccessfully(GenerateShaderCode(body).c_str());
4681 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4682 EXPECT_EQ(getDiagnosticString(), "");
4683 }
4684
TEST_F(ValidateImage,QuerySizeLevelsVulkanNonSampledError)4685 TEST_F(ValidateImage, QuerySizeLevelsVulkanNonSampledError) {
4686 // Create a whole shader module. Avoid Vulkan incompatibility with
4687 // SampledRrect images inserted by helper function GenerateShaderCode.
4688 const std::string body = R"(
4689 OpCapability Shader
4690 OpCapability ImageQuery
4691 OpMemoryModel Logical Simple
4692 OpEntryPoint Fragment %main "main"
4693 OpExecutionMode %main OriginUpperLeft
4694
4695 %f32 = OpTypeFloat 32
4696 %u32 = OpTypeInt 32 0
4697 %void = OpTypeVoid
4698 %voidfn = OpTypeFunction %void
4699
4700 ; Test with a storage image.
4701 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4702 %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
4703 %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
4704
4705 %main = OpFunction %void None %voidfn
4706 %entry = OpLabel
4707 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4708 %res1 = OpImageQueryLevels %u32 %img
4709 OpReturn
4710 OpFunctionEnd
4711 )";
4712
4713 CompileSuccessfully(body.c_str());
4714 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4715 EXPECT_THAT(getDiagnosticString(),
4716 AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
4717 EXPECT_THAT(
4718 getDiagnosticString(),
4719 HasSubstr("OpImageQueryLevels must only consume an \"Image\" operand "
4720 "whose type has its \"Sampled\" operand set to 1"));
4721 }
4722
TEST_F(ValidateImage,QuerySamplesSuccess)4723 TEST_F(ValidateImage, QuerySamplesSuccess) {
4724 const std::string body = R"(
4725 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4726 %res1 = OpImageQuerySamples %u32 %img
4727 )";
4728
4729 CompileSuccessfully(GenerateKernelCode(body).c_str());
4730 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4731 }
4732
TEST_F(ValidateImage,QuerySamplesNot2D)4733 TEST_F(ValidateImage, QuerySamplesNot2D) {
4734 const std::string body = R"(
4735 %img = OpLoad %type_image_f32_3d_0011 %uniform_image_f32_3d_0011
4736 %res1 = OpImageQuerySamples %u32 %img
4737 )";
4738
4739 CompileSuccessfully(GenerateKernelCode(body).c_str());
4740 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4741 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' must be 2D"));
4742 }
4743
TEST_F(ValidateImage,QuerySamplesNotMultisampled)4744 TEST_F(ValidateImage, QuerySamplesNotMultisampled) {
4745 const std::string body = R"(
4746 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4747 %res1 = OpImageQuerySamples %u32 %img
4748 )";
4749
4750 CompileSuccessfully(GenerateKernelCode(body).c_str());
4751 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4752 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 1"));
4753 }
4754
TEST_F(ValidateImage,QueryLodWrongExecutionModel)4755 TEST_F(ValidateImage, QueryLodWrongExecutionModel) {
4756 const std::string body = R"(
4757 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4758 %sampler = OpLoad %type_sampler %uniform_sampler
4759 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4760 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4761 )";
4762
4763 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4764 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4765 EXPECT_THAT(
4766 getDiagnosticString(),
4767 HasSubstr(
4768 "OpImageQueryLod requires Fragment or GLCompute execution model"));
4769 }
4770
TEST_F(ValidateImage,QueryLodWrongExecutionModelWithFunc)4771 TEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) {
4772 const std::string body = R"(
4773 %call_ret = OpFunctionCall %void %my_func
4774 OpReturn
4775 OpFunctionEnd
4776 %my_func = OpFunction %void None %func
4777 %my_func_entry = OpLabel
4778 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4779 %sampler = OpLoad %type_sampler %uniform_sampler
4780 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4781 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4782 )";
4783
4784 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4785 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4786 EXPECT_THAT(
4787 getDiagnosticString(),
4788 HasSubstr(
4789 "OpImageQueryLod requires Fragment or GLCompute execution model"));
4790 }
4791
TEST_F(ValidateImage,QueryLodComputeShaderDerivatives)4792 TEST_F(ValidateImage, QueryLodComputeShaderDerivatives) {
4793 const std::string body = R"(
4794 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4795 %sampler = OpLoad %type_sampler %uniform_sampler
4796 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4797 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4798 )";
4799
4800 const std::string extra = R"(
4801 OpCapability ComputeDerivativeGroupLinearNV
4802 OpExtension "SPV_NV_compute_shader_derivatives"
4803 )";
4804 const std::string mode = R"(
4805 OpExecutionMode %main LocalSize 8 8 1
4806 OpExecutionMode %main DerivativeGroupLinearNV
4807 )";
4808 CompileSuccessfully(
4809 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4810 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4811 }
4812
TEST_F(ValidateImage,QueryLodUniversalSuccess)4813 TEST_F(ValidateImage, QueryLodUniversalSuccess) {
4814 // Create a whole shader module. Avoid Vulkan incompatibility with
4815 // SampledRrect images inserted by helper function GenerateShaderCode.
4816 const std::string body = R"(
4817 OpCapability Shader
4818 OpCapability ImageQuery
4819 OpMemoryModel Logical Simple
4820 OpEntryPoint Fragment %main "main"
4821 OpExecutionMode %main OriginUpperLeft
4822
4823 OpDecorate %uniform_image_f32_2d_0000 DescriptorSet 0
4824 OpDecorate %uniform_image_f32_2d_0000 Binding 0
4825 OpDecorate %sampler DescriptorSet 0
4826 OpDecorate %sampler Binding 1
4827
4828 %f32 = OpTypeFloat 32
4829 %f32vec2 = OpTypeVector %f32 2
4830 %f32vec2_null = OpConstantNull %f32vec2
4831 %u32 = OpTypeInt 32 0
4832 %u32vec2 = OpTypeVector %u32 2
4833 %void = OpTypeVoid
4834 %voidfn = OpTypeFunction %void
4835
4836 ; Test with an image with sampled = 0
4837 %type_image_f32_2d_0000 = OpTypeImage %f32 2D 0 0 0 0 Rgba32f
4838 %ptr_image_f32_2d_0000 = OpTypePointer UniformConstant %type_image_f32_2d_0000
4839 %uniform_image_f32_2d_0000 = OpVariable %ptr_image_f32_2d_0000 UniformConstant
4840 %sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0000
4841
4842 %sampler_ty = OpTypeSampler
4843 %ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
4844 %sampler = OpVariable %ptr_sampler_ty UniformConstant
4845
4846
4847 %main = OpFunction %void None %voidfn
4848 %entry = OpLabel
4849 %img = OpLoad %type_image_f32_2d_0000 %uniform_image_f32_2d_0000
4850 %s = OpLoad %sampler_ty %sampler
4851 %simg = OpSampledImage %sampled_image_ty %img %s
4852 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
4853 OpReturn
4854 OpFunctionEnd
4855 )";
4856
4857 CompileSuccessfully(body.c_str());
4858 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4859 }
4860
TEST_F(ValidateImage,QueryLodVulkanNonSampledError)4861 TEST_F(ValidateImage, QueryLodVulkanNonSampledError) {
4862 // Create a whole shader module. Avoid Vulkan incompatibility with
4863 // SampledRrect images inserted by helper function GenerateShaderCode.
4864 const std::string body = R"(
4865 OpCapability Shader
4866 OpCapability ImageQuery
4867 OpMemoryModel Logical Simple
4868 OpEntryPoint Fragment %main "main"
4869 OpExecutionMode %main OriginUpperLeft
4870
4871 OpDecorate %sampled_image DescriptorSet 0
4872 OpDecorate %sampled_image Binding 0
4873
4874 %f32 = OpTypeFloat 32
4875 %f32vec2 = OpTypeVector %f32 2
4876 %f32vec2_null = OpConstantNull %f32vec2
4877 %u32 = OpTypeInt 32 0
4878 %u32vec2 = OpTypeVector %u32 2
4879 %void = OpTypeVoid
4880 %voidfn = OpTypeFunction %void
4881
4882 ; Test with an image with Sampled = 2
4883 ; In Vulkan it Sampled must be 1 or 2, checked in another part of the
4884 ; validation flow.
4885 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4886
4887 ; Expect to fail here.
4888 %sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0002
4889 %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
4890 %sampled_image = OpVariable %ptr_sampled_image_ty UniformConstant
4891
4892 %main = OpFunction %void None %voidfn
4893 %entry = OpLabel
4894 %simg = OpLoad %sampled_image_ty %sampled_image
4895 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
4896 OpReturn
4897 OpFunctionEnd
4898 )";
4899
4900 CompileSuccessfully(body.c_str());
4901 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4902 EXPECT_THAT(getDiagnosticString(),
4903 AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
4904 EXPECT_THAT(getDiagnosticString(),
4905 HasSubstr("Sampled image type requires an image type with "
4906 "\"Sampled\" operand set to 0 or 1"));
4907 }
4908
TEST_F(ValidateImage,QueryLodComputeShaderDerivativesMissingMode)4909 TEST_F(ValidateImage, QueryLodComputeShaderDerivativesMissingMode) {
4910 const std::string body = R"(
4911 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4912 %sampler = OpLoad %type_sampler %uniform_sampler
4913 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4914 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4915 )";
4916
4917 const std::string extra = R"(
4918 OpCapability ComputeDerivativeGroupLinearNV
4919 OpExtension "SPV_NV_compute_shader_derivatives"
4920 )";
4921 const std::string mode = R"(
4922 OpExecutionMode %main LocalSize 8 8 1
4923 )";
4924 CompileSuccessfully(
4925 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4926 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4927 EXPECT_THAT(getDiagnosticString(),
4928 HasSubstr("OpImageQueryLod requires DerivativeGroupQuadsNV or "
4929 "DerivativeGroupLinearNV execution mode for GLCompute "
4930 "execution model"));
4931 }
4932
TEST_F(ValidateImage,ImplicitLodWrongExecutionModel)4933 TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
4934 const std::string body = R"(
4935 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4936 %sampler = OpLoad %type_sampler %uniform_sampler
4937 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4938 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4939 )";
4940
4941 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4942 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4943 EXPECT_THAT(getDiagnosticString(),
4944 HasSubstr("ImplicitLod instructions require Fragment or "
4945 "GLCompute execution model"));
4946 }
4947
TEST_F(ValidateImage,ImplicitLodComputeShaderDerivatives)4948 TEST_F(ValidateImage, ImplicitLodComputeShaderDerivatives) {
4949 const std::string body = R"(
4950 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4951 %sampler = OpLoad %type_sampler %uniform_sampler
4952 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4953 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4954 )";
4955
4956 const std::string extra = R"(
4957 OpCapability ComputeDerivativeGroupLinearNV
4958 OpExtension "SPV_NV_compute_shader_derivatives"
4959 )";
4960 const std::string mode = R"(
4961 OpExecutionMode %main LocalSize 8 8 1
4962 OpExecutionMode %main DerivativeGroupLinearNV
4963 )";
4964 CompileSuccessfully(
4965 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4966 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4967 }
4968
TEST_F(ValidateImage,ImplicitLodComputeShaderDerivativesMissingMode)4969 TEST_F(ValidateImage, ImplicitLodComputeShaderDerivativesMissingMode) {
4970 const std::string body = R"(
4971 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4972 %sampler = OpLoad %type_sampler %uniform_sampler
4973 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4974 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4975 )";
4976
4977 const std::string extra = R"(
4978 OpCapability ComputeDerivativeGroupLinearNV
4979 OpExtension "SPV_NV_compute_shader_derivatives"
4980 )";
4981 const std::string mode = R"(
4982 OpExecutionMode %main LocalSize 8 8 1
4983 )";
4984 CompileSuccessfully(
4985 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4986 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4987 EXPECT_THAT(
4988 getDiagnosticString(),
4989 HasSubstr("ImplicitLod instructions require DerivativeGroupQuadsNV or "
4990 "DerivativeGroupLinearNV execution mode for GLCompute "
4991 "execution model"));
4992 }
4993
TEST_F(ValidateImage,ReadSubpassDataWrongExecutionModel)4994 TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
4995 const std::string body = R"(
4996 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
4997 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
4998 )";
4999
5000 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5001 CompileSuccessfully(GenerateShaderCode(body, extra, "Vertex").c_str());
5002 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5003 EXPECT_THAT(getDiagnosticString(),
5004 HasSubstr("Dim SubpassData requires Fragment execution model"));
5005 }
5006
TEST_F(ValidateImage,SparseSampleImplicitLodSuccess)5007 TEST_F(ValidateImage, SparseSampleImplicitLodSuccess) {
5008 const std::string body = R"(
5009 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5010 %sampler = OpLoad %type_sampler %uniform_sampler
5011 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5012 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh
5013 %res2 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Bias %f32_0_25
5014 %res4 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
5015 %res5 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
5016 %res6 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
5017 %res7 = OpImageSparseSampleImplicitLod %struct_u64_f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
5018 %res8 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
5019 )";
5020
5021 const std::string extra = R"(
5022 OpCapability VulkanMemoryModelKHR
5023 OpExtension "SPV_KHR_vulkan_memory_model"
5024 )";
5025 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5026 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5027 .c_str());
5028 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5029 }
5030
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotStruct)5031 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotStruct) {
5032 const std::string body = R"(
5033 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5034 %sampler = OpLoad %type_sampler %uniform_sampler
5035 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5036 %res1 = OpImageSparseSampleImplicitLod %f32 %simg %f32vec2_hh
5037 )";
5038
5039 CompileSuccessfully(GenerateShaderCode(body).c_str());
5040 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5041 EXPECT_THAT(getDiagnosticString(),
5042 HasSubstr("Expected Result Type to be OpTypeStruct"));
5043 }
5044
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotTwoMembers1)5045 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers1) {
5046 const std::string body = R"(
5047 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5048 %sampler = OpLoad %type_sampler %uniform_sampler
5049 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5050 %res1 = OpImageSparseSampleImplicitLod %struct_u32 %simg %f32vec2_hh
5051 )";
5052
5053 CompileSuccessfully(GenerateShaderCode(body).c_str());
5054 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5055 EXPECT_THAT(getDiagnosticString(),
5056 HasSubstr("Expected Result Type to be a struct containing an int "
5057 "scalar and a texel"));
5058 }
5059
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotTwoMembers2)5060 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers2) {
5061 const std::string body = R"(
5062 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5063 %sampler = OpLoad %type_sampler %uniform_sampler
5064 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5065 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4_u32 %simg %f32vec2_hh
5066 )";
5067
5068 CompileSuccessfully(GenerateShaderCode(body).c_str());
5069 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5070 EXPECT_THAT(getDiagnosticString(),
5071 HasSubstr("Expected Result Type to be a struct containing an "
5072 "int scalar and a texel"));
5073 }
5074
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeFirstMemberNotInt)5075 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeFirstMemberNotInt) {
5076 const std::string body = R"(
5077 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5078 %sampler = OpLoad %type_sampler %uniform_sampler
5079 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5080 %res1 = OpImageSparseSampleImplicitLod %struct_f32_f32vec4 %simg %f32vec2_hh
5081 )";
5082
5083 CompileSuccessfully(GenerateShaderCode(body).c_str());
5084 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5085 EXPECT_THAT(getDiagnosticString(),
5086 HasSubstr("Expected Result Type to be a struct containing an "
5087 "int scalar and a texel"));
5088 }
5089
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeTexelNotVector)5090 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeTexelNotVector) {
5091 const std::string body = R"(
5092 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5093 %sampler = OpLoad %type_sampler %uniform_sampler
5094 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5095 %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32 %simg %f32vec2_hh
5096 )";
5097
5098 CompileSuccessfully(GenerateShaderCode(body).c_str());
5099 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5100 EXPECT_THAT(getDiagnosticString(),
5101 HasSubstr("Expected Result Type's second member to be int or "
5102 "float vector type"));
5103 }
5104
TEST_F(ValidateImage,SparseSampleImplicitLodWrongNumComponentsTexel)5105 TEST_F(ValidateImage, SparseSampleImplicitLodWrongNumComponentsTexel) {
5106 const std::string body = R"(
5107 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5108 %sampler = OpLoad %type_sampler %uniform_sampler
5109 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5110 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec3 %simg %f32vec2_hh
5111 )";
5112
5113 CompileSuccessfully(GenerateShaderCode(body).c_str());
5114 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5115 EXPECT_THAT(getDiagnosticString(),
5116 HasSubstr("Expected Result Type's second member to have 4 "
5117 "components"));
5118 }
5119
TEST_F(ValidateImage,SparseSampleImplicitLodWrongComponentTypeTexel)5120 TEST_F(ValidateImage, SparseSampleImplicitLodWrongComponentTypeTexel) {
5121 const std::string body = R"(
5122 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5123 %sampler = OpLoad %type_sampler %uniform_sampler
5124 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5125 %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32vec4 %simg %f32vec2_hh
5126 )";
5127
5128 CompileSuccessfully(GenerateShaderCode(body).c_str());
5129 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5130 EXPECT_THAT(getDiagnosticString(),
5131 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5132 "Result Type's second member components"));
5133 }
5134
TEST_F(ValidateImage,SparseSampleDrefImplicitLodSuccess)5135 TEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) {
5136 const std::string body = R"(
5137 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
5138 %sampler = OpLoad %type_sampler %uniform_sampler
5139 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
5140 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
5141 %res2 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
5142 %res4 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
5143 %res5 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
5144 %res6 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
5145 %res7 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
5146 %res8 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
5147 )";
5148
5149 const std::string extra = R"(
5150 OpCapability VulkanMemoryModelKHR
5151 OpExtension "SPV_KHR_vulkan_memory_model"
5152 )";
5153 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5154 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5155 .c_str());
5156 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5157 }
5158
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotStruct)5159 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotStruct) {
5160 const std::string body = R"(
5161 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5162 %sampler = OpLoad %type_sampler %uniform_sampler
5163 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5164 %res1 = OpImageSparseSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1
5165 )";
5166
5167 CompileSuccessfully(GenerateShaderCode(body).c_str());
5168 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5169 EXPECT_THAT(getDiagnosticString(),
5170 HasSubstr("Expected Result Type to be OpTypeStruct"));
5171 }
5172
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotTwoMembers1)5173 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers1) {
5174 const std::string body = R"(
5175 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5176 %sampler = OpLoad %type_sampler %uniform_sampler
5177 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5178 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32 %simg %f32vec2_hh %f32_1
5179 )";
5180
5181 CompileSuccessfully(GenerateShaderCode(body).c_str());
5182 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5183 EXPECT_THAT(
5184 getDiagnosticString(),
5185 HasSubstr("Expected Result Type to be a struct containing an int scalar "
5186 "and a texel"));
5187 }
5188
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotTwoMembers2)5189 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers2) {
5190 const std::string body = R"(
5191 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5192 %sampler = OpLoad %type_sampler %uniform_sampler
5193 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5194 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_f32_u32 %simg %f32vec2_hh %f32_1
5195 )";
5196
5197 CompileSuccessfully(GenerateShaderCode(body).c_str());
5198 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5199 EXPECT_THAT(
5200 getDiagnosticString(),
5201 HasSubstr("Expected Result Type to be a struct containing an int scalar "
5202 "and a texel"));
5203 }
5204
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt)5205 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt) {
5206 const std::string body = R"(
5207 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5208 %sampler = OpLoad %type_sampler %uniform_sampler
5209 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5210 %res1 = OpImageSparseSampleDrefImplicitLod %struct_f32_f32 %simg %f32vec2_hh %f32_1
5211 )";
5212
5213 CompileSuccessfully(GenerateShaderCode(body).c_str());
5214 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5215 EXPECT_THAT(
5216 getDiagnosticString(),
5217 HasSubstr("Expected Result Type to be a struct containing an int scalar "
5218 "and a texel"));
5219 }
5220
TEST_F(ValidateImage,SparseSampleDrefImplicitLodDifferentSampledType)5221 TEST_F(ValidateImage, SparseSampleDrefImplicitLodDifferentSampledType) {
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 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
5227 )";
5228
5229 CompileSuccessfully(GenerateShaderCode(body).c_str());
5230 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5231 EXPECT_THAT(getDiagnosticString(),
5232 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5233 "Result Type's second member"));
5234 }
5235
TEST_F(ValidateImage,SparseFetchSuccess)5236 TEST_F(ValidateImage, SparseFetchSuccess) {
5237 const std::string body = R"(
5238 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
5239 %res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
5240 %res2 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
5241 )";
5242
5243 const std::string extra = R"(
5244 OpCapability VulkanMemoryModelKHR
5245 OpExtension "SPV_KHR_vulkan_memory_model"
5246 )";
5247 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5248 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5249 .c_str());
5250 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5251 }
5252
TEST_F(ValidateImage,SparseFetchResultTypeNotStruct)5253 TEST_F(ValidateImage, SparseFetchResultTypeNotStruct) {
5254 const std::string body = R"(
5255 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5256 %res1 = OpImageSparseFetch %f32 %img %u32vec2_01
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 to be OpTypeStruct"));
5263 }
5264
TEST_F(ValidateImage,SparseFetchResultTypeNotTwoMembers1)5265 TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers1) {
5266 const std::string body = R"(
5267 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5268 %res1 = OpImageSparseFetch %struct_u32 %img %u32vec2_01
5269 )";
5270
5271 CompileSuccessfully(GenerateShaderCode(body).c_str());
5272 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5273 EXPECT_THAT(getDiagnosticString(),
5274 HasSubstr("Expected Result Type to be a struct containing an "
5275 "int scalar and a texel"));
5276 }
5277
TEST_F(ValidateImage,SparseFetchResultTypeNotTwoMembers2)5278 TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers2) {
5279 const std::string body = R"(
5280 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5281 %res1 = OpImageSparseFetch %struct_u32_f32vec4_u32 %img %u32vec2_01
5282 )";
5283
5284 CompileSuccessfully(GenerateShaderCode(body).c_str());
5285 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5286 EXPECT_THAT(getDiagnosticString(),
5287 HasSubstr("Expected Result Type to be a struct containing an "
5288 "int scalar and a texel"));
5289 }
5290
TEST_F(ValidateImage,SparseFetchResultTypeFirstMemberNotInt)5291 TEST_F(ValidateImage, SparseFetchResultTypeFirstMemberNotInt) {
5292 const std::string body = R"(
5293 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5294 %res1 = OpImageSparseFetch %struct_f32_f32vec4 %img %u32vec2_01
5295 )";
5296
5297 CompileSuccessfully(GenerateShaderCode(body).c_str());
5298 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5299 EXPECT_THAT(getDiagnosticString(),
5300 HasSubstr("Expected Result Type to be a struct containing an "
5301 "int scalar and a texel"));
5302 }
5303
TEST_F(ValidateImage,SparseFetchResultTypeTexelNotVector)5304 TEST_F(ValidateImage, SparseFetchResultTypeTexelNotVector) {
5305 const std::string body = R"(
5306 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5307 %res1 = OpImageSparseFetch %struct_u32_u32 %img %u32vec2_01
5308 )";
5309
5310 CompileSuccessfully(GenerateShaderCode(body).c_str());
5311 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5312 EXPECT_THAT(getDiagnosticString(),
5313 HasSubstr("Expected Result Type's second member to be int or "
5314 "float vector type"));
5315 }
5316
TEST_F(ValidateImage,SparseFetchWrongNumComponentsTexel)5317 TEST_F(ValidateImage, SparseFetchWrongNumComponentsTexel) {
5318 const std::string body = R"(
5319 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5320 %res1 = OpImageSparseFetch %struct_u32_f32vec3 %img %u32vec2_01
5321 )";
5322
5323 CompileSuccessfully(GenerateShaderCode(body).c_str());
5324 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5325 EXPECT_THAT(getDiagnosticString(),
5326 HasSubstr("Expected Result Type's second member to have 4 "
5327 "components"));
5328 }
5329
TEST_F(ValidateImage,SparseFetchWrongComponentTypeTexel)5330 TEST_F(ValidateImage, SparseFetchWrongComponentTypeTexel) {
5331 const std::string body = R"(
5332 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5333 %res1 = OpImageSparseFetch %struct_u32_u32vec4 %img %u32vec2_01
5334 )";
5335
5336 CompileSuccessfully(GenerateShaderCode(body).c_str());
5337 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5338 EXPECT_THAT(getDiagnosticString(),
5339 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5340 "Result Type's second member components"));
5341 }
5342
TEST_F(ValidateImage,SparseReadSuccess)5343 TEST_F(ValidateImage, SparseReadSuccess) {
5344 const std::string body = R"(
5345 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5346 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
5347 )";
5348
5349 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5350 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5351 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5352 }
5353
TEST_F(ValidateImage,SparseReadResultTypeNotStruct)5354 TEST_F(ValidateImage, SparseReadResultTypeNotStruct) {
5355 const std::string body = R"(
5356 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5357 %res1 = OpImageSparseRead %f32 %img %u32vec2_01
5358 )";
5359
5360 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5361 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5362 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5363 EXPECT_THAT(getDiagnosticString(),
5364 HasSubstr("Expected Result Type to be OpTypeStruct"));
5365 }
5366
TEST_F(ValidateImage,SparseReadResultTypeNotTwoMembers1)5367 TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers1) {
5368 const std::string body = R"(
5369 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5370 %res1 = OpImageSparseRead %struct_u32 %img %u32vec2_01
5371 )";
5372
5373 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5374 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5375 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5376 EXPECT_THAT(getDiagnosticString(),
5377 HasSubstr("Expected Result Type to be a struct containing an "
5378 "int scalar and a texel"));
5379 }
5380
TEST_F(ValidateImage,SparseReadResultTypeNotTwoMembers2)5381 TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers2) {
5382 const std::string body = R"(
5383 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5384 %res1 = OpImageSparseRead %struct_u32_f32vec4_u32 %img %u32vec2_01
5385 )";
5386
5387 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5388 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5389 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5390 EXPECT_THAT(getDiagnosticString(),
5391 HasSubstr("Expected Result Type to be a struct containing an "
5392 "int scalar and a texel"));
5393 }
5394
TEST_F(ValidateImage,SparseReadResultTypeFirstMemberNotInt)5395 TEST_F(ValidateImage, SparseReadResultTypeFirstMemberNotInt) {
5396 const std::string body = R"(
5397 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5398 %res1 = OpImageSparseRead %struct_f32_f32vec4 %img %u32vec2_01
5399 )";
5400
5401 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5402 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5403 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5404 EXPECT_THAT(getDiagnosticString(),
5405 HasSubstr("Expected Result Type to be a struct containing an "
5406 "int scalar and a texel"));
5407 }
5408
TEST_F(ValidateImage,SparseReadResultTypeTexelWrongType)5409 TEST_F(ValidateImage, SparseReadResultTypeTexelWrongType) {
5410 const std::string body = R"(
5411 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5412 %res1 = OpImageSparseRead %struct_u32_u32arr4 %img %u32vec2_01
5413 )";
5414
5415 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5416 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5417 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5418 EXPECT_THAT(getDiagnosticString(),
5419 HasSubstr("Expected Result Type's second member to be int or "
5420 "float scalar or vector type"));
5421 }
5422
TEST_F(ValidateImage,SparseReadWrongComponentTypeTexel)5423 TEST_F(ValidateImage, SparseReadWrongComponentTypeTexel) {
5424 const std::string body = R"(
5425 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5426 %res1 = OpImageSparseRead %struct_u32_u32vec4 %img %u32vec2_01
5427 )";
5428
5429 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5430 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5431 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5432 EXPECT_THAT(getDiagnosticString(),
5433 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5434 "Result Type's second member components"));
5435 }
5436
TEST_F(ValidateImage,SparseReadSubpassDataNotAllowed)5437 TEST_F(ValidateImage, SparseReadSubpassDataNotAllowed) {
5438 const std::string body = R"(
5439 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
5440 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
5441 )";
5442
5443 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5444 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment").c_str());
5445 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5446 EXPECT_THAT(
5447 getDiagnosticString(),
5448 HasSubstr("Image Dim SubpassData cannot be used with ImageSparseRead"));
5449 }
5450
TEST_F(ValidateImage,SparseGatherSuccess)5451 TEST_F(ValidateImage, SparseGatherSuccess) {
5452 const std::string body = R"(
5453 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5454 %sampler = OpLoad %type_sampler %uniform_sampler
5455 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5456 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1
5457 %res2 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
5458 )";
5459
5460 const std::string extra = R"(
5461 OpCapability VulkanMemoryModelKHR
5462 OpExtension "SPV_KHR_vulkan_memory_model"
5463 )";
5464 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5465 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5466 .c_str());
5467 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5468 }
5469
TEST_F(ValidateImage,SparseGatherResultTypeNotStruct)5470 TEST_F(ValidateImage, SparseGatherResultTypeNotStruct) {
5471 const std::string body = R"(
5472 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5473 %sampler = OpLoad %type_sampler %uniform_sampler
5474 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5475 %res1 = OpImageSparseGather %f32 %simg %f32vec2_hh %u32_1
5476 )";
5477
5478 CompileSuccessfully(GenerateShaderCode(body).c_str());
5479 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5480 EXPECT_THAT(getDiagnosticString(),
5481 HasSubstr("Expected Result Type to be OpTypeStruct"));
5482 }
5483
TEST_F(ValidateImage,SparseGatherResultTypeNotTwoMembers1)5484 TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers1) {
5485 const std::string body = R"(
5486 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5487 %sampler = OpLoad %type_sampler %uniform_sampler
5488 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5489 %res1 = OpImageSparseGather %struct_u32 %simg %f32vec2_hh %u32_1
5490 )";
5491
5492 CompileSuccessfully(GenerateShaderCode(body).c_str());
5493 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5494 EXPECT_THAT(getDiagnosticString(),
5495 HasSubstr("Expected Result Type to be a struct containing an int "
5496 "scalar and a texel"));
5497 }
5498
TEST_F(ValidateImage,SparseGatherResultTypeNotTwoMembers2)5499 TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers2) {
5500 const std::string body = R"(
5501 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5502 %sampler = OpLoad %type_sampler %uniform_sampler
5503 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5504 %res1 = OpImageSparseGather %struct_u32_f32vec4_u32 %simg %f32vec2_hh %u32_1
5505 )";
5506
5507 CompileSuccessfully(GenerateShaderCode(body).c_str());
5508 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5509 EXPECT_THAT(getDiagnosticString(),
5510 HasSubstr("Expected Result Type to be a struct containing an int "
5511 "scalar and a texel"));
5512 }
5513
TEST_F(ValidateImage,SparseGatherResultTypeFirstMemberNotInt)5514 TEST_F(ValidateImage, SparseGatherResultTypeFirstMemberNotInt) {
5515 const std::string body = R"(
5516 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5517 %sampler = OpLoad %type_sampler %uniform_sampler
5518 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5519 %res1 = OpImageSparseGather %struct_f32_f32vec4 %simg %f32vec2_hh %u32_1
5520 )";
5521
5522 CompileSuccessfully(GenerateShaderCode(body).c_str());
5523 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5524 EXPECT_THAT(getDiagnosticString(),
5525 HasSubstr("Expected Result Type to be a struct containing an "
5526 "int scalar and a texel"));
5527 }
5528
TEST_F(ValidateImage,SparseGatherResultTypeTexelNotVector)5529 TEST_F(ValidateImage, SparseGatherResultTypeTexelNotVector) {
5530 const std::string body = R"(
5531 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5532 %sampler = OpLoad %type_sampler %uniform_sampler
5533 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5534 %res1 = OpImageSparseGather %struct_u32_u32 %simg %f32vec2_hh %u32_1
5535 )";
5536
5537 CompileSuccessfully(GenerateShaderCode(body).c_str());
5538 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5539 EXPECT_THAT(getDiagnosticString(),
5540 HasSubstr("Expected Result Type's second member to be int or "
5541 "float vector type"));
5542 }
5543
TEST_F(ValidateImage,SparseGatherWrongNumComponentsTexel)5544 TEST_F(ValidateImage, SparseGatherWrongNumComponentsTexel) {
5545 const std::string body = R"(
5546 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5547 %sampler = OpLoad %type_sampler %uniform_sampler
5548 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5549 %res1 = OpImageSparseGather %struct_u32_f32vec3 %simg %f32vec2_hh %u32_1
5550 )";
5551
5552 CompileSuccessfully(GenerateShaderCode(body).c_str());
5553 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5554 EXPECT_THAT(getDiagnosticString(),
5555 HasSubstr("Expected Result Type's second member to have 4 "
5556 "components"));
5557 }
5558
TEST_F(ValidateImage,SparseGatherWrongComponentTypeTexel)5559 TEST_F(ValidateImage, SparseGatherWrongComponentTypeTexel) {
5560 const std::string body = R"(
5561 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5562 %sampler = OpLoad %type_sampler %uniform_sampler
5563 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5564 %res1 = OpImageSparseGather %struct_u32_u32vec4 %simg %f32vec2_hh %u32_1
5565 )";
5566
5567 CompileSuccessfully(GenerateShaderCode(body).c_str());
5568 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5569 EXPECT_THAT(getDiagnosticString(),
5570 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5571 "Result Type's second member components"));
5572 }
5573
TEST_F(ValidateImage,SparseTexelsResidentSuccess)5574 TEST_F(ValidateImage, SparseTexelsResidentSuccess) {
5575 const std::string body = R"(
5576 %res1 = OpImageSparseTexelsResident %bool %u32_1
5577 )";
5578
5579 CompileSuccessfully(GenerateShaderCode(body).c_str());
5580 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5581 }
5582
TEST_F(ValidateImage,SparseTexelsResidentResultTypeNotBool)5583 TEST_F(ValidateImage, SparseTexelsResidentResultTypeNotBool) {
5584 const std::string body = R"(
5585 %res1 = OpImageSparseTexelsResident %u32 %u32_1
5586 )";
5587
5588 CompileSuccessfully(GenerateShaderCode(body).c_str());
5589 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5590 EXPECT_THAT(getDiagnosticString(),
5591 HasSubstr("Expected Result Type to be bool scalar type"));
5592 }
5593
TEST_F(ValidateImage,MakeTexelVisibleKHRSuccessImageRead)5594 TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageRead) {
5595 const std::string body = R"(
5596 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5597 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
5598 )";
5599
5600 const std::string extra = R"(
5601 OpCapability StorageImageReadWithoutFormat
5602 OpCapability VulkanMemoryModelKHR
5603 OpExtension "SPV_KHR_vulkan_memory_model"
5604 )";
5605 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5606 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5607 .c_str());
5608 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5609 }
5610
TEST_F(ValidateImage,MakeTexelVisibleKHRSuccessImageSparseRead)5611 TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageSparseRead) {
5612 const std::string body = R"(
5613 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5614 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
5615 )";
5616
5617 const std::string extra = R"(
5618 OpCapability StorageImageReadWithoutFormat
5619 OpCapability VulkanMemoryModelKHR
5620 OpExtension "SPV_KHR_vulkan_memory_model"
5621 )";
5622 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5623 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5624 .c_str());
5625 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5626 }
5627
TEST_F(ValidateImage,MakeTexelVisibleKHRFailureOpcode)5628 TEST_F(ValidateImage, MakeTexelVisibleKHRFailureOpcode) {
5629 const std::string body = R"(
5630 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5631 %sampler = OpLoad %type_sampler %uniform_sampler
5632 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5633 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5634 )";
5635
5636 const std::string extra = R"(
5637 OpCapability StorageImageReadWithoutFormat
5638 OpCapability VulkanMemoryModelKHR
5639 OpExtension "SPV_KHR_vulkan_memory_model"
5640 )";
5641 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5642 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5643 .c_str());
5644 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5645 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5646 EXPECT_THAT(
5647 getDiagnosticString(),
5648 HasSubstr("Image Operand MakeTexelVisibleKHR can only be used with "
5649 "OpImageRead or OpImageSparseRead: OpImageSampleImplicitLod"));
5650 }
5651
TEST_F(ValidateImage,MakeTexelVisibleKHRFailureMissingNonPrivate)5652 TEST_F(ValidateImage, MakeTexelVisibleKHRFailureMissingNonPrivate) {
5653 const std::string body = R"(
5654 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5655 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR %u32_1
5656 )";
5657
5658 const std::string extra = R"(
5659 OpCapability StorageImageReadWithoutFormat
5660 OpCapability VulkanMemoryModelKHR
5661 OpExtension "SPV_KHR_vulkan_memory_model"
5662 )";
5663 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5664 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5665 .c_str());
5666 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5667 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5668 EXPECT_THAT(getDiagnosticString(),
5669 HasSubstr("Image Operand MakeTexelVisibleKHR requires "
5670 "NonPrivateTexelKHR is also specified: OpImageRead"));
5671 }
5672
TEST_F(ValidateImage,MakeTexelAvailableKHRSuccessImageWrite)5673 TEST_F(ValidateImage, MakeTexelAvailableKHRSuccessImageWrite) {
5674 const std::string body = R"(
5675 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5676 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2
5677 )";
5678
5679 const std::string extra = R"(
5680 OpCapability StorageImageWriteWithoutFormat
5681 OpCapability VulkanMemoryModelKHR
5682 OpExtension "SPV_KHR_vulkan_memory_model"
5683 )";
5684 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5685 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5686 .c_str());
5687 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5688 }
5689
TEST_F(ValidateImage,MakeTexelAvailableKHRFailureOpcode)5690 TEST_F(ValidateImage, MakeTexelAvailableKHRFailureOpcode) {
5691 const std::string body = R"(
5692 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5693 %sampler = OpLoad %type_sampler %uniform_sampler
5694 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5695 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5696 )";
5697
5698 const std::string extra = R"(
5699 OpCapability StorageImageReadWithoutFormat
5700 OpCapability VulkanMemoryModelKHR
5701 OpExtension "SPV_KHR_vulkan_memory_model"
5702 )";
5703 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5704 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5705 .c_str());
5706 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5707 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5708 EXPECT_THAT(getDiagnosticString(),
5709 HasSubstr("Image Operand MakeTexelAvailableKHR can only be used "
5710 "with OpImageWrite: OpImageSampleImplicitLod"));
5711 }
5712
TEST_F(ValidateImage,MakeTexelAvailableKHRFailureMissingNonPrivate)5713 TEST_F(ValidateImage, MakeTexelAvailableKHRFailureMissingNonPrivate) {
5714 const std::string body = R"(
5715 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5716 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1
5717 )";
5718
5719 const std::string extra = R"(
5720 OpCapability StorageImageWriteWithoutFormat
5721 OpCapability VulkanMemoryModelKHR
5722 OpExtension "SPV_KHR_vulkan_memory_model"
5723 )";
5724 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5725 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5726 .c_str());
5727 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5728 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5729 EXPECT_THAT(getDiagnosticString(),
5730 HasSubstr("Image Operand MakeTexelAvailableKHR requires "
5731 "NonPrivateTexelKHR is also specified: OpImageWrite"));
5732 }
5733
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageWriteBad)5734 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteBad) {
5735 const std::string body = R"(
5736 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5737 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5738 )";
5739
5740 const std::string extra = R"(
5741 OpCapability StorageImageWriteWithoutFormat
5742 OpCapability VulkanMemoryModelKHR
5743 OpExtension "SPV_KHR_vulkan_memory_model"
5744 )";
5745 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5746 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5747 .c_str());
5748 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5749 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5750 EXPECT_THAT(
5751 getDiagnosticString(),
5752 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
5753 "VulkanMemoryModelDeviceScopeKHR capability"));
5754 }
5755
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageWriteGood)5756 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteGood) {
5757 const std::string body = R"(
5758 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5759 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5760 )";
5761
5762 const std::string extra = R"(
5763 OpCapability StorageImageWriteWithoutFormat
5764 OpCapability VulkanMemoryModelKHR
5765 OpCapability VulkanMemoryModelDeviceScopeKHR
5766 OpExtension "SPV_KHR_vulkan_memory_model"
5767 )";
5768 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5769 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5770 .c_str());
5771 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5772 }
5773
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageReadBad)5774 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadBad) {
5775 const std::string body = R"(
5776 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5777 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5778 )";
5779
5780 const std::string extra = R"(
5781 OpCapability StorageImageReadWithoutFormat
5782 OpCapability VulkanMemoryModelKHR
5783 OpExtension "SPV_KHR_vulkan_memory_model"
5784 )";
5785 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5786 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5787 .c_str());
5788 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5789 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5790 EXPECT_THAT(
5791 getDiagnosticString(),
5792 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
5793 "VulkanMemoryModelDeviceScopeKHR capability"));
5794 }
5795
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageReadGood)5796 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadGood) {
5797 const std::string body = R"(
5798 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5799 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5800 )";
5801
5802 const std::string extra = R"(
5803 OpCapability StorageImageReadWithoutFormat
5804 OpCapability VulkanMemoryModelKHR
5805 OpCapability VulkanMemoryModelDeviceScopeKHR
5806 OpExtension "SPV_KHR_vulkan_memory_model"
5807 )";
5808 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5809 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5810 .c_str());
5811 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5812 }
5813
5814 // This example used to cause a seg fault on OpReturnValue, verifying it doesn't
5815 // anymore.
TEST_F(ValidateImage,Issue2463NoSegFault)5816 TEST_F(ValidateImage, Issue2463NoSegFault) {
5817 const std::string spirv = R"(
5818 OpCapability Linkage
5819 OpCapability Shader
5820 %1 = OpExtInstImport "GLSL.std.450"
5821 OpMemoryModel Logical GLSL450
5822 %void = OpTypeVoid
5823 %6 = OpTypeFunction %void
5824 %float = OpTypeFloat 32
5825 %8 = OpTypeImage %float 3D 0 0 0 1 Unknown
5826 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
5827 %10 = OpTypeSampler
5828 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
5829 %12 = OpTypeSampledImage %8
5830 %13 = OpTypeFunction %12 %_ptr_UniformConstant_8 %_ptr_UniformConstant_10
5831 %23 = OpFunction %12 None %13
5832 %24 = OpFunctionParameter %_ptr_UniformConstant_8
5833 %25 = OpFunctionParameter %_ptr_UniformConstant_10
5834 %26 = OpLabel
5835 %27 = OpLoad %8 %24
5836 %28 = OpLoad %10 %25
5837 %29 = OpSampledImage %12 %27 %28
5838 OpReturnValue %29
5839 OpFunctionEnd
5840 )";
5841
5842 CompileSuccessfully(spirv);
5843 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5844 EXPECT_THAT(getDiagnosticString(),
5845 HasSubstr("OpSampledImage instruction must not appear as operand "
5846 "for OpReturnValue"));
5847 }
5848
TEST_F(ValidateImage,SignExtendV13Bad)5849 TEST_F(ValidateImage, SignExtendV13Bad) {
5850 const std::string body = R"(
5851 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5852 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
5853 )";
5854
5855 CompileSuccessfully(
5856 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3));
5857 ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions());
5858 EXPECT_THAT(
5859 getDiagnosticString(),
5860 HasSubstr("SignExtend(4096) requires SPIR-V version 1.4 or later"));
5861 }
5862
TEST_F(ValidateImage,ZeroExtendV13Bad)5863 TEST_F(ValidateImage, ZeroExtendV13Bad) {
5864 const std::string body = R"(
5865 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5866 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
5867 )";
5868
5869 CompileSuccessfully(
5870 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3));
5871 ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions());
5872 EXPECT_THAT(
5873 getDiagnosticString(),
5874 HasSubstr("ZeroExtend(8192) requires SPIR-V version 1.4 or later"));
5875 }
5876
TEST_F(ValidateImage,SignExtendScalarUIntTexelV14Good)5877 TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) {
5878 // Unsigned int sampled type
5879 const std::string body = R"(
5880 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5881 %res1 = OpImageRead %u32 %img %u32vec2_01 SignExtend
5882 )";
5883 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5884
5885 CompileSuccessfully(
5886 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5887 SPV_ENV_UNIVERSAL_1_4);
5888 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5889 EXPECT_THAT(getDiagnosticString(), Eq(""));
5890 }
5891
TEST_F(ValidateImage,SignExtendScalarSIntTexelV14Good)5892 TEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) {
5893 // Signed int sampled type
5894 const std::string body = R"(
5895 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5896 %res1 = OpImageRead %s32 %img %u32vec2_01 SignExtend
5897 )";
5898 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5899
5900 CompileSuccessfully(
5901 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5902 SPV_ENV_UNIVERSAL_1_4);
5903 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5904 EXPECT_THAT(getDiagnosticString(), Eq(""));
5905 }
5906
TEST_F(ValidateImage,SignExtendScalarVectorUIntTexelV14Good)5907 TEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) {
5908 const std::string body = R"(
5909 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5910 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
5911 )";
5912 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5913
5914 CompileSuccessfully(
5915 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5916 SPV_ENV_UNIVERSAL_1_4);
5917 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5918 EXPECT_THAT(getDiagnosticString(), Eq(""));
5919 }
5920
TEST_F(ValidateImage,SignExtendVectorSIntTexelV14Good)5921 TEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) {
5922 const std::string body = R"(
5923 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5924 %res1 = OpImageRead %s32vec4 %img %u32vec2_01 SignExtend
5925 )";
5926 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5927
5928 CompileSuccessfully(
5929 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5930 SPV_ENV_UNIVERSAL_1_4);
5931 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5932 EXPECT_THAT(getDiagnosticString(), Eq(""));
5933 }
5934
5935 // No negative tests for SignExtend since we don't truly know the
5936 // texel format.
5937
TEST_F(ValidateImage,ZeroExtendScalarUIntTexelV14Good)5938 TEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) {
5939 // Unsigned int sampled type
5940 const std::string body = R"(
5941 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5942 %res1 = OpImageRead %u32 %img %u32vec2_01 ZeroExtend
5943 )";
5944 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5945
5946 CompileSuccessfully(
5947 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5948 SPV_ENV_UNIVERSAL_1_4);
5949 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5950 EXPECT_THAT(getDiagnosticString(), Eq(""));
5951 }
5952
TEST_F(ValidateImage,ZeroExtendScalarSIntTexelV14Good)5953 TEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) {
5954 // Zeroed int sampled type
5955 const std::string body = R"(
5956 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5957 %res1 = OpImageRead %s32 %img %u32vec2_01 ZeroExtend
5958 )";
5959 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5960
5961 CompileSuccessfully(
5962 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5963 SPV_ENV_UNIVERSAL_1_4);
5964 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5965 EXPECT_THAT(getDiagnosticString(), Eq(""));
5966 }
5967
TEST_F(ValidateImage,ZeroExtendScalarVectorUIntTexelV14Good)5968 TEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) {
5969 const std::string body = R"(
5970 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5971 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
5972 )";
5973 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5974
5975 CompileSuccessfully(
5976 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5977 SPV_ENV_UNIVERSAL_1_4);
5978 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5979 EXPECT_THAT(getDiagnosticString(), Eq(""));
5980 }
5981
TEST_F(ValidateImage,ZeroExtendVectorSIntTexelV14Good)5982 TEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) {
5983 const std::string body = R"(
5984 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5985 %res1 = OpImageRead %s32vec4 %img %u32vec2_01 ZeroExtend
5986 )";
5987 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5988
5989 CompileSuccessfully(
5990 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5991 SPV_ENV_UNIVERSAL_1_4);
5992 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5993 EXPECT_THAT(getDiagnosticString(), Eq(""));
5994 }
5995
TEST_F(ValidateImage,ReadLodAMDSuccess1)5996 TEST_F(ValidateImage, ReadLodAMDSuccess1) {
5997 const std::string body = R"(
5998 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5999 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 Lod %u32_0
6000 )";
6001
6002 const std::string extra =
6003 "\nOpCapability StorageImageReadWithoutFormat\n"
6004 "OpCapability ImageReadWriteLodAMD\n"
6005 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6006 CompileSuccessfully(
6007 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6008 SPV_ENV_UNIVERSAL_1_1);
6009 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6010 }
6011
TEST_F(ValidateImage,ReadLodAMDSuccess2)6012 TEST_F(ValidateImage, ReadLodAMDSuccess2) {
6013 const std::string body = R"(
6014 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
6015 %res1 = OpImageRead %f32vec4 %img %u32vec2_01 Lod %u32_0
6016 )";
6017
6018 const std::string extra =
6019 "\nOpCapability Image1D\n"
6020 "OpCapability ImageReadWriteLodAMD\n"
6021 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6022 CompileSuccessfully(
6023 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6024 SPV_ENV_UNIVERSAL_1_1);
6025 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6026 }
6027
TEST_F(ValidateImage,ReadLodAMDSuccess3)6028 TEST_F(ValidateImage, ReadLodAMDSuccess3) {
6029 const std::string body = R"(
6030 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6031 %res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
6032 )";
6033
6034 const std::string extra =
6035 "\nOpCapability ImageCubeArray\n"
6036 "OpCapability ImageReadWriteLodAMD\n"
6037 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6038 CompileSuccessfully(
6039 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6040 SPV_ENV_UNIVERSAL_1_1);
6041 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6042 }
6043
TEST_F(ValidateImage,ReadLodAMDNeedCapability)6044 TEST_F(ValidateImage, ReadLodAMDNeedCapability) {
6045 const std::string body = R"(
6046 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6047 %res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
6048 )";
6049
6050 const std::string extra = "\nOpCapability ImageCubeArray\n";
6051 CompileSuccessfully(
6052 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6053 SPV_ENV_UNIVERSAL_1_1);
6054 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
6055 ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6056 EXPECT_THAT(getDiagnosticString(),
6057 HasSubstr("Image Operand Lod can only be used with ExplicitLod "
6058 "opcodes and OpImageFetch"));
6059 }
6060
TEST_F(ValidateImage,WriteLodAMDSuccess1)6061 TEST_F(ValidateImage, WriteLodAMDSuccess1) {
6062 const std::string body = R"(
6063 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
6064 OpImageWrite %img %u32vec2_01 %u32vec4_0123 Lod %u32_0
6065 )";
6066
6067 const std::string extra =
6068 "\nOpCapability StorageImageWriteWithoutFormat\n"
6069 "OpCapability ImageReadWriteLodAMD\n"
6070 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6071 CompileSuccessfully(
6072 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6073 SPV_ENV_UNIVERSAL_1_1);
6074 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6075 }
6076
TEST_F(ValidateImage,WriteLodAMDSuccess2)6077 TEST_F(ValidateImage, WriteLodAMDSuccess2) {
6078 const std::string body = R"(
6079 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
6080 OpImageWrite %img %u32_1 %f32vec4_0000 Lod %u32_0
6081 )";
6082
6083 const std::string extra =
6084 "\nOpCapability Image1D\n"
6085 "OpCapability ImageReadWriteLodAMD\n"
6086 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6087 CompileSuccessfully(
6088 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6089 SPV_ENV_UNIVERSAL_1_1);
6090 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6091 }
6092
TEST_F(ValidateImage,WriteLodAMDSuccess3)6093 TEST_F(ValidateImage, WriteLodAMDSuccess3) {
6094 const std::string body = R"(
6095 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6096 OpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
6097 )";
6098
6099 const std::string extra =
6100 "\nOpCapability ImageCubeArray\n"
6101 "OpCapability ImageReadWriteLodAMD\n"
6102 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6103 CompileSuccessfully(
6104 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6105 SPV_ENV_UNIVERSAL_1_1);
6106 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6107 }
6108
TEST_F(ValidateImage,WriteLodAMDNeedCapability)6109 TEST_F(ValidateImage, WriteLodAMDNeedCapability) {
6110 const std::string body = R"(
6111 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6112 OpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
6113 )";
6114
6115 const std::string extra = "\nOpCapability ImageCubeArray\n";
6116 CompileSuccessfully(
6117 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6118 SPV_ENV_UNIVERSAL_1_1);
6119 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
6120 ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6121 EXPECT_THAT(getDiagnosticString(),
6122 HasSubstr("Image Operand Lod can only be used with ExplicitLod "
6123 "opcodes and OpImageFetch"));
6124 }
6125
TEST_F(ValidateImage,SparseReadLodAMDSuccess)6126 TEST_F(ValidateImage, SparseReadLodAMDSuccess) {
6127 const std::string body = R"(
6128 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
6129 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
6130 )";
6131
6132 const std::string extra =
6133 "\nOpCapability StorageImageReadWithoutFormat\n"
6134 "OpCapability ImageReadWriteLodAMD\n"
6135 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6136 CompileSuccessfully(
6137 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6138 SPV_ENV_UNIVERSAL_1_1);
6139 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6140 }
6141
TEST_F(ValidateImage,SparseReadLodAMDNeedCapability)6142 TEST_F(ValidateImage, SparseReadLodAMDNeedCapability) {
6143 const std::string body = R"(
6144 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
6145 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
6146 )";
6147
6148 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
6149 CompileSuccessfully(
6150 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6151 SPV_ENV_UNIVERSAL_1_1);
6152 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
6153 ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6154 EXPECT_THAT(getDiagnosticString(),
6155 HasSubstr("Image Operand Lod can only be used with ExplicitLod "
6156 "opcodes and OpImageFetch"));
6157 }
6158
TEST_F(ValidateImage,GatherBiasAMDSuccess)6159 TEST_F(ValidateImage, GatherBiasAMDSuccess) {
6160 const std::string body = R"(
6161 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6162 %sampler = OpLoad %type_sampler %uniform_sampler
6163 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6164 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
6165 )";
6166
6167 const std::string extra = R"(
6168 OpCapability ImageGatherBiasLodAMD
6169 OpExtension "SPV_AMD_texture_gather_bias_lod"
6170 )";
6171 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6172 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6173 }
6174
TEST_F(ValidateImage,GatherLodAMDSuccess)6175 TEST_F(ValidateImage, GatherLodAMDSuccess) {
6176 const std::string body = R"(
6177 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6178 %sampler = OpLoad %type_sampler %uniform_sampler
6179 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6180 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
6181 )";
6182
6183 const std::string extra = R"(
6184 OpCapability ImageGatherBiasLodAMD
6185 OpExtension "SPV_AMD_texture_gather_bias_lod"
6186 )";
6187 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6188 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6189 }
6190
TEST_F(ValidateImage,SparseGatherBiasAMDSuccess)6191 TEST_F(ValidateImage, SparseGatherBiasAMDSuccess) {
6192 const std::string body = R"(
6193 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6194 %sampler = OpLoad %type_sampler %uniform_sampler
6195 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6196 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
6197 )";
6198
6199 const std::string extra = R"(
6200 OpCapability ImageGatherBiasLodAMD
6201 OpExtension "SPV_AMD_texture_gather_bias_lod"
6202 )";
6203 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6204 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6205 }
6206
TEST_F(ValidateImage,SparseGatherLodAMDSuccess)6207 TEST_F(ValidateImage, SparseGatherLodAMDSuccess) {
6208 const std::string body = R"(
6209 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6210 %sampler = OpLoad %type_sampler %uniform_sampler
6211 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6212 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
6213 )";
6214
6215 const std::string extra = R"(
6216 OpCapability ImageGatherBiasLodAMD
6217 OpExtension "SPV_AMD_texture_gather_bias_lod"
6218 )";
6219 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6220 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6221 }
6222
6223 // No negative tests for ZeroExtend since we don't truly know the
6224 // texel format.
6225
6226 // Tests for 64-bit images
6227 static const std::string capabilities_and_extensions_image64 = R"(
6228 OpCapability Int64ImageEXT
6229 OpExtension "SPV_EXT_shader_image_int64"
6230 )";
6231 static const std::string capabilities_and_extensions_image64_atomic = R"(
6232 OpCapability Int64Atomics
6233 OpCapability Int64ImageEXT
6234 OpExtension "SPV_EXT_shader_image_int64"
6235 )";
6236 static const std::string declarations_image64 = R"(
6237 %type_image_u64_buffer_0002_r64ui = OpTypeImage %u64 Buffer 0 0 0 2 R64ui
6238 %ptr_Image_u64 = OpTypePointer Image %u64
6239 %ptr_image_u64_buffer_0002_r64ui = OpTypePointer Private %type_image_u64_buffer_0002_r64ui
6240 %private_image_u64_buffer_0002_r64ui = OpVariable %ptr_image_u64_buffer_0002_r64ui Private
6241 )";
6242 static const std::string declarations_image64i = R"(
6243 %type_image_s64_buffer_0002_r64i = OpTypeImage %s64 Buffer 0 0 0 2 R64i
6244 %ptr_Image_s64 = OpTypePointer Image %s64
6245 %ptr_image_s64_buffer_0002_r64i = OpTypePointer Private %type_image_s64_buffer_0002_r64i
6246 %private_image_s64_buffer_0002_r64i = OpVariable %ptr_image_s64_buffer_0002_r64i Private
6247 )";
6248
TEST_F(ValidateImage,Image64MissingCapability)6249 TEST_F(ValidateImage, Image64MissingCapability) {
6250 CompileSuccessfully(GenerateShaderCode("", "", "Fragment", "",
6251 SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6252 declarations_image64)
6253 .c_str());
6254 ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
6255 }
6256
TEST_F(ValidateImage,Image64MissingExtension)6257 TEST_F(ValidateImage, Image64MissingExtension) {
6258 const std::string extra = R"(
6259 OpCapability Int64ImageEXT
6260 )";
6261
6262 CompileSuccessfully(GenerateShaderCode("", extra, "Fragment", "",
6263 SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6264 declarations_image64)
6265 .c_str());
6266 ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
6267 }
6268
TEST_F(ValidateImage,ImageTexelPointer64Success)6269 TEST_F(ValidateImage, ImageTexelPointer64Success) {
6270 const std::string body = R"(
6271 %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6272 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6273 )";
6274
6275 CompileSuccessfully(
6276 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6277 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6278 declarations_image64)
6279 .c_str());
6280 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6281 }
6282
TEST_F(ValidateImage,ImageTexelPointer64ResultTypeNotPointer)6283 TEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotPointer) {
6284 const std::string body = R"(
6285 %texel_ptr = OpImageTexelPointer %type_image_u64_buffer_0002_r64ui %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6286 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6287 )";
6288
6289 CompileSuccessfully(
6290 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6291 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6292 declarations_image64)
6293 .c_str());
6294 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6295 EXPECT_THAT(getDiagnosticString(),
6296 HasSubstr("Expected Result Type to be OpTypePointer"));
6297 }
6298
TEST_F(ValidateImage,ImageTexelPointer64ResultTypeNotImageClass)6299 TEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotImageClass) {
6300 const std::string body = R"(
6301 %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6302 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6303 )";
6304
6305 CompileSuccessfully(
6306 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6307 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6308 declarations_image64)
6309 .c_str());
6310 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6311 EXPECT_THAT(getDiagnosticString(),
6312 HasSubstr("Expected Result Type to be OpTypePointer whose "
6313 "Storage Class operand is Image"));
6314 }
6315
TEST_F(ValidateImage,ImageTexelPointer64SampleNotZeroForImageWithMSZero)6316 TEST_F(ValidateImage, ImageTexelPointer64SampleNotZeroForImageWithMSZero) {
6317 const std::string body = R"(
6318 %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_1
6319 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6320 )";
6321
6322 CompileSuccessfully(
6323 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6324 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6325 declarations_image64)
6326 .c_str());
6327 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6328 EXPECT_THAT(getDiagnosticString(),
6329 HasSubstr("Expected Sample for Image with MS 0 to be a valid "
6330 "<id> for the value 0"));
6331 }
6332
TEST_F(ValidateImage,ImageTexelPointerR32uiSuccessVulkan)6333 TEST_F(ValidateImage, ImageTexelPointerR32uiSuccessVulkan) {
6334 const std::string body = R"(
6335 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
6336 )";
6337
6338 spv_target_env env = SPV_ENV_VULKAN_1_0;
6339 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
6340 env);
6341 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6342 }
6343
TEST_F(ValidateImage,ImageTexelPointerR32iSuccessVulkan)6344 TEST_F(ValidateImage, ImageTexelPointerR32iSuccessVulkan) {
6345 const std::string& declarations = R"(
6346 %type_image_s32_buffer_0002_r32i = OpTypeImage %s32 Buffer 0 0 0 2 R32i
6347 %ptr_Image_s32 = OpTypePointer Image %s32
6348 %ptr_image_s32_buffer_0002_r32i = OpTypePointer Private %type_image_s32_buffer_0002_r32i
6349 %private_image_s32_buffer_0002_r32i = OpVariable %ptr_image_s32_buffer_0002_r32i Private
6350 )";
6351
6352 const std::string body = R"(
6353 %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_r32i %u32_0 %u32_0
6354 )";
6355
6356 spv_target_env env = SPV_ENV_VULKAN_1_0;
6357 CompileSuccessfully(
6358 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6359 .c_str(),
6360 env);
6361 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6362 }
6363
TEST_F(ValidateImage,ImageTexelPointerR64uiSuccessVulkan)6364 TEST_F(ValidateImage, ImageTexelPointerR64uiSuccessVulkan) {
6365 const std::string body = R"(
6366 %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6367 )";
6368
6369 spv_target_env env = SPV_ENV_VULKAN_1_0;
6370 CompileSuccessfully(
6371 GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
6372 "", env, "GLSL450", declarations_image64)
6373 .c_str(),
6374 env);
6375 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6376 }
6377
TEST_F(ValidateImage,ImageTexelPointerR64iSuccessVulkan)6378 TEST_F(ValidateImage, ImageTexelPointerR64iSuccessVulkan) {
6379 const std::string body = R"(
6380 %texel_ptr = OpImageTexelPointer %ptr_Image_s64 %private_image_s64_buffer_0002_r64i %u32_0 %u32_0
6381 )";
6382
6383 spv_target_env env = SPV_ENV_VULKAN_1_0;
6384 CompileSuccessfully(
6385 GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
6386 "", env, "GLSL450", declarations_image64i)
6387 .c_str(),
6388 env);
6389 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6390 }
6391
TEST_F(ValidateImage,ImageTexelPointerR32fSuccessVulkan)6392 TEST_F(ValidateImage, ImageTexelPointerR32fSuccessVulkan) {
6393 const std::string& declarations = R"(
6394 %type_image_f32_buffer_0002_r32f = OpTypeImage %f32 Buffer 0 0 0 2 R32f
6395 %ptr_image_f32_buffer_0002_r32f = OpTypePointer Private %type_image_f32_buffer_0002_r32f
6396 %private_image_f32_buffer_0002_r32f = OpVariable %ptr_image_f32_buffer_0002_r32f Private
6397 )";
6398
6399 const std::string body = R"(
6400 %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32f %u32_0 %u32_0
6401 )";
6402
6403 spv_target_env env = SPV_ENV_VULKAN_1_0;
6404 CompileSuccessfully(
6405 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6406 .c_str(),
6407 env);
6408 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6409 }
6410
TEST_F(ValidateImage,ImageTexelPointerRgba32iVulkan)6411 TEST_F(ValidateImage, ImageTexelPointerRgba32iVulkan) {
6412 const std::string& declarations = R"(
6413 %type_image_s32_buffer_0002_rgba32i = OpTypeImage %s32 Buffer 0 0 0 2 Rgba32i
6414 %ptr_Image_s32 = OpTypePointer Image %s32
6415 %ptr_image_s32_buffer_0002_rgba32i = OpTypePointer Private %type_image_s32_buffer_0002_rgba32i
6416 %private_image_s32_buffer_0002_rgba32i = OpVariable %ptr_image_s32_buffer_0002_rgba32i Private
6417 )";
6418
6419 const std::string body = R"(
6420 %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba32i %u32_0 %u32_0
6421 )";
6422
6423 spv_target_env env = SPV_ENV_VULKAN_1_0;
6424 CompileSuccessfully(
6425 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6426 .c_str(),
6427 env);
6428 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
6429 EXPECT_THAT(getDiagnosticString(),
6430 AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
6431 EXPECT_THAT(getDiagnosticString(),
6432 HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
6433 "R32f, R32i, or R32ui for Vulkan environment"));
6434 }
6435
TEST_F(ValidateImage,ImageTexelPointerRgba16fVulkan)6436 TEST_F(ValidateImage, ImageTexelPointerRgba16fVulkan) {
6437 const std::string& declarations = R"(
6438 %type_image_s32_buffer_0002_rgba16f = OpTypeImage %s32 Buffer 0 0 0 2 Rgba16f
6439 %ptr_Image_s32 = OpTypePointer Image %s32
6440 %ptr_image_s32_buffer_0002_rgba16f = OpTypePointer Private %type_image_s32_buffer_0002_rgba16f
6441 %private_image_s32_buffer_0002_rgba16f = OpVariable %ptr_image_s32_buffer_0002_rgba16f Private
6442 )";
6443
6444 const std::string body = R"(
6445 %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba16f %u32_0 %u32_0
6446 )";
6447
6448 spv_target_env env = SPV_ENV_VULKAN_1_0;
6449 CompileSuccessfully(
6450 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6451 .c_str(),
6452 env);
6453 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
6454 EXPECT_THAT(getDiagnosticString(),
6455 AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
6456 EXPECT_THAT(getDiagnosticString(),
6457 HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
6458 "R32f, R32i, or R32ui for Vulkan environment"));
6459 }
6460
TEST_F(ValidateImage,ImageExecutionModeLimitationNoMode)6461 TEST_F(ValidateImage, ImageExecutionModeLimitationNoMode) {
6462 const std::string text = R"(
6463 OpCapability Shader
6464 OpMemoryModel Logical GLSL450
6465 OpEntryPoint GLCompute %2 " " %4
6466 %void = OpTypeVoid
6467 %8 = OpTypeFunction %void
6468 %float = OpTypeFloat 32
6469 %v4float = OpTypeVector %float 4
6470 %12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
6471 %13 = OpTypeSampledImage %12
6472 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6473 %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
6474 %_ptr_Input_v4float = OpTypePointer Input %v4float
6475 %4 = OpVariable %_ptr_Input_v4float Input
6476 %v2float = OpTypeVector %float 2
6477 %float_1_35631564en19 = OpConstant %float 1.35631564e-19
6478 %2 = OpFunction %void None %8
6479 %8224 = OpLabel
6480 %6 = OpLoad %13 %5
6481 %19 = OpLoad %v4float %4
6482 %20 = OpVectorShuffle %v2float %19 %19 0 1
6483 %21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
6484 %65312 = OpImageSampleImplicitLod %v4float %6 %21
6485 OpUnreachable
6486 OpFunctionEnd
6487 )";
6488
6489 CompileSuccessfully(text);
6490 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6491 EXPECT_THAT(getDiagnosticString(),
6492 HasSubstr("ImplicitLod instructions require "
6493 "DerivativeGroupQuadsNV or DerivativeGroupLinearNV "
6494 "execution mode for GLCompute execution model"));
6495 }
6496
TEST_F(ValidateImage,TypeSampledImageNotBufferPost1p6)6497 TEST_F(ValidateImage, TypeSampledImageNotBufferPost1p6) {
6498 const std::string text = R"(
6499 OpCapability Shader
6500 OpCapability Linkage
6501 OpCapability SampledBuffer
6502 OpMemoryModel Logical GLSL450
6503 %float = OpTypeFloat 32
6504 %image = OpTypeImage %float Buffer 0 0 0 1 Unknown
6505 %sampled = OpTypeSampledImage %image
6506 )";
6507
6508 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
6509 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
6510 EXPECT_THAT(getDiagnosticString(),
6511 HasSubstr("In SPIR-V 1.6 or later, sampled image dimension must "
6512 "not be Buffer"));
6513 }
6514
TEST_F(ValidateImage,NonTemporalImage)6515 TEST_F(ValidateImage, NonTemporalImage) {
6516 const std::string text = R"(
6517 OpCapability Shader
6518 OpMemoryModel Logical GLSL450
6519 OpEntryPoint Fragment %2 " " %4 %5
6520 OpExecutionMode %2 OriginUpperLeft
6521 %void = OpTypeVoid
6522 %8 = OpTypeFunction %void
6523 %float = OpTypeFloat 32
6524 %v4float = OpTypeVector %float 4
6525 %12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
6526 %13 = OpTypeSampledImage %12
6527 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6528 %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
6529 %_ptr_Input_v4float = OpTypePointer Input %v4float
6530 %4 = OpVariable %_ptr_Input_v4float Input
6531 %v2float = OpTypeVector %float 2
6532 %float_1_35631564en19 = OpConstant %float 1.35631564e-19
6533 %2 = OpFunction %void None %8
6534 %8224 = OpLabel
6535 %6 = OpLoad %13 %5
6536 %19 = OpLoad %v4float %4
6537 %20 = OpVectorShuffle %v2float %19 %19 0 1
6538 %21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
6539 %65312 = OpImageSampleImplicitLod %v4float %6 %21 Nontemporal
6540 OpReturn
6541 OpFunctionEnd
6542 )";
6543
6544 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
6545 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
6546 }
6547
TEST_F(ValidateImage,NVBindlessSamplerBuiltins)6548 TEST_F(ValidateImage, NVBindlessSamplerBuiltins) {
6549 const std::string text = R"(
6550 OpCapability Shader
6551 OpCapability Int64
6552 OpCapability Image1D
6553 OpCapability BindlessTextureNV
6554 OpExtension "SPV_NV_bindless_texture"
6555 %1 = OpExtInstImport "GLSL.std.450"
6556 OpMemoryModel Logical GLSL450
6557 OpSamplerImageAddressingModeNV 64
6558 OpEntryPoint Fragment %main "main"
6559 OpExecutionMode %main OriginUpperLeft
6560 OpSource GLSL 450
6561 OpName %main "main"
6562 OpName %s2D "s2D"
6563 OpName %textureHandle "textureHandle"
6564 OpName %i1D "i1D"
6565 OpName %s "s"
6566 OpName %temp "temp"
6567 %void = OpTypeVoid
6568 %3 = OpTypeFunction %void
6569 %float = OpTypeFloat 32
6570 %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
6571 %8 = OpTypeSampledImage %7
6572 %_ptr_Function_8 = OpTypePointer Function %8
6573 %ulong = OpTypeInt 64 0
6574 %_ptr_Private_ulong = OpTypePointer Private %ulong
6575 %textureHandle = OpVariable %_ptr_Private_ulong Private
6576 %16 = OpTypeImage %float 1D 0 0 0 2 Rgba32f
6577 %_ptr_Function_16 = OpTypePointer Function %16
6578 %21 = OpTypeSampler
6579 %_ptr_Function_21 = OpTypePointer Function %21
6580 %_ptr_Function_ulong = OpTypePointer Function %ulong
6581 %main = OpFunction %void None %3
6582 %5 = OpLabel
6583 %s2D = OpVariable %_ptr_Function_8 Function
6584 %i1D = OpVariable %_ptr_Function_16 Function
6585 %s = OpVariable %_ptr_Function_21 Function
6586 %temp = OpVariable %_ptr_Function_ulong Function
6587 %14 = OpLoad %ulong %textureHandle
6588 %15 = OpConvertUToSampledImageNV %8 %14
6589 OpStore %s2D %15
6590 %19 = OpLoad %ulong %textureHandle
6591 %20 = OpConvertUToImageNV %16 %19
6592 OpStore %i1D %20
6593 %24 = OpLoad %ulong %textureHandle
6594 %25 = OpConvertUToSamplerNV %21 %24
6595 OpStore %s %25
6596 %28 = OpLoad %8 %s2D
6597 %29 = OpConvertSampledImageToUNV %ulong %28
6598 OpStore %temp %29
6599 %30 = OpLoad %16 %i1D
6600 %31 = OpConvertImageToUNV %ulong %30
6601 OpStore %temp %31
6602 %32 = OpLoad %21 %s
6603 %33 = OpConvertSamplerToUNV %ulong %32
6604 OpStore %temp %33
6605 OpReturn
6606 OpFunctionEnd
6607 )";
6608
6609 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6610 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6611 }
6612
TEST_F(ValidateImage,NVBindlessAddressingMode64)6613 TEST_F(ValidateImage, NVBindlessAddressingMode64) {
6614 std::string text = R"(
6615 OpCapability Shader
6616 OpCapability BindlessTextureNV
6617 OpExtension "SPV_NV_bindless_texture"
6618 OpMemoryModel Logical GLSL450
6619 OpSamplerImageAddressingModeNV 64
6620 OpEntryPoint GLCompute %func "main"
6621 %voidt = OpTypeVoid
6622 %uintt = OpTypeInt 32 0
6623 %funct = OpTypeFunction %voidt
6624 %func = OpFunction %voidt None %funct
6625 %entry = OpLabel
6626 %udef = OpUndef %uintt
6627 OpReturn
6628 OpFunctionEnd
6629 )";
6630 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6631 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6632 }
6633
TEST_F(ValidateImage,NVBindlessAddressingMode32)6634 TEST_F(ValidateImage, NVBindlessAddressingMode32) {
6635 std::string text = R"(
6636 OpCapability Shader
6637 OpCapability BindlessTextureNV
6638 OpExtension "SPV_NV_bindless_texture"
6639 OpMemoryModel Logical GLSL450
6640 OpSamplerImageAddressingModeNV 32
6641 OpEntryPoint GLCompute %func "main"
6642 %voidt = OpTypeVoid
6643 %uintt = OpTypeInt 32 0
6644 %funct = OpTypeFunction %voidt
6645 %func = OpFunction %voidt None %funct
6646 %entry = OpLabel
6647 %udef = OpUndef %uintt
6648 OpReturn
6649 OpFunctionEnd
6650 )";
6651 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6652 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6653 }
6654
TEST_F(ValidateImage,NVBindlessInvalidAddressingMode)6655 TEST_F(ValidateImage, NVBindlessInvalidAddressingMode) {
6656 std::string text = R"(
6657 OpCapability Shader
6658 OpCapability BindlessTextureNV
6659 OpExtension "SPV_NV_bindless_texture"
6660 OpMemoryModel Logical GLSL450
6661 OpSamplerImageAddressingModeNV 0
6662 OpEntryPoint GLCompute %func "main"
6663 %voidt = OpTypeVoid
6664 %uintt = OpTypeInt 32 0
6665 %funct = OpTypeFunction %voidt
6666 %func = OpFunction %voidt None %funct
6667 %entry = OpLabel
6668 %udef = OpUndef %uintt
6669 OpReturn
6670 OpFunctionEnd
6671 )";
6672 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6673 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6674 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6675 EXPECT_THAT(
6676 getDiagnosticString(),
6677 HasSubstr("OpSamplerImageAddressingModeNV bitwidth should be 64 or 32"));
6678 }
6679
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADNoDecorationA)6680 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationA) {
6681 std::string text = R"(
6682 OpCapability Shader
6683 OpCapability TextureBlockMatchQCOM
6684 OpExtension "SPV_QCOM_image_processing"
6685 %1 = OpExtInstImport "GLSL.std.450"
6686 OpMemoryModel Logical GLSL450
6687 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6688 OpExecutionMode %2 OriginUpperLeft
6689 OpDecorate %3 Location 0
6690 OpDecorate %4 DescriptorSet 0
6691 OpDecorate %4 Binding 1
6692 OpDecorate %5 DescriptorSet 0
6693 OpDecorate %5 Binding 3
6694 OpDecorate %6 DescriptorSet 0
6695 OpDecorate %6 Binding 2
6696 OpDecorate %6 BlockMatchTextureQCOM
6697 %void = OpTypeVoid
6698 %8 = OpTypeFunction %void
6699 %uint = OpTypeInt 32 0
6700 %v2uint = OpTypeVector %uint 2
6701 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6702 %float = OpTypeFloat 32
6703 %v4float = OpTypeVector %float 4
6704 %_ptr_Input_float = OpTypePointer Input %float
6705 %_ptr_Function_uint = OpTypePointer Function %uint
6706 %uint_4 = OpConstant %uint 4
6707 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6708 %_ptr_Output_v4float = OpTypePointer Output %v4float
6709 %3 = OpVariable %_ptr_Output_v4float Output
6710 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6711 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6712 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6713 %21 = OpTypeSampler
6714 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6715 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6716 %23 = OpTypeSampledImage %19
6717 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6718 %2 = OpFunction %void None %8
6719 %24 = OpLabel
6720 %25 = OpVariable %_ptr_Function_v2uint Function
6721 %26 = OpLoad %19 %4
6722 %27 = OpLoad %21 %5
6723 %28 = OpSampledImage %23 %26 %27
6724 %29 = OpLoad %v2uint %25
6725 %30 = OpLoad %19 %6
6726 %31 = OpLoad %21 %5
6727 %32 = OpSampledImage %23 %30 %31
6728 %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29
6729 OpStore %3 %33
6730 OpReturn
6731 OpFunctionEnd
6732 )";
6733 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6734 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6735 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6736 EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
6737 }
6738
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADNoDecorationB)6739 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationB) {
6740 std::string text = R"(
6741 OpCapability Shader
6742 OpCapability TextureBlockMatchQCOM
6743 OpExtension "SPV_QCOM_image_processing"
6744 %1 = OpExtInstImport "GLSL.std.450"
6745 OpMemoryModel Logical GLSL450
6746 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6747 OpExecutionMode %2 OriginUpperLeft
6748 OpDecorate %3 Location 0
6749 OpDecorate %4 DescriptorSet 0
6750 OpDecorate %4 Binding 1
6751 OpDecorate %5 DescriptorSet 0
6752 OpDecorate %5 Binding 3
6753 OpDecorate %5 BlockMatchTextureQCOM
6754 OpDecorate %6 DescriptorSet 0
6755 OpDecorate %6 Binding 2
6756 %void = OpTypeVoid
6757 %8 = OpTypeFunction %void
6758 %uint = OpTypeInt 32 0
6759 %v2uint = OpTypeVector %uint 2
6760 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6761 %float = OpTypeFloat 32
6762 %v4float = OpTypeVector %float 4
6763 %_ptr_Input_float = OpTypePointer Input %float
6764 %_ptr_Function_uint = OpTypePointer Function %uint
6765 %uint_4 = OpConstant %uint 4
6766 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6767 %_ptr_Output_v4float = OpTypePointer Output %v4float
6768 %3 = OpVariable %_ptr_Output_v4float Output
6769 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6770 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6771 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6772 %21 = OpTypeSampler
6773 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6774 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6775 %23 = OpTypeSampledImage %19
6776 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6777 %2 = OpFunction %void None %8
6778 %24 = OpLabel
6779 %25 = OpVariable %_ptr_Function_v2uint Function
6780 %26 = OpLoad %19 %4
6781 %27 = OpLoad %21 %5
6782 %28 = OpSampledImage %23 %26 %27
6783 %29 = OpLoad %v2uint %25
6784 %30 = OpLoad %19 %6
6785 %31 = OpLoad %21 %5
6786 %32 = OpSampledImage %23 %30 %31
6787 %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29
6788 OpStore %3 %33
6789 OpReturn
6790 OpFunctionEnd
6791 )";
6792 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6793 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6794 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6795 EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
6796 }
6797
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADNoDecorationC)6798 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationC) {
6799 std::string text = R"(
6800 OpCapability Shader
6801 OpCapability TextureBlockMatchQCOM
6802 OpExtension "SPV_QCOM_image_processing"
6803 %1 = OpExtInstImport "GLSL.std.450"
6804 OpMemoryModel Logical GLSL450
6805 OpEntryPoint Fragment %2 "main" %3 %4 %5
6806 OpExecutionMode %2 OriginUpperLeft
6807 OpDecorate %3 Location 0
6808 OpDecorate %4 DescriptorSet 0
6809 OpDecorate %4 Binding 4
6810 OpDecorate %5 DescriptorSet 0
6811 OpDecorate %5 Binding 5
6812 OpDecorate %5 BlockMatchTextureQCOM
6813 %void = OpTypeVoid
6814 %7 = OpTypeFunction %void
6815 %uint = OpTypeInt 32 0
6816 %v2uint = OpTypeVector %uint 2
6817 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6818 %float = OpTypeFloat 32
6819 %v4float = OpTypeVector %float 4
6820 %_ptr_Input_v4float = OpTypePointer Input %v4float
6821 %_ptr_Input_float = OpTypePointer Input %float
6822 %_ptr_Function_uint = OpTypePointer Function %uint
6823 %_ptr_Output_v4float = OpTypePointer Output %v4float
6824 %3 = OpVariable %_ptr_Output_v4float Output
6825 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
6826 %19 = OpTypeSampledImage %18
6827 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6828 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6829 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6830 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
6831 %2 = OpFunction %void None %7
6832 %22 = OpLabel
6833 %23 = OpVariable %_ptr_Function_v2uint Function
6834 %24 = OpLoad %19 %4
6835 %25 = OpLoad %v2uint %23
6836 %26 = OpLoad %19 %5
6837 %27 = OpLoad %v2uint %23
6838 %28 = OpLoad %v2uint %23
6839 %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28
6840 OpStore %3 %29
6841 OpReturn
6842 OpFunctionEnd
6843 )";
6844 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6845 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6846 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6847 EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
6848 }
6849
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADNoDecorationD)6850 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationD) {
6851 std::string text = R"(
6852 OpCapability Shader
6853 OpCapability TextureBlockMatchQCOM
6854 OpExtension "SPV_QCOM_image_processing"
6855 %1 = OpExtInstImport "GLSL.std.450"
6856 OpMemoryModel Logical GLSL450
6857 OpEntryPoint Fragment %2 "main" %3 %4 %5
6858 OpExecutionMode %2 OriginUpperLeft
6859 OpDecorate %3 Location 0
6860 OpDecorate %4 DescriptorSet 0
6861 OpDecorate %4 Binding 4
6862 OpDecorate %4 BlockMatchTextureQCOM
6863 OpDecorate %5 DescriptorSet 0
6864 OpDecorate %5 Binding 5
6865 %void = OpTypeVoid
6866 %7 = OpTypeFunction %void
6867 %uint = OpTypeInt 32 0
6868 %v2uint = OpTypeVector %uint 2
6869 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6870 %float = OpTypeFloat 32
6871 %v4float = OpTypeVector %float 4
6872 %_ptr_Input_v4float = OpTypePointer Input %v4float
6873 %_ptr_Input_float = OpTypePointer Input %float
6874 %_ptr_Function_uint = OpTypePointer Function %uint
6875 %_ptr_Output_v4float = OpTypePointer Output %v4float
6876 %3 = OpVariable %_ptr_Output_v4float Output
6877 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
6878 %19 = OpTypeSampledImage %18
6879 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6880 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6881 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6882 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
6883 %2 = OpFunction %void None %7
6884 %22 = OpLabel
6885 %23 = OpVariable %_ptr_Function_v2uint Function
6886 %24 = OpLoad %19 %4
6887 %25 = OpLoad %v2uint %23
6888 %26 = OpLoad %19 %5
6889 %27 = OpLoad %v2uint %23
6890 %28 = OpLoad %v2uint %23
6891 %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28
6892 OpStore %3 %29
6893 OpReturn
6894 OpFunctionEnd
6895 )";
6896 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6897 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6898 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6899 EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
6900 }
6901
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDNoDecorationA)6902 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationA) {
6903 std::string text = R"(
6904 OpCapability Shader
6905 OpCapability TextureBlockMatchQCOM
6906 OpExtension "SPV_QCOM_image_processing"
6907 %1 = OpExtInstImport "GLSL.std.450"
6908 OpMemoryModel Logical GLSL450
6909 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6910 OpExecutionMode %2 OriginUpperLeft
6911 OpDecorate %3 Location 0
6912 OpDecorate %4 DescriptorSet 0
6913 OpDecorate %4 Binding 1
6914 OpDecorate %5 DescriptorSet 0
6915 OpDecorate %5 Binding 3
6916 OpDecorate %6 DescriptorSet 0
6917 OpDecorate %6 Binding 2
6918 OpDecorate %6 BlockMatchTextureQCOM
6919 %void = OpTypeVoid
6920 %8 = OpTypeFunction %void
6921 %uint = OpTypeInt 32 0
6922 %v2uint = OpTypeVector %uint 2
6923 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6924 %float = OpTypeFloat 32
6925 %v4float = OpTypeVector %float 4
6926 %_ptr_Input_float = OpTypePointer Input %float
6927 %_ptr_Function_uint = OpTypePointer Function %uint
6928 %uint_4 = OpConstant %uint 4
6929 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6930 %_ptr_Output_v4float = OpTypePointer Output %v4float
6931 %3 = OpVariable %_ptr_Output_v4float Output
6932 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6933 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6934 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6935 %21 = OpTypeSampler
6936 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6937 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6938 %23 = OpTypeSampledImage %19
6939 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6940 %2 = OpFunction %void None %8
6941 %24 = OpLabel
6942 %25 = OpVariable %_ptr_Function_v2uint Function
6943 %26 = OpLoad %19 %4
6944 %27 = OpLoad %21 %5
6945 %28 = OpSampledImage %23 %26 %27
6946 %29 = OpLoad %v2uint %25
6947 %30 = OpLoad %19 %6
6948 %31 = OpLoad %21 %5
6949 %32 = OpSampledImage %23 %30 %31
6950 %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29
6951 OpStore %3 %33
6952 OpReturn
6953 OpFunctionEnd
6954 )";
6955 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6956 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6957 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6958 EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
6959 }
6960
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDNoDecorationB)6961 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationB) {
6962 std::string text = R"(
6963 OpCapability Shader
6964 OpCapability TextureBlockMatchQCOM
6965 OpExtension "SPV_QCOM_image_processing"
6966 %1 = OpExtInstImport "GLSL.std.450"
6967 OpMemoryModel Logical GLSL450
6968 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6969 OpExecutionMode %2 OriginUpperLeft
6970 OpDecorate %3 Location 0
6971 OpDecorate %4 DescriptorSet 0
6972 OpDecorate %4 Binding 1
6973 OpDecorate %5 DescriptorSet 0
6974 OpDecorate %5 Binding 3
6975 OpDecorate %5 BlockMatchTextureQCOM
6976 OpDecorate %6 DescriptorSet 0
6977 OpDecorate %6 Binding 2
6978 %void = OpTypeVoid
6979 %8 = OpTypeFunction %void
6980 %uint = OpTypeInt 32 0
6981 %v2uint = OpTypeVector %uint 2
6982 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6983 %float = OpTypeFloat 32
6984 %v4float = OpTypeVector %float 4
6985 %_ptr_Input_float = OpTypePointer Input %float
6986 %_ptr_Function_uint = OpTypePointer Function %uint
6987 %uint_4 = OpConstant %uint 4
6988 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6989 %_ptr_Output_v4float = OpTypePointer Output %v4float
6990 %3 = OpVariable %_ptr_Output_v4float Output
6991 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6992 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6993 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6994 %21 = OpTypeSampler
6995 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6996 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6997 %23 = OpTypeSampledImage %19
6998 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6999 %2 = OpFunction %void None %8
7000 %24 = OpLabel
7001 %25 = OpVariable %_ptr_Function_v2uint Function
7002 %26 = OpLoad %19 %4
7003 %27 = OpLoad %21 %5
7004 %28 = OpSampledImage %23 %26 %27
7005 %29 = OpLoad %v2uint %25
7006 %30 = OpLoad %19 %6
7007 %31 = OpLoad %21 %5
7008 %32 = OpSampledImage %23 %30 %31
7009 %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29
7010 OpStore %3 %33
7011 OpReturn
7012 OpFunctionEnd
7013 )";
7014 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7015 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7016 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7017 EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
7018 }
7019
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDNoDecorationC)7020 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationC) {
7021 std::string text = R"(
7022 OpCapability Shader
7023 OpCapability TextureBlockMatchQCOM
7024 OpExtension "SPV_QCOM_image_processing"
7025 %1 = OpExtInstImport "GLSL.std.450"
7026 OpMemoryModel Logical GLSL450
7027 OpEntryPoint Fragment %2 "main" %3 %4 %5
7028 OpExecutionMode %2 OriginUpperLeft
7029 OpDecorate %3 Location 0
7030 OpDecorate %4 DescriptorSet 0
7031 OpDecorate %4 Binding 4
7032 OpDecorate %5 DescriptorSet 0
7033 OpDecorate %5 Binding 5
7034 OpDecorate %5 BlockMatchTextureQCOM
7035 %void = OpTypeVoid
7036 %7 = OpTypeFunction %void
7037 %uint = OpTypeInt 32 0
7038 %v2uint = OpTypeVector %uint 2
7039 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7040 %float = OpTypeFloat 32
7041 %v4float = OpTypeVector %float 4
7042 %_ptr_Input_v4float = OpTypePointer Input %v4float
7043 %_ptr_Input_float = OpTypePointer Input %float
7044 %_ptr_Function_uint = OpTypePointer Function %uint
7045 %_ptr_Output_v4float = OpTypePointer Output %v4float
7046 %3 = OpVariable %_ptr_Output_v4float Output
7047 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7048 %19 = OpTypeSampledImage %18
7049 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7050 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7051 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7052 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
7053 %2 = OpFunction %void None %7
7054 %22 = OpLabel
7055 %23 = OpVariable %_ptr_Function_v2uint Function
7056 %24 = OpLoad %19 %4
7057 %25 = OpLoad %v2uint %23
7058 %26 = OpLoad %19 %5
7059 %27 = OpLoad %v2uint %23
7060 %28 = OpLoad %v2uint %23
7061 %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28
7062 OpStore %3 %29
7063 OpReturn
7064 OpFunctionEnd
7065 )";
7066 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7067 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7068 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7069 EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
7070 }
7071
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDNoDecorationD)7072 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationD) {
7073 std::string text = R"(
7074 OpCapability Shader
7075 OpCapability TextureBlockMatchQCOM
7076 OpExtension "SPV_QCOM_image_processing"
7077 %1 = OpExtInstImport "GLSL.std.450"
7078 OpMemoryModel Logical GLSL450
7079 OpEntryPoint Fragment %2 "main" %3 %4 %5
7080 OpExecutionMode %2 OriginUpperLeft
7081 OpDecorate %3 Location 0
7082 OpDecorate %4 DescriptorSet 0
7083 OpDecorate %4 Binding 4
7084 OpDecorate %4 BlockMatchTextureQCOM
7085 OpDecorate %5 DescriptorSet 0
7086 OpDecorate %5 Binding 5
7087 %void = OpTypeVoid
7088 %7 = OpTypeFunction %void
7089 %uint = OpTypeInt 32 0
7090 %v2uint = OpTypeVector %uint 2
7091 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7092 %float = OpTypeFloat 32
7093 %v4float = OpTypeVector %float 4
7094 %_ptr_Input_v4float = OpTypePointer Input %v4float
7095 %_ptr_Input_float = OpTypePointer Input %float
7096 %_ptr_Function_uint = OpTypePointer Function %uint
7097 %_ptr_Output_v4float = OpTypePointer Output %v4float
7098 %3 = OpVariable %_ptr_Output_v4float Output
7099 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7100 %19 = OpTypeSampledImage %18
7101 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7102 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7103 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7104 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
7105 %2 = OpFunction %void None %7
7106 %22 = OpLabel
7107 %23 = OpVariable %_ptr_Function_v2uint Function
7108 %24 = OpLoad %19 %4
7109 %25 = OpLoad %v2uint %23
7110 %26 = OpLoad %19 %5
7111 %27 = OpLoad %v2uint %23
7112 %28 = OpLoad %v2uint %23
7113 %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28
7114 OpStore %3 %29
7115 OpReturn
7116 OpFunctionEnd
7117 )";
7118 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7119 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7120 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7121 EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
7122 }
7123
TEST_F(ValidateImage,QCOMImageProcessingSampleWeightedNoDecorationA)7124 TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationA) {
7125 std::string text = R"(
7126 OpCapability Shader
7127 OpCapability TextureSampleWeightedQCOM
7128 OpExtension "SPV_QCOM_image_processing"
7129 %1 = OpExtInstImport "GLSL.std.450"
7130 OpMemoryModel Logical GLSL450
7131 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7
7132 OpExecutionMode %2 OriginUpperLeft
7133 OpDecorate %3 Location 0
7134 OpDecorate %4 DescriptorSet 0
7135 OpDecorate %4 Binding 1
7136 OpDecorate %5 DescriptorSet 0
7137 OpDecorate %5 Binding 3
7138 OpDecorate %6 Location 0
7139 OpDecorate %7 DescriptorSet 0
7140 OpDecorate %7 Binding 0
7141 %void = OpTypeVoid
7142 %9 = OpTypeFunction %void
7143 %float = OpTypeFloat 32
7144 %v4float = OpTypeVector %float 4
7145 %_ptr_Output_v4float = OpTypePointer Output %v4float
7146 %3 = OpVariable %_ptr_Output_v4float Output
7147 %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
7148 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
7149 %4 = OpVariable %_ptr_UniformConstant_13 UniformConstant
7150 %15 = OpTypeSampler
7151 %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
7152 %5 = OpVariable %_ptr_UniformConstant_15 UniformConstant
7153 %17 = OpTypeSampledImage %13
7154 %_ptr_Input_v4float = OpTypePointer Input %v4float
7155 %6 = OpVariable %_ptr_Input_v4float Input
7156 %v2float = OpTypeVector %float 2
7157 %20 = OpTypeImage %float 2D 0 1 0 1 Unknown
7158 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7159 %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7160 %22 = OpTypeSampledImage %20
7161 %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
7162 %2 = OpFunction %void None %9
7163 %24 = OpLabel
7164 %25 = OpLoad %13 %4
7165 %26 = OpLoad %15 %5
7166 %27 = OpSampledImage %17 %25 %26
7167 %28 = OpLoad %v4float %6
7168 %29 = OpVectorShuffle %v2float %28 %28 0 1
7169 %30 = OpLoad %20 %7
7170 %31 = OpLoad %15 %5
7171 %32 = OpSampledImage %22 %30 %31
7172 %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32
7173 OpStore %3 %33
7174 OpReturn
7175 OpFunctionEnd
7176 )";
7177 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7178 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7179 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7180 EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
7181 }
7182
TEST_F(ValidateImage,QCOMImageProcessingSampleWeightedNoDecorationB)7183 TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationB) {
7184 std::string text = R"(
7185 OpCapability Shader
7186 OpCapability TextureSampleWeightedQCOM
7187 OpExtension "SPV_QCOM_image_processing"
7188 %1 = OpExtInstImport "GLSL.std.450"
7189 OpMemoryModel Logical GLSL450
7190 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7191 OpExecutionMode %2 OriginUpperLeft
7192 OpDecorate %3 Location 0
7193 OpDecorate %4 Location 0
7194 OpDecorate %5 DescriptorSet 0
7195 OpDecorate %5 Binding 4
7196 OpDecorate %6 DescriptorSet 0
7197 OpDecorate %6 Binding 5
7198 %void = OpTypeVoid
7199 %8 = OpTypeFunction %void
7200 %float = OpTypeFloat 32
7201 %v4float = OpTypeVector %float 4
7202 %_ptr_Output_v4float = OpTypePointer Output %v4float
7203 %3 = OpVariable %_ptr_Output_v4float Output
7204 %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
7205 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
7206 %14 = OpTypeSampler
7207 %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
7208 %16 = OpTypeSampledImage %12
7209 %_ptr_Input_v4float = OpTypePointer Input %v4float
7210 %4 = OpVariable %_ptr_Input_v4float Input
7211 %v2float = OpTypeVector %float 2
7212 %19 = OpTypeImage %float 2D 0 1 0 1 Unknown
7213 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7214 %21 = OpTypeSampledImage %19
7215 %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
7216 %5 = OpVariable %_ptr_UniformConstant_16 UniformConstant
7217 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
7218 %6 = OpVariable %_ptr_UniformConstant_21 UniformConstant
7219 %2 = OpFunction %void None %8
7220 %24 = OpLabel
7221 %25 = OpLoad %16 %5
7222 %26 = OpLoad %v4float %4
7223 %27 = OpVectorShuffle %v2float %26 %26 0 1
7224 %28 = OpLoad %21 %6
7225 %29 = OpImageSampleWeightedQCOM %v4float %25 %27 %28
7226 OpStore %3 %29
7227 OpReturn
7228 OpFunctionEnd
7229 )";
7230 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7231 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7232 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7233 EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
7234 }
7235
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADInvalidUseA)7236 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseA) {
7237 std::string text = R"(
7238 ; SPIR-V
7239 ; Version: 1.0
7240 ; Generator: Khronos Glslang Reference Front End; 11
7241 ; Bound: 79
7242 ; Schema: 0
7243 OpCapability Shader
7244 OpCapability TextureBlockMatchQCOM
7245 OpExtension "SPV_QCOM_image_processing"
7246 %1 = OpExtInstImport "GLSL.std.450"
7247 OpMemoryModel Logical GLSL450
7248 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7249 OpExecutionMode %main OriginUpperLeft
7250 OpDecorate %100 Location 0
7251 OpDecorate %101 Location 0
7252 OpDecorate %102 DescriptorSet 0
7253 OpDecorate %102 Binding 1
7254 OpDecorate %103 DescriptorSet 0
7255 OpDecorate %103 Binding 3
7256 OpDecorate %104 DescriptorSet 0
7257 OpDecorate %104 Binding 2
7258 OpDecorate %102 BlockMatchTextureQCOM
7259 OpDecorate %104 BlockMatchTextureQCOM
7260 %void = OpTypeVoid
7261 %3 = OpTypeFunction %void
7262 %uint = OpTypeInt 32 0
7263 %v2uint = OpTypeVector %uint 2
7264 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7265 %float = OpTypeFloat 32
7266 %v4float = OpTypeVector %float 4
7267 %_ptr_Input_v4float = OpTypePointer Input %v4float
7268 %100 = OpVariable %_ptr_Input_v4float Input
7269 %_ptr_Output_v4float = OpTypePointer Output %v4float
7270 %101 = OpVariable %_ptr_Output_v4float Output
7271 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7272 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7273 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7274 %46 = OpTypeSampler
7275 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7276 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7277 %50 = OpTypeSampledImage %42
7278 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7279 %v2float = OpTypeVector %float 2
7280 %main = OpFunction %void None %3
7281 %5 = OpLabel
7282 %15 = OpVariable %_ptr_Function_v2uint Function
7283 %45 = OpLoad %42 %102
7284 %49 = OpLoad %46 %103
7285 %51 = OpSampledImage %50 %45 %49
7286 %52 = OpLoad %v2uint %15
7287 %54 = OpLoad %42 %104
7288 %55 = OpLoad %46 %103
7289 %56 = OpSampledImage %50 %54 %55
7290 %57 = OpLoad %v2uint %15
7291 %58 = OpLoad %v2uint %15
7292 %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58
7293 OpStore %101 %59
7294 %69 = OpLoad %42 %102
7295 %70 = OpLoad %46 %103
7296 %71 = OpSampledImage %50 %69 %70
7297 %73 = OpLoad %v4float %100
7298 %74 = OpVectorShuffle %v2float %73 %73 0 0
7299 %75 = OpImageSampleImplicitLod %v4float %71 %74
7300 OpStore %101 %75
7301 OpReturn
7302 OpFunctionEnd
7303 )";
7304 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7305 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7306 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7307 EXPECT_THAT(
7308 getDiagnosticString(),
7309 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7310 }
7311
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADInvalidUseB)7312 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseB) {
7313 std::string text = R"(
7314 ; SPIR-V
7315 ; Version: 1.0
7316 ; Generator: Khronos Glslang Reference Front End; 11
7317 ; Bound: 79
7318 ; Schema: 0
7319 OpCapability Shader
7320 OpCapability TextureBlockMatchQCOM
7321 OpExtension "SPV_QCOM_image_processing"
7322 %1 = OpExtInstImport "GLSL.std.450"
7323 OpMemoryModel Logical GLSL450
7324 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7325 OpExecutionMode %main OriginUpperLeft
7326 OpDecorate %100 Location 0
7327 OpDecorate %101 Location 0
7328 OpDecorate %102 DescriptorSet 0
7329 OpDecorate %102 Binding 1
7330 OpDecorate %103 DescriptorSet 0
7331 OpDecorate %103 Binding 3
7332 OpDecorate %104 DescriptorSet 0
7333 OpDecorate %104 Binding 2
7334 OpDecorate %102 BlockMatchTextureQCOM
7335 OpDecorate %104 BlockMatchTextureQCOM
7336 %void = OpTypeVoid
7337 %3 = OpTypeFunction %void
7338 %uint = OpTypeInt 32 0
7339 %v2uint = OpTypeVector %uint 2
7340 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7341 %float = OpTypeFloat 32
7342 %v4float = OpTypeVector %float 4
7343 %_ptr_Input_v4float = OpTypePointer Input %v4float
7344 %100 = OpVariable %_ptr_Input_v4float Input
7345 %_ptr_Output_v4float = OpTypePointer Output %v4float
7346 %101 = OpVariable %_ptr_Output_v4float Output
7347 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7348 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7349 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7350 %46 = OpTypeSampler
7351 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7352 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7353 %50 = OpTypeSampledImage %42
7354 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7355 %v2float = OpTypeVector %float 2
7356 %main = OpFunction %void None %3
7357 %5 = OpLabel
7358 %15 = OpVariable %_ptr_Function_v2uint Function
7359 %45 = OpLoad %42 %102
7360 %49 = OpLoad %46 %103
7361 %51 = OpSampledImage %50 %45 %49
7362 %52 = OpLoad %v2uint %15
7363 %54 = OpLoad %42 %104
7364 %55 = OpLoad %46 %103
7365 %56 = OpSampledImage %50 %54 %55
7366 %57 = OpLoad %v2uint %15
7367 %58 = OpLoad %v2uint %15
7368 %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58
7369 OpStore %101 %59
7370 %69 = OpLoad %42 %104
7371 %70 = OpLoad %46 %103
7372 %71 = OpSampledImage %50 %69 %70
7373 %73 = OpLoad %v4float %100
7374 %74 = OpVectorShuffle %v2float %73 %73 0 0
7375 %75 = OpImageSampleImplicitLod %v4float %71 %74
7376 OpStore %101 %75
7377 OpReturn
7378 OpFunctionEnd
7379 )";
7380 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7381 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7382 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7383 EXPECT_THAT(
7384 getDiagnosticString(),
7385 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7386 }
7387
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADInvalidUseC)7388 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseC) {
7389 std::string text = R"(
7390 OpCapability Shader
7391 OpCapability TextureBlockMatchQCOM
7392 OpExtension "SPV_QCOM_image_processing"
7393 %1 = OpExtInstImport "GLSL.std.450"
7394 OpMemoryModel Logical GLSL450
7395 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7396 OpExecutionMode %2 OriginUpperLeft
7397 OpDecorate %3 Location 0
7398 OpDecorate %4 Location 0
7399 OpDecorate %5 DescriptorSet 0
7400 OpDecorate %5 Binding 4
7401 OpDecorate %6 DescriptorSet 0
7402 OpDecorate %6 Binding 5
7403 OpDecorate %5 BlockMatchTextureQCOM
7404 OpDecorate %6 BlockMatchTextureQCOM
7405 %void = OpTypeVoid
7406 %8 = OpTypeFunction %void
7407 %uint = OpTypeInt 32 0
7408 %v2uint = OpTypeVector %uint 2
7409 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7410 %float = OpTypeFloat 32
7411 %v4float = OpTypeVector %float 4
7412 %_ptr_Input_v4float = OpTypePointer Input %v4float
7413 %3 = OpVariable %_ptr_Input_v4float Input
7414 %uint_4 = OpConstant %uint 4
7415 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7416 %_ptr_Output_v4float = OpTypePointer Output %v4float
7417 %4 = OpVariable %_ptr_Output_v4float Output
7418 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7419 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7420 %20 = OpTypeSampledImage %18
7421 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7422 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7423 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7424 %v2float = OpTypeVector %float 2
7425 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7426 %2 = OpFunction %void None %8
7427 %24 = OpLabel
7428 %25 = OpVariable %_ptr_Function_v2uint Function
7429 OpStore %25 %16
7430 %26 = OpLoad %20 %5
7431 %27 = OpLoad %v2uint %25
7432 %28 = OpLoad %20 %6
7433 %29 = OpLoad %v2uint %25
7434 %30 = OpLoad %v2uint %25
7435 %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30
7436 OpStore %4 %31
7437 %32 = OpLoad %20 %5
7438 %33 = OpLoad %v4float %3
7439 %34 = OpVectorShuffle %v2float %33 %33 0 2
7440 %35 = OpImageSampleImplicitLod %v4float %32 %34
7441 OpStore %4 %35
7442 OpReturn
7443 OpFunctionEnd
7444 )";
7445 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7446 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7447 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7448 EXPECT_THAT(
7449 getDiagnosticString(),
7450 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7451 }
7452
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADInvalidUseD)7453 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseD) {
7454 std::string text = R"(
7455 OpCapability Shader
7456 OpCapability TextureBlockMatchQCOM
7457 OpExtension "SPV_QCOM_image_processing"
7458 %1 = OpExtInstImport "GLSL.std.450"
7459 OpMemoryModel Logical GLSL450
7460 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7461 OpExecutionMode %2 OriginUpperLeft
7462 OpDecorate %3 Location 0
7463 OpDecorate %4 Location 0
7464 OpDecorate %5 DescriptorSet 0
7465 OpDecorate %5 Binding 4
7466 OpDecorate %6 DescriptorSet 0
7467 OpDecorate %6 Binding 5
7468 OpDecorate %5 BlockMatchTextureQCOM
7469 OpDecorate %6 BlockMatchTextureQCOM
7470 %void = OpTypeVoid
7471 %8 = OpTypeFunction %void
7472 %uint = OpTypeInt 32 0
7473 %v2uint = OpTypeVector %uint 2
7474 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7475 %float = OpTypeFloat 32
7476 %v4float = OpTypeVector %float 4
7477 %_ptr_Input_v4float = OpTypePointer Input %v4float
7478 %3 = OpVariable %_ptr_Input_v4float Input
7479 %uint_4 = OpConstant %uint 4
7480 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7481 %_ptr_Output_v4float = OpTypePointer Output %v4float
7482 %4 = OpVariable %_ptr_Output_v4float Output
7483 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7484 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7485 %20 = OpTypeSampledImage %18
7486 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7487 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7488 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7489 %v2float = OpTypeVector %float 2
7490 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7491 %2 = OpFunction %void None %8
7492 %24 = OpLabel
7493 %25 = OpVariable %_ptr_Function_v2uint Function
7494 OpStore %25 %16
7495 %26 = OpLoad %20 %5
7496 %27 = OpLoad %v2uint %25
7497 %28 = OpLoad %20 %6
7498 %29 = OpLoad %v2uint %25
7499 %30 = OpLoad %v2uint %25
7500 %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30
7501 OpStore %4 %31
7502 %32 = OpLoad %20 %6
7503 %33 = OpLoad %v4float %3
7504 %34 = OpVectorShuffle %v2float %33 %33 0 2
7505 %35 = OpImageSampleImplicitLod %v4float %32 %34
7506 OpStore %4 %35
7507 OpReturn
7508 OpFunctionEnd
7509 )";
7510 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7511 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7512 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7513 EXPECT_THAT(
7514 getDiagnosticString(),
7515 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7516 }
7517
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDInvalidUseA)7518 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseA) {
7519 std::string text = R"(
7520 ; SPIR-V
7521 ; Version: 1.0
7522 ; Generator: Khronos Glslang Reference Front End; 11
7523 ; Bound: 79
7524 ; Schema: 0
7525 OpCapability Shader
7526 OpCapability TextureBlockMatchQCOM
7527 OpExtension "SPV_QCOM_image_processing"
7528 %1 = OpExtInstImport "GLSL.std.450"
7529 OpMemoryModel Logical GLSL450
7530 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7531 OpExecutionMode %main OriginUpperLeft
7532 OpDecorate %100 Location 0
7533 OpDecorate %101 Location 0
7534 OpDecorate %102 DescriptorSet 0
7535 OpDecorate %102 Binding 1
7536 OpDecorate %103 DescriptorSet 0
7537 OpDecorate %103 Binding 3
7538 OpDecorate %104 DescriptorSet 0
7539 OpDecorate %104 Binding 2
7540 OpDecorate %102 BlockMatchTextureQCOM
7541 OpDecorate %104 BlockMatchTextureQCOM
7542 %void = OpTypeVoid
7543 %3 = OpTypeFunction %void
7544 %uint = OpTypeInt 32 0
7545 %v2uint = OpTypeVector %uint 2
7546 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7547 %float = OpTypeFloat 32
7548 %v4float = OpTypeVector %float 4
7549 %_ptr_Input_v4float = OpTypePointer Input %v4float
7550 %100 = OpVariable %_ptr_Input_v4float Input
7551 %_ptr_Output_v4float = OpTypePointer Output %v4float
7552 %101 = OpVariable %_ptr_Output_v4float Output
7553 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7554 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7555 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7556 %46 = OpTypeSampler
7557 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7558 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7559 %50 = OpTypeSampledImage %42
7560 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7561 %v2float = OpTypeVector %float 2
7562 %main = OpFunction %void None %3
7563 %5 = OpLabel
7564 %15 = OpVariable %_ptr_Function_v2uint Function
7565 %45 = OpLoad %42 %102
7566 %49 = OpLoad %46 %103
7567 %51 = OpSampledImage %50 %45 %49
7568 %52 = OpLoad %v2uint %15
7569 %54 = OpLoad %42 %104
7570 %55 = OpLoad %46 %103
7571 %56 = OpSampledImage %50 %54 %55
7572 %57 = OpLoad %v2uint %15
7573 %58 = OpLoad %v2uint %15
7574 %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58
7575 OpStore %101 %59
7576 %69 = OpLoad %42 %102
7577 %70 = OpLoad %46 %103
7578 %71 = OpSampledImage %50 %69 %70
7579 %73 = OpLoad %v4float %100
7580 %74 = OpVectorShuffle %v2float %73 %73 0 0
7581 %75 = OpImageSampleImplicitLod %v4float %71 %74
7582 OpStore %101 %75
7583 OpReturn
7584 OpFunctionEnd
7585 )";
7586 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7587 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7588 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7589 EXPECT_THAT(
7590 getDiagnosticString(),
7591 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7592 }
7593
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDInvalidUseB)7594 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseB) {
7595 std::string text = R"(
7596 ; SPIR-V
7597 ; Version: 1.0
7598 ; Generator: Khronos Glslang Reference Front End; 11
7599 ; Bound: 79
7600 ; Schema: 0
7601 OpCapability Shader
7602 OpCapability TextureBlockMatchQCOM
7603 OpExtension "SPV_QCOM_image_processing"
7604 %1 = OpExtInstImport "GLSL.std.450"
7605 OpMemoryModel Logical GLSL450
7606 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7607 OpExecutionMode %main OriginUpperLeft
7608 OpDecorate %100 Location 0
7609 OpDecorate %101 Location 0
7610 OpDecorate %102 DescriptorSet 0
7611 OpDecorate %102 Binding 1
7612 OpDecorate %103 DescriptorSet 0
7613 OpDecorate %103 Binding 3
7614 OpDecorate %104 DescriptorSet 0
7615 OpDecorate %104 Binding 2
7616 OpDecorate %102 BlockMatchTextureQCOM
7617 OpDecorate %104 BlockMatchTextureQCOM
7618 %void = OpTypeVoid
7619 %3 = OpTypeFunction %void
7620 %uint = OpTypeInt 32 0
7621 %v2uint = OpTypeVector %uint 2
7622 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7623 %float = OpTypeFloat 32
7624 %v4float = OpTypeVector %float 4
7625 %_ptr_Input_v4float = OpTypePointer Input %v4float
7626 %100 = OpVariable %_ptr_Input_v4float Input
7627 %_ptr_Output_v4float = OpTypePointer Output %v4float
7628 %101 = OpVariable %_ptr_Output_v4float Output
7629 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7630 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7631 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7632 %46 = OpTypeSampler
7633 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7634 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7635 %50 = OpTypeSampledImage %42
7636 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7637 %v2float = OpTypeVector %float 2
7638 %main = OpFunction %void None %3
7639 %5 = OpLabel
7640 %15 = OpVariable %_ptr_Function_v2uint Function
7641 %45 = OpLoad %42 %102
7642 %49 = OpLoad %46 %103
7643 %51 = OpSampledImage %50 %45 %49
7644 %52 = OpLoad %v2uint %15
7645 %54 = OpLoad %42 %104
7646 %55 = OpLoad %46 %103
7647 %56 = OpSampledImage %50 %54 %55
7648 %57 = OpLoad %v2uint %15
7649 %58 = OpLoad %v2uint %15
7650 %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58
7651 OpStore %101 %59
7652 %69 = OpLoad %42 %104
7653 %70 = OpLoad %46 %103
7654 %71 = OpSampledImage %50 %69 %70
7655 %73 = OpLoad %v4float %100
7656 %74 = OpVectorShuffle %v2float %73 %73 0 0
7657 %75 = OpImageSampleImplicitLod %v4float %71 %74
7658 OpStore %101 %75
7659 OpReturn
7660 OpFunctionEnd
7661 )";
7662 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7663 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7664 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7665 EXPECT_THAT(
7666 getDiagnosticString(),
7667 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7668 }
7669
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDInvalidUseC)7670 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseC) {
7671 std::string text = R"(
7672 OpCapability Shader
7673 OpCapability TextureBlockMatchQCOM
7674 OpExtension "SPV_QCOM_image_processing"
7675 %1 = OpExtInstImport "GLSL.std.450"
7676 OpMemoryModel Logical GLSL450
7677 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7678 OpExecutionMode %2 OriginUpperLeft
7679 OpDecorate %3 Location 0
7680 OpDecorate %4 Location 0
7681 OpDecorate %5 DescriptorSet 0
7682 OpDecorate %5 Binding 4
7683 OpDecorate %6 DescriptorSet 0
7684 OpDecorate %6 Binding 5
7685 OpDecorate %5 BlockMatchTextureQCOM
7686 OpDecorate %6 BlockMatchTextureQCOM
7687 %void = OpTypeVoid
7688 %8 = OpTypeFunction %void
7689 %uint = OpTypeInt 32 0
7690 %v2uint = OpTypeVector %uint 2
7691 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7692 %float = OpTypeFloat 32
7693 %v4float = OpTypeVector %float 4
7694 %_ptr_Input_v4float = OpTypePointer Input %v4float
7695 %3 = OpVariable %_ptr_Input_v4float Input
7696 %uint_4 = OpConstant %uint 4
7697 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7698 %_ptr_Output_v4float = OpTypePointer Output %v4float
7699 %4 = OpVariable %_ptr_Output_v4float Output
7700 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7701 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7702 %20 = OpTypeSampledImage %18
7703 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7704 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7705 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7706 %v2float = OpTypeVector %float 2
7707 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7708 %2 = OpFunction %void None %8
7709 %24 = OpLabel
7710 %25 = OpVariable %_ptr_Function_v2uint Function
7711 OpStore %25 %16
7712 %26 = OpLoad %20 %5
7713 %27 = OpLoad %v2uint %25
7714 %28 = OpLoad %20 %6
7715 %29 = OpLoad %v2uint %25
7716 %30 = OpLoad %v2uint %25
7717 %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30
7718 OpStore %4 %31
7719 %32 = OpLoad %20 %5
7720 %33 = OpLoad %v4float %3
7721 %34 = OpVectorShuffle %v2float %33 %33 0 2
7722 %35 = OpImageSampleImplicitLod %v4float %32 %34
7723 OpStore %4 %35
7724 OpReturn
7725 OpFunctionEnd
7726 )";
7727 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7728 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7729 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7730 EXPECT_THAT(
7731 getDiagnosticString(),
7732 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7733 }
7734
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDInvalidUseD)7735 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseD) {
7736 std::string text = R"(
7737 OpCapability Shader
7738 OpCapability TextureBlockMatchQCOM
7739 OpExtension "SPV_QCOM_image_processing"
7740 %1 = OpExtInstImport "GLSL.std.450"
7741 OpMemoryModel Logical GLSL450
7742 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7743 OpExecutionMode %2 OriginUpperLeft
7744 OpDecorate %3 Location 0
7745 OpDecorate %4 Location 0
7746 OpDecorate %5 DescriptorSet 0
7747 OpDecorate %5 Binding 4
7748 OpDecorate %6 DescriptorSet 0
7749 OpDecorate %6 Binding 5
7750 OpDecorate %5 BlockMatchTextureQCOM
7751 OpDecorate %6 BlockMatchTextureQCOM
7752 %void = OpTypeVoid
7753 %8 = OpTypeFunction %void
7754 %uint = OpTypeInt 32 0
7755 %v2uint = OpTypeVector %uint 2
7756 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7757 %float = OpTypeFloat 32
7758 %v4float = OpTypeVector %float 4
7759 %_ptr_Input_v4float = OpTypePointer Input %v4float
7760 %3 = OpVariable %_ptr_Input_v4float Input
7761 %uint_4 = OpConstant %uint 4
7762 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7763 %_ptr_Output_v4float = OpTypePointer Output %v4float
7764 %4 = OpVariable %_ptr_Output_v4float Output
7765 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7766 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7767 %20 = OpTypeSampledImage %18
7768 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7769 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7770 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7771 %v2float = OpTypeVector %float 2
7772 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7773 %2 = OpFunction %void None %8
7774 %24 = OpLabel
7775 %25 = OpVariable %_ptr_Function_v2uint Function
7776 OpStore %25 %16
7777 %26 = OpLoad %20 %5
7778 %27 = OpLoad %v2uint %25
7779 %28 = OpLoad %20 %6
7780 %29 = OpLoad %v2uint %25
7781 %30 = OpLoad %v2uint %25
7782 %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30
7783 OpStore %4 %31
7784 %32 = OpLoad %20 %6
7785 %33 = OpLoad %v4float %3
7786 %34 = OpVectorShuffle %v2float %33 %33 0 2
7787 %35 = OpImageSampleImplicitLod %v4float %32 %34
7788 OpStore %4 %35
7789 OpReturn
7790 OpFunctionEnd
7791 )";
7792 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7793 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7794 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7795 EXPECT_THAT(
7796 getDiagnosticString(),
7797 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7798 }
7799
TEST_F(ValidateImage,QCOMImageProcessingSampleWeightedInvalidUseA)7800 TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseA) {
7801 std::string text = R"(
7802 OpCapability Shader
7803 OpCapability TextureSampleWeightedQCOM
7804 OpExtension "SPV_QCOM_image_processing"
7805 %1 = OpExtInstImport "GLSL.std.450"
7806 OpMemoryModel Logical GLSL450
7807 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7808 OpExecutionMode %2 OriginUpperLeft
7809 OpDecorate %3 Location 0
7810 OpDecorate %4 Location 0
7811 OpDecorate %5 DescriptorSet 0
7812 OpDecorate %5 Binding 4
7813 OpDecorate %6 DescriptorSet 0
7814 OpDecorate %6 Binding 5
7815 OpDecorate %6 WeightTextureQCOM
7816 %void = OpTypeVoid
7817 %8 = OpTypeFunction %void
7818 %float = OpTypeFloat 32
7819 %v4float = OpTypeVector %float 4
7820 %_ptr_Output_v4float = OpTypePointer Output %v4float
7821 %3 = OpVariable %_ptr_Output_v4float Output
7822 %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
7823 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
7824 %14 = OpTypeSampledImage %12
7825 %_ptr_Input_v4float = OpTypePointer Input %v4float
7826 %4 = OpVariable %_ptr_Input_v4float Input
7827 %v2float = OpTypeVector %float 2
7828 %17 = OpTypeImage %float 2D 0 1 0 1 Unknown
7829 %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
7830 %19 = OpTypeSampledImage %17
7831 %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
7832 %5 = OpVariable %_ptr_UniformConstant_14 UniformConstant
7833 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7834 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7835 %v3float = OpTypeVector %float 3
7836 %2 = OpFunction %void None %8
7837 %23 = OpLabel
7838 %24 = OpLoad %v4float %4
7839 %25 = OpVectorShuffle %v2float %24 %24 0 1
7840 %26 = OpLoad %14 %5
7841 %27 = OpLoad %v4float %4
7842 %28 = OpVectorShuffle %v2float %27 %27 0 1
7843 %29 = OpLoad %19 %6
7844 %30 = OpImageSampleWeightedQCOM %v4float %26 %28 %29
7845 OpStore %3 %30
7846 %31 = OpLoad %19 %6
7847 %32 = OpLoad %v4float %4
7848 %33 = OpVectorShuffle %v3float %32 %32 0 1 0
7849 %34 = OpCompositeExtract %float %33 0
7850 %35 = OpCompositeExtract %float %33 1
7851 %36 = OpCompositeExtract %float %33 2
7852 %37 = OpCompositeConstruct %v3float %34 %35 %36
7853 %38 = OpImageSampleImplicitLod %v4float %31 %37
7854 OpStore %3 %38
7855 OpReturn
7856 OpFunctionEnd
7857 )";
7858 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7859 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7860 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7861 EXPECT_THAT(
7862 getDiagnosticString(),
7863 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7864 }
7865
TEST_F(ValidateImage,QCOMImageProcessingSampleWeightedInvalidUseB)7866 TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseB) {
7867 std::string text = R"(
7868 OpCapability Shader
7869 OpCapability TextureSampleWeightedQCOM
7870 OpExtension "SPV_QCOM_image_processing"
7871 %1 = OpExtInstImport "GLSL.std.450"
7872 OpMemoryModel Logical GLSL450
7873 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7
7874 OpExecutionMode %2 OriginUpperLeft
7875 OpDecorate %3 Location 0
7876 OpDecorate %5 DescriptorSet 0
7877 OpDecorate %5 Binding 1
7878 OpDecorate %6 DescriptorSet 0
7879 OpDecorate %6 Binding 3
7880 OpDecorate %4 Location 0
7881 OpDecorate %7 DescriptorSet 0
7882 OpDecorate %7 Binding 0
7883 OpDecorate %7 WeightTextureQCOM
7884 %void = OpTypeVoid
7885 %9 = OpTypeFunction %void
7886 %float = OpTypeFloat 32
7887 %v4float = OpTypeVector %float 4
7888 %_ptr_Output_v4float = OpTypePointer Output %v4float
7889 %3 = OpVariable %_ptr_Output_v4float Output
7890 %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
7891 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
7892 %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
7893 %15 = OpTypeSampler
7894 %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
7895 %6 = OpVariable %_ptr_UniformConstant_15 UniformConstant
7896 %17 = OpTypeSampledImage %13
7897 %_ptr_Input_v4float = OpTypePointer Input %v4float
7898 %4 = OpVariable %_ptr_Input_v4float Input
7899 %v2float = OpTypeVector %float 2
7900 %20 = OpTypeImage %float 2D 0 1 0 1 Unknown
7901 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7902 %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7903 %22 = OpTypeSampledImage %20
7904 %v3float = OpTypeVector %float 3
7905 %2 = OpFunction %void None %9
7906 %24 = OpLabel
7907 %25 = OpLoad %13 %5
7908 %26 = OpLoad %15 %6
7909 %27 = OpSampledImage %17 %25 %26
7910 %28 = OpLoad %v4float %4
7911 %29 = OpVectorShuffle %v2float %28 %28 0 1
7912 %30 = OpLoad %20 %7
7913 %31 = OpLoad %15 %6
7914 %32 = OpSampledImage %22 %30 %31
7915 %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32
7916 OpStore %3 %33
7917 %34 = OpLoad %20 %7
7918 %35 = OpLoad %15 %6
7919 %36 = OpSampledImage %22 %34 %35
7920 %37 = OpLoad %v4float %4
7921 %38 = OpVectorShuffle %v3float %37 %37 0 1 0
7922 %39 = OpCompositeExtract %float %38 0
7923 %40 = OpCompositeExtract %float %38 1
7924 %41 = OpCompositeExtract %float %38 2
7925 %42 = OpCompositeConstruct %v3float %39 %40 %41
7926 %43 = OpImageSampleImplicitLod %v4float %36 %42
7927 OpStore %3 %43
7928 OpReturn
7929 OpFunctionEnd
7930 )";
7931 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7932 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7933 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7934 EXPECT_THAT(
7935 getDiagnosticString(),
7936 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7937 }
7938
TEST_F(ValidateImage,ImageMSArray_ArrayedSampledTypeRequiresCapability)7939 TEST_F(ValidateImage, ImageMSArray_ArrayedSampledTypeRequiresCapability) {
7940 const std::string code = R"(
7941 OpCapability Shader
7942 OpCapability StorageImageMultisample
7943 OpCapability StorageImageReadWithoutFormat
7944 OpMemoryModel Logical GLSL450
7945 OpEntryPoint Fragment %main "main"
7946 OpExecutionMode %main OriginUpperLeft
7947 OpDecorate %var_image DescriptorSet 0
7948 OpDecorate %var_image Binding 1
7949 %void = OpTypeVoid
7950 %func = OpTypeFunction %void
7951 %f32 = OpTypeFloat 32
7952 %u32 = OpTypeInt 32 0
7953 %uint_2 = OpConstant %u32 2
7954 %uint_1 = OpConstant %u32 1
7955 %v2uint = OpTypeVector %u32 2
7956 %v4float = OpTypeVector %f32 4
7957 %image = OpTypeImage %f32 2D 2 1 1 2 Unknown
7958 %ptr_image = OpTypePointer UniformConstant %image
7959 %10 = OpConstantComposite %v2uint %uint_1 %uint_2
7960 %var_image = OpVariable %ptr_image UniformConstant
7961 %main = OpFunction %void None %func
7962 %main_lab = OpLabel
7963 %18 = OpLoad %image %var_image
7964 %19 = OpImageRead %v4float %18 %10 Sample %uint_2
7965 OpReturn
7966 OpFunctionEnd
7967 )";
7968
7969 const spv_target_env env = SPV_ENV_VULKAN_1_0;
7970 CompileSuccessfully(code, env);
7971 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
7972 EXPECT_THAT(
7973 getDiagnosticString(),
7974 HasSubstr("Capability ImageMSArray is required to access storage image"));
7975 }
7976
TEST_F(ValidateImage,ImageMSArray_SampledTypeDoesNotRequireCapability)7977 TEST_F(ValidateImage, ImageMSArray_SampledTypeDoesNotRequireCapability) {
7978 const std::string code = R"(
7979 OpCapability Shader
7980 OpCapability StorageImageMultisample
7981 OpCapability StorageImageReadWithoutFormat
7982 OpMemoryModel Logical GLSL450
7983 OpEntryPoint Fragment %main "main"
7984 OpExecutionMode %main OriginUpperLeft
7985 OpDecorate %var_image DescriptorSet 0
7986 OpDecorate %var_image Binding 1
7987 %void = OpTypeVoid
7988 %func = OpTypeFunction %void
7989 %f32 = OpTypeFloat 32
7990 %u32 = OpTypeInt 32 0
7991 %uint_2 = OpConstant %u32 2
7992 %uint_1 = OpConstant %u32 1
7993 %v2uint = OpTypeVector %u32 2
7994 %v4float = OpTypeVector %f32 4
7995 %image = OpTypeImage %f32 2D 2 0 1 2 Unknown
7996 %ptr_image = OpTypePointer UniformConstant %image
7997 %10 = OpConstantComposite %v2uint %uint_1 %uint_2
7998 %var_image = OpVariable %ptr_image UniformConstant
7999 %main = OpFunction %void None %func
8000 %main_lab = OpLabel
8001 %18 = OpLoad %image %var_image
8002 %19 = OpImageRead %v4float %18 %10 Sample %uint_2
8003 OpReturn
8004 OpFunctionEnd
8005 )";
8006
8007 const spv_target_env env = SPV_ENV_VULKAN_1_0;
8008 CompileSuccessfully(code, env);
8009 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
8010 EXPECT_THAT(getDiagnosticString(), Eq(""));
8011 }
8012
TEST_F(ValidateImage,ImageMSArray_ArrayedTypeDoesNotRequireCapability)8013 TEST_F(ValidateImage, ImageMSArray_ArrayedTypeDoesNotRequireCapability) {
8014 const std::string code = R"(
8015 OpCapability Shader
8016 OpCapability StorageImageReadWithoutFormat
8017 OpMemoryModel Logical GLSL450
8018 OpEntryPoint Fragment %main "main"
8019 OpExecutionMode %main OriginUpperLeft
8020 OpDecorate %var_image DescriptorSet 0
8021 OpDecorate %var_image Binding 1
8022 %void = OpTypeVoid
8023 %func = OpTypeFunction %void
8024 %f32 = OpTypeFloat 32
8025 %u32 = OpTypeInt 32 0
8026 %uint_3 = OpConstant %u32 3
8027 %uint_2 = OpConstant %u32 2
8028 %uint_1 = OpConstant %u32 1
8029 %v3uint = OpTypeVector %u32 3
8030 %v4float = OpTypeVector %f32 4
8031 %image = OpTypeImage %f32 2D 2 1 0 2 Unknown
8032 %ptr_image = OpTypePointer UniformConstant %image
8033 %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
8034 %var_image = OpVariable %ptr_image UniformConstant
8035 %main = OpFunction %void None %func
8036 %main_lab = OpLabel
8037 %18 = OpLoad %image %var_image
8038 %19 = OpImageRead %v4float %18 %10
8039 OpReturn
8040 OpFunctionEnd
8041 )";
8042
8043 const spv_target_env env = SPV_ENV_VULKAN_1_0;
8044 CompileSuccessfully(code, env);
8045 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
8046 EXPECT_THAT(getDiagnosticString(), Eq(""));
8047 }
8048
8049 } // namespace
8050 } // namespace val
8051 } // namespace spvtools
8052