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,TypeImageDimRectVulkan)789 TEST_F(ValidateImage, TypeImageDimRectVulkan) {
790 const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
791 R"(
792 %img_type = OpTypeImage %f32 Rect 0 1 0 2 Unknown
793 )" + TrivialMain();
794
795 CompileSuccessfully(code.c_str());
796 ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY,
797 ValidateInstructions(SPV_ENV_VULKAN_1_0));
798 // Can't actually hit VUID-StandaloneSpirv-OpTypeImage-09638
799 EXPECT_THAT(
800 getDiagnosticString(),
801 AnyVUID("TypeImage requires one of these capabilities: SampledRect"));
802 }
803
TEST_F(ValidateImage,TypeImageWrongSampledTypeForTileImageDataEXT)804 TEST_F(ValidateImage, TypeImageWrongSampledTypeForTileImageDataEXT) {
805 const std::string code = GetShaderHeader(
806 "OpCapability TileImageColorReadAccessEXT\n"
807 "OpExtension \"SPV_EXT_shader_tile_image\"\n",
808 false) +
809 R"(
810 %img_type = OpTypeImage %void TileImageDataEXT 0 0 0 2 Unknown
811 )";
812
813 CompileSuccessfully(code.c_str());
814 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
815 EXPECT_THAT(
816 getDiagnosticString(),
817 HasSubstr(
818 "Dim TileImageDataEXT requires Sampled Type to be not OpTypeVoid"));
819 }
820
TEST_F(ValidateImage,TypeImageWrongSampledForTileImageDataEXT)821 TEST_F(ValidateImage, TypeImageWrongSampledForTileImageDataEXT) {
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 1 Unknown
828 )";
829
830 CompileSuccessfully(code.c_str());
831 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
832 EXPECT_THAT(getDiagnosticString(),
833 HasSubstr("Dim TileImageDataEXT requires Sampled to be 2"));
834 }
835
TEST_F(ValidateImage,TypeImageWrongFormatForTileImageDataEXT)836 TEST_F(ValidateImage, TypeImageWrongFormatForTileImageDataEXT) {
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 0 0 0 2 Rgba32f
843 )";
844
845 CompileSuccessfully(code.c_str());
846 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
847 EXPECT_THAT(getDiagnosticString(),
848 HasSubstr("Dim TileImageDataEXT requires format Unknown"));
849 }
850
TEST_F(ValidateImage,TypeImageWrongDepthForTileImageDataEXT)851 TEST_F(ValidateImage, TypeImageWrongDepthForTileImageDataEXT) {
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 1 0 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 Depth to be 0"));
864 }
865
TEST_F(ValidateImage,TypeImageWrongArrayedForTileImageDataEXT)866 TEST_F(ValidateImage, TypeImageWrongArrayedForTileImageDataEXT) {
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 1 0 2 Unknown
873 )";
874
875 CompileSuccessfully(code.c_str());
876 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
877 EXPECT_THAT(getDiagnosticString(),
878 HasSubstr("Dim TileImageDataEXT requires Arrayed to be 0"));
879 }
880
TEST_F(ValidateImage,TypeSampledImage_TileImageDataEXT_Error)881 TEST_F(ValidateImage, TypeSampledImage_TileImageDataEXT_Error) {
882 const std::string code = GetShaderHeader(
883 "OpCapability TileImageColorReadAccessEXT\n"
884 "OpExtension \"SPV_EXT_shader_tile_image\"\n",
885 false) +
886 R"(
887 %img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
888 %simg_type = OpTypeSampledImage %img_type
889 )";
890
891 CompileSuccessfully(code.c_str());
892 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
893 EXPECT_THAT(getDiagnosticString(),
894 HasSubstr("Sampled image type requires an image type with "
895 "\"Sampled\" operand set to 0 or 1"));
896 }
897
TEST_F(ValidateImage,ImageTexelPointerImageDimTileImageDataEXTBad)898 TEST_F(ValidateImage, ImageTexelPointerImageDimTileImageDataEXTBad) {
899 const std::string body = R"(
900 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %tile_image_u32_tid_0002 %u32_0 %u32_0
901 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
902 )";
903 const std::string decl = R"(
904 %type_image_u32_tid_0002 = OpTypeImage %u32 TileImageDataEXT 0 0 0 2 Unknown
905 %ptr_image_u32_tid_0002 = OpTypePointer TileImageEXT %type_image_u32_tid_0002
906 %tile_image_u32_tid_0002 = OpVariable %ptr_image_u32_tid_0002 TileImageEXT
907 )";
908
909 const std::string extra = R"(
910 OpCapability TileImageColorReadAccessEXT
911 OpExtension "SPV_EXT_shader_tile_image"
912 )";
913
914 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
915 SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
916 .c_str());
917 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
918 EXPECT_THAT(getDiagnosticString(),
919 HasSubstr("Image Dim TileImageDataEXT cannot be used with "
920 "OpImageTexelPointer"));
921 }
922
TEST_F(ValidateImage,ReadTileImageDataEXT)923 TEST_F(ValidateImage, ReadTileImageDataEXT) {
924 const std::string body = R"(
925 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
926 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
927 )";
928
929 const std::string decl = R"(
930 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
931 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
932 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
933 )";
934
935 const std::string extra = R"(
936 OpCapability StorageImageReadWithoutFormat
937 OpCapability TileImageColorReadAccessEXT
938 OpExtension "SPV_EXT_shader_tile_image"
939 )";
940
941 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
942 SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
943 .c_str());
944 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
945 EXPECT_THAT(
946 getDiagnosticString(),
947 HasSubstr("Image Dim TileImageDataEXT cannot be used with ImageRead"));
948 }
949
TEST_F(ValidateImage,WriteTileImageDataEXT)950 TEST_F(ValidateImage, WriteTileImageDataEXT) {
951 const std::string body = R"(
952 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
953 OpImageWrite %img %u32vec2_01 %f32vec4_0000
954 )";
955
956 const std::string decl = R"(
957 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
958 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
959 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
960 )";
961
962 const std::string extra = R"(
963 OpCapability TileImageColorReadAccessEXT
964 OpExtension "SPV_EXT_shader_tile_image"
965 )";
966
967 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
968 SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
969 .c_str());
970 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
971 EXPECT_THAT(getDiagnosticString(),
972 HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
973 }
974
TEST_F(ValidateImage,QueryFormatTileImageDataEXT)975 TEST_F(ValidateImage, QueryFormatTileImageDataEXT) {
976 const std::string body = R"(
977 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
978 %res1 = OpImageQueryFormat %u32 %img
979 )";
980
981 const std::string decl = R"(
982 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
983 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
984 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
985 )";
986
987 const std::string extra = R"(
988 OpCapability TileImageColorReadAccessEXT
989 OpExtension "SPV_EXT_shader_tile_image"
990 )";
991
992 CompileSuccessfully(GenerateKernelCode(body, extra, decl).c_str());
993
994 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
995 EXPECT_THAT(getDiagnosticString(),
996 HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
997 }
998
TEST_F(ValidateImage,QueryOrderTileImageDataEXT)999 TEST_F(ValidateImage, QueryOrderTileImageDataEXT) {
1000 const std::string body = R"(
1001 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
1002 %res1 = OpImageQueryOrder %u32 %img
1003 )";
1004
1005 const std::string decl = R"(
1006 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
1007 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
1008 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
1009 )";
1010
1011 const std::string extra = R"(
1012 OpCapability TileImageColorReadAccessEXT
1013 OpExtension "SPV_EXT_shader_tile_image"
1014 )";
1015
1016 CompileSuccessfully(GenerateKernelCode(body, extra, decl).c_str());
1017
1018 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1019 EXPECT_THAT(getDiagnosticString(),
1020 HasSubstr("Image 'Dim' cannot be TileImageDataEXT"));
1021 }
1022
TEST_F(ValidateImage,SparseFetchTileImageDataEXT)1023 TEST_F(ValidateImage, SparseFetchTileImageDataEXT) {
1024 const std::string body = R"(
1025 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
1026 %res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
1027 )";
1028
1029 const std::string decl = R"(
1030 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
1031 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
1032 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
1033 )";
1034
1035 const std::string extra = R"(
1036 OpCapability StorageImageReadWithoutFormat
1037 OpCapability TileImageColorReadAccessEXT
1038 OpExtension "SPV_EXT_shader_tile_image"
1039 )";
1040
1041 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1042 SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
1043 .c_str());
1044 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1045 EXPECT_THAT(getDiagnosticString(),
1046 HasSubstr("Expected Image 'Sampled' parameter to be 1"));
1047 }
1048
TEST_F(ValidateImage,SparseReadTileImageDataEXT)1049 TEST_F(ValidateImage, SparseReadTileImageDataEXT) {
1050 const std::string body = R"(
1051 %img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002
1052 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
1053 )";
1054
1055 const std::string decl = R"(
1056 %type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown
1057 %ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002
1058 %uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant
1059 )";
1060
1061 const std::string extra = R"(
1062 OpCapability StorageImageReadWithoutFormat
1063 OpCapability TileImageColorReadAccessEXT
1064 OpExtension "SPV_EXT_shader_tile_image"
1065 )";
1066
1067 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1068 SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl)
1069 .c_str());
1070 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1071 EXPECT_THAT(
1072 getDiagnosticString(),
1073 HasSubstr(
1074 "Image Dim TileImageDataEXT cannot be used with ImageSparseRead"));
1075 }
1076
TEST_F(ValidateImage,TypeImage_OpenCL_Sampled0_OK)1077 TEST_F(ValidateImage, TypeImage_OpenCL_Sampled0_OK) {
1078 const std::string code = GetKernelHeader() + R"(
1079 %img_type = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
1080 )";
1081
1082 CompileSuccessfully(code.c_str());
1083 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1084 EXPECT_THAT(getDiagnosticString(), Eq(""));
1085 }
1086
TEST_F(ValidateImage,TypeImage_OpenCL_Sampled1_Invalid)1087 TEST_F(ValidateImage, TypeImage_OpenCL_Sampled1_Invalid) {
1088 const std::string code = GetKernelHeader() + R"(
1089 %img_type = OpTypeImage %void 2D 0 0 0 1 Unknown ReadOnly
1090 )";
1091
1092 CompileSuccessfully(code.c_str());
1093 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1094 EXPECT_THAT(getDiagnosticString(),
1095 HasSubstr("Sampled must be 0 in the OpenCL environment."));
1096 }
1097
TEST_F(ValidateImage,TypeImage_OpenCL_Sampled2_Invalid)1098 TEST_F(ValidateImage, TypeImage_OpenCL_Sampled2_Invalid) {
1099 const std::string code = GetKernelHeader() + R"(
1100 %img_type = OpTypeImage %void 2D 0 0 0 2 Unknown ReadOnly
1101 )";
1102
1103 CompileSuccessfully(code.c_str());
1104 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1105 EXPECT_THAT(getDiagnosticString(),
1106 HasSubstr("Sampled must be 0 in the OpenCL environment."));
1107 }
1108
TEST_F(ValidateImage,TypeImage_OpenCL_AccessQualifierMissing)1109 TEST_F(ValidateImage, TypeImage_OpenCL_AccessQualifierMissing) {
1110 const std::string code = GetKernelHeader() + R"(
1111 %img_type = OpTypeImage %void 2D 0 0 0 0 Unknown
1112 )";
1113
1114 CompileSuccessfully(code.c_str());
1115 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_2_1));
1116 EXPECT_THAT(getDiagnosticString(),
1117 HasSubstr("In the OpenCL environment, the optional Access "
1118 "Qualifier must be present"));
1119 }
1120
TEST_F(ValidateImage,TypeImage_Vulkan_Sampled1_OK)1121 TEST_F(ValidateImage, TypeImage_Vulkan_Sampled1_OK) {
1122 const std::string code = GetShaderHeader() + R"(
1123 %img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown
1124 )" + TrivialMain();
1125
1126 CompileSuccessfully(code.c_str());
1127 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1128 EXPECT_THAT(getDiagnosticString(), Eq(""));
1129 }
1130
TEST_F(ValidateImage,TypeImage_Vulkan_Sampled2_OK)1131 TEST_F(ValidateImage, TypeImage_Vulkan_Sampled2_OK) {
1132 const std::string code = GetShaderHeader() + R"(
1133 %img_type = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
1134 )" + TrivialMain();
1135
1136 CompileSuccessfully(code.c_str());
1137 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1138 EXPECT_THAT(getDiagnosticString(), Eq(""));
1139 }
1140
TEST_F(ValidateImage,TypeImage_Vulkan_Sampled0_Invalid)1141 TEST_F(ValidateImage, TypeImage_Vulkan_Sampled0_Invalid) {
1142 const std::string code = GetShaderHeader() + R"(
1143 %img_type = OpTypeImage %f32 2D 0 0 0 0 Unknown
1144 )" + TrivialMain();
1145
1146 CompileSuccessfully(code.c_str());
1147 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1148 EXPECT_THAT(getDiagnosticString(),
1149 AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
1150 EXPECT_THAT(getDiagnosticString(),
1151 HasSubstr("Sampled must be 1 or 2 in the Vulkan environment."));
1152 }
1153
TEST_F(ValidateImage,TypeImageWrongFormatForSubpassData)1154 TEST_F(ValidateImage, TypeImageWrongFormatForSubpassData) {
1155 const std::string code =
1156 GetShaderHeader("OpCapability InputAttachment\n", false) +
1157 R"(
1158 %img_type = OpTypeImage %f32 SubpassData 0 0 0 2 Rgba32f
1159 )";
1160
1161 CompileSuccessfully(code.c_str());
1162 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1163 EXPECT_THAT(getDiagnosticString(),
1164 HasSubstr("Dim SubpassData requires format Unknown"));
1165 }
1166
TEST_F(ValidateImage,TypeImageMultisampleStorageImage_MissingCapability)1167 TEST_F(ValidateImage, TypeImageMultisampleStorageImage_MissingCapability) {
1168 const std::string code = GetShaderHeader("", false) +
1169 R"(
1170 %img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
1171 )";
1172
1173 CompileSuccessfully(code.c_str());
1174 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()) << code;
1175 EXPECT_THAT(getDiagnosticString(),
1176 HasSubstr("Capability StorageImageMultisample is required when "
1177 "using multisampled storage image"));
1178 }
1179
TEST_F(ValidateImage,TypeImageMultisampleStorageImage_UsesCapability)1180 TEST_F(ValidateImage, TypeImageMultisampleStorageImage_UsesCapability) {
1181 const std::string code =
1182 GetShaderHeader("OpCapability StorageImageMultisample\n", false) +
1183 R"(
1184 %img_type = OpTypeImage %f32 2D 0 0 1 2 Rgba32f
1185 )";
1186
1187 CompileSuccessfully(code.c_str());
1188 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
1189 EXPECT_THAT(getDiagnosticString(), Eq(""));
1190 }
1191
TEST_F(ValidateImage,TypeImageMultisampleSubpassData_OK)1192 TEST_F(ValidateImage, TypeImageMultisampleSubpassData_OK) {
1193 const std::string code =
1194 GetShaderHeader("OpCapability InputAttachment\n", false) +
1195 R"(
1196 %img_type = OpTypeImage %f32 SubpassData 0 0 1 2 Unknown
1197 )";
1198
1199 CompileSuccessfully(code.c_str());
1200 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << code;
1201 EXPECT_THAT(getDiagnosticString(), Eq(""));
1202 }
1203
TEST_F(ValidateImage,TypeSampledImage_NotImage_Error)1204 TEST_F(ValidateImage, TypeSampledImage_NotImage_Error) {
1205 const std::string code = GetShaderHeader("", false) + R"(
1206 %simg_type = OpTypeSampledImage %f32
1207 )";
1208
1209 CompileSuccessfully(code.c_str());
1210 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1211 EXPECT_THAT(getDiagnosticString(),
1212 HasSubstr("Expected Image to be of type OpTypeImage"));
1213 }
1214
TEST_F(ValidateImage,TypeSampledImage_Sampled0_Success)1215 TEST_F(ValidateImage, TypeSampledImage_Sampled0_Success) {
1216 // This is ok in the OpenCL and universal environments.
1217 // Vulkan will reject an OpTypeImage with Sampled=0, checked elsewhere.
1218 const std::string code = GetShaderHeader() + R"(
1219 %imty = OpTypeImage %f32 2D 0 0 0 0 Unknown
1220 %simg_type = OpTypeSampledImage %imty
1221 )" + TrivialMain();
1222
1223 CompileSuccessfully(code.c_str());
1224 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1225 EXPECT_EQ(getDiagnosticString(), "");
1226 }
1227
TEST_F(ValidateImage,TypeSampledImage_Sampled2_Error)1228 TEST_F(ValidateImage, TypeSampledImage_Sampled2_Error) {
1229 const std::string code = GetShaderHeader() + R"(
1230 %storage_image = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
1231 %simg_type = OpTypeSampledImage %storage_image
1232 )" + TrivialMain();
1233
1234 CompileSuccessfully(code.c_str());
1235 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1236 EXPECT_THAT(getDiagnosticString(),
1237 HasSubstr("Sampled image type requires an image type with "
1238 "\"Sampled\" operand set to 0 or 1"));
1239 }
1240
TEST_F(ValidateImage,TypeSampledImage_Sampled1_Success)1241 TEST_F(ValidateImage, TypeSampledImage_Sampled1_Success) {
1242 const std::string code = GetShaderHeader() + R"(
1243 %im = OpTypeImage %f32 2D 0 0 0 1 Unknown
1244 %simg_type = OpTypeSampledImage %im
1245 )" + TrivialMain();
1246
1247 CompileSuccessfully(code.c_str());
1248 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1249 EXPECT_EQ(getDiagnosticString(), "");
1250 }
1251
TEST_F(ValidateImage,SampledImageSuccess)1252 TEST_F(ValidateImage, SampledImageSuccess) {
1253 const std::string body = R"(
1254 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1255 %sampler = OpLoad %type_sampler %uniform_sampler
1256 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1257 )";
1258
1259 CompileSuccessfully(GenerateShaderCode(body).c_str());
1260 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1261 }
1262
TEST_F(ValidateImage,SampledImageVulkanSuccess)1263 TEST_F(ValidateImage, SampledImageVulkanSuccess) {
1264 const std::string body = R"(
1265 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1266 %sampler = OpLoad %type_sampler %uniform_sampler
1267 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1268 )";
1269
1270 const spv_target_env env = SPV_ENV_VULKAN_1_0;
1271 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
1272 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
1273 }
1274
TEST_F(ValidateImage,SampledImageWrongResultType)1275 TEST_F(ValidateImage, SampledImageWrongResultType) {
1276 const std::string body = R"(
1277 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1278 %sampler = OpLoad %type_sampler %uniform_sampler
1279 %simg = OpSampledImage %type_image_f32_2d_0001 %img %sampler
1280 )";
1281
1282 CompileSuccessfully(GenerateShaderCode(body).c_str());
1283 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1284 EXPECT_THAT(getDiagnosticString(),
1285 HasSubstr("Expected Result Type to be OpTypeSampledImage"));
1286 }
1287
TEST_F(ValidateImage,SampledImageNotImage)1288 TEST_F(ValidateImage, SampledImageNotImage) {
1289 const std::string body = R"(
1290 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1291 %sampler = OpLoad %type_sampler %uniform_sampler
1292 %simg1 = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1293 %simg2 = OpSampledImage %type_sampled_image_f32_2d_0001 %simg1 %sampler
1294 )";
1295
1296 CompileSuccessfully(GenerateShaderCode(body).c_str());
1297 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1298 EXPECT_THAT(getDiagnosticString(),
1299 HasSubstr("Expected Image to be of type OpTypeImage"));
1300 }
1301
TEST_F(ValidateImage,SampledImageImageNotForSampling)1302 TEST_F(ValidateImage, SampledImageImageNotForSampling) {
1303 const std::string code = GetShaderHeader() + R"(
1304 %im_ty = OpTypeImage %f32 2D 0 0 0 2 Unknown
1305 %sampler_ty = OpTypeSampler
1306 %sampled_image_ty = OpTypeSampledImage %im_ty ; will fail here first!
1307
1308 %ptr_im_ty = OpTypePointer UniformConstant %im_ty
1309 %var_im = OpVariable %ptr_im_ty UniformConstant
1310
1311 %ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
1312 %var_sampler = OpVariable %ptr_sampler_ty UniformConstant
1313
1314 %main = OpFunction %void None %func
1315 %entry = OpLabel
1316 %im = OpLoad %im_ty %var_im
1317 %sampler = OpLoad %sampler_ty %var_sampler
1318 %sampled_image = OpSampledImage %sampled_image_ty %im %sampler
1319 OpReturn
1320 OpFunctionEnd
1321 )";
1322
1323 CompileSuccessfully(code.c_str());
1324 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1325 EXPECT_THAT(getDiagnosticString(),
1326 HasSubstr("Sampled image type requires an image type with "
1327 "\"Sampled\" operand set to 0 or 1"))
1328 << code;
1329 }
1330
TEST_F(ValidateImage,SampledImageNotSampler)1331 TEST_F(ValidateImage, SampledImageNotSampler) {
1332 const std::string body = R"(
1333 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1334 %sampler = OpLoad %type_sampler %uniform_sampler
1335 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %img
1336 )";
1337
1338 CompileSuccessfully(GenerateShaderCode(body).c_str());
1339 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1340 EXPECT_THAT(getDiagnosticString(),
1341 HasSubstr("Expected Sampler to be of type OpTypeSampler"));
1342 }
1343
TEST_F(ValidateImage,SampledImageIsStorage)1344 TEST_F(ValidateImage, SampledImageIsStorage) {
1345 const std::string declarations = R"(
1346 %type_sampled_image_f32_2d_0002 = OpTypeSampledImage %type_image_f32_2d_0002
1347 )";
1348 const std::string body = R"(
1349 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
1350 %sampler = OpLoad %type_sampler %uniform_sampler
1351 %simg = OpSampledImage %type_sampled_image_f32_2d_0002 %img %sampler
1352 )";
1353
1354 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "",
1355 SPV_ENV_UNIVERSAL_1_0, "GLSL450",
1356 declarations)
1357 .c_str());
1358 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1359 EXPECT_THAT(getDiagnosticString(),
1360 HasSubstr("Sampled image type requires an image type with "
1361 "\"Sampled\" operand set to 0 or 1"));
1362 }
1363
TEST_F(ValidateImage,ImageTexelPointerSuccess)1364 TEST_F(ValidateImage, ImageTexelPointerSuccess) {
1365 const std::string body = R"(
1366 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1367 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1368 )";
1369
1370 CompileSuccessfully(GenerateShaderCode(body).c_str());
1371 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1372 }
1373
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotPointer)1374 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotPointer) {
1375 const std::string body = R"(
1376 %texel_ptr = OpImageTexelPointer %type_image_u32_buffer_0002_r32ui %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1377 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1378 )";
1379
1380 CompileSuccessfully(GenerateShaderCode(body).c_str());
1381 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1382 EXPECT_THAT(getDiagnosticString(),
1383 HasSubstr("Expected Result Type to be OpTypePointer"));
1384 }
1385
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotImageClass)1386 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotImageClass) {
1387 const std::string body = R"(
1388 %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1389 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1390 )";
1391
1392 CompileSuccessfully(GenerateShaderCode(body).c_str());
1393 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1394 EXPECT_THAT(getDiagnosticString(),
1395 HasSubstr("Expected Result Type to be OpTypePointer whose "
1396 "Storage Class operand is Image"));
1397 }
1398
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotNumericNorVoid)1399 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotNumericNorVoid) {
1400 const std::string body = R"(
1401 %texel_ptr = OpImageTexelPointer %ptr_Image_u32arr4 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
1402 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1403 )";
1404
1405 CompileSuccessfully(GenerateShaderCode(body).c_str());
1406 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1407 EXPECT_THAT(
1408 getDiagnosticString(),
1409 HasSubstr("Expected Result Type to be OpTypePointer whose Type operand "
1410 "must be a scalar numerical type or OpTypeVoid"));
1411 }
1412
TEST_F(ValidateImage,ImageTexelPointerImageNotResultTypePointer)1413 TEST_F(ValidateImage, ImageTexelPointerImageNotResultTypePointer) {
1414 const std::string body = R"(
1415 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %type_image_f32_buffer_0002_r32ui %u32_0 %u32_0
1416 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1417 )";
1418
1419 CompileSuccessfully(GenerateShaderCode(body).c_str());
1420 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
1421 EXPECT_THAT(getDiagnosticString(),
1422 HasSubstr("Operand '148[%148]' cannot be a "
1423 "type"));
1424 }
1425
TEST_F(ValidateImage,ImageTexelPointerImageNotImage)1426 TEST_F(ValidateImage, ImageTexelPointerImageNotImage) {
1427 const std::string body = R"(
1428 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_sampler %u32_0 %u32_0
1429 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1430 )";
1431
1432 CompileSuccessfully(GenerateShaderCode(body).c_str());
1433 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1434 EXPECT_THAT(
1435 getDiagnosticString(),
1436 HasSubstr("Expected Image to be OpTypePointer with Type OpTypeImage"));
1437 }
1438
TEST_F(ValidateImage,ImageTexelPointerImageSampledNotResultType)1439 TEST_F(ValidateImage, ImageTexelPointerImageSampledNotResultType) {
1440 const std::string body = R"(
1441 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_f32_cube_0101 %u32_0 %u32_0
1442 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1443 )";
1444
1445 CompileSuccessfully(GenerateShaderCode(body).c_str());
1446 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1447 EXPECT_THAT(getDiagnosticString(),
1448 HasSubstr("Expected Image 'Sampled Type' to be the same as the "
1449 "Type pointed to by Result Type"));
1450 }
1451
TEST_F(ValidateImage,ImageTexelPointerImageDimSubpassDataBad)1452 TEST_F(ValidateImage, ImageTexelPointerImageDimSubpassDataBad) {
1453 const std::string body = R"(
1454 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_spd_0002 %u32_0 %u32_0
1455 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1456 )";
1457
1458 CompileSuccessfully(GenerateShaderCode(body).c_str());
1459 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1460 EXPECT_THAT(
1461 getDiagnosticString(),
1462 HasSubstr(
1463 "Image Dim SubpassData cannot be used with OpImageTexelPointer"));
1464 }
1465
TEST_F(ValidateImage,ImageTexelPointerImageCoordTypeBad)1466 TEST_F(ValidateImage, ImageTexelPointerImageCoordTypeBad) {
1467 const std::string body = R"(
1468 %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32ui %f32_0 %f32_0
1469 %sum = OpAtomicIAdd %f32 %texel_ptr %f32_1 %f32_0 %f32_1
1470 )";
1471
1472 CompileSuccessfully(GenerateShaderCode(body).c_str());
1473 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1474 EXPECT_THAT(getDiagnosticString(),
1475 HasSubstr("Expected Coordinate to be integer scalar or vector"));
1476 }
1477
TEST_F(ValidateImage,ImageTexelPointerImageCoordSizeBad)1478 TEST_F(ValidateImage, ImageTexelPointerImageCoordSizeBad) {
1479 const std::string body = R"(
1480 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_u32_2d_0002 %u32vec3_012 %u32_0
1481 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1482 )";
1483
1484 CompileSuccessfully(GenerateShaderCode(body).c_str());
1485 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1486 EXPECT_THAT(
1487 getDiagnosticString(),
1488 HasSubstr("Expected Coordinate to have 2 components, but given 3"));
1489 }
1490
TEST_F(ValidateImage,ImageTexelPointerSampleNotIntScalar)1491 TEST_F(ValidateImage, ImageTexelPointerSampleNotIntScalar) {
1492 const std::string body = R"(
1493 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %f32_0
1494 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1495 )";
1496
1497 CompileSuccessfully(GenerateShaderCode(body).c_str());
1498 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1499 EXPECT_THAT(getDiagnosticString(),
1500 HasSubstr("Expected Sample to be integer scalar"));
1501 }
1502
TEST_F(ValidateImage,ImageTexelPointerSampleNotZeroForImageWithMSZero)1503 TEST_F(ValidateImage, ImageTexelPointerSampleNotZeroForImageWithMSZero) {
1504 const std::string body = R"(
1505 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_1
1506 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
1507 )";
1508
1509 CompileSuccessfully(GenerateShaderCode(body).c_str());
1510 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1511 EXPECT_THAT(getDiagnosticString(),
1512 HasSubstr("Expected Sample for Image with MS 0 to be a valid "
1513 "<id> for the value 0"));
1514 }
1515
TEST_F(ValidateImage,SampleImplicitLodSuccess)1516 TEST_F(ValidateImage, SampleImplicitLodSuccess) {
1517 const std::string body = R"(
1518 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1519 %sampler = OpLoad %type_sampler %uniform_sampler
1520 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1521 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
1522 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0_25
1523 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
1524 %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
1525 %res6 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
1526 %res7 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
1527 %res8 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
1528 )";
1529
1530 const std::string extra = R"(
1531 OpCapability VulkanMemoryModelKHR
1532 OpExtension "SPV_KHR_vulkan_memory_model"
1533 )";
1534 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1535 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1536 .c_str());
1537 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1538 }
1539
TEST_F(ValidateImage,SampleImplicitLodWrongResultType)1540 TEST_F(ValidateImage, SampleImplicitLodWrongResultType) {
1541 const std::string body = R"(
1542 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1543 %sampler = OpLoad %type_sampler %uniform_sampler
1544 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1545 %res1 = OpImageSampleImplicitLod %f32 %simg %f32vec2_hh
1546 )";
1547
1548 CompileSuccessfully(GenerateShaderCode(body).c_str());
1549 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1550 EXPECT_THAT(getDiagnosticString(),
1551 HasSubstr("Expected Result Type to be int or float vector type"));
1552 }
1553
TEST_F(ValidateImage,SampleImplicitLodWrongNumComponentsResultType)1554 TEST_F(ValidateImage, SampleImplicitLodWrongNumComponentsResultType) {
1555 const std::string body = R"(
1556 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1557 %sampler = OpLoad %type_sampler %uniform_sampler
1558 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1559 %res1 = OpImageSampleImplicitLod %f32vec3 %simg %f32vec2_hh
1560 )";
1561
1562 CompileSuccessfully(GenerateShaderCode(body).c_str());
1563 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1564 EXPECT_THAT(getDiagnosticString(),
1565 HasSubstr("Expected Result Type to have 4 components"));
1566 }
1567
TEST_F(ValidateImage,SampleImplicitLodNotSampledImage)1568 TEST_F(ValidateImage, SampleImplicitLodNotSampledImage) {
1569 const std::string body = R"(
1570 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1571 %res1 = OpImageSampleImplicitLod %f32vec4 %img %f32vec2_hh
1572 )";
1573
1574 CompileSuccessfully(GenerateShaderCode(body).c_str());
1575 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1576 EXPECT_THAT(
1577 getDiagnosticString(),
1578 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1579 }
1580
TEST_F(ValidateImage,SampleImplicitLodMultisampleError)1581 TEST_F(ValidateImage, SampleImplicitLodMultisampleError) {
1582 const std::string body = R"(
1583 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
1584 %sampler = OpLoad %type_sampler %uniform_sampler
1585 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
1586 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
1587 )";
1588
1589 CompileSuccessfully(GenerateShaderCode(body).c_str());
1590 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1591 EXPECT_THAT(getDiagnosticString(),
1592 HasSubstr("Sampling operation is invalid for multisample image"));
1593 }
1594
TEST_F(ValidateImage,SampleImplicitLodWrongSampledType)1595 TEST_F(ValidateImage, SampleImplicitLodWrongSampledType) {
1596 const std::string body = R"(
1597 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1598 %sampler = OpLoad %type_sampler %uniform_sampler
1599 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1600 %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
1601 )";
1602
1603 CompileSuccessfully(GenerateShaderCode(body).c_str());
1604 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1605 EXPECT_THAT(getDiagnosticString(),
1606 HasSubstr("Expected Image 'Sampled Type' to be the same as "
1607 "Result Type components"));
1608 }
1609
TEST_F(ValidateImage,SampleImplicitLodVoidSampledType)1610 TEST_F(ValidateImage, SampleImplicitLodVoidSampledType) {
1611 const std::string body = R"(
1612 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1613 %sampler = OpLoad %type_sampler %uniform_sampler
1614 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1615 %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
1616 )";
1617
1618 CompileSuccessfully(GenerateShaderCode(body).c_str());
1619 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1620 }
1621
TEST_F(ValidateImage,SampleImplicitLodWrongCoordinateType)1622 TEST_F(ValidateImage, SampleImplicitLodWrongCoordinateType) {
1623 const std::string body = R"(
1624 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1625 %sampler = OpLoad %type_sampler %uniform_sampler
1626 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1627 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %img
1628 )";
1629
1630 CompileSuccessfully(GenerateShaderCode(body).c_str());
1631 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1632 EXPECT_THAT(getDiagnosticString(),
1633 HasSubstr("Expected Coordinate to be float scalar or vector"));
1634 }
1635
TEST_F(ValidateImage,SampleImplicitLodCoordinateSizeTooSmall)1636 TEST_F(ValidateImage, SampleImplicitLodCoordinateSizeTooSmall) {
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 = OpImageSampleImplicitLod %f32vec4 %simg %f32_0_5
1642 )";
1643
1644 CompileSuccessfully(GenerateShaderCode(body).c_str());
1645 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1646 EXPECT_THAT(getDiagnosticString(),
1647 HasSubstr("Expected Coordinate to have at least 2 components, "
1648 "but given only 1"));
1649 }
1650
TEST_F(ValidateImage,SampleExplicitLodSuccessShader)1651 TEST_F(ValidateImage, SampleExplicitLodSuccessShader) {
1652 const std::string body = R"(
1653 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1654 %sampler = OpLoad %type_sampler %uniform_sampler
1655 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1656 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod %f32_1
1657 %res2 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_10 %f32vec2_01
1658 %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
1659 %res4 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
1660 %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset|MinLod %f32vec2_10 %f32vec2_01 %s32vec2_01 %f32_0_5
1661 %res6 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod|NonPrivateTexelKHR %f32_1
1662 )";
1663
1664 const std::string extra = R"(
1665 OpCapability VulkanMemoryModelKHR
1666 OpExtension "SPV_KHR_vulkan_memory_model"
1667 )";
1668 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1669 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1670 .c_str());
1671 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1672 }
1673
TEST_F(ValidateImage,SampleExplicitLodSuccessKernel)1674 TEST_F(ValidateImage, SampleExplicitLodSuccessKernel) {
1675 const std::string body = R"(
1676 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1677 %sampler = OpLoad %type_sampler %uniform_sampler
1678 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1679 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec4_0123 Lod %f32_1
1680 %res2 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Grad %f32vec2_10 %f32vec2_01
1681 %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %u32vec2_01
1682 %res4 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Offset %u32vec2_01
1683 %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset %f32vec2_10 %f32vec2_01 %u32vec2_01
1684 )";
1685
1686 CompileSuccessfully(GenerateKernelCode(body).c_str());
1687 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1688 }
1689
TEST_F(ValidateImage,SampleExplicitLodSuccessCubeArrayed)1690 TEST_F(ValidateImage, SampleExplicitLodSuccessCubeArrayed) {
1691 const std::string body = R"(
1692 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1693 %sampler = OpLoad %type_sampler %uniform_sampler
1694 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1695 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec3_hhh
1696 )";
1697
1698 CompileSuccessfully(GenerateShaderCode(body).c_str());
1699 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1700 }
1701
TEST_F(ValidateImage,SampleExplicitLodWrongResultType)1702 TEST_F(ValidateImage, SampleExplicitLodWrongResultType) {
1703 const std::string body = R"(
1704 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1705 %sampler = OpLoad %type_sampler %uniform_sampler
1706 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1707 %res1 = OpImageSampleExplicitLod %f32 %simg %f32vec2_hh Lod %f32_1
1708 )";
1709
1710 CompileSuccessfully(GenerateShaderCode(body).c_str());
1711 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1712 EXPECT_THAT(getDiagnosticString(),
1713 HasSubstr("Expected Result Type to be int or float vector type"));
1714 }
1715
TEST_F(ValidateImage,SampleExplicitLodWrongNumComponentsResultType)1716 TEST_F(ValidateImage, SampleExplicitLodWrongNumComponentsResultType) {
1717 const std::string body = R"(
1718 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1719 %sampler = OpLoad %type_sampler %uniform_sampler
1720 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1721 %res1 = OpImageSampleExplicitLod %f32vec3 %simg %f32vec2_hh Lod %f32_1
1722 )";
1723
1724 CompileSuccessfully(GenerateShaderCode(body).c_str());
1725 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1726 EXPECT_THAT(getDiagnosticString(),
1727 HasSubstr("Expected Result Type to have 4 components"));
1728 }
1729
TEST_F(ValidateImage,SampleExplicitLodNotSampledImage)1730 TEST_F(ValidateImage, SampleExplicitLodNotSampledImage) {
1731 const std::string body = R"(
1732 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1733 %res1 = OpImageSampleExplicitLod %f32vec4 %img %f32vec2_hh Lod %f32_1
1734 )";
1735
1736 CompileSuccessfully(GenerateShaderCode(body).c_str());
1737 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1738 EXPECT_THAT(
1739 getDiagnosticString(),
1740 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1741 }
1742
TEST_F(ValidateImage,SampleExplicitLodMultisampleError)1743 TEST_F(ValidateImage, SampleExplicitLodMultisampleError) {
1744 const std::string body = R"(
1745 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
1746 %sampler = OpLoad %type_sampler %uniform_sampler
1747 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
1748 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_0 %u32_1
1749 )";
1750
1751 CompileSuccessfully(GenerateShaderCode(body).c_str());
1752 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1753 EXPECT_THAT(getDiagnosticString(),
1754 HasSubstr("Sampling operation is invalid for multisample image"));
1755 }
1756
TEST_F(ValidateImage,SampleExplicitLodWrongSampledType)1757 TEST_F(ValidateImage, SampleExplicitLodWrongSampledType) {
1758 const std::string body = R"(
1759 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1760 %sampler = OpLoad %type_sampler %uniform_sampler
1761 %simg = OpSampledImage %type_sampled_image_f32_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_ERROR_INVALID_DATA, ValidateInstructions());
1767 EXPECT_THAT(getDiagnosticString(),
1768 HasSubstr("Expected Image 'Sampled Type' to be the same as "
1769 "Result Type components"));
1770 }
1771
TEST_F(ValidateImage,SampleExplicitLodVoidSampledType)1772 TEST_F(ValidateImage, SampleExplicitLodVoidSampledType) {
1773 const std::string body = R"(
1774 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1775 %sampler = OpLoad %type_sampler %uniform_sampler
1776 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1777 %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
1778 )";
1779
1780 CompileSuccessfully(GenerateShaderCode(body).c_str());
1781 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1782 }
1783
TEST_F(ValidateImage,SampleExplicitLodWrongCoordinateType)1784 TEST_F(ValidateImage, SampleExplicitLodWrongCoordinateType) {
1785 const std::string body = R"(
1786 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1787 %sampler = OpLoad %type_sampler %uniform_sampler
1788 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1789 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %img Lod %f32_1
1790 )";
1791
1792 CompileSuccessfully(GenerateShaderCode(body).c_str());
1793 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1794 EXPECT_THAT(getDiagnosticString(),
1795 HasSubstr("Expected Coordinate to be float scalar or vector"));
1796 }
1797
TEST_F(ValidateImage,SampleExplicitLodCoordinateSizeTooSmall)1798 TEST_F(ValidateImage, SampleExplicitLodCoordinateSizeTooSmall) {
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 %f32_0_5 Lod %f32_1
1804 )";
1805
1806 CompileSuccessfully(GenerateShaderCode(body).c_str());
1807 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1808 EXPECT_THAT(getDiagnosticString(),
1809 HasSubstr("Expected Coordinate to have at least 2 components, "
1810 "but given only 1"));
1811 }
1812
TEST_F(ValidateImage,SampleExplicitLodBias)1813 TEST_F(ValidateImage, SampleExplicitLodBias) {
1814 const std::string body = R"(
1815 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1816 %sampler = OpLoad %type_sampler %uniform_sampler
1817 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1818 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Bias|Lod %f32_1 %f32_1
1819 )";
1820
1821 CompileSuccessfully(GenerateShaderCode(body).c_str());
1822 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1823 EXPECT_THAT(
1824 getDiagnosticString(),
1825 HasSubstr(
1826 "Image Operand Bias can only be used with ImplicitLod opcodes"));
1827 }
1828
TEST_F(ValidateImage,LodAndGrad)1829 TEST_F(ValidateImage, LodAndGrad) {
1830 const std::string body = R"(
1831 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1832 %sampler = OpLoad %type_sampler %uniform_sampler
1833 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1834 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|Grad %f32_1 %f32vec2_hh %f32vec2_hh
1835 )";
1836
1837 CompileSuccessfully(GenerateShaderCode(body).c_str());
1838 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1839 EXPECT_THAT(
1840 getDiagnosticString(),
1841 HasSubstr(
1842 "Image Operand bits Lod and Grad cannot be set at the same time"));
1843 }
1844
TEST_F(ValidateImage,ImplicitLodWithLod)1845 TEST_F(ValidateImage, ImplicitLodWithLod) {
1846 const std::string body = R"(
1847 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1848 %sampler = OpLoad %type_sampler %uniform_sampler
1849 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1850 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_0_5
1851 )";
1852
1853 CompileSuccessfully(GenerateShaderCode(body).c_str());
1854 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1855 EXPECT_THAT(
1856 getDiagnosticString(),
1857 HasSubstr("Image Operand Lod can only be used with ExplicitLod opcodes "
1858 "and OpImageFetch"));
1859 }
1860
TEST_F(ValidateImage,LodWrongType)1861 TEST_F(ValidateImage, LodWrongType) {
1862 const std::string body = R"(
1863 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1864 %sampler = OpLoad %type_sampler %uniform_sampler
1865 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1866 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32vec2_hh)";
1867
1868 CompileSuccessfully(GenerateShaderCode(body).c_str());
1869 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1870 EXPECT_THAT(getDiagnosticString(),
1871 HasSubstr("Expected Image Operand Lod to be float scalar when "
1872 "used with ExplicitLod"));
1873 }
1874
TEST_F(ValidateImage,LodWrongDim)1875 TEST_F(ValidateImage, LodWrongDim) {
1876 const std::string body = R"(
1877 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1878 %sampler = OpLoad %type_sampler %uniform_sampler
1879 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1880 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32_0)";
1881
1882 CompileSuccessfully(GenerateShaderCode(body).c_str());
1883 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1884 EXPECT_THAT(getDiagnosticString(),
1885 HasSubstr("Image Operand Lod requires 'Dim' parameter to be 1D, "
1886 "2D, 3D or Cube"));
1887 }
1888
TEST_F(ValidateImage,MinLodIncompatible)1889 TEST_F(ValidateImage, MinLodIncompatible) {
1890 const std::string body = R"(
1891 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1892 %sampler = OpLoad %type_sampler %uniform_sampler
1893 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1894 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|MinLod %f32_0 %f32_0)";
1895
1896 CompileSuccessfully(GenerateShaderCode(body).c_str());
1897 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1898 EXPECT_THAT(
1899 getDiagnosticString(),
1900 HasSubstr(
1901 "Image Operand MinLod can only be used with ImplicitLod opcodes or "
1902 "together with Image Operand Grad"));
1903 }
1904
TEST_F(ValidateImage,ImplicitLodWithGrad)1905 TEST_F(ValidateImage, ImplicitLodWithGrad) {
1906 const std::string body = R"(
1907 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1908 %sampler = OpLoad %type_sampler %uniform_sampler
1909 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1910 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_hh %f32vec2_hh
1911 )";
1912
1913 CompileSuccessfully(GenerateShaderCode(body).c_str());
1914 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1915 EXPECT_THAT(
1916 getDiagnosticString(),
1917 HasSubstr(
1918 "Image Operand Grad can only be used with ExplicitLod opcodes"));
1919 }
1920
TEST_F(ValidateImage,SampleImplicitLodCubeArrayedSuccess)1921 TEST_F(ValidateImage, SampleImplicitLodCubeArrayedSuccess) {
1922 const std::string body = R"(
1923 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1924 %sampler = OpLoad %type_sampler %uniform_sampler
1925 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1926 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000
1927 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias %f32_0_25
1928 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %f32_0_5
1929 %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias|MinLod %f32_0_25 %f32_0_5
1930 )";
1931
1932 CompileSuccessfully(GenerateShaderCode(body).c_str());
1933 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1934 }
1935
TEST_F(ValidateImage,SampleImplicitLodBiasWrongType)1936 TEST_F(ValidateImage, SampleImplicitLodBiasWrongType) {
1937 const std::string body = R"(
1938 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1939 %sampler = OpLoad %type_sampler %uniform_sampler
1940 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1941 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %u32_0
1942 )";
1943
1944 CompileSuccessfully(GenerateShaderCode(body).c_str());
1945 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1946 EXPECT_THAT(getDiagnosticString(),
1947 HasSubstr("Expected Image Operand Bias to be float scalar"));
1948 }
1949
TEST_F(ValidateImage,SampleImplicitLodBiasWrongDim)1950 TEST_F(ValidateImage, SampleImplicitLodBiasWrongDim) {
1951 const std::string body = R"(
1952 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1953 %sampler = OpLoad %type_sampler %uniform_sampler
1954 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1955 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0
1956 )";
1957
1958 CompileSuccessfully(GenerateShaderCode(body).c_str());
1959 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1960 EXPECT_THAT(getDiagnosticString(),
1961 HasSubstr("Image Operand Bias requires 'Dim' parameter to be 1D, "
1962 "2D, 3D or Cube"));
1963 }
1964
TEST_F(ValidateImage,SampleExplicitLodGradDxWrongType)1965 TEST_F(ValidateImage, SampleExplicitLodGradDxWrongType) {
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 %s32vec3_012 %f32vec3_hhh
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,SampleExplicitLodGradDyWrongType)1980 TEST_F(ValidateImage, SampleExplicitLodGradDyWrongType) {
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 %f32vec3_hhh %s32vec3_012
1986 )";
1987
1988 CompileSuccessfully(GenerateShaderCode(body).c_str());
1989 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1990 EXPECT_THAT(getDiagnosticString(),
1991 HasSubstr("Expected both Image Operand Grad ids to be float "
1992 "scalars or vectors"));
1993 }
1994
TEST_F(ValidateImage,SampleExplicitLodGradDxWrongSize)1995 TEST_F(ValidateImage, SampleExplicitLodGradDxWrongSize) {
1996 const std::string body = R"(
1997 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1998 %sampler = OpLoad %type_sampler %uniform_sampler
1999 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2000 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec2_00 %f32vec3_hhh
2001 )";
2002
2003 CompileSuccessfully(GenerateShaderCode(body).c_str());
2004 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2005 EXPECT_THAT(
2006 getDiagnosticString(),
2007 HasSubstr(
2008 "Expected Image Operand Grad dx to have 3 components, but given 2"));
2009 }
2010
TEST_F(ValidateImage,SampleExplicitLodGradDyWrongSize)2011 TEST_F(ValidateImage, SampleExplicitLodGradDyWrongSize) {
2012 const std::string body = R"(
2013 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2014 %sampler = OpLoad %type_sampler %uniform_sampler
2015 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2016 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec2_00
2017 )";
2018
2019 CompileSuccessfully(GenerateShaderCode(body).c_str());
2020 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2021 EXPECT_THAT(
2022 getDiagnosticString(),
2023 HasSubstr(
2024 "Expected Image Operand Grad dy to have 3 components, but given 2"));
2025 }
2026
TEST_F(ValidateImage,SampleImplicitLodConstOffsetCubeDim)2027 TEST_F(ValidateImage, SampleImplicitLodConstOffsetCubeDim) {
2028 const std::string body = R"(
2029 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2030 %sampler = OpLoad %type_sampler %uniform_sampler
2031 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2032 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec3_012
2033 )";
2034
2035 CompileSuccessfully(GenerateShaderCode(body).c_str());
2036 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2037 EXPECT_THAT(
2038 getDiagnosticString(),
2039 HasSubstr(
2040 "Image Operand ConstOffset cannot be used with Cube Image 'Dim'"));
2041 }
2042
TEST_F(ValidateImage,SampleImplicitLodConstOffsetWrongType)2043 TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongType) {
2044 const std::string body = R"(
2045 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2046 %sampler = OpLoad %type_sampler %uniform_sampler
2047 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2048 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %f32vec2_00
2049 )";
2050
2051 CompileSuccessfully(GenerateShaderCode(body).c_str());
2052 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2053 EXPECT_THAT(
2054 getDiagnosticString(),
2055 HasSubstr(
2056 "Expected Image Operand ConstOffset to be int scalar or vector"));
2057 }
2058
TEST_F(ValidateImage,SampleImplicitLodConstOffsetWrongSize)2059 TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongSize) {
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 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %s32vec3_012
2065 )";
2066
2067 CompileSuccessfully(GenerateShaderCode(body).c_str());
2068 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2069 EXPECT_THAT(getDiagnosticString(),
2070 HasSubstr("Expected Image Operand ConstOffset to have 2 "
2071 "components, but given 3"));
2072 }
2073
TEST_F(ValidateImage,SampleImplicitLodConstOffsetNotConst)2074 TEST_F(ValidateImage, SampleImplicitLodConstOffsetNotConst) {
2075 const std::string body = R"(
2076 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2077 %sampler = OpLoad %type_sampler %uniform_sampler
2078 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2079 %offset = OpSNegate %s32vec3 %s32vec3_012
2080 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_00 ConstOffset %offset
2081 )";
2082
2083 CompileSuccessfully(GenerateShaderCode(body).c_str());
2084 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2085 EXPECT_THAT(
2086 getDiagnosticString(),
2087 HasSubstr("Expected Image Operand ConstOffset to be a const object"));
2088 }
2089
TEST_F(ValidateImage,SampleImplicitLodOffsetCubeDim)2090 TEST_F(ValidateImage, SampleImplicitLodOffsetCubeDim) {
2091 const std::string body = R"(
2092 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2093 %sampler = OpLoad %type_sampler %uniform_sampler
2094 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2095 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
2096 )";
2097
2098 CompileSuccessfully(GenerateShaderCode(body).c_str());
2099 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2100 EXPECT_THAT(
2101 getDiagnosticString(),
2102 HasSubstr("Image Operand Offset cannot be used with Cube Image 'Dim'"));
2103 }
2104
TEST_F(ValidateImage,SampleImplicitLodOffsetWrongType)2105 TEST_F(ValidateImage, SampleImplicitLodOffsetWrongType) {
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 %f32vec2_00
2111 )";
2112
2113 CompileSuccessfully(GenerateShaderCode(body).c_str());
2114 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2115 EXPECT_THAT(
2116 getDiagnosticString(),
2117 HasSubstr("Expected Image Operand Offset to be int scalar or vector"));
2118 }
2119
TEST_F(ValidateImage,SampleImplicitLodOffsetWrongSize)2120 TEST_F(ValidateImage, SampleImplicitLodOffsetWrongSize) {
2121 const std::string body = R"(
2122 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2123 %sampler = OpLoad %type_sampler %uniform_sampler
2124 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2125 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
2126 )";
2127
2128 CompileSuccessfully(GenerateShaderCode(body).c_str());
2129 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2130 EXPECT_THAT(
2131 getDiagnosticString(),
2132 HasSubstr(
2133 "Expected Image Operand Offset to have 2 components, but given 3"));
2134 }
2135
TEST_F(ValidateImage,SampleImplicitLodVulkanOffsetWrongSize)2136 TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongSize) {
2137 const std::string body = R"(
2138 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2139 %sampler = OpLoad %type_sampler %uniform_sampler
2140 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2141 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
2142 )";
2143
2144 CompileSuccessfully(
2145 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2146 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2147 EXPECT_THAT(getDiagnosticString(),
2148 AnyVUID("VUID-StandaloneSpirv-Offset-04663"));
2149 EXPECT_THAT(getDiagnosticString(),
2150 HasSubstr("Image Operand Offset can only be used with "
2151 "OpImage*Gather operations"));
2152 }
2153
TEST_F(ValidateImage,SampleImplicitLodVulkanOffsetWrongBeforeLegalization)2154 TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongBeforeLegalization) {
2155 const std::string body = R"(
2156 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2157 %sampler = OpLoad %type_sampler %uniform_sampler
2158 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2159 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
2160 )";
2161
2162 CompileSuccessfully(
2163 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2164 getValidatorOptions()->before_hlsl_legalization = true;
2165 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2166 }
2167
TEST_F(ValidateImage,SampleImplicitLodMoreThanOneOffset)2168 TEST_F(ValidateImage, SampleImplicitLodMoreThanOneOffset) {
2169 const std::string body = R"(
2170 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2171 %sampler = OpLoad %type_sampler %uniform_sampler
2172 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2173 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
2174 )";
2175
2176 CompileSuccessfully(GenerateShaderCode(body).c_str());
2177 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2178 EXPECT_THAT(
2179 getDiagnosticString(),
2180 HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
2181 "cannot be used together"));
2182 }
2183
TEST_F(ValidateImage,SampleImplicitLodVulkanMoreThanOneOffset)2184 TEST_F(ValidateImage, SampleImplicitLodVulkanMoreThanOneOffset) {
2185 const std::string body = R"(
2186 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2187 %sampler = OpLoad %type_sampler %uniform_sampler
2188 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2189 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec2_01 %s32vec2_01
2190 )";
2191
2192 CompileSuccessfully(
2193 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2194 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2195 EXPECT_THAT(
2196 getDiagnosticString(),
2197 HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
2198 "cannot be used together"));
2199 }
2200
TEST_F(ValidateImage,SampleImplicitLodMinLodWrongType)2201 TEST_F(ValidateImage, SampleImplicitLodMinLodWrongType) {
2202 const std::string body = R"(
2203 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2204 %sampler = OpLoad %type_sampler %uniform_sampler
2205 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2206 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %s32_0
2207 )";
2208
2209 CompileSuccessfully(GenerateShaderCode(body).c_str());
2210 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2211 EXPECT_THAT(getDiagnosticString(),
2212 HasSubstr("Expected Image Operand MinLod to be float scalar"));
2213 }
2214
TEST_F(ValidateImage,SampleImplicitLodMinLodWrongDim)2215 TEST_F(ValidateImage, SampleImplicitLodMinLodWrongDim) {
2216 const std::string body = R"(
2217 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2218 %sampler = OpLoad %type_sampler %uniform_sampler
2219 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
2220 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_25
2221 )";
2222
2223 CompileSuccessfully(GenerateShaderCode(body).c_str());
2224 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2225 EXPECT_THAT(getDiagnosticString(),
2226 HasSubstr("Image Operand MinLod requires 'Dim' parameter to be "
2227 "1D, 2D, 3D or Cube"));
2228 }
2229
TEST_F(ValidateImage,SampleProjExplicitLodSuccess2D)2230 TEST_F(ValidateImage, SampleProjExplicitLodSuccess2D) {
2231 const std::string body = R"(
2232 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2233 %sampler = OpLoad %type_sampler %uniform_sampler
2234 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2235 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod %f32_1
2236 %res3 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
2237 %res4 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
2238 %res5 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
2239 %res7 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
2240 %res8 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod|NonPrivateTexelKHR %f32_1
2241 )";
2242
2243 const std::string extra = R"(
2244 OpCapability VulkanMemoryModelKHR
2245 OpExtension "SPV_KHR_vulkan_memory_model"
2246 )";
2247 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2248 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2249 .c_str());
2250 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2251 }
2252
TEST_F(ValidateImage,SampleProjExplicitLodSuccessRect)2253 TEST_F(ValidateImage, SampleProjExplicitLodSuccessRect) {
2254 const std::string body = R"(
2255 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2256 %sampler = OpLoad %type_sampler %uniform_sampler
2257 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
2258 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
2259 %res2 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
2260 )";
2261
2262 CompileSuccessfully(GenerateShaderCode(body).c_str());
2263 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2264 }
2265
TEST_F(ValidateImage,SampleProjExplicitLodWrongResultType)2266 TEST_F(ValidateImage, SampleProjExplicitLodWrongResultType) {
2267 const std::string body = R"(
2268 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2269 %sampler = OpLoad %type_sampler %uniform_sampler
2270 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2271 %res1 = OpImageSampleProjExplicitLod %f32 %simg %f32vec3_hhh Lod %f32_1
2272 )";
2273
2274 CompileSuccessfully(GenerateShaderCode(body).c_str());
2275 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2276 EXPECT_THAT(getDiagnosticString(),
2277 HasSubstr("Expected Result Type to be int or float vector type"));
2278 }
2279
TEST_F(ValidateImage,SampleProjExplicitLodWrongNumComponentsResultType)2280 TEST_F(ValidateImage, SampleProjExplicitLodWrongNumComponentsResultType) {
2281 const std::string body = R"(
2282 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2283 %sampler = OpLoad %type_sampler %uniform_sampler
2284 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2285 %res1 = OpImageSampleProjExplicitLod %f32vec3 %simg %f32vec3_hhh Lod %f32_1
2286 )";
2287
2288 CompileSuccessfully(GenerateShaderCode(body).c_str());
2289 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2290 EXPECT_THAT(getDiagnosticString(),
2291 HasSubstr("Expected Result Type to have 4 components"));
2292 }
2293
TEST_F(ValidateImage,SampleProjExplicitLodNotSampledImage)2294 TEST_F(ValidateImage, SampleProjExplicitLodNotSampledImage) {
2295 const std::string body = R"(
2296 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2297 %res1 = OpImageSampleProjExplicitLod %f32vec4 %img %f32vec3_hhh Lod %f32_1
2298 )";
2299
2300 CompileSuccessfully(GenerateShaderCode(body).c_str());
2301 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2302 EXPECT_THAT(
2303 getDiagnosticString(),
2304 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2305 }
2306
TEST_F(ValidateImage,SampleProjExplicitLodMultisampleError)2307 TEST_F(ValidateImage, SampleProjExplicitLodMultisampleError) {
2308 const std::string body = R"(
2309 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2310 %sampler = OpLoad %type_sampler %uniform_sampler
2311 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2312 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod|Sample %f32_1 %u32_1
2313 )";
2314
2315 CompileSuccessfully(GenerateShaderCode(body).c_str());
2316 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2317 EXPECT_THAT(getDiagnosticString(),
2318 HasSubstr("Expected Image 'MS' parameter to be 0"));
2319 }
2320
TEST_F(ValidateImage,SampleProjExplicitLodWrongSampledType)2321 TEST_F(ValidateImage, SampleProjExplicitLodWrongSampledType) {
2322 const std::string body = R"(
2323 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2324 %sampler = OpLoad %type_sampler %uniform_sampler
2325 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2326 %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
2327 )";
2328
2329 CompileSuccessfully(GenerateShaderCode(body).c_str());
2330 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2331 EXPECT_THAT(getDiagnosticString(),
2332 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2333 "Result Type components"));
2334 }
2335
TEST_F(ValidateImage,SampleProjExplicitLodVoidSampledType)2336 TEST_F(ValidateImage, SampleProjExplicitLodVoidSampledType) {
2337 const std::string body = R"(
2338 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2339 %sampler = OpLoad %type_sampler %uniform_sampler
2340 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2341 %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
2342 )";
2343
2344 CompileSuccessfully(GenerateShaderCode(body).c_str());
2345 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2346 }
2347
TEST_F(ValidateImage,SampleProjExplicitLodWrongCoordinateType)2348 TEST_F(ValidateImage, SampleProjExplicitLodWrongCoordinateType) {
2349 const std::string body = R"(
2350 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2351 %sampler = OpLoad %type_sampler %uniform_sampler
2352 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2353 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %img Lod %f32_1
2354 )";
2355
2356 CompileSuccessfully(GenerateShaderCode(body).c_str());
2357 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2358 EXPECT_THAT(getDiagnosticString(),
2359 HasSubstr("Expected Coordinate to be float scalar or vector"));
2360 }
2361
TEST_F(ValidateImage,SampleProjExplicitLodCoordinateSizeTooSmall)2362 TEST_F(ValidateImage, SampleProjExplicitLodCoordinateSizeTooSmall) {
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 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_1
2368 )";
2369
2370 CompileSuccessfully(GenerateShaderCode(body).c_str());
2371 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2372 EXPECT_THAT(getDiagnosticString(),
2373 HasSubstr("Expected Coordinate to have at least 3 components, "
2374 "but given only 2"));
2375 }
2376
TEST_F(ValidateImage,SampleProjImplicitLodSuccess)2377 TEST_F(ValidateImage, SampleProjImplicitLodSuccess) {
2378 const std::string body = R"(
2379 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2380 %sampler = OpLoad %type_sampler %uniform_sampler
2381 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2382 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh
2383 %res2 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias %f32_0_25
2384 %res4 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
2385 %res5 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
2386 %res6 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh MinLod %f32_0_5
2387 %res7 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2388 %res8 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh NonPrivateTexelKHR
2389 )";
2390
2391 const std::string extra = R"(
2392 OpCapability VulkanMemoryModelKHR
2393 OpExtension "SPV_KHR_vulkan_memory_model"
2394 )";
2395 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2396 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2397 .c_str());
2398 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2399 }
2400
TEST_F(ValidateImage,SampleProjImplicitLodWrongResultType)2401 TEST_F(ValidateImage, SampleProjImplicitLodWrongResultType) {
2402 const std::string body = R"(
2403 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2404 %sampler = OpLoad %type_sampler %uniform_sampler
2405 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2406 %res1 = OpImageSampleProjImplicitLod %f32 %simg %f32vec3_hhh
2407 )";
2408
2409 CompileSuccessfully(GenerateShaderCode(body).c_str());
2410 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2411 EXPECT_THAT(getDiagnosticString(),
2412 HasSubstr("Expected Result Type to be int or float vector type"));
2413 }
2414
TEST_F(ValidateImage,SampleProjImplicitLodWrongNumComponentsResultType)2415 TEST_F(ValidateImage, SampleProjImplicitLodWrongNumComponentsResultType) {
2416 const std::string body = R"(
2417 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2418 %sampler = OpLoad %type_sampler %uniform_sampler
2419 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2420 %res1 = OpImageSampleProjImplicitLod %f32vec3 %simg %f32vec3_hhh
2421 )";
2422
2423 CompileSuccessfully(GenerateShaderCode(body).c_str());
2424 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2425 EXPECT_THAT(getDiagnosticString(),
2426 HasSubstr("Expected Result Type to have 4 components"));
2427 }
2428
TEST_F(ValidateImage,SampleProjImplicitLodNotSampledImage)2429 TEST_F(ValidateImage, SampleProjImplicitLodNotSampledImage) {
2430 const std::string body = R"(
2431 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2432 %res1 = OpImageSampleProjImplicitLod %f32vec4 %img %f32vec3_hhh
2433 )";
2434
2435 CompileSuccessfully(GenerateShaderCode(body).c_str());
2436 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2437 EXPECT_THAT(
2438 getDiagnosticString(),
2439 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2440 }
2441
TEST_F(ValidateImage,SampleProjImplicitLodMultisampleError)2442 TEST_F(ValidateImage, SampleProjImplicitLodMultisampleError) {
2443 const std::string body = R"(
2444 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2445 %sampler = OpLoad %type_sampler %uniform_sampler
2446 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2447 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh Sample %u32_1
2448 )";
2449
2450 CompileSuccessfully(GenerateShaderCode(body).c_str());
2451 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2452 EXPECT_THAT(getDiagnosticString(),
2453 HasSubstr("Expected Image 'MS' parameter to be 0"));
2454 }
2455
TEST_F(ValidateImage,SampleProjImplicitLodWrongSampledType)2456 TEST_F(ValidateImage, SampleProjImplicitLodWrongSampledType) {
2457 const std::string body = R"(
2458 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2459 %sampler = OpLoad %type_sampler %uniform_sampler
2460 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2461 %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
2462 )";
2463
2464 CompileSuccessfully(GenerateShaderCode(body).c_str());
2465 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2466 EXPECT_THAT(getDiagnosticString(),
2467 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2468 "Result Type components"));
2469 }
2470
TEST_F(ValidateImage,SampleProjImplicitLodVoidSampledType)2471 TEST_F(ValidateImage, SampleProjImplicitLodVoidSampledType) {
2472 const std::string body = R"(
2473 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2474 %sampler = OpLoad %type_sampler %uniform_sampler
2475 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2476 %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
2477 )";
2478
2479 CompileSuccessfully(GenerateShaderCode(body).c_str());
2480 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2481 }
2482
TEST_F(ValidateImage,SampleProjImplicitLodWrongCoordinateType)2483 TEST_F(ValidateImage, SampleProjImplicitLodWrongCoordinateType) {
2484 const std::string body = R"(
2485 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2486 %sampler = OpLoad %type_sampler %uniform_sampler
2487 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2488 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %img
2489 )";
2490
2491 CompileSuccessfully(GenerateShaderCode(body).c_str());
2492 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2493 EXPECT_THAT(getDiagnosticString(),
2494 HasSubstr("Expected Coordinate to be float scalar or vector"));
2495 }
2496
TEST_F(ValidateImage,SampleProjImplicitLodCoordinateSizeTooSmall)2497 TEST_F(ValidateImage, SampleProjImplicitLodCoordinateSizeTooSmall) {
2498 const std::string body = R"(
2499 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2500 %sampler = OpLoad %type_sampler %uniform_sampler
2501 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2502 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh
2503 )";
2504
2505 CompileSuccessfully(GenerateShaderCode(body).c_str());
2506 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2507 EXPECT_THAT(getDiagnosticString(),
2508 HasSubstr("Expected Coordinate to have at least 3 components, "
2509 "but given only 2"));
2510 }
2511
TEST_F(ValidateImage,SampleDrefImplicitLodSuccess)2512 TEST_F(ValidateImage, SampleDrefImplicitLodSuccess) {
2513 const std::string body = R"(
2514 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2515 %sampler = OpLoad %type_sampler %uniform_sampler
2516 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2517 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1
2518 %res2 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
2519 %res4 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
2520 %res5 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
2521 %res6 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
2522 %res7 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2523 %res8 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
2524 )";
2525
2526 const std::string extra = R"(
2527 OpCapability VulkanMemoryModelKHR
2528 OpExtension "SPV_KHR_vulkan_memory_model"
2529 )";
2530 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2531 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2532 .c_str());
2533 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2534 }
2535
TEST_F(ValidateImage,SampleDrefImplicitLodWrongResultType)2536 TEST_F(ValidateImage, SampleDrefImplicitLodWrongResultType) {
2537 const std::string body = R"(
2538 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2539 %sampler = OpLoad %type_sampler %uniform_sampler
2540 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2541 %res1 = OpImageSampleDrefImplicitLod %void %simg %f32vec2_hh %u32_1
2542 )";
2543
2544 CompileSuccessfully(GenerateShaderCode(body).c_str());
2545 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2546 EXPECT_THAT(getDiagnosticString(),
2547 HasSubstr("Expected Result Type to be int or float scalar type"));
2548 }
2549
TEST_F(ValidateImage,SampleDrefImplicitLodNotSampledImage)2550 TEST_F(ValidateImage, SampleDrefImplicitLodNotSampledImage) {
2551 const std::string body = R"(
2552 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2553 %res1 = OpImageSampleDrefImplicitLod %u32 %img %f32vec2_hh %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("Expected Sampled Image to be of type OpTypeSampledImage"));
2561 }
2562
TEST_F(ValidateImage,SampleDrefImplicitLodMultisampleError)2563 TEST_F(ValidateImage, SampleDrefImplicitLodMultisampleError) {
2564 const std::string body = R"(
2565 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2566 %sampler = OpLoad %type_sampler %uniform_sampler
2567 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2568 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %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("Dref sampling operation is invalid for multisample image"));
2576 }
2577
TEST_F(ValidateImage,SampleDrefImplicitLodWrongSampledType)2578 TEST_F(ValidateImage, SampleDrefImplicitLodWrongSampledType) {
2579 const std::string body = R"(
2580 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2581 %sampler = OpLoad %type_sampler %uniform_sampler
2582 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2583 %res1 = OpImageSampleDrefImplicitLod %f32 %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,SampleDrefImplicitLodVoidSampledType)2593 TEST_F(ValidateImage, SampleDrefImplicitLodVoidSampledType) {
2594 const std::string body = R"(
2595 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2596 %sampler = OpLoad %type_sampler %uniform_sampler
2597 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2598 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %u32_1
2599 )";
2600
2601 CompileSuccessfully(GenerateShaderCode(body).c_str());
2602 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2603 EXPECT_THAT(
2604 getDiagnosticString(),
2605 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2606 }
2607
TEST_F(ValidateImage,SampleDrefImplicitLodWrongCoordinateType)2608 TEST_F(ValidateImage, SampleDrefImplicitLodWrongCoordinateType) {
2609 const std::string body = R"(
2610 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2611 %sampler = OpLoad %type_sampler %uniform_sampler
2612 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2613 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %img %u32_1
2614 )";
2615
2616 CompileSuccessfully(GenerateShaderCode(body).c_str());
2617 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2618 EXPECT_THAT(getDiagnosticString(),
2619 HasSubstr("Expected Coordinate to be float scalar or vector"));
2620 }
2621
TEST_F(ValidateImage,SampleDrefImplicitLodCoordinateSizeTooSmall)2622 TEST_F(ValidateImage, SampleDrefImplicitLodCoordinateSizeTooSmall) {
2623 const std::string body = R"(
2624 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2625 %sampler = OpLoad %type_sampler %uniform_sampler
2626 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2627 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32_0_5 %f32_0_5
2628 )";
2629
2630 CompileSuccessfully(GenerateShaderCode(body).c_str());
2631 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2632 EXPECT_THAT(getDiagnosticString(),
2633 HasSubstr("Expected Coordinate to have at least 2 components, "
2634 "but given only 1"));
2635 }
2636
TEST_F(ValidateImage,SampleDrefImplicitLodWrongDrefType)2637 TEST_F(ValidateImage, SampleDrefImplicitLodWrongDrefType) {
2638 const std::string body = R"(
2639 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2640 %sampler = OpLoad %type_sampler %uniform_sampler
2641 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2642 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %f64_1
2643 )";
2644
2645 CompileSuccessfully(GenerateShaderCode(body).c_str());
2646 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2647 EXPECT_THAT(getDiagnosticString(),
2648 HasSubstr("Expected Dref to be of 32-bit float type"));
2649 }
2650
TEST_F(ValidateImage,SampleDrefImplicitLodWrongDimVulkan)2651 TEST_F(ValidateImage, SampleDrefImplicitLodWrongDimVulkan) {
2652 const std::string body = R"(
2653 %img = OpLoad %type_image_u32_3d_0001 %uniform_image_u32_3d_0001
2654 %sampler = OpLoad %type_sampler %uniform_sampler
2655 %simg = OpSampledImage %type_sampled_image_u32_3d_0001 %img %sampler
2656 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_1
2657 )";
2658
2659 CompileSuccessfully(
2660 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
2661 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2662 EXPECT_THAT(getDiagnosticString(),
2663 AnyVUID("VUID-StandaloneSpirv-OpImage-04777"));
2664 EXPECT_THAT(getDiagnosticString(),
2665 HasSubstr("In Vulkan, OpImage*Dref* instructions must not use "
2666 "images with a 3D Dim"));
2667 }
2668
TEST_F(ValidateImage,SampleDrefExplicitLodSuccess)2669 TEST_F(ValidateImage, SampleDrefExplicitLodSuccess) {
2670 const std::string body = R"(
2671 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2672 %sampler = OpLoad %type_sampler %uniform_sampler
2673 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2674 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod %f32_1
2675 %res3 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad %f32vec3_hhh %f32vec3_hhh
2676 %res4 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 ConstOffset %s32vec3_012
2677 %res5 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Offset %s32vec3_012
2678 %res7 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad|Offset %f32vec3_hhh %f32vec3_hhh %s32vec3_012
2679 %res8 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod|NonPrivateTexelKHR %f32_1
2680 )";
2681
2682 const std::string extra = R"(
2683 OpCapability VulkanMemoryModelKHR
2684 OpExtension "SPV_KHR_vulkan_memory_model"
2685 )";
2686 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2687 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2688 .c_str());
2689 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2690 }
2691
TEST_F(ValidateImage,SampleDrefExplicitLodWrongResultType)2692 TEST_F(ValidateImage, SampleDrefExplicitLodWrongResultType) {
2693 const std::string body = R"(
2694 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2695 %sampler = OpLoad %type_sampler %uniform_sampler
2696 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2697 %res1 = OpImageSampleDrefExplicitLod %bool %simg %f32vec3_hhh %s32_1 Lod %f32_1
2698 )";
2699
2700 CompileSuccessfully(GenerateShaderCode(body).c_str());
2701 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2702 EXPECT_THAT(getDiagnosticString(),
2703 HasSubstr("Expected Result Type to be int or float scalar type"));
2704 }
2705
TEST_F(ValidateImage,SampleDrefExplicitLodNotSampledImage)2706 TEST_F(ValidateImage, SampleDrefExplicitLodNotSampledImage) {
2707 const std::string body = R"(
2708 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2709 %res1 = OpImageSampleDrefExplicitLod %s32 %img %f32vec3_hhh %s32_1 Lod %f32_1
2710 )";
2711
2712 CompileSuccessfully(GenerateShaderCode(body).c_str());
2713 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2714 EXPECT_THAT(
2715 getDiagnosticString(),
2716 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2717 }
2718
TEST_F(ValidateImage,SampleDrefExplicitLodMultisampleError)2719 TEST_F(ValidateImage, SampleDrefExplicitLodMultisampleError) {
2720 const std::string body = R"(
2721 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2722 %sampler = OpLoad %type_sampler %uniform_sampler
2723 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2724 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
2725 )";
2726
2727 CompileSuccessfully(GenerateShaderCode(body).c_str());
2728 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2729 EXPECT_THAT(
2730 getDiagnosticString(),
2731 HasSubstr("Dref sampling operation is invalid for multisample image"));
2732 }
2733
TEST_F(ValidateImage,SampleDrefExplicitLodWrongSampledType)2734 TEST_F(ValidateImage, SampleDrefExplicitLodWrongSampledType) {
2735 const std::string body = R"(
2736 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2737 %sampler = OpLoad %type_sampler %uniform_sampler
2738 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2739 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec3_hhh %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,SampleDrefExplicitLodVoidSampledType)2749 TEST_F(ValidateImage, SampleDrefExplicitLodVoidSampledType) {
2750 const std::string body = R"(
2751 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2752 %sampler = OpLoad %type_sampler %uniform_sampler
2753 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2754 %res1 = OpImageSampleDrefExplicitLod %u32 %simg %f32vec2_00 %s32_1 Lod %f32_1
2755 )";
2756
2757 CompileSuccessfully(GenerateShaderCode(body).c_str());
2758 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2759 EXPECT_THAT(
2760 getDiagnosticString(),
2761 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2762 }
2763
TEST_F(ValidateImage,SampleDrefExplicitLodWrongCoordinateType)2764 TEST_F(ValidateImage, SampleDrefExplicitLodWrongCoordinateType) {
2765 const std::string body = R"(
2766 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2767 %sampler = OpLoad %type_sampler %uniform_sampler
2768 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2769 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %img %s32_1 Lod %f32_1
2770 )";
2771
2772 CompileSuccessfully(GenerateShaderCode(body).c_str());
2773 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2774 EXPECT_THAT(getDiagnosticString(),
2775 HasSubstr("Expected Coordinate to be float scalar or vector"));
2776 }
2777
TEST_F(ValidateImage,SampleDrefExplicitLodCoordinateSizeTooSmall)2778 TEST_F(ValidateImage, SampleDrefExplicitLodCoordinateSizeTooSmall) {
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 %f32vec2_hh %s32_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 Coordinate to have at least 3 components, "
2790 "but given only 2"));
2791 }
2792
TEST_F(ValidateImage,SampleDrefExplicitLodWrongDrefType)2793 TEST_F(ValidateImage, SampleDrefExplicitLodWrongDrefType) {
2794 const std::string body = R"(
2795 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2796 %sampler = OpLoad %type_sampler %uniform_sampler
2797 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2798 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %u32_1 Lod %f32_1
2799 )";
2800
2801 CompileSuccessfully(GenerateShaderCode(body).c_str());
2802 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2803 EXPECT_THAT(getDiagnosticString(),
2804 HasSubstr("Expected Dref to be of 32-bit float type"));
2805 }
2806
TEST_F(ValidateImage,SampleProjDrefImplicitLodSuccess)2807 TEST_F(ValidateImage, SampleProjDrefImplicitLodSuccess) {
2808 const std::string body = R"(
2809 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2810 %sampler = OpLoad %type_sampler %uniform_sampler
2811 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2812 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5
2813 %res2 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias %f32_0_25
2814 %res4 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 ConstOffset %s32vec2_01
2815 %res5 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Offset %s32vec2_01
2816 %res6 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 MinLod %f32_0_5
2817 %res7 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2818 %res8 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 NonPrivateTexelKHR
2819 )";
2820
2821 const std::string extra = R"(
2822 OpCapability VulkanMemoryModelKHR
2823 OpExtension "SPV_KHR_vulkan_memory_model"
2824 )";
2825 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2826 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2827 .c_str());
2828 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2829 }
2830
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongResultType)2831 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongResultType) {
2832 const std::string body = R"(
2833 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2834 %sampler = OpLoad %type_sampler %uniform_sampler
2835 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2836 %res1 = OpImageSampleProjDrefImplicitLod %void %simg %f32vec3_hhh %f32_0_5
2837 )";
2838
2839 CompileSuccessfully(GenerateShaderCode(body).c_str());
2840 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2841 EXPECT_THAT(getDiagnosticString(),
2842 HasSubstr("Expected Result Type to be int or float scalar type"));
2843 }
2844
TEST_F(ValidateImage,SampleProjDrefImplicitLodNotSampledImage)2845 TEST_F(ValidateImage, SampleProjDrefImplicitLodNotSampledImage) {
2846 const std::string body = R"(
2847 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2848 %res1 = OpImageSampleProjDrefImplicitLod %f32 %img %f32vec3_hhh %f32_0_5
2849 )";
2850
2851 CompileSuccessfully(GenerateShaderCode(body).c_str());
2852 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2853 EXPECT_THAT(
2854 getDiagnosticString(),
2855 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2856 }
2857
TEST_F(ValidateImage,SampleProjDrefImplicitLodMultisampleError)2858 TEST_F(ValidateImage, SampleProjDrefImplicitLodMultisampleError) {
2859 const std::string body = R"(
2860 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2861 %sampler = OpLoad %type_sampler %uniform_sampler
2862 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
2863 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Sample %u32_1
2864 )";
2865
2866 CompileSuccessfully(GenerateShaderCode(body).c_str());
2867 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2868 EXPECT_THAT(
2869 getDiagnosticString(),
2870 HasSubstr("Dref sampling operation is invalid for multisample image"));
2871 }
2872
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongSampledType)2873 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongSampledType) {
2874 const std::string body = R"(
2875 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2876 %sampler = OpLoad %type_sampler %uniform_sampler
2877 %simg = OpSampledImage %type_sampled_image_f32_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,SampleProjDrefImplicitLodVoidSampledType)2888 TEST_F(ValidateImage, SampleProjDrefImplicitLodVoidSampledType) {
2889 const std::string body = R"(
2890 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2891 %sampler = OpLoad %type_sampler %uniform_sampler
2892 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2893 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2894 )";
2895
2896 CompileSuccessfully(GenerateShaderCode(body).c_str());
2897 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2898 EXPECT_THAT(
2899 getDiagnosticString(),
2900 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2901 }
2902
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongCoordinateType)2903 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongCoordinateType) {
2904 const std::string body = R"(
2905 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2906 %sampler = OpLoad %type_sampler %uniform_sampler
2907 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2908 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %img %f32_0_5
2909 )";
2910
2911 CompileSuccessfully(GenerateShaderCode(body).c_str());
2912 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2913 EXPECT_THAT(getDiagnosticString(),
2914 HasSubstr("Expected Coordinate to be float scalar or vector"));
2915 }
2916
TEST_F(ValidateImage,SampleProjDrefImplicitLodCoordinateSizeTooSmall)2917 TEST_F(ValidateImage, SampleProjDrefImplicitLodCoordinateSizeTooSmall) {
2918 const std::string body = R"(
2919 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2920 %sampler = OpLoad %type_sampler %uniform_sampler
2921 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2922 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec2_hh %f32_0_5
2923 )";
2924
2925 CompileSuccessfully(GenerateShaderCode(body).c_str());
2926 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2927 EXPECT_THAT(getDiagnosticString(),
2928 HasSubstr("Expected Coordinate to have at least 3 components, "
2929 "but given only 2"));
2930 }
2931
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongDrefType)2932 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongDrefType) {
2933 const std::string body = R"(
2934 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2935 %sampler = OpLoad %type_sampler %uniform_sampler
2936 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2937 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32vec4_0000
2938 )";
2939
2940 CompileSuccessfully(GenerateShaderCode(body).c_str());
2941 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2942 EXPECT_THAT(getDiagnosticString(),
2943 HasSubstr("Expected Dref to be of 32-bit float type"));
2944 }
2945
TEST_F(ValidateImage,SampleProjDrefExplicitLodSuccess)2946 TEST_F(ValidateImage, SampleProjDrefExplicitLodSuccess) {
2947 const std::string body = R"(
2948 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2949 %sampler = OpLoad %type_sampler %uniform_sampler
2950 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2951 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2952 %res2 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Grad %f32_0_5 %f32_0_5
2953 %res3 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 ConstOffset %s32_1
2954 %res4 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Offset %s32_1
2955 %res5 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Grad|Offset %f32_0_5 %f32_0_5 %s32_1
2956 %res6 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod|NonPrivateTexelKHR %f32_1
2957 )";
2958
2959 const std::string extra = R"(
2960 OpCapability VulkanMemoryModelKHR
2961 OpExtension "SPV_KHR_vulkan_memory_model"
2962 )";
2963 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2964 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2965 .c_str());
2966 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2967 }
2968
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongResultType)2969 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongResultType) {
2970 const std::string body = R"(
2971 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2972 %sampler = OpLoad %type_sampler %uniform_sampler
2973 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2974 %res1 = OpImageSampleProjDrefExplicitLod %bool %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2975 )";
2976
2977 CompileSuccessfully(GenerateShaderCode(body).c_str());
2978 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2979 EXPECT_THAT(getDiagnosticString(),
2980 HasSubstr("Expected Result Type to be int or float scalar type"));
2981 }
2982
TEST_F(ValidateImage,SampleProjDrefExplicitLodNotSampledImage)2983 TEST_F(ValidateImage, SampleProjDrefExplicitLodNotSampledImage) {
2984 const std::string body = R"(
2985 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2986 %res1 = OpImageSampleProjDrefExplicitLod %f32 %img %f32vec2_hh %f32_0_5 Lod %f32_1
2987 )";
2988
2989 CompileSuccessfully(GenerateShaderCode(body).c_str());
2990 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2991 EXPECT_THAT(
2992 getDiagnosticString(),
2993 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2994 }
2995
TEST_F(ValidateImage,SampleProjDrefExplicitLodMultisampleError)2996 TEST_F(ValidateImage, SampleProjDrefExplicitLodMultisampleError) {
2997 const std::string body = R"(
2998 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
2999 %sampler = OpLoad %type_sampler %uniform_sampler
3000 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
3001 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec2_hh %f32_1 Lod|Sample %f32_1 %u32_1
3002 )";
3003
3004 CompileSuccessfully(GenerateShaderCode(body).c_str());
3005 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3006 EXPECT_THAT(
3007 getDiagnosticString(),
3008 HasSubstr("Dref sampling operation is invalid for multisample image"));
3009 }
3010
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongSampledType)3011 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongSampledType) {
3012 const std::string body = R"(
3013 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
3014 %sampler = OpLoad %type_sampler %uniform_sampler
3015 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
3016 %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec2_hh %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,SampleProjDrefExplicitLodVoidSampledType)3026 TEST_F(ValidateImage, SampleProjDrefExplicitLodVoidSampledType) {
3027 const std::string body = R"(
3028 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3029 %sampler = OpLoad %type_sampler %uniform_sampler
3030 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
3031 %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec3_hhh %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(
3037 getDiagnosticString(),
3038 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
3039 }
3040
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongCoordinateType)3041 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongCoordinateType) {
3042 const std::string body = R"(
3043 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
3044 %sampler = OpLoad %type_sampler %uniform_sampler
3045 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
3046 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %img %f32_0_5 Lod %f32_1
3047 )";
3048
3049 CompileSuccessfully(GenerateShaderCode(body).c_str());
3050 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3051 EXPECT_THAT(getDiagnosticString(),
3052 HasSubstr("Expected Coordinate to be float scalar or vector"));
3053 }
3054
TEST_F(ValidateImage,SampleProjDrefExplicitLodCoordinateSizeTooSmall)3055 TEST_F(ValidateImage, SampleProjDrefExplicitLodCoordinateSizeTooSmall) {
3056 const std::string body = R"(
3057 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
3058 %sampler = OpLoad %type_sampler %uniform_sampler
3059 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
3060 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32_0_5 %f32_0_5 Lod %f32_1
3061 )";
3062
3063 CompileSuccessfully(GenerateShaderCode(body).c_str());
3064 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3065 EXPECT_THAT(getDiagnosticString(),
3066 HasSubstr("Expected Coordinate to have at least 2 components, "
3067 "but given only 1"));
3068 }
3069
TEST_F(ValidateImage,FetchSuccess)3070 TEST_F(ValidateImage, FetchSuccess) {
3071 const std::string body = R"(
3072 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
3073 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
3074 %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
3075 )";
3076
3077 const std::string extra = R"(
3078 OpCapability VulkanMemoryModelKHR
3079 OpExtension "SPV_KHR_vulkan_memory_model"
3080 )";
3081 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3082 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3083 .c_str());
3084 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3085 }
3086
TEST_F(ValidateImage,FetchMultisampledSuccess)3087 TEST_F(ValidateImage, FetchMultisampledSuccess) {
3088 const std::string body = R"(
3089 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3090 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample %u32_1
3091 %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 Sample|NonPrivateTexelKHR %u32_1
3092 )";
3093
3094 const std::string extra = R"(
3095 OpCapability VulkanMemoryModelKHR
3096 OpExtension "SPV_KHR_vulkan_memory_model"
3097 )";
3098 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3099 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3100 .c_str());
3101 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3102 }
3103
TEST_F(ValidateImage,FetchWrongResultType)3104 TEST_F(ValidateImage, FetchWrongResultType) {
3105 const std::string body = R"(
3106 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3107 %res1 = OpImageFetch %f32 %img %u32vec2_01
3108 )";
3109
3110 CompileSuccessfully(GenerateShaderCode(body).c_str());
3111 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3112 EXPECT_THAT(getDiagnosticString(),
3113 HasSubstr("Expected Result Type to be int or float vector type"));
3114 }
3115
TEST_F(ValidateImage,FetchWrongNumComponentsResultType)3116 TEST_F(ValidateImage, FetchWrongNumComponentsResultType) {
3117 const std::string body = R"(
3118 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3119 %res1 = OpImageFetch %f32vec3 %img %u32vec2_01
3120 )";
3121
3122 CompileSuccessfully(GenerateShaderCode(body).c_str());
3123 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3124 EXPECT_THAT(getDiagnosticString(),
3125 HasSubstr("Expected Result Type to have 4 components"));
3126 }
3127
TEST_F(ValidateImage,FetchNotImage)3128 TEST_F(ValidateImage, FetchNotImage) {
3129 const std::string body = R"(
3130 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3131 %sampler = OpLoad %type_sampler %uniform_sampler
3132 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3133 %res1 = OpImageFetch %f32vec4 %sampler %u32vec2_01
3134 )";
3135
3136 CompileSuccessfully(GenerateShaderCode(body).c_str());
3137 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3138 EXPECT_THAT(getDiagnosticString(),
3139 HasSubstr("Expected Image to be of type OpTypeImage"));
3140 }
3141
TEST_F(ValidateImage,FetchSampledImageDirectly)3142 TEST_F(ValidateImage, FetchSampledImageDirectly) {
3143 const std::string body = R"(
3144 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3145 %sampler = OpLoad %type_sampler %uniform_sampler
3146 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3147 %res1 = OpImageFetch %f32vec4 %simg %u32vec2_01
3148 )";
3149
3150 CompileSuccessfully(GenerateShaderCode(body).c_str());
3151 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3152 EXPECT_THAT(getDiagnosticString(),
3153 HasSubstr("OpSampledImage instruction must not appear as operand "
3154 "for OpImageFetch"));
3155 }
3156
TEST_F(ValidateImage,FetchNotSampled)3157 TEST_F(ValidateImage, FetchNotSampled) {
3158 const std::string body = R"(
3159 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3160 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
3161 )";
3162
3163 CompileSuccessfully(GenerateShaderCode(body).c_str());
3164 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3165 EXPECT_THAT(getDiagnosticString(),
3166 HasSubstr("Expected Image 'Sampled' parameter to be 1"));
3167 }
3168
TEST_F(ValidateImage,FetchCube)3169 TEST_F(ValidateImage, FetchCube) {
3170 const std::string body = R"(
3171 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3172 %res1 = OpImageFetch %f32vec4 %img %u32vec3_012
3173 )";
3174
3175 CompileSuccessfully(GenerateShaderCode(body).c_str());
3176 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3177 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' cannot be Cube"));
3178 }
3179
TEST_F(ValidateImage,FetchWrongSampledType)3180 TEST_F(ValidateImage, FetchWrongSampledType) {
3181 const std::string body = R"(
3182 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3183 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
3184 )";
3185
3186 CompileSuccessfully(GenerateShaderCode(body).c_str());
3187 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3188 EXPECT_THAT(getDiagnosticString(),
3189 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3190 "Result Type components"));
3191 }
3192
TEST_F(ValidateImage,FetchVoidSampledType)3193 TEST_F(ValidateImage, FetchVoidSampledType) {
3194 const std::string body = R"(
3195 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3196 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
3197 %res2 = OpImageFetch %u32vec4 %img %u32vec2_01
3198 %res3 = OpImageFetch %s32vec4 %img %u32vec2_01
3199 )";
3200
3201 CompileSuccessfully(GenerateShaderCode(body).c_str());
3202 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3203 }
3204
TEST_F(ValidateImage,FetchWrongCoordinateType)3205 TEST_F(ValidateImage, FetchWrongCoordinateType) {
3206 const std::string body = R"(
3207 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3208 %res1 = OpImageFetch %f32vec4 %img %f32vec2_00
3209 )";
3210
3211 CompileSuccessfully(GenerateShaderCode(body).c_str());
3212 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3213 EXPECT_THAT(getDiagnosticString(),
3214 HasSubstr("Expected Coordinate to be int scalar or vector"));
3215 }
3216
TEST_F(ValidateImage,FetchCoordinateSizeTooSmall)3217 TEST_F(ValidateImage, FetchCoordinateSizeTooSmall) {
3218 const std::string body = R"(
3219 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3220 %res1 = OpImageFetch %f32vec4 %img %u32_1
3221 )";
3222
3223 CompileSuccessfully(GenerateShaderCode(body).c_str());
3224 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3225 EXPECT_THAT(getDiagnosticString(),
3226 HasSubstr("Expected Coordinate to have at least 2 components, "
3227 "but given only 1"));
3228 }
3229
TEST_F(ValidateImage,FetchLodNotInt)3230 TEST_F(ValidateImage, FetchLodNotInt) {
3231 const std::string body = R"(
3232 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3233 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Lod %f32_1
3234 )";
3235
3236 CompileSuccessfully(GenerateShaderCode(body).c_str());
3237 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3238 EXPECT_THAT(getDiagnosticString(),
3239 HasSubstr("Expected Image Operand Lod to be int scalar when used "
3240 "with OpImageFetch"));
3241 }
3242
TEST_F(ValidateImage,FetchMultisampledMissingSample)3243 TEST_F(ValidateImage, FetchMultisampledMissingSample) {
3244 const std::string body = R"(
3245 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3246 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
3247 )";
3248
3249 CompileSuccessfully(GenerateShaderCode(body).c_str());
3250 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions())
3251 << GenerateShaderCode(body);
3252 EXPECT_THAT(getDiagnosticString(),
3253 HasSubstr("Image Operand Sample is required for operation on "
3254 "multi-sampled image"))
3255 << getDiagnosticString();
3256 }
3257
TEST_F(ValidateImage,GatherSuccess)3258 TEST_F(ValidateImage, GatherSuccess) {
3259 const std::string body = R"(
3260 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3261 %sampler = OpLoad %type_sampler %uniform_sampler
3262 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3263 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1
3264 %res2 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
3265 %res3 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
3266 )";
3267
3268 const std::string extra = R"(
3269 OpCapability VulkanMemoryModelKHR
3270 OpExtension "SPV_KHR_vulkan_memory_model"
3271 )";
3272 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3273 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3274 .c_str());
3275 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3276 }
3277
TEST_F(ValidateImage,GatherWrongResultType)3278 TEST_F(ValidateImage, GatherWrongResultType) {
3279 const std::string body = R"(
3280 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3281 %sampler = OpLoad %type_sampler %uniform_sampler
3282 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3283 %res1 = OpImageGather %f32 %simg %f32vec4_0000 %u32_1
3284 )";
3285
3286 CompileSuccessfully(GenerateShaderCode(body).c_str());
3287 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3288 EXPECT_THAT(getDiagnosticString(),
3289 HasSubstr("Expected Result Type to be int or float vector type"));
3290 }
3291
TEST_F(ValidateImage,GatherWrongNumComponentsResultType)3292 TEST_F(ValidateImage, GatherWrongNumComponentsResultType) {
3293 const std::string body = R"(
3294 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3295 %sampler = OpLoad %type_sampler %uniform_sampler
3296 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3297 %res1 = OpImageGather %f32vec3 %simg %f32vec4_0000 %u32_1
3298 )";
3299
3300 CompileSuccessfully(GenerateShaderCode(body).c_str());
3301 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3302 EXPECT_THAT(getDiagnosticString(),
3303 HasSubstr("Expected Result Type to have 4 components"));
3304 }
3305
TEST_F(ValidateImage,GatherNotSampledImage)3306 TEST_F(ValidateImage, GatherNotSampledImage) {
3307 const std::string body = R"(
3308 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3309 %res1 = OpImageGather %f32vec4 %img %f32vec4_0000 %u32_1
3310 )";
3311
3312 CompileSuccessfully(GenerateShaderCode(body).c_str());
3313 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3314 EXPECT_THAT(
3315 getDiagnosticString(),
3316 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
3317 }
3318
TEST_F(ValidateImage,GatherMultisampleError)3319 TEST_F(ValidateImage, GatherMultisampleError) {
3320 const std::string body = R"(
3321 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3322 %sampler = OpLoad %type_sampler %uniform_sampler
3323 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
3324 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Sample %u32_1
3325 )";
3326
3327 CompileSuccessfully(GenerateShaderCode(body).c_str());
3328 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3329 EXPECT_THAT(getDiagnosticString(),
3330 HasSubstr("Gather operation is invalid for multisample image"));
3331 }
3332
TEST_F(ValidateImage,GatherWrongSampledType)3333 TEST_F(ValidateImage, GatherWrongSampledType) {
3334 const std::string body = R"(
3335 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3336 %sampler = OpLoad %type_sampler %uniform_sampler
3337 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3338 %res1 = OpImageGather %u32vec4 %simg %f32vec4_0000 %u32_1
3339 )";
3340
3341 CompileSuccessfully(GenerateShaderCode(body).c_str());
3342 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3343 EXPECT_THAT(getDiagnosticString(),
3344 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3345 "Result Type components"));
3346 }
3347
TEST_F(ValidateImage,GatherVoidSampledType)3348 TEST_F(ValidateImage, GatherVoidSampledType) {
3349 const std::string body = R"(
3350 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3351 %sampler = OpLoad %type_sampler %uniform_sampler
3352 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
3353 %res1 = OpImageGather %u32vec4 %simg %f32vec2_00 %u32_1
3354 )";
3355
3356 CompileSuccessfully(GenerateShaderCode(body).c_str());
3357 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3358 }
3359
TEST_F(ValidateImage,GatherWrongCoordinateType)3360 TEST_F(ValidateImage, GatherWrongCoordinateType) {
3361 const std::string body = R"(
3362 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3363 %sampler = OpLoad %type_sampler %uniform_sampler
3364 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3365 %res1 = OpImageGather %f32vec4 %simg %u32vec4_0123 %u32_1
3366 )";
3367
3368 CompileSuccessfully(GenerateShaderCode(body).c_str());
3369 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3370 EXPECT_THAT(getDiagnosticString(),
3371 HasSubstr("Expected Coordinate to be float scalar or vector"));
3372 }
3373
TEST_F(ValidateImage,GatherCoordinateSizeTooSmall)3374 TEST_F(ValidateImage, GatherCoordinateSizeTooSmall) {
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 %f32_0_5 %u32_1
3380 )";
3381
3382 CompileSuccessfully(GenerateShaderCode(body).c_str());
3383 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3384 EXPECT_THAT(getDiagnosticString(),
3385 HasSubstr("Expected Coordinate to have at least 4 components, "
3386 "but given only 1"));
3387 }
3388
TEST_F(ValidateImage,GatherWrongComponentType)3389 TEST_F(ValidateImage, GatherWrongComponentType) {
3390 const std::string body = R"(
3391 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3392 %sampler = OpLoad %type_sampler %uniform_sampler
3393 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3394 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %f32_1
3395 )";
3396
3397 CompileSuccessfully(GenerateShaderCode(body).c_str());
3398 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3399 EXPECT_THAT(getDiagnosticString(),
3400 HasSubstr("Expected Component to be 32-bit int scalar"));
3401 }
3402
TEST_F(ValidateImage,GatherComponentNot32Bit)3403 TEST_F(ValidateImage, GatherComponentNot32Bit) {
3404 const std::string body = R"(
3405 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3406 %sampler = OpLoad %type_sampler %uniform_sampler
3407 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3408 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u64_0
3409 )";
3410
3411 CompileSuccessfully(GenerateShaderCode(body).c_str());
3412 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3413 EXPECT_THAT(getDiagnosticString(),
3414 HasSubstr("Expected Component to be 32-bit int scalar"));
3415 }
3416
TEST_F(ValidateImage,GatherComponentSuccessVulkan)3417 TEST_F(ValidateImage, GatherComponentSuccessVulkan) {
3418 const std::string body = R"(
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 %u32_0
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_SUCCESS, ValidateInstructions(env));
3429 }
3430
TEST_F(ValidateImage,GatherComponentNotConstantVulkan)3431 TEST_F(ValidateImage, GatherComponentNotConstantVulkan) {
3432 const std::string body = R"(
3433 %input_u32 = OpLoad %u32 %input_flat_u32
3434 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3435 %sampler = OpLoad %type_sampler %uniform_sampler
3436 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3437 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %input_u32
3438 )";
3439
3440 spv_target_env env = SPV_ENV_VULKAN_1_0;
3441 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3442 env);
3443 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3444 EXPECT_THAT(getDiagnosticString(),
3445 AnyVUID("VUID-StandaloneSpirv-OpImageGather-04664"));
3446 EXPECT_THAT(getDiagnosticString(),
3447 HasSubstr("Expected Component Operand to be a const object for "
3448 "Vulkan environment"));
3449 }
3450
TEST_F(ValidateImage,GatherDimCube)3451 TEST_F(ValidateImage, GatherDimCube) {
3452 const std::string body = R"(
3453 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3454 %sampler = OpLoad %type_sampler %uniform_sampler
3455 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3456 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
3457 )";
3458
3459 CompileSuccessfully(GenerateShaderCode(body).c_str());
3460 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3461 EXPECT_THAT(
3462 getDiagnosticString(),
3463 HasSubstr(
3464 "Image Operand ConstOffsets cannot be used with Cube Image 'Dim'"));
3465 }
3466
TEST_F(ValidateImage,GatherConstOffsetsNotArray)3467 TEST_F(ValidateImage, GatherConstOffsetsNotArray) {
3468 const std::string body = R"(
3469 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3470 %sampler = OpLoad %type_sampler %uniform_sampler
3471 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3472 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %u32vec4_0123
3473 )";
3474
3475 CompileSuccessfully(GenerateShaderCode(body).c_str());
3476 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3477 EXPECT_THAT(
3478 getDiagnosticString(),
3479 HasSubstr(
3480 "Expected Image Operand ConstOffsets to be an array of size 4"));
3481 }
3482
TEST_F(ValidateImage,GatherConstOffsetsArrayWrongSize)3483 TEST_F(ValidateImage, GatherConstOffsetsArrayWrongSize) {
3484 const std::string body = R"(
3485 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3486 %sampler = OpLoad %type_sampler %uniform_sampler
3487 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3488 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets3x2
3489 )";
3490
3491 CompileSuccessfully(GenerateShaderCode(body).c_str());
3492 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3493 EXPECT_THAT(
3494 getDiagnosticString(),
3495 HasSubstr(
3496 "Expected Image Operand ConstOffsets to be an array of size 4"));
3497 }
3498
TEST_F(ValidateImage,GatherConstOffsetsArrayNotVector)3499 TEST_F(ValidateImage, GatherConstOffsetsArrayNotVector) {
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_offsets4xu
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,GatherConstOffsetsArrayVectorWrongSize)3514 TEST_F(ValidateImage, GatherConstOffsetsArrayVectorWrongSize) {
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 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4x3
3520 )";
3521
3522 CompileSuccessfully(GenerateShaderCode(body).c_str());
3523 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3524 EXPECT_THAT(getDiagnosticString(),
3525 HasSubstr("Expected Image Operand ConstOffsets array components "
3526 "to be int vectors of size 2"));
3527 }
3528
TEST_F(ValidateImage,GatherConstOffsetsArrayNotConst)3529 TEST_F(ValidateImage, GatherConstOffsetsArrayNotConst) {
3530 const std::string body = R"(
3531 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3532 %sampler = OpLoad %type_sampler %uniform_sampler
3533 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3534 %offsets = OpUndef %u32vec2arr4
3535 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %offsets
3536 )";
3537
3538 CompileSuccessfully(GenerateShaderCode(body).c_str());
3539 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3540 EXPECT_THAT(
3541 getDiagnosticString(),
3542 HasSubstr("Expected Image Operand ConstOffsets to be a const object"));
3543 }
3544
TEST_F(ValidateImage,NotGatherWithConstOffsets)3545 TEST_F(ValidateImage, NotGatherWithConstOffsets) {
3546 const std::string body = R"(
3547 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3548 %sampler = OpLoad %type_sampler %uniform_sampler
3549 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3550 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffsets %const_offsets
3551 )";
3552
3553 CompileSuccessfully(GenerateShaderCode(body).c_str());
3554 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3555 EXPECT_THAT(
3556 getDiagnosticString(),
3557 HasSubstr(
3558 "Image Operand ConstOffsets can only be used with OpImageGather "
3559 "and OpImageDrefGather"));
3560 }
3561
TEST_F(ValidateImage,DrefGatherSuccess)3562 TEST_F(ValidateImage, DrefGatherSuccess) {
3563 const std::string body = R"(
3564 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3565 %sampler = OpLoad %type_sampler %uniform_sampler
3566 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3567 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
3568 %res2 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 ConstOffsets %const_offsets
3569 %res3 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 NonPrivateTexelKHR
3570 )";
3571
3572 const std::string extra = R"(
3573 OpCapability VulkanMemoryModelKHR
3574 OpExtension "SPV_KHR_vulkan_memory_model"
3575 )";
3576 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3577 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3578 .c_str());
3579 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3580 }
3581
TEST_F(ValidateImage,DrefGatherMultisampleError)3582 TEST_F(ValidateImage, DrefGatherMultisampleError) {
3583 const std::string body = R"(
3584 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
3585 %sampler = OpLoad %type_sampler %uniform_sampler
3586 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
3587 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_1 Sample %u32_1
3588 )";
3589
3590 CompileSuccessfully(GenerateShaderCode(body).c_str());
3591 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3592 EXPECT_THAT(getDiagnosticString(),
3593 HasSubstr("Gather operation is invalid for multisample image"));
3594 }
3595
TEST_F(ValidateImage,DrefGatherVoidSampledType)3596 TEST_F(ValidateImage, DrefGatherVoidSampledType) {
3597 const std::string body = R"(
3598 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
3599 %sampler = OpLoad %type_sampler %uniform_sampler
3600 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
3601 %res1 = OpImageDrefGather %u32vec4 %simg %f32vec2_00 %f32_0_5
3602 )";
3603
3604 CompileSuccessfully(GenerateShaderCode(body).c_str());
3605 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3606 EXPECT_THAT(getDiagnosticString(),
3607 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3608 "Result Type components"));
3609 }
3610
TEST_F(ValidateImage,DrefGatherWrongDrefType)3611 TEST_F(ValidateImage, DrefGatherWrongDrefType) {
3612 const std::string body = R"(
3613 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
3614 %sampler = OpLoad %type_sampler %uniform_sampler
3615 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
3616 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %u32_1
3617 )";
3618
3619 CompileSuccessfully(GenerateShaderCode(body).c_str());
3620 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3621 EXPECT_THAT(getDiagnosticString(),
3622 HasSubstr("Expected Dref to be of 32-bit float type"));
3623 }
3624
TEST_F(ValidateImage,DrefGatherWrongDimVulkan)3625 TEST_F(ValidateImage, DrefGatherWrongDimVulkan) {
3626 const std::string body = R"(
3627 %img = OpLoad %type_image_f32_3d_0001 %uniform_image_f32_3d_0001
3628 %sampler = OpLoad %type_sampler %uniform_sampler
3629 %simg = OpSampledImage %type_sampled_image_f32_3d_0001 %img %sampler
3630 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
3631 )";
3632
3633 CompileSuccessfully(
3634 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
3635 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3636 EXPECT_THAT(getDiagnosticString(),
3637 AnyVUID("VUID-StandaloneSpirv-OpImage-04777"));
3638 EXPECT_THAT(getDiagnosticString(),
3639 HasSubstr("Expected Image 'Dim' to be 2D, Cube, or Rect"));
3640 }
3641
TEST_F(ValidateImage,ReadSuccess1)3642 TEST_F(ValidateImage, ReadSuccess1) {
3643 const std::string body = R"(
3644 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3645 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
3646 )";
3647
3648 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3649 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3650 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3651 }
3652
TEST_F(ValidateImage,ReadSuccess2)3653 TEST_F(ValidateImage, ReadSuccess2) {
3654 const std::string body = R"(
3655 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3656 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3657 )";
3658
3659 const std::string extra = "\nOpCapability Image1D\n";
3660 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3661 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3662 }
3663
TEST_F(ValidateImage,ReadSuccess3)3664 TEST_F(ValidateImage, ReadSuccess3) {
3665 const std::string body = R"(
3666 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3667 %res1 = OpImageRead %f32vec4 %img %u32vec3_012
3668 )";
3669
3670 const std::string extra = "\nOpCapability ImageCubeArray\n";
3671 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3672 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3673 }
3674
TEST_F(ValidateImage,ReadSuccess4)3675 TEST_F(ValidateImage, ReadSuccess4) {
3676 const std::string body = R"(
3677 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3678 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3679 )";
3680
3681 CompileSuccessfully(GenerateShaderCode(body).c_str());
3682 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3683 }
3684
TEST_F(ValidateImage,ReadNeedCapabilityStorageImageReadWithoutFormat)3685 TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) {
3686 const std::string body = R"(
3687 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3688 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
3689 )";
3690
3691 CompileSuccessfully(GenerateShaderCode(body).c_str());
3692 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3693 }
3694
TEST_F(ValidateImage,ReadNeedCapabilityStorageImageReadWithoutFormatVulkan)3695 TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) {
3696 const std::string body = R"(
3697 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3698 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
3699 )";
3700
3701 spv_target_env env = SPV_ENV_VULKAN_1_0;
3702 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3703 env);
3704 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3705 EXPECT_THAT(getDiagnosticString(),
3706 HasSubstr("Capability StorageImageReadWithoutFormat is required "
3707 "to read storage image"));
3708 }
3709
TEST_F(ValidateImage,ReadNeedCapabilityImage1D)3710 TEST_F(ValidateImage, ReadNeedCapabilityImage1D) {
3711 const std::string body = R"(
3712 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3713 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3714 )";
3715
3716 CompileSuccessfully(GenerateShaderCode(body).c_str());
3717 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3718 EXPECT_THAT(
3719 getDiagnosticString(),
3720 HasSubstr("Capability Image1D is required to access storage image"));
3721 }
3722
TEST_F(ValidateImage,ReadNeedCapabilityImageCubeArray)3723 TEST_F(ValidateImage, ReadNeedCapabilityImageCubeArray) {
3724 const std::string body = R"(
3725 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3726 %res1 = OpImageRead %f32vec4 %img %u32vec3_012
3727 )";
3728
3729 CompileSuccessfully(GenerateShaderCode(body).c_str());
3730 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3731 EXPECT_THAT(
3732 getDiagnosticString(),
3733 HasSubstr(
3734 "Capability ImageCubeArray is required to access storage image"));
3735 }
3736
3737 // TODO(atgoo@github.com) Disabled until the spec is clarified.
TEST_F(ValidateImage,DISABLED_ReadWrongResultType)3738 TEST_F(ValidateImage, DISABLED_ReadWrongResultType) {
3739 const std::string body = R"(
3740 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3741 %res1 = OpImageRead %f32 %img %u32vec2_01
3742 )";
3743
3744 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3745 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3746 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3747 EXPECT_THAT(getDiagnosticString(),
3748 HasSubstr("Expected Result Type to be int or float vector type"));
3749 }
3750
TEST_F(ValidateImage,ReadScalarResultType_Universal)3751 TEST_F(ValidateImage, ReadScalarResultType_Universal) {
3752 const std::string body = R"(
3753 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3754 %res1 = OpImageRead %u32 %img %u32vec2_01
3755 )";
3756
3757 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3758 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3759 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
3760 EXPECT_THAT(getDiagnosticString(), Eq(""));
3761 }
3762
TEST_F(ValidateImage,ReadUnusualNumComponentsResultType_Universal)3763 TEST_F(ValidateImage, ReadUnusualNumComponentsResultType_Universal) {
3764 const std::string body = R"(
3765 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3766 %res1 = OpImageRead %u32vec3 %img %u32vec2_01
3767 )";
3768
3769 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3770 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3771 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
3772 EXPECT_THAT(getDiagnosticString(), Eq(""));
3773 }
3774
TEST_F(ValidateImage,ReadWrongNumComponentsResultType_Vulkan)3775 TEST_F(ValidateImage, ReadWrongNumComponentsResultType_Vulkan) {
3776 const std::string body = R"(
3777 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3778 %res1 = OpImageRead %u32vec3 %img %u32vec2_01
3779 )";
3780
3781 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3782 CompileSuccessfully(
3783 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_VULKAN_1_0)
3784 .c_str());
3785 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3786 EXPECT_THAT(getDiagnosticString(),
3787 AnyVUID("VUID-StandaloneSpirv-Result-04780"));
3788 EXPECT_THAT(getDiagnosticString(),
3789 HasSubstr("Expected Result Type to have 4 components"));
3790 }
3791
TEST_F(ValidateImage,ReadNotImage)3792 TEST_F(ValidateImage, ReadNotImage) {
3793 const std::string body = R"(
3794 %sampler = OpLoad %type_sampler %uniform_sampler
3795 %res1 = OpImageRead %f32vec4 %sampler %u32vec2_01
3796 )";
3797
3798 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3799 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3800 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3801 EXPECT_THAT(getDiagnosticString(),
3802 HasSubstr("Expected Image to be of type OpTypeImage"));
3803 }
3804
TEST_F(ValidateImage,ReadImageSampled)3805 TEST_F(ValidateImage, ReadImageSampled) {
3806 const std::string body = R"(
3807 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3808 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3809 )";
3810
3811 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3812 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3813 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3814 EXPECT_THAT(getDiagnosticString(),
3815 HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
3816 }
3817
TEST_F(ValidateImage,ReadWrongSampledType)3818 TEST_F(ValidateImage, ReadWrongSampledType) {
3819 const std::string body = R"(
3820 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3821 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3822 )";
3823
3824 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3825 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3826 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3827 EXPECT_THAT(getDiagnosticString(),
3828 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3829 "Result Type components"));
3830 }
3831
TEST_F(ValidateImage,ReadVoidSampledType)3832 TEST_F(ValidateImage, ReadVoidSampledType) {
3833 const std::string body = R"(
3834 %img = OpLoad %type_image_void_2d_0002 %uniform_image_void_2d_0002
3835 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3836 %res2 = OpImageRead %u32vec4 %img %u32vec2_01
3837 %res3 = OpImageRead %s32vec4 %img %u32vec2_01
3838 )";
3839
3840 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3841 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3842 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3843 }
3844
TEST_F(ValidateImage,ReadWrongCoordinateType)3845 TEST_F(ValidateImage, ReadWrongCoordinateType) {
3846 const std::string body = R"(
3847 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3848 %res1 = OpImageRead %u32vec4 %img %f32vec2_00
3849 )";
3850
3851 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3852 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3853 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3854 EXPECT_THAT(getDiagnosticString(),
3855 HasSubstr("Expected Coordinate to be int scalar or vector"));
3856 }
3857
TEST_F(ValidateImage,ReadCoordinateSizeTooSmall)3858 TEST_F(ValidateImage, ReadCoordinateSizeTooSmall) {
3859 const std::string body = R"(
3860 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3861 %res1 = OpImageRead %u32vec4 %img %u32_1
3862 )";
3863
3864 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3865 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3866 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3867 EXPECT_THAT(getDiagnosticString(),
3868 HasSubstr("Expected Coordinate to have at least 2 components, "
3869 "but given only 1"));
3870 }
3871
TEST_F(ValidateImage,WriteSuccess1)3872 TEST_F(ValidateImage, WriteSuccess1) {
3873 const std::string body = R"(
3874 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3875 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3876 )";
3877
3878 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3879 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3880 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3881 }
3882
TEST_F(ValidateImage,WriteSuccess2)3883 TEST_F(ValidateImage, WriteSuccess2) {
3884 const std::string body = R"(
3885 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3886 OpImageWrite %img %u32_1 %f32vec4_0000
3887 )";
3888
3889 const std::string extra = "\nOpCapability Image1D\n";
3890 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3891 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3892 }
3893
TEST_F(ValidateImage,WriteSuccess3)3894 TEST_F(ValidateImage, WriteSuccess3) {
3895 const std::string body = R"(
3896 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3897 OpImageWrite %img %u32vec3_012 %f32vec4_0000
3898 )";
3899
3900 const std::string extra = "\nOpCapability ImageCubeArray\n";
3901 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3902 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3903 }
3904
TEST_F(ValidateImage,WriteSuccess4)3905 TEST_F(ValidateImage, WriteSuccess4) {
3906 const std::string body = R"(
3907 %img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
3908 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
3909 )";
3910
3911 const std::string extra = R"(
3912 OpCapability StorageImageWriteWithoutFormat
3913 OpCapability StorageImageMultisample
3914 )";
3915
3916 const std::string declarations = R"(
3917 %type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
3918 %ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
3919 %uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
3920 )";
3921 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3922 SPV_ENV_UNIVERSAL_1_0, "GLSL450",
3923 declarations)
3924 .c_str());
3925 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3926 }
3927
TEST_F(ValidateImage,WriteSubpassData)3928 TEST_F(ValidateImage, WriteSubpassData) {
3929 const std::string body = R"(
3930 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3931 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3932 )";
3933
3934 CompileSuccessfully(GenerateShaderCode(body).c_str());
3935 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3936 EXPECT_THAT(getDiagnosticString(),
3937 HasSubstr("Image 'Dim' cannot be SubpassData"));
3938 }
3939
TEST_F(ValidateImage,WriteNeedCapabilityStorageImageWriteWithoutFormat)3940 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
3941 const std::string body = R"(
3942 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3943 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3944 )";
3945
3946 CompileSuccessfully(GenerateShaderCode(body).c_str());
3947 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3948 }
3949
TEST_F(ValidateImage,WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan)3950 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
3951 const std::string body = R"(
3952 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
3953 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3954 )";
3955
3956 spv_target_env env = SPV_ENV_VULKAN_1_0;
3957 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3958 env);
3959 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3960 EXPECT_THAT(
3961 getDiagnosticString(),
3962 HasSubstr(
3963 "Capability StorageImageWriteWithoutFormat is required to write to "
3964 "storage image"));
3965 }
3966
TEST_F(ValidateImage,WriteNeedCapabilityImage1D)3967 TEST_F(ValidateImage, WriteNeedCapabilityImage1D) {
3968 const std::string body = R"(
3969 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3970 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3971 )";
3972
3973 CompileSuccessfully(GenerateShaderCode(body).c_str());
3974 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3975 EXPECT_THAT(getDiagnosticString(),
3976 HasSubstr("Capability Image1D is required to access storage "
3977 "image"));
3978 }
3979
TEST_F(ValidateImage,WriteNeedCapabilityImageCubeArray)3980 TEST_F(ValidateImage, WriteNeedCapabilityImageCubeArray) {
3981 const std::string body = R"(
3982 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3983 OpImageWrite %img %u32vec3_012 %f32vec4_0000
3984 )";
3985
3986 CompileSuccessfully(GenerateShaderCode(body).c_str());
3987 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3988 EXPECT_THAT(
3989 getDiagnosticString(),
3990 HasSubstr(
3991 "Capability ImageCubeArray is required to access storage image"));
3992 }
3993
TEST_F(ValidateImage,WriteNotImage)3994 TEST_F(ValidateImage, WriteNotImage) {
3995 const std::string body = R"(
3996 %sampler = OpLoad %type_sampler %uniform_sampler
3997 OpImageWrite %sampler %u32vec2_01 %f32vec4_0000
3998 )";
3999
4000 CompileSuccessfully(GenerateShaderCode(body).c_str());
4001 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4002 EXPECT_THAT(getDiagnosticString(),
4003 HasSubstr("Expected Image to be of type OpTypeImage"));
4004 }
4005
TEST_F(ValidateImage,WriteImageSampled)4006 TEST_F(ValidateImage, WriteImageSampled) {
4007 const std::string body = R"(
4008 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4009 OpImageWrite %img %u32vec2_01 %f32vec4_0000
4010 )";
4011
4012 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4013 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4014 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4015 EXPECT_THAT(getDiagnosticString(),
4016 HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
4017 }
4018
TEST_F(ValidateImage,WriteWrongCoordinateType)4019 TEST_F(ValidateImage, WriteWrongCoordinateType) {
4020 const std::string body = R"(
4021 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4022 OpImageWrite %img %f32vec2_00 %u32vec4_0123
4023 )";
4024
4025 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4026 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4027 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4028 EXPECT_THAT(getDiagnosticString(),
4029 HasSubstr("Expected Coordinate to be int scalar or vector"));
4030 }
4031
TEST_F(ValidateImage,WriteCoordinateSizeTooSmall)4032 TEST_F(ValidateImage, WriteCoordinateSizeTooSmall) {
4033 const std::string body = R"(
4034 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4035 OpImageWrite %img %u32_1 %u32vec4_0123
4036 )";
4037
4038 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4039 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4040 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4041 EXPECT_THAT(getDiagnosticString(),
4042 HasSubstr("Expected Coordinate to have at least 2 components, "
4043 "but given only 1"));
4044 }
4045
TEST_F(ValidateImage,WriteTexelScalarSuccess)4046 TEST_F(ValidateImage, WriteTexelScalarSuccess) {
4047 const std::string body = R"(
4048 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4049 OpImageWrite %img %u32vec2_01 %u32_2
4050 )";
4051
4052 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4053 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4054 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4055 }
4056
TEST_F(ValidateImage,WriteTexelWrongType)4057 TEST_F(ValidateImage, WriteTexelWrongType) {
4058 const std::string body = R"(
4059 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4060 OpImageWrite %img %u32vec2_01 %img
4061 )";
4062
4063 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4064 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4065 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4066 EXPECT_THAT(getDiagnosticString(),
4067 HasSubstr("Expected Texel to be int or float vector or scalar"));
4068 }
4069
TEST_F(ValidateImage,WriteTexelNonNumericalType)4070 TEST_F(ValidateImage, WriteTexelNonNumericalType) {
4071 const std::string body = R"(
4072 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4073 OpImageWrite %img %u32vec2_01 %boolvec4_tttt
4074 )";
4075
4076 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4077 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4078 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4079 EXPECT_THAT(getDiagnosticString(),
4080 HasSubstr("Expected Texel to be int or float vector or scalar"));
4081 }
4082
TEST_F(ValidateImage,WriteTexelWrongComponentType)4083 TEST_F(ValidateImage, WriteTexelWrongComponentType) {
4084 const std::string body = R"(
4085 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
4086 OpImageWrite %img %u32vec2_01 %f32vec4_0000
4087 )";
4088
4089 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4090 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4091 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4092 EXPECT_THAT(
4093 getDiagnosticString(),
4094 HasSubstr(
4095 "Expected Image 'Sampled Type' to be the same as Texel components"));
4096 }
4097
TEST_F(ValidateImage,WriteSampleNotInteger)4098 TEST_F(ValidateImage, WriteSampleNotInteger) {
4099 const std::string body = R"(
4100 %img = OpLoad %type_image_f32_2d_0012 %uniform_image_f32_2d_0012
4101 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1
4102 )";
4103
4104 const std::string extra = R"(
4105 OpCapability StorageImageWriteWithoutFormat
4106 OpCapability StorageImageMultisample
4107 )";
4108 const std::string declarations = R"(
4109 %type_image_f32_2d_0012 = OpTypeImage %f32 2D 0 0 1 2 Unknown
4110 %ptr_image_f32_2d_0012 = OpTypePointer UniformConstant %type_image_f32_2d_0012
4111 %uniform_image_f32_2d_0012 = OpVariable %ptr_image_f32_2d_0012 UniformConstant
4112 )";
4113 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4114 SPV_ENV_UNIVERSAL_1_0, "GLSL450",
4115 declarations)
4116 .c_str());
4117 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4118 EXPECT_THAT(getDiagnosticString(),
4119 HasSubstr("Expected Image Operand Sample to be int scalar"));
4120 }
4121
TEST_F(ValidateImage,WriteSampleNotMultisampled)4122 TEST_F(ValidateImage, WriteSampleNotMultisampled) {
4123 const std::string body = R"(
4124 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4125 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
4126 )";
4127
4128 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
4129 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4130 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4131 EXPECT_THAT(
4132 getDiagnosticString(),
4133 HasSubstr("Image Operand Sample requires non-zero 'MS' parameter"));
4134 }
4135
TEST_F(ValidateImage,SampleWrongOpcode)4136 TEST_F(ValidateImage, SampleWrongOpcode) {
4137 const std::string body = R"(
4138 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4139 %sampler = OpLoad %type_sampler %uniform_sampler
4140 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
4141 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Sample %u32_1
4142 )";
4143
4144 CompileSuccessfully(GenerateShaderCode(body).c_str());
4145 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4146 EXPECT_THAT(getDiagnosticString(),
4147 HasSubstr("Sampling operation is invalid for multisample image"));
4148 }
4149
TEST_F(ValidateImage,SampleImageToImageSuccess)4150 TEST_F(ValidateImage, SampleImageToImageSuccess) {
4151 const std::string body = R"(
4152 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4153 %sampler = OpLoad %type_sampler %uniform_sampler
4154 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4155 %img2 = OpImage %type_image_f32_2d_0001 %simg
4156 )";
4157
4158 CompileSuccessfully(GenerateShaderCode(body).c_str());
4159 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4160 }
4161
TEST_F(ValidateImage,SampleImageToImageWrongResultType)4162 TEST_F(ValidateImage, SampleImageToImageWrongResultType) {
4163 const std::string body = R"(
4164 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4165 %sampler = OpLoad %type_sampler %uniform_sampler
4166 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4167 %img2 = OpImage %type_sampled_image_f32_2d_0001 %simg
4168 )";
4169
4170 CompileSuccessfully(GenerateShaderCode(body).c_str());
4171 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4172 EXPECT_THAT(getDiagnosticString(),
4173 HasSubstr("Expected Result Type to be OpTypeImage"));
4174 }
4175
TEST_F(ValidateImage,SampleImageToImageNotSampledImage)4176 TEST_F(ValidateImage, SampleImageToImageNotSampledImage) {
4177 const std::string body = R"(
4178 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4179 %img2 = OpImage %type_image_f32_2d_0001 %img
4180 )";
4181
4182 CompileSuccessfully(GenerateShaderCode(body).c_str());
4183 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4184 EXPECT_THAT(
4185 getDiagnosticString(),
4186 HasSubstr("Expected Sample Image to be of type OpTypeSampleImage"));
4187 }
4188
TEST_F(ValidateImage,SampleImageToImageNotTheSameImageType)4189 TEST_F(ValidateImage, SampleImageToImageNotTheSameImageType) {
4190 const std::string body = R"(
4191 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4192 %sampler = OpLoad %type_sampler %uniform_sampler
4193 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4194 %img2 = OpImage %type_image_f32_2d_0002 %simg
4195 )";
4196
4197 CompileSuccessfully(GenerateShaderCode(body).c_str());
4198 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4199 EXPECT_THAT(getDiagnosticString(),
4200 HasSubstr("Expected Sample Image image type to be equal to "
4201 "Result Type"));
4202 }
4203
TEST_F(ValidateImage,QueryFormatSuccess)4204 TEST_F(ValidateImage, QueryFormatSuccess) {
4205 const std::string body = R"(
4206 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4207 %res1 = OpImageQueryFormat %u32 %img
4208 )";
4209
4210 CompileSuccessfully(GenerateKernelCode(body).c_str());
4211 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4212 }
4213
TEST_F(ValidateImage,QueryFormatWrongResultType)4214 TEST_F(ValidateImage, QueryFormatWrongResultType) {
4215 const std::string body = R"(
4216 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4217 %res1 = OpImageQueryFormat %bool %img
4218 )";
4219
4220 CompileSuccessfully(GenerateKernelCode(body).c_str());
4221 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4222 EXPECT_THAT(getDiagnosticString(),
4223 HasSubstr("Expected Result Type to be int scalar type"));
4224 }
4225
TEST_F(ValidateImage,QueryFormatNotImage)4226 TEST_F(ValidateImage, QueryFormatNotImage) {
4227 const std::string body = R"(
4228 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4229 %sampler = OpLoad %type_sampler %uniform_sampler
4230 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4231 %res1 = OpImageQueryFormat %u32 %sampler
4232 )";
4233
4234 CompileSuccessfully(GenerateKernelCode(body).c_str());
4235 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4236 EXPECT_THAT(getDiagnosticString(),
4237 HasSubstr("Expected operand to be of type OpTypeImage"));
4238 }
4239
TEST_F(ValidateImage,QueryOrderSuccess)4240 TEST_F(ValidateImage, QueryOrderSuccess) {
4241 const std::string body = R"(
4242 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4243 %res1 = OpImageQueryOrder %u32 %img
4244 )";
4245
4246 CompileSuccessfully(GenerateKernelCode(body).c_str());
4247 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4248 }
4249
TEST_F(ValidateImage,QueryOrderWrongResultType)4250 TEST_F(ValidateImage, QueryOrderWrongResultType) {
4251 const std::string body = R"(
4252 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4253 %res1 = OpImageQueryOrder %bool %img
4254 )";
4255
4256 CompileSuccessfully(GenerateKernelCode(body).c_str());
4257 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4258 EXPECT_THAT(getDiagnosticString(),
4259 HasSubstr("Expected Result Type to be int scalar type"));
4260 }
4261
TEST_F(ValidateImage,QueryOrderNotImage)4262 TEST_F(ValidateImage, QueryOrderNotImage) {
4263 const std::string body = R"(
4264 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4265 %sampler = OpLoad %type_sampler %uniform_sampler
4266 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4267 %res1 = OpImageQueryOrder %u32 %sampler
4268 )";
4269
4270 CompileSuccessfully(GenerateKernelCode(body).c_str());
4271 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4272 EXPECT_THAT(getDiagnosticString(),
4273 HasSubstr("Expected operand to be of type OpTypeImage"));
4274 }
4275
TEST_F(ValidateImage,QuerySizeLodSuccess)4276 TEST_F(ValidateImage, QuerySizeLodSuccess) {
4277 const std::string body = R"(
4278 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4279 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4280 )";
4281
4282 CompileSuccessfully(GenerateKernelCode(body).c_str());
4283 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4284 }
4285
TEST_F(ValidateImage,QuerySizeLodWrongResultType)4286 TEST_F(ValidateImage, QuerySizeLodWrongResultType) {
4287 const std::string body = R"(
4288 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4289 %res1 = OpImageQuerySizeLod %f32vec2 %img %u32_1
4290 )";
4291
4292 CompileSuccessfully(GenerateKernelCode(body).c_str());
4293 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4294 EXPECT_THAT(
4295 getDiagnosticString(),
4296 HasSubstr("Expected Result Type to be int scalar or vector type"));
4297 }
4298
TEST_F(ValidateImage,QuerySizeLodResultTypeWrongSize)4299 TEST_F(ValidateImage, QuerySizeLodResultTypeWrongSize) {
4300 const std::string body = R"(
4301 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4302 %res1 = OpImageQuerySizeLod %u32 %img %u32_1
4303 )";
4304
4305 CompileSuccessfully(GenerateKernelCode(body).c_str());
4306 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4307 EXPECT_THAT(getDiagnosticString(),
4308 HasSubstr("Result Type has 1 components, but 2 expected"));
4309 }
4310
TEST_F(ValidateImage,QuerySizeLodNotImage)4311 TEST_F(ValidateImage, QuerySizeLodNotImage) {
4312 const std::string body = R"(
4313 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4314 %sampler = OpLoad %type_sampler %uniform_sampler
4315 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4316 %res1 = OpImageQuerySizeLod %u32vec2 %sampler %u32_1
4317 )";
4318
4319 CompileSuccessfully(GenerateKernelCode(body).c_str());
4320 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4321 EXPECT_THAT(getDiagnosticString(),
4322 HasSubstr("Expected Image to be of type OpTypeImage"));
4323 }
4324
TEST_F(ValidateImage,QuerySizeLodSampledImageDirectly)4325 TEST_F(ValidateImage, QuerySizeLodSampledImageDirectly) {
4326 const std::string body = R"(
4327 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4328 %sampler = OpLoad %type_sampler %uniform_sampler
4329 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4330 %res1 = OpImageQuerySizeLod %u32vec2 %simg %u32_1
4331 )";
4332
4333 CompileSuccessfully(GenerateShaderCode(body).c_str());
4334 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4335 EXPECT_THAT(getDiagnosticString(),
4336 HasSubstr("OpSampledImage instruction must not appear as operand "
4337 "for OpImageQuerySizeLod"));
4338 }
4339
TEST_F(ValidateImage,QuerySizeLodMultisampledError)4340 TEST_F(ValidateImage, QuerySizeLodMultisampledError) {
4341 const std::string body = R"(
4342 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4343 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4344 )";
4345
4346 CompileSuccessfully(GenerateKernelCode(body).c_str());
4347 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4348 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 0"));
4349 }
4350
TEST_F(ValidateImage,QuerySizeLodNonSampledUniversalSuccess)4351 TEST_F(ValidateImage, QuerySizeLodNonSampledUniversalSuccess) {
4352 const std::string body = R"(
4353 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4354 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4355 )";
4356
4357 CompileSuccessfully(GenerateShaderCode(body).c_str());
4358 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4359 EXPECT_EQ(getDiagnosticString(), "");
4360 }
4361
TEST_F(ValidateImage,QuerySizeLodVulkanNonSampledError)4362 TEST_F(ValidateImage, QuerySizeLodVulkanNonSampledError) {
4363 // Create a whole shader module. Avoid Vulkan incompatibility with
4364 // SampledRrect images inserted by helper function GenerateShaderCode.
4365 const std::string body = R"(
4366 OpCapability Shader
4367 OpCapability ImageQuery
4368 OpMemoryModel Logical Simple
4369 OpEntryPoint Fragment %main "main"
4370 OpExecutionMode %main OriginUpperLeft
4371
4372 %f32 = OpTypeFloat 32
4373 %u32 = OpTypeInt 32 0
4374 %u32_0 = OpConstant %u32 0
4375 %u32vec2 = OpTypeVector %u32 2
4376 %void = OpTypeVoid
4377 %voidfn = OpTypeFunction %void
4378
4379 ; Test with a storage image.
4380 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4381 %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
4382 %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
4383
4384 %main = OpFunction %void None %voidfn
4385 %entry = OpLabel
4386 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4387 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_0
4388 OpReturn
4389 OpFunctionEnd
4390 )";
4391
4392 CompileSuccessfully(body.c_str());
4393 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4394 EXPECT_THAT(getDiagnosticString(),
4395 AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
4396 EXPECT_THAT(
4397 getDiagnosticString(),
4398 HasSubstr(
4399 "OpImageQuerySizeLod must only consume an \"Image\" operand whose "
4400 "type has its \"Sampled\" operand set to 1"));
4401 }
4402
TEST_F(ValidateImage,QuerySizeLodWrongImageDim)4403 TEST_F(ValidateImage, QuerySizeLodWrongImageDim) {
4404 const std::string body = R"(
4405 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4406 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
4407 )";
4408
4409 CompileSuccessfully(GenerateKernelCode(body).c_str());
4410 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4411 EXPECT_THAT(getDiagnosticString(),
4412 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4413 }
4414
TEST_F(ValidateImage,QuerySizeLodWrongLodType)4415 TEST_F(ValidateImage, QuerySizeLodWrongLodType) {
4416 const std::string body = R"(
4417 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4418 %res1 = OpImageQuerySizeLod %u32vec2 %img %f32_0
4419 )";
4420
4421 CompileSuccessfully(GenerateKernelCode(body).c_str());
4422 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4423 EXPECT_THAT(getDiagnosticString(),
4424 HasSubstr("Expected Level of Detail to be int scalar"));
4425 }
4426
TEST_F(ValidateImage,QuerySizeSuccess)4427 TEST_F(ValidateImage, QuerySizeSuccess) {
4428 const std::string body = R"(
4429 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4430 %res1 = OpImageQuerySize %u32vec2 %img
4431 )";
4432
4433 CompileSuccessfully(GenerateKernelCode(body).c_str());
4434 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4435 }
4436
TEST_F(ValidateImage,QuerySizeWrongResultType)4437 TEST_F(ValidateImage, QuerySizeWrongResultType) {
4438 const std::string body = R"(
4439 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4440 %res1 = OpImageQuerySize %f32vec2 %img
4441 )";
4442
4443 CompileSuccessfully(GenerateKernelCode(body).c_str());
4444 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4445 EXPECT_THAT(
4446 getDiagnosticString(),
4447 HasSubstr("Expected Result Type to be int scalar or vector type"));
4448 }
4449
TEST_F(ValidateImage,QuerySizeNotImage)4450 TEST_F(ValidateImage, QuerySizeNotImage) {
4451 const std::string body = R"(
4452 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4453 %sampler = OpLoad %type_sampler %uniform_sampler
4454 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
4455 %res1 = OpImageQuerySize %u32vec2 %sampler
4456 )";
4457
4458 CompileSuccessfully(GenerateKernelCode(body).c_str());
4459 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4460 EXPECT_THAT(getDiagnosticString(),
4461 HasSubstr("Expected Image to be of type OpTypeImage"));
4462 }
4463
TEST_F(ValidateImage,QuerySizeSampledImageDirectly)4464 TEST_F(ValidateImage, QuerySizeSampledImageDirectly) {
4465 const std::string body = R"(
4466 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4467 %sampler = OpLoad %type_sampler %uniform_sampler
4468 %simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
4469 %res1 = OpImageQuerySize %u32vec2 %simg
4470 )";
4471
4472 CompileSuccessfully(GenerateShaderCode(body).c_str());
4473 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4474 EXPECT_THAT(getDiagnosticString(),
4475 HasSubstr("OpSampledImage instruction must not appear as operand "
4476 "for OpImageQuerySize"));
4477 }
4478
TEST_F(ValidateImage,QuerySizeDimSubpassDataBad)4479 TEST_F(ValidateImage, QuerySizeDimSubpassDataBad) {
4480 const std::string body = R"(
4481 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
4482 %res1 = OpImageQuerySize %u32vec2 %img
4483 )";
4484
4485 CompileSuccessfully(GenerateShaderCode(body).c_str());
4486 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4487 EXPECT_THAT(
4488 getDiagnosticString(),
4489 HasSubstr("Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"));
4490 }
4491
TEST_F(ValidateImage,QuerySizeWrongSampling)4492 TEST_F(ValidateImage, QuerySizeWrongSampling) {
4493 const std::string body = R"(
4494 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4495 %res1 = OpImageQuerySize %u32vec2 %img
4496 )";
4497
4498 CompileSuccessfully(GenerateKernelCode(body).c_str());
4499 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4500 EXPECT_THAT(
4501 getDiagnosticString(),
4502 HasSubstr("Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"));
4503 }
4504
TEST_F(ValidateImage,QuerySizeWrongNumberOfComponents)4505 TEST_F(ValidateImage, QuerySizeWrongNumberOfComponents) {
4506 const std::string body = R"(
4507 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
4508 %res1 = OpImageQuerySize %u32vec2 %img
4509 )";
4510
4511 CompileSuccessfully(GenerateShaderCode(body).c_str());
4512 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4513 EXPECT_THAT(getDiagnosticString(),
4514 HasSubstr("Result Type has 2 components, but 4 expected"));
4515 }
4516
TEST_F(ValidateImage,QueryLodSuccessKernel)4517 TEST_F(ValidateImage, QueryLodSuccessKernel) {
4518 const std::string body = R"(
4519 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4520 %sampler = OpLoad %type_sampler %uniform_sampler
4521 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4522 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4523 %res2 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
4524 )";
4525
4526 CompileSuccessfully(GenerateKernelCode(body).c_str());
4527 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4528 }
4529
TEST_F(ValidateImage,QueryLodSuccessShader)4530 TEST_F(ValidateImage, QueryLodSuccessShader) {
4531 const std::string body = R"(
4532 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4533 %sampler = OpLoad %type_sampler %uniform_sampler
4534 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4535 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4536 )";
4537
4538 CompileSuccessfully(GenerateShaderCode(body).c_str());
4539 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4540 }
4541
TEST_F(ValidateImage,QueryLodWrongResultType)4542 TEST_F(ValidateImage, QueryLodWrongResultType) {
4543 const std::string body = R"(
4544 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4545 %sampler = OpLoad %type_sampler %uniform_sampler
4546 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4547 %res1 = OpImageQueryLod %u32vec2 %simg %f32vec2_hh
4548 )";
4549
4550 CompileSuccessfully(GenerateKernelCode(body).c_str());
4551 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4552 EXPECT_THAT(getDiagnosticString(),
4553 HasSubstr("Expected Result Type to be float vector type"));
4554 }
4555
TEST_F(ValidateImage,QueryLodResultTypeWrongSize)4556 TEST_F(ValidateImage, QueryLodResultTypeWrongSize) {
4557 const std::string body = R"(
4558 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4559 %sampler = OpLoad %type_sampler %uniform_sampler
4560 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4561 %res1 = OpImageQueryLod %f32vec3 %simg %f32vec2_hh
4562 )";
4563
4564 CompileSuccessfully(GenerateKernelCode(body).c_str());
4565 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4566 EXPECT_THAT(getDiagnosticString(),
4567 HasSubstr("Expected Result Type to have 2 components"));
4568 }
4569
TEST_F(ValidateImage,QueryLodNotSampledImage)4570 TEST_F(ValidateImage, QueryLodNotSampledImage) {
4571 const std::string body = R"(
4572 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4573 %res1 = OpImageQueryLod %f32vec2 %img %f32vec2_hh
4574 )";
4575
4576 CompileSuccessfully(GenerateKernelCode(body).c_str());
4577 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4578 EXPECT_THAT(
4579 getDiagnosticString(),
4580 HasSubstr("Expected Image operand to be of type OpTypeSampledImage"));
4581 }
4582
TEST_F(ValidateImage,QueryLodWrongDim)4583 TEST_F(ValidateImage, QueryLodWrongDim) {
4584 const std::string body = R"(
4585 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4586 %sampler = OpLoad %type_sampler %uniform_sampler
4587 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
4588 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4589 )";
4590
4591 CompileSuccessfully(GenerateKernelCode(body).c_str());
4592 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4593 EXPECT_THAT(getDiagnosticString(),
4594 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4595 }
4596
TEST_F(ValidateImage,QueryLodWrongCoordinateType)4597 TEST_F(ValidateImage, QueryLodWrongCoordinateType) {
4598 const std::string body = R"(
4599 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4600 %sampler = OpLoad %type_sampler %uniform_sampler
4601 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4602 %res1 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
4603 )";
4604
4605 CompileSuccessfully(GenerateShaderCode(body).c_str());
4606 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4607 EXPECT_THAT(getDiagnosticString(),
4608 HasSubstr("Expected Coordinate to be float scalar or vector"));
4609 }
4610
TEST_F(ValidateImage,QueryLodCoordinateSizeTooSmall)4611 TEST_F(ValidateImage, QueryLodCoordinateSizeTooSmall) {
4612 const std::string body = R"(
4613 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4614 %sampler = OpLoad %type_sampler %uniform_sampler
4615 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4616 %res1 = OpImageQueryLod %f32vec2 %simg %f32_0
4617 )";
4618
4619 CompileSuccessfully(GenerateShaderCode(body).c_str());
4620 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4621 EXPECT_THAT(getDiagnosticString(),
4622 HasSubstr("Expected Coordinate to have at least 2 components, "
4623 "but given only 1"));
4624 }
4625
TEST_F(ValidateImage,QueryLevelsSuccess)4626 TEST_F(ValidateImage, QueryLevelsSuccess) {
4627 const std::string body = R"(
4628 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4629 %res1 = OpImageQueryLevels %u32 %img
4630 )";
4631
4632 CompileSuccessfully(GenerateKernelCode(body).c_str());
4633 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4634 }
4635
TEST_F(ValidateImage,QueryLevelsWrongResultType)4636 TEST_F(ValidateImage, QueryLevelsWrongResultType) {
4637 const std::string body = R"(
4638 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4639 %res1 = OpImageQueryLevels %f32 %img
4640 )";
4641
4642 CompileSuccessfully(GenerateKernelCode(body).c_str());
4643 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4644 EXPECT_THAT(getDiagnosticString(),
4645 HasSubstr("Expected Result Type to be int scalar type"));
4646 }
4647
TEST_F(ValidateImage,QueryLevelsNotImage)4648 TEST_F(ValidateImage, QueryLevelsNotImage) {
4649 const std::string body = R"(
4650 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4651 %sampler = OpLoad %type_sampler %uniform_sampler
4652 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4653 %res1 = OpImageQueryLevels %u32 %sampler
4654 )";
4655
4656 CompileSuccessfully(GenerateKernelCode(body).c_str());
4657 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4658 EXPECT_THAT(getDiagnosticString(),
4659 HasSubstr("Expected Image to be of type OpTypeImage"));
4660 }
4661
TEST_F(ValidateImage,QueryLevelsSampledImageDirectly)4662 TEST_F(ValidateImage, QueryLevelsSampledImageDirectly) {
4663 const std::string body = R"(
4664 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4665 %sampler = OpLoad %type_sampler %uniform_sampler
4666 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4667 %res1 = OpImageQueryLevels %u32 %simg
4668 )";
4669
4670 CompileSuccessfully(GenerateShaderCode(body).c_str());
4671 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4672 EXPECT_THAT(getDiagnosticString(),
4673 HasSubstr("OpSampledImage instruction must not appear as operand "
4674 "for OpImageQueryLevels"));
4675 }
4676
TEST_F(ValidateImage,QueryLevelsWrongDim)4677 TEST_F(ValidateImage, QueryLevelsWrongDim) {
4678 const std::string body = R"(
4679 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4680 %res1 = OpImageQueryLevels %u32 %img
4681 )";
4682
4683 CompileSuccessfully(GenerateKernelCode(body).c_str());
4684 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4685 EXPECT_THAT(getDiagnosticString(),
4686 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
4687 }
4688
TEST_F(ValidateImage,QuerySizeLevelsNonSampledUniversalSuccess)4689 TEST_F(ValidateImage, QuerySizeLevelsNonSampledUniversalSuccess) {
4690 const std::string body = R"(
4691 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4692 %res1 = OpImageQueryLevels %u32 %img
4693 )";
4694
4695 CompileSuccessfully(GenerateShaderCode(body).c_str());
4696 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4697 EXPECT_EQ(getDiagnosticString(), "");
4698 }
4699
TEST_F(ValidateImage,QuerySizeLevelsVulkanNonSampledError)4700 TEST_F(ValidateImage, QuerySizeLevelsVulkanNonSampledError) {
4701 // Create a whole shader module. Avoid Vulkan incompatibility with
4702 // SampledRrect images inserted by helper function GenerateShaderCode.
4703 const std::string body = R"(
4704 OpCapability Shader
4705 OpCapability ImageQuery
4706 OpMemoryModel Logical Simple
4707 OpEntryPoint Fragment %main "main"
4708 OpExecutionMode %main OriginUpperLeft
4709
4710 %f32 = OpTypeFloat 32
4711 %u32 = OpTypeInt 32 0
4712 %void = OpTypeVoid
4713 %voidfn = OpTypeFunction %void
4714
4715 ; Test with a storage image.
4716 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4717 %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
4718 %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
4719
4720 %main = OpFunction %void None %voidfn
4721 %entry = OpLabel
4722 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4723 %res1 = OpImageQueryLevels %u32 %img
4724 OpReturn
4725 OpFunctionEnd
4726 )";
4727
4728 CompileSuccessfully(body.c_str());
4729 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4730 EXPECT_THAT(getDiagnosticString(),
4731 AnyVUID("VUID-StandaloneSpirv-OpImageQuerySizeLod-04659"));
4732 EXPECT_THAT(
4733 getDiagnosticString(),
4734 HasSubstr("OpImageQueryLevels must only consume an \"Image\" operand "
4735 "whose type has its \"Sampled\" operand set to 1"));
4736 }
4737
TEST_F(ValidateImage,QuerySamplesSuccess)4738 TEST_F(ValidateImage, QuerySamplesSuccess) {
4739 const std::string body = R"(
4740 %img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
4741 %res1 = OpImageQuerySamples %u32 %img
4742 )";
4743
4744 CompileSuccessfully(GenerateKernelCode(body).c_str());
4745 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4746 }
4747
TEST_F(ValidateImage,QuerySamplesNot2D)4748 TEST_F(ValidateImage, QuerySamplesNot2D) {
4749 const std::string body = R"(
4750 %img = OpLoad %type_image_f32_3d_0011 %uniform_image_f32_3d_0011
4751 %res1 = OpImageQuerySamples %u32 %img
4752 )";
4753
4754 CompileSuccessfully(GenerateKernelCode(body).c_str());
4755 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4756 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' must be 2D"));
4757 }
4758
TEST_F(ValidateImage,QuerySamplesNotMultisampled)4759 TEST_F(ValidateImage, QuerySamplesNotMultisampled) {
4760 const std::string body = R"(
4761 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4762 %res1 = OpImageQuerySamples %u32 %img
4763 )";
4764
4765 CompileSuccessfully(GenerateKernelCode(body).c_str());
4766 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4767 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 1"));
4768 }
4769
TEST_F(ValidateImage,QueryLodWrongExecutionModel)4770 TEST_F(ValidateImage, QueryLodWrongExecutionModel) {
4771 const std::string body = R"(
4772 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4773 %sampler = OpLoad %type_sampler %uniform_sampler
4774 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4775 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4776 )";
4777
4778 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4779 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4780 EXPECT_THAT(
4781 getDiagnosticString(),
4782 HasSubstr(
4783 "OpImageQueryLod requires Fragment or GLCompute execution model"));
4784 }
4785
TEST_F(ValidateImage,QueryLodWrongExecutionModelWithFunc)4786 TEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) {
4787 const std::string body = R"(
4788 %call_ret = OpFunctionCall %void %my_func
4789 OpReturn
4790 OpFunctionEnd
4791 %my_func = OpFunction %void None %func
4792 %my_func_entry = OpLabel
4793 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4794 %sampler = OpLoad %type_sampler %uniform_sampler
4795 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4796 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4797 )";
4798
4799 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4800 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4801 EXPECT_THAT(
4802 getDiagnosticString(),
4803 HasSubstr(
4804 "OpImageQueryLod requires Fragment or GLCompute execution model"));
4805 }
4806
TEST_F(ValidateImage,QueryLodComputeShaderDerivatives)4807 TEST_F(ValidateImage, QueryLodComputeShaderDerivatives) {
4808 const std::string body = R"(
4809 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4810 %sampler = OpLoad %type_sampler %uniform_sampler
4811 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4812 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4813 )";
4814
4815 const std::string extra = R"(
4816 OpCapability ComputeDerivativeGroupLinearNV
4817 OpExtension "SPV_NV_compute_shader_derivatives"
4818 )";
4819 const std::string mode = R"(
4820 OpExecutionMode %main LocalSize 8 8 1
4821 OpExecutionMode %main DerivativeGroupLinearNV
4822 )";
4823 CompileSuccessfully(
4824 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4825 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4826 }
4827
TEST_F(ValidateImage,QueryLodUniversalSuccess)4828 TEST_F(ValidateImage, QueryLodUniversalSuccess) {
4829 // Create a whole shader module. Avoid Vulkan incompatibility with
4830 // SampledRrect images inserted by helper function GenerateShaderCode.
4831 const std::string body = R"(
4832 OpCapability Shader
4833 OpCapability ImageQuery
4834 OpMemoryModel Logical Simple
4835 OpEntryPoint Fragment %main "main"
4836 OpExecutionMode %main OriginUpperLeft
4837
4838 OpDecorate %uniform_image_f32_2d_0000 DescriptorSet 0
4839 OpDecorate %uniform_image_f32_2d_0000 Binding 0
4840 OpDecorate %sampler DescriptorSet 0
4841 OpDecorate %sampler Binding 1
4842
4843 %f32 = OpTypeFloat 32
4844 %f32vec2 = OpTypeVector %f32 2
4845 %f32vec2_null = OpConstantNull %f32vec2
4846 %u32 = OpTypeInt 32 0
4847 %u32vec2 = OpTypeVector %u32 2
4848 %void = OpTypeVoid
4849 %voidfn = OpTypeFunction %void
4850
4851 ; Test with an image with sampled = 0
4852 %type_image_f32_2d_0000 = OpTypeImage %f32 2D 0 0 0 0 Rgba32f
4853 %ptr_image_f32_2d_0000 = OpTypePointer UniformConstant %type_image_f32_2d_0000
4854 %uniform_image_f32_2d_0000 = OpVariable %ptr_image_f32_2d_0000 UniformConstant
4855 %sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0000
4856
4857 %sampler_ty = OpTypeSampler
4858 %ptr_sampler_ty = OpTypePointer UniformConstant %sampler_ty
4859 %sampler = OpVariable %ptr_sampler_ty UniformConstant
4860
4861
4862 %main = OpFunction %void None %voidfn
4863 %entry = OpLabel
4864 %img = OpLoad %type_image_f32_2d_0000 %uniform_image_f32_2d_0000
4865 %s = OpLoad %sampler_ty %sampler
4866 %simg = OpSampledImage %sampled_image_ty %img %s
4867 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
4868 OpReturn
4869 OpFunctionEnd
4870 )";
4871
4872 CompileSuccessfully(body.c_str());
4873 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4874 }
4875
TEST_F(ValidateImage,QueryLodVulkanNonSampledError)4876 TEST_F(ValidateImage, QueryLodVulkanNonSampledError) {
4877 // Create a whole shader module. Avoid Vulkan incompatibility with
4878 // SampledRrect images inserted by helper function GenerateShaderCode.
4879 const std::string body = R"(
4880 OpCapability Shader
4881 OpCapability ImageQuery
4882 OpMemoryModel Logical Simple
4883 OpEntryPoint Fragment %main "main"
4884 OpExecutionMode %main OriginUpperLeft
4885
4886 OpDecorate %sampled_image DescriptorSet 0
4887 OpDecorate %sampled_image Binding 0
4888
4889 %f32 = OpTypeFloat 32
4890 %f32vec2 = OpTypeVector %f32 2
4891 %f32vec2_null = OpConstantNull %f32vec2
4892 %u32 = OpTypeInt 32 0
4893 %u32vec2 = OpTypeVector %u32 2
4894 %void = OpTypeVoid
4895 %voidfn = OpTypeFunction %void
4896
4897 ; Test with an image with Sampled = 2
4898 ; In Vulkan it Sampled must be 1 or 2, checked in another part of the
4899 ; validation flow.
4900 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Rgba32f
4901
4902 ; Expect to fail here.
4903 %sampled_image_ty = OpTypeSampledImage %type_image_f32_2d_0002
4904 %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
4905 %sampled_image = OpVariable %ptr_sampled_image_ty UniformConstant
4906
4907 %main = OpFunction %void None %voidfn
4908 %entry = OpLabel
4909 %simg = OpLoad %sampled_image_ty %sampled_image
4910 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_null
4911 OpReturn
4912 OpFunctionEnd
4913 )";
4914
4915 CompileSuccessfully(body.c_str());
4916 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4917 EXPECT_THAT(getDiagnosticString(),
4918 AnyVUID("VUID-StandaloneSpirv-OpTypeImage-04657"));
4919 EXPECT_THAT(getDiagnosticString(),
4920 HasSubstr("Sampled image type requires an image type with "
4921 "\"Sampled\" operand set to 0 or 1"));
4922 }
4923
TEST_F(ValidateImage,QueryLodComputeShaderDerivativesMissingMode)4924 TEST_F(ValidateImage, QueryLodComputeShaderDerivativesMissingMode) {
4925 const std::string body = R"(
4926 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4927 %sampler = OpLoad %type_sampler %uniform_sampler
4928 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4929 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
4930 )";
4931
4932 const std::string extra = R"(
4933 OpCapability ComputeDerivativeGroupLinearNV
4934 OpExtension "SPV_NV_compute_shader_derivatives"
4935 )";
4936 const std::string mode = R"(
4937 OpExecutionMode %main LocalSize 8 8 1
4938 )";
4939 CompileSuccessfully(
4940 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4941 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4942 EXPECT_THAT(getDiagnosticString(),
4943 HasSubstr("OpImageQueryLod requires DerivativeGroupQuadsNV or "
4944 "DerivativeGroupLinearNV execution mode for GLCompute "
4945 "execution model"));
4946 }
4947
TEST_F(ValidateImage,ImplicitLodWrongExecutionModel)4948 TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
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 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
4957 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4958 EXPECT_THAT(getDiagnosticString(),
4959 HasSubstr("ImplicitLod instructions require Fragment or "
4960 "GLCompute execution model"));
4961 }
4962
TEST_F(ValidateImage,ImplicitLodComputeShaderDerivatives)4963 TEST_F(ValidateImage, ImplicitLodComputeShaderDerivatives) {
4964 const std::string body = R"(
4965 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4966 %sampler = OpLoad %type_sampler %uniform_sampler
4967 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4968 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4969 )";
4970
4971 const std::string extra = R"(
4972 OpCapability ComputeDerivativeGroupLinearNV
4973 OpExtension "SPV_NV_compute_shader_derivatives"
4974 )";
4975 const std::string mode = R"(
4976 OpExecutionMode %main LocalSize 8 8 1
4977 OpExecutionMode %main DerivativeGroupLinearNV
4978 )";
4979 CompileSuccessfully(
4980 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
4981 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4982 }
4983
TEST_F(ValidateImage,ImplicitLodComputeShaderDerivativesMissingMode)4984 TEST_F(ValidateImage, ImplicitLodComputeShaderDerivativesMissingMode) {
4985 const std::string body = R"(
4986 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4987 %sampler = OpLoad %type_sampler %uniform_sampler
4988 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4989 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
4990 )";
4991
4992 const std::string extra = R"(
4993 OpCapability ComputeDerivativeGroupLinearNV
4994 OpExtension "SPV_NV_compute_shader_derivatives"
4995 )";
4996 const std::string mode = R"(
4997 OpExecutionMode %main LocalSize 8 8 1
4998 )";
4999 CompileSuccessfully(
5000 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
5001 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5002 EXPECT_THAT(
5003 getDiagnosticString(),
5004 HasSubstr("ImplicitLod instructions require DerivativeGroupQuadsNV or "
5005 "DerivativeGroupLinearNV execution mode for GLCompute "
5006 "execution model"));
5007 }
5008
TEST_F(ValidateImage,ReadSubpassDataWrongExecutionModel)5009 TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
5010 const std::string body = R"(
5011 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
5012 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
5013 )";
5014
5015 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5016 CompileSuccessfully(GenerateShaderCode(body, extra, "Vertex").c_str());
5017 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5018 EXPECT_THAT(getDiagnosticString(),
5019 HasSubstr("Dim SubpassData requires Fragment execution model"));
5020 }
5021
TEST_F(ValidateImage,SparseSampleImplicitLodSuccess)5022 TEST_F(ValidateImage, SparseSampleImplicitLodSuccess) {
5023 const std::string body = R"(
5024 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5025 %sampler = OpLoad %type_sampler %uniform_sampler
5026 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5027 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh
5028 %res2 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Bias %f32_0_25
5029 %res4 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
5030 %res5 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
5031 %res6 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
5032 %res7 = OpImageSparseSampleImplicitLod %struct_u64_f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
5033 %res8 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
5034 )";
5035
5036 const std::string extra = R"(
5037 OpCapability VulkanMemoryModelKHR
5038 OpExtension "SPV_KHR_vulkan_memory_model"
5039 )";
5040 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5041 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5042 .c_str());
5043 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5044 }
5045
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotStruct)5046 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotStruct) {
5047 const std::string body = R"(
5048 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5049 %sampler = OpLoad %type_sampler %uniform_sampler
5050 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5051 %res1 = OpImageSparseSampleImplicitLod %f32 %simg %f32vec2_hh
5052 )";
5053
5054 CompileSuccessfully(GenerateShaderCode(body).c_str());
5055 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5056 EXPECT_THAT(getDiagnosticString(),
5057 HasSubstr("Expected Result Type to be OpTypeStruct"));
5058 }
5059
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotTwoMembers1)5060 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers1) {
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 %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 int "
5072 "scalar and a texel"));
5073 }
5074
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotTwoMembers2)5075 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers2) {
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_u32_f32vec4_u32 %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,SparseSampleImplicitLodResultTypeFirstMemberNotInt)5090 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeFirstMemberNotInt) {
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_f32_f32vec4 %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 to be a struct containing an "
5102 "int scalar and a texel"));
5103 }
5104
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeTexelNotVector)5105 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeTexelNotVector) {
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_u32 %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 be int or "
5117 "float vector type"));
5118 }
5119
TEST_F(ValidateImage,SparseSampleImplicitLodWrongNumComponentsTexel)5120 TEST_F(ValidateImage, SparseSampleImplicitLodWrongNumComponentsTexel) {
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_f32vec3 %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 Result Type's second member to have 4 "
5132 "components"));
5133 }
5134
TEST_F(ValidateImage,SparseSampleImplicitLodWrongComponentTypeTexel)5135 TEST_F(ValidateImage, SparseSampleImplicitLodWrongComponentTypeTexel) {
5136 const std::string body = R"(
5137 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5138 %sampler = OpLoad %type_sampler %uniform_sampler
5139 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5140 %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32vec4 %simg %f32vec2_hh
5141 )";
5142
5143 CompileSuccessfully(GenerateShaderCode(body).c_str());
5144 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5145 EXPECT_THAT(getDiagnosticString(),
5146 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5147 "Result Type's second member components"));
5148 }
5149
TEST_F(ValidateImage,SparseSampleDrefImplicitLodSuccess)5150 TEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) {
5151 const std::string body = R"(
5152 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
5153 %sampler = OpLoad %type_sampler %uniform_sampler
5154 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
5155 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
5156 %res2 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
5157 %res4 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
5158 %res5 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
5159 %res6 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
5160 %res7 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
5161 %res8 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
5162 )";
5163
5164 const std::string extra = R"(
5165 OpCapability VulkanMemoryModelKHR
5166 OpExtension "SPV_KHR_vulkan_memory_model"
5167 )";
5168 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5169 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5170 .c_str());
5171 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5172 }
5173
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotStruct)5174 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotStruct) {
5175 const std::string body = R"(
5176 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5177 %sampler = OpLoad %type_sampler %uniform_sampler
5178 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5179 %res1 = OpImageSparseSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1
5180 )";
5181
5182 CompileSuccessfully(GenerateShaderCode(body).c_str());
5183 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5184 EXPECT_THAT(getDiagnosticString(),
5185 HasSubstr("Expected Result Type to be OpTypeStruct"));
5186 }
5187
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotTwoMembers1)5188 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers1) {
5189 const std::string body = R"(
5190 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5191 %sampler = OpLoad %type_sampler %uniform_sampler
5192 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5193 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32 %simg %f32vec2_hh %f32_1
5194 )";
5195
5196 CompileSuccessfully(GenerateShaderCode(body).c_str());
5197 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5198 EXPECT_THAT(
5199 getDiagnosticString(),
5200 HasSubstr("Expected Result Type to be a struct containing an int scalar "
5201 "and a texel"));
5202 }
5203
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotTwoMembers2)5204 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers2) {
5205 const std::string body = R"(
5206 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5207 %sampler = OpLoad %type_sampler %uniform_sampler
5208 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5209 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_f32_u32 %simg %f32vec2_hh %f32_1
5210 )";
5211
5212 CompileSuccessfully(GenerateShaderCode(body).c_str());
5213 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5214 EXPECT_THAT(
5215 getDiagnosticString(),
5216 HasSubstr("Expected Result Type to be a struct containing an int scalar "
5217 "and a texel"));
5218 }
5219
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt)5220 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt) {
5221 const std::string body = R"(
5222 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5223 %sampler = OpLoad %type_sampler %uniform_sampler
5224 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5225 %res1 = OpImageSparseSampleDrefImplicitLod %struct_f32_f32 %simg %f32vec2_hh %f32_1
5226 )";
5227
5228 CompileSuccessfully(GenerateShaderCode(body).c_str());
5229 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5230 EXPECT_THAT(
5231 getDiagnosticString(),
5232 HasSubstr("Expected Result Type to be a struct containing an int scalar "
5233 "and a texel"));
5234 }
5235
TEST_F(ValidateImage,SparseSampleDrefImplicitLodDifferentSampledType)5236 TEST_F(ValidateImage, SparseSampleDrefImplicitLodDifferentSampledType) {
5237 const std::string body = R"(
5238 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5239 %sampler = OpLoad %type_sampler %uniform_sampler
5240 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5241 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
5242 )";
5243
5244 CompileSuccessfully(GenerateShaderCode(body).c_str());
5245 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5246 EXPECT_THAT(getDiagnosticString(),
5247 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5248 "Result Type's second member"));
5249 }
5250
TEST_F(ValidateImage,SparseFetchSuccess)5251 TEST_F(ValidateImage, SparseFetchSuccess) {
5252 const std::string body = R"(
5253 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
5254 %res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
5255 %res2 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
5256 )";
5257
5258 const std::string extra = R"(
5259 OpCapability VulkanMemoryModelKHR
5260 OpExtension "SPV_KHR_vulkan_memory_model"
5261 )";
5262 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5263 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5264 .c_str());
5265 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5266 }
5267
TEST_F(ValidateImage,SparseFetchResultTypeNotStruct)5268 TEST_F(ValidateImage, SparseFetchResultTypeNotStruct) {
5269 const std::string body = R"(
5270 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5271 %res1 = OpImageSparseFetch %f32 %img %u32vec2_01
5272 )";
5273
5274 CompileSuccessfully(GenerateShaderCode(body).c_str());
5275 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5276 EXPECT_THAT(getDiagnosticString(),
5277 HasSubstr("Expected Result Type to be OpTypeStruct"));
5278 }
5279
TEST_F(ValidateImage,SparseFetchResultTypeNotTwoMembers1)5280 TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers1) {
5281 const std::string body = R"(
5282 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5283 %res1 = OpImageSparseFetch %struct_u32 %img %u32vec2_01
5284 )";
5285
5286 CompileSuccessfully(GenerateShaderCode(body).c_str());
5287 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5288 EXPECT_THAT(getDiagnosticString(),
5289 HasSubstr("Expected Result Type to be a struct containing an "
5290 "int scalar and a texel"));
5291 }
5292
TEST_F(ValidateImage,SparseFetchResultTypeNotTwoMembers2)5293 TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers2) {
5294 const std::string body = R"(
5295 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5296 %res1 = OpImageSparseFetch %struct_u32_f32vec4_u32 %img %u32vec2_01
5297 )";
5298
5299 CompileSuccessfully(GenerateShaderCode(body).c_str());
5300 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5301 EXPECT_THAT(getDiagnosticString(),
5302 HasSubstr("Expected Result Type to be a struct containing an "
5303 "int scalar and a texel"));
5304 }
5305
TEST_F(ValidateImage,SparseFetchResultTypeFirstMemberNotInt)5306 TEST_F(ValidateImage, SparseFetchResultTypeFirstMemberNotInt) {
5307 const std::string body = R"(
5308 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5309 %res1 = OpImageSparseFetch %struct_f32_f32vec4 %img %u32vec2_01
5310 )";
5311
5312 CompileSuccessfully(GenerateShaderCode(body).c_str());
5313 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5314 EXPECT_THAT(getDiagnosticString(),
5315 HasSubstr("Expected Result Type to be a struct containing an "
5316 "int scalar and a texel"));
5317 }
5318
TEST_F(ValidateImage,SparseFetchResultTypeTexelNotVector)5319 TEST_F(ValidateImage, SparseFetchResultTypeTexelNotVector) {
5320 const std::string body = R"(
5321 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5322 %res1 = OpImageSparseFetch %struct_u32_u32 %img %u32vec2_01
5323 )";
5324
5325 CompileSuccessfully(GenerateShaderCode(body).c_str());
5326 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5327 EXPECT_THAT(getDiagnosticString(),
5328 HasSubstr("Expected Result Type's second member to be int or "
5329 "float vector type"));
5330 }
5331
TEST_F(ValidateImage,SparseFetchWrongNumComponentsTexel)5332 TEST_F(ValidateImage, SparseFetchWrongNumComponentsTexel) {
5333 const std::string body = R"(
5334 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5335 %res1 = OpImageSparseFetch %struct_u32_f32vec3 %img %u32vec2_01
5336 )";
5337
5338 CompileSuccessfully(GenerateShaderCode(body).c_str());
5339 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5340 EXPECT_THAT(getDiagnosticString(),
5341 HasSubstr("Expected Result Type's second member to have 4 "
5342 "components"));
5343 }
5344
TEST_F(ValidateImage,SparseFetchWrongComponentTypeTexel)5345 TEST_F(ValidateImage, SparseFetchWrongComponentTypeTexel) {
5346 const std::string body = R"(
5347 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
5348 %res1 = OpImageSparseFetch %struct_u32_u32vec4 %img %u32vec2_01
5349 )";
5350
5351 CompileSuccessfully(GenerateShaderCode(body).c_str());
5352 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5353 EXPECT_THAT(getDiagnosticString(),
5354 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5355 "Result Type's second member components"));
5356 }
5357
TEST_F(ValidateImage,SparseReadSuccess)5358 TEST_F(ValidateImage, SparseReadSuccess) {
5359 const std::string body = R"(
5360 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5361 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
5362 )";
5363
5364 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5365 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5366 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5367 }
5368
TEST_F(ValidateImage,SparseReadResultTypeNotStruct)5369 TEST_F(ValidateImage, SparseReadResultTypeNotStruct) {
5370 const std::string body = R"(
5371 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5372 %res1 = OpImageSparseRead %f32 %img %u32vec2_01
5373 )";
5374
5375 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5376 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5377 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5378 EXPECT_THAT(getDiagnosticString(),
5379 HasSubstr("Expected Result Type to be OpTypeStruct"));
5380 }
5381
TEST_F(ValidateImage,SparseReadResultTypeNotTwoMembers1)5382 TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers1) {
5383 const std::string body = R"(
5384 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5385 %res1 = OpImageSparseRead %struct_u32 %img %u32vec2_01
5386 )";
5387
5388 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5389 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5390 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5391 EXPECT_THAT(getDiagnosticString(),
5392 HasSubstr("Expected Result Type to be a struct containing an "
5393 "int scalar and a texel"));
5394 }
5395
TEST_F(ValidateImage,SparseReadResultTypeNotTwoMembers2)5396 TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers2) {
5397 const std::string body = R"(
5398 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5399 %res1 = OpImageSparseRead %struct_u32_f32vec4_u32 %img %u32vec2_01
5400 )";
5401
5402 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5403 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5404 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5405 EXPECT_THAT(getDiagnosticString(),
5406 HasSubstr("Expected Result Type to be a struct containing an "
5407 "int scalar and a texel"));
5408 }
5409
TEST_F(ValidateImage,SparseReadResultTypeFirstMemberNotInt)5410 TEST_F(ValidateImage, SparseReadResultTypeFirstMemberNotInt) {
5411 const std::string body = R"(
5412 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5413 %res1 = OpImageSparseRead %struct_f32_f32vec4 %img %u32vec2_01
5414 )";
5415
5416 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5417 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5418 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5419 EXPECT_THAT(getDiagnosticString(),
5420 HasSubstr("Expected Result Type to be a struct containing an "
5421 "int scalar and a texel"));
5422 }
5423
TEST_F(ValidateImage,SparseReadResultTypeTexelWrongType)5424 TEST_F(ValidateImage, SparseReadResultTypeTexelWrongType) {
5425 const std::string body = R"(
5426 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5427 %res1 = OpImageSparseRead %struct_u32_u32arr4 %img %u32vec2_01
5428 )";
5429
5430 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5431 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5432 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5433 EXPECT_THAT(getDiagnosticString(),
5434 HasSubstr("Expected Result Type's second member to be int or "
5435 "float scalar or vector type"));
5436 }
5437
TEST_F(ValidateImage,SparseReadWrongComponentTypeTexel)5438 TEST_F(ValidateImage, SparseReadWrongComponentTypeTexel) {
5439 const std::string body = R"(
5440 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5441 %res1 = OpImageSparseRead %struct_u32_u32vec4 %img %u32vec2_01
5442 )";
5443
5444 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5445 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
5446 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5447 EXPECT_THAT(getDiagnosticString(),
5448 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5449 "Result Type's second member components"));
5450 }
5451
TEST_F(ValidateImage,SparseReadSubpassDataNotAllowed)5452 TEST_F(ValidateImage, SparseReadSubpassDataNotAllowed) {
5453 const std::string body = R"(
5454 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
5455 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
5456 )";
5457
5458 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5459 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment").c_str());
5460 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5461 EXPECT_THAT(
5462 getDiagnosticString(),
5463 HasSubstr("Image Dim SubpassData cannot be used with ImageSparseRead"));
5464 }
5465
TEST_F(ValidateImage,SparseGatherSuccess)5466 TEST_F(ValidateImage, SparseGatherSuccess) {
5467 const std::string body = R"(
5468 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5469 %sampler = OpLoad %type_sampler %uniform_sampler
5470 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5471 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1
5472 %res2 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
5473 )";
5474
5475 const std::string extra = R"(
5476 OpCapability VulkanMemoryModelKHR
5477 OpExtension "SPV_KHR_vulkan_memory_model"
5478 )";
5479 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5480 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5481 .c_str());
5482 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5483 }
5484
TEST_F(ValidateImage,SparseGatherResultTypeNotStruct)5485 TEST_F(ValidateImage, SparseGatherResultTypeNotStruct) {
5486 const std::string body = R"(
5487 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5488 %sampler = OpLoad %type_sampler %uniform_sampler
5489 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5490 %res1 = OpImageSparseGather %f32 %simg %f32vec2_hh %u32_1
5491 )";
5492
5493 CompileSuccessfully(GenerateShaderCode(body).c_str());
5494 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5495 EXPECT_THAT(getDiagnosticString(),
5496 HasSubstr("Expected Result Type to be OpTypeStruct"));
5497 }
5498
TEST_F(ValidateImage,SparseGatherResultTypeNotTwoMembers1)5499 TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers1) {
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 %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,SparseGatherResultTypeNotTwoMembers2)5514 TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers2) {
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_u32_f32vec4_u32 %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 int "
5526 "scalar and a texel"));
5527 }
5528
TEST_F(ValidateImage,SparseGatherResultTypeFirstMemberNotInt)5529 TEST_F(ValidateImage, SparseGatherResultTypeFirstMemberNotInt) {
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_f32_f32vec4 %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 to be a struct containing an "
5541 "int scalar and a texel"));
5542 }
5543
TEST_F(ValidateImage,SparseGatherResultTypeTexelNotVector)5544 TEST_F(ValidateImage, SparseGatherResultTypeTexelNotVector) {
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_u32 %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 be int or "
5556 "float vector type"));
5557 }
5558
TEST_F(ValidateImage,SparseGatherWrongNumComponentsTexel)5559 TEST_F(ValidateImage, SparseGatherWrongNumComponentsTexel) {
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_f32vec3 %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 Result Type's second member to have 4 "
5571 "components"));
5572 }
5573
TEST_F(ValidateImage,SparseGatherWrongComponentTypeTexel)5574 TEST_F(ValidateImage, SparseGatherWrongComponentTypeTexel) {
5575 const std::string body = R"(
5576 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5577 %sampler = OpLoad %type_sampler %uniform_sampler
5578 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5579 %res1 = OpImageSparseGather %struct_u32_u32vec4 %simg %f32vec2_hh %u32_1
5580 )";
5581
5582 CompileSuccessfully(GenerateShaderCode(body).c_str());
5583 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5584 EXPECT_THAT(getDiagnosticString(),
5585 HasSubstr("Expected Image 'Sampled Type' to be the same as "
5586 "Result Type's second member components"));
5587 }
5588
TEST_F(ValidateImage,SparseTexelsResidentSuccess)5589 TEST_F(ValidateImage, SparseTexelsResidentSuccess) {
5590 const std::string body = R"(
5591 %res1 = OpImageSparseTexelsResident %bool %u32_1
5592 )";
5593
5594 CompileSuccessfully(GenerateShaderCode(body).c_str());
5595 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5596 }
5597
TEST_F(ValidateImage,SparseTexelsResidentResultTypeNotBool)5598 TEST_F(ValidateImage, SparseTexelsResidentResultTypeNotBool) {
5599 const std::string body = R"(
5600 %res1 = OpImageSparseTexelsResident %u32 %u32_1
5601 )";
5602
5603 CompileSuccessfully(GenerateShaderCode(body).c_str());
5604 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5605 EXPECT_THAT(getDiagnosticString(),
5606 HasSubstr("Expected Result Type to be bool scalar type"));
5607 }
5608
TEST_F(ValidateImage,MakeTexelVisibleKHRSuccessImageRead)5609 TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageRead) {
5610 const std::string body = R"(
5611 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5612 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
5613 )";
5614
5615 const std::string extra = R"(
5616 OpCapability StorageImageReadWithoutFormat
5617 OpCapability VulkanMemoryModelKHR
5618 OpExtension "SPV_KHR_vulkan_memory_model"
5619 )";
5620 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5621 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5622 .c_str());
5623 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5624 }
5625
TEST_F(ValidateImage,MakeTexelVisibleKHRSuccessImageSparseRead)5626 TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageSparseRead) {
5627 const std::string body = R"(
5628 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
5629 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
5630 )";
5631
5632 const std::string extra = R"(
5633 OpCapability StorageImageReadWithoutFormat
5634 OpCapability VulkanMemoryModelKHR
5635 OpExtension "SPV_KHR_vulkan_memory_model"
5636 )";
5637 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5638 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5639 .c_str());
5640 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5641 }
5642
TEST_F(ValidateImage,MakeTexelVisibleKHRFailureOpcode)5643 TEST_F(ValidateImage, MakeTexelVisibleKHRFailureOpcode) {
5644 const std::string body = R"(
5645 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5646 %sampler = OpLoad %type_sampler %uniform_sampler
5647 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5648 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5649 )";
5650
5651 const std::string extra = R"(
5652 OpCapability StorageImageReadWithoutFormat
5653 OpCapability VulkanMemoryModelKHR
5654 OpExtension "SPV_KHR_vulkan_memory_model"
5655 )";
5656 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5657 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5658 .c_str());
5659 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5660 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5661 EXPECT_THAT(
5662 getDiagnosticString(),
5663 HasSubstr("Image Operand MakeTexelVisibleKHR can only be used with "
5664 "OpImageRead or OpImageSparseRead: OpImageSampleImplicitLod"));
5665 }
5666
TEST_F(ValidateImage,MakeTexelVisibleKHRFailureMissingNonPrivate)5667 TEST_F(ValidateImage, MakeTexelVisibleKHRFailureMissingNonPrivate) {
5668 const std::string body = R"(
5669 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5670 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR %u32_1
5671 )";
5672
5673 const std::string extra = R"(
5674 OpCapability StorageImageReadWithoutFormat
5675 OpCapability VulkanMemoryModelKHR
5676 OpExtension "SPV_KHR_vulkan_memory_model"
5677 )";
5678 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5679 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5680 .c_str());
5681 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5682 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5683 EXPECT_THAT(getDiagnosticString(),
5684 HasSubstr("Image Operand MakeTexelVisibleKHR requires "
5685 "NonPrivateTexelKHR is also specified: OpImageRead"));
5686 }
5687
TEST_F(ValidateImage,MakeTexelAvailableKHRSuccessImageWrite)5688 TEST_F(ValidateImage, MakeTexelAvailableKHRSuccessImageWrite) {
5689 const std::string body = R"(
5690 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5691 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2
5692 )";
5693
5694 const std::string extra = R"(
5695 OpCapability StorageImageWriteWithoutFormat
5696 OpCapability VulkanMemoryModelKHR
5697 OpExtension "SPV_KHR_vulkan_memory_model"
5698 )";
5699 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5700 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5701 .c_str());
5702 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5703 }
5704
TEST_F(ValidateImage,MakeTexelAvailableKHRFailureOpcode)5705 TEST_F(ValidateImage, MakeTexelAvailableKHRFailureOpcode) {
5706 const std::string body = R"(
5707 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
5708 %sampler = OpLoad %type_sampler %uniform_sampler
5709 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
5710 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5711 )";
5712
5713 const std::string extra = R"(
5714 OpCapability StorageImageReadWithoutFormat
5715 OpCapability VulkanMemoryModelKHR
5716 OpExtension "SPV_KHR_vulkan_memory_model"
5717 )";
5718 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5719 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5720 .c_str());
5721 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5722 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5723 EXPECT_THAT(getDiagnosticString(),
5724 HasSubstr("Image Operand MakeTexelAvailableKHR can only be used "
5725 "with OpImageWrite: OpImageSampleImplicitLod"));
5726 }
5727
TEST_F(ValidateImage,MakeTexelAvailableKHRFailureMissingNonPrivate)5728 TEST_F(ValidateImage, MakeTexelAvailableKHRFailureMissingNonPrivate) {
5729 const std::string body = R"(
5730 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5731 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1
5732 )";
5733
5734 const std::string extra = R"(
5735 OpCapability StorageImageWriteWithoutFormat
5736 OpCapability VulkanMemoryModelKHR
5737 OpExtension "SPV_KHR_vulkan_memory_model"
5738 )";
5739 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5740 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5741 .c_str());
5742 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5743 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5744 EXPECT_THAT(getDiagnosticString(),
5745 HasSubstr("Image Operand MakeTexelAvailableKHR requires "
5746 "NonPrivateTexelKHR is also specified: OpImageWrite"));
5747 }
5748
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageWriteBad)5749 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteBad) {
5750 const std::string body = R"(
5751 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5752 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5753 )";
5754
5755 const std::string extra = R"(
5756 OpCapability StorageImageWriteWithoutFormat
5757 OpCapability VulkanMemoryModelKHR
5758 OpExtension "SPV_KHR_vulkan_memory_model"
5759 )";
5760 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5761 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5762 .c_str());
5763 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5764 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5765 EXPECT_THAT(
5766 getDiagnosticString(),
5767 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
5768 "VulkanMemoryModelDeviceScopeKHR capability"));
5769 }
5770
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageWriteGood)5771 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteGood) {
5772 const std::string body = R"(
5773 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5774 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
5775 )";
5776
5777 const std::string extra = R"(
5778 OpCapability StorageImageWriteWithoutFormat
5779 OpCapability VulkanMemoryModelKHR
5780 OpCapability VulkanMemoryModelDeviceScopeKHR
5781 OpExtension "SPV_KHR_vulkan_memory_model"
5782 )";
5783 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5784 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5785 .c_str());
5786 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5787 }
5788
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageReadBad)5789 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadBad) {
5790 const std::string body = R"(
5791 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5792 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5793 )";
5794
5795 const std::string extra = R"(
5796 OpCapability StorageImageReadWithoutFormat
5797 OpCapability VulkanMemoryModelKHR
5798 OpExtension "SPV_KHR_vulkan_memory_model"
5799 )";
5800 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5801 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5802 .c_str());
5803 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
5804 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5805 EXPECT_THAT(
5806 getDiagnosticString(),
5807 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
5808 "VulkanMemoryModelDeviceScopeKHR capability"));
5809 }
5810
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageReadGood)5811 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadGood) {
5812 const std::string body = R"(
5813 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5814 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
5815 )";
5816
5817 const std::string extra = R"(
5818 OpCapability StorageImageReadWithoutFormat
5819 OpCapability VulkanMemoryModelKHR
5820 OpCapability VulkanMemoryModelDeviceScopeKHR
5821 OpExtension "SPV_KHR_vulkan_memory_model"
5822 )";
5823 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
5824 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
5825 .c_str());
5826 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
5827 }
5828
5829 // This example used to cause a seg fault on OpReturnValue, verifying it doesn't
5830 // anymore.
TEST_F(ValidateImage,Issue2463NoSegFault)5831 TEST_F(ValidateImage, Issue2463NoSegFault) {
5832 const std::string spirv = R"(
5833 OpCapability Linkage
5834 OpCapability Shader
5835 %1 = OpExtInstImport "GLSL.std.450"
5836 OpMemoryModel Logical GLSL450
5837 %void = OpTypeVoid
5838 %6 = OpTypeFunction %void
5839 %float = OpTypeFloat 32
5840 %8 = OpTypeImage %float 3D 0 0 0 1 Unknown
5841 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
5842 %10 = OpTypeSampler
5843 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
5844 %12 = OpTypeSampledImage %8
5845 %13 = OpTypeFunction %12 %_ptr_UniformConstant_8 %_ptr_UniformConstant_10
5846 %23 = OpFunction %12 None %13
5847 %24 = OpFunctionParameter %_ptr_UniformConstant_8
5848 %25 = OpFunctionParameter %_ptr_UniformConstant_10
5849 %26 = OpLabel
5850 %27 = OpLoad %8 %24
5851 %28 = OpLoad %10 %25
5852 %29 = OpSampledImage %12 %27 %28
5853 OpReturnValue %29
5854 OpFunctionEnd
5855 )";
5856
5857 CompileSuccessfully(spirv);
5858 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5859 EXPECT_THAT(getDiagnosticString(),
5860 HasSubstr("OpSampledImage instruction must not appear as operand "
5861 "for OpReturnValue"));
5862 }
5863
TEST_F(ValidateImage,SignExtendV13Bad)5864 TEST_F(ValidateImage, SignExtendV13Bad) {
5865 const std::string body = R"(
5866 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5867 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
5868 )";
5869
5870 CompileSuccessfully(
5871 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3));
5872 ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions());
5873 EXPECT_THAT(
5874 getDiagnosticString(),
5875 HasSubstr("SignExtend(4096) requires SPIR-V version 1.4 or later"));
5876 }
5877
TEST_F(ValidateImage,ZeroExtendV13Bad)5878 TEST_F(ValidateImage, ZeroExtendV13Bad) {
5879 const std::string body = R"(
5880 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5881 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
5882 )";
5883
5884 CompileSuccessfully(
5885 GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3));
5886 ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions());
5887 EXPECT_THAT(
5888 getDiagnosticString(),
5889 HasSubstr("ZeroExtend(8192) requires SPIR-V version 1.4 or later"));
5890 }
5891
TEST_F(ValidateImage,SignExtendScalarUIntTexelV14Good)5892 TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) {
5893 // Unsigned int sampled type
5894 const std::string body = R"(
5895 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5896 %res1 = OpImageRead %u32 %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,SignExtendScalarSIntTexelV14Good)5907 TEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) {
5908 // Signed int sampled type
5909 const std::string body = R"(
5910 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5911 %res1 = OpImageRead %s32 %img %u32vec2_01 SignExtend
5912 )";
5913 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5914
5915 CompileSuccessfully(
5916 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5917 SPV_ENV_UNIVERSAL_1_4);
5918 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5919 EXPECT_THAT(getDiagnosticString(), Eq(""));
5920 }
5921
TEST_F(ValidateImage,SignExtendScalarVectorUIntTexelV14Good)5922 TEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) {
5923 const std::string body = R"(
5924 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5925 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
5926 )";
5927 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5928
5929 CompileSuccessfully(
5930 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5931 SPV_ENV_UNIVERSAL_1_4);
5932 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5933 EXPECT_THAT(getDiagnosticString(), Eq(""));
5934 }
5935
TEST_F(ValidateImage,SignExtendVectorSIntTexelV14Good)5936 TEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) {
5937 const std::string body = R"(
5938 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5939 %res1 = OpImageRead %s32vec4 %img %u32vec2_01 SignExtend
5940 )";
5941 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5942
5943 CompileSuccessfully(
5944 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5945 SPV_ENV_UNIVERSAL_1_4);
5946 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5947 EXPECT_THAT(getDiagnosticString(), Eq(""));
5948 }
5949
5950 // No negative tests for SignExtend since we don't truly know the
5951 // texel format.
5952
TEST_F(ValidateImage,ZeroExtendScalarUIntTexelV14Good)5953 TEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) {
5954 // Unsigned int sampled type
5955 const std::string body = R"(
5956 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5957 %res1 = OpImageRead %u32 %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,ZeroExtendScalarSIntTexelV14Good)5968 TEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) {
5969 // Zeroed int sampled type
5970 const std::string body = R"(
5971 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
5972 %res1 = OpImageRead %s32 %img %u32vec2_01 ZeroExtend
5973 )";
5974 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5975
5976 CompileSuccessfully(
5977 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5978 SPV_ENV_UNIVERSAL_1_4);
5979 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5980 EXPECT_THAT(getDiagnosticString(), Eq(""));
5981 }
5982
TEST_F(ValidateImage,ZeroExtendScalarVectorUIntTexelV14Good)5983 TEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) {
5984 const std::string body = R"(
5985 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
5986 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
5987 )";
5988 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
5989
5990 CompileSuccessfully(
5991 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
5992 SPV_ENV_UNIVERSAL_1_4);
5993 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
5994 EXPECT_THAT(getDiagnosticString(), Eq(""));
5995 }
5996
TEST_F(ValidateImage,ZeroExtendVectorSIntTexelV14Good)5997 TEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) {
5998 const std::string body = R"(
5999 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
6000 %res1 = OpImageRead %s32vec4 %img %u32vec2_01 ZeroExtend
6001 )";
6002 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
6003
6004 CompileSuccessfully(
6005 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
6006 SPV_ENV_UNIVERSAL_1_4);
6007 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6008 EXPECT_THAT(getDiagnosticString(), Eq(""));
6009 }
6010
TEST_F(ValidateImage,ReadLodAMDSuccess1)6011 TEST_F(ValidateImage, ReadLodAMDSuccess1) {
6012 const std::string body = R"(
6013 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
6014 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 Lod %u32_0
6015 )";
6016
6017 const std::string extra =
6018 "\nOpCapability StorageImageReadWithoutFormat\n"
6019 "OpCapability ImageReadWriteLodAMD\n"
6020 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6021 CompileSuccessfully(
6022 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6023 SPV_ENV_UNIVERSAL_1_1);
6024 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6025 }
6026
TEST_F(ValidateImage,ReadLodAMDSuccess2)6027 TEST_F(ValidateImage, ReadLodAMDSuccess2) {
6028 const std::string body = R"(
6029 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
6030 %res1 = OpImageRead %f32vec4 %img %u32vec2_01 Lod %u32_0
6031 )";
6032
6033 const std::string extra =
6034 "\nOpCapability Image1D\n"
6035 "OpCapability ImageReadWriteLodAMD\n"
6036 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6037 CompileSuccessfully(
6038 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6039 SPV_ENV_UNIVERSAL_1_1);
6040 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6041 }
6042
TEST_F(ValidateImage,ReadLodAMDSuccess3)6043 TEST_F(ValidateImage, ReadLodAMDSuccess3) {
6044 const std::string body = R"(
6045 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6046 %res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
6047 )";
6048
6049 const std::string extra =
6050 "\nOpCapability ImageCubeArray\n"
6051 "OpCapability ImageReadWriteLodAMD\n"
6052 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6053 CompileSuccessfully(
6054 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6055 SPV_ENV_UNIVERSAL_1_1);
6056 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6057 }
6058
TEST_F(ValidateImage,ReadLodAMDNeedCapability)6059 TEST_F(ValidateImage, ReadLodAMDNeedCapability) {
6060 const std::string body = R"(
6061 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6062 %res1 = OpImageRead %f32vec4 %img %u32vec3_012 Lod %u32_0
6063 )";
6064
6065 const std::string extra = "\nOpCapability ImageCubeArray\n";
6066 CompileSuccessfully(
6067 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6068 SPV_ENV_UNIVERSAL_1_1);
6069 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
6070 ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6071 EXPECT_THAT(getDiagnosticString(),
6072 HasSubstr("Image Operand Lod can only be used with ExplicitLod "
6073 "opcodes and OpImageFetch"));
6074 }
6075
TEST_F(ValidateImage,WriteLodAMDSuccess1)6076 TEST_F(ValidateImage, WriteLodAMDSuccess1) {
6077 const std::string body = R"(
6078 %img = OpLoad %type_image_u32_2d_0002 %uniform_image_u32_2d_0002
6079 OpImageWrite %img %u32vec2_01 %u32vec4_0123 Lod %u32_0
6080 )";
6081
6082 const std::string extra =
6083 "\nOpCapability StorageImageWriteWithoutFormat\n"
6084 "OpCapability ImageReadWriteLodAMD\n"
6085 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6086 CompileSuccessfully(
6087 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6088 SPV_ENV_UNIVERSAL_1_1);
6089 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6090 }
6091
TEST_F(ValidateImage,WriteLodAMDSuccess2)6092 TEST_F(ValidateImage, WriteLodAMDSuccess2) {
6093 const std::string body = R"(
6094 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
6095 OpImageWrite %img %u32_1 %f32vec4_0000 Lod %u32_0
6096 )";
6097
6098 const std::string extra =
6099 "\nOpCapability Image1D\n"
6100 "OpCapability ImageReadWriteLodAMD\n"
6101 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6102 CompileSuccessfully(
6103 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6104 SPV_ENV_UNIVERSAL_1_1);
6105 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6106 }
6107
TEST_F(ValidateImage,WriteLodAMDSuccess3)6108 TEST_F(ValidateImage, WriteLodAMDSuccess3) {
6109 const std::string body = R"(
6110 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6111 OpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
6112 )";
6113
6114 const std::string extra =
6115 "\nOpCapability ImageCubeArray\n"
6116 "OpCapability ImageReadWriteLodAMD\n"
6117 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6118 CompileSuccessfully(
6119 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6120 SPV_ENV_UNIVERSAL_1_1);
6121 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6122 }
6123
TEST_F(ValidateImage,WriteLodAMDNeedCapability)6124 TEST_F(ValidateImage, WriteLodAMDNeedCapability) {
6125 const std::string body = R"(
6126 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
6127 OpImageWrite %img %u32vec3_012 %f32vec4_0000 Lod %u32_0
6128 )";
6129
6130 const std::string extra = "\nOpCapability ImageCubeArray\n";
6131 CompileSuccessfully(
6132 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6133 SPV_ENV_UNIVERSAL_1_1);
6134 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
6135 ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6136 EXPECT_THAT(getDiagnosticString(),
6137 HasSubstr("Image Operand Lod can only be used with ExplicitLod "
6138 "opcodes and OpImageFetch"));
6139 }
6140
TEST_F(ValidateImage,SparseReadLodAMDSuccess)6141 TEST_F(ValidateImage, SparseReadLodAMDSuccess) {
6142 const std::string body = R"(
6143 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
6144 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
6145 )";
6146
6147 const std::string extra =
6148 "\nOpCapability StorageImageReadWithoutFormat\n"
6149 "OpCapability ImageReadWriteLodAMD\n"
6150 "OpExtension \"SPV_AMD_shader_image_load_store_lod\"\n";
6151 CompileSuccessfully(
6152 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6153 SPV_ENV_UNIVERSAL_1_1);
6154 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6155 }
6156
TEST_F(ValidateImage,SparseReadLodAMDNeedCapability)6157 TEST_F(ValidateImage, SparseReadLodAMDNeedCapability) {
6158 const std::string body = R"(
6159 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
6160 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 Lod %u32_0
6161 )";
6162
6163 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
6164 CompileSuccessfully(
6165 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_1),
6166 SPV_ENV_UNIVERSAL_1_1);
6167 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
6168 ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
6169 EXPECT_THAT(getDiagnosticString(),
6170 HasSubstr("Image Operand Lod can only be used with ExplicitLod "
6171 "opcodes and OpImageFetch"));
6172 }
6173
TEST_F(ValidateImage,GatherBiasAMDSuccess)6174 TEST_F(ValidateImage, GatherBiasAMDSuccess) {
6175 const std::string body = R"(
6176 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6177 %sampler = OpLoad %type_sampler %uniform_sampler
6178 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6179 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
6180 )";
6181
6182 const std::string extra = R"(
6183 OpCapability ImageGatherBiasLodAMD
6184 OpExtension "SPV_AMD_texture_gather_bias_lod"
6185 )";
6186 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6187 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6188 }
6189
TEST_F(ValidateImage,GatherLodAMDSuccess)6190 TEST_F(ValidateImage, GatherLodAMDSuccess) {
6191 const std::string body = R"(
6192 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6193 %sampler = OpLoad %type_sampler %uniform_sampler
6194 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6195 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
6196 )";
6197
6198 const std::string extra = R"(
6199 OpCapability ImageGatherBiasLodAMD
6200 OpExtension "SPV_AMD_texture_gather_bias_lod"
6201 )";
6202 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6203 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6204 }
6205
TEST_F(ValidateImage,SparseGatherBiasAMDSuccess)6206 TEST_F(ValidateImage, SparseGatherBiasAMDSuccess) {
6207 const std::string body = R"(
6208 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6209 %sampler = OpLoad %type_sampler %uniform_sampler
6210 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6211 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Bias %f32_1
6212 )";
6213
6214 const std::string extra = R"(
6215 OpCapability ImageGatherBiasLodAMD
6216 OpExtension "SPV_AMD_texture_gather_bias_lod"
6217 )";
6218 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6219 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6220 }
6221
TEST_F(ValidateImage,SparseGatherLodAMDSuccess)6222 TEST_F(ValidateImage, SparseGatherLodAMDSuccess) {
6223 const std::string body = R"(
6224 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
6225 %sampler = OpLoad %type_sampler %uniform_sampler
6226 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
6227 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 Lod %f32_1
6228 )";
6229
6230 const std::string extra = R"(
6231 OpCapability ImageGatherBiasLodAMD
6232 OpExtension "SPV_AMD_texture_gather_bias_lod"
6233 )";
6234 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
6235 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6236 }
6237
6238 // No negative tests for ZeroExtend since we don't truly know the
6239 // texel format.
6240
6241 // Tests for 64-bit images
6242 static const std::string capabilities_and_extensions_image64 = R"(
6243 OpCapability Int64ImageEXT
6244 OpExtension "SPV_EXT_shader_image_int64"
6245 )";
6246 static const std::string capabilities_and_extensions_image64_atomic = R"(
6247 OpCapability Int64Atomics
6248 OpCapability Int64ImageEXT
6249 OpExtension "SPV_EXT_shader_image_int64"
6250 )";
6251 static const std::string declarations_image64 = R"(
6252 %type_image_u64_buffer_0002_r64ui = OpTypeImage %u64 Buffer 0 0 0 2 R64ui
6253 %ptr_Image_u64 = OpTypePointer Image %u64
6254 %ptr_image_u64_buffer_0002_r64ui = OpTypePointer Private %type_image_u64_buffer_0002_r64ui
6255 %private_image_u64_buffer_0002_r64ui = OpVariable %ptr_image_u64_buffer_0002_r64ui Private
6256 )";
6257 static const std::string declarations_image64i = R"(
6258 %type_image_s64_buffer_0002_r64i = OpTypeImage %s64 Buffer 0 0 0 2 R64i
6259 %ptr_Image_s64 = OpTypePointer Image %s64
6260 %ptr_image_s64_buffer_0002_r64i = OpTypePointer Private %type_image_s64_buffer_0002_r64i
6261 %private_image_s64_buffer_0002_r64i = OpVariable %ptr_image_s64_buffer_0002_r64i Private
6262 )";
6263
TEST_F(ValidateImage,Image64MissingCapability)6264 TEST_F(ValidateImage, Image64MissingCapability) {
6265 CompileSuccessfully(GenerateShaderCode("", "", "Fragment", "",
6266 SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6267 declarations_image64)
6268 .c_str());
6269 ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
6270 }
6271
TEST_F(ValidateImage,Image64MissingExtension)6272 TEST_F(ValidateImage, Image64MissingExtension) {
6273 const std::string extra = R"(
6274 OpCapability Int64ImageEXT
6275 )";
6276
6277 CompileSuccessfully(GenerateShaderCode("", extra, "Fragment", "",
6278 SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6279 declarations_image64)
6280 .c_str());
6281 ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
6282 }
6283
TEST_F(ValidateImage,ImageTexelPointer64Success)6284 TEST_F(ValidateImage, ImageTexelPointer64Success) {
6285 const std::string body = R"(
6286 %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6287 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6288 )";
6289
6290 CompileSuccessfully(
6291 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6292 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6293 declarations_image64)
6294 .c_str());
6295 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6296 }
6297
TEST_F(ValidateImage,ImageTexelPointer64ResultTypeNotPointer)6298 TEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotPointer) {
6299 const std::string body = R"(
6300 %texel_ptr = OpImageTexelPointer %type_image_u64_buffer_0002_r64ui %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6301 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6302 )";
6303
6304 CompileSuccessfully(
6305 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6306 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6307 declarations_image64)
6308 .c_str());
6309 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6310 EXPECT_THAT(getDiagnosticString(),
6311 HasSubstr("Expected Result Type to be OpTypePointer"));
6312 }
6313
TEST_F(ValidateImage,ImageTexelPointer64ResultTypeNotImageClass)6314 TEST_F(ValidateImage, ImageTexelPointer64ResultTypeNotImageClass) {
6315 const std::string body = R"(
6316 %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6317 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6318 )";
6319
6320 CompileSuccessfully(
6321 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6322 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6323 declarations_image64)
6324 .c_str());
6325 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6326 EXPECT_THAT(getDiagnosticString(),
6327 HasSubstr("Expected Result Type to be OpTypePointer whose "
6328 "Storage Class operand is Image"));
6329 }
6330
TEST_F(ValidateImage,ImageTexelPointer64SampleNotZeroForImageWithMSZero)6331 TEST_F(ValidateImage, ImageTexelPointer64SampleNotZeroForImageWithMSZero) {
6332 const std::string body = R"(
6333 %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_1
6334 %sum = OpAtomicIAdd %u64 %texel_ptr %u32_1 %u32_0 %u64_1
6335 )";
6336
6337 CompileSuccessfully(
6338 GenerateShaderCode(body, capabilities_and_extensions_image64_atomic,
6339 "Fragment", "", SPV_ENV_UNIVERSAL_1_3, "GLSL450",
6340 declarations_image64)
6341 .c_str());
6342 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6343 EXPECT_THAT(getDiagnosticString(),
6344 HasSubstr("Expected Sample for Image with MS 0 to be a valid "
6345 "<id> for the value 0"));
6346 }
6347
TEST_F(ValidateImage,ImageTexelPointerR32uiSuccessVulkan)6348 TEST_F(ValidateImage, ImageTexelPointerR32uiSuccessVulkan) {
6349 const std::string body = R"(
6350 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
6351 )";
6352
6353 spv_target_env env = SPV_ENV_VULKAN_1_0;
6354 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
6355 env);
6356 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6357 }
6358
TEST_F(ValidateImage,ImageTexelPointerR32iSuccessVulkan)6359 TEST_F(ValidateImage, ImageTexelPointerR32iSuccessVulkan) {
6360 const std::string& declarations = R"(
6361 %type_image_s32_buffer_0002_r32i = OpTypeImage %s32 Buffer 0 0 0 2 R32i
6362 %ptr_Image_s32 = OpTypePointer Image %s32
6363 %ptr_image_s32_buffer_0002_r32i = OpTypePointer Private %type_image_s32_buffer_0002_r32i
6364 %private_image_s32_buffer_0002_r32i = OpVariable %ptr_image_s32_buffer_0002_r32i Private
6365 )";
6366
6367 const std::string body = R"(
6368 %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_r32i %u32_0 %u32_0
6369 )";
6370
6371 spv_target_env env = SPV_ENV_VULKAN_1_0;
6372 CompileSuccessfully(
6373 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6374 .c_str(),
6375 env);
6376 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6377 }
6378
TEST_F(ValidateImage,ImageTexelPointerR64uiSuccessVulkan)6379 TEST_F(ValidateImage, ImageTexelPointerR64uiSuccessVulkan) {
6380 const std::string body = R"(
6381 %texel_ptr = OpImageTexelPointer %ptr_Image_u64 %private_image_u64_buffer_0002_r64ui %u32_0 %u32_0
6382 )";
6383
6384 spv_target_env env = SPV_ENV_VULKAN_1_0;
6385 CompileSuccessfully(
6386 GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
6387 "", env, "GLSL450", declarations_image64)
6388 .c_str(),
6389 env);
6390 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6391 }
6392
TEST_F(ValidateImage,ImageTexelPointerR64iSuccessVulkan)6393 TEST_F(ValidateImage, ImageTexelPointerR64iSuccessVulkan) {
6394 const std::string body = R"(
6395 %texel_ptr = OpImageTexelPointer %ptr_Image_s64 %private_image_s64_buffer_0002_r64i %u32_0 %u32_0
6396 )";
6397
6398 spv_target_env env = SPV_ENV_VULKAN_1_0;
6399 CompileSuccessfully(
6400 GenerateShaderCode(body, capabilities_and_extensions_image64, "Fragment",
6401 "", env, "GLSL450", declarations_image64i)
6402 .c_str(),
6403 env);
6404 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6405 }
6406
TEST_F(ValidateImage,ImageTexelPointerR32fSuccessVulkan)6407 TEST_F(ValidateImage, ImageTexelPointerR32fSuccessVulkan) {
6408 const std::string& declarations = R"(
6409 %type_image_f32_buffer_0002_r32f = OpTypeImage %f32 Buffer 0 0 0 2 R32f
6410 %ptr_image_f32_buffer_0002_r32f = OpTypePointer Private %type_image_f32_buffer_0002_r32f
6411 %private_image_f32_buffer_0002_r32f = OpVariable %ptr_image_f32_buffer_0002_r32f Private
6412 )";
6413
6414 const std::string body = R"(
6415 %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32f %u32_0 %u32_0
6416 )";
6417
6418 spv_target_env env = SPV_ENV_VULKAN_1_0;
6419 CompileSuccessfully(
6420 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6421 .c_str(),
6422 env);
6423 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
6424 }
6425
TEST_F(ValidateImage,ImageTexelPointerRgba32iVulkan)6426 TEST_F(ValidateImage, ImageTexelPointerRgba32iVulkan) {
6427 const std::string& declarations = R"(
6428 %type_image_s32_buffer_0002_rgba32i = OpTypeImage %s32 Buffer 0 0 0 2 Rgba32i
6429 %ptr_Image_s32 = OpTypePointer Image %s32
6430 %ptr_image_s32_buffer_0002_rgba32i = OpTypePointer Private %type_image_s32_buffer_0002_rgba32i
6431 %private_image_s32_buffer_0002_rgba32i = OpVariable %ptr_image_s32_buffer_0002_rgba32i Private
6432 )";
6433
6434 const std::string body = R"(
6435 %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba32i %u32_0 %u32_0
6436 )";
6437
6438 spv_target_env env = SPV_ENV_VULKAN_1_0;
6439 CompileSuccessfully(
6440 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6441 .c_str(),
6442 env);
6443 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
6444 EXPECT_THAT(getDiagnosticString(),
6445 AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
6446 EXPECT_THAT(getDiagnosticString(),
6447 HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
6448 "R32f, R32i, or R32ui for Vulkan environment"));
6449 }
6450
TEST_F(ValidateImage,ImageTexelPointerRgba16fVulkan)6451 TEST_F(ValidateImage, ImageTexelPointerRgba16fVulkan) {
6452 const std::string& declarations = R"(
6453 %type_image_s32_buffer_0002_rgba16f = OpTypeImage %s32 Buffer 0 0 0 2 Rgba16f
6454 %ptr_Image_s32 = OpTypePointer Image %s32
6455 %ptr_image_s32_buffer_0002_rgba16f = OpTypePointer Private %type_image_s32_buffer_0002_rgba16f
6456 %private_image_s32_buffer_0002_rgba16f = OpVariable %ptr_image_s32_buffer_0002_rgba16f Private
6457 )";
6458
6459 const std::string body = R"(
6460 %texel_ptr = OpImageTexelPointer %ptr_Image_s32 %private_image_s32_buffer_0002_rgba16f %u32_0 %u32_0
6461 )";
6462
6463 spv_target_env env = SPV_ENV_VULKAN_1_0;
6464 CompileSuccessfully(
6465 GenerateShaderCode(body, "", "Fragment", "", env, "GLSL450", declarations)
6466 .c_str(),
6467 env);
6468 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
6469 EXPECT_THAT(getDiagnosticString(),
6470 AnyVUID("VUID-StandaloneSpirv-OpImageTexelPointer-04658"));
6471 EXPECT_THAT(getDiagnosticString(),
6472 HasSubstr("Expected the Image Format in Image to be R64i, R64ui, "
6473 "R32f, R32i, or R32ui for Vulkan environment"));
6474 }
6475
TEST_F(ValidateImage,ImageExecutionModeLimitationNoMode)6476 TEST_F(ValidateImage, ImageExecutionModeLimitationNoMode) {
6477 const std::string text = R"(
6478 OpCapability Shader
6479 OpMemoryModel Logical GLSL450
6480 OpEntryPoint GLCompute %2 " " %4
6481 %void = OpTypeVoid
6482 %8 = OpTypeFunction %void
6483 %float = OpTypeFloat 32
6484 %v4float = OpTypeVector %float 4
6485 %12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
6486 %13 = OpTypeSampledImage %12
6487 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6488 %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
6489 %_ptr_Input_v4float = OpTypePointer Input %v4float
6490 %4 = OpVariable %_ptr_Input_v4float Input
6491 %v2float = OpTypeVector %float 2
6492 %float_1_35631564en19 = OpConstant %float 1.35631564e-19
6493 %2 = OpFunction %void None %8
6494 %8224 = OpLabel
6495 %6 = OpLoad %13 %5
6496 %19 = OpLoad %v4float %4
6497 %20 = OpVectorShuffle %v2float %19 %19 0 1
6498 %21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
6499 %65312 = OpImageSampleImplicitLod %v4float %6 %21
6500 OpUnreachable
6501 OpFunctionEnd
6502 )";
6503
6504 CompileSuccessfully(text);
6505 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
6506 EXPECT_THAT(getDiagnosticString(),
6507 HasSubstr("ImplicitLod instructions require "
6508 "DerivativeGroupQuadsNV or DerivativeGroupLinearNV "
6509 "execution mode for GLCompute execution model"));
6510 }
6511
TEST_F(ValidateImage,TypeSampledImageNotBufferPost1p6)6512 TEST_F(ValidateImage, TypeSampledImageNotBufferPost1p6) {
6513 const std::string text = R"(
6514 OpCapability Shader
6515 OpCapability Linkage
6516 OpCapability SampledBuffer
6517 OpMemoryModel Logical GLSL450
6518 %float = OpTypeFloat 32
6519 %image = OpTypeImage %float Buffer 0 0 0 1 Unknown
6520 %sampled = OpTypeSampledImage %image
6521 )";
6522
6523 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
6524 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
6525 EXPECT_THAT(getDiagnosticString(),
6526 HasSubstr("In SPIR-V 1.6 or later, sampled image dimension must "
6527 "not be Buffer"));
6528 }
6529
TEST_F(ValidateImage,NonTemporalImage)6530 TEST_F(ValidateImage, NonTemporalImage) {
6531 const std::string text = R"(
6532 OpCapability Shader
6533 OpMemoryModel Logical GLSL450
6534 OpEntryPoint Fragment %2 " " %4 %5
6535 OpExecutionMode %2 OriginUpperLeft
6536 %void = OpTypeVoid
6537 %8 = OpTypeFunction %void
6538 %float = OpTypeFloat 32
6539 %v4float = OpTypeVector %float 4
6540 %12 = OpTypeImage %float 2D 0 0 0 1 Rgba8ui
6541 %13 = OpTypeSampledImage %12
6542 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6543 %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
6544 %_ptr_Input_v4float = OpTypePointer Input %v4float
6545 %4 = OpVariable %_ptr_Input_v4float Input
6546 %v2float = OpTypeVector %float 2
6547 %float_1_35631564en19 = OpConstant %float 1.35631564e-19
6548 %2 = OpFunction %void None %8
6549 %8224 = OpLabel
6550 %6 = OpLoad %13 %5
6551 %19 = OpLoad %v4float %4
6552 %20 = OpVectorShuffle %v2float %19 %19 0 1
6553 %21 = OpVectorTimesScalar %v2float %20 %float_1_35631564en19
6554 %65312 = OpImageSampleImplicitLod %v4float %6 %21 Nontemporal
6555 OpReturn
6556 OpFunctionEnd
6557 )";
6558
6559 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
6560 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
6561 }
6562
TEST_F(ValidateImage,NVBindlessSamplerBuiltins)6563 TEST_F(ValidateImage, NVBindlessSamplerBuiltins) {
6564 const std::string text = R"(
6565 OpCapability Shader
6566 OpCapability Int64
6567 OpCapability Image1D
6568 OpCapability BindlessTextureNV
6569 OpExtension "SPV_NV_bindless_texture"
6570 %1 = OpExtInstImport "GLSL.std.450"
6571 OpMemoryModel Logical GLSL450
6572 OpSamplerImageAddressingModeNV 64
6573 OpEntryPoint Fragment %main "main"
6574 OpExecutionMode %main OriginUpperLeft
6575 OpSource GLSL 450
6576 OpName %main "main"
6577 OpName %s2D "s2D"
6578 OpName %textureHandle "textureHandle"
6579 OpName %i1D "i1D"
6580 OpName %s "s"
6581 OpName %temp "temp"
6582 %void = OpTypeVoid
6583 %3 = OpTypeFunction %void
6584 %float = OpTypeFloat 32
6585 %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
6586 %8 = OpTypeSampledImage %7
6587 %_ptr_Function_8 = OpTypePointer Function %8
6588 %ulong = OpTypeInt 64 0
6589 %_ptr_Private_ulong = OpTypePointer Private %ulong
6590 %textureHandle = OpVariable %_ptr_Private_ulong Private
6591 %16 = OpTypeImage %float 1D 0 0 0 2 Rgba32f
6592 %_ptr_Function_16 = OpTypePointer Function %16
6593 %21 = OpTypeSampler
6594 %_ptr_Function_21 = OpTypePointer Function %21
6595 %_ptr_Function_ulong = OpTypePointer Function %ulong
6596 %main = OpFunction %void None %3
6597 %5 = OpLabel
6598 %s2D = OpVariable %_ptr_Function_8 Function
6599 %i1D = OpVariable %_ptr_Function_16 Function
6600 %s = OpVariable %_ptr_Function_21 Function
6601 %temp = OpVariable %_ptr_Function_ulong Function
6602 %14 = OpLoad %ulong %textureHandle
6603 %15 = OpConvertUToSampledImageNV %8 %14
6604 OpStore %s2D %15
6605 %19 = OpLoad %ulong %textureHandle
6606 %20 = OpConvertUToImageNV %16 %19
6607 OpStore %i1D %20
6608 %24 = OpLoad %ulong %textureHandle
6609 %25 = OpConvertUToSamplerNV %21 %24
6610 OpStore %s %25
6611 %28 = OpLoad %8 %s2D
6612 %29 = OpConvertSampledImageToUNV %ulong %28
6613 OpStore %temp %29
6614 %30 = OpLoad %16 %i1D
6615 %31 = OpConvertImageToUNV %ulong %30
6616 OpStore %temp %31
6617 %32 = OpLoad %21 %s
6618 %33 = OpConvertSamplerToUNV %ulong %32
6619 OpStore %temp %33
6620 OpReturn
6621 OpFunctionEnd
6622 )";
6623
6624 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6625 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6626 }
6627
TEST_F(ValidateImage,NVBindlessAddressingMode64)6628 TEST_F(ValidateImage, NVBindlessAddressingMode64) {
6629 std::string text = R"(
6630 OpCapability Shader
6631 OpCapability BindlessTextureNV
6632 OpExtension "SPV_NV_bindless_texture"
6633 OpMemoryModel Logical GLSL450
6634 OpSamplerImageAddressingModeNV 64
6635 OpEntryPoint GLCompute %func "main"
6636 %voidt = OpTypeVoid
6637 %uintt = OpTypeInt 32 0
6638 %funct = OpTypeFunction %voidt
6639 %func = OpFunction %voidt None %funct
6640 %entry = OpLabel
6641 %udef = OpUndef %uintt
6642 OpReturn
6643 OpFunctionEnd
6644 )";
6645 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6646 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6647 }
6648
TEST_F(ValidateImage,NVBindlessAddressingMode32)6649 TEST_F(ValidateImage, NVBindlessAddressingMode32) {
6650 std::string text = R"(
6651 OpCapability Shader
6652 OpCapability BindlessTextureNV
6653 OpExtension "SPV_NV_bindless_texture"
6654 OpMemoryModel Logical GLSL450
6655 OpSamplerImageAddressingModeNV 32
6656 OpEntryPoint GLCompute %func "main"
6657 %voidt = OpTypeVoid
6658 %uintt = OpTypeInt 32 0
6659 %funct = OpTypeFunction %voidt
6660 %func = OpFunction %voidt None %funct
6661 %entry = OpLabel
6662 %udef = OpUndef %uintt
6663 OpReturn
6664 OpFunctionEnd
6665 )";
6666 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6667 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6668 }
6669
TEST_F(ValidateImage,NVBindlessInvalidAddressingMode)6670 TEST_F(ValidateImage, NVBindlessInvalidAddressingMode) {
6671 std::string text = R"(
6672 OpCapability Shader
6673 OpCapability BindlessTextureNV
6674 OpExtension "SPV_NV_bindless_texture"
6675 OpMemoryModel Logical GLSL450
6676 OpSamplerImageAddressingModeNV 0
6677 OpEntryPoint GLCompute %func "main"
6678 %voidt = OpTypeVoid
6679 %uintt = OpTypeInt 32 0
6680 %funct = OpTypeFunction %voidt
6681 %func = OpFunction %voidt None %funct
6682 %entry = OpLabel
6683 %udef = OpUndef %uintt
6684 OpReturn
6685 OpFunctionEnd
6686 )";
6687 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
6688 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6689 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
6690 EXPECT_THAT(
6691 getDiagnosticString(),
6692 HasSubstr("OpSamplerImageAddressingModeNV bitwidth should be 64 or 32"));
6693 }
6694
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADNoDecorationA)6695 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationA) {
6696 std::string text = R"(
6697 OpCapability Shader
6698 OpCapability TextureBlockMatchQCOM
6699 OpExtension "SPV_QCOM_image_processing"
6700 %1 = OpExtInstImport "GLSL.std.450"
6701 OpMemoryModel Logical GLSL450
6702 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6703 OpExecutionMode %2 OriginUpperLeft
6704 OpDecorate %3 Location 0
6705 OpDecorate %4 DescriptorSet 0
6706 OpDecorate %4 Binding 1
6707 OpDecorate %5 DescriptorSet 0
6708 OpDecorate %5 Binding 3
6709 OpDecorate %6 DescriptorSet 0
6710 OpDecorate %6 Binding 2
6711 OpDecorate %6 BlockMatchTextureQCOM
6712 %void = OpTypeVoid
6713 %8 = OpTypeFunction %void
6714 %uint = OpTypeInt 32 0
6715 %v2uint = OpTypeVector %uint 2
6716 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6717 %float = OpTypeFloat 32
6718 %v4float = OpTypeVector %float 4
6719 %_ptr_Input_float = OpTypePointer Input %float
6720 %_ptr_Function_uint = OpTypePointer Function %uint
6721 %uint_4 = OpConstant %uint 4
6722 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6723 %_ptr_Output_v4float = OpTypePointer Output %v4float
6724 %3 = OpVariable %_ptr_Output_v4float Output
6725 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6726 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6727 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6728 %21 = OpTypeSampler
6729 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6730 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6731 %23 = OpTypeSampledImage %19
6732 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6733 %2 = OpFunction %void None %8
6734 %24 = OpLabel
6735 %25 = OpVariable %_ptr_Function_v2uint Function
6736 %26 = OpLoad %19 %4
6737 %27 = OpLoad %21 %5
6738 %28 = OpSampledImage %23 %26 %27
6739 %29 = OpLoad %v2uint %25
6740 %30 = OpLoad %19 %6
6741 %31 = OpLoad %21 %5
6742 %32 = OpSampledImage %23 %30 %31
6743 %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29
6744 OpStore %3 %33
6745 OpReturn
6746 OpFunctionEnd
6747 )";
6748 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6749 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6750 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6751 EXPECT_THAT(getDiagnosticString(),
6752 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
6753 }
6754
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADNoDecorationB)6755 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationB) {
6756 std::string text = R"(
6757 OpCapability Shader
6758 OpCapability TextureBlockMatchQCOM
6759 OpExtension "SPV_QCOM_image_processing"
6760 %1 = OpExtInstImport "GLSL.std.450"
6761 OpMemoryModel Logical GLSL450
6762 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6763 OpExecutionMode %2 OriginUpperLeft
6764 OpDecorate %3 Location 0
6765 OpDecorate %4 DescriptorSet 0
6766 OpDecorate %4 Binding 1
6767 OpDecorate %5 DescriptorSet 0
6768 OpDecorate %5 Binding 3
6769 OpDecorate %5 BlockMatchTextureQCOM
6770 OpDecorate %6 DescriptorSet 0
6771 OpDecorate %6 Binding 2
6772 %void = OpTypeVoid
6773 %8 = OpTypeFunction %void
6774 %uint = OpTypeInt 32 0
6775 %v2uint = OpTypeVector %uint 2
6776 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6777 %float = OpTypeFloat 32
6778 %v4float = OpTypeVector %float 4
6779 %_ptr_Input_float = OpTypePointer Input %float
6780 %_ptr_Function_uint = OpTypePointer Function %uint
6781 %uint_4 = OpConstant %uint 4
6782 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6783 %_ptr_Output_v4float = OpTypePointer Output %v4float
6784 %3 = OpVariable %_ptr_Output_v4float Output
6785 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6786 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6787 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6788 %21 = OpTypeSampler
6789 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6790 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6791 %23 = OpTypeSampledImage %19
6792 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6793 %2 = OpFunction %void None %8
6794 %24 = OpLabel
6795 %25 = OpVariable %_ptr_Function_v2uint Function
6796 %26 = OpLoad %19 %4
6797 %27 = OpLoad %21 %5
6798 %28 = OpSampledImage %23 %26 %27
6799 %29 = OpLoad %v2uint %25
6800 %30 = OpLoad %19 %6
6801 %31 = OpLoad %21 %5
6802 %32 = OpSampledImage %23 %30 %31
6803 %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29
6804 OpStore %3 %33
6805 OpReturn
6806 OpFunctionEnd
6807 )";
6808 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6809 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6810 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6811 EXPECT_THAT(getDiagnosticString(),
6812 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
6813 }
6814
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADNoDecorationC)6815 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationC) {
6816 std::string text = R"(
6817 OpCapability Shader
6818 OpCapability TextureBlockMatchQCOM
6819 OpExtension "SPV_QCOM_image_processing"
6820 %1 = OpExtInstImport "GLSL.std.450"
6821 OpMemoryModel Logical GLSL450
6822 OpEntryPoint Fragment %2 "main" %3 %4 %5
6823 OpExecutionMode %2 OriginUpperLeft
6824 OpDecorate %3 Location 0
6825 OpDecorate %4 DescriptorSet 0
6826 OpDecorate %4 Binding 4
6827 OpDecorate %5 DescriptorSet 0
6828 OpDecorate %5 Binding 5
6829 OpDecorate %5 BlockMatchTextureQCOM
6830 %void = OpTypeVoid
6831 %7 = OpTypeFunction %void
6832 %uint = OpTypeInt 32 0
6833 %v2uint = OpTypeVector %uint 2
6834 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6835 %float = OpTypeFloat 32
6836 %v4float = OpTypeVector %float 4
6837 %_ptr_Input_v4float = OpTypePointer Input %v4float
6838 %_ptr_Input_float = OpTypePointer Input %float
6839 %_ptr_Function_uint = OpTypePointer Function %uint
6840 %_ptr_Output_v4float = OpTypePointer Output %v4float
6841 %3 = OpVariable %_ptr_Output_v4float Output
6842 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
6843 %19 = OpTypeSampledImage %18
6844 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6845 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6846 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6847 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
6848 %2 = OpFunction %void None %7
6849 %22 = OpLabel
6850 %23 = OpVariable %_ptr_Function_v2uint Function
6851 %24 = OpLoad %19 %4
6852 %25 = OpLoad %v2uint %23
6853 %26 = OpLoad %19 %5
6854 %27 = OpLoad %v2uint %23
6855 %28 = OpLoad %v2uint %23
6856 %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28
6857 OpStore %3 %29
6858 OpReturn
6859 OpFunctionEnd
6860 )";
6861 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6862 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6863 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6864 EXPECT_THAT(getDiagnosticString(),
6865 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
6866 }
6867
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADNoDecorationD)6868 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationD) {
6869 std::string text = R"(
6870 OpCapability Shader
6871 OpCapability TextureBlockMatchQCOM
6872 OpExtension "SPV_QCOM_image_processing"
6873 %1 = OpExtInstImport "GLSL.std.450"
6874 OpMemoryModel Logical GLSL450
6875 OpEntryPoint Fragment %2 "main" %3 %4 %5
6876 OpExecutionMode %2 OriginUpperLeft
6877 OpDecorate %3 Location 0
6878 OpDecorate %4 DescriptorSet 0
6879 OpDecorate %4 Binding 4
6880 OpDecorate %4 BlockMatchTextureQCOM
6881 OpDecorate %5 DescriptorSet 0
6882 OpDecorate %5 Binding 5
6883 %void = OpTypeVoid
6884 %7 = OpTypeFunction %void
6885 %uint = OpTypeInt 32 0
6886 %v2uint = OpTypeVector %uint 2
6887 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6888 %float = OpTypeFloat 32
6889 %v4float = OpTypeVector %float 4
6890 %_ptr_Input_v4float = OpTypePointer Input %v4float
6891 %_ptr_Input_float = OpTypePointer Input %float
6892 %_ptr_Function_uint = OpTypePointer Function %uint
6893 %_ptr_Output_v4float = OpTypePointer Output %v4float
6894 %3 = OpVariable %_ptr_Output_v4float Output
6895 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
6896 %19 = OpTypeSampledImage %18
6897 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6898 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6899 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6900 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
6901 %2 = OpFunction %void None %7
6902 %22 = OpLabel
6903 %23 = OpVariable %_ptr_Function_v2uint Function
6904 %24 = OpLoad %19 %4
6905 %25 = OpLoad %v2uint %23
6906 %26 = OpLoad %19 %5
6907 %27 = OpLoad %v2uint %23
6908 %28 = OpLoad %v2uint %23
6909 %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28
6910 OpStore %3 %29
6911 OpReturn
6912 OpFunctionEnd
6913 )";
6914 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6915 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6916 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6917 EXPECT_THAT(getDiagnosticString(),
6918 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
6919 }
6920
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDNoDecorationA)6921 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationA) {
6922 std::string text = R"(
6923 OpCapability Shader
6924 OpCapability TextureBlockMatchQCOM
6925 OpExtension "SPV_QCOM_image_processing"
6926 %1 = OpExtInstImport "GLSL.std.450"
6927 OpMemoryModel Logical GLSL450
6928 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6929 OpExecutionMode %2 OriginUpperLeft
6930 OpDecorate %3 Location 0
6931 OpDecorate %4 DescriptorSet 0
6932 OpDecorate %4 Binding 1
6933 OpDecorate %5 DescriptorSet 0
6934 OpDecorate %5 Binding 3
6935 OpDecorate %6 DescriptorSet 0
6936 OpDecorate %6 Binding 2
6937 OpDecorate %6 BlockMatchTextureQCOM
6938 %void = OpTypeVoid
6939 %8 = OpTypeFunction %void
6940 %uint = OpTypeInt 32 0
6941 %v2uint = OpTypeVector %uint 2
6942 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
6943 %float = OpTypeFloat 32
6944 %v4float = OpTypeVector %float 4
6945 %_ptr_Input_float = OpTypePointer Input %float
6946 %_ptr_Function_uint = OpTypePointer Function %uint
6947 %uint_4 = OpConstant %uint 4
6948 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
6949 %_ptr_Output_v4float = OpTypePointer Output %v4float
6950 %3 = OpVariable %_ptr_Output_v4float Output
6951 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
6952 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
6953 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6954 %21 = OpTypeSampler
6955 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
6956 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
6957 %23 = OpTypeSampledImage %19
6958 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
6959 %2 = OpFunction %void None %8
6960 %24 = OpLabel
6961 %25 = OpVariable %_ptr_Function_v2uint Function
6962 %26 = OpLoad %19 %4
6963 %27 = OpLoad %21 %5
6964 %28 = OpSampledImage %23 %26 %27
6965 %29 = OpLoad %v2uint %25
6966 %30 = OpLoad %19 %6
6967 %31 = OpLoad %21 %5
6968 %32 = OpSampledImage %23 %30 %31
6969 %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29
6970 OpStore %3 %33
6971 OpReturn
6972 OpFunctionEnd
6973 )";
6974 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
6975 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
6976 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
6977 EXPECT_THAT(getDiagnosticString(),
6978 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
6979 }
6980
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDNoDecorationB)6981 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationB) {
6982 std::string text = R"(
6983 OpCapability Shader
6984 OpCapability TextureBlockMatchQCOM
6985 OpExtension "SPV_QCOM_image_processing"
6986 %1 = OpExtInstImport "GLSL.std.450"
6987 OpMemoryModel Logical GLSL450
6988 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
6989 OpExecutionMode %2 OriginUpperLeft
6990 OpDecorate %3 Location 0
6991 OpDecorate %4 DescriptorSet 0
6992 OpDecorate %4 Binding 1
6993 OpDecorate %5 DescriptorSet 0
6994 OpDecorate %5 Binding 3
6995 OpDecorate %5 BlockMatchTextureQCOM
6996 OpDecorate %6 DescriptorSet 0
6997 OpDecorate %6 Binding 2
6998 %void = OpTypeVoid
6999 %8 = OpTypeFunction %void
7000 %uint = OpTypeInt 32 0
7001 %v2uint = OpTypeVector %uint 2
7002 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7003 %float = OpTypeFloat 32
7004 %v4float = OpTypeVector %float 4
7005 %_ptr_Input_float = OpTypePointer Input %float
7006 %_ptr_Function_uint = OpTypePointer Function %uint
7007 %uint_4 = OpConstant %uint 4
7008 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
7009 %_ptr_Output_v4float = OpTypePointer Output %v4float
7010 %3 = OpVariable %_ptr_Output_v4float Output
7011 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
7012 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7013 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7014 %21 = OpTypeSampler
7015 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
7016 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
7017 %23 = OpTypeSampledImage %19
7018 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7019 %2 = OpFunction %void None %8
7020 %24 = OpLabel
7021 %25 = OpVariable %_ptr_Function_v2uint Function
7022 %26 = OpLoad %19 %4
7023 %27 = OpLoad %21 %5
7024 %28 = OpSampledImage %23 %26 %27
7025 %29 = OpLoad %v2uint %25
7026 %30 = OpLoad %19 %6
7027 %31 = OpLoad %21 %5
7028 %32 = OpSampledImage %23 %30 %31
7029 %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29
7030 OpStore %3 %33
7031 OpReturn
7032 OpFunctionEnd
7033 )";
7034 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7035 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7036 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7037 EXPECT_THAT(getDiagnosticString(),
7038 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
7039 }
7040
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDNoDecorationC)7041 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationC) {
7042 std::string text = R"(
7043 OpCapability Shader
7044 OpCapability TextureBlockMatchQCOM
7045 OpExtension "SPV_QCOM_image_processing"
7046 %1 = OpExtInstImport "GLSL.std.450"
7047 OpMemoryModel Logical GLSL450
7048 OpEntryPoint Fragment %2 "main" %3 %4 %5
7049 OpExecutionMode %2 OriginUpperLeft
7050 OpDecorate %3 Location 0
7051 OpDecorate %4 DescriptorSet 0
7052 OpDecorate %4 Binding 4
7053 OpDecorate %5 DescriptorSet 0
7054 OpDecorate %5 Binding 5
7055 OpDecorate %5 BlockMatchTextureQCOM
7056 %void = OpTypeVoid
7057 %7 = OpTypeFunction %void
7058 %uint = OpTypeInt 32 0
7059 %v2uint = OpTypeVector %uint 2
7060 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7061 %float = OpTypeFloat 32
7062 %v4float = OpTypeVector %float 4
7063 %_ptr_Input_v4float = OpTypePointer Input %v4float
7064 %_ptr_Input_float = OpTypePointer Input %float
7065 %_ptr_Function_uint = OpTypePointer Function %uint
7066 %_ptr_Output_v4float = OpTypePointer Output %v4float
7067 %3 = OpVariable %_ptr_Output_v4float Output
7068 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7069 %19 = OpTypeSampledImage %18
7070 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7071 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7072 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7073 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
7074 %2 = OpFunction %void None %7
7075 %22 = OpLabel
7076 %23 = OpVariable %_ptr_Function_v2uint Function
7077 %24 = OpLoad %19 %4
7078 %25 = OpLoad %v2uint %23
7079 %26 = OpLoad %19 %5
7080 %27 = OpLoad %v2uint %23
7081 %28 = OpLoad %v2uint %23
7082 %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28
7083 OpStore %3 %29
7084 OpReturn
7085 OpFunctionEnd
7086 )";
7087 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7088 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7089 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7090 EXPECT_THAT(getDiagnosticString(),
7091 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
7092 }
7093
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDNoDecorationD)7094 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationD) {
7095 std::string text = R"(
7096 OpCapability Shader
7097 OpCapability TextureBlockMatchQCOM
7098 OpExtension "SPV_QCOM_image_processing"
7099 %1 = OpExtInstImport "GLSL.std.450"
7100 OpMemoryModel Logical GLSL450
7101 OpEntryPoint Fragment %2 "main" %3 %4 %5
7102 OpExecutionMode %2 OriginUpperLeft
7103 OpDecorate %3 Location 0
7104 OpDecorate %4 DescriptorSet 0
7105 OpDecorate %4 Binding 4
7106 OpDecorate %4 BlockMatchTextureQCOM
7107 OpDecorate %5 DescriptorSet 0
7108 OpDecorate %5 Binding 5
7109 %void = OpTypeVoid
7110 %7 = OpTypeFunction %void
7111 %uint = OpTypeInt 32 0
7112 %v2uint = OpTypeVector %uint 2
7113 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7114 %float = OpTypeFloat 32
7115 %v4float = OpTypeVector %float 4
7116 %_ptr_Input_v4float = OpTypePointer Input %v4float
7117 %_ptr_Input_float = OpTypePointer Input %float
7118 %_ptr_Function_uint = OpTypePointer Function %uint
7119 %_ptr_Output_v4float = OpTypePointer Output %v4float
7120 %3 = OpVariable %_ptr_Output_v4float Output
7121 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7122 %19 = OpTypeSampledImage %18
7123 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7124 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7125 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7126 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
7127 %2 = OpFunction %void None %7
7128 %22 = OpLabel
7129 %23 = OpVariable %_ptr_Function_v2uint Function
7130 %24 = OpLoad %19 %4
7131 %25 = OpLoad %v2uint %23
7132 %26 = OpLoad %19 %5
7133 %27 = OpLoad %v2uint %23
7134 %28 = OpLoad %v2uint %23
7135 %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28
7136 OpStore %3 %29
7137 OpReturn
7138 OpFunctionEnd
7139 )";
7140 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7141 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7142 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7143 EXPECT_THAT(getDiagnosticString(),
7144 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
7145 }
7146
TEST_F(ValidateImage,QCOMImageProcessingSampleWeightedNoDecorationA)7147 TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationA) {
7148 std::string text = R"(
7149 OpCapability Shader
7150 OpCapability TextureSampleWeightedQCOM
7151 OpExtension "SPV_QCOM_image_processing"
7152 %1 = OpExtInstImport "GLSL.std.450"
7153 OpMemoryModel Logical GLSL450
7154 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7
7155 OpExecutionMode %2 OriginUpperLeft
7156 OpDecorate %3 Location 0
7157 OpDecorate %4 DescriptorSet 0
7158 OpDecorate %4 Binding 1
7159 OpDecorate %5 DescriptorSet 0
7160 OpDecorate %5 Binding 3
7161 OpDecorate %6 Location 0
7162 OpDecorate %7 DescriptorSet 0
7163 OpDecorate %7 Binding 0
7164 %void = OpTypeVoid
7165 %9 = OpTypeFunction %void
7166 %float = OpTypeFloat 32
7167 %v4float = OpTypeVector %float 4
7168 %_ptr_Output_v4float = OpTypePointer Output %v4float
7169 %3 = OpVariable %_ptr_Output_v4float Output
7170 %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
7171 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
7172 %4 = OpVariable %_ptr_UniformConstant_13 UniformConstant
7173 %15 = OpTypeSampler
7174 %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
7175 %5 = OpVariable %_ptr_UniformConstant_15 UniformConstant
7176 %17 = OpTypeSampledImage %13
7177 %_ptr_Input_v4float = OpTypePointer Input %v4float
7178 %6 = OpVariable %_ptr_Input_v4float Input
7179 %v2float = OpTypeVector %float 2
7180 %20 = OpTypeImage %float 2D 0 1 0 1 Unknown
7181 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7182 %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7183 %22 = OpTypeSampledImage %20
7184 %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
7185 %2 = OpFunction %void None %9
7186 %24 = OpLabel
7187 %25 = OpLoad %13 %4
7188 %26 = OpLoad %15 %5
7189 %27 = OpSampledImage %17 %25 %26
7190 %28 = OpLoad %v4float %6
7191 %29 = OpVectorShuffle %v2float %28 %28 0 1
7192 %30 = OpLoad %20 %7
7193 %31 = OpLoad %15 %5
7194 %32 = OpSampledImage %22 %30 %31
7195 %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32
7196 OpStore %3 %33
7197 OpReturn
7198 OpFunctionEnd
7199 )";
7200 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7201 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7202 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7203 EXPECT_THAT(getDiagnosticString(),
7204 HasSubstr("Missing decoration WeightTextureQCOM"));
7205 }
7206
TEST_F(ValidateImage,QCOMImageProcessingSampleWeightedNoDecorationB)7207 TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationB) {
7208 std::string text = R"(
7209 OpCapability Shader
7210 OpCapability TextureSampleWeightedQCOM
7211 OpExtension "SPV_QCOM_image_processing"
7212 %1 = OpExtInstImport "GLSL.std.450"
7213 OpMemoryModel Logical GLSL450
7214 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7215 OpExecutionMode %2 OriginUpperLeft
7216 OpDecorate %3 Location 0
7217 OpDecorate %4 Location 0
7218 OpDecorate %5 DescriptorSet 0
7219 OpDecorate %5 Binding 4
7220 OpDecorate %6 DescriptorSet 0
7221 OpDecorate %6 Binding 5
7222 %void = OpTypeVoid
7223 %8 = OpTypeFunction %void
7224 %float = OpTypeFloat 32
7225 %v4float = OpTypeVector %float 4
7226 %_ptr_Output_v4float = OpTypePointer Output %v4float
7227 %3 = OpVariable %_ptr_Output_v4float Output
7228 %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
7229 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
7230 %14 = OpTypeSampler
7231 %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
7232 %16 = OpTypeSampledImage %12
7233 %_ptr_Input_v4float = OpTypePointer Input %v4float
7234 %4 = OpVariable %_ptr_Input_v4float Input
7235 %v2float = OpTypeVector %float 2
7236 %19 = OpTypeImage %float 2D 0 1 0 1 Unknown
7237 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7238 %21 = OpTypeSampledImage %19
7239 %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
7240 %5 = OpVariable %_ptr_UniformConstant_16 UniformConstant
7241 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
7242 %6 = OpVariable %_ptr_UniformConstant_21 UniformConstant
7243 %2 = OpFunction %void None %8
7244 %24 = OpLabel
7245 %25 = OpLoad %16 %5
7246 %26 = OpLoad %v4float %4
7247 %27 = OpVectorShuffle %v2float %26 %26 0 1
7248 %28 = OpLoad %21 %6
7249 %29 = OpImageSampleWeightedQCOM %v4float %25 %27 %28
7250 OpStore %3 %29
7251 OpReturn
7252 OpFunctionEnd
7253 )";
7254 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7255 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7256 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7257 EXPECT_THAT(getDiagnosticString(),
7258 HasSubstr("Missing decoration WeightTextureQCOM"));
7259 }
7260
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchWindowSADInvalidUseA)7261 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchWindowSADInvalidUseA) {
7262 std::string text = R"(
7263 ; SPIR-V
7264 ; Version: 1.0
7265 ; Generator: Khronos Glslang Reference Front End; 11
7266 ; Bound: 79
7267 ; Schema: 0
7268 OpCapability Shader
7269 OpCapability TextureBlockMatchQCOM
7270 OpExtension "SPV_QCOM_image_processing"
7271 %1 = OpExtInstImport "GLSL.std.450"
7272 OpMemoryModel Logical GLSL450
7273 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7274 OpExecutionMode %main OriginUpperLeft
7275 OpDecorate %100 Location 0
7276 OpDecorate %101 Location 0
7277 OpDecorate %102 DescriptorSet 0
7278 OpDecorate %102 Binding 1
7279 OpDecorate %103 DescriptorSet 0
7280 OpDecorate %103 Binding 3
7281 OpDecorate %104 DescriptorSet 0
7282 OpDecorate %104 Binding 2
7283 OpDecorate %102 BlockMatchTextureQCOM
7284 OpDecorate %104 BlockMatchTextureQCOM
7285 %void = OpTypeVoid
7286 %3 = OpTypeFunction %void
7287 %uint = OpTypeInt 32 0
7288 %v2uint = OpTypeVector %uint 2
7289 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7290 %float = OpTypeFloat 32
7291 %v4float = OpTypeVector %float 4
7292 %_ptr_Input_v4float = OpTypePointer Input %v4float
7293 %100 = OpVariable %_ptr_Input_v4float Input
7294 %_ptr_Output_v4float = OpTypePointer Output %v4float
7295 %101 = OpVariable %_ptr_Output_v4float Output
7296 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7297 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7298 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7299 %46 = OpTypeSampler
7300 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7301 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7302 %50 = OpTypeSampledImage %42
7303 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7304 %v2float = OpTypeVector %float 2
7305 %main = OpFunction %void None %3
7306 %5 = OpLabel
7307 %15 = OpVariable %_ptr_Function_v2uint Function
7308 %45 = OpLoad %42 %102
7309 %49 = OpLoad %46 %103
7310 %51 = OpSampledImage %50 %45 %49
7311 %52 = OpLoad %v2uint %15
7312 %54 = OpLoad %42 %104
7313 %55 = OpLoad %46 %103
7314 %56 = OpSampledImage %50 %54 %55
7315 %57 = OpLoad %v2uint %15
7316 %58 = OpLoad %v2uint %15
7317 %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58
7318 OpStore %101 %59
7319 %69 = OpLoad %42 %102
7320 %70 = OpLoad %46 %103
7321 %71 = OpSampledImage %50 %69 %70
7322 %73 = OpLoad %v4float %100
7323 %74 = OpVectorShuffle %v2float %73 %73 0 0
7324 %75 = OpImageSampleImplicitLod %v4float %71 %74
7325 OpStore %101 %75
7326 OpReturn
7327 OpFunctionEnd
7328 )";
7329 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7330 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7331 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7332 EXPECT_THAT(
7333 getDiagnosticString(),
7334 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7335 }
7336
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADInvalidUseB)7337 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseB) {
7338 std::string text = R"(
7339 ; SPIR-V
7340 ; Version: 1.0
7341 ; Generator: Khronos Glslang Reference Front End; 11
7342 ; Bound: 79
7343 ; Schema: 0
7344 OpCapability Shader
7345 OpCapability TextureBlockMatchQCOM
7346 OpExtension "SPV_QCOM_image_processing"
7347 %1 = OpExtInstImport "GLSL.std.450"
7348 OpMemoryModel Logical GLSL450
7349 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7350 OpExecutionMode %main OriginUpperLeft
7351 OpDecorate %100 Location 0
7352 OpDecorate %101 Location 0
7353 OpDecorate %102 DescriptorSet 0
7354 OpDecorate %102 Binding 1
7355 OpDecorate %103 DescriptorSet 0
7356 OpDecorate %103 Binding 3
7357 OpDecorate %104 DescriptorSet 0
7358 OpDecorate %104 Binding 2
7359 OpDecorate %102 BlockMatchTextureQCOM
7360 OpDecorate %104 BlockMatchTextureQCOM
7361 %void = OpTypeVoid
7362 %3 = OpTypeFunction %void
7363 %uint = OpTypeInt 32 0
7364 %v2uint = OpTypeVector %uint 2
7365 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7366 %float = OpTypeFloat 32
7367 %v4float = OpTypeVector %float 4
7368 %_ptr_Input_v4float = OpTypePointer Input %v4float
7369 %100 = OpVariable %_ptr_Input_v4float Input
7370 %_ptr_Output_v4float = OpTypePointer Output %v4float
7371 %101 = OpVariable %_ptr_Output_v4float Output
7372 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7373 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7374 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7375 %46 = OpTypeSampler
7376 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7377 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7378 %50 = OpTypeSampledImage %42
7379 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7380 %v2float = OpTypeVector %float 2
7381 %main = OpFunction %void None %3
7382 %5 = OpLabel
7383 %15 = OpVariable %_ptr_Function_v2uint Function
7384 %45 = OpLoad %42 %102
7385 %49 = OpLoad %46 %103
7386 %51 = OpSampledImage %50 %45 %49
7387 %52 = OpLoad %v2uint %15
7388 %54 = OpLoad %42 %104
7389 %55 = OpLoad %46 %103
7390 %56 = OpSampledImage %50 %54 %55
7391 %57 = OpLoad %v2uint %15
7392 %58 = OpLoad %v2uint %15
7393 %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58
7394 OpStore %101 %59
7395 %69 = OpLoad %42 %104
7396 %70 = OpLoad %46 %103
7397 %71 = OpSampledImage %50 %69 %70
7398 %73 = OpLoad %v4float %100
7399 %74 = OpVectorShuffle %v2float %73 %73 0 0
7400 %75 = OpImageSampleImplicitLod %v4float %71 %74
7401 OpStore %101 %75
7402 OpReturn
7403 OpFunctionEnd
7404 )";
7405 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7406 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7407 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7408 EXPECT_THAT(
7409 getDiagnosticString(),
7410 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7411 }
7412
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADInvalidUseC)7413 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseC) {
7414 std::string text = R"(
7415 OpCapability Shader
7416 OpCapability TextureBlockMatchQCOM
7417 OpExtension "SPV_QCOM_image_processing"
7418 %1 = OpExtInstImport "GLSL.std.450"
7419 OpMemoryModel Logical GLSL450
7420 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7421 OpExecutionMode %2 OriginUpperLeft
7422 OpDecorate %3 Location 0
7423 OpDecorate %4 Location 0
7424 OpDecorate %5 DescriptorSet 0
7425 OpDecorate %5 Binding 4
7426 OpDecorate %6 DescriptorSet 0
7427 OpDecorate %6 Binding 5
7428 OpDecorate %5 BlockMatchTextureQCOM
7429 OpDecorate %6 BlockMatchTextureQCOM
7430 %void = OpTypeVoid
7431 %8 = OpTypeFunction %void
7432 %uint = OpTypeInt 32 0
7433 %v2uint = OpTypeVector %uint 2
7434 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7435 %float = OpTypeFloat 32
7436 %v4float = OpTypeVector %float 4
7437 %_ptr_Input_v4float = OpTypePointer Input %v4float
7438 %3 = OpVariable %_ptr_Input_v4float Input
7439 %uint_4 = OpConstant %uint 4
7440 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7441 %_ptr_Output_v4float = OpTypePointer Output %v4float
7442 %4 = OpVariable %_ptr_Output_v4float Output
7443 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7444 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7445 %20 = OpTypeSampledImage %18
7446 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7447 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7448 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7449 %v2float = OpTypeVector %float 2
7450 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7451 %2 = OpFunction %void None %8
7452 %24 = OpLabel
7453 %25 = OpVariable %_ptr_Function_v2uint Function
7454 OpStore %25 %16
7455 %26 = OpLoad %20 %5
7456 %27 = OpLoad %v2uint %25
7457 %28 = OpLoad %20 %6
7458 %29 = OpLoad %v2uint %25
7459 %30 = OpLoad %v2uint %25
7460 %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30
7461 OpStore %4 %31
7462 %32 = OpLoad %20 %5
7463 %33 = OpLoad %v4float %3
7464 %34 = OpVectorShuffle %v2float %33 %33 0 2
7465 %35 = OpImageSampleImplicitLod %v4float %32 %34
7466 OpStore %4 %35
7467 OpReturn
7468 OpFunctionEnd
7469 )";
7470 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7471 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7472 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7473 EXPECT_THAT(
7474 getDiagnosticString(),
7475 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7476 }
7477
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSADInvalidUseD)7478 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseD) {
7479 std::string text = R"(
7480 OpCapability Shader
7481 OpCapability TextureBlockMatchQCOM
7482 OpExtension "SPV_QCOM_image_processing"
7483 %1 = OpExtInstImport "GLSL.std.450"
7484 OpMemoryModel Logical GLSL450
7485 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7486 OpExecutionMode %2 OriginUpperLeft
7487 OpDecorate %3 Location 0
7488 OpDecorate %4 Location 0
7489 OpDecorate %5 DescriptorSet 0
7490 OpDecorate %5 Binding 4
7491 OpDecorate %6 DescriptorSet 0
7492 OpDecorate %6 Binding 5
7493 OpDecorate %5 BlockMatchTextureQCOM
7494 OpDecorate %6 BlockMatchTextureQCOM
7495 %void = OpTypeVoid
7496 %8 = OpTypeFunction %void
7497 %uint = OpTypeInt 32 0
7498 %v2uint = OpTypeVector %uint 2
7499 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7500 %float = OpTypeFloat 32
7501 %v4float = OpTypeVector %float 4
7502 %_ptr_Input_v4float = OpTypePointer Input %v4float
7503 %3 = OpVariable %_ptr_Input_v4float Input
7504 %uint_4 = OpConstant %uint 4
7505 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7506 %_ptr_Output_v4float = OpTypePointer Output %v4float
7507 %4 = OpVariable %_ptr_Output_v4float Output
7508 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7509 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7510 %20 = OpTypeSampledImage %18
7511 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7512 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7513 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7514 %v2float = OpTypeVector %float 2
7515 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7516 %2 = OpFunction %void None %8
7517 %24 = OpLabel
7518 %25 = OpVariable %_ptr_Function_v2uint Function
7519 OpStore %25 %16
7520 %26 = OpLoad %20 %5
7521 %27 = OpLoad %v2uint %25
7522 %28 = OpLoad %20 %6
7523 %29 = OpLoad %v2uint %25
7524 %30 = OpLoad %v2uint %25
7525 %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30
7526 OpStore %4 %31
7527 %32 = OpLoad %20 %6
7528 %33 = OpLoad %v4float %3
7529 %34 = OpVectorShuffle %v2float %33 %33 0 2
7530 %35 = OpImageSampleImplicitLod %v4float %32 %34
7531 OpStore %4 %35
7532 OpReturn
7533 OpFunctionEnd
7534 )";
7535 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7536 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7537 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7538 EXPECT_THAT(
7539 getDiagnosticString(),
7540 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7541 }
7542
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDInvalidUseA)7543 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseA) {
7544 std::string text = R"(
7545 ; SPIR-V
7546 ; Version: 1.0
7547 ; Generator: Khronos Glslang Reference Front End; 11
7548 ; Bound: 79
7549 ; Schema: 0
7550 OpCapability Shader
7551 OpCapability TextureBlockMatchQCOM
7552 OpExtension "SPV_QCOM_image_processing"
7553 %1 = OpExtInstImport "GLSL.std.450"
7554 OpMemoryModel Logical GLSL450
7555 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7556 OpExecutionMode %main OriginUpperLeft
7557 OpDecorate %100 Location 0
7558 OpDecorate %101 Location 0
7559 OpDecorate %102 DescriptorSet 0
7560 OpDecorate %102 Binding 1
7561 OpDecorate %103 DescriptorSet 0
7562 OpDecorate %103 Binding 3
7563 OpDecorate %104 DescriptorSet 0
7564 OpDecorate %104 Binding 2
7565 OpDecorate %102 BlockMatchTextureQCOM
7566 OpDecorate %104 BlockMatchTextureQCOM
7567 %void = OpTypeVoid
7568 %3 = OpTypeFunction %void
7569 %uint = OpTypeInt 32 0
7570 %v2uint = OpTypeVector %uint 2
7571 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7572 %float = OpTypeFloat 32
7573 %v4float = OpTypeVector %float 4
7574 %_ptr_Input_v4float = OpTypePointer Input %v4float
7575 %100 = OpVariable %_ptr_Input_v4float Input
7576 %_ptr_Output_v4float = OpTypePointer Output %v4float
7577 %101 = OpVariable %_ptr_Output_v4float Output
7578 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7579 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7580 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7581 %46 = OpTypeSampler
7582 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7583 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7584 %50 = OpTypeSampledImage %42
7585 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7586 %v2float = OpTypeVector %float 2
7587 %main = OpFunction %void None %3
7588 %5 = OpLabel
7589 %15 = OpVariable %_ptr_Function_v2uint Function
7590 %45 = OpLoad %42 %102
7591 %49 = OpLoad %46 %103
7592 %51 = OpSampledImage %50 %45 %49
7593 %52 = OpLoad %v2uint %15
7594 %54 = OpLoad %42 %104
7595 %55 = OpLoad %46 %103
7596 %56 = OpSampledImage %50 %54 %55
7597 %57 = OpLoad %v2uint %15
7598 %58 = OpLoad %v2uint %15
7599 %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58
7600 OpStore %101 %59
7601 %69 = OpLoad %42 %102
7602 %70 = OpLoad %46 %103
7603 %71 = OpSampledImage %50 %69 %70
7604 %73 = OpLoad %v4float %100
7605 %74 = OpVectorShuffle %v2float %73 %73 0 0
7606 %75 = OpImageSampleImplicitLod %v4float %71 %74
7607 OpStore %101 %75
7608 OpReturn
7609 OpFunctionEnd
7610 )";
7611 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7612 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7613 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7614 EXPECT_THAT(
7615 getDiagnosticString(),
7616 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7617 }
7618
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDInvalidUseB)7619 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseB) {
7620 std::string text = R"(
7621 ; SPIR-V
7622 ; Version: 1.0
7623 ; Generator: Khronos Glslang Reference Front End; 11
7624 ; Bound: 79
7625 ; Schema: 0
7626 OpCapability Shader
7627 OpCapability TextureBlockMatchQCOM
7628 OpExtension "SPV_QCOM_image_processing"
7629 %1 = OpExtInstImport "GLSL.std.450"
7630 OpMemoryModel Logical GLSL450
7631 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
7632 OpExecutionMode %main OriginUpperLeft
7633 OpDecorate %100 Location 0
7634 OpDecorate %101 Location 0
7635 OpDecorate %102 DescriptorSet 0
7636 OpDecorate %102 Binding 1
7637 OpDecorate %103 DescriptorSet 0
7638 OpDecorate %103 Binding 3
7639 OpDecorate %104 DescriptorSet 0
7640 OpDecorate %104 Binding 2
7641 OpDecorate %102 BlockMatchTextureQCOM
7642 OpDecorate %104 BlockMatchTextureQCOM
7643 %void = OpTypeVoid
7644 %3 = OpTypeFunction %void
7645 %uint = OpTypeInt 32 0
7646 %v2uint = OpTypeVector %uint 2
7647 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7648 %float = OpTypeFloat 32
7649 %v4float = OpTypeVector %float 4
7650 %_ptr_Input_v4float = OpTypePointer Input %v4float
7651 %100 = OpVariable %_ptr_Input_v4float Input
7652 %_ptr_Output_v4float = OpTypePointer Output %v4float
7653 %101 = OpVariable %_ptr_Output_v4float Output
7654 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
7655 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
7656 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7657 %46 = OpTypeSampler
7658 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7659 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
7660 %50 = OpTypeSampledImage %42
7661 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
7662 %v2float = OpTypeVector %float 2
7663 %main = OpFunction %void None %3
7664 %5 = OpLabel
7665 %15 = OpVariable %_ptr_Function_v2uint Function
7666 %45 = OpLoad %42 %102
7667 %49 = OpLoad %46 %103
7668 %51 = OpSampledImage %50 %45 %49
7669 %52 = OpLoad %v2uint %15
7670 %54 = OpLoad %42 %104
7671 %55 = OpLoad %46 %103
7672 %56 = OpSampledImage %50 %54 %55
7673 %57 = OpLoad %v2uint %15
7674 %58 = OpLoad %v2uint %15
7675 %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58
7676 OpStore %101 %59
7677 %69 = OpLoad %42 %104
7678 %70 = OpLoad %46 %103
7679 %71 = OpSampledImage %50 %69 %70
7680 %73 = OpLoad %v4float %100
7681 %74 = OpVectorShuffle %v2float %73 %73 0 0
7682 %75 = OpImageSampleImplicitLod %v4float %71 %74
7683 OpStore %101 %75
7684 OpReturn
7685 OpFunctionEnd
7686 )";
7687 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7688 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7689 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7690 EXPECT_THAT(
7691 getDiagnosticString(),
7692 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7693 }
7694
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDInvalidUseC)7695 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseC) {
7696 std::string text = R"(
7697 OpCapability Shader
7698 OpCapability TextureBlockMatchQCOM
7699 OpExtension "SPV_QCOM_image_processing"
7700 %1 = OpExtInstImport "GLSL.std.450"
7701 OpMemoryModel Logical GLSL450
7702 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7703 OpExecutionMode %2 OriginUpperLeft
7704 OpDecorate %3 Location 0
7705 OpDecorate %4 Location 0
7706 OpDecorate %5 DescriptorSet 0
7707 OpDecorate %5 Binding 4
7708 OpDecorate %6 DescriptorSet 0
7709 OpDecorate %6 Binding 5
7710 OpDecorate %5 BlockMatchTextureQCOM
7711 OpDecorate %6 BlockMatchTextureQCOM
7712 %void = OpTypeVoid
7713 %8 = OpTypeFunction %void
7714 %uint = OpTypeInt 32 0
7715 %v2uint = OpTypeVector %uint 2
7716 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7717 %float = OpTypeFloat 32
7718 %v4float = OpTypeVector %float 4
7719 %_ptr_Input_v4float = OpTypePointer Input %v4float
7720 %3 = OpVariable %_ptr_Input_v4float Input
7721 %uint_4 = OpConstant %uint 4
7722 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7723 %_ptr_Output_v4float = OpTypePointer Output %v4float
7724 %4 = OpVariable %_ptr_Output_v4float Output
7725 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7726 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7727 %20 = OpTypeSampledImage %18
7728 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7729 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7730 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7731 %v2float = OpTypeVector %float 2
7732 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7733 %2 = OpFunction %void None %8
7734 %24 = OpLabel
7735 %25 = OpVariable %_ptr_Function_v2uint Function
7736 OpStore %25 %16
7737 %26 = OpLoad %20 %5
7738 %27 = OpLoad %v2uint %25
7739 %28 = OpLoad %20 %6
7740 %29 = OpLoad %v2uint %25
7741 %30 = OpLoad %v2uint %25
7742 %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30
7743 OpStore %4 %31
7744 %32 = OpLoad %20 %5
7745 %33 = OpLoad %v4float %3
7746 %34 = OpVectorShuffle %v2float %33 %33 0 2
7747 %35 = OpImageSampleImplicitLod %v4float %32 %34
7748 OpStore %4 %35
7749 OpReturn
7750 OpFunctionEnd
7751 )";
7752 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7753 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7754 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7755 EXPECT_THAT(
7756 getDiagnosticString(),
7757 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7758 }
7759
TEST_F(ValidateImage,QCOMImageProcessingBlockMatchSSDInvalidUseD)7760 TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseD) {
7761 std::string text = R"(
7762 OpCapability Shader
7763 OpCapability TextureBlockMatchQCOM
7764 OpExtension "SPV_QCOM_image_processing"
7765 %1 = OpExtInstImport "GLSL.std.450"
7766 OpMemoryModel Logical GLSL450
7767 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7768 OpExecutionMode %2 OriginUpperLeft
7769 OpDecorate %3 Location 0
7770 OpDecorate %4 Location 0
7771 OpDecorate %5 DescriptorSet 0
7772 OpDecorate %5 Binding 4
7773 OpDecorate %6 DescriptorSet 0
7774 OpDecorate %6 Binding 5
7775 OpDecorate %5 BlockMatchTextureQCOM
7776 OpDecorate %6 BlockMatchTextureQCOM
7777 %void = OpTypeVoid
7778 %8 = OpTypeFunction %void
7779 %uint = OpTypeInt 32 0
7780 %v2uint = OpTypeVector %uint 2
7781 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7782 %float = OpTypeFloat 32
7783 %v4float = OpTypeVector %float 4
7784 %_ptr_Input_v4float = OpTypePointer Input %v4float
7785 %3 = OpVariable %_ptr_Input_v4float Input
7786 %uint_4 = OpConstant %uint 4
7787 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
7788 %_ptr_Output_v4float = OpTypePointer Output %v4float
7789 %4 = OpVariable %_ptr_Output_v4float Output
7790 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7791 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
7792 %20 = OpTypeSampledImage %18
7793 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7794 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7795 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7796 %v2float = OpTypeVector %float 2
7797 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
7798 %2 = OpFunction %void None %8
7799 %24 = OpLabel
7800 %25 = OpVariable %_ptr_Function_v2uint Function
7801 OpStore %25 %16
7802 %26 = OpLoad %20 %5
7803 %27 = OpLoad %v2uint %25
7804 %28 = OpLoad %20 %6
7805 %29 = OpLoad %v2uint %25
7806 %30 = OpLoad %v2uint %25
7807 %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30
7808 OpStore %4 %31
7809 %32 = OpLoad %20 %6
7810 %33 = OpLoad %v4float %3
7811 %34 = OpVectorShuffle %v2float %33 %33 0 2
7812 %35 = OpImageSampleImplicitLod %v4float %32 %34
7813 OpStore %4 %35
7814 OpReturn
7815 OpFunctionEnd
7816 )";
7817 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7818 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7819 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7820 EXPECT_THAT(
7821 getDiagnosticString(),
7822 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7823 }
7824
TEST_F(ValidateImage,QCOMImageProcessingSampleWeightedInvalidUseA)7825 TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseA) {
7826 std::string text = R"(
7827 OpCapability Shader
7828 OpCapability TextureSampleWeightedQCOM
7829 OpExtension "SPV_QCOM_image_processing"
7830 %1 = OpExtInstImport "GLSL.std.450"
7831 OpMemoryModel Logical GLSL450
7832 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
7833 OpExecutionMode %2 OriginUpperLeft
7834 OpDecorate %3 Location 0
7835 OpDecorate %4 Location 0
7836 OpDecorate %5 DescriptorSet 0
7837 OpDecorate %5 Binding 4
7838 OpDecorate %6 DescriptorSet 0
7839 OpDecorate %6 Binding 5
7840 OpDecorate %6 WeightTextureQCOM
7841 %void = OpTypeVoid
7842 %8 = OpTypeFunction %void
7843 %float = OpTypeFloat 32
7844 %v4float = OpTypeVector %float 4
7845 %_ptr_Output_v4float = OpTypePointer Output %v4float
7846 %3 = OpVariable %_ptr_Output_v4float Output
7847 %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
7848 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
7849 %14 = OpTypeSampledImage %12
7850 %_ptr_Input_v4float = OpTypePointer Input %v4float
7851 %4 = OpVariable %_ptr_Input_v4float Input
7852 %v2float = OpTypeVector %float 2
7853 %17 = OpTypeImage %float 2D 0 1 0 1 Unknown
7854 %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
7855 %19 = OpTypeSampledImage %17
7856 %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
7857 %5 = OpVariable %_ptr_UniformConstant_14 UniformConstant
7858 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7859 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7860 %v3float = OpTypeVector %float 3
7861 %2 = OpFunction %void None %8
7862 %23 = OpLabel
7863 %24 = OpLoad %v4float %4
7864 %25 = OpVectorShuffle %v2float %24 %24 0 1
7865 %26 = OpLoad %14 %5
7866 %27 = OpLoad %v4float %4
7867 %28 = OpVectorShuffle %v2float %27 %27 0 1
7868 %29 = OpLoad %19 %6
7869 %30 = OpImageSampleWeightedQCOM %v4float %26 %28 %29
7870 OpStore %3 %30
7871 %31 = OpLoad %19 %6
7872 %32 = OpLoad %v4float %4
7873 %33 = OpVectorShuffle %v3float %32 %32 0 1 0
7874 %34 = OpCompositeExtract %float %33 0
7875 %35 = OpCompositeExtract %float %33 1
7876 %36 = OpCompositeExtract %float %33 2
7877 %37 = OpCompositeConstruct %v3float %34 %35 %36
7878 %38 = OpImageSampleImplicitLod %v4float %31 %37
7879 OpStore %3 %38
7880 OpReturn
7881 OpFunctionEnd
7882 )";
7883 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7884 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7885 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7886 EXPECT_THAT(
7887 getDiagnosticString(),
7888 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7889 }
7890
TEST_F(ValidateImage,QCOMImageProcessingSampleWeightedInvalidUseB)7891 TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseB) {
7892 std::string text = R"(
7893 OpCapability Shader
7894 OpCapability TextureSampleWeightedQCOM
7895 OpExtension "SPV_QCOM_image_processing"
7896 %1 = OpExtInstImport "GLSL.std.450"
7897 OpMemoryModel Logical GLSL450
7898 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7
7899 OpExecutionMode %2 OriginUpperLeft
7900 OpDecorate %3 Location 0
7901 OpDecorate %5 DescriptorSet 0
7902 OpDecorate %5 Binding 1
7903 OpDecorate %6 DescriptorSet 0
7904 OpDecorate %6 Binding 3
7905 OpDecorate %4 Location 0
7906 OpDecorate %7 DescriptorSet 0
7907 OpDecorate %7 Binding 0
7908 OpDecorate %7 WeightTextureQCOM
7909 %void = OpTypeVoid
7910 %9 = OpTypeFunction %void
7911 %float = OpTypeFloat 32
7912 %v4float = OpTypeVector %float 4
7913 %_ptr_Output_v4float = OpTypePointer Output %v4float
7914 %3 = OpVariable %_ptr_Output_v4float Output
7915 %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
7916 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
7917 %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
7918 %15 = OpTypeSampler
7919 %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
7920 %6 = OpVariable %_ptr_UniformConstant_15 UniformConstant
7921 %17 = OpTypeSampledImage %13
7922 %_ptr_Input_v4float = OpTypePointer Input %v4float
7923 %4 = OpVariable %_ptr_Input_v4float Input
7924 %v2float = OpTypeVector %float 2
7925 %20 = OpTypeImage %float 2D 0 1 0 1 Unknown
7926 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
7927 %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant
7928 %22 = OpTypeSampledImage %20
7929 %v3float = OpTypeVector %float 3
7930 %2 = OpFunction %void None %9
7931 %24 = OpLabel
7932 %25 = OpLoad %13 %5
7933 %26 = OpLoad %15 %6
7934 %27 = OpSampledImage %17 %25 %26
7935 %28 = OpLoad %v4float %4
7936 %29 = OpVectorShuffle %v2float %28 %28 0 1
7937 %30 = OpLoad %20 %7
7938 %31 = OpLoad %15 %6
7939 %32 = OpSampledImage %22 %30 %31
7940 %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32
7941 OpStore %3 %33
7942 %34 = OpLoad %20 %7
7943 %35 = OpLoad %15 %6
7944 %36 = OpSampledImage %22 %34 %35
7945 %37 = OpLoad %v4float %4
7946 %38 = OpVectorShuffle %v3float %37 %37 0 1 0
7947 %39 = OpCompositeExtract %float %38 0
7948 %40 = OpCompositeExtract %float %38 1
7949 %41 = OpCompositeExtract %float %38 2
7950 %42 = OpCompositeConstruct %v3float %39 %40 %41
7951 %43 = OpImageSampleImplicitLod %v4float %36 %42
7952 OpStore %3 %43
7953 OpReturn
7954 OpFunctionEnd
7955 )";
7956 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
7957 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
7958 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
7959 EXPECT_THAT(
7960 getDiagnosticString(),
7961 HasSubstr("Illegal use of QCOM image processing decorated texture"));
7962 }
7963
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetIT)7964 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetIT) {
7965 const std::string text = R"(
7966 OpCapability Shader
7967 OpCapability TextureBlockMatchQCOM
7968 OpCapability TextureBlockMatch2QCOM
7969 OpExtension "SPV_QCOM_image_processing"
7970 OpExtension "SPV_QCOM_image_processing2"
7971 %1 = OpExtInstImport "GLSL.std.450"
7972 OpMemoryModel Logical GLSL450
7973 OpEntryPoint Fragment %2 "main" %3 %4 %5
7974 OpExecutionMode %2 OriginUpperLeft
7975 OpDecorate %3 Location 0
7976 OpDecorate %4 DescriptorSet 0
7977 OpDecorate %4 Binding 4
7978 OpDecorate %4 BlockMatchSamplerQCOM
7979 OpDecorate %5 DescriptorSet 0
7980 OpDecorate %5 Binding 5
7981 OpDecorate %5 BlockMatchTextureQCOM
7982 OpDecorate %5 BlockMatchSamplerQCOM
7983 %void = OpTypeVoid
7984 %7 = OpTypeFunction %void
7985 %uint = OpTypeInt 32 0
7986 %v2uint = OpTypeVector %uint 2
7987 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
7988 %float = OpTypeFloat 32
7989 %v4float = OpTypeVector %float 4
7990 %_ptr_Input_v4float = OpTypePointer Input %v4float
7991 %_ptr_Input_float = OpTypePointer Input %float
7992 %_ptr_Function_uint = OpTypePointer Function %uint
7993 %_ptr_Output_v4float = OpTypePointer Output %v4float
7994 %3 = OpVariable %_ptr_Output_v4float Output
7995 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
7996 %19 = OpTypeSampledImage %18
7997 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
7998 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
7999 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8000 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
8001 %2 = OpFunction %void None %7
8002 %22 = OpLabel
8003 %23 = OpVariable %_ptr_Function_v2uint Function
8004 %24 = OpLoad %19 %4
8005 %25 = OpLoad %v2uint %23
8006 %26 = OpLoad %19 %5
8007 %27 = OpLoad %v2uint %23
8008 %28 = OpLoad %v2uint %23
8009 %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
8010 OpStore %3 %29
8011 OpReturn
8012 OpFunctionEnd
8013 )";
8014 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8015 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8016 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8017 EXPECT_THAT(getDiagnosticString(),
8018 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
8019 }
8020
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetIS)8021 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetIS) {
8022 const std::string text = R"(
8023 OpCapability Shader
8024 OpCapability TextureBlockMatchQCOM
8025 OpCapability TextureBlockMatch2QCOM
8026 OpExtension "SPV_QCOM_image_processing"
8027 OpExtension "SPV_QCOM_image_processing2"
8028 %1 = OpExtInstImport "GLSL.std.450"
8029 OpMemoryModel Logical GLSL450
8030 OpEntryPoint Fragment %2 "main" %3 %4 %5
8031 OpExecutionMode %2 OriginUpperLeft
8032 OpDecorate %3 Location 0
8033 OpDecorate %4 DescriptorSet 0
8034 OpDecorate %4 Binding 4
8035 OpDecorate %4 BlockMatchTextureQCOM
8036 OpDecorate %5 DescriptorSet 0
8037 OpDecorate %5 Binding 5
8038 OpDecorate %5 BlockMatchTextureQCOM
8039 OpDecorate %5 BlockMatchSamplerQCOM
8040 %void = OpTypeVoid
8041 %7 = OpTypeFunction %void
8042 %uint = OpTypeInt 32 0
8043 %v2uint = OpTypeVector %uint 2
8044 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8045 %float = OpTypeFloat 32
8046 %v4float = OpTypeVector %float 4
8047 %_ptr_Input_v4float = OpTypePointer Input %v4float
8048 %_ptr_Input_float = OpTypePointer Input %float
8049 %_ptr_Function_uint = OpTypePointer Function %uint
8050 %_ptr_Output_v4float = OpTypePointer Output %v4float
8051 %3 = OpVariable %_ptr_Output_v4float Output
8052 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
8053 %19 = OpTypeSampledImage %18
8054 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8055 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8056 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8057 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
8058 %2 = OpFunction %void None %7
8059 %22 = OpLabel
8060 %23 = OpVariable %_ptr_Function_v2uint Function
8061 %24 = OpLoad %19 %4
8062 %25 = OpLoad %v2uint %23
8063 %26 = OpLoad %19 %5
8064 %27 = OpLoad %v2uint %23
8065 %28 = OpLoad %v2uint %23
8066 %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
8067 OpStore %3 %29
8068 OpReturn
8069 OpFunctionEnd
8070 )";
8071 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8072 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8073 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8074 EXPECT_THAT(getDiagnosticString(),
8075 HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
8076 }
8077
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADNoDecorRefIT)8078 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefIT) {
8079 const std::string text = R"(
8080 OpCapability Shader
8081 OpCapability TextureBlockMatchQCOM
8082 OpCapability TextureBlockMatch2QCOM
8083 OpExtension "SPV_QCOM_image_processing"
8084 OpExtension "SPV_QCOM_image_processing2"
8085 %1 = OpExtInstImport "GLSL.std.450"
8086 OpMemoryModel Logical GLSL450
8087 OpEntryPoint Fragment %2 "main" %3 %4 %5
8088 OpExecutionMode %2 OriginUpperLeft
8089 OpDecorate %3 Location 0
8090 OpDecorate %4 DescriptorSet 0
8091 OpDecorate %4 Binding 4
8092 OpDecorate %4 BlockMatchTextureQCOM
8093 OpDecorate %4 BlockMatchSamplerQCOM
8094 OpDecorate %5 DescriptorSet 0
8095 OpDecorate %5 Binding 5
8096 OpDecorate %5 BlockMatchSamplerQCOM
8097 %void = OpTypeVoid
8098 %7 = OpTypeFunction %void
8099 %uint = OpTypeInt 32 0
8100 %v2uint = OpTypeVector %uint 2
8101 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8102 %float = OpTypeFloat 32
8103 %v4float = OpTypeVector %float 4
8104 %_ptr_Input_v4float = OpTypePointer Input %v4float
8105 %_ptr_Input_float = OpTypePointer Input %float
8106 %_ptr_Function_uint = OpTypePointer Function %uint
8107 %_ptr_Output_v4float = OpTypePointer Output %v4float
8108 %3 = OpVariable %_ptr_Output_v4float Output
8109 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
8110 %19 = OpTypeSampledImage %18
8111 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8112 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8113 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8114 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
8115 %2 = OpFunction %void None %7
8116 %22 = OpLabel
8117 %23 = OpVariable %_ptr_Function_v2uint Function
8118 %24 = OpLoad %19 %4
8119 %25 = OpLoad %v2uint %23
8120 %26 = OpLoad %19 %5
8121 %27 = OpLoad %v2uint %23
8122 %28 = OpLoad %v2uint %23
8123 %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
8124 OpStore %3 %29
8125 OpReturn
8126 OpFunctionEnd
8127 )";
8128 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8129 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8130 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8131 EXPECT_THAT(getDiagnosticString(),
8132 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
8133 }
8134
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADNoDecorRefIS)8135 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefIS) {
8136 const std::string text = R"(
8137 OpCapability Shader
8138 OpCapability TextureBlockMatchQCOM
8139 OpCapability TextureBlockMatch2QCOM
8140 OpExtension "SPV_QCOM_image_processing"
8141 OpExtension "SPV_QCOM_image_processing2"
8142 %1 = OpExtInstImport "GLSL.std.450"
8143 OpMemoryModel Logical GLSL450
8144 OpEntryPoint Fragment %2 "main" %3 %4 %5
8145 OpExecutionMode %2 OriginUpperLeft
8146 OpDecorate %3 Location 0
8147 OpDecorate %4 DescriptorSet 0
8148 OpDecorate %4 Binding 4
8149 OpDecorate %4 BlockMatchTextureQCOM
8150 OpDecorate %4 BlockMatchSamplerQCOM
8151 OpDecorate %5 DescriptorSet 0
8152 OpDecorate %5 Binding 5
8153 OpDecorate %5 BlockMatchTextureQCOM
8154 %void = OpTypeVoid
8155 %7 = OpTypeFunction %void
8156 %uint = OpTypeInt 32 0
8157 %v2uint = OpTypeVector %uint 2
8158 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8159 %float = OpTypeFloat 32
8160 %v4float = OpTypeVector %float 4
8161 %_ptr_Input_v4float = OpTypePointer Input %v4float
8162 %_ptr_Input_float = OpTypePointer Input %float
8163 %_ptr_Function_uint = OpTypePointer Function %uint
8164 %_ptr_Output_v4float = OpTypePointer Output %v4float
8165 %3 = OpVariable %_ptr_Output_v4float Output
8166 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
8167 %19 = OpTypeSampledImage %18
8168 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8169 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8170 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8171 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
8172 %2 = OpFunction %void None %7
8173 %22 = OpLabel
8174 %23 = OpVariable %_ptr_Function_v2uint Function
8175 %24 = OpLoad %19 %4
8176 %25 = OpLoad %v2uint %23
8177 %26 = OpLoad %19 %5
8178 %27 = OpLoad %v2uint %23
8179 %28 = OpLoad %v2uint %23
8180 %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
8181 OpStore %3 %29
8182 OpReturn
8183 OpFunctionEnd
8184 )";
8185 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8186 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8187 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8188 EXPECT_THAT(getDiagnosticString(),
8189 HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
8190 }
8191
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetNIT)8192 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetNIT) {
8193 const std::string text = R"(
8194 OpCapability Shader
8195 OpCapability TextureBlockMatchQCOM
8196 OpCapability TextureBlockMatch2QCOM
8197 OpExtension "SPV_QCOM_image_processing"
8198 OpExtension "SPV_QCOM_image_processing2"
8199 %1 = OpExtInstImport "GLSL.std.450"
8200 OpMemoryModel Logical GLSL450
8201 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
8202 OpExecutionMode %2 OriginUpperLeft
8203 OpDecorate %3 Location 0
8204 OpDecorate %4 DescriptorSet 0
8205 OpDecorate %4 Binding 1
8206 OpDecorate %4 BlockMatchSamplerQCOM
8207 OpDecorate %5 DescriptorSet 0
8208 OpDecorate %5 Binding 3
8209 OpDecorate %6 DescriptorSet 0
8210 OpDecorate %6 Binding 2
8211 OpDecorate %6 BlockMatchTextureQCOM
8212 OpDecorate %6 BlockMatchSamplerQCOM
8213 %void = OpTypeVoid
8214 %8 = OpTypeFunction %void
8215 %uint = OpTypeInt 32 0
8216 %v2uint = OpTypeVector %uint 2
8217 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8218 %float = OpTypeFloat 32
8219 %v4float = OpTypeVector %float 4
8220 %_ptr_Input_float = OpTypePointer Input %float
8221 %_ptr_Function_uint = OpTypePointer Function %uint
8222 %uint_4 = OpConstant %uint 4
8223 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
8224 %_ptr_Output_v4float = OpTypePointer Output %v4float
8225 %3 = OpVariable %_ptr_Output_v4float Output
8226 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
8227 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8228 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8229 %21 = OpTypeSampler
8230 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
8231 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
8232 %23 = OpTypeSampledImage %19
8233 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8234 %2 = OpFunction %void None %8
8235 %24 = OpLabel
8236 %25 = OpVariable %_ptr_Function_v2uint Function
8237 %26 = OpLoad %19 %4
8238 %27 = OpLoad %21 %5
8239 %28 = OpSampledImage %23 %26 %27
8240 %29 = OpLoad %v2uint %25
8241 %30 = OpLoad %19 %6
8242 %31 = OpLoad %21 %5
8243 %32 = OpSampledImage %23 %30 %31
8244 %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
8245 OpStore %3 %33
8246 OpReturn
8247 OpFunctionEnd
8248 )";
8249 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8250 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8251 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8252 EXPECT_THAT(getDiagnosticString(),
8253 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
8254 }
8255
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetNIS)8256 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetNIS) {
8257 const std::string text = R"(
8258 OpCapability Shader
8259 OpCapability TextureBlockMatchQCOM
8260 OpCapability TextureBlockMatch2QCOM
8261 OpExtension "SPV_QCOM_image_processing"
8262 OpExtension "SPV_QCOM_image_processing2"
8263 %1 = OpExtInstImport "GLSL.std.450"
8264 OpMemoryModel Logical GLSL450
8265 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
8266 OpExecutionMode %2 OriginUpperLeft
8267 OpDecorate %3 Location 0
8268 OpDecorate %4 DescriptorSet 0
8269 OpDecorate %4 Binding 1
8270 OpDecorate %4 BlockMatchTextureQCOM
8271 OpDecorate %5 DescriptorSet 0
8272 OpDecorate %5 Binding 3
8273 OpDecorate %6 DescriptorSet 0
8274 OpDecorate %6 Binding 2
8275 OpDecorate %6 BlockMatchTextureQCOM
8276 OpDecorate %6 BlockMatchSamplerQCOM
8277 %void = OpTypeVoid
8278 %8 = OpTypeFunction %void
8279 %uint = OpTypeInt 32 0
8280 %v2uint = OpTypeVector %uint 2
8281 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8282 %float = OpTypeFloat 32
8283 %v4float = OpTypeVector %float 4
8284 %_ptr_Input_float = OpTypePointer Input %float
8285 %_ptr_Function_uint = OpTypePointer Function %uint
8286 %uint_4 = OpConstant %uint 4
8287 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
8288 %_ptr_Output_v4float = OpTypePointer Output %v4float
8289 %3 = OpVariable %_ptr_Output_v4float Output
8290 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
8291 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8292 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8293 %21 = OpTypeSampler
8294 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
8295 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
8296 %23 = OpTypeSampledImage %19
8297 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8298 %2 = OpFunction %void None %8
8299 %24 = OpLabel
8300 %25 = OpVariable %_ptr_Function_v2uint Function
8301 %26 = OpLoad %19 %4
8302 %27 = OpLoad %21 %5
8303 %28 = OpSampledImage %23 %26 %27
8304 %29 = OpLoad %v2uint %25
8305 %30 = OpLoad %19 %6
8306 %31 = OpLoad %21 %5
8307 %32 = OpSampledImage %23 %30 %31
8308 %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
8309 OpStore %3 %33
8310 OpReturn
8311 OpFunctionEnd
8312 )";
8313 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8314 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8315 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8316 EXPECT_THAT(getDiagnosticString(),
8317 HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
8318 }
8319
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADNoDecorRefNIT)8320 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefNIT) {
8321 const std::string text = R"(
8322 OpCapability Shader
8323 OpCapability TextureBlockMatchQCOM
8324 OpCapability TextureBlockMatch2QCOM
8325 OpExtension "SPV_QCOM_image_processing"
8326 OpExtension "SPV_QCOM_image_processing2"
8327 %1 = OpExtInstImport "GLSL.std.450"
8328 OpMemoryModel Logical GLSL450
8329 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
8330 OpExecutionMode %2 OriginUpperLeft
8331 OpDecorate %3 Location 0
8332 OpDecorate %4 DescriptorSet 0
8333 OpDecorate %4 Binding 1
8334 OpDecorate %4 BlockMatchTextureQCOM
8335 OpDecorate %5 DescriptorSet 0
8336 OpDecorate %5 Binding 3
8337 OpDecorate %5 BlockMatchSamplerQCOM
8338 OpDecorate %6 DescriptorSet 0
8339 OpDecorate %6 Binding 2
8340 OpDecorate %6 BlockMatchSamplerQCOM
8341 %void = OpTypeVoid
8342 %8 = OpTypeFunction %void
8343 %uint = OpTypeInt 32 0
8344 %v2uint = OpTypeVector %uint 2
8345 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8346 %float = OpTypeFloat 32
8347 %v4float = OpTypeVector %float 4
8348 %_ptr_Input_float = OpTypePointer Input %float
8349 %_ptr_Function_uint = OpTypePointer Function %uint
8350 %uint_4 = OpConstant %uint 4
8351 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
8352 %_ptr_Output_v4float = OpTypePointer Output %v4float
8353 %3 = OpVariable %_ptr_Output_v4float Output
8354 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
8355 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8356 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8357 %21 = OpTypeSampler
8358 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
8359 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
8360 %23 = OpTypeSampledImage %19
8361 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8362 %2 = OpFunction %void None %8
8363 %24 = OpLabel
8364 %25 = OpVariable %_ptr_Function_v2uint Function
8365 %26 = OpLoad %19 %4
8366 %27 = OpLoad %21 %5
8367 %28 = OpSampledImage %23 %26 %27
8368 %29 = OpLoad %v2uint %25
8369 %30 = OpLoad %19 %6
8370 %31 = OpLoad %21 %5
8371 %32 = OpSampledImage %23 %30 %31
8372 %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
8373 OpStore %3 %33
8374 OpReturn
8375 OpFunctionEnd
8376 )";
8377 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8378 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8379 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8380 EXPECT_THAT(getDiagnosticString(),
8381 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
8382 }
8383
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADNoDecorRefNIS)8384 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefNIS) {
8385 const std::string text = R"(
8386 OpCapability Shader
8387 OpCapability TextureBlockMatchQCOM
8388 OpCapability TextureBlockMatch2QCOM
8389 OpExtension "SPV_QCOM_image_processing"
8390 OpExtension "SPV_QCOM_image_processing2"
8391 %1 = OpExtInstImport "GLSL.std.450"
8392 OpMemoryModel Logical GLSL450
8393 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
8394 OpExecutionMode %2 OriginUpperLeft
8395 OpDecorate %3 Location 0
8396 OpDecorate %4 DescriptorSet 0
8397 OpDecorate %4 Binding 1
8398 OpDecorate %4 BlockMatchTextureQCOM
8399 OpDecorate %4 BlockMatchSamplerQCOM
8400 OpDecorate %5 DescriptorSet 0
8401 OpDecorate %5 Binding 3
8402 OpDecorate %6 DescriptorSet 0
8403 OpDecorate %6 Binding 2
8404 OpDecorate %6 BlockMatchTextureQCOM
8405 %void = OpTypeVoid
8406 %8 = OpTypeFunction %void
8407 %uint = OpTypeInt 32 0
8408 %v2uint = OpTypeVector %uint 2
8409 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8410 %float = OpTypeFloat 32
8411 %v4float = OpTypeVector %float 4
8412 %_ptr_Input_float = OpTypePointer Input %float
8413 %_ptr_Function_uint = OpTypePointer Function %uint
8414 %uint_4 = OpConstant %uint 4
8415 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
8416 %_ptr_Output_v4float = OpTypePointer Output %v4float
8417 %3 = OpVariable %_ptr_Output_v4float Output
8418 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
8419 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8420 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8421 %21 = OpTypeSampler
8422 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
8423 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
8424 %23 = OpTypeSampledImage %19
8425 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8426 %2 = OpFunction %void None %8
8427 %24 = OpLabel
8428 %25 = OpVariable %_ptr_Function_v2uint Function
8429 %26 = OpLoad %19 %4
8430 %27 = OpLoad %21 %5
8431 %28 = OpSampledImage %23 %26 %27
8432 %29 = OpLoad %v2uint %25
8433 %30 = OpLoad %19 %6
8434 %31 = OpLoad %21 %5
8435 %32 = OpSampledImage %23 %30 %31
8436 %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
8437 OpStore %3 %33
8438 OpReturn
8439 OpFunctionEnd
8440 )";
8441 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8442 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8443 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8444 EXPECT_THAT(getDiagnosticString(),
8445 HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
8446 }
8447
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetIT)8448 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetIT) {
8449 const std::string text = R"(
8450 OpCapability Shader
8451 OpCapability TextureBlockMatchQCOM
8452 OpCapability TextureBlockMatch2QCOM
8453 OpExtension "SPV_QCOM_image_processing"
8454 OpExtension "SPV_QCOM_image_processing2"
8455 %1 = OpExtInstImport "GLSL.std.450"
8456 OpMemoryModel Logical GLSL450
8457 OpEntryPoint Fragment %2 "main" %3 %4 %5
8458 OpExecutionMode %2 OriginUpperLeft
8459 OpDecorate %3 Location 0
8460 OpDecorate %4 DescriptorSet 0
8461 OpDecorate %4 Binding 4
8462 OpDecorate %4 BlockMatchSamplerQCOM
8463 OpDecorate %5 DescriptorSet 0
8464 OpDecorate %5 Binding 5
8465 OpDecorate %5 BlockMatchTextureQCOM
8466 OpDecorate %5 BlockMatchSamplerQCOM
8467 %void = OpTypeVoid
8468 %7 = OpTypeFunction %void
8469 %uint = OpTypeInt 32 0
8470 %v2uint = OpTypeVector %uint 2
8471 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8472 %float = OpTypeFloat 32
8473 %v4float = OpTypeVector %float 4
8474 %_ptr_Input_v4float = OpTypePointer Input %v4float
8475 %_ptr_Input_float = OpTypePointer Input %float
8476 %_ptr_Function_uint = OpTypePointer Function %uint
8477 %_ptr_Output_v4float = OpTypePointer Output %v4float
8478 %3 = OpVariable %_ptr_Output_v4float Output
8479 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
8480 %19 = OpTypeSampledImage %18
8481 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8482 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8483 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8484 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
8485 %2 = OpFunction %void None %7
8486 %22 = OpLabel
8487 %23 = OpVariable %_ptr_Function_v2uint Function
8488 %24 = OpLoad %19 %4
8489 %25 = OpLoad %v2uint %23
8490 %26 = OpLoad %19 %5
8491 %27 = OpLoad %v2uint %23
8492 %28 = OpLoad %v2uint %23
8493 %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
8494 OpStore %3 %29
8495 OpReturn
8496 OpFunctionEnd
8497 )";
8498 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8499 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8500 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8501 EXPECT_THAT(getDiagnosticString(),
8502 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
8503 }
8504
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetIS)8505 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetIS) {
8506 const std::string text = R"(
8507 OpCapability Shader
8508 OpCapability TextureBlockMatchQCOM
8509 OpCapability TextureBlockMatch2QCOM
8510 OpExtension "SPV_QCOM_image_processing"
8511 OpExtension "SPV_QCOM_image_processing2"
8512 %1 = OpExtInstImport "GLSL.std.450"
8513 OpMemoryModel Logical GLSL450
8514 OpEntryPoint Fragment %2 "main" %3 %4 %5
8515 OpExecutionMode %2 OriginUpperLeft
8516 OpDecorate %3 Location 0
8517 OpDecorate %4 DescriptorSet 0
8518 OpDecorate %4 Binding 4
8519 OpDecorate %4 BlockMatchTextureQCOM
8520 OpDecorate %5 DescriptorSet 0
8521 OpDecorate %5 Binding 5
8522 OpDecorate %5 BlockMatchTextureQCOM
8523 OpDecorate %5 BlockMatchSamplerQCOM
8524 %void = OpTypeVoid
8525 %7 = OpTypeFunction %void
8526 %uint = OpTypeInt 32 0
8527 %v2uint = OpTypeVector %uint 2
8528 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8529 %float = OpTypeFloat 32
8530 %v4float = OpTypeVector %float 4
8531 %_ptr_Input_v4float = OpTypePointer Input %v4float
8532 %_ptr_Input_float = OpTypePointer Input %float
8533 %_ptr_Function_uint = OpTypePointer Function %uint
8534 %_ptr_Output_v4float = OpTypePointer Output %v4float
8535 %3 = OpVariable %_ptr_Output_v4float Output
8536 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
8537 %19 = OpTypeSampledImage %18
8538 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8539 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8540 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8541 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
8542 %2 = OpFunction %void None %7
8543 %22 = OpLabel
8544 %23 = OpVariable %_ptr_Function_v2uint Function
8545 %24 = OpLoad %19 %4
8546 %25 = OpLoad %v2uint %23
8547 %26 = OpLoad %19 %5
8548 %27 = OpLoad %v2uint %23
8549 %28 = OpLoad %v2uint %23
8550 %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
8551 OpStore %3 %29
8552 OpReturn
8553 OpFunctionEnd
8554 )";
8555 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8556 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8557 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8558 EXPECT_THAT(getDiagnosticString(),
8559 HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
8560 }
8561
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefIT)8562 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefIT) {
8563 const std::string text = R"(
8564 OpCapability Shader
8565 OpCapability TextureBlockMatchQCOM
8566 OpCapability TextureBlockMatch2QCOM
8567 OpExtension "SPV_QCOM_image_processing"
8568 OpExtension "SPV_QCOM_image_processing2"
8569 %1 = OpExtInstImport "GLSL.std.450"
8570 OpMemoryModel Logical GLSL450
8571 OpEntryPoint Fragment %2 "main" %3 %4 %5
8572 OpExecutionMode %2 OriginUpperLeft
8573 OpDecorate %3 Location 0
8574 OpDecorate %4 DescriptorSet 0
8575 OpDecorate %4 Binding 4
8576 OpDecorate %4 BlockMatchTextureQCOM
8577 OpDecorate %4 BlockMatchSamplerQCOM
8578 OpDecorate %5 DescriptorSet 0
8579 OpDecorate %5 Binding 5
8580 OpDecorate %5 BlockMatchSamplerQCOM
8581 %void = OpTypeVoid
8582 %7 = OpTypeFunction %void
8583 %uint = OpTypeInt 32 0
8584 %v2uint = OpTypeVector %uint 2
8585 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8586 %float = OpTypeFloat 32
8587 %v4float = OpTypeVector %float 4
8588 %_ptr_Input_v4float = OpTypePointer Input %v4float
8589 %_ptr_Input_float = OpTypePointer Input %float
8590 %_ptr_Function_uint = OpTypePointer Function %uint
8591 %_ptr_Output_v4float = OpTypePointer Output %v4float
8592 %3 = OpVariable %_ptr_Output_v4float Output
8593 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
8594 %19 = OpTypeSampledImage %18
8595 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8596 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8597 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8598 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
8599 %2 = OpFunction %void None %7
8600 %22 = OpLabel
8601 %23 = OpVariable %_ptr_Function_v2uint Function
8602 %24 = OpLoad %19 %4
8603 %25 = OpLoad %v2uint %23
8604 %26 = OpLoad %19 %5
8605 %27 = OpLoad %v2uint %23
8606 %28 = OpLoad %v2uint %23
8607 %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
8608 OpStore %3 %29
8609 OpReturn
8610 OpFunctionEnd
8611 )";
8612 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8613 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8614 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8615 EXPECT_THAT(getDiagnosticString(),
8616 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
8617 }
8618
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefIS)8619 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefIS) {
8620 const std::string text = R"(
8621 OpCapability Shader
8622 OpCapability TextureBlockMatchQCOM
8623 OpCapability TextureBlockMatch2QCOM
8624 OpExtension "SPV_QCOM_image_processing"
8625 OpExtension "SPV_QCOM_image_processing2"
8626 %1 = OpExtInstImport "GLSL.std.450"
8627 OpMemoryModel Logical GLSL450
8628 OpEntryPoint Fragment %2 "main" %3 %4 %5
8629 OpExecutionMode %2 OriginUpperLeft
8630 OpDecorate %3 Location 0
8631 OpDecorate %4 DescriptorSet 0
8632 OpDecorate %4 Binding 4
8633 OpDecorate %4 BlockMatchTextureQCOM
8634 OpDecorate %4 BlockMatchSamplerQCOM
8635 OpDecorate %5 DescriptorSet 0
8636 OpDecorate %5 Binding 5
8637 OpDecorate %5 BlockMatchTextureQCOM
8638 %void = OpTypeVoid
8639 %7 = OpTypeFunction %void
8640 %uint = OpTypeInt 32 0
8641 %v2uint = OpTypeVector %uint 2
8642 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8643 %float = OpTypeFloat 32
8644 %v4float = OpTypeVector %float 4
8645 %_ptr_Input_v4float = OpTypePointer Input %v4float
8646 %_ptr_Input_float = OpTypePointer Input %float
8647 %_ptr_Function_uint = OpTypePointer Function %uint
8648 %_ptr_Output_v4float = OpTypePointer Output %v4float
8649 %3 = OpVariable %_ptr_Output_v4float Output
8650 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
8651 %19 = OpTypeSampledImage %18
8652 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8653 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8654 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8655 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
8656 %2 = OpFunction %void None %7
8657 %22 = OpLabel
8658 %23 = OpVariable %_ptr_Function_v2uint Function
8659 %24 = OpLoad %19 %4
8660 %25 = OpLoad %v2uint %23
8661 %26 = OpLoad %19 %5
8662 %27 = OpLoad %v2uint %23
8663 %28 = OpLoad %v2uint %23
8664 %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
8665 OpStore %3 %29
8666 OpReturn
8667 OpFunctionEnd
8668 )";
8669 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8670 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8671 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8672 EXPECT_THAT(getDiagnosticString(),
8673 HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
8674 }
8675
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetNIT)8676 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetNIT) {
8677 const std::string text = R"(
8678 OpCapability Shader
8679 OpCapability TextureBlockMatchQCOM
8680 OpCapability TextureBlockMatch2QCOM
8681 OpExtension "SPV_QCOM_image_processing"
8682 OpExtension "SPV_QCOM_image_processing2"
8683 %1 = OpExtInstImport "GLSL.std.450"
8684 OpMemoryModel Logical GLSL450
8685 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
8686 OpExecutionMode %2 OriginUpperLeft
8687 OpDecorate %3 Location 0
8688 OpDecorate %4 DescriptorSet 0
8689 OpDecorate %4 Binding 1
8690 OpDecorate %4 BlockMatchSamplerQCOM
8691 OpDecorate %5 DescriptorSet 0
8692 OpDecorate %5 Binding 3
8693 OpDecorate %6 DescriptorSet 0
8694 OpDecorate %6 Binding 2
8695 OpDecorate %6 BlockMatchTextureQCOM
8696 OpDecorate %6 BlockMatchSamplerQCOM
8697 %void = OpTypeVoid
8698 %8 = OpTypeFunction %void
8699 %uint = OpTypeInt 32 0
8700 %v2uint = OpTypeVector %uint 2
8701 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8702 %float = OpTypeFloat 32
8703 %v4float = OpTypeVector %float 4
8704 %_ptr_Input_float = OpTypePointer Input %float
8705 %_ptr_Function_uint = OpTypePointer Function %uint
8706 %uint_4 = OpConstant %uint 4
8707 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
8708 %_ptr_Output_v4float = OpTypePointer Output %v4float
8709 %3 = OpVariable %_ptr_Output_v4float Output
8710 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
8711 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8712 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8713 %21 = OpTypeSampler
8714 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
8715 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
8716 %23 = OpTypeSampledImage %19
8717 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8718 %2 = OpFunction %void None %8
8719 %24 = OpLabel
8720 %25 = OpVariable %_ptr_Function_v2uint Function
8721 %26 = OpLoad %19 %4
8722 %27 = OpLoad %21 %5
8723 %28 = OpSampledImage %23 %26 %27
8724 %29 = OpLoad %v2uint %25
8725 %30 = OpLoad %19 %6
8726 %31 = OpLoad %21 %5
8727 %32 = OpSampledImage %23 %30 %31
8728 %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
8729 OpStore %3 %33
8730 OpReturn
8731 OpFunctionEnd
8732 )";
8733 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8734 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8735 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8736 EXPECT_THAT(getDiagnosticString(),
8737 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
8738 }
8739
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetNIS)8740 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetNIS) {
8741 const std::string text = R"(
8742 OpCapability Shader
8743 OpCapability TextureBlockMatchQCOM
8744 OpCapability TextureBlockMatch2QCOM
8745 OpExtension "SPV_QCOM_image_processing"
8746 OpExtension "SPV_QCOM_image_processing2"
8747 %1 = OpExtInstImport "GLSL.std.450"
8748 OpMemoryModel Logical GLSL450
8749 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
8750 OpExecutionMode %2 OriginUpperLeft
8751 OpDecorate %3 Location 0
8752 OpDecorate %4 DescriptorSet 0
8753 OpDecorate %4 Binding 1
8754 OpDecorate %4 BlockMatchTextureQCOM
8755 OpDecorate %5 DescriptorSet 0
8756 OpDecorate %5 Binding 3
8757 OpDecorate %6 DescriptorSet 0
8758 OpDecorate %6 Binding 2
8759 OpDecorate %6 BlockMatchTextureQCOM
8760 OpDecorate %6 BlockMatchSamplerQCOM
8761 %void = OpTypeVoid
8762 %8 = OpTypeFunction %void
8763 %uint = OpTypeInt 32 0
8764 %v2uint = OpTypeVector %uint 2
8765 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8766 %float = OpTypeFloat 32
8767 %v4float = OpTypeVector %float 4
8768 %_ptr_Input_float = OpTypePointer Input %float
8769 %_ptr_Function_uint = OpTypePointer Function %uint
8770 %uint_4 = OpConstant %uint 4
8771 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
8772 %_ptr_Output_v4float = OpTypePointer Output %v4float
8773 %3 = OpVariable %_ptr_Output_v4float Output
8774 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
8775 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8776 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8777 %21 = OpTypeSampler
8778 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
8779 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
8780 %23 = OpTypeSampledImage %19
8781 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8782 %2 = OpFunction %void None %8
8783 %24 = OpLabel
8784 %25 = OpVariable %_ptr_Function_v2uint Function
8785 %26 = OpLoad %19 %4
8786 %27 = OpLoad %21 %5
8787 %28 = OpSampledImage %23 %26 %27
8788 %29 = OpLoad %v2uint %25
8789 %30 = OpLoad %19 %6
8790 %31 = OpLoad %21 %5
8791 %32 = OpSampledImage %23 %30 %31
8792 %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
8793 OpStore %3 %33
8794 OpReturn
8795 OpFunctionEnd
8796 )";
8797 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8798 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8799 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8800 EXPECT_THAT(getDiagnosticString(),
8801 HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
8802 }
8803
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefNIT)8804 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefNIT) {
8805 const std::string text = R"(
8806 OpCapability Shader
8807 OpCapability TextureBlockMatchQCOM
8808 OpCapability TextureBlockMatch2QCOM
8809 OpExtension "SPV_QCOM_image_processing"
8810 OpExtension "SPV_QCOM_image_processing2"
8811 %1 = OpExtInstImport "GLSL.std.450"
8812 OpMemoryModel Logical GLSL450
8813 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
8814 OpExecutionMode %2 OriginUpperLeft
8815 OpDecorate %3 Location 0
8816 OpDecorate %4 DescriptorSet 0
8817 OpDecorate %4 Binding 1
8818 OpDecorate %4 BlockMatchTextureQCOM
8819 OpDecorate %5 DescriptorSet 0
8820 OpDecorate %5 Binding 3
8821 OpDecorate %5 BlockMatchSamplerQCOM
8822 OpDecorate %6 DescriptorSet 0
8823 OpDecorate %6 Binding 2
8824 OpDecorate %6 BlockMatchSamplerQCOM
8825 %void = OpTypeVoid
8826 %8 = OpTypeFunction %void
8827 %uint = OpTypeInt 32 0
8828 %v2uint = OpTypeVector %uint 2
8829 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8830 %float = OpTypeFloat 32
8831 %v4float = OpTypeVector %float 4
8832 %_ptr_Input_float = OpTypePointer Input %float
8833 %_ptr_Function_uint = OpTypePointer Function %uint
8834 %uint_4 = OpConstant %uint 4
8835 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
8836 %_ptr_Output_v4float = OpTypePointer Output %v4float
8837 %3 = OpVariable %_ptr_Output_v4float Output
8838 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
8839 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8840 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8841 %21 = OpTypeSampler
8842 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
8843 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
8844 %23 = OpTypeSampledImage %19
8845 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8846 %2 = OpFunction %void None %8
8847 %24 = OpLabel
8848 %25 = OpVariable %_ptr_Function_v2uint Function
8849 %26 = OpLoad %19 %4
8850 %27 = OpLoad %21 %5
8851 %28 = OpSampledImage %23 %26 %27
8852 %29 = OpLoad %v2uint %25
8853 %30 = OpLoad %19 %6
8854 %31 = OpLoad %21 %5
8855 %32 = OpSampledImage %23 %30 %31
8856 %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
8857 OpStore %3 %33
8858 OpReturn
8859 OpFunctionEnd
8860 )";
8861 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8862 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8863 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8864 EXPECT_THAT(getDiagnosticString(),
8865 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
8866 }
8867
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefNIS)8868 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefNIS) {
8869 const std::string text = R"(
8870 OpCapability Shader
8871 OpCapability TextureBlockMatchQCOM
8872 OpCapability TextureBlockMatch2QCOM
8873 OpExtension "SPV_QCOM_image_processing"
8874 OpExtension "SPV_QCOM_image_processing2"
8875 %1 = OpExtInstImport "GLSL.std.450"
8876 OpMemoryModel Logical GLSL450
8877 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
8878 OpExecutionMode %2 OriginUpperLeft
8879 OpDecorate %3 Location 0
8880 OpDecorate %4 DescriptorSet 0
8881 OpDecorate %4 Binding 1
8882 OpDecorate %4 BlockMatchTextureQCOM
8883 OpDecorate %4 BlockMatchSamplerQCOM
8884 OpDecorate %5 DescriptorSet 0
8885 OpDecorate %5 Binding 3
8886 OpDecorate %6 DescriptorSet 0
8887 OpDecorate %6 Binding 2
8888 OpDecorate %6 BlockMatchTextureQCOM
8889 %void = OpTypeVoid
8890 %8 = OpTypeFunction %void
8891 %uint = OpTypeInt 32 0
8892 %v2uint = OpTypeVector %uint 2
8893 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8894 %float = OpTypeFloat 32
8895 %v4float = OpTypeVector %float 4
8896 %_ptr_Input_float = OpTypePointer Input %float
8897 %_ptr_Function_uint = OpTypePointer Function %uint
8898 %uint_4 = OpConstant %uint 4
8899 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
8900 %_ptr_Output_v4float = OpTypePointer Output %v4float
8901 %3 = OpVariable %_ptr_Output_v4float Output
8902 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
8903 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8904 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8905 %21 = OpTypeSampler
8906 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
8907 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
8908 %23 = OpTypeSampledImage %19
8909 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8910 %2 = OpFunction %void None %8
8911 %24 = OpLabel
8912 %25 = OpVariable %_ptr_Function_v2uint Function
8913 %26 = OpLoad %19 %4
8914 %27 = OpLoad %21 %5
8915 %28 = OpSampledImage %23 %26 %27
8916 %29 = OpLoad %v2uint %25
8917 %30 = OpLoad %19 %6
8918 %31 = OpLoad %21 %5
8919 %32 = OpSampledImage %23 %30 %31
8920 %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
8921 OpStore %3 %33
8922 OpReturn
8923 OpFunctionEnd
8924 )";
8925 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8926 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8927 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8928 EXPECT_THAT(getDiagnosticString(),
8929 HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
8930 }
8931
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSADNoDecorTargetIT)8932 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorTargetIT) {
8933 const std::string text = R"(
8934 OpCapability Shader
8935 OpCapability TextureBlockMatchQCOM
8936 OpCapability TextureBlockMatch2QCOM
8937 OpExtension "SPV_QCOM_image_processing"
8938 OpExtension "SPV_QCOM_image_processing2"
8939 %1 = OpExtInstImport "GLSL.std.450"
8940 OpMemoryModel Logical GLSL450
8941 OpEntryPoint Fragment %2 "main" %3 %4 %5
8942 OpExecutionMode %2 OriginUpperLeft
8943 OpDecorate %3 Location 0
8944 OpDecorate %4 DescriptorSet 0
8945 OpDecorate %4 Binding 4
8946 OpDecorate %5 DescriptorSet 0
8947 OpDecorate %5 Binding 5
8948 OpDecorate %5 BlockMatchTextureQCOM
8949 %void = OpTypeVoid
8950 %7 = OpTypeFunction %void
8951 %uint = OpTypeInt 32 0
8952 %v2uint = OpTypeVector %uint 2
8953 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
8954 %float = OpTypeFloat 32
8955 %v4float = OpTypeVector %float 4
8956 %_ptr_Input_v4float = OpTypePointer Input %v4float
8957 %_ptr_Input_float = OpTypePointer Input %float
8958 %_ptr_Function_uint = OpTypePointer Function %uint
8959 %_ptr_Output_v4float = OpTypePointer Output %v4float
8960 %3 = OpVariable %_ptr_Output_v4float Output
8961 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
8962 %19 = OpTypeSampledImage %18
8963 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
8964 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8965 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
8966 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
8967 %2 = OpFunction %void None %7
8968 %22 = OpLabel
8969 %23 = OpVariable %_ptr_Function_v2uint Function
8970 %24 = OpLoad %19 %4
8971 %25 = OpLoad %v2uint %23
8972 %26 = OpLoad %19 %5
8973 %27 = OpLoad %v2uint %23
8974 %28 = OpLoad %v2uint %23
8975 %29 = OpImageBlockMatchGatherSADQCOM %v4float %24 %25 %26 %27 %28
8976 OpStore %3 %29
8977 OpReturn
8978 OpFunctionEnd
8979 )";
8980 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
8981 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
8982 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
8983 EXPECT_THAT(getDiagnosticString(),
8984 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
8985 }
8986
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSADNoDecorRefIT)8987 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorRefIT) {
8988 const std::string text = R"(
8989 OpCapability Shader
8990 OpCapability TextureBlockMatchQCOM
8991 OpCapability TextureBlockMatch2QCOM
8992 OpExtension "SPV_QCOM_image_processing"
8993 OpExtension "SPV_QCOM_image_processing2"
8994 %1 = OpExtInstImport "GLSL.std.450"
8995 OpMemoryModel Logical GLSL450
8996 OpEntryPoint Fragment %2 "main" %3 %4 %5
8997 OpExecutionMode %2 OriginUpperLeft
8998 OpDecorate %3 Location 0
8999 OpDecorate %4 DescriptorSet 0
9000 OpDecorate %4 Binding 4
9001 OpDecorate %4 BlockMatchTextureQCOM
9002 OpDecorate %5 DescriptorSet 0
9003 OpDecorate %5 Binding 5
9004 %void = OpTypeVoid
9005 %7 = OpTypeFunction %void
9006 %uint = OpTypeInt 32 0
9007 %v2uint = OpTypeVector %uint 2
9008 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9009 %float = OpTypeFloat 32
9010 %v4float = OpTypeVector %float 4
9011 %_ptr_Input_v4float = OpTypePointer Input %v4float
9012 %_ptr_Input_float = OpTypePointer Input %float
9013 %_ptr_Function_uint = OpTypePointer Function %uint
9014 %_ptr_Output_v4float = OpTypePointer Output %v4float
9015 %3 = OpVariable %_ptr_Output_v4float Output
9016 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
9017 %19 = OpTypeSampledImage %18
9018 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
9019 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9020 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9021 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
9022 %2 = OpFunction %void None %7
9023 %22 = OpLabel
9024 %23 = OpVariable %_ptr_Function_v2uint Function
9025 %24 = OpLoad %19 %4
9026 %25 = OpLoad %v2uint %23
9027 %26 = OpLoad %19 %5
9028 %27 = OpLoad %v2uint %23
9029 %28 = OpLoad %v2uint %23
9030 %29 = OpImageBlockMatchGatherSADQCOM %v4float %24 %25 %26 %27 %28
9031 OpStore %3 %29
9032 OpReturn
9033 OpFunctionEnd
9034 )";
9035 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9036 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9037 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9038 EXPECT_THAT(getDiagnosticString(),
9039 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
9040 }
9041
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSADNoDecorTargetNIT)9042 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorTargetNIT) {
9043 const std::string text = R"(
9044 OpCapability Shader
9045 OpCapability TextureBlockMatchQCOM
9046 OpCapability TextureBlockMatch2QCOM
9047 OpExtension "SPV_QCOM_image_processing"
9048 OpExtension "SPV_QCOM_image_processing2"
9049 %1 = OpExtInstImport "GLSL.std.450"
9050 OpMemoryModel Logical GLSL450
9051 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
9052 OpExecutionMode %2 OriginUpperLeft
9053 OpDecorate %3 Location 0
9054 OpDecorate %4 DescriptorSet 0
9055 OpDecorate %4 Binding 1
9056 OpDecorate %5 DescriptorSet 0
9057 OpDecorate %5 Binding 3
9058 OpDecorate %6 DescriptorSet 0
9059 OpDecorate %6 Binding 2
9060 OpDecorate %6 BlockMatchTextureQCOM
9061 %void = OpTypeVoid
9062 %8 = OpTypeFunction %void
9063 %uint = OpTypeInt 32 0
9064 %v2uint = OpTypeVector %uint 2
9065 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9066 %float = OpTypeFloat 32
9067 %v4float = OpTypeVector %float 4
9068 %_ptr_Input_float = OpTypePointer Input %float
9069 %_ptr_Function_uint = OpTypePointer Function %uint
9070 %uint_4 = OpConstant %uint 4
9071 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
9072 %_ptr_Output_v4float = OpTypePointer Output %v4float
9073 %3 = OpVariable %_ptr_Output_v4float Output
9074 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
9075 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
9076 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9077 %21 = OpTypeSampler
9078 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
9079 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
9080 %23 = OpTypeSampledImage %19
9081 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9082 %2 = OpFunction %void None %8
9083 %24 = OpLabel
9084 %25 = OpVariable %_ptr_Function_v2uint Function
9085 %26 = OpLoad %19 %4
9086 %27 = OpLoad %21 %5
9087 %28 = OpSampledImage %23 %26 %27
9088 %29 = OpLoad %v2uint %25
9089 %30 = OpLoad %19 %6
9090 %31 = OpLoad %21 %5
9091 %32 = OpSampledImage %23 %30 %31
9092 %33 = OpImageBlockMatchGatherSADQCOM %v4float %28 %29 %32 %29 %29
9093 OpStore %3 %33
9094 OpReturn
9095 OpFunctionEnd
9096 )";
9097 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9098 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9099 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9100 EXPECT_THAT(getDiagnosticString(),
9101 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
9102 }
9103
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSADNoDecorRefNIT)9104 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorRefNIT) {
9105 const std::string text = R"(
9106 OpCapability Shader
9107 OpCapability TextureBlockMatchQCOM
9108 OpCapability TextureBlockMatch2QCOM
9109 OpExtension "SPV_QCOM_image_processing"
9110 OpExtension "SPV_QCOM_image_processing2"
9111 %1 = OpExtInstImport "GLSL.std.450"
9112 OpMemoryModel Logical GLSL450
9113 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
9114 OpExecutionMode %2 OriginUpperLeft
9115 OpDecorate %3 Location 0
9116 OpDecorate %4 DescriptorSet 0
9117 OpDecorate %4 Binding 1
9118 OpDecorate %4 BlockMatchTextureQCOM
9119 OpDecorate %5 DescriptorSet 0
9120 OpDecorate %5 Binding 3
9121 OpDecorate %6 DescriptorSet 0
9122 OpDecorate %6 Binding 2
9123 %void = OpTypeVoid
9124 %8 = OpTypeFunction %void
9125 %uint = OpTypeInt 32 0
9126 %v2uint = OpTypeVector %uint 2
9127 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9128 %float = OpTypeFloat 32
9129 %v4float = OpTypeVector %float 4
9130 %_ptr_Input_float = OpTypePointer Input %float
9131 %_ptr_Function_uint = OpTypePointer Function %uint
9132 %uint_4 = OpConstant %uint 4
9133 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
9134 %_ptr_Output_v4float = OpTypePointer Output %v4float
9135 %3 = OpVariable %_ptr_Output_v4float Output
9136 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
9137 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
9138 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9139 %21 = OpTypeSampler
9140 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
9141 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
9142 %23 = OpTypeSampledImage %19
9143 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9144 %2 = OpFunction %void None %8
9145 %24 = OpLabel
9146 %25 = OpVariable %_ptr_Function_v2uint Function
9147 %26 = OpLoad %19 %4
9148 %27 = OpLoad %21 %5
9149 %28 = OpSampledImage %23 %26 %27
9150 %29 = OpLoad %v2uint %25
9151 %30 = OpLoad %19 %6
9152 %31 = OpLoad %21 %5
9153 %32 = OpSampledImage %23 %30 %31
9154 %33 = OpImageBlockMatchGatherSADQCOM %v4float %28 %29 %32 %29 %29
9155 OpStore %3 %33
9156 OpReturn
9157 OpFunctionEnd
9158 )";
9159 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9160 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9161 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9162 EXPECT_THAT(getDiagnosticString(),
9163 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
9164 }
9165
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSSDNoDecorTargetIT)9166 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorTargetIT) {
9167 const std::string text = R"(
9168 OpCapability Shader
9169 OpCapability TextureBlockMatchQCOM
9170 OpCapability TextureBlockMatch2QCOM
9171 OpExtension "SPV_QCOM_image_processing"
9172 OpExtension "SPV_QCOM_image_processing2"
9173 %1 = OpExtInstImport "GLSL.std.450"
9174 OpMemoryModel Logical GLSL450
9175 OpEntryPoint Fragment %2 "main" %3 %4 %5
9176 OpExecutionMode %2 OriginUpperLeft
9177 OpDecorate %3 Location 0
9178 OpDecorate %4 DescriptorSet 0
9179 OpDecorate %4 Binding 4
9180 OpDecorate %5 DescriptorSet 0
9181 OpDecorate %5 Binding 5
9182 OpDecorate %5 BlockMatchTextureQCOM
9183 %void = OpTypeVoid
9184 %7 = OpTypeFunction %void
9185 %uint = OpTypeInt 32 0
9186 %v2uint = OpTypeVector %uint 2
9187 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9188 %float = OpTypeFloat 32
9189 %v4float = OpTypeVector %float 4
9190 %_ptr_Input_v4float = OpTypePointer Input %v4float
9191 %_ptr_Input_float = OpTypePointer Input %float
9192 %_ptr_Function_uint = OpTypePointer Function %uint
9193 %_ptr_Output_v4float = OpTypePointer Output %v4float
9194 %3 = OpVariable %_ptr_Output_v4float Output
9195 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
9196 %19 = OpTypeSampledImage %18
9197 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
9198 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9199 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9200 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
9201 %2 = OpFunction %void None %7
9202 %22 = OpLabel
9203 %23 = OpVariable %_ptr_Function_v2uint Function
9204 %24 = OpLoad %19 %4
9205 %25 = OpLoad %v2uint %23
9206 %26 = OpLoad %19 %5
9207 %27 = OpLoad %v2uint %23
9208 %28 = OpLoad %v2uint %23
9209 %29 = OpImageBlockMatchGatherSSDQCOM %v4float %24 %25 %26 %27 %28
9210 OpStore %3 %29
9211 OpReturn
9212 OpFunctionEnd
9213 )";
9214 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9215 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9216 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9217 EXPECT_THAT(getDiagnosticString(),
9218 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
9219 }
9220
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSSDNoDecorRefIT)9221 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorRefIT) {
9222 const std::string text = R"(
9223 OpCapability Shader
9224 OpCapability TextureBlockMatchQCOM
9225 OpCapability TextureBlockMatch2QCOM
9226 OpExtension "SPV_QCOM_image_processing"
9227 OpExtension "SPV_QCOM_image_processing2"
9228 %1 = OpExtInstImport "GLSL.std.450"
9229 OpMemoryModel Logical GLSL450
9230 OpEntryPoint Fragment %2 "main" %3 %4 %5
9231 OpExecutionMode %2 OriginUpperLeft
9232 OpDecorate %3 Location 0
9233 OpDecorate %4 DescriptorSet 0
9234 OpDecorate %4 Binding 4
9235 OpDecorate %4 BlockMatchTextureQCOM
9236 OpDecorate %5 DescriptorSet 0
9237 OpDecorate %5 Binding 5
9238 %void = OpTypeVoid
9239 %7 = OpTypeFunction %void
9240 %uint = OpTypeInt 32 0
9241 %v2uint = OpTypeVector %uint 2
9242 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9243 %float = OpTypeFloat 32
9244 %v4float = OpTypeVector %float 4
9245 %_ptr_Input_v4float = OpTypePointer Input %v4float
9246 %_ptr_Input_float = OpTypePointer Input %float
9247 %_ptr_Function_uint = OpTypePointer Function %uint
9248 %_ptr_Output_v4float = OpTypePointer Output %v4float
9249 %3 = OpVariable %_ptr_Output_v4float Output
9250 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
9251 %19 = OpTypeSampledImage %18
9252 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
9253 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9254 %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9255 %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
9256 %2 = OpFunction %void None %7
9257 %22 = OpLabel
9258 %23 = OpVariable %_ptr_Function_v2uint Function
9259 %24 = OpLoad %19 %4
9260 %25 = OpLoad %v2uint %23
9261 %26 = OpLoad %19 %5
9262 %27 = OpLoad %v2uint %23
9263 %28 = OpLoad %v2uint %23
9264 %29 = OpImageBlockMatchGatherSSDQCOM %v4float %24 %25 %26 %27 %28
9265 OpStore %3 %29
9266 OpReturn
9267 OpFunctionEnd
9268 )";
9269 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9270 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9271 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9272 EXPECT_THAT(getDiagnosticString(),
9273 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
9274 }
9275
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSSDNoDecorTargetNIT)9276 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorTargetNIT) {
9277 const std::string text = R"(
9278 OpCapability Shader
9279 OpCapability TextureBlockMatchQCOM
9280 OpCapability TextureBlockMatch2QCOM
9281 OpExtension "SPV_QCOM_image_processing"
9282 OpExtension "SPV_QCOM_image_processing2"
9283 %1 = OpExtInstImport "GLSL.std.450"
9284 OpMemoryModel Logical GLSL450
9285 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
9286 OpExecutionMode %2 OriginUpperLeft
9287 OpDecorate %3 Location 0
9288 OpDecorate %4 DescriptorSet 0
9289 OpDecorate %4 Binding 1
9290 OpDecorate %5 DescriptorSet 0
9291 OpDecorate %5 Binding 3
9292 OpDecorate %6 DescriptorSet 0
9293 OpDecorate %6 Binding 2
9294 OpDecorate %6 BlockMatchTextureQCOM
9295 %void = OpTypeVoid
9296 %8 = OpTypeFunction %void
9297 %uint = OpTypeInt 32 0
9298 %v2uint = OpTypeVector %uint 2
9299 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9300 %float = OpTypeFloat 32
9301 %v4float = OpTypeVector %float 4
9302 %_ptr_Input_float = OpTypePointer Input %float
9303 %_ptr_Function_uint = OpTypePointer Function %uint
9304 %uint_4 = OpConstant %uint 4
9305 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
9306 %_ptr_Output_v4float = OpTypePointer Output %v4float
9307 %3 = OpVariable %_ptr_Output_v4float Output
9308 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
9309 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
9310 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9311 %21 = OpTypeSampler
9312 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
9313 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
9314 %23 = OpTypeSampledImage %19
9315 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9316 %2 = OpFunction %void None %8
9317 %24 = OpLabel
9318 %25 = OpVariable %_ptr_Function_v2uint Function
9319 %26 = OpLoad %19 %4
9320 %27 = OpLoad %21 %5
9321 %28 = OpSampledImage %23 %26 %27
9322 %29 = OpLoad %v2uint %25
9323 %30 = OpLoad %19 %6
9324 %31 = OpLoad %21 %5
9325 %32 = OpSampledImage %23 %30 %31
9326 %33 = OpImageBlockMatchGatherSSDQCOM %v4float %28 %29 %32 %29 %29
9327 OpStore %3 %33
9328 OpReturn
9329 OpFunctionEnd
9330 )";
9331 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9332 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9333 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9334 EXPECT_THAT(getDiagnosticString(),
9335 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
9336 }
9337
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSSDNoDecorRefNIT)9338 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorRefNIT) {
9339 const std::string text = R"(
9340 OpCapability Shader
9341 OpCapability TextureBlockMatchQCOM
9342 OpCapability TextureBlockMatch2QCOM
9343 OpExtension "SPV_QCOM_image_processing"
9344 OpExtension "SPV_QCOM_image_processing2"
9345 %1 = OpExtInstImport "GLSL.std.450"
9346 OpMemoryModel Logical GLSL450
9347 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
9348 OpExecutionMode %2 OriginUpperLeft
9349 OpDecorate %3 Location 0
9350 OpDecorate %4 DescriptorSet 0
9351 OpDecorate %4 Binding 1
9352 OpDecorate %4 BlockMatchTextureQCOM
9353 OpDecorate %5 DescriptorSet 0
9354 OpDecorate %5 Binding 3
9355 OpDecorate %6 DescriptorSet 0
9356 OpDecorate %6 Binding 2
9357 %void = OpTypeVoid
9358 %8 = OpTypeFunction %void
9359 %uint = OpTypeInt 32 0
9360 %v2uint = OpTypeVector %uint 2
9361 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9362 %float = OpTypeFloat 32
9363 %v4float = OpTypeVector %float 4
9364 %_ptr_Input_float = OpTypePointer Input %float
9365 %_ptr_Function_uint = OpTypePointer Function %uint
9366 %uint_4 = OpConstant %uint 4
9367 %17 = OpConstantComposite %v2uint %uint_4 %uint_4
9368 %_ptr_Output_v4float = OpTypePointer Output %v4float
9369 %3 = OpVariable %_ptr_Output_v4float Output
9370 %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
9371 %_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
9372 %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9373 %21 = OpTypeSampler
9374 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
9375 %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
9376 %23 = OpTypeSampledImage %19
9377 %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
9378 %2 = OpFunction %void None %8
9379 %24 = OpLabel
9380 %25 = OpVariable %_ptr_Function_v2uint Function
9381 %26 = OpLoad %19 %4
9382 %27 = OpLoad %21 %5
9383 %28 = OpSampledImage %23 %26 %27
9384 %29 = OpLoad %v2uint %25
9385 %30 = OpLoad %19 %6
9386 %31 = OpLoad %21 %5
9387 %32 = OpSampledImage %23 %30 %31
9388 %33 = OpImageBlockMatchGatherSSDQCOM %v4float %28 %29 %32 %29 %29
9389 OpStore %3 %33
9390 OpReturn
9391 OpFunctionEnd
9392 )";
9393 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9394 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9395 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9396 EXPECT_THAT(getDiagnosticString(),
9397 HasSubstr("Missing decoration BlockMatchTextureQCOM"));
9398 }
9399
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADInvalidUseTargetI)9400 TEST_F(ValidateImage,
9401 QCOMImageProcessing2BlockMatchWindowSADInvalidUseTargetI) {
9402 const std::string text = R"(
9403 OpCapability Shader
9404 OpCapability TextureBlockMatchQCOM
9405 OpCapability TextureBlockMatch2QCOM
9406 OpExtension "SPV_QCOM_image_processing"
9407 OpExtension "SPV_QCOM_image_processing2"
9408 %1 = OpExtInstImport "GLSL.std.450"
9409 OpMemoryModel Logical GLSL450
9410 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
9411 OpExecutionMode %2 OriginUpperLeft
9412 OpDecorate %3 Location 0
9413 OpDecorate %4 Location 0
9414 OpDecorate %5 DescriptorSet 0
9415 OpDecorate %5 Binding 4
9416 OpDecorate %6 DescriptorSet 0
9417 OpDecorate %6 Binding 5
9418 OpDecorate %5 BlockMatchTextureQCOM
9419 OpDecorate %5 BlockMatchSamplerQCOM
9420 OpDecorate %6 BlockMatchTextureQCOM
9421 OpDecorate %6 BlockMatchSamplerQCOM
9422 %void = OpTypeVoid
9423 %8 = OpTypeFunction %void
9424 %uint = OpTypeInt 32 0
9425 %v2uint = OpTypeVector %uint 2
9426 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9427 %float = OpTypeFloat 32
9428 %v4float = OpTypeVector %float 4
9429 %_ptr_Input_v4float = OpTypePointer Input %v4float
9430 %3 = OpVariable %_ptr_Input_v4float Input
9431 %uint_4 = OpConstant %uint 4
9432 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
9433 %_ptr_Output_v4float = OpTypePointer Output %v4float
9434 %4 = OpVariable %_ptr_Output_v4float Output
9435 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
9436 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
9437 %20 = OpTypeSampledImage %18
9438 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
9439 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
9440 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
9441 %v2float = OpTypeVector %float 2
9442 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
9443 %2 = OpFunction %void None %8
9444 %24 = OpLabel
9445 %25 = OpVariable %_ptr_Function_v2uint Function
9446 OpStore %25 %16
9447 %26 = OpLoad %20 %5
9448 %27 = OpLoad %v2uint %25
9449 %28 = OpLoad %20 %6
9450 %29 = OpLoad %v2uint %25
9451 %30 = OpLoad %v2uint %25
9452 %31 = OpImageBlockMatchWindowSADQCOM %v4float %26 %27 %28 %29 %30
9453 OpStore %4 %31
9454 %32 = OpLoad %20 %5
9455 %33 = OpLoad %v4float %3
9456 %34 = OpVectorShuffle %v2float %33 %33 0 2
9457 %35 = OpImageSampleImplicitLod %v4float %32 %34
9458 OpStore %4 %35
9459 OpReturn
9460 OpFunctionEnd
9461 )";
9462 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9463 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9464 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9465 EXPECT_THAT(
9466 getDiagnosticString(),
9467 HasSubstr("Illegal use of QCOM image processing decorated texture"));
9468 }
9469
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADInvalidUseRefI)9470 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADInvalidUseRefI) {
9471 const std::string text = R"(
9472 OpCapability Shader
9473 OpCapability TextureBlockMatchQCOM
9474 OpCapability TextureBlockMatch2QCOM
9475 OpExtension "SPV_QCOM_image_processing"
9476 OpExtension "SPV_QCOM_image_processing2"
9477 %1 = OpExtInstImport "GLSL.std.450"
9478 OpMemoryModel Logical GLSL450
9479 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
9480 OpExecutionMode %2 OriginUpperLeft
9481 OpDecorate %3 Location 0
9482 OpDecorate %4 Location 0
9483 OpDecorate %5 DescriptorSet 0
9484 OpDecorate %5 Binding 4
9485 OpDecorate %6 DescriptorSet 0
9486 OpDecorate %6 Binding 5
9487 OpDecorate %5 BlockMatchTextureQCOM
9488 OpDecorate %5 BlockMatchSamplerQCOM
9489 OpDecorate %6 BlockMatchTextureQCOM
9490 OpDecorate %6 BlockMatchSamplerQCOM
9491 %void = OpTypeVoid
9492 %8 = OpTypeFunction %void
9493 %uint = OpTypeInt 32 0
9494 %v2uint = OpTypeVector %uint 2
9495 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9496 %float = OpTypeFloat 32
9497 %v4float = OpTypeVector %float 4
9498 %_ptr_Input_v4float = OpTypePointer Input %v4float
9499 %3 = OpVariable %_ptr_Input_v4float Input
9500 %uint_4 = OpConstant %uint 4
9501 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
9502 %_ptr_Output_v4float = OpTypePointer Output %v4float
9503 %4 = OpVariable %_ptr_Output_v4float Output
9504 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
9505 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
9506 %20 = OpTypeSampledImage %18
9507 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
9508 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
9509 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
9510 %v2float = OpTypeVector %float 2
9511 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
9512 %2 = OpFunction %void None %8
9513 %24 = OpLabel
9514 %25 = OpVariable %_ptr_Function_v2uint Function
9515 OpStore %25 %16
9516 %26 = OpLoad %20 %5
9517 %27 = OpLoad %v2uint %25
9518 %28 = OpLoad %20 %6
9519 %29 = OpLoad %v2uint %25
9520 %30 = OpLoad %v2uint %25
9521 %31 = OpImageBlockMatchWindowSADQCOM %v4float %26 %27 %28 %29 %30
9522 OpStore %4 %31
9523 %32 = OpLoad %20 %6
9524 %33 = OpLoad %v4float %3
9525 %34 = OpVectorShuffle %v2float %33 %33 0 2
9526 %35 = OpImageSampleImplicitLod %v4float %32 %34
9527 OpStore %4 %35
9528 OpReturn
9529 OpFunctionEnd
9530 )";
9531 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9532 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9533 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9534 EXPECT_THAT(
9535 getDiagnosticString(),
9536 HasSubstr("Illegal use of QCOM image processing decorated texture"));
9537 }
9538
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADInvalidUseTargetNI)9539 TEST_F(ValidateImage,
9540 QCOMImageProcessing2BlockMatchWindowSADInvalidUseTargetNI) {
9541 const std::string text = R"(
9542 OpCapability Shader
9543 OpCapability TextureBlockMatchQCOM
9544 OpCapability TextureBlockMatch2QCOM
9545 OpExtension "SPV_QCOM_image_processing"
9546 OpExtension "SPV_QCOM_image_processing2"
9547 %1 = OpExtInstImport "GLSL.std.450"
9548 OpMemoryModel Logical GLSL450
9549 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
9550 OpExecutionMode %main OriginUpperLeft
9551 OpDecorate %100 Location 0
9552 OpDecorate %101 Location 0
9553 OpDecorate %102 DescriptorSet 0
9554 OpDecorate %102 Binding 1
9555 OpDecorate %103 DescriptorSet 0
9556 OpDecorate %103 Binding 3
9557 OpDecorate %104 DescriptorSet 0
9558 OpDecorate %104 Binding 2
9559 OpDecorate %102 BlockMatchTextureQCOM
9560 OpDecorate %103 BlockMatchSamplerQCOM
9561 OpDecorate %104 BlockMatchTextureQCOM
9562 %void = OpTypeVoid
9563 %3 = OpTypeFunction %void
9564 %uint = OpTypeInt 32 0
9565 %v2uint = OpTypeVector %uint 2
9566 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9567 %float = OpTypeFloat 32
9568 %v4float = OpTypeVector %float 4
9569 %_ptr_Input_v4float = OpTypePointer Input %v4float
9570 %100 = OpVariable %_ptr_Input_v4float Input
9571 %_ptr_Output_v4float = OpTypePointer Output %v4float
9572 %101 = OpVariable %_ptr_Output_v4float Output
9573 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
9574 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
9575 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
9576 %46 = OpTypeSampler
9577 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
9578 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
9579 %50 = OpTypeSampledImage %42
9580 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
9581 %v2float = OpTypeVector %float 2
9582 %main = OpFunction %void None %3
9583 %5 = OpLabel
9584 %15 = OpVariable %_ptr_Function_v2uint Function
9585 %45 = OpLoad %42 %102
9586 %49 = OpLoad %46 %103
9587 %51 = OpSampledImage %50 %45 %49
9588 %52 = OpLoad %v2uint %15
9589 %54 = OpLoad %42 %104
9590 %55 = OpLoad %46 %103
9591 %56 = OpSampledImage %50 %54 %55
9592 %57 = OpLoad %v2uint %15
9593 %58 = OpLoad %v2uint %15
9594 %59 = OpImageBlockMatchWindowSADQCOM %v4float %51 %52 %56 %57 %58
9595 OpStore %101 %59
9596 %69 = OpLoad %42 %102
9597 %70 = OpLoad %46 %103
9598 %71 = OpSampledImage %50 %69 %70
9599 %73 = OpLoad %v4float %100
9600 %74 = OpVectorShuffle %v2float %73 %73 0 0
9601 %75 = OpImageSampleImplicitLod %v4float %71 %74
9602 OpStore %101 %75
9603 OpReturn
9604 OpFunctionEnd
9605 )";
9606 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9607 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9608 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9609 EXPECT_THAT(
9610 getDiagnosticString(),
9611 HasSubstr("Illegal use of QCOM image processing decorated texture"));
9612 }
9613
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSADInvalidUseRefNI)9614 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADInvalidUseRefNI) {
9615 const std::string text = R"(
9616 OpCapability Shader
9617 OpCapability TextureBlockMatchQCOM
9618 OpCapability TextureBlockMatch2QCOM
9619 OpExtension "SPV_QCOM_image_processing"
9620 OpExtension "SPV_QCOM_image_processing2"
9621 %1 = OpExtInstImport "GLSL.std.450"
9622 OpMemoryModel Logical GLSL450
9623 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
9624 OpExecutionMode %main OriginUpperLeft
9625 OpDecorate %100 Location 0
9626 OpDecorate %101 Location 0
9627 OpDecorate %102 DescriptorSet 0
9628 OpDecorate %102 Binding 1
9629 OpDecorate %103 DescriptorSet 0
9630 OpDecorate %103 Binding 3
9631 OpDecorate %104 DescriptorSet 0
9632 OpDecorate %104 Binding 2
9633 OpDecorate %102 BlockMatchTextureQCOM
9634 OpDecorate %103 BlockMatchSamplerQCOM
9635 OpDecorate %104 BlockMatchTextureQCOM
9636 %void = OpTypeVoid
9637 %3 = OpTypeFunction %void
9638 %uint = OpTypeInt 32 0
9639 %v2uint = OpTypeVector %uint 2
9640 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9641 %float = OpTypeFloat 32
9642 %v4float = OpTypeVector %float 4
9643 %_ptr_Input_v4float = OpTypePointer Input %v4float
9644 %100 = OpVariable %_ptr_Input_v4float Input
9645 %_ptr_Output_v4float = OpTypePointer Output %v4float
9646 %101 = OpVariable %_ptr_Output_v4float Output
9647 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
9648 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
9649 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
9650 %46 = OpTypeSampler
9651 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
9652 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
9653 %50 = OpTypeSampledImage %42
9654 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
9655 %v2float = OpTypeVector %float 2
9656 %main = OpFunction %void None %3
9657 %5 = OpLabel
9658 %15 = OpVariable %_ptr_Function_v2uint Function
9659 %45 = OpLoad %42 %102
9660 %49 = OpLoad %46 %103
9661 %51 = OpSampledImage %50 %45 %49
9662 %52 = OpLoad %v2uint %15
9663 %54 = OpLoad %42 %104
9664 %55 = OpLoad %46 %103
9665 %56 = OpSampledImage %50 %54 %55
9666 %57 = OpLoad %v2uint %15
9667 %58 = OpLoad %v2uint %15
9668 %59 = OpImageBlockMatchWindowSADQCOM %v4float %51 %52 %56 %57 %58
9669 OpStore %101 %59
9670 %69 = OpLoad %42 %104
9671 %70 = OpLoad %46 %103
9672 %71 = OpSampledImage %50 %69 %70
9673 %73 = OpLoad %v4float %100
9674 %74 = OpVectorShuffle %v2float %73 %73 0 0
9675 %75 = OpImageSampleImplicitLod %v4float %71 %74
9676 OpStore %101 %75
9677 OpReturn
9678 OpFunctionEnd
9679 )";
9680 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9681 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9682 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9683 EXPECT_THAT(
9684 getDiagnosticString(),
9685 HasSubstr("Illegal use of QCOM image processing decorated texture"));
9686 }
9687
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDInvalidUseTargetI)9688 TEST_F(ValidateImage,
9689 QCOMImageProcessing2BlockMatchWindowSSDInvalidUseTargetI) {
9690 const std::string text = R"(
9691 OpCapability Shader
9692 OpCapability TextureBlockMatchQCOM
9693 OpCapability TextureBlockMatch2QCOM
9694 OpExtension "SPV_QCOM_image_processing"
9695 OpExtension "SPV_QCOM_image_processing2"
9696 %1 = OpExtInstImport "GLSL.std.450"
9697 OpMemoryModel Logical GLSL450
9698 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
9699 OpExecutionMode %2 OriginUpperLeft
9700 OpDecorate %3 Location 0
9701 OpDecorate %4 Location 0
9702 OpDecorate %5 DescriptorSet 0
9703 OpDecorate %5 Binding 4
9704 OpDecorate %6 DescriptorSet 0
9705 OpDecorate %6 Binding 5
9706 OpDecorate %5 BlockMatchTextureQCOM
9707 OpDecorate %5 BlockMatchSamplerQCOM
9708 OpDecorate %6 BlockMatchTextureQCOM
9709 OpDecorate %6 BlockMatchSamplerQCOM
9710 %void = OpTypeVoid
9711 %8 = OpTypeFunction %void
9712 %uint = OpTypeInt 32 0
9713 %v2uint = OpTypeVector %uint 2
9714 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9715 %float = OpTypeFloat 32
9716 %v4float = OpTypeVector %float 4
9717 %_ptr_Input_v4float = OpTypePointer Input %v4float
9718 %3 = OpVariable %_ptr_Input_v4float Input
9719 %uint_4 = OpConstant %uint 4
9720 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
9721 %_ptr_Output_v4float = OpTypePointer Output %v4float
9722 %4 = OpVariable %_ptr_Output_v4float Output
9723 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
9724 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
9725 %20 = OpTypeSampledImage %18
9726 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
9727 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
9728 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
9729 %v2float = OpTypeVector %float 2
9730 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
9731 %2 = OpFunction %void None %8
9732 %24 = OpLabel
9733 %25 = OpVariable %_ptr_Function_v2uint Function
9734 OpStore %25 %16
9735 %26 = OpLoad %20 %5
9736 %27 = OpLoad %v2uint %25
9737 %28 = OpLoad %20 %6
9738 %29 = OpLoad %v2uint %25
9739 %30 = OpLoad %v2uint %25
9740 %31 = OpImageBlockMatchWindowSSDQCOM %v4float %26 %27 %28 %29 %30
9741 OpStore %4 %31
9742 %32 = OpLoad %20 %5
9743 %33 = OpLoad %v4float %3
9744 %34 = OpVectorShuffle %v2float %33 %33 0 2
9745 %35 = OpImageSampleImplicitLod %v4float %32 %34
9746 OpStore %4 %35
9747 OpReturn
9748 OpFunctionEnd
9749 )";
9750 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9751 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9752 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9753 EXPECT_THAT(
9754 getDiagnosticString(),
9755 HasSubstr("Illegal use of QCOM image processing decorated texture"));
9756 }
9757
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDInvalidUseRefI)9758 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDInvalidUseRefI) {
9759 const std::string text = R"(
9760 OpCapability Shader
9761 OpCapability TextureBlockMatchQCOM
9762 OpCapability TextureBlockMatch2QCOM
9763 OpExtension "SPV_QCOM_image_processing"
9764 OpExtension "SPV_QCOM_image_processing2"
9765 %1 = OpExtInstImport "GLSL.std.450"
9766 OpMemoryModel Logical GLSL450
9767 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
9768 OpExecutionMode %2 OriginUpperLeft
9769 OpDecorate %3 Location 0
9770 OpDecorate %4 Location 0
9771 OpDecorate %5 DescriptorSet 0
9772 OpDecorate %5 Binding 4
9773 OpDecorate %6 DescriptorSet 0
9774 OpDecorate %6 Binding 5
9775 OpDecorate %5 BlockMatchTextureQCOM
9776 OpDecorate %5 BlockMatchSamplerQCOM
9777 OpDecorate %6 BlockMatchTextureQCOM
9778 OpDecorate %6 BlockMatchSamplerQCOM
9779 %void = OpTypeVoid
9780 %8 = OpTypeFunction %void
9781 %uint = OpTypeInt 32 0
9782 %v2uint = OpTypeVector %uint 2
9783 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9784 %float = OpTypeFloat 32
9785 %v4float = OpTypeVector %float 4
9786 %_ptr_Input_v4float = OpTypePointer Input %v4float
9787 %3 = OpVariable %_ptr_Input_v4float Input
9788 %uint_4 = OpConstant %uint 4
9789 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
9790 %_ptr_Output_v4float = OpTypePointer Output %v4float
9791 %4 = OpVariable %_ptr_Output_v4float Output
9792 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
9793 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
9794 %20 = OpTypeSampledImage %18
9795 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
9796 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
9797 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
9798 %v2float = OpTypeVector %float 2
9799 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
9800 %2 = OpFunction %void None %8
9801 %24 = OpLabel
9802 %25 = OpVariable %_ptr_Function_v2uint Function
9803 OpStore %25 %16
9804 %26 = OpLoad %20 %5
9805 %27 = OpLoad %v2uint %25
9806 %28 = OpLoad %20 %6
9807 %29 = OpLoad %v2uint %25
9808 %30 = OpLoad %v2uint %25
9809 %31 = OpImageBlockMatchWindowSSDQCOM %v4float %26 %27 %28 %29 %30
9810 OpStore %4 %31
9811 %32 = OpLoad %20 %6
9812 %33 = OpLoad %v4float %3
9813 %34 = OpVectorShuffle %v2float %33 %33 0 2
9814 %35 = OpImageSampleImplicitLod %v4float %32 %34
9815 OpStore %4 %35
9816 OpReturn
9817 OpFunctionEnd
9818 )";
9819 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9820 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9821 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9822 EXPECT_THAT(
9823 getDiagnosticString(),
9824 HasSubstr("Illegal use of QCOM image processing decorated texture"));
9825 }
9826
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDInvalidUseTargetNI)9827 TEST_F(ValidateImage,
9828 QCOMImageProcessing2BlockMatchWindowSSDInvalidUseTargetNI) {
9829 const std::string text = R"(
9830 OpCapability Shader
9831 OpCapability TextureBlockMatchQCOM
9832 OpCapability TextureBlockMatch2QCOM
9833 OpExtension "SPV_QCOM_image_processing"
9834 OpExtension "SPV_QCOM_image_processing2"
9835 %1 = OpExtInstImport "GLSL.std.450"
9836 OpMemoryModel Logical GLSL450
9837 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
9838 OpExecutionMode %main OriginUpperLeft
9839 OpDecorate %100 Location 0
9840 OpDecorate %101 Location 0
9841 OpDecorate %102 DescriptorSet 0
9842 OpDecorate %102 Binding 1
9843 OpDecorate %103 DescriptorSet 0
9844 OpDecorate %103 Binding 3
9845 OpDecorate %104 DescriptorSet 0
9846 OpDecorate %104 Binding 2
9847 OpDecorate %102 BlockMatchTextureQCOM
9848 OpDecorate %103 BlockMatchSamplerQCOM
9849 OpDecorate %104 BlockMatchTextureQCOM
9850 %void = OpTypeVoid
9851 %3 = OpTypeFunction %void
9852 %uint = OpTypeInt 32 0
9853 %v2uint = OpTypeVector %uint 2
9854 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9855 %float = OpTypeFloat 32
9856 %v4float = OpTypeVector %float 4
9857 %_ptr_Input_v4float = OpTypePointer Input %v4float
9858 %100 = OpVariable %_ptr_Input_v4float Input
9859 %_ptr_Output_v4float = OpTypePointer Output %v4float
9860 %101 = OpVariable %_ptr_Output_v4float Output
9861 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
9862 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
9863 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
9864 %46 = OpTypeSampler
9865 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
9866 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
9867 %50 = OpTypeSampledImage %42
9868 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
9869 %v2float = OpTypeVector %float 2
9870 %main = OpFunction %void None %3
9871 %5 = OpLabel
9872 %15 = OpVariable %_ptr_Function_v2uint Function
9873 %45 = OpLoad %42 %102
9874 %49 = OpLoad %46 %103
9875 %51 = OpSampledImage %50 %45 %49
9876 %52 = OpLoad %v2uint %15
9877 %54 = OpLoad %42 %104
9878 %55 = OpLoad %46 %103
9879 %56 = OpSampledImage %50 %54 %55
9880 %57 = OpLoad %v2uint %15
9881 %58 = OpLoad %v2uint %15
9882 %59 = OpImageBlockMatchWindowSSDQCOM %v4float %51 %52 %56 %57 %58
9883 OpStore %101 %59
9884 %69 = OpLoad %42 %102
9885 %70 = OpLoad %46 %103
9886 %71 = OpSampledImage %50 %69 %70
9887 %73 = OpLoad %v4float %100
9888 %74 = OpVectorShuffle %v2float %73 %73 0 0
9889 %75 = OpImageSampleImplicitLod %v4float %71 %74
9890 OpStore %101 %75
9891 OpReturn
9892 OpFunctionEnd
9893 )";
9894 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9895 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9896 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9897 EXPECT_THAT(
9898 getDiagnosticString(),
9899 HasSubstr("Illegal use of QCOM image processing decorated texture"));
9900 }
9901
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchWindowSSDInvalidUseRefNI)9902 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDInvalidUseRefNI) {
9903 const std::string text = R"(
9904 OpCapability Shader
9905 OpCapability TextureBlockMatchQCOM
9906 OpCapability TextureBlockMatch2QCOM
9907 OpExtension "SPV_QCOM_image_processing"
9908 OpExtension "SPV_QCOM_image_processing2"
9909 %1 = OpExtInstImport "GLSL.std.450"
9910 OpMemoryModel Logical GLSL450
9911 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
9912 OpExecutionMode %main OriginUpperLeft
9913 OpDecorate %100 Location 0
9914 OpDecorate %101 Location 0
9915 OpDecorate %102 DescriptorSet 0
9916 OpDecorate %102 Binding 1
9917 OpDecorate %103 DescriptorSet 0
9918 OpDecorate %103 Binding 3
9919 OpDecorate %104 DescriptorSet 0
9920 OpDecorate %104 Binding 2
9921 OpDecorate %102 BlockMatchTextureQCOM
9922 OpDecorate %103 BlockMatchSamplerQCOM
9923 OpDecorate %104 BlockMatchTextureQCOM
9924 %void = OpTypeVoid
9925 %3 = OpTypeFunction %void
9926 %uint = OpTypeInt 32 0
9927 %v2uint = OpTypeVector %uint 2
9928 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
9929 %float = OpTypeFloat 32
9930 %v4float = OpTypeVector %float 4
9931 %_ptr_Input_v4float = OpTypePointer Input %v4float
9932 %100 = OpVariable %_ptr_Input_v4float Input
9933 %_ptr_Output_v4float = OpTypePointer Output %v4float
9934 %101 = OpVariable %_ptr_Output_v4float Output
9935 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
9936 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
9937 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
9938 %46 = OpTypeSampler
9939 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
9940 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
9941 %50 = OpTypeSampledImage %42
9942 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
9943 %v2float = OpTypeVector %float 2
9944 %main = OpFunction %void None %3
9945 %5 = OpLabel
9946 %15 = OpVariable %_ptr_Function_v2uint Function
9947 %45 = OpLoad %42 %102
9948 %49 = OpLoad %46 %103
9949 %51 = OpSampledImage %50 %45 %49
9950 %52 = OpLoad %v2uint %15
9951 %54 = OpLoad %42 %104
9952 %55 = OpLoad %46 %103
9953 %56 = OpSampledImage %50 %54 %55
9954 %57 = OpLoad %v2uint %15
9955 %58 = OpLoad %v2uint %15
9956 %59 = OpImageBlockMatchWindowSSDQCOM %v4float %51 %52 %56 %57 %58
9957 OpStore %101 %59
9958 %69 = OpLoad %42 %104
9959 %70 = OpLoad %46 %103
9960 %71 = OpSampledImage %50 %69 %70
9961 %73 = OpLoad %v4float %100
9962 %74 = OpVectorShuffle %v2float %73 %73 0 0
9963 %75 = OpImageSampleImplicitLod %v4float %71 %74
9964 OpStore %101 %75
9965 OpReturn
9966 OpFunctionEnd
9967 )";
9968 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
9969 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
9970 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
9971 EXPECT_THAT(
9972 getDiagnosticString(),
9973 HasSubstr("Illegal use of QCOM image processing decorated texture"));
9974 }
9975
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSADInvalidUseTargetI)9976 TEST_F(ValidateImage,
9977 QCOMImageProcessing2BlockMatchGatherSADInvalidUseTargetI) {
9978 const std::string text = R"(
9979 OpCapability Shader
9980 OpCapability TextureBlockMatchQCOM
9981 OpCapability TextureBlockMatch2QCOM
9982 OpExtension "SPV_QCOM_image_processing"
9983 OpExtension "SPV_QCOM_image_processing2"
9984 %1 = OpExtInstImport "GLSL.std.450"
9985 OpMemoryModel Logical GLSL450
9986 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
9987 OpExecutionMode %2 OriginUpperLeft
9988 OpDecorate %3 Location 0
9989 OpDecorate %4 Location 0
9990 OpDecorate %5 DescriptorSet 0
9991 OpDecorate %5 Binding 4
9992 OpDecorate %6 DescriptorSet 0
9993 OpDecorate %6 Binding 5
9994 OpDecorate %5 BlockMatchTextureQCOM
9995 OpDecorate %6 BlockMatchTextureQCOM
9996 %void = OpTypeVoid
9997 %8 = OpTypeFunction %void
9998 %uint = OpTypeInt 32 0
9999 %v2uint = OpTypeVector %uint 2
10000 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
10001 %float = OpTypeFloat 32
10002 %v4float = OpTypeVector %float 4
10003 %_ptr_Input_v4float = OpTypePointer Input %v4float
10004 %3 = OpVariable %_ptr_Input_v4float Input
10005 %uint_4 = OpConstant %uint 4
10006 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
10007 %_ptr_Output_v4float = OpTypePointer Output %v4float
10008 %4 = OpVariable %_ptr_Output_v4float Output
10009 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
10010 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
10011 %20 = OpTypeSampledImage %18
10012 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
10013 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
10014 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
10015 %v2float = OpTypeVector %float 2
10016 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
10017 %2 = OpFunction %void None %8
10018 %24 = OpLabel
10019 %25 = OpVariable %_ptr_Function_v2uint Function
10020 OpStore %25 %16
10021 %26 = OpLoad %20 %5
10022 %27 = OpLoad %v2uint %25
10023 %28 = OpLoad %20 %6
10024 %29 = OpLoad %v2uint %25
10025 %30 = OpLoad %v2uint %25
10026 %31 = OpImageBlockMatchGatherSADQCOM %v4float %26 %27 %28 %29 %30
10027 OpStore %4 %31
10028 %32 = OpLoad %20 %5
10029 %33 = OpLoad %v4float %3
10030 %34 = OpVectorShuffle %v2float %33 %33 0 2
10031 %35 = OpImageSampleImplicitLod %v4float %32 %34
10032 OpStore %4 %35
10033 OpReturn
10034 OpFunctionEnd
10035 )";
10036 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
10037 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
10038 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
10039 EXPECT_THAT(
10040 getDiagnosticString(),
10041 HasSubstr("Illegal use of QCOM image processing decorated texture"));
10042 }
10043
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSADInvalidUseRefI)10044 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADInvalidUseRefI) {
10045 const std::string text = R"(
10046 OpCapability Shader
10047 OpCapability TextureBlockMatchQCOM
10048 OpCapability TextureBlockMatch2QCOM
10049 OpExtension "SPV_QCOM_image_processing"
10050 OpExtension "SPV_QCOM_image_processing2"
10051 %1 = OpExtInstImport "GLSL.std.450"
10052 OpMemoryModel Logical GLSL450
10053 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
10054 OpExecutionMode %2 OriginUpperLeft
10055 OpDecorate %3 Location 0
10056 OpDecorate %4 Location 0
10057 OpDecorate %5 DescriptorSet 0
10058 OpDecorate %5 Binding 4
10059 OpDecorate %6 DescriptorSet 0
10060 OpDecorate %6 Binding 5
10061 OpDecorate %5 BlockMatchTextureQCOM
10062 OpDecorate %6 BlockMatchTextureQCOM
10063 %void = OpTypeVoid
10064 %8 = OpTypeFunction %void
10065 %uint = OpTypeInt 32 0
10066 %v2uint = OpTypeVector %uint 2
10067 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
10068 %float = OpTypeFloat 32
10069 %v4float = OpTypeVector %float 4
10070 %_ptr_Input_v4float = OpTypePointer Input %v4float
10071 %3 = OpVariable %_ptr_Input_v4float Input
10072 %uint_4 = OpConstant %uint 4
10073 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
10074 %_ptr_Output_v4float = OpTypePointer Output %v4float
10075 %4 = OpVariable %_ptr_Output_v4float Output
10076 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
10077 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
10078 %20 = OpTypeSampledImage %18
10079 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
10080 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
10081 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
10082 %v2float = OpTypeVector %float 2
10083 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
10084 %2 = OpFunction %void None %8
10085 %24 = OpLabel
10086 %25 = OpVariable %_ptr_Function_v2uint Function
10087 OpStore %25 %16
10088 %26 = OpLoad %20 %5
10089 %27 = OpLoad %v2uint %25
10090 %28 = OpLoad %20 %6
10091 %29 = OpLoad %v2uint %25
10092 %30 = OpLoad %v2uint %25
10093 %31 = OpImageBlockMatchGatherSADQCOM %v4float %26 %27 %28 %29 %30
10094 OpStore %4 %31
10095 %32 = OpLoad %20 %6
10096 %33 = OpLoad %v4float %3
10097 %34 = OpVectorShuffle %v2float %33 %33 0 2
10098 %35 = OpImageSampleImplicitLod %v4float %32 %34
10099 OpStore %4 %35
10100 OpReturn
10101 OpFunctionEnd
10102 )";
10103 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
10104 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
10105 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
10106 EXPECT_THAT(
10107 getDiagnosticString(),
10108 HasSubstr("Illegal use of QCOM image processing decorated texture"));
10109 }
10110
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSADInvalidUseTargetNI)10111 TEST_F(ValidateImage,
10112 QCOMImageProcessing2BlockMatchGatherSADInvalidUseTargetNI) {
10113 const std::string text = R"(
10114 OpCapability Shader
10115 OpCapability TextureBlockMatchQCOM
10116 OpCapability TextureBlockMatch2QCOM
10117 OpExtension "SPV_QCOM_image_processing"
10118 OpExtension "SPV_QCOM_image_processing2"
10119 %1 = OpExtInstImport "GLSL.std.450"
10120 OpMemoryModel Logical GLSL450
10121 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
10122 OpExecutionMode %main OriginUpperLeft
10123 OpDecorate %100 Location 0
10124 OpDecorate %101 Location 0
10125 OpDecorate %102 DescriptorSet 0
10126 OpDecorate %102 Binding 1
10127 OpDecorate %103 DescriptorSet 0
10128 OpDecorate %103 Binding 3
10129 OpDecorate %104 DescriptorSet 0
10130 OpDecorate %104 Binding 2
10131 OpDecorate %102 BlockMatchTextureQCOM
10132 OpDecorate %104 BlockMatchTextureQCOM
10133 %void = OpTypeVoid
10134 %3 = OpTypeFunction %void
10135 %uint = OpTypeInt 32 0
10136 %v2uint = OpTypeVector %uint 2
10137 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
10138 %float = OpTypeFloat 32
10139 %v4float = OpTypeVector %float 4
10140 %_ptr_Input_v4float = OpTypePointer Input %v4float
10141 %100 = OpVariable %_ptr_Input_v4float Input
10142 %_ptr_Output_v4float = OpTypePointer Output %v4float
10143 %101 = OpVariable %_ptr_Output_v4float Output
10144 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
10145 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
10146 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
10147 %46 = OpTypeSampler
10148 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
10149 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
10150 %50 = OpTypeSampledImage %42
10151 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
10152 %v2float = OpTypeVector %float 2
10153 %main = OpFunction %void None %3
10154 %5 = OpLabel
10155 %15 = OpVariable %_ptr_Function_v2uint Function
10156 %45 = OpLoad %42 %102
10157 %49 = OpLoad %46 %103
10158 %51 = OpSampledImage %50 %45 %49
10159 %52 = OpLoad %v2uint %15
10160 %54 = OpLoad %42 %104
10161 %55 = OpLoad %46 %103
10162 %56 = OpSampledImage %50 %54 %55
10163 %57 = OpLoad %v2uint %15
10164 %58 = OpLoad %v2uint %15
10165 %59 = OpImageBlockMatchGatherSADQCOM %v4float %51 %52 %56 %57 %58
10166 OpStore %101 %59
10167 %69 = OpLoad %42 %102
10168 %70 = OpLoad %46 %103
10169 %71 = OpSampledImage %50 %69 %70
10170 %73 = OpLoad %v4float %100
10171 %74 = OpVectorShuffle %v2float %73 %73 0 0
10172 %75 = OpImageSampleImplicitLod %v4float %71 %74
10173 OpStore %101 %75
10174 OpReturn
10175 OpFunctionEnd
10176 )";
10177 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
10178 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
10179 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
10180 EXPECT_THAT(
10181 getDiagnosticString(),
10182 HasSubstr("Illegal use of QCOM image processing decorated texture"));
10183 }
10184
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSADInvalidUseRefNI)10185 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADInvalidUseRefNI) {
10186 const std::string text = R"(
10187 OpCapability Shader
10188 OpCapability TextureBlockMatchQCOM
10189 OpCapability TextureBlockMatch2QCOM
10190 OpExtension "SPV_QCOM_image_processing"
10191 OpExtension "SPV_QCOM_image_processing2"
10192 %1 = OpExtInstImport "GLSL.std.450"
10193 OpMemoryModel Logical GLSL450
10194 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
10195 OpExecutionMode %main OriginUpperLeft
10196 OpDecorate %100 Location 0
10197 OpDecorate %101 Location 0
10198 OpDecorate %102 DescriptorSet 0
10199 OpDecorate %102 Binding 1
10200 OpDecorate %103 DescriptorSet 0
10201 OpDecorate %103 Binding 3
10202 OpDecorate %104 DescriptorSet 0
10203 OpDecorate %104 Binding 2
10204 OpDecorate %102 BlockMatchTextureQCOM
10205 OpDecorate %104 BlockMatchTextureQCOM
10206 %void = OpTypeVoid
10207 %3 = OpTypeFunction %void
10208 %uint = OpTypeInt 32 0
10209 %v2uint = OpTypeVector %uint 2
10210 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
10211 %float = OpTypeFloat 32
10212 %v4float = OpTypeVector %float 4
10213 %_ptr_Input_v4float = OpTypePointer Input %v4float
10214 %100 = OpVariable %_ptr_Input_v4float Input
10215 %_ptr_Output_v4float = OpTypePointer Output %v4float
10216 %101 = OpVariable %_ptr_Output_v4float Output
10217 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
10218 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
10219 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
10220 %46 = OpTypeSampler
10221 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
10222 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
10223 %50 = OpTypeSampledImage %42
10224 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
10225 %v2float = OpTypeVector %float 2
10226 %main = OpFunction %void None %3
10227 %5 = OpLabel
10228 %15 = OpVariable %_ptr_Function_v2uint Function
10229 %45 = OpLoad %42 %102
10230 %49 = OpLoad %46 %103
10231 %51 = OpSampledImage %50 %45 %49
10232 %52 = OpLoad %v2uint %15
10233 %54 = OpLoad %42 %104
10234 %55 = OpLoad %46 %103
10235 %56 = OpSampledImage %50 %54 %55
10236 %57 = OpLoad %v2uint %15
10237 %58 = OpLoad %v2uint %15
10238 %59 = OpImageBlockMatchGatherSADQCOM %v4float %51 %52 %56 %57 %58
10239 OpStore %101 %59
10240 %69 = OpLoad %42 %104
10241 %70 = OpLoad %46 %103
10242 %71 = OpSampledImage %50 %69 %70
10243 %73 = OpLoad %v4float %100
10244 %74 = OpVectorShuffle %v2float %73 %73 0 0
10245 %75 = OpImageSampleImplicitLod %v4float %71 %74
10246 OpStore %101 %75
10247 OpReturn
10248 OpFunctionEnd
10249 )";
10250 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
10251 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
10252 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
10253 EXPECT_THAT(
10254 getDiagnosticString(),
10255 HasSubstr("Illegal use of QCOM image processing decorated texture"));
10256 }
10257
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSSDInvalidUseTargetI)10258 TEST_F(ValidateImage,
10259 QCOMImageProcessing2BlockMatchGatherSSDInvalidUseTargetI) {
10260 const std::string text = R"(
10261 OpCapability Shader
10262 OpCapability TextureBlockMatchQCOM
10263 OpCapability TextureBlockMatch2QCOM
10264 OpExtension "SPV_QCOM_image_processing"
10265 OpExtension "SPV_QCOM_image_processing2"
10266 %1 = OpExtInstImport "GLSL.std.450"
10267 OpMemoryModel Logical GLSL450
10268 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
10269 OpExecutionMode %2 OriginUpperLeft
10270 OpDecorate %3 Location 0
10271 OpDecorate %4 Location 0
10272 OpDecorate %5 DescriptorSet 0
10273 OpDecorate %5 Binding 4
10274 OpDecorate %6 DescriptorSet 0
10275 OpDecorate %6 Binding 5
10276 OpDecorate %5 BlockMatchTextureQCOM
10277 OpDecorate %6 BlockMatchTextureQCOM
10278 %void = OpTypeVoid
10279 %8 = OpTypeFunction %void
10280 %uint = OpTypeInt 32 0
10281 %v2uint = OpTypeVector %uint 2
10282 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
10283 %float = OpTypeFloat 32
10284 %v4float = OpTypeVector %float 4
10285 %_ptr_Input_v4float = OpTypePointer Input %v4float
10286 %3 = OpVariable %_ptr_Input_v4float Input
10287 %uint_4 = OpConstant %uint 4
10288 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
10289 %_ptr_Output_v4float = OpTypePointer Output %v4float
10290 %4 = OpVariable %_ptr_Output_v4float Output
10291 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
10292 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
10293 %20 = OpTypeSampledImage %18
10294 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
10295 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
10296 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
10297 %v2float = OpTypeVector %float 2
10298 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
10299 %2 = OpFunction %void None %8
10300 %24 = OpLabel
10301 %25 = OpVariable %_ptr_Function_v2uint Function
10302 OpStore %25 %16
10303 %26 = OpLoad %20 %5
10304 %27 = OpLoad %v2uint %25
10305 %28 = OpLoad %20 %6
10306 %29 = OpLoad %v2uint %25
10307 %30 = OpLoad %v2uint %25
10308 %31 = OpImageBlockMatchGatherSSDQCOM %v4float %26 %27 %28 %29 %30
10309 OpStore %4 %31
10310 %32 = OpLoad %20 %5
10311 %33 = OpLoad %v4float %3
10312 %34 = OpVectorShuffle %v2float %33 %33 0 2
10313 %35 = OpImageSampleImplicitLod %v4float %32 %34
10314 OpStore %4 %35
10315 OpReturn
10316 OpFunctionEnd
10317 )";
10318 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
10319 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
10320 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
10321 EXPECT_THAT(
10322 getDiagnosticString(),
10323 HasSubstr("Illegal use of QCOM image processing decorated texture"));
10324 }
10325
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefI)10326 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefI) {
10327 const std::string text = R"(
10328 OpCapability Shader
10329 OpCapability TextureBlockMatchQCOM
10330 OpCapability TextureBlockMatch2QCOM
10331 OpExtension "SPV_QCOM_image_processing"
10332 OpExtension "SPV_QCOM_image_processing2"
10333 %1 = OpExtInstImport "GLSL.std.450"
10334 OpMemoryModel Logical GLSL450
10335 OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
10336 OpExecutionMode %2 OriginUpperLeft
10337 OpDecorate %3 Location 0
10338 OpDecorate %4 Location 0
10339 OpDecorate %5 DescriptorSet 0
10340 OpDecorate %5 Binding 4
10341 OpDecorate %6 DescriptorSet 0
10342 OpDecorate %6 Binding 5
10343 OpDecorate %5 BlockMatchTextureQCOM
10344 OpDecorate %6 BlockMatchTextureQCOM
10345 %void = OpTypeVoid
10346 %8 = OpTypeFunction %void
10347 %uint = OpTypeInt 32 0
10348 %v2uint = OpTypeVector %uint 2
10349 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
10350 %float = OpTypeFloat 32
10351 %v4float = OpTypeVector %float 4
10352 %_ptr_Input_v4float = OpTypePointer Input %v4float
10353 %3 = OpVariable %_ptr_Input_v4float Input
10354 %uint_4 = OpConstant %uint 4
10355 %16 = OpConstantComposite %v2uint %uint_4 %uint_4
10356 %_ptr_Output_v4float = OpTypePointer Output %v4float
10357 %4 = OpVariable %_ptr_Output_v4float Output
10358 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
10359 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
10360 %20 = OpTypeSampledImage %18
10361 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
10362 %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
10363 %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
10364 %v2float = OpTypeVector %float 2
10365 %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
10366 %2 = OpFunction %void None %8
10367 %24 = OpLabel
10368 %25 = OpVariable %_ptr_Function_v2uint Function
10369 OpStore %25 %16
10370 %26 = OpLoad %20 %5
10371 %27 = OpLoad %v2uint %25
10372 %28 = OpLoad %20 %6
10373 %29 = OpLoad %v2uint %25
10374 %30 = OpLoad %v2uint %25
10375 %31 = OpImageBlockMatchGatherSSDQCOM %v4float %26 %27 %28 %29 %30
10376 OpStore %4 %31
10377 %32 = OpLoad %20 %6
10378 %33 = OpLoad %v4float %3
10379 %34 = OpVectorShuffle %v2float %33 %33 0 2
10380 %35 = OpImageSampleImplicitLod %v4float %32 %34
10381 OpStore %4 %35
10382 OpReturn
10383 OpFunctionEnd
10384 )";
10385 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
10386 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
10387 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
10388 EXPECT_THAT(
10389 getDiagnosticString(),
10390 HasSubstr("Illegal use of QCOM image processing decorated texture"));
10391 }
10392
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSSDInvalidUseTargetNI)10393 TEST_F(ValidateImage,
10394 QCOMImageProcessing2BlockMatchGatherSSDInvalidUseTargetNI) {
10395 const std::string text = R"(
10396 OpCapability Shader
10397 OpCapability TextureBlockMatchQCOM
10398 OpCapability TextureBlockMatch2QCOM
10399 OpExtension "SPV_QCOM_image_processing"
10400 OpExtension "SPV_QCOM_image_processing2"
10401 %1 = OpExtInstImport "GLSL.std.450"
10402 OpMemoryModel Logical GLSL450
10403 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
10404 OpExecutionMode %main OriginUpperLeft
10405 OpDecorate %100 Location 0
10406 OpDecorate %101 Location 0
10407 OpDecorate %102 DescriptorSet 0
10408 OpDecorate %102 Binding 1
10409 OpDecorate %103 DescriptorSet 0
10410 OpDecorate %103 Binding 3
10411 OpDecorate %104 DescriptorSet 0
10412 OpDecorate %104 Binding 2
10413 OpDecorate %102 BlockMatchTextureQCOM
10414 OpDecorate %104 BlockMatchTextureQCOM
10415 %void = OpTypeVoid
10416 %3 = OpTypeFunction %void
10417 %uint = OpTypeInt 32 0
10418 %v2uint = OpTypeVector %uint 2
10419 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
10420 %float = OpTypeFloat 32
10421 %v4float = OpTypeVector %float 4
10422 %_ptr_Input_v4float = OpTypePointer Input %v4float
10423 %100 = OpVariable %_ptr_Input_v4float Input
10424 %_ptr_Output_v4float = OpTypePointer Output %v4float
10425 %101 = OpVariable %_ptr_Output_v4float Output
10426 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
10427 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
10428 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
10429 %46 = OpTypeSampler
10430 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
10431 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
10432 %50 = OpTypeSampledImage %42
10433 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
10434 %v2float = OpTypeVector %float 2
10435 %main = OpFunction %void None %3
10436 %5 = OpLabel
10437 %15 = OpVariable %_ptr_Function_v2uint Function
10438 %45 = OpLoad %42 %102
10439 %49 = OpLoad %46 %103
10440 %51 = OpSampledImage %50 %45 %49
10441 %52 = OpLoad %v2uint %15
10442 %54 = OpLoad %42 %104
10443 %55 = OpLoad %46 %103
10444 %56 = OpSampledImage %50 %54 %55
10445 %57 = OpLoad %v2uint %15
10446 %58 = OpLoad %v2uint %15
10447 %59 = OpImageBlockMatchGatherSSDQCOM %v4float %51 %52 %56 %57 %58
10448 OpStore %101 %59
10449 %69 = OpLoad %42 %102
10450 %70 = OpLoad %46 %103
10451 %71 = OpSampledImage %50 %69 %70
10452 %73 = OpLoad %v4float %100
10453 %74 = OpVectorShuffle %v2float %73 %73 0 0
10454 %75 = OpImageSampleImplicitLod %v4float %71 %74
10455 OpStore %101 %75
10456 OpReturn
10457 OpFunctionEnd
10458 )";
10459 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
10460 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
10461 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
10462 EXPECT_THAT(
10463 getDiagnosticString(),
10464 HasSubstr("Illegal use of QCOM image processing decorated texture"));
10465 }
10466
TEST_F(ValidateImage,QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefNI)10467 TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefNI) {
10468 const std::string text = R"(
10469 OpCapability Shader
10470 OpCapability TextureBlockMatchQCOM
10471 OpCapability TextureBlockMatch2QCOM
10472 OpExtension "SPV_QCOM_image_processing"
10473 OpExtension "SPV_QCOM_image_processing2"
10474 %1 = OpExtInstImport "GLSL.std.450"
10475 OpMemoryModel Logical GLSL450
10476 OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
10477 OpExecutionMode %main OriginUpperLeft
10478 OpDecorate %100 Location 0
10479 OpDecorate %101 Location 0
10480 OpDecorate %102 DescriptorSet 0
10481 OpDecorate %102 Binding 1
10482 OpDecorate %103 DescriptorSet 0
10483 OpDecorate %103 Binding 3
10484 OpDecorate %104 DescriptorSet 0
10485 OpDecorate %104 Binding 2
10486 OpDecorate %102 BlockMatchTextureQCOM
10487 OpDecorate %104 BlockMatchTextureQCOM
10488 %void = OpTypeVoid
10489 %3 = OpTypeFunction %void
10490 %uint = OpTypeInt 32 0
10491 %v2uint = OpTypeVector %uint 2
10492 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
10493 %float = OpTypeFloat 32
10494 %v4float = OpTypeVector %float 4
10495 %_ptr_Input_v4float = OpTypePointer Input %v4float
10496 %100 = OpVariable %_ptr_Input_v4float Input
10497 %_ptr_Output_v4float = OpTypePointer Output %v4float
10498 %101 = OpVariable %_ptr_Output_v4float Output
10499 %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
10500 %_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
10501 %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
10502 %46 = OpTypeSampler
10503 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
10504 %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
10505 %50 = OpTypeSampledImage %42
10506 %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
10507 %v2float = OpTypeVector %float 2
10508 %main = OpFunction %void None %3
10509 %5 = OpLabel
10510 %15 = OpVariable %_ptr_Function_v2uint Function
10511 %45 = OpLoad %42 %102
10512 %49 = OpLoad %46 %103
10513 %51 = OpSampledImage %50 %45 %49
10514 %52 = OpLoad %v2uint %15
10515 %54 = OpLoad %42 %104
10516 %55 = OpLoad %46 %103
10517 %56 = OpSampledImage %50 %54 %55
10518 %57 = OpLoad %v2uint %15
10519 %58 = OpLoad %v2uint %15
10520 %59 = OpImageBlockMatchGatherSSDQCOM %v4float %51 %52 %56 %57 %58
10521 OpStore %101 %59
10522 %69 = OpLoad %42 %104
10523 %70 = OpLoad %46 %103
10524 %71 = OpSampledImage %50 %69 %70
10525 %73 = OpLoad %v4float %100
10526 %74 = OpVectorShuffle %v2float %73 %73 0 0
10527 %75 = OpImageSampleImplicitLod %v4float %71 %74
10528 OpStore %101 %75
10529 OpReturn
10530 OpFunctionEnd
10531 )";
10532 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
10533 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
10534 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
10535 EXPECT_THAT(
10536 getDiagnosticString(),
10537 HasSubstr("Illegal use of QCOM image processing decorated texture"));
10538 }
10539
TEST_F(ValidateImage,ImageMSArray_ArrayedSampledTypeRequiresCapability)10540 TEST_F(ValidateImage, ImageMSArray_ArrayedSampledTypeRequiresCapability) {
10541 const std::string code = R"(
10542 OpCapability Shader
10543 OpCapability StorageImageMultisample
10544 OpCapability StorageImageReadWithoutFormat
10545 OpMemoryModel Logical GLSL450
10546 OpEntryPoint Fragment %main "main"
10547 OpExecutionMode %main OriginUpperLeft
10548 OpDecorate %var_image DescriptorSet 0
10549 OpDecorate %var_image Binding 1
10550 %void = OpTypeVoid
10551 %func = OpTypeFunction %void
10552 %f32 = OpTypeFloat 32
10553 %u32 = OpTypeInt 32 0
10554 %uint_2 = OpConstant %u32 2
10555 %uint_1 = OpConstant %u32 1
10556 %v2uint = OpTypeVector %u32 2
10557 %v4float = OpTypeVector %f32 4
10558 %image = OpTypeImage %f32 2D 2 1 1 2 Unknown
10559 %ptr_image = OpTypePointer UniformConstant %image
10560 %10 = OpConstantComposite %v2uint %uint_1 %uint_2
10561 %var_image = OpVariable %ptr_image UniformConstant
10562 %main = OpFunction %void None %func
10563 %main_lab = OpLabel
10564 %18 = OpLoad %image %var_image
10565 %19 = OpImageRead %v4float %18 %10 Sample %uint_2
10566 OpReturn
10567 OpFunctionEnd
10568 )";
10569
10570 const spv_target_env env = SPV_ENV_VULKAN_1_0;
10571 CompileSuccessfully(code, env);
10572 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
10573 EXPECT_THAT(
10574 getDiagnosticString(),
10575 HasSubstr("Capability ImageMSArray is required to access storage image"));
10576 }
10577
TEST_F(ValidateImage,ImageMSArray_SampledTypeDoesNotRequireCapability)10578 TEST_F(ValidateImage, ImageMSArray_SampledTypeDoesNotRequireCapability) {
10579 const std::string code = R"(
10580 OpCapability Shader
10581 OpCapability StorageImageMultisample
10582 OpCapability StorageImageReadWithoutFormat
10583 OpMemoryModel Logical GLSL450
10584 OpEntryPoint Fragment %main "main"
10585 OpExecutionMode %main OriginUpperLeft
10586 OpDecorate %var_image DescriptorSet 0
10587 OpDecorate %var_image Binding 1
10588 %void = OpTypeVoid
10589 %func = OpTypeFunction %void
10590 %f32 = OpTypeFloat 32
10591 %u32 = OpTypeInt 32 0
10592 %uint_2 = OpConstant %u32 2
10593 %uint_1 = OpConstant %u32 1
10594 %v2uint = OpTypeVector %u32 2
10595 %v4float = OpTypeVector %f32 4
10596 %image = OpTypeImage %f32 2D 2 0 1 2 Unknown
10597 %ptr_image = OpTypePointer UniformConstant %image
10598 %10 = OpConstantComposite %v2uint %uint_1 %uint_2
10599 %var_image = OpVariable %ptr_image UniformConstant
10600 %main = OpFunction %void None %func
10601 %main_lab = OpLabel
10602 %18 = OpLoad %image %var_image
10603 %19 = OpImageRead %v4float %18 %10 Sample %uint_2
10604 OpReturn
10605 OpFunctionEnd
10606 )";
10607
10608 const spv_target_env env = SPV_ENV_VULKAN_1_0;
10609 CompileSuccessfully(code, env);
10610 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
10611 EXPECT_THAT(getDiagnosticString(), Eq(""));
10612 }
10613
TEST_F(ValidateImage,ImageMSArray_ArrayedTypeDoesNotRequireCapability)10614 TEST_F(ValidateImage, ImageMSArray_ArrayedTypeDoesNotRequireCapability) {
10615 const std::string code = R"(
10616 OpCapability Shader
10617 OpCapability StorageImageReadWithoutFormat
10618 OpMemoryModel Logical GLSL450
10619 OpEntryPoint Fragment %main "main"
10620 OpExecutionMode %main OriginUpperLeft
10621 OpDecorate %var_image DescriptorSet 0
10622 OpDecorate %var_image Binding 1
10623 %void = OpTypeVoid
10624 %func = OpTypeFunction %void
10625 %f32 = OpTypeFloat 32
10626 %u32 = OpTypeInt 32 0
10627 %uint_3 = OpConstant %u32 3
10628 %uint_2 = OpConstant %u32 2
10629 %uint_1 = OpConstant %u32 1
10630 %v3uint = OpTypeVector %u32 3
10631 %v4float = OpTypeVector %f32 4
10632 %image = OpTypeImage %f32 2D 2 1 0 2 Unknown
10633 %ptr_image = OpTypePointer UniformConstant %image
10634 %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
10635 %var_image = OpVariable %ptr_image UniformConstant
10636 %main = OpFunction %void None %func
10637 %main_lab = OpLabel
10638 %18 = OpLoad %image %var_image
10639 %19 = OpImageRead %v4float %18 %10
10640 OpReturn
10641 OpFunctionEnd
10642 )";
10643
10644 const spv_target_env env = SPV_ENV_VULKAN_1_0;
10645 CompileSuccessfully(code, env);
10646 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
10647 EXPECT_THAT(getDiagnosticString(), Eq(""));
10648 }
10649
TEST_F(ValidateImage,SampledImageTypeMismatch)10650 TEST_F(ValidateImage, SampledImageTypeMismatch) {
10651 const std::string code = R"(
10652 OpCapability Shader
10653 OpMemoryModel Logical GLSL450
10654 OpEntryPoint GLCompute %main "main"
10655 OpExecutionMode %main LocalSize 1 1 1
10656 OpDecorate %im_var DescriptorSet 0
10657 OpDecorate %im_var Binding 0
10658 OpDecorate %s_var DescriptorSet 1
10659 OpDecorate %s_var Binding 0
10660 %void = OpTypeVoid
10661 %float = OpTypeFloat 32
10662 %im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
10663 %im2_ty = OpTypeImage %float 2D 1 0 0 1 Unknown
10664 %s_ty = OpTypeSampler
10665 %s_im_ty = OpTypeSampledImage %im2_ty
10666 %ptr_im = OpTypePointer UniformConstant %im1_ty
10667 %ptr_s = OpTypePointer UniformConstant %s_ty
10668 %im_var = OpVariable %ptr_im UniformConstant
10669 %s_var = OpVariable %ptr_s UniformConstant
10670 %void_fn = OpTypeFunction %void
10671 %main = OpFunction %void None %void_fn
10672 %entry = OpLabel
10673 %im_ld = OpLoad %im1_ty %im_var
10674 %s_ld = OpLoad %s_ty %s_var
10675 %sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
10676 OpReturn
10677 OpFunctionEnd
10678 )";
10679
10680 const spv_target_env env = SPV_ENV_VULKAN_1_0;
10681 CompileSuccessfully(code, env);
10682 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
10683 EXPECT_THAT(
10684 getDiagnosticString(),
10685 HasSubstr("Expected Image to have the same type as Result Type Image"));
10686 }
10687
10688 } // namespace
10689 } // namespace val
10690 } // namespace spvtools
10691