1 // Copyright (c) 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Tests for unique type declaration rules validator.
16
17 #include <sstream>
18 #include <string>
19
20 #include "gmock/gmock.h"
21 #include "test/unit_spirv.h"
22 #include "test/val/val_fixtures.h"
23
24 namespace spvtools {
25 namespace val {
26 namespace {
27
28 using ::testing::Eq;
29 using ::testing::HasSubstr;
30 using ::testing::Not;
31
32 using ValidateImage = spvtest::ValidateBase<bool>;
33
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")34 std::string GenerateShaderCode(
35 const std::string& body,
36 const std::string& capabilities_and_extensions = "",
37 const std::string& execution_model = "Fragment",
38 const std::string& execution_mode = "",
39 const spv_target_env env = SPV_ENV_UNIVERSAL_1_0,
40 const std::string& memory_model = "GLSL450") {
41 std::ostringstream ss;
42 ss << R"(
43 OpCapability Shader
44 OpCapability InputAttachment
45 OpCapability ImageGatherExtended
46 OpCapability MinLod
47 OpCapability Sampled1D
48 OpCapability ImageQuery
49 OpCapability Int64
50 OpCapability Float64
51 OpCapability SparseResidency
52 OpCapability ImageBuffer
53 )";
54
55 if (env == SPV_ENV_UNIVERSAL_1_0) {
56 ss << "OpCapability SampledRect\n";
57 }
58
59 // In 1.4, the entry point must list all module-scope variables used. Just
60 // list all of them.
61 std::string interface_vars = (env != SPV_ENV_UNIVERSAL_1_4) ? "" :
62 R"(
63 %uniform_image_f32_1d_0001
64 %uniform_image_f32_1d_0002_rgba32f
65 %uniform_image_f32_2d_0001
66 %uniform_image_f32_2d_0010
67 %uniform_image_u32_2d_0001
68 %uniform_image_u32_2d_0000
69 %uniform_image_s32_3d_0001
70 %uniform_image_f32_2d_0002
71 %uniform_image_s32_2d_0002
72 %uniform_image_f32_spd_0002
73 %uniform_image_f32_3d_0111
74 %uniform_image_f32_cube_0101
75 %uniform_image_f32_cube_0102_rgba32f
76 %uniform_sampler
77 %private_image_u32_buffer_0002_r32ui
78 %private_image_u32_spd_0002
79 %private_image_f32_buffer_0002_r32ui
80 )";
81
82 ss << capabilities_and_extensions;
83 ss << "OpMemoryModel Logical " << memory_model << "\n";
84 ss << "OpEntryPoint " << execution_model
85 << " %main \"main\" " + interface_vars + "\n";
86 if (execution_model == "Fragment") {
87 ss << "OpExecutionMode %main OriginUpperLeft\n";
88 }
89 ss << execution_mode;
90
91 if (env == SPV_ENV_VULKAN_1_0) {
92 ss << R"(
93 OpDecorate %uniform_image_f32_1d_0001 DescriptorSet 0
94 OpDecorate %uniform_image_f32_1d_0001 Binding 0
95 OpDecorate %uniform_image_f32_1d_0002_rgba32f DescriptorSet 0
96 OpDecorate %uniform_image_f32_1d_0002_rgba32f Binding 1
97 OpDecorate %uniform_image_f32_2d_0001 DescriptorSet 0
98 OpDecorate %uniform_image_f32_2d_0001 Binding 2
99 OpDecorate %uniform_image_f32_2d_0010 DescriptorSet 0
100 OpDecorate %uniform_image_f32_2d_0010 Binding 3
101 OpDecorate %uniform_image_u32_2d_0001 DescriptorSet 1
102 OpDecorate %uniform_image_u32_2d_0001 Binding 0
103 OpDecorate %uniform_image_u32_2d_0000 DescriptorSet 1
104 OpDecorate %uniform_image_u32_2d_0000 Binding 1
105 OpDecorate %uniform_image_s32_3d_0001 DescriptorSet 1
106 OpDecorate %uniform_image_s32_3d_0001 Binding 2
107 OpDecorate %uniform_image_f32_2d_0002 DescriptorSet 1
108 OpDecorate %uniform_image_f32_2d_0002 Binding 3
109 OpDecorate %uniform_image_s32_2d_0002 DescriptorSet 1
110 OpDecorate %uniform_image_s32_2d_0002 Binding 4
111 OpDecorate %uniform_image_f32_spd_0002 DescriptorSet 2
112 OpDecorate %uniform_image_f32_spd_0002 Binding 0
113 OpDecorate %uniform_image_f32_3d_0111 DescriptorSet 2
114 OpDecorate %uniform_image_f32_3d_0111 Binding 1
115 OpDecorate %uniform_image_f32_cube_0101 DescriptorSet 2
116 OpDecorate %uniform_image_f32_cube_0101 Binding 2
117 OpDecorate %uniform_image_f32_cube_0102_rgba32f DescriptorSet 2
118 OpDecorate %uniform_image_f32_cube_0102_rgba32f Binding 3
119 OpDecorate %uniform_sampler DescriptorSet 3
120 OpDecorate %uniform_sampler Binding 0
121 )";
122 }
123
124 ss << R"(
125 %void = OpTypeVoid
126 %func = OpTypeFunction %void
127 %bool = OpTypeBool
128 %f32 = OpTypeFloat 32
129 %f64 = OpTypeFloat 64
130 %u32 = OpTypeInt 32 0
131 %s32 = OpTypeInt 32 1
132 %u64 = OpTypeInt 64 0
133 %s32vec2 = OpTypeVector %s32 2
134 %u32vec2 = OpTypeVector %u32 2
135 %f32vec2 = OpTypeVector %f32 2
136 %u32vec3 = OpTypeVector %u32 3
137 %s32vec3 = OpTypeVector %s32 3
138 %f32vec3 = OpTypeVector %f32 3
139 %u32vec4 = OpTypeVector %u32 4
140 %s32vec4 = OpTypeVector %s32 4
141 %f32vec4 = OpTypeVector %f32 4
142
143 %f32_0 = OpConstant %f32 0
144 %f32_1 = OpConstant %f32 1
145 %f32_0_5 = OpConstant %f32 0.5
146 %f32_0_25 = OpConstant %f32 0.25
147 %f32_0_75 = OpConstant %f32 0.75
148
149 %f64_0 = OpConstant %f64 0
150 %f64_1 = OpConstant %f64 1
151
152 %s32_0 = OpConstant %s32 0
153 %s32_1 = OpConstant %s32 1
154 %s32_2 = OpConstant %s32 2
155 %s32_3 = OpConstant %s32 3
156 %s32_4 = OpConstant %s32 4
157 %s32_m1 = OpConstant %s32 -1
158
159 %u32_0 = OpConstant %u32 0
160 %u32_1 = OpConstant %u32 1
161 %u32_2 = OpConstant %u32 2
162 %u32_3 = OpConstant %u32 3
163 %u32_4 = OpConstant %u32 4
164
165 %u64_0 = OpConstant %u64 0
166
167 %u32vec2arr4 = OpTypeArray %u32vec2 %u32_4
168 %u32vec2arr3 = OpTypeArray %u32vec2 %u32_3
169 %u32arr4 = OpTypeArray %u32 %u32_4
170 %u32vec3arr4 = OpTypeArray %u32vec3 %u32_4
171
172 %struct_u32_f32vec4 = OpTypeStruct %u32 %f32vec4
173 %struct_u64_f32vec4 = OpTypeStruct %u64 %f32vec4
174 %struct_u32_u32vec4 = OpTypeStruct %u32 %u32vec4
175 %struct_u32_f32vec3 = OpTypeStruct %u32 %f32vec3
176 %struct_f32_f32vec4 = OpTypeStruct %f32 %f32vec4
177 %struct_u32_u32 = OpTypeStruct %u32 %u32
178 %struct_f32_f32 = OpTypeStruct %f32 %f32
179 %struct_u32 = OpTypeStruct %u32
180 %struct_u32_f32_u32 = OpTypeStruct %u32 %f32 %u32
181 %struct_u32_f32vec4_u32 = OpTypeStruct %u32 %f32vec4 %u32
182 %struct_u32_u32arr4 = OpTypeStruct %u32 %u32arr4
183
184 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
185 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
186 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
187 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
188 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
189 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
190
191 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
192 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
193 %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
194 %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
195 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
196 %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
197
198 %f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
199 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
200 %f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
201 %f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
202 %f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
203
204 %f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
205 %f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
206
207 %f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
208
209 %const_offsets = OpConstantComposite %u32vec2arr4 %u32vec2_01 %u32vec2_12 %u32vec2_01 %u32vec2_12
210 %const_offsets3x2 = OpConstantComposite %u32vec2arr3 %u32vec2_01 %u32vec2_12 %u32vec2_01
211 %const_offsets4xu = OpConstantComposite %u32arr4 %u32_0 %u32_0 %u32_0 %u32_0
212 %const_offsets4x3 = OpConstantComposite %u32vec3arr4 %u32vec3_012 %u32vec3_012 %u32vec3_012 %u32vec3_012
213
214 %type_image_f32_1d_0001 = OpTypeImage %f32 1D 0 0 0 1 Unknown
215 %ptr_image_f32_1d_0001 = OpTypePointer UniformConstant %type_image_f32_1d_0001
216 %uniform_image_f32_1d_0001 = OpVariable %ptr_image_f32_1d_0001 UniformConstant
217 %type_sampled_image_f32_1d_0001 = OpTypeSampledImage %type_image_f32_1d_0001
218
219 %type_image_f32_1d_0002_rgba32f = OpTypeImage %f32 1D 0 0 0 2 Rgba32f
220 %ptr_image_f32_1d_0002_rgba32f = OpTypePointer UniformConstant %type_image_f32_1d_0002_rgba32f
221 %uniform_image_f32_1d_0002_rgba32f = OpVariable %ptr_image_f32_1d_0002_rgba32f UniformConstant
222 %type_sampled_image_f32_1d_0002_rgba32f = OpTypeSampledImage %type_image_f32_1d_0002_rgba32f
223
224 %type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
225 %ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
226 %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
227 %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
228
229 %type_image_f32_2d_0010 = OpTypeImage %f32 2D 0 0 1 0 Unknown
230 %ptr_image_f32_2d_0010 = OpTypePointer UniformConstant %type_image_f32_2d_0010
231 %uniform_image_f32_2d_0010 = OpVariable %ptr_image_f32_2d_0010 UniformConstant
232 %type_sampled_image_f32_2d_0010 = OpTypeSampledImage %type_image_f32_2d_0010
233
234 %type_image_u32_2d_0001 = OpTypeImage %u32 2D 0 0 0 1 Unknown
235 %ptr_image_u32_2d_0001 = OpTypePointer UniformConstant %type_image_u32_2d_0001
236 %uniform_image_u32_2d_0001 = OpVariable %ptr_image_u32_2d_0001 UniformConstant
237 %type_sampled_image_u32_2d_0001 = OpTypeSampledImage %type_image_u32_2d_0001
238
239 %type_image_u32_2d_0000 = OpTypeImage %u32 2D 0 0 0 0 Unknown
240 %ptr_image_u32_2d_0000 = OpTypePointer UniformConstant %type_image_u32_2d_0000
241 %uniform_image_u32_2d_0000 = OpVariable %ptr_image_u32_2d_0000 UniformConstant
242 %type_sampled_image_u32_2d_0000 = OpTypeSampledImage %type_image_u32_2d_0000
243
244 %type_image_s32_3d_0001 = OpTypeImage %s32 3D 0 0 0 1 Unknown
245 %ptr_image_s32_3d_0001 = OpTypePointer UniformConstant %type_image_s32_3d_0001
246 %uniform_image_s32_3d_0001 = OpVariable %ptr_image_s32_3d_0001 UniformConstant
247 %type_sampled_image_s32_3d_0001 = OpTypeSampledImage %type_image_s32_3d_0001
248
249 %type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Unknown
250 %ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
251 %uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
252 %type_sampled_image_f32_2d_0002 = OpTypeSampledImage %type_image_f32_2d_0002
253
254 %type_image_s32_2d_0002 = OpTypeImage %s32 2D 0 0 0 2 Unknown
255 %ptr_image_s32_2d_0002 = OpTypePointer UniformConstant %type_image_s32_2d_0002
256 %uniform_image_s32_2d_0002 = OpVariable %ptr_image_s32_2d_0002 UniformConstant
257 %type_sampled_image_s32_2d_0002 = OpTypeSampledImage %type_image_s32_2d_0002
258
259 %type_image_f32_spd_0002 = OpTypeImage %f32 SubpassData 0 0 0 2 Unknown
260 %ptr_image_f32_spd_0002 = OpTypePointer UniformConstant %type_image_f32_spd_0002
261 %uniform_image_f32_spd_0002 = OpVariable %ptr_image_f32_spd_0002 UniformConstant
262 %type_sampled_image_f32_spd_0002 = OpTypeSampledImage %type_image_f32_spd_0002
263
264 %type_image_f32_3d_0111 = OpTypeImage %f32 3D 0 1 1 1 Unknown
265 %ptr_image_f32_3d_0111 = OpTypePointer UniformConstant %type_image_f32_3d_0111
266 %uniform_image_f32_3d_0111 = OpVariable %ptr_image_f32_3d_0111 UniformConstant
267 %type_sampled_image_f32_3d_0111 = OpTypeSampledImage %type_image_f32_3d_0111
268
269 %type_image_f32_cube_0101 = OpTypeImage %f32 Cube 0 1 0 1 Unknown
270 %ptr_image_f32_cube_0101 = OpTypePointer UniformConstant %type_image_f32_cube_0101
271 %uniform_image_f32_cube_0101 = OpVariable %ptr_image_f32_cube_0101 UniformConstant
272 %type_sampled_image_f32_cube_0101 = OpTypeSampledImage %type_image_f32_cube_0101
273
274 %type_image_f32_cube_0102_rgba32f = OpTypeImage %f32 Cube 0 1 0 2 Rgba32f
275 %ptr_image_f32_cube_0102_rgba32f = OpTypePointer UniformConstant %type_image_f32_cube_0102_rgba32f
276 %uniform_image_f32_cube_0102_rgba32f = OpVariable %ptr_image_f32_cube_0102_rgba32f UniformConstant
277 %type_sampled_image_f32_cube_0102_rgba32f = OpTypeSampledImage %type_image_f32_cube_0102_rgba32f
278
279 %type_sampler = OpTypeSampler
280 %ptr_sampler = OpTypePointer UniformConstant %type_sampler
281 %uniform_sampler = OpVariable %ptr_sampler UniformConstant
282
283 %type_image_u32_buffer_0002_r32ui = OpTypeImage %u32 Buffer 0 0 0 2 R32ui
284 %ptr_Image_u32 = OpTypePointer Image %u32
285 %ptr_image_u32_buffer_0002_r32ui = OpTypePointer Private %type_image_u32_buffer_0002_r32ui
286 %private_image_u32_buffer_0002_r32ui = OpVariable %ptr_image_u32_buffer_0002_r32ui Private
287
288 %ptr_Image_u32arr4 = OpTypePointer Image %u32arr4
289
290 %type_image_u32_spd_0002 = OpTypeImage %u32 SubpassData 0 0 0 2 Unknown
291 %ptr_image_u32_spd_0002 = OpTypePointer Private %type_image_u32_spd_0002
292 %private_image_u32_spd_0002 = OpVariable %ptr_image_u32_spd_0002 Private
293
294 %type_image_f32_buffer_0002_r32ui = OpTypeImage %f32 Buffer 0 0 0 2 R32ui
295 %ptr_Image_f32 = OpTypePointer Image %f32
296 %ptr_image_f32_buffer_0002_r32ui = OpTypePointer Private %type_image_f32_buffer_0002_r32ui
297 %private_image_f32_buffer_0002_r32ui = OpVariable %ptr_image_f32_buffer_0002_r32ui Private
298 )";
299
300 if (env == SPV_ENV_UNIVERSAL_1_0) {
301 ss << R"(
302 %type_image_void_2d_0001 = OpTypeImage %void 2D 0 0 0 1 Unknown
303 %ptr_image_void_2d_0001 = OpTypePointer UniformConstant %type_image_void_2d_0001
304 %uniform_image_void_2d_0001 = OpVariable %ptr_image_void_2d_0001 UniformConstant
305 %type_sampled_image_void_2d_0001 = OpTypeSampledImage %type_image_void_2d_0001
306
307 %type_image_void_2d_0002 = OpTypeImage %void 2D 0 0 0 2 Unknown
308 %ptr_image_void_2d_0002 = OpTypePointer UniformConstant %type_image_void_2d_0002
309 %uniform_image_void_2d_0002 = OpVariable %ptr_image_void_2d_0002 UniformConstant
310 %type_sampled_image_void_2d_0002 = OpTypeSampledImage %type_image_void_2d_0002
311
312 %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
313 %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
314 %uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
315 %type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
316 )";
317 }
318
319 ss << R"(
320 %main = OpFunction %void None %func
321 %main_entry = OpLabel
322 )";
323
324 ss << body;
325
326 ss << R"(
327 OpReturn
328 OpFunctionEnd)";
329
330 return ss.str();
331 }
332
GenerateKernelCode(const std::string & body,const std::string & capabilities_and_extensions="")333 std::string GenerateKernelCode(
334 const std::string& body,
335 const std::string& capabilities_and_extensions = "") {
336 std::ostringstream ss;
337 ss << R"(
338 OpCapability Addresses
339 OpCapability Kernel
340 OpCapability Linkage
341 OpCapability ImageQuery
342 OpCapability ImageGatherExtended
343 OpCapability InputAttachment
344 OpCapability SampledRect
345 )";
346
347 ss << capabilities_and_extensions;
348 ss << R"(
349 OpMemoryModel Physical32 OpenCL
350 %void = OpTypeVoid
351 %func = OpTypeFunction %void
352 %bool = OpTypeBool
353 %f32 = OpTypeFloat 32
354 %u32 = OpTypeInt 32 0
355 %u32vec2 = OpTypeVector %u32 2
356 %f32vec2 = OpTypeVector %f32 2
357 %u32vec3 = OpTypeVector %u32 3
358 %f32vec3 = OpTypeVector %f32 3
359 %u32vec4 = OpTypeVector %u32 4
360 %f32vec4 = OpTypeVector %f32 4
361
362 %f32_0 = OpConstant %f32 0
363 %f32_1 = OpConstant %f32 1
364 %f32_0_5 = OpConstant %f32 0.5
365 %f32_0_25 = OpConstant %f32 0.25
366 %f32_0_75 = OpConstant %f32 0.75
367
368 %u32_0 = OpConstant %u32 0
369 %u32_1 = OpConstant %u32 1
370 %u32_2 = OpConstant %u32 2
371 %u32_3 = OpConstant %u32 3
372 %u32_4 = OpConstant %u32 4
373
374 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
375 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
376 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
377 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
378 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
379 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
380
381 %f32vec2_00 = OpConstantComposite %f32vec2 %f32_0 %f32_0
382 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
383 %f32vec2_10 = OpConstantComposite %f32vec2 %f32_1 %f32_0
384 %f32vec2_11 = OpConstantComposite %f32vec2 %f32_1 %f32_1
385 %f32vec2_hh = OpConstantComposite %f32vec2 %f32_0_5 %f32_0_5
386
387 %f32vec3_000 = OpConstantComposite %f32vec3 %f32_0 %f32_0 %f32_0
388 %f32vec3_hhh = OpConstantComposite %f32vec3 %f32_0_5 %f32_0_5 %f32_0_5
389
390 %f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0
391
392 %type_image_f32_2d_0001 = OpTypeImage %f32 2D 0 0 0 1 Unknown
393 %ptr_image_f32_2d_0001 = OpTypePointer UniformConstant %type_image_f32_2d_0001
394 %uniform_image_f32_2d_0001 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
395 %type_sampled_image_f32_2d_0001 = OpTypeSampledImage %type_image_f32_2d_0001
396
397 %type_image_f32_2d_0010 = OpTypeImage %f32 2D 0 0 1 0 Unknown
398 %ptr_image_f32_2d_0010 = OpTypePointer UniformConstant %type_image_f32_2d_0010
399 %uniform_image_f32_2d_0010 = OpVariable %ptr_image_f32_2d_0010 UniformConstant
400 %type_sampled_image_f32_2d_0010 = OpTypeSampledImage %type_image_f32_2d_0010
401
402 %type_image_f32_3d_0010 = OpTypeImage %f32 3D 0 0 1 0 Unknown
403 %ptr_image_f32_3d_0010 = OpTypePointer UniformConstant %type_image_f32_3d_0010
404 %uniform_image_f32_3d_0010 = OpVariable %ptr_image_f32_3d_0010 UniformConstant
405 %type_sampled_image_f32_3d_0010 = OpTypeSampledImage %type_image_f32_3d_0010
406
407 %type_image_f32_rect_0001 = OpTypeImage %f32 Rect 0 0 0 1 Unknown
408 %ptr_image_f32_rect_0001 = OpTypePointer UniformConstant %type_image_f32_rect_0001
409 %uniform_image_f32_rect_0001 = OpVariable %ptr_image_f32_rect_0001 UniformConstant
410 %type_sampled_image_f32_rect_0001 = OpTypeSampledImage %type_image_f32_rect_0001
411
412 %type_sampler = OpTypeSampler
413 %ptr_sampler = OpTypePointer UniformConstant %type_sampler
414 %uniform_sampler = OpVariable %ptr_sampler UniformConstant
415
416 %main = OpFunction %void None %func
417 %main_entry = OpLabel
418 )";
419
420 ss << body;
421 ss << R"(
422 OpReturn
423 OpFunctionEnd)";
424
425 return ss.str();
426 }
427
GetShaderHeader(const std::string & capabilities_and_extensions="",bool include_entry_point=true)428 std::string GetShaderHeader(const std::string& capabilities_and_extensions = "",
429 bool include_entry_point = true) {
430 std::ostringstream ss;
431 ss << R"(
432 OpCapability Shader
433 OpCapability Int64
434 )";
435
436 ss << capabilities_and_extensions;
437 if (!include_entry_point) {
438 ss << "OpCapability Linkage";
439 }
440
441 ss << R"(
442 OpMemoryModel Logical GLSL450
443 )";
444
445 if (include_entry_point) {
446 ss << "OpEntryPoint Fragment %main \"main\"\n";
447 ss << "OpExecutionMode %main OriginUpperLeft";
448 }
449 ss << R"(
450 %void = OpTypeVoid
451 %func = OpTypeFunction %void
452 %bool = OpTypeBool
453 %f32 = OpTypeFloat 32
454 %u32 = OpTypeInt 32 0
455 %u64 = OpTypeInt 64 0
456 %s32 = OpTypeInt 32 1
457 )";
458
459 return ss.str();
460 }
461
TEST_F(ValidateImage,TypeImageWrongSampledType)462 TEST_F(ValidateImage, TypeImageWrongSampledType) {
463 const std::string code = GetShaderHeader("", false) + R"(
464 %img_type = OpTypeImage %bool 2D 0 0 0 1 Unknown
465 )";
466
467 CompileSuccessfully(code.c_str());
468 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
469 EXPECT_THAT(getDiagnosticString(),
470 HasSubstr("Expected Sampled Type to be either void or "
471 "numerical scalar "
472 "type"));
473 }
474
TEST_F(ValidateImage,TypeImageVoidSampledTypeVulkan)475 TEST_F(ValidateImage, TypeImageVoidSampledTypeVulkan) {
476 const std::string code = GetShaderHeader() + R"(
477 %img_type = OpTypeImage %void 2D 0 0 0 1 Unknown
478 %void_func = OpTypeFunction %void
479 %main = OpFunction %void None %void_func
480 %main_lab = OpLabel
481 OpReturn
482 OpFunctionEnd
483 )";
484
485 const spv_target_env env = SPV_ENV_VULKAN_1_0;
486 CompileSuccessfully(code, env);
487 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
488 EXPECT_THAT(getDiagnosticString(),
489 HasSubstr("Expected Sampled Type to be a 32-bit int "
490 "or float scalar type for Vulkan environment"));
491 }
492
TEST_F(ValidateImage,TypeImageU64SampledTypeVulkan)493 TEST_F(ValidateImage, TypeImageU64SampledTypeVulkan) {
494 const std::string code = GetShaderHeader() + R"(
495 %img_type = OpTypeImage %u64 2D 0 0 0 1 Unknown
496 %void_func = OpTypeFunction %void
497 %main = OpFunction %void None %void_func
498 %main_lab = OpLabel
499 OpReturn
500 OpFunctionEnd
501 )";
502
503 const spv_target_env env = SPV_ENV_VULKAN_1_0;
504 CompileSuccessfully(code, env);
505 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
506 EXPECT_THAT(getDiagnosticString(),
507 HasSubstr("Expected Sampled Type to be a 32-bit int "
508 "or float scalar type for Vulkan environment"));
509 }
510
TEST_F(ValidateImage,TypeImageWrongDepth)511 TEST_F(ValidateImage, TypeImageWrongDepth) {
512 const std::string code = GetShaderHeader("", false) + R"(
513 %img_type = OpTypeImage %f32 2D 3 0 0 1 Unknown
514 )";
515
516 CompileSuccessfully(code.c_str());
517 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
518 EXPECT_THAT(getDiagnosticString(),
519 HasSubstr("Invalid Depth 3 (must be 0, 1 or 2)"));
520 }
521
TEST_F(ValidateImage,TypeImageWrongArrayed)522 TEST_F(ValidateImage, TypeImageWrongArrayed) {
523 const std::string code = GetShaderHeader("", false) + R"(
524 %img_type = OpTypeImage %f32 2D 0 2 0 1 Unknown
525 )";
526
527 CompileSuccessfully(code.c_str());
528 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
529 EXPECT_THAT(getDiagnosticString(),
530 HasSubstr("Invalid Arrayed 2 (must be 0 or 1)"));
531 }
532
TEST_F(ValidateImage,TypeImageWrongMS)533 TEST_F(ValidateImage, TypeImageWrongMS) {
534 const std::string code = GetShaderHeader("", false) + R"(
535 %img_type = OpTypeImage %f32 2D 0 0 2 1 Unknown
536 )";
537
538 CompileSuccessfully(code.c_str());
539 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
540 EXPECT_THAT(getDiagnosticString(),
541 HasSubstr("Invalid MS 2 (must be 0 or 1)"));
542 }
543
TEST_F(ValidateImage,TypeImageWrongSampled)544 TEST_F(ValidateImage, TypeImageWrongSampled) {
545 const std::string code = GetShaderHeader("", false) + R"(
546 %img_type = OpTypeImage %f32 2D 0 0 0 3 Unknown
547 )";
548
549 CompileSuccessfully(code.c_str());
550 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
551 EXPECT_THAT(getDiagnosticString(),
552 HasSubstr("Invalid Sampled 3 (must be 0, 1 or 2)"));
553 }
554
TEST_F(ValidateImage,TypeImageWrongSampledForSubpassData)555 TEST_F(ValidateImage, TypeImageWrongSampledForSubpassData) {
556 const std::string code =
557 GetShaderHeader("OpCapability InputAttachment\n", false) +
558 R"(
559 %img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
560 )";
561
562 CompileSuccessfully(code.c_str());
563 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
564 EXPECT_THAT(getDiagnosticString(),
565 HasSubstr("Dim SubpassData requires Sampled to be 2"));
566 }
567
TEST_F(ValidateImage,TypeImageWrongFormatForSubpassData)568 TEST_F(ValidateImage, TypeImageWrongFormatForSubpassData) {
569 const std::string code =
570 GetShaderHeader("OpCapability InputAttachment\n", false) +
571 R"(
572 %img_type = OpTypeImage %f32 SubpassData 0 0 0 2 Rgba32f
573 )";
574
575 CompileSuccessfully(code.c_str());
576 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
577 EXPECT_THAT(getDiagnosticString(),
578 HasSubstr("Dim SubpassData requires format Unknown"));
579 }
580
TEST_F(ValidateImage,TypeSampledImageNotImage)581 TEST_F(ValidateImage, TypeSampledImageNotImage) {
582 const std::string code = GetShaderHeader("", false) + R"(
583 %simg_type = OpTypeSampledImage %f32
584 )";
585
586 CompileSuccessfully(code.c_str());
587 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
588 EXPECT_THAT(getDiagnosticString(),
589 HasSubstr("Expected Image to be of type OpTypeImage"));
590 }
591
TEST_F(ValidateImage,SampledImageSuccess)592 TEST_F(ValidateImage, SampledImageSuccess) {
593 const std::string body = R"(
594 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
595 %sampler = OpLoad %type_sampler %uniform_sampler
596 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
597 )";
598
599 CompileSuccessfully(GenerateShaderCode(body).c_str());
600 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
601 }
602
TEST_F(ValidateImage,SampledImageVulkanSuccess)603 TEST_F(ValidateImage, SampledImageVulkanSuccess) {
604 const std::string body = R"(
605 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
606 %sampler = OpLoad %type_sampler %uniform_sampler
607 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
608 )";
609
610 const spv_target_env env = SPV_ENV_VULKAN_1_0;
611 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
612 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
613 }
614
TEST_F(ValidateImage,SampledImageWrongResultType)615 TEST_F(ValidateImage, SampledImageWrongResultType) {
616 const std::string body = R"(
617 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
618 %sampler = OpLoad %type_sampler %uniform_sampler
619 %simg = OpSampledImage %type_image_f32_2d_0001 %img %sampler
620 )";
621
622 CompileSuccessfully(GenerateShaderCode(body).c_str());
623 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
624 EXPECT_THAT(getDiagnosticString(),
625 HasSubstr("Expected Result Type to be OpTypeSampledImage"));
626 }
627
TEST_F(ValidateImage,SampledImageNotImage)628 TEST_F(ValidateImage, SampledImageNotImage) {
629 const std::string body = R"(
630 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
631 %sampler = OpLoad %type_sampler %uniform_sampler
632 %simg1 = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
633 %simg2 = OpSampledImage %type_sampled_image_f32_2d_0001 %simg1 %sampler
634 )";
635
636 CompileSuccessfully(GenerateShaderCode(body).c_str());
637 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
638 EXPECT_THAT(getDiagnosticString(),
639 HasSubstr("Expected Image to be of type OpTypeImage"));
640 }
641
TEST_F(ValidateImage,SampledImageImageNotForSampling)642 TEST_F(ValidateImage, SampledImageImageNotForSampling) {
643 const std::string body = R"(
644 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
645 %sampler = OpLoad %type_sampler %uniform_sampler
646 %simg = OpSampledImage %type_sampled_image_f32_2d_0002 %img %sampler
647 )";
648
649 CompileSuccessfully(GenerateShaderCode(body).c_str());
650 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
651 EXPECT_THAT(getDiagnosticString(),
652 HasSubstr("Expected Image 'Sampled' parameter to be 0 or 1"));
653 }
654
TEST_F(ValidateImage,SampledImageVulkanUnknownSampled)655 TEST_F(ValidateImage, SampledImageVulkanUnknownSampled) {
656 const std::string body = R"(
657 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
658 %sampler = OpLoad %type_sampler %uniform_sampler
659 %simg = OpSampledImage %type_sampled_image_u32_2d_0000 %img %sampler
660 )";
661
662 const spv_target_env env = SPV_ENV_VULKAN_1_0;
663 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
664 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
665 EXPECT_THAT(getDiagnosticString(),
666 HasSubstr("Expected Image 'Sampled' parameter to "
667 "be 1 for Vulkan environment."));
668 }
669
TEST_F(ValidateImage,SampledImageNotSampler)670 TEST_F(ValidateImage, SampledImageNotSampler) {
671 const std::string body = R"(
672 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
673 %sampler = OpLoad %type_sampler %uniform_sampler
674 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %img
675 )";
676
677 CompileSuccessfully(GenerateShaderCode(body).c_str());
678 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
679 EXPECT_THAT(getDiagnosticString(),
680 HasSubstr("Expected Sampler to be of type OpTypeSampler"));
681 }
682
TEST_F(ValidateImage,ImageTexelPointerSuccess)683 TEST_F(ValidateImage, ImageTexelPointerSuccess) {
684 const std::string body = R"(
685 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
686 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
687 )";
688
689 CompileSuccessfully(GenerateShaderCode(body).c_str());
690 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
691 }
692
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotPointer)693 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotPointer) {
694 const std::string body = R"(
695 %texel_ptr = OpImageTexelPointer %type_image_u32_buffer_0002_r32ui %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
696 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
697 )";
698
699 CompileSuccessfully(GenerateShaderCode(body).c_str());
700 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
701 EXPECT_THAT(getDiagnosticString(),
702 HasSubstr("Expected Result Type to be OpTypePointer"));
703 }
704
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotImageClass)705 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotImageClass) {
706 const std::string body = R"(
707 %texel_ptr = OpImageTexelPointer %ptr_image_f32_cube_0101 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
708 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
709 )";
710
711 CompileSuccessfully(GenerateShaderCode(body).c_str());
712 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
713 EXPECT_THAT(getDiagnosticString(),
714 HasSubstr("Expected Result Type to be OpTypePointer whose "
715 "Storage Class operand is Image"));
716 }
717
TEST_F(ValidateImage,ImageTexelPointerResultTypeNotNumericNorVoid)718 TEST_F(ValidateImage, ImageTexelPointerResultTypeNotNumericNorVoid) {
719 const std::string body = R"(
720 %texel_ptr = OpImageTexelPointer %ptr_Image_u32arr4 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0
721 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
722 )";
723
724 CompileSuccessfully(GenerateShaderCode(body).c_str());
725 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
726 EXPECT_THAT(
727 getDiagnosticString(),
728 HasSubstr("Expected Result Type to be OpTypePointer whose Type operand "
729 "must be a scalar numerical type or OpTypeVoid"));
730 }
731
TEST_F(ValidateImage,ImageTexelPointerImageNotResultTypePointer)732 TEST_F(ValidateImage, ImageTexelPointerImageNotResultTypePointer) {
733 const std::string body = R"(
734 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %type_image_f32_buffer_0002_r32ui %u32_0 %u32_0
735 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
736 )";
737
738 CompileSuccessfully(GenerateShaderCode(body).c_str());
739 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
740 EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 140[%140] cannot be a "
741 "type"));
742 }
743
TEST_F(ValidateImage,ImageTexelPointerImageNotImage)744 TEST_F(ValidateImage, ImageTexelPointerImageNotImage) {
745 const std::string body = R"(
746 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_sampler %u32_0 %u32_0
747 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
748 )";
749
750 CompileSuccessfully(GenerateShaderCode(body).c_str());
751 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
752 EXPECT_THAT(
753 getDiagnosticString(),
754 HasSubstr("Expected Image to be OpTypePointer with Type OpTypeImage"));
755 }
756
TEST_F(ValidateImage,ImageTexelPointerImageSampledNotResultType)757 TEST_F(ValidateImage, ImageTexelPointerImageSampledNotResultType) {
758 const std::string body = R"(
759 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_f32_cube_0101 %u32_0 %u32_0
760 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
761 )";
762
763 CompileSuccessfully(GenerateShaderCode(body).c_str());
764 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
765 EXPECT_THAT(getDiagnosticString(),
766 HasSubstr("Expected Image 'Sampled Type' to be the same as the "
767 "Type pointed to by Result Type"));
768 }
769
TEST_F(ValidateImage,ImageTexelPointerImageDimSubpassDataBad)770 TEST_F(ValidateImage, ImageTexelPointerImageDimSubpassDataBad) {
771 const std::string body = R"(
772 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_spd_0002 %u32_0 %u32_0
773 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
774 )";
775
776 CompileSuccessfully(GenerateShaderCode(body).c_str());
777 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
778 EXPECT_THAT(
779 getDiagnosticString(),
780 HasSubstr(
781 "Image Dim SubpassData cannot be used with OpImageTexelPointer"));
782 }
783
TEST_F(ValidateImage,ImageTexelPointerImageCoordTypeBad)784 TEST_F(ValidateImage, ImageTexelPointerImageCoordTypeBad) {
785 const std::string body = R"(
786 %texel_ptr = OpImageTexelPointer %ptr_Image_f32 %private_image_f32_buffer_0002_r32ui %f32_0 %f32_0
787 %sum = OpAtomicIAdd %f32 %texel_ptr %f32_1 %f32_0 %f32_1
788 )";
789
790 CompileSuccessfully(GenerateShaderCode(body).c_str());
791 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
792 EXPECT_THAT(getDiagnosticString(),
793 HasSubstr("Expected Coordinate to be integer scalar or vector"));
794 }
795
TEST_F(ValidateImage,ImageTexelPointerImageCoordSizeBad)796 TEST_F(ValidateImage, ImageTexelPointerImageCoordSizeBad) {
797 const std::string body = R"(
798 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %uniform_image_u32_2d_0000 %u32vec3_012 %u32_0
799 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
800 )";
801
802 CompileSuccessfully(GenerateShaderCode(body).c_str());
803 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
804 EXPECT_THAT(
805 getDiagnosticString(),
806 HasSubstr("Expected Coordinate to have 2 components, but given 3"));
807 }
808
TEST_F(ValidateImage,ImageTexelPointerSampleNotIntScalar)809 TEST_F(ValidateImage, ImageTexelPointerSampleNotIntScalar) {
810 const std::string body = R"(
811 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %f32_0
812 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
813 )";
814
815 CompileSuccessfully(GenerateShaderCode(body).c_str());
816 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
817 EXPECT_THAT(getDiagnosticString(),
818 HasSubstr("Expected Sample to be integer scalar"));
819 }
820
TEST_F(ValidateImage,ImageTexelPointerSampleNotZeroForImageWithMSZero)821 TEST_F(ValidateImage, ImageTexelPointerSampleNotZeroForImageWithMSZero) {
822 const std::string body = R"(
823 %texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_1
824 %sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1
825 )";
826
827 CompileSuccessfully(GenerateShaderCode(body).c_str());
828 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
829 EXPECT_THAT(getDiagnosticString(),
830 HasSubstr("Expected Sample for Image with MS 0 to be a valid "
831 "<id> for the value 0"));
832 }
833
TEST_F(ValidateImage,SampleImplicitLodSuccess)834 TEST_F(ValidateImage, SampleImplicitLodSuccess) {
835 const std::string body = R"(
836 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
837 %sampler = OpLoad %type_sampler %uniform_sampler
838 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
839 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
840 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0_25
841 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
842 %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
843 %res6 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
844 %res7 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
845 %res8 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
846 )";
847
848 const std::string extra = R"(
849 OpCapability VulkanMemoryModelKHR
850 OpExtension "SPV_KHR_vulkan_memory_model"
851 )";
852 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
853 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
854 .c_str());
855 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
856 }
857
TEST_F(ValidateImage,SampleImplicitLodWrongResultType)858 TEST_F(ValidateImage, SampleImplicitLodWrongResultType) {
859 const std::string body = R"(
860 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
861 %sampler = OpLoad %type_sampler %uniform_sampler
862 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
863 %res1 = OpImageSampleImplicitLod %f32 %simg %f32vec2_hh
864 )";
865
866 CompileSuccessfully(GenerateShaderCode(body).c_str());
867 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
868 EXPECT_THAT(getDiagnosticString(),
869 HasSubstr("Expected Result Type to be int or float vector type"));
870 }
871
TEST_F(ValidateImage,SampleImplicitLodWrongNumComponentsResultType)872 TEST_F(ValidateImage, SampleImplicitLodWrongNumComponentsResultType) {
873 const std::string body = R"(
874 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
875 %sampler = OpLoad %type_sampler %uniform_sampler
876 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
877 %res1 = OpImageSampleImplicitLod %f32vec3 %simg %f32vec2_hh
878 )";
879
880 CompileSuccessfully(GenerateShaderCode(body).c_str());
881 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
882 EXPECT_THAT(getDiagnosticString(),
883 HasSubstr("Expected Result Type to have 4 components"));
884 }
885
TEST_F(ValidateImage,SampleImplicitLodNotSampledImage)886 TEST_F(ValidateImage, SampleImplicitLodNotSampledImage) {
887 const std::string body = R"(
888 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
889 %res1 = OpImageSampleImplicitLod %f32vec4 %img %f32vec2_hh
890 )";
891
892 CompileSuccessfully(GenerateShaderCode(body).c_str());
893 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
894 EXPECT_THAT(
895 getDiagnosticString(),
896 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
897 }
898
TEST_F(ValidateImage,SampleImplicitLodWrongSampledType)899 TEST_F(ValidateImage, SampleImplicitLodWrongSampledType) {
900 const std::string body = R"(
901 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
902 %sampler = OpLoad %type_sampler %uniform_sampler
903 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
904 %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
905 )";
906
907 CompileSuccessfully(GenerateShaderCode(body).c_str());
908 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
909 EXPECT_THAT(getDiagnosticString(),
910 HasSubstr("Expected Image 'Sampled Type' to be the same as "
911 "Result Type components"));
912 }
913
TEST_F(ValidateImage,SampleImplicitLodVoidSampledType)914 TEST_F(ValidateImage, SampleImplicitLodVoidSampledType) {
915 const std::string body = R"(
916 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
917 %sampler = OpLoad %type_sampler %uniform_sampler
918 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
919 %res1 = OpImageSampleImplicitLod %u32vec4 %simg %f32vec2_00
920 )";
921
922 CompileSuccessfully(GenerateShaderCode(body).c_str());
923 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
924 }
925
TEST_F(ValidateImage,SampleImplicitLodWrongCoordinateType)926 TEST_F(ValidateImage, SampleImplicitLodWrongCoordinateType) {
927 const std::string body = R"(
928 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
929 %sampler = OpLoad %type_sampler %uniform_sampler
930 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
931 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %img
932 )";
933
934 CompileSuccessfully(GenerateShaderCode(body).c_str());
935 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
936 EXPECT_THAT(getDiagnosticString(),
937 HasSubstr("Expected Coordinate to be float scalar or vector"));
938 }
939
TEST_F(ValidateImage,SampleImplicitLodCoordinateSizeTooSmall)940 TEST_F(ValidateImage, SampleImplicitLodCoordinateSizeTooSmall) {
941 const std::string body = R"(
942 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
943 %sampler = OpLoad %type_sampler %uniform_sampler
944 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
945 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32_0_5
946 )";
947
948 CompileSuccessfully(GenerateShaderCode(body).c_str());
949 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
950 EXPECT_THAT(getDiagnosticString(),
951 HasSubstr("Expected Coordinate to have at least 2 components, "
952 "but given only 1"));
953 }
954
TEST_F(ValidateImage,SampleExplicitLodSuccessShader)955 TEST_F(ValidateImage, SampleExplicitLodSuccessShader) {
956 const std::string body = R"(
957 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
958 %sampler = OpLoad %type_sampler %uniform_sampler
959 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
960 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod %f32_1
961 %res2 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_10 %f32vec2_01
962 %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
963 %res4 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
964 %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset|MinLod %f32vec2_10 %f32vec2_01 %s32vec2_01 %f32_0_5
965 %res6 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Lod|NonPrivateTexelKHR %f32_1
966 )";
967
968 const std::string extra = R"(
969 OpCapability VulkanMemoryModelKHR
970 OpExtension "SPV_KHR_vulkan_memory_model"
971 )";
972 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
973 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
974 .c_str());
975 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
976 }
977
TEST_F(ValidateImage,SampleExplicitLodSuccessKernel)978 TEST_F(ValidateImage, SampleExplicitLodSuccessKernel) {
979 const std::string body = R"(
980 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
981 %sampler = OpLoad %type_sampler %uniform_sampler
982 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
983 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec4_0123 Lod %f32_1
984 %res2 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Grad %f32vec2_10 %f32vec2_01
985 %res3 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh ConstOffset %u32vec2_01
986 %res4 = OpImageSampleExplicitLod %f32vec4 %simg %u32vec2_01 Offset %u32vec2_01
987 %res5 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_hh Grad|Offset %f32vec2_10 %f32vec2_01 %u32vec2_01
988 )";
989
990 CompileSuccessfully(GenerateKernelCode(body).c_str());
991 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
992 }
993
TEST_F(ValidateImage,SampleExplicitLodSuccessCubeArrayed)994 TEST_F(ValidateImage, SampleExplicitLodSuccessCubeArrayed) {
995 const std::string body = R"(
996 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
997 %sampler = OpLoad %type_sampler %uniform_sampler
998 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
999 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec3_hhh
1000 )";
1001
1002 CompileSuccessfully(GenerateShaderCode(body).c_str());
1003 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1004 }
1005
TEST_F(ValidateImage,SampleExplicitLodWrongResultType)1006 TEST_F(ValidateImage, SampleExplicitLodWrongResultType) {
1007 const std::string body = R"(
1008 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1009 %sampler = OpLoad %type_sampler %uniform_sampler
1010 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1011 %res1 = OpImageSampleExplicitLod %f32 %simg %f32vec2_hh Lod %f32_1
1012 )";
1013
1014 CompileSuccessfully(GenerateShaderCode(body).c_str());
1015 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1016 EXPECT_THAT(getDiagnosticString(),
1017 HasSubstr("Expected Result Type to be int or float vector type"));
1018 }
1019
TEST_F(ValidateImage,SampleExplicitLodWrongNumComponentsResultType)1020 TEST_F(ValidateImage, SampleExplicitLodWrongNumComponentsResultType) {
1021 const std::string body = R"(
1022 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1023 %sampler = OpLoad %type_sampler %uniform_sampler
1024 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1025 %res1 = OpImageSampleExplicitLod %f32vec3 %simg %f32vec2_hh Lod %f32_1
1026 )";
1027
1028 CompileSuccessfully(GenerateShaderCode(body).c_str());
1029 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1030 EXPECT_THAT(getDiagnosticString(),
1031 HasSubstr("Expected Result Type to have 4 components"));
1032 }
1033
TEST_F(ValidateImage,SampleExplicitLodNotSampledImage)1034 TEST_F(ValidateImage, SampleExplicitLodNotSampledImage) {
1035 const std::string body = R"(
1036 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1037 %res1 = OpImageSampleExplicitLod %f32vec4 %img %f32vec2_hh Lod %f32_1
1038 )";
1039
1040 CompileSuccessfully(GenerateShaderCode(body).c_str());
1041 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1042 EXPECT_THAT(
1043 getDiagnosticString(),
1044 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1045 }
1046
TEST_F(ValidateImage,SampleExplicitLodWrongSampledType)1047 TEST_F(ValidateImage, SampleExplicitLodWrongSampledType) {
1048 const std::string body = R"(
1049 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1050 %sampler = OpLoad %type_sampler %uniform_sampler
1051 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1052 %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
1053 )";
1054
1055 CompileSuccessfully(GenerateShaderCode(body).c_str());
1056 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1057 EXPECT_THAT(getDiagnosticString(),
1058 HasSubstr("Expected Image 'Sampled Type' to be the same as "
1059 "Result Type components"));
1060 }
1061
TEST_F(ValidateImage,SampleExplicitLodVoidSampledType)1062 TEST_F(ValidateImage, SampleExplicitLodVoidSampledType) {
1063 const std::string body = R"(
1064 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1065 %sampler = OpLoad %type_sampler %uniform_sampler
1066 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1067 %res1 = OpImageSampleExplicitLod %u32vec4 %simg %f32vec2_00 Lod %f32_1
1068 )";
1069
1070 CompileSuccessfully(GenerateShaderCode(body).c_str());
1071 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1072 }
1073
TEST_F(ValidateImage,SampleExplicitLodWrongCoordinateType)1074 TEST_F(ValidateImage, SampleExplicitLodWrongCoordinateType) {
1075 const std::string body = R"(
1076 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1077 %sampler = OpLoad %type_sampler %uniform_sampler
1078 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1079 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %img Lod %f32_1
1080 )";
1081
1082 CompileSuccessfully(GenerateShaderCode(body).c_str());
1083 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1084 EXPECT_THAT(getDiagnosticString(),
1085 HasSubstr("Expected Coordinate to be float scalar or vector"));
1086 }
1087
TEST_F(ValidateImage,SampleExplicitLodCoordinateSizeTooSmall)1088 TEST_F(ValidateImage, SampleExplicitLodCoordinateSizeTooSmall) {
1089 const std::string body = R"(
1090 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1091 %sampler = OpLoad %type_sampler %uniform_sampler
1092 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1093 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32_0_5 Lod %f32_1
1094 )";
1095
1096 CompileSuccessfully(GenerateShaderCode(body).c_str());
1097 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1098 EXPECT_THAT(getDiagnosticString(),
1099 HasSubstr("Expected Coordinate to have at least 2 components, "
1100 "but given only 1"));
1101 }
1102
TEST_F(ValidateImage,SampleExplicitLodBias)1103 TEST_F(ValidateImage, SampleExplicitLodBias) {
1104 const std::string body = R"(
1105 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1106 %sampler = OpLoad %type_sampler %uniform_sampler
1107 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1108 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Bias|Lod %f32_1 %f32_1
1109 )";
1110
1111 CompileSuccessfully(GenerateShaderCode(body).c_str());
1112 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1113 EXPECT_THAT(
1114 getDiagnosticString(),
1115 HasSubstr(
1116 "Image Operand Bias can only be used with ImplicitLod opcodes"));
1117 }
1118
TEST_F(ValidateImage,LodAndGrad)1119 TEST_F(ValidateImage, LodAndGrad) {
1120 const std::string body = R"(
1121 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1122 %sampler = OpLoad %type_sampler %uniform_sampler
1123 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1124 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|Grad %f32_1 %f32vec2_hh %f32vec2_hh
1125 )";
1126
1127 CompileSuccessfully(GenerateShaderCode(body).c_str());
1128 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1129 EXPECT_THAT(
1130 getDiagnosticString(),
1131 HasSubstr(
1132 "Image Operand bits Lod and Grad cannot be set at the same time"));
1133 }
1134
TEST_F(ValidateImage,ImplicitLodWithLod)1135 TEST_F(ValidateImage, ImplicitLodWithLod) {
1136 const std::string body = R"(
1137 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1138 %sampler = OpLoad %type_sampler %uniform_sampler
1139 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1140 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_0_5
1141 )";
1142
1143 CompileSuccessfully(GenerateShaderCode(body).c_str());
1144 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1145 EXPECT_THAT(
1146 getDiagnosticString(),
1147 HasSubstr("Image Operand Lod can only be used with ExplicitLod opcodes "
1148 "and OpImageFetch"));
1149 }
1150
TEST_F(ValidateImage,LodWrongType)1151 TEST_F(ValidateImage, LodWrongType) {
1152 const std::string body = R"(
1153 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1154 %sampler = OpLoad %type_sampler %uniform_sampler
1155 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1156 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32vec2_hh)";
1157
1158 CompileSuccessfully(GenerateShaderCode(body).c_str());
1159 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1160 EXPECT_THAT(getDiagnosticString(),
1161 HasSubstr("Expected Image Operand Lod to be float scalar when "
1162 "used with ExplicitLod"));
1163 }
1164
TEST_F(ValidateImage,LodWrongDim)1165 TEST_F(ValidateImage, LodWrongDim) {
1166 const std::string body = R"(
1167 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1168 %sampler = OpLoad %type_sampler %uniform_sampler
1169 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1170 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32_0)";
1171
1172 CompileSuccessfully(GenerateShaderCode(body).c_str());
1173 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1174 EXPECT_THAT(getDiagnosticString(),
1175 HasSubstr("Image Operand Lod requires 'Dim' parameter to be 1D, "
1176 "2D, 3D or Cube"));
1177 }
1178
TEST_F(ValidateImage,LodMultisampled)1179 TEST_F(ValidateImage, LodMultisampled) {
1180 const std::string body = R"(
1181 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
1182 %sampler = OpLoad %type_sampler %uniform_sampler
1183 %simg = OpSampledImage %type_sampled_image_f32_2d_0010 %img %sampler
1184 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod %f32_0)";
1185
1186 CompileSuccessfully(GenerateShaderCode(body).c_str());
1187 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1188 EXPECT_THAT(getDiagnosticString(),
1189 HasSubstr("Image Operand Lod requires 'MS' parameter to be 0"));
1190 }
1191
TEST_F(ValidateImage,MinLodIncompatible)1192 TEST_F(ValidateImage, MinLodIncompatible) {
1193 const std::string body = R"(
1194 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1195 %sampler = OpLoad %type_sampler %uniform_sampler
1196 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1197 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Lod|MinLod %f32_0 %f32_0)";
1198
1199 CompileSuccessfully(GenerateShaderCode(body).c_str());
1200 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1201 EXPECT_THAT(
1202 getDiagnosticString(),
1203 HasSubstr(
1204 "Image Operand MinLod can only be used with ImplicitLod opcodes or "
1205 "together with Image Operand Grad"));
1206 }
1207
TEST_F(ValidateImage,ImplicitLodWithGrad)1208 TEST_F(ValidateImage, ImplicitLodWithGrad) {
1209 const std::string body = R"(
1210 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1211 %sampler = OpLoad %type_sampler %uniform_sampler
1212 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1213 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Grad %f32vec2_hh %f32vec2_hh
1214 )";
1215
1216 CompileSuccessfully(GenerateShaderCode(body).c_str());
1217 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1218 EXPECT_THAT(
1219 getDiagnosticString(),
1220 HasSubstr(
1221 "Image Operand Grad can only be used with ExplicitLod opcodes"));
1222 }
1223
TEST_F(ValidateImage,SampleImplicitLod3DArrayedMultisampledSuccess)1224 TEST_F(ValidateImage, SampleImplicitLod3DArrayedMultisampledSuccess) {
1225 const std::string body = R"(
1226 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1227 %sampler = OpLoad %type_sampler %uniform_sampler
1228 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1229 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000
1230 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec3_012
1231 %res3 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
1232 )";
1233
1234 CompileSuccessfully(GenerateShaderCode(body).c_str());
1235 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1236 }
1237
TEST_F(ValidateImage,SampleImplicitLodCubeArrayedSuccess)1238 TEST_F(ValidateImage, SampleImplicitLodCubeArrayedSuccess) {
1239 const std::string body = R"(
1240 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1241 %sampler = OpLoad %type_sampler %uniform_sampler
1242 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1243 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000
1244 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias %f32_0_25
1245 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %f32_0_5
1246 %res5 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias|MinLod %f32_0_25 %f32_0_5
1247 )";
1248
1249 CompileSuccessfully(GenerateShaderCode(body).c_str());
1250 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1251 }
1252
TEST_F(ValidateImage,SampleImplicitLodBiasWrongType)1253 TEST_F(ValidateImage, SampleImplicitLodBiasWrongType) {
1254 const std::string body = R"(
1255 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1256 %sampler = OpLoad %type_sampler %uniform_sampler
1257 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1258 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %u32_0
1259 )";
1260
1261 CompileSuccessfully(GenerateShaderCode(body).c_str());
1262 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1263 EXPECT_THAT(getDiagnosticString(),
1264 HasSubstr("Expected Image Operand Bias to be float scalar"));
1265 }
1266
TEST_F(ValidateImage,SampleImplicitLodBiasWrongDim)1267 TEST_F(ValidateImage, SampleImplicitLodBiasWrongDim) {
1268 const std::string body = R"(
1269 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1270 %sampler = OpLoad %type_sampler %uniform_sampler
1271 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1272 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh Bias %f32_0
1273 )";
1274
1275 CompileSuccessfully(GenerateShaderCode(body).c_str());
1276 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1277 EXPECT_THAT(getDiagnosticString(),
1278 HasSubstr("Image Operand Bias requires 'Dim' parameter to be 1D, "
1279 "2D, 3D or Cube"));
1280 }
1281
TEST_F(ValidateImage,SampleImplicitLodBiasMultisampled)1282 TEST_F(ValidateImage, SampleImplicitLodBiasMultisampled) {
1283 const std::string body = R"(
1284 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1285 %sampler = OpLoad %type_sampler %uniform_sampler
1286 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1287 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Bias %f32_0_25
1288 )";
1289
1290 CompileSuccessfully(GenerateShaderCode(body).c_str());
1291 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1292 EXPECT_THAT(getDiagnosticString(),
1293 HasSubstr("Image Operand Bias requires 'MS' parameter to be 0"));
1294 }
1295
TEST_F(ValidateImage,SampleExplicitLodGradDxWrongType)1296 TEST_F(ValidateImage, SampleExplicitLodGradDxWrongType) {
1297 const std::string body = R"(
1298 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1299 %sampler = OpLoad %type_sampler %uniform_sampler
1300 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1301 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %s32vec3_012 %f32vec3_hhh
1302 )";
1303
1304 CompileSuccessfully(GenerateShaderCode(body).c_str());
1305 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1306 EXPECT_THAT(getDiagnosticString(),
1307 HasSubstr("Expected both Image Operand Grad ids to be float "
1308 "scalars or vectors"));
1309 }
1310
TEST_F(ValidateImage,SampleExplicitLodGradDyWrongType)1311 TEST_F(ValidateImage, SampleExplicitLodGradDyWrongType) {
1312 const std::string body = R"(
1313 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1314 %sampler = OpLoad %type_sampler %uniform_sampler
1315 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1316 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %s32vec3_012
1317 )";
1318
1319 CompileSuccessfully(GenerateShaderCode(body).c_str());
1320 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1321 EXPECT_THAT(getDiagnosticString(),
1322 HasSubstr("Expected both Image Operand Grad ids to be float "
1323 "scalars or vectors"));
1324 }
1325
TEST_F(ValidateImage,SampleExplicitLodGradDxWrongSize)1326 TEST_F(ValidateImage, SampleExplicitLodGradDxWrongSize) {
1327 const std::string body = R"(
1328 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1329 %sampler = OpLoad %type_sampler %uniform_sampler
1330 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1331 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec2_00 %f32vec3_hhh
1332 )";
1333
1334 CompileSuccessfully(GenerateShaderCode(body).c_str());
1335 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1336 EXPECT_THAT(
1337 getDiagnosticString(),
1338 HasSubstr(
1339 "Expected Image Operand Grad dx to have 3 components, but given 2"));
1340 }
1341
TEST_F(ValidateImage,SampleExplicitLodGradDyWrongSize)1342 TEST_F(ValidateImage, SampleExplicitLodGradDyWrongSize) {
1343 const std::string body = R"(
1344 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1345 %sampler = OpLoad %type_sampler %uniform_sampler
1346 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1347 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_hhh %f32vec2_00
1348 )";
1349
1350 CompileSuccessfully(GenerateShaderCode(body).c_str());
1351 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1352 EXPECT_THAT(
1353 getDiagnosticString(),
1354 HasSubstr(
1355 "Expected Image Operand Grad dy to have 3 components, but given 2"));
1356 }
1357
TEST_F(ValidateImage,SampleExplicitLodGradMultisampled)1358 TEST_F(ValidateImage, SampleExplicitLodGradMultisampled) {
1359 const std::string body = R"(
1360 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1361 %sampler = OpLoad %type_sampler %uniform_sampler
1362 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1363 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec4_0000 Grad %f32vec3_000 %f32vec3_000
1364 )";
1365
1366 CompileSuccessfully(GenerateShaderCode(body).c_str());
1367 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1368 EXPECT_THAT(getDiagnosticString(),
1369 HasSubstr("Image Operand Grad requires 'MS' parameter to be 0"));
1370 }
1371
TEST_F(ValidateImage,SampleImplicitLodConstOffsetCubeDim)1372 TEST_F(ValidateImage, SampleImplicitLodConstOffsetCubeDim) {
1373 const std::string body = R"(
1374 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1375 %sampler = OpLoad %type_sampler %uniform_sampler
1376 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1377 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec3_012
1378 )";
1379
1380 CompileSuccessfully(GenerateShaderCode(body).c_str());
1381 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1382 EXPECT_THAT(
1383 getDiagnosticString(),
1384 HasSubstr(
1385 "Image Operand ConstOffset cannot be used with Cube Image 'Dim'"));
1386 }
1387
TEST_F(ValidateImage,SampleImplicitLodConstOffsetWrongType)1388 TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongType) {
1389 const std::string body = R"(
1390 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1391 %sampler = OpLoad %type_sampler %uniform_sampler
1392 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1393 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %f32vec3_000
1394 )";
1395
1396 CompileSuccessfully(GenerateShaderCode(body).c_str());
1397 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1398 EXPECT_THAT(
1399 getDiagnosticString(),
1400 HasSubstr(
1401 "Expected Image Operand ConstOffset to be int scalar or vector"));
1402 }
1403
TEST_F(ValidateImage,SampleImplicitLodConstOffsetWrongSize)1404 TEST_F(ValidateImage, SampleImplicitLodConstOffsetWrongSize) {
1405 const std::string body = R"(
1406 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1407 %sampler = OpLoad %type_sampler %uniform_sampler
1408 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1409 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %s32vec2_01
1410 )";
1411
1412 CompileSuccessfully(GenerateShaderCode(body).c_str());
1413 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1414 EXPECT_THAT(getDiagnosticString(),
1415 HasSubstr("Expected Image Operand ConstOffset to have 3 "
1416 "components, but given 2"));
1417 }
1418
TEST_F(ValidateImage,SampleImplicitLodConstOffsetNotConst)1419 TEST_F(ValidateImage, SampleImplicitLodConstOffsetNotConst) {
1420 const std::string body = R"(
1421 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1422 %sampler = OpLoad %type_sampler %uniform_sampler
1423 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1424 %offset = OpSNegate %s32vec3 %s32vec3_012
1425 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset %offset
1426 )";
1427
1428 CompileSuccessfully(GenerateShaderCode(body).c_str());
1429 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1430 EXPECT_THAT(
1431 getDiagnosticString(),
1432 HasSubstr("Expected Image Operand ConstOffset to be a const object"));
1433 }
1434
TEST_F(ValidateImage,SampleImplicitLodOffsetCubeDim)1435 TEST_F(ValidateImage, SampleImplicitLodOffsetCubeDim) {
1436 const std::string body = R"(
1437 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1438 %sampler = OpLoad %type_sampler %uniform_sampler
1439 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1440 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec3_012
1441 )";
1442
1443 CompileSuccessfully(GenerateShaderCode(body).c_str());
1444 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1445 EXPECT_THAT(
1446 getDiagnosticString(),
1447 HasSubstr("Image Operand Offset cannot be used with Cube Image 'Dim'"));
1448 }
1449
TEST_F(ValidateImage,SampleImplicitLodOffsetWrongType)1450 TEST_F(ValidateImage, SampleImplicitLodOffsetWrongType) {
1451 const std::string body = R"(
1452 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1453 %sampler = OpLoad %type_sampler %uniform_sampler
1454 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1455 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %f32vec3_000
1456 )";
1457
1458 CompileSuccessfully(GenerateShaderCode(body).c_str());
1459 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1460 EXPECT_THAT(
1461 getDiagnosticString(),
1462 HasSubstr("Expected Image Operand Offset to be int scalar or vector"));
1463 }
1464
TEST_F(ValidateImage,SampleImplicitLodOffsetWrongSize)1465 TEST_F(ValidateImage, SampleImplicitLodOffsetWrongSize) {
1466 const std::string body = R"(
1467 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1468 %sampler = OpLoad %type_sampler %uniform_sampler
1469 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1470 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
1471 )";
1472
1473 CompileSuccessfully(GenerateShaderCode(body).c_str());
1474 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1475 EXPECT_THAT(
1476 getDiagnosticString(),
1477 HasSubstr(
1478 "Expected Image Operand Offset to have 3 components, but given 2"));
1479 }
1480
TEST_F(ValidateImage,SampleImplicitLodMoreThanOneOffset)1481 TEST_F(ValidateImage, SampleImplicitLodMoreThanOneOffset) {
1482 const std::string body = R"(
1483 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1484 %sampler = OpLoad %type_sampler %uniform_sampler
1485 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1486 %res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 ConstOffset|Offset %s32vec3_012 %s32vec3_012
1487 )";
1488
1489 CompileSuccessfully(GenerateShaderCode(body).c_str());
1490 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1491 EXPECT_THAT(getDiagnosticString(),
1492 HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets "
1493 "cannot be used together"));
1494 }
1495
TEST_F(ValidateImage,SampleImplicitLodMinLodWrongType)1496 TEST_F(ValidateImage, SampleImplicitLodMinLodWrongType) {
1497 const std::string body = R"(
1498 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
1499 %sampler = OpLoad %type_sampler %uniform_sampler
1500 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
1501 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %s32_0
1502 )";
1503
1504 CompileSuccessfully(GenerateShaderCode(body).c_str());
1505 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1506 EXPECT_THAT(getDiagnosticString(),
1507 HasSubstr("Expected Image Operand MinLod to be float scalar"));
1508 }
1509
TEST_F(ValidateImage,SampleImplicitLodMinLodWrongDim)1510 TEST_F(ValidateImage, SampleImplicitLodMinLodWrongDim) {
1511 const std::string body = R"(
1512 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1513 %sampler = OpLoad %type_sampler %uniform_sampler
1514 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1515 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MinLod %f32_0_25
1516 )";
1517
1518 CompileSuccessfully(GenerateShaderCode(body).c_str());
1519 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1520 EXPECT_THAT(getDiagnosticString(),
1521 HasSubstr("Image Operand MinLod requires 'Dim' parameter to be "
1522 "1D, 2D, 3D or Cube"));
1523 }
1524
TEST_F(ValidateImage,SampleImplicitLodMinLodMultisampled)1525 TEST_F(ValidateImage, SampleImplicitLodMinLodMultisampled) {
1526 const std::string body = R"(
1527 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
1528 %sampler = OpLoad %type_sampler %uniform_sampler
1529 %simg = OpSampledImage %type_sampled_image_f32_3d_0111 %img %sampler
1530 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 MinLod %f32_0_25
1531 )";
1532
1533 CompileSuccessfully(GenerateShaderCode(body).c_str());
1534 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1535 EXPECT_THAT(
1536 getDiagnosticString(),
1537 HasSubstr("Image Operand MinLod requires 'MS' parameter to be 0"));
1538 }
1539
TEST_F(ValidateImage,SampleProjExplicitLodSuccess2D)1540 TEST_F(ValidateImage, SampleProjExplicitLodSuccess2D) {
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 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod %f32_1
1546 %res3 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
1547 %res4 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
1548 %res5 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
1549 %res7 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
1550 %res8 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Lod|NonPrivateTexelKHR %f32_1
1551 )";
1552
1553 const std::string extra = R"(
1554 OpCapability VulkanMemoryModelKHR
1555 OpExtension "SPV_KHR_vulkan_memory_model"
1556 )";
1557 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1558 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1559 .c_str());
1560 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1561 }
1562
TEST_F(ValidateImage,SampleProjExplicitLodSuccessRect)1563 TEST_F(ValidateImage, SampleProjExplicitLodSuccessRect) {
1564 const std::string body = R"(
1565 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
1566 %sampler = OpLoad %type_sampler %uniform_sampler
1567 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
1568 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad %f32vec2_10 %f32vec2_01
1569 %res2 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec3_hhh Grad|Offset %f32vec2_10 %f32vec2_01 %s32vec2_01
1570 )";
1571
1572 CompileSuccessfully(GenerateShaderCode(body).c_str());
1573 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1574 }
1575
TEST_F(ValidateImage,SampleProjExplicitLodWrongResultType)1576 TEST_F(ValidateImage, SampleProjExplicitLodWrongResultType) {
1577 const std::string body = R"(
1578 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1579 %sampler = OpLoad %type_sampler %uniform_sampler
1580 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1581 %res1 = OpImageSampleProjExplicitLod %f32 %simg %f32vec3_hhh Lod %f32_1
1582 )";
1583
1584 CompileSuccessfully(GenerateShaderCode(body).c_str());
1585 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1586 EXPECT_THAT(getDiagnosticString(),
1587 HasSubstr("Expected Result Type to be int or float vector type"));
1588 }
1589
TEST_F(ValidateImage,SampleProjExplicitLodWrongNumComponentsResultType)1590 TEST_F(ValidateImage, SampleProjExplicitLodWrongNumComponentsResultType) {
1591 const std::string body = R"(
1592 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1593 %sampler = OpLoad %type_sampler %uniform_sampler
1594 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1595 %res1 = OpImageSampleProjExplicitLod %f32vec3 %simg %f32vec3_hhh Lod %f32_1
1596 )";
1597
1598 CompileSuccessfully(GenerateShaderCode(body).c_str());
1599 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1600 EXPECT_THAT(getDiagnosticString(),
1601 HasSubstr("Expected Result Type to have 4 components"));
1602 }
1603
TEST_F(ValidateImage,SampleProjExplicitLodNotSampledImage)1604 TEST_F(ValidateImage, SampleProjExplicitLodNotSampledImage) {
1605 const std::string body = R"(
1606 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1607 %res1 = OpImageSampleProjExplicitLod %f32vec4 %img %f32vec3_hhh Lod %f32_1
1608 )";
1609
1610 CompileSuccessfully(GenerateShaderCode(body).c_str());
1611 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1612 EXPECT_THAT(
1613 getDiagnosticString(),
1614 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1615 }
1616
TEST_F(ValidateImage,SampleProjExplicitLodWrongSampledType)1617 TEST_F(ValidateImage, SampleProjExplicitLodWrongSampledType) {
1618 const std::string body = R"(
1619 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1620 %sampler = OpLoad %type_sampler %uniform_sampler
1621 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1622 %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
1623 )";
1624
1625 CompileSuccessfully(GenerateShaderCode(body).c_str());
1626 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1627 EXPECT_THAT(getDiagnosticString(),
1628 HasSubstr("Expected Image 'Sampled Type' to be the same as "
1629 "Result Type components"));
1630 }
1631
TEST_F(ValidateImage,SampleProjExplicitLodVoidSampledType)1632 TEST_F(ValidateImage, SampleProjExplicitLodVoidSampledType) {
1633 const std::string body = R"(
1634 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1635 %sampler = OpLoad %type_sampler %uniform_sampler
1636 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1637 %res1 = OpImageSampleProjExplicitLod %u32vec4 %simg %f32vec3_hhh Lod %f32_1
1638 )";
1639
1640 CompileSuccessfully(GenerateShaderCode(body).c_str());
1641 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1642 }
1643
TEST_F(ValidateImage,SampleProjExplicitLodWrongCoordinateType)1644 TEST_F(ValidateImage, SampleProjExplicitLodWrongCoordinateType) {
1645 const std::string body = R"(
1646 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1647 %sampler = OpLoad %type_sampler %uniform_sampler
1648 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1649 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %img Lod %f32_1
1650 )";
1651
1652 CompileSuccessfully(GenerateShaderCode(body).c_str());
1653 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1654 EXPECT_THAT(getDiagnosticString(),
1655 HasSubstr("Expected Coordinate to be float scalar or vector"));
1656 }
1657
TEST_F(ValidateImage,SampleProjExplicitLodCoordinateSizeTooSmall)1658 TEST_F(ValidateImage, SampleProjExplicitLodCoordinateSizeTooSmall) {
1659 const std::string body = R"(
1660 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1661 %sampler = OpLoad %type_sampler %uniform_sampler
1662 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1663 %res1 = OpImageSampleProjExplicitLod %f32vec4 %simg %f32vec2_hh Lod %f32_1
1664 )";
1665
1666 CompileSuccessfully(GenerateShaderCode(body).c_str());
1667 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1668 EXPECT_THAT(getDiagnosticString(),
1669 HasSubstr("Expected Coordinate to have at least 3 components, "
1670 "but given only 2"));
1671 }
1672
TEST_F(ValidateImage,SampleProjImplicitLodSuccess)1673 TEST_F(ValidateImage, SampleProjImplicitLodSuccess) {
1674 const std::string body = R"(
1675 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1676 %sampler = OpLoad %type_sampler %uniform_sampler
1677 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1678 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh
1679 %res2 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias %f32_0_25
1680 %res4 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh ConstOffset %s32vec2_01
1681 %res5 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Offset %s32vec2_01
1682 %res6 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh MinLod %f32_0_5
1683 %res7 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
1684 %res8 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec3_hhh NonPrivateTexelKHR
1685 )";
1686
1687 const std::string extra = R"(
1688 OpCapability VulkanMemoryModelKHR
1689 OpExtension "SPV_KHR_vulkan_memory_model"
1690 )";
1691 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1692 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1693 .c_str());
1694 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1695 }
1696
TEST_F(ValidateImage,SampleProjImplicitLodWrongResultType)1697 TEST_F(ValidateImage, SampleProjImplicitLodWrongResultType) {
1698 const std::string body = R"(
1699 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1700 %sampler = OpLoad %type_sampler %uniform_sampler
1701 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1702 %res1 = OpImageSampleProjImplicitLod %f32 %simg %f32vec3_hhh
1703 )";
1704
1705 CompileSuccessfully(GenerateShaderCode(body).c_str());
1706 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1707 EXPECT_THAT(getDiagnosticString(),
1708 HasSubstr("Expected Result Type to be int or float vector type"));
1709 }
1710
TEST_F(ValidateImage,SampleProjImplicitLodWrongNumComponentsResultType)1711 TEST_F(ValidateImage, SampleProjImplicitLodWrongNumComponentsResultType) {
1712 const std::string body = R"(
1713 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1714 %sampler = OpLoad %type_sampler %uniform_sampler
1715 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1716 %res1 = OpImageSampleProjImplicitLod %f32vec3 %simg %f32vec3_hhh
1717 )";
1718
1719 CompileSuccessfully(GenerateShaderCode(body).c_str());
1720 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1721 EXPECT_THAT(getDiagnosticString(),
1722 HasSubstr("Expected Result Type to have 4 components"));
1723 }
1724
TEST_F(ValidateImage,SampleProjImplicitLodNotSampledImage)1725 TEST_F(ValidateImage, SampleProjImplicitLodNotSampledImage) {
1726 const std::string body = R"(
1727 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1728 %res1 = OpImageSampleProjImplicitLod %f32vec4 %img %f32vec3_hhh
1729 )";
1730
1731 CompileSuccessfully(GenerateShaderCode(body).c_str());
1732 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1733 EXPECT_THAT(
1734 getDiagnosticString(),
1735 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1736 }
1737
TEST_F(ValidateImage,SampleProjImplicitLodWrongSampledType)1738 TEST_F(ValidateImage, SampleProjImplicitLodWrongSampledType) {
1739 const std::string body = R"(
1740 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1741 %sampler = OpLoad %type_sampler %uniform_sampler
1742 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1743 %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
1744 )";
1745
1746 CompileSuccessfully(GenerateShaderCode(body).c_str());
1747 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1748 EXPECT_THAT(getDiagnosticString(),
1749 HasSubstr("Expected Image 'Sampled Type' to be the same as "
1750 "Result Type components"));
1751 }
1752
TEST_F(ValidateImage,SampleProjImplicitLodVoidSampledType)1753 TEST_F(ValidateImage, SampleProjImplicitLodVoidSampledType) {
1754 const std::string body = R"(
1755 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1756 %sampler = OpLoad %type_sampler %uniform_sampler
1757 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1758 %res1 = OpImageSampleProjImplicitLod %u32vec4 %simg %f32vec3_hhh
1759 )";
1760
1761 CompileSuccessfully(GenerateShaderCode(body).c_str());
1762 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1763 }
1764
TEST_F(ValidateImage,SampleProjImplicitLodWrongCoordinateType)1765 TEST_F(ValidateImage, SampleProjImplicitLodWrongCoordinateType) {
1766 const std::string body = R"(
1767 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1768 %sampler = OpLoad %type_sampler %uniform_sampler
1769 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1770 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %img
1771 )";
1772
1773 CompileSuccessfully(GenerateShaderCode(body).c_str());
1774 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1775 EXPECT_THAT(getDiagnosticString(),
1776 HasSubstr("Expected Coordinate to be float scalar or vector"));
1777 }
1778
TEST_F(ValidateImage,SampleProjImplicitLodCoordinateSizeTooSmall)1779 TEST_F(ValidateImage, SampleProjImplicitLodCoordinateSizeTooSmall) {
1780 const std::string body = R"(
1781 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
1782 %sampler = OpLoad %type_sampler %uniform_sampler
1783 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
1784 %res1 = OpImageSampleProjImplicitLod %f32vec4 %simg %f32vec2_hh
1785 )";
1786
1787 CompileSuccessfully(GenerateShaderCode(body).c_str());
1788 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1789 EXPECT_THAT(getDiagnosticString(),
1790 HasSubstr("Expected Coordinate to have at least 3 components, "
1791 "but given only 2"));
1792 }
1793
TEST_F(ValidateImage,SampleDrefImplicitLodSuccess)1794 TEST_F(ValidateImage, SampleDrefImplicitLodSuccess) {
1795 const std::string body = R"(
1796 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
1797 %sampler = OpLoad %type_sampler %uniform_sampler
1798 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
1799 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1
1800 %res2 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
1801 %res4 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
1802 %res5 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
1803 %res6 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
1804 %res7 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
1805 %res8 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
1806 )";
1807
1808 const std::string extra = R"(
1809 OpCapability VulkanMemoryModelKHR
1810 OpExtension "SPV_KHR_vulkan_memory_model"
1811 )";
1812 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1813 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1814 .c_str());
1815 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1816 }
1817
TEST_F(ValidateImage,SampleDrefImplicitLodWrongResultType)1818 TEST_F(ValidateImage, SampleDrefImplicitLodWrongResultType) {
1819 const std::string body = R"(
1820 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1821 %sampler = OpLoad %type_sampler %uniform_sampler
1822 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1823 %res1 = OpImageSampleDrefImplicitLod %void %simg %f32vec2_hh %u32_1
1824 )";
1825
1826 CompileSuccessfully(GenerateShaderCode(body).c_str());
1827 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1828 EXPECT_THAT(getDiagnosticString(),
1829 HasSubstr("Expected Result Type to be int or float scalar type"));
1830 }
1831
TEST_F(ValidateImage,SampleDrefImplicitLodNotSampledImage)1832 TEST_F(ValidateImage, SampleDrefImplicitLodNotSampledImage) {
1833 const std::string body = R"(
1834 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
1835 %res1 = OpImageSampleDrefImplicitLod %u32 %img %f32vec2_hh %u32_1
1836 )";
1837
1838 CompileSuccessfully(GenerateShaderCode(body).c_str());
1839 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1840 EXPECT_THAT(
1841 getDiagnosticString(),
1842 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1843 }
1844
TEST_F(ValidateImage,SampleDrefImplicitLodWrongSampledType)1845 TEST_F(ValidateImage, SampleDrefImplicitLodWrongSampledType) {
1846 const std::string body = R"(
1847 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
1848 %sampler = OpLoad %type_sampler %uniform_sampler
1849 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
1850 %res1 = OpImageSampleDrefImplicitLod %f32 %simg %f32vec2_00 %u32_1
1851 )";
1852
1853 CompileSuccessfully(GenerateShaderCode(body).c_str());
1854 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1855 EXPECT_THAT(
1856 getDiagnosticString(),
1857 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
1858 }
1859
TEST_F(ValidateImage,SampleDrefImplicitLodVoidSampledType)1860 TEST_F(ValidateImage, SampleDrefImplicitLodVoidSampledType) {
1861 const std::string body = R"(
1862 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1863 %sampler = OpLoad %type_sampler %uniform_sampler
1864 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1865 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %u32_1
1866 )";
1867
1868 CompileSuccessfully(GenerateShaderCode(body).c_str());
1869 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1870 EXPECT_THAT(
1871 getDiagnosticString(),
1872 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
1873 }
1874
TEST_F(ValidateImage,SampleDrefImplicitLodWrongCoordinateType)1875 TEST_F(ValidateImage, SampleDrefImplicitLodWrongCoordinateType) {
1876 const std::string body = R"(
1877 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
1878 %sampler = OpLoad %type_sampler %uniform_sampler
1879 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
1880 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %img %u32_1
1881 )";
1882
1883 CompileSuccessfully(GenerateShaderCode(body).c_str());
1884 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1885 EXPECT_THAT(getDiagnosticString(),
1886 HasSubstr("Expected Coordinate to be float scalar or vector"));
1887 }
1888
TEST_F(ValidateImage,SampleDrefImplicitLodCoordinateSizeTooSmall)1889 TEST_F(ValidateImage, SampleDrefImplicitLodCoordinateSizeTooSmall) {
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 = OpImageSampleDrefImplicitLod %f32 %simg %f32_0_5 %f32_0_5
1895 )";
1896
1897 CompileSuccessfully(GenerateShaderCode(body).c_str());
1898 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1899 EXPECT_THAT(getDiagnosticString(),
1900 HasSubstr("Expected Coordinate to have at least 2 components, "
1901 "but given only 1"));
1902 }
1903
TEST_F(ValidateImage,SampleDrefImplicitLodWrongDrefType)1904 TEST_F(ValidateImage, SampleDrefImplicitLodWrongDrefType) {
1905 const std::string body = R"(
1906 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
1907 %sampler = OpLoad %type_sampler %uniform_sampler
1908 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
1909 %res1 = OpImageSampleDrefImplicitLod %u32 %simg %f32vec2_00 %f64_1
1910 )";
1911
1912 CompileSuccessfully(GenerateShaderCode(body).c_str());
1913 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1914 EXPECT_THAT(getDiagnosticString(),
1915 HasSubstr("Expected Dref to be of 32-bit float type"));
1916 }
1917
TEST_F(ValidateImage,SampleDrefExplicitLodSuccess)1918 TEST_F(ValidateImage, SampleDrefExplicitLodSuccess) {
1919 const std::string body = R"(
1920 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
1921 %sampler = OpLoad %type_sampler %uniform_sampler
1922 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
1923 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod %f32_1
1924 %res3 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad %f32vec3_hhh %f32vec3_hhh
1925 %res4 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 ConstOffset %s32vec3_012
1926 %res5 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Offset %s32vec3_012
1927 %res7 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %f32_1 Grad|Offset %f32vec3_hhh %f32vec3_hhh %s32vec3_012
1928 %res8 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec4_0000 %f32_1 Lod|NonPrivateTexelKHR %f32_1
1929 )";
1930
1931 const std::string extra = R"(
1932 OpCapability VulkanMemoryModelKHR
1933 OpExtension "SPV_KHR_vulkan_memory_model"
1934 )";
1935 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
1936 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
1937 .c_str());
1938 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1939 }
1940
TEST_F(ValidateImage,SampleDrefExplicitLodWrongResultType)1941 TEST_F(ValidateImage, SampleDrefExplicitLodWrongResultType) {
1942 const std::string body = R"(
1943 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
1944 %sampler = OpLoad %type_sampler %uniform_sampler
1945 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
1946 %res1 = OpImageSampleDrefExplicitLod %bool %simg %f32vec3_hhh %s32_1 Lod %f32_1
1947 )";
1948
1949 CompileSuccessfully(GenerateShaderCode(body).c_str());
1950 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1951 EXPECT_THAT(getDiagnosticString(),
1952 HasSubstr("Expected Result Type to be int or float scalar type"));
1953 }
1954
TEST_F(ValidateImage,SampleDrefExplicitLodNotSampledImage)1955 TEST_F(ValidateImage, SampleDrefExplicitLodNotSampledImage) {
1956 const std::string body = R"(
1957 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
1958 %res1 = OpImageSampleDrefExplicitLod %s32 %img %f32vec3_hhh %s32_1 Lod %f32_1
1959 )";
1960
1961 CompileSuccessfully(GenerateShaderCode(body).c_str());
1962 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1963 EXPECT_THAT(
1964 getDiagnosticString(),
1965 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
1966 }
1967
TEST_F(ValidateImage,SampleDrefExplicitLodWrongSampledType)1968 TEST_F(ValidateImage, SampleDrefExplicitLodWrongSampledType) {
1969 const std::string body = R"(
1970 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
1971 %sampler = OpLoad %type_sampler %uniform_sampler
1972 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
1973 %res1 = OpImageSampleDrefExplicitLod %f32 %simg %f32vec3_hhh %s32_1 Lod %f32_1
1974 )";
1975
1976 CompileSuccessfully(GenerateShaderCode(body).c_str());
1977 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1978 EXPECT_THAT(
1979 getDiagnosticString(),
1980 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
1981 }
1982
TEST_F(ValidateImage,SampleDrefExplicitLodVoidSampledType)1983 TEST_F(ValidateImage, SampleDrefExplicitLodVoidSampledType) {
1984 const std::string body = R"(
1985 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
1986 %sampler = OpLoad %type_sampler %uniform_sampler
1987 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
1988 %res1 = OpImageSampleDrefExplicitLod %u32 %simg %f32vec2_00 %s32_1 Lod %f32_1
1989 )";
1990
1991 CompileSuccessfully(GenerateShaderCode(body).c_str());
1992 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1993 EXPECT_THAT(
1994 getDiagnosticString(),
1995 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
1996 }
1997
TEST_F(ValidateImage,SampleDrefExplicitLodWrongCoordinateType)1998 TEST_F(ValidateImage, SampleDrefExplicitLodWrongCoordinateType) {
1999 const std::string body = R"(
2000 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2001 %sampler = OpLoad %type_sampler %uniform_sampler
2002 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2003 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %img %s32_1 Lod %f32_1
2004 )";
2005
2006 CompileSuccessfully(GenerateShaderCode(body).c_str());
2007 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2008 EXPECT_THAT(getDiagnosticString(),
2009 HasSubstr("Expected Coordinate to be float scalar or vector"));
2010 }
2011
TEST_F(ValidateImage,SampleDrefExplicitLodCoordinateSizeTooSmall)2012 TEST_F(ValidateImage, SampleDrefExplicitLodCoordinateSizeTooSmall) {
2013 const std::string body = R"(
2014 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2015 %sampler = OpLoad %type_sampler %uniform_sampler
2016 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2017 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec2_hh %s32_1 Lod %f32_1
2018 )";
2019
2020 CompileSuccessfully(GenerateShaderCode(body).c_str());
2021 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2022 EXPECT_THAT(getDiagnosticString(),
2023 HasSubstr("Expected Coordinate to have at least 3 components, "
2024 "but given only 2"));
2025 }
2026
TEST_F(ValidateImage,SampleDrefExplicitLodWrongDrefType)2027 TEST_F(ValidateImage, SampleDrefExplicitLodWrongDrefType) {
2028 const std::string body = R"(
2029 %img = OpLoad %type_image_s32_3d_0001 %uniform_image_s32_3d_0001
2030 %sampler = OpLoad %type_sampler %uniform_sampler
2031 %simg = OpSampledImage %type_sampled_image_s32_3d_0001 %img %sampler
2032 %res1 = OpImageSampleDrefExplicitLod %s32 %simg %f32vec3_hhh %u32_1 Lod %f32_1
2033 )";
2034
2035 CompileSuccessfully(GenerateShaderCode(body).c_str());
2036 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2037 EXPECT_THAT(getDiagnosticString(),
2038 HasSubstr("Expected Dref to be of 32-bit float type"));
2039 }
2040
TEST_F(ValidateImage,SampleProjDrefImplicitLodSuccess)2041 TEST_F(ValidateImage, SampleProjDrefImplicitLodSuccess) {
2042 const std::string body = R"(
2043 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2044 %sampler = OpLoad %type_sampler %uniform_sampler
2045 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2046 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5
2047 %res2 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias %f32_0_25
2048 %res4 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 ConstOffset %s32vec2_01
2049 %res5 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Offset %s32vec2_01
2050 %res6 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 MinLod %f32_0_5
2051 %res7 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
2052 %res8 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 NonPrivateTexelKHR
2053 )";
2054
2055 const std::string extra = R"(
2056 OpCapability VulkanMemoryModelKHR
2057 OpExtension "SPV_KHR_vulkan_memory_model"
2058 )";
2059 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2060 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2061 .c_str());
2062 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2063 }
2064
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongResultType)2065 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongResultType) {
2066 const std::string body = R"(
2067 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2068 %sampler = OpLoad %type_sampler %uniform_sampler
2069 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2070 %res1 = OpImageSampleProjDrefImplicitLod %void %simg %f32vec3_hhh %f32_0_5
2071 )";
2072
2073 CompileSuccessfully(GenerateShaderCode(body).c_str());
2074 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2075 EXPECT_THAT(getDiagnosticString(),
2076 HasSubstr("Expected Result Type to be int or float scalar type"));
2077 }
2078
TEST_F(ValidateImage,SampleProjDrefImplicitLodNotSampledImage)2079 TEST_F(ValidateImage, SampleProjDrefImplicitLodNotSampledImage) {
2080 const std::string body = R"(
2081 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2082 %res1 = OpImageSampleProjDrefImplicitLod %f32 %img %f32vec3_hhh %f32_0_5
2083 )";
2084
2085 CompileSuccessfully(GenerateShaderCode(body).c_str());
2086 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2087 EXPECT_THAT(
2088 getDiagnosticString(),
2089 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2090 }
2091
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongSampledType)2092 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongSampledType) {
2093 const std::string body = R"(
2094 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2095 %sampler = OpLoad %type_sampler %uniform_sampler
2096 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2097 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2098 )";
2099
2100 CompileSuccessfully(GenerateShaderCode(body).c_str());
2101 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2102 EXPECT_THAT(
2103 getDiagnosticString(),
2104 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2105 }
2106
TEST_F(ValidateImage,SampleProjDrefImplicitLodVoidSampledType)2107 TEST_F(ValidateImage, SampleProjDrefImplicitLodVoidSampledType) {
2108 const std::string body = R"(
2109 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2110 %sampler = OpLoad %type_sampler %uniform_sampler
2111 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2112 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32_0_5
2113 )";
2114
2115 CompileSuccessfully(GenerateShaderCode(body).c_str());
2116 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2117 EXPECT_THAT(
2118 getDiagnosticString(),
2119 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2120 }
2121
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongCoordinateType)2122 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongCoordinateType) {
2123 const std::string body = R"(
2124 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2125 %sampler = OpLoad %type_sampler %uniform_sampler
2126 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2127 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %img %f32_0_5
2128 )";
2129
2130 CompileSuccessfully(GenerateShaderCode(body).c_str());
2131 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2132 EXPECT_THAT(getDiagnosticString(),
2133 HasSubstr("Expected Coordinate to be float scalar or vector"));
2134 }
2135
TEST_F(ValidateImage,SampleProjDrefImplicitLodCoordinateSizeTooSmall)2136 TEST_F(ValidateImage, SampleProjDrefImplicitLodCoordinateSizeTooSmall) {
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 %res1 = OpImageSampleProjDrefImplicitLod %f32 %simg %f32vec2_hh %f32_0_5
2142 )";
2143
2144 CompileSuccessfully(GenerateShaderCode(body).c_str());
2145 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2146 EXPECT_THAT(getDiagnosticString(),
2147 HasSubstr("Expected Coordinate to have at least 3 components, "
2148 "but given only 2"));
2149 }
2150
TEST_F(ValidateImage,SampleProjDrefImplicitLodWrongDrefType)2151 TEST_F(ValidateImage, SampleProjDrefImplicitLodWrongDrefType) {
2152 const std::string body = R"(
2153 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
2154 %sampler = OpLoad %type_sampler %uniform_sampler
2155 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
2156 %res1 = OpImageSampleProjDrefImplicitLod %u32 %simg %f32vec3_hhh %f32vec4_0000
2157 )";
2158
2159 CompileSuccessfully(GenerateShaderCode(body).c_str());
2160 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2161 EXPECT_THAT(getDiagnosticString(),
2162 HasSubstr("Expected Dref to be of 32-bit float type"));
2163 }
2164
TEST_F(ValidateImage,SampleProjDrefExplicitLodSuccess)2165 TEST_F(ValidateImage, SampleProjDrefExplicitLodSuccess) {
2166 const std::string body = R"(
2167 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2168 %sampler = OpLoad %type_sampler %uniform_sampler
2169 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2170 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2171 %res2 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec3_hhh %f32_0_5 Grad %f32_0_5 %f32_0_5
2172 %res3 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 ConstOffset %s32_1
2173 %res4 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Offset %s32_1
2174 %res5 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Grad|Offset %f32_0_5 %f32_0_5 %s32_1
2175 %res6 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32vec2_hh %f32_0_5 Lod|NonPrivateTexelKHR %f32_1
2176 )";
2177
2178 const std::string extra = R"(
2179 OpCapability VulkanMemoryModelKHR
2180 OpExtension "SPV_KHR_vulkan_memory_model"
2181 )";
2182 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2183 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2184 .c_str());
2185 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2186 }
2187
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongResultType)2188 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongResultType) {
2189 const std::string body = R"(
2190 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2191 %sampler = OpLoad %type_sampler %uniform_sampler
2192 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2193 %res1 = OpImageSampleProjDrefExplicitLod %bool %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2194 )";
2195
2196 CompileSuccessfully(GenerateShaderCode(body).c_str());
2197 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2198 EXPECT_THAT(getDiagnosticString(),
2199 HasSubstr("Expected Result Type to be int or float scalar type"));
2200 }
2201
TEST_F(ValidateImage,SampleProjDrefExplicitLodNotSampledImage)2202 TEST_F(ValidateImage, SampleProjDrefExplicitLodNotSampledImage) {
2203 const std::string body = R"(
2204 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2205 %res1 = OpImageSampleProjDrefExplicitLod %f32 %img %f32vec2_hh %f32_0_5 Lod %f32_1
2206 )";
2207
2208 CompileSuccessfully(GenerateShaderCode(body).c_str());
2209 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2210 EXPECT_THAT(
2211 getDiagnosticString(),
2212 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2213 }
2214
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongSampledType)2215 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongSampledType) {
2216 const std::string body = R"(
2217 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2218 %sampler = OpLoad %type_sampler %uniform_sampler
2219 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2220 %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec2_hh %f32_0_5 Lod %f32_1
2221 )";
2222
2223 CompileSuccessfully(GenerateShaderCode(body).c_str());
2224 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2225 EXPECT_THAT(
2226 getDiagnosticString(),
2227 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2228 }
2229
TEST_F(ValidateImage,SampleProjDrefExplicitLodVoidSampledType)2230 TEST_F(ValidateImage, SampleProjDrefExplicitLodVoidSampledType) {
2231 const std::string body = R"(
2232 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2233 %sampler = OpLoad %type_sampler %uniform_sampler
2234 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2235 %res1 = OpImageSampleProjDrefExplicitLod %u32 %simg %f32vec3_hhh %f32_0_5 Lod %f32_1
2236 )";
2237
2238 CompileSuccessfully(GenerateShaderCode(body).c_str());
2239 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2240 EXPECT_THAT(
2241 getDiagnosticString(),
2242 HasSubstr("Expected Image 'Sampled Type' to be the same as Result Type"));
2243 }
2244
TEST_F(ValidateImage,SampleProjDrefExplicitLodWrongCoordinateType)2245 TEST_F(ValidateImage, SampleProjDrefExplicitLodWrongCoordinateType) {
2246 const std::string body = R"(
2247 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2248 %sampler = OpLoad %type_sampler %uniform_sampler
2249 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2250 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %img %f32_0_5 Lod %f32_1
2251 )";
2252
2253 CompileSuccessfully(GenerateShaderCode(body).c_str());
2254 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2255 EXPECT_THAT(getDiagnosticString(),
2256 HasSubstr("Expected Coordinate to be float scalar or vector"));
2257 }
2258
TEST_F(ValidateImage,SampleProjDrefExplicitLodCoordinateSizeTooSmall)2259 TEST_F(ValidateImage, SampleProjDrefExplicitLodCoordinateSizeTooSmall) {
2260 const std::string body = R"(
2261 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2262 %sampler = OpLoad %type_sampler %uniform_sampler
2263 %simg = OpSampledImage %type_sampled_image_f32_1d_0001 %img %sampler
2264 %res1 = OpImageSampleProjDrefExplicitLod %f32 %simg %f32_0_5 %f32_0_5 Lod %f32_1
2265 )";
2266
2267 CompileSuccessfully(GenerateShaderCode(body).c_str());
2268 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2269 EXPECT_THAT(getDiagnosticString(),
2270 HasSubstr("Expected Coordinate to have at least 2 components, "
2271 "but given only 1"));
2272 }
2273
TEST_F(ValidateImage,FetchSuccess)2274 TEST_F(ValidateImage, FetchSuccess) {
2275 const std::string body = R"(
2276 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
2277 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
2278 %res2 = OpImageFetch %f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
2279 )";
2280
2281 const std::string extra = R"(
2282 OpCapability VulkanMemoryModelKHR
2283 OpExtension "SPV_KHR_vulkan_memory_model"
2284 )";
2285 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2286 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2287 .c_str());
2288 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2289 }
2290
TEST_F(ValidateImage,FetchWrongResultType)2291 TEST_F(ValidateImage, FetchWrongResultType) {
2292 const std::string body = R"(
2293 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2294 %res1 = OpImageFetch %f32 %img %u32vec2_01
2295 )";
2296
2297 CompileSuccessfully(GenerateShaderCode(body).c_str());
2298 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2299 EXPECT_THAT(getDiagnosticString(),
2300 HasSubstr("Expected Result Type to be int or float vector type"));
2301 }
2302
TEST_F(ValidateImage,FetchWrongNumComponentsResultType)2303 TEST_F(ValidateImage, FetchWrongNumComponentsResultType) {
2304 const std::string body = R"(
2305 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2306 %res1 = OpImageFetch %f32vec3 %img %u32vec2_01
2307 )";
2308
2309 CompileSuccessfully(GenerateShaderCode(body).c_str());
2310 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2311 EXPECT_THAT(getDiagnosticString(),
2312 HasSubstr("Expected Result Type to have 4 components"));
2313 }
2314
TEST_F(ValidateImage,FetchNotImage)2315 TEST_F(ValidateImage, FetchNotImage) {
2316 const std::string body = R"(
2317 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2318 %sampler = OpLoad %type_sampler %uniform_sampler
2319 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2320 %res1 = OpImageFetch %f32vec4 %sampler %u32vec2_01
2321 )";
2322
2323 CompileSuccessfully(GenerateShaderCode(body).c_str());
2324 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2325 EXPECT_THAT(getDiagnosticString(),
2326 HasSubstr("Expected Image to be of type OpTypeImage"));
2327 }
2328
TEST_F(ValidateImage,FetchSampledImageDirectly)2329 TEST_F(ValidateImage, FetchSampledImageDirectly) {
2330 const std::string body = R"(
2331 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2332 %sampler = OpLoad %type_sampler %uniform_sampler
2333 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2334 %res1 = OpImageFetch %f32vec4 %simg %u32vec2_01
2335 )";
2336
2337 CompileSuccessfully(GenerateShaderCode(body).c_str());
2338 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
2339 EXPECT_THAT(getDiagnosticString(),
2340 HasSubstr("OpSampledImage instruction must not appear as operand "
2341 "for OpImageFetch"));
2342 }
2343
TEST_F(ValidateImage,FetchNotSampled)2344 TEST_F(ValidateImage, FetchNotSampled) {
2345 const std::string body = R"(
2346 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2347 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
2348 )";
2349
2350 CompileSuccessfully(GenerateShaderCode(body).c_str());
2351 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2352 EXPECT_THAT(getDiagnosticString(),
2353 HasSubstr("Expected Image 'Sampled' parameter to be 1"));
2354 }
2355
TEST_F(ValidateImage,FetchCube)2356 TEST_F(ValidateImage, FetchCube) {
2357 const std::string body = R"(
2358 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2359 %res1 = OpImageFetch %f32vec4 %img %u32vec3_012
2360 )";
2361
2362 CompileSuccessfully(GenerateShaderCode(body).c_str());
2363 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2364 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' cannot be Cube"));
2365 }
2366
TEST_F(ValidateImage,FetchWrongSampledType)2367 TEST_F(ValidateImage, FetchWrongSampledType) {
2368 const std::string body = R"(
2369 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2370 %res1 = OpImageFetch %u32vec4 %img %u32vec2_01
2371 )";
2372
2373 CompileSuccessfully(GenerateShaderCode(body).c_str());
2374 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2375 EXPECT_THAT(getDiagnosticString(),
2376 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2377 "Result Type components"));
2378 }
2379
TEST_F(ValidateImage,FetchVoidSampledType)2380 TEST_F(ValidateImage, FetchVoidSampledType) {
2381 const std::string body = R"(
2382 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2383 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01
2384 %res2 = OpImageFetch %u32vec4 %img %u32vec2_01
2385 %res3 = OpImageFetch %s32vec4 %img %u32vec2_01
2386 )";
2387
2388 CompileSuccessfully(GenerateShaderCode(body).c_str());
2389 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2390 }
2391
TEST_F(ValidateImage,FetchWrongCoordinateType)2392 TEST_F(ValidateImage, FetchWrongCoordinateType) {
2393 const std::string body = R"(
2394 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2395 %res1 = OpImageFetch %f32vec4 %img %f32vec2_00
2396 )";
2397
2398 CompileSuccessfully(GenerateShaderCode(body).c_str());
2399 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2400 EXPECT_THAT(getDiagnosticString(),
2401 HasSubstr("Expected Coordinate to be int scalar or vector"));
2402 }
2403
TEST_F(ValidateImage,FetchCoordinateSizeTooSmall)2404 TEST_F(ValidateImage, FetchCoordinateSizeTooSmall) {
2405 const std::string body = R"(
2406 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
2407 %res1 = OpImageFetch %f32vec4 %img %u32_1
2408 )";
2409
2410 CompileSuccessfully(GenerateShaderCode(body).c_str());
2411 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2412 EXPECT_THAT(getDiagnosticString(),
2413 HasSubstr("Expected Coordinate to have at least 2 components, "
2414 "but given only 1"));
2415 }
2416
TEST_F(ValidateImage,FetchLodNotInt)2417 TEST_F(ValidateImage, FetchLodNotInt) {
2418 const std::string body = R"(
2419 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2420 %res1 = OpImageFetch %f32vec4 %img %u32vec2_01 Lod %f32_1
2421 )";
2422
2423 CompileSuccessfully(GenerateShaderCode(body).c_str());
2424 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2425 EXPECT_THAT(getDiagnosticString(),
2426 HasSubstr("Expected Image Operand Lod to be int scalar when used "
2427 "with OpImageFetch"));
2428 }
2429
TEST_F(ValidateImage,GatherSuccess)2430 TEST_F(ValidateImage, GatherSuccess) {
2431 const std::string body = R"(
2432 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2433 %sampler = OpLoad %type_sampler %uniform_sampler
2434 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2435 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1
2436 %res2 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
2437 %res3 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
2438 )";
2439
2440 const std::string extra = R"(
2441 OpCapability VulkanMemoryModelKHR
2442 OpExtension "SPV_KHR_vulkan_memory_model"
2443 )";
2444 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2445 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2446 .c_str());
2447 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2448 }
2449
TEST_F(ValidateImage,GatherWrongResultType)2450 TEST_F(ValidateImage, GatherWrongResultType) {
2451 const std::string body = R"(
2452 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2453 %sampler = OpLoad %type_sampler %uniform_sampler
2454 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2455 %res1 = OpImageGather %f32 %simg %f32vec4_0000 %u32_1
2456 )";
2457
2458 CompileSuccessfully(GenerateShaderCode(body).c_str());
2459 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2460 EXPECT_THAT(getDiagnosticString(),
2461 HasSubstr("Expected Result Type to be int or float vector type"));
2462 }
2463
TEST_F(ValidateImage,GatherWrongNumComponentsResultType)2464 TEST_F(ValidateImage, GatherWrongNumComponentsResultType) {
2465 const std::string body = R"(
2466 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2467 %sampler = OpLoad %type_sampler %uniform_sampler
2468 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2469 %res1 = OpImageGather %f32vec3 %simg %f32vec4_0000 %u32_1
2470 )";
2471
2472 CompileSuccessfully(GenerateShaderCode(body).c_str());
2473 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2474 EXPECT_THAT(getDiagnosticString(),
2475 HasSubstr("Expected Result Type to have 4 components"));
2476 }
2477
TEST_F(ValidateImage,GatherNotSampledImage)2478 TEST_F(ValidateImage, GatherNotSampledImage) {
2479 const std::string body = R"(
2480 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2481 %res1 = OpImageGather %f32vec4 %img %f32vec4_0000 %u32_1
2482 )";
2483
2484 CompileSuccessfully(GenerateShaderCode(body).c_str());
2485 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2486 EXPECT_THAT(
2487 getDiagnosticString(),
2488 HasSubstr("Expected Sampled Image to be of type OpTypeSampledImage"));
2489 }
2490
TEST_F(ValidateImage,GatherWrongSampledType)2491 TEST_F(ValidateImage, GatherWrongSampledType) {
2492 const std::string body = R"(
2493 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2494 %sampler = OpLoad %type_sampler %uniform_sampler
2495 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2496 %res1 = OpImageGather %u32vec4 %simg %f32vec4_0000 %u32_1
2497 )";
2498
2499 CompileSuccessfully(GenerateShaderCode(body).c_str());
2500 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2501 EXPECT_THAT(getDiagnosticString(),
2502 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2503 "Result Type components"));
2504 }
2505
TEST_F(ValidateImage,GatherVoidSampledType)2506 TEST_F(ValidateImage, GatherVoidSampledType) {
2507 const std::string body = R"(
2508 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2509 %sampler = OpLoad %type_sampler %uniform_sampler
2510 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2511 %res1 = OpImageGather %u32vec4 %simg %f32vec2_00 %u32_1
2512 )";
2513
2514 CompileSuccessfully(GenerateShaderCode(body).c_str());
2515 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2516 }
2517
TEST_F(ValidateImage,GatherWrongCoordinateType)2518 TEST_F(ValidateImage, GatherWrongCoordinateType) {
2519 const std::string body = R"(
2520 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2521 %sampler = OpLoad %type_sampler %uniform_sampler
2522 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2523 %res1 = OpImageGather %f32vec4 %simg %u32vec4_0123 %u32_1
2524 )";
2525
2526 CompileSuccessfully(GenerateShaderCode(body).c_str());
2527 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2528 EXPECT_THAT(getDiagnosticString(),
2529 HasSubstr("Expected Coordinate to be float scalar or vector"));
2530 }
2531
TEST_F(ValidateImage,GatherCoordinateSizeTooSmall)2532 TEST_F(ValidateImage, GatherCoordinateSizeTooSmall) {
2533 const std::string body = R"(
2534 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2535 %sampler = OpLoad %type_sampler %uniform_sampler
2536 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2537 %res1 = OpImageGather %f32vec4 %simg %f32_0_5 %u32_1
2538 )";
2539
2540 CompileSuccessfully(GenerateShaderCode(body).c_str());
2541 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2542 EXPECT_THAT(getDiagnosticString(),
2543 HasSubstr("Expected Coordinate to have at least 4 components, "
2544 "but given only 1"));
2545 }
2546
TEST_F(ValidateImage,GatherWrongComponentType)2547 TEST_F(ValidateImage, GatherWrongComponentType) {
2548 const std::string body = R"(
2549 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2550 %sampler = OpLoad %type_sampler %uniform_sampler
2551 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2552 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %f32_1
2553 )";
2554
2555 CompileSuccessfully(GenerateShaderCode(body).c_str());
2556 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2557 EXPECT_THAT(getDiagnosticString(),
2558 HasSubstr("Expected Component to be 32-bit int scalar"));
2559 }
2560
TEST_F(ValidateImage,GatherComponentNot32Bit)2561 TEST_F(ValidateImage, GatherComponentNot32Bit) {
2562 const std::string body = R"(
2563 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2564 %sampler = OpLoad %type_sampler %uniform_sampler
2565 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2566 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u64_0
2567 )";
2568
2569 CompileSuccessfully(GenerateShaderCode(body).c_str());
2570 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2571 EXPECT_THAT(getDiagnosticString(),
2572 HasSubstr("Expected Component to be 32-bit int scalar"));
2573 }
2574
TEST_F(ValidateImage,GatherDimCube)2575 TEST_F(ValidateImage, GatherDimCube) {
2576 const std::string body = R"(
2577 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2578 %sampler = OpLoad %type_sampler %uniform_sampler
2579 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2580 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets
2581 )";
2582
2583 CompileSuccessfully(GenerateShaderCode(body).c_str());
2584 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2585 EXPECT_THAT(
2586 getDiagnosticString(),
2587 HasSubstr(
2588 "Image Operand ConstOffsets cannot be used with Cube Image 'Dim'"));
2589 }
2590
TEST_F(ValidateImage,GatherConstOffsetsNotArray)2591 TEST_F(ValidateImage, GatherConstOffsetsNotArray) {
2592 const std::string body = R"(
2593 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2594 %sampler = OpLoad %type_sampler %uniform_sampler
2595 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2596 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %u32vec4_0123
2597 )";
2598
2599 CompileSuccessfully(GenerateShaderCode(body).c_str());
2600 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2601 EXPECT_THAT(
2602 getDiagnosticString(),
2603 HasSubstr(
2604 "Expected Image Operand ConstOffsets to be an array of size 4"));
2605 }
2606
TEST_F(ValidateImage,GatherConstOffsetsArrayWrongSize)2607 TEST_F(ValidateImage, GatherConstOffsetsArrayWrongSize) {
2608 const std::string body = R"(
2609 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2610 %sampler = OpLoad %type_sampler %uniform_sampler
2611 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2612 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets3x2
2613 )";
2614
2615 CompileSuccessfully(GenerateShaderCode(body).c_str());
2616 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2617 EXPECT_THAT(
2618 getDiagnosticString(),
2619 HasSubstr(
2620 "Expected Image Operand ConstOffsets to be an array of size 4"));
2621 }
2622
TEST_F(ValidateImage,GatherConstOffsetsArrayNotVector)2623 TEST_F(ValidateImage, GatherConstOffsetsArrayNotVector) {
2624 const std::string body = R"(
2625 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2626 %sampler = OpLoad %type_sampler %uniform_sampler
2627 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2628 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4xu
2629 )";
2630
2631 CompileSuccessfully(GenerateShaderCode(body).c_str());
2632 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2633 EXPECT_THAT(getDiagnosticString(),
2634 HasSubstr("Expected Image Operand ConstOffsets array componenets "
2635 "to be int vectors of size 2"));
2636 }
2637
TEST_F(ValidateImage,GatherConstOffsetsArrayVectorWrongSize)2638 TEST_F(ValidateImage, GatherConstOffsetsArrayVectorWrongSize) {
2639 const std::string body = R"(
2640 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2641 %sampler = OpLoad %type_sampler %uniform_sampler
2642 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2643 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %const_offsets4x3
2644 )";
2645
2646 CompileSuccessfully(GenerateShaderCode(body).c_str());
2647 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2648 EXPECT_THAT(getDiagnosticString(),
2649 HasSubstr("Expected Image Operand ConstOffsets array componenets "
2650 "to be int vectors of size 2"));
2651 }
2652
TEST_F(ValidateImage,GatherConstOffsetsArrayNotConst)2653 TEST_F(ValidateImage, GatherConstOffsetsArrayNotConst) {
2654 const std::string body = R"(
2655 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2656 %sampler = OpLoad %type_sampler %uniform_sampler
2657 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2658 %offsets = OpUndef %u32vec2arr4
2659 %res1 = OpImageGather %f32vec4 %simg %f32vec4_0000 %u32_1 ConstOffsets %offsets
2660 )";
2661
2662 CompileSuccessfully(GenerateShaderCode(body).c_str());
2663 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2664 EXPECT_THAT(
2665 getDiagnosticString(),
2666 HasSubstr("Expected Image Operand ConstOffsets to be a const object"));
2667 }
2668
TEST_F(ValidateImage,NotGatherWithConstOffsets)2669 TEST_F(ValidateImage, NotGatherWithConstOffsets) {
2670 const std::string body = R"(
2671 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2672 %sampler = OpLoad %type_sampler %uniform_sampler
2673 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2674 %res2 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh ConstOffsets %const_offsets
2675 )";
2676
2677 CompileSuccessfully(GenerateShaderCode(body).c_str());
2678 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2679 EXPECT_THAT(
2680 getDiagnosticString(),
2681 HasSubstr(
2682 "Image Operand ConstOffsets can only be used with OpImageGather "
2683 "and OpImageDrefGather"));
2684 }
2685
TEST_F(ValidateImage,DrefGatherSuccess)2686 TEST_F(ValidateImage, DrefGatherSuccess) {
2687 const std::string body = R"(
2688 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2689 %sampler = OpLoad %type_sampler %uniform_sampler
2690 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
2691 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5
2692 %res2 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 ConstOffsets %const_offsets
2693 %res3 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %f32_0_5 NonPrivateTexelKHR
2694 )";
2695
2696 const std::string extra = R"(
2697 OpCapability VulkanMemoryModelKHR
2698 OpExtension "SPV_KHR_vulkan_memory_model"
2699 )";
2700 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
2701 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
2702 .c_str());
2703 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
2704 }
2705
TEST_F(ValidateImage,DrefGatherVoidSampledType)2706 TEST_F(ValidateImage, DrefGatherVoidSampledType) {
2707 const std::string body = R"(
2708 %img = OpLoad %type_image_void_2d_0001 %uniform_image_void_2d_0001
2709 %sampler = OpLoad %type_sampler %uniform_sampler
2710 %simg = OpSampledImage %type_sampled_image_void_2d_0001 %img %sampler
2711 %res1 = OpImageDrefGather %u32vec4 %simg %f32vec2_00 %f32_0_5
2712 )";
2713
2714 CompileSuccessfully(GenerateShaderCode(body).c_str());
2715 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2716 EXPECT_THAT(getDiagnosticString(),
2717 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2718 "Result Type components"));
2719 }
2720
TEST_F(ValidateImage,DrefGatherWrongDrefType)2721 TEST_F(ValidateImage, DrefGatherWrongDrefType) {
2722 const std::string body = R"(
2723 %img = OpLoad %type_image_f32_cube_0101 %uniform_image_f32_cube_0101
2724 %sampler = OpLoad %type_sampler %uniform_sampler
2725 %simg = OpSampledImage %type_sampled_image_f32_cube_0101 %img %sampler
2726 %res1 = OpImageDrefGather %f32vec4 %simg %f32vec4_0000 %u32_1
2727 )";
2728
2729 CompileSuccessfully(GenerateShaderCode(body).c_str());
2730 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2731 EXPECT_THAT(getDiagnosticString(),
2732 HasSubstr("Expected Dref to be of 32-bit float type"));
2733 }
2734
TEST_F(ValidateImage,ReadSuccess1)2735 TEST_F(ValidateImage, ReadSuccess1) {
2736 const std::string body = R"(
2737 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2738 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
2739 )";
2740
2741 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2742 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2743 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2744 }
2745
TEST_F(ValidateImage,ReadSuccess2)2746 TEST_F(ValidateImage, ReadSuccess2) {
2747 const std::string body = R"(
2748 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
2749 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2750 )";
2751
2752 const std::string extra = "\nOpCapability Image1D\n";
2753 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2754 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2755 }
2756
TEST_F(ValidateImage,ReadSuccess3)2757 TEST_F(ValidateImage, ReadSuccess3) {
2758 const std::string body = R"(
2759 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
2760 %res1 = OpImageRead %f32vec4 %img %u32vec3_012
2761 )";
2762
2763 const std::string extra = "\nOpCapability ImageCubeArray\n";
2764 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2765 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2766 }
2767
TEST_F(ValidateImage,ReadSuccess4)2768 TEST_F(ValidateImage, ReadSuccess4) {
2769 const std::string body = R"(
2770 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
2771 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2772 )";
2773
2774 CompileSuccessfully(GenerateShaderCode(body).c_str());
2775 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2776 }
2777
TEST_F(ValidateImage,ReadNeedCapabilityStorageImageReadWithoutFormat)2778 TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) {
2779 const std::string body = R"(
2780 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2781 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
2782 )";
2783
2784 CompileSuccessfully(GenerateShaderCode(body).c_str());
2785 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2786 }
2787
TEST_F(ValidateImage,ReadNeedCapabilityStorageImageReadWithoutFormatVulkan)2788 TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) {
2789 const std::string body = R"(
2790 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2791 %res1 = OpImageRead %u32vec4 %img %u32vec2_01
2792 )";
2793
2794 spv_target_env env = SPV_ENV_VULKAN_1_0;
2795 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
2796 env);
2797 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
2798 EXPECT_THAT(getDiagnosticString(),
2799 HasSubstr("Capability StorageImageReadWithoutFormat is required "
2800 "to read storage image"));
2801 }
2802
TEST_F(ValidateImage,ReadNeedCapabilityImage1D)2803 TEST_F(ValidateImage, ReadNeedCapabilityImage1D) {
2804 const std::string body = R"(
2805 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
2806 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2807 )";
2808
2809 CompileSuccessfully(GenerateShaderCode(body).c_str());
2810 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2811 EXPECT_THAT(
2812 getDiagnosticString(),
2813 HasSubstr("Capability Image1D is required to access storage image"));
2814 }
2815
TEST_F(ValidateImage,ReadNeedCapabilityImageCubeArray)2816 TEST_F(ValidateImage, ReadNeedCapabilityImageCubeArray) {
2817 const std::string body = R"(
2818 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
2819 %res1 = OpImageRead %f32vec4 %img %u32vec3_012
2820 )";
2821
2822 CompileSuccessfully(GenerateShaderCode(body).c_str());
2823 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2824 EXPECT_THAT(
2825 getDiagnosticString(),
2826 HasSubstr(
2827 "Capability ImageCubeArray is required to access storage image"));
2828 }
2829
2830 // TODO(atgoo@github.com) Disabled until the spec is clarified.
TEST_F(ValidateImage,DISABLED_ReadWrongResultType)2831 TEST_F(ValidateImage, DISABLED_ReadWrongResultType) {
2832 const std::string body = R"(
2833 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2834 %res1 = OpImageRead %f32 %img %u32vec2_01
2835 )";
2836
2837 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2838 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2839 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2840 EXPECT_THAT(getDiagnosticString(),
2841 HasSubstr("Expected Result Type to be int or float vector type"));
2842 }
2843
2844 // TODO(atgoo@github.com) Disabled until the spec is clarified.
TEST_F(ValidateImage,DISABLED_ReadWrongNumComponentsResultType)2845 TEST_F(ValidateImage, DISABLED_ReadWrongNumComponentsResultType) {
2846 const std::string body = R"(
2847 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2848 %res1 = OpImageRead %f32vec3 %img %u32vec2_01
2849 )";
2850
2851 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2852 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2853 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2854 EXPECT_THAT(getDiagnosticString(),
2855 HasSubstr("Expected Result Type to have 4 components"));
2856 }
2857
TEST_F(ValidateImage,ReadNotImage)2858 TEST_F(ValidateImage, ReadNotImage) {
2859 const std::string body = R"(
2860 %sampler = OpLoad %type_sampler %uniform_sampler
2861 %res1 = OpImageRead %f32vec4 %sampler %u32vec2_01
2862 )";
2863
2864 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2865 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2866 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2867 EXPECT_THAT(getDiagnosticString(),
2868 HasSubstr("Expected Image to be of type OpTypeImage"));
2869 }
2870
TEST_F(ValidateImage,ReadImageSampled)2871 TEST_F(ValidateImage, ReadImageSampled) {
2872 const std::string body = R"(
2873 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
2874 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2875 )";
2876
2877 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2878 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2879 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2880 EXPECT_THAT(getDiagnosticString(),
2881 HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
2882 }
2883
TEST_F(ValidateImage,ReadWrongSampledType)2884 TEST_F(ValidateImage, ReadWrongSampledType) {
2885 const std::string body = R"(
2886 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2887 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2888 )";
2889
2890 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2891 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2892 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2893 EXPECT_THAT(getDiagnosticString(),
2894 HasSubstr("Expected Image 'Sampled Type' to be the same as "
2895 "Result Type components"));
2896 }
2897
TEST_F(ValidateImage,ReadVoidSampledType)2898 TEST_F(ValidateImage, ReadVoidSampledType) {
2899 const std::string body = R"(
2900 %img = OpLoad %type_image_void_2d_0002 %uniform_image_void_2d_0002
2901 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
2902 %res2 = OpImageRead %u32vec4 %img %u32vec2_01
2903 %res3 = OpImageRead %s32vec4 %img %u32vec2_01
2904 )";
2905
2906 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2907 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2908 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2909 }
2910
TEST_F(ValidateImage,ReadWrongCoordinateType)2911 TEST_F(ValidateImage, ReadWrongCoordinateType) {
2912 const std::string body = R"(
2913 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2914 %res1 = OpImageRead %u32vec4 %img %f32vec2_00
2915 )";
2916
2917 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2918 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2919 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2920 EXPECT_THAT(getDiagnosticString(),
2921 HasSubstr("Expected Coordinate to be int scalar or vector"));
2922 }
2923
TEST_F(ValidateImage,ReadCoordinateSizeTooSmall)2924 TEST_F(ValidateImage, ReadCoordinateSizeTooSmall) {
2925 const std::string body = R"(
2926 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2927 %res1 = OpImageRead %u32vec4 %img %u32_1
2928 )";
2929
2930 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
2931 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2932 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2933 EXPECT_THAT(getDiagnosticString(),
2934 HasSubstr("Expected Coordinate to have at least 2 components, "
2935 "but given only 1"));
2936 }
2937
TEST_F(ValidateImage,WriteSuccess1)2938 TEST_F(ValidateImage, WriteSuccess1) {
2939 const std::string body = R"(
2940 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2941 OpImageWrite %img %u32vec2_01 %u32vec4_0123
2942 )";
2943
2944 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
2945 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2946 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2947 }
2948
TEST_F(ValidateImage,WriteSuccess2)2949 TEST_F(ValidateImage, WriteSuccess2) {
2950 const std::string body = R"(
2951 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
2952 OpImageWrite %img %u32_1 %f32vec4_0000
2953 )";
2954
2955 const std::string extra = "\nOpCapability Image1D\n";
2956 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2957 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2958 }
2959
TEST_F(ValidateImage,WriteSuccess3)2960 TEST_F(ValidateImage, WriteSuccess3) {
2961 const std::string body = R"(
2962 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
2963 OpImageWrite %img %u32vec3_012 %f32vec4_0000
2964 )";
2965
2966 const std::string extra = "\nOpCapability ImageCubeArray\n";
2967 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2968 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2969 }
2970
TEST_F(ValidateImage,WriteSuccess4)2971 TEST_F(ValidateImage, WriteSuccess4) {
2972 const std::string body = R"(
2973 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
2974 ;TODO(atgoo@github.com) Is it legal to write to MS image without sample index?
2975 OpImageWrite %img %u32vec2_01 %f32vec4_0000
2976 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
2977 )";
2978
2979 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
2980 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
2981 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2982 }
2983
TEST_F(ValidateImage,WriteSubpassData)2984 TEST_F(ValidateImage, WriteSubpassData) {
2985 const std::string body = R"(
2986 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
2987 OpImageWrite %img %u32vec2_01 %f32vec4_0000
2988 )";
2989
2990 CompileSuccessfully(GenerateShaderCode(body).c_str());
2991 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2992 EXPECT_THAT(getDiagnosticString(),
2993 HasSubstr("Image 'Dim' cannot be SubpassData"));
2994 }
2995
TEST_F(ValidateImage,WriteNeedCapabilityStorageImageWriteWithoutFormat)2996 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
2997 const std::string body = R"(
2998 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
2999 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3000 )";
3001
3002 CompileSuccessfully(GenerateShaderCode(body).c_str());
3003 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3004 }
3005
TEST_F(ValidateImage,WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan)3006 TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
3007 const std::string body = R"(
3008 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3009 OpImageWrite %img %u32vec2_01 %u32vec4_0123
3010 )";
3011
3012 spv_target_env env = SPV_ENV_VULKAN_1_0;
3013 CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
3014 env);
3015 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
3016 EXPECT_THAT(
3017 getDiagnosticString(),
3018 HasSubstr(
3019 "Capability StorageImageWriteWithoutFormat is required to write to "
3020 "storage image"));
3021 }
3022
TEST_F(ValidateImage,WriteNeedCapabilityImage1D)3023 TEST_F(ValidateImage, WriteNeedCapabilityImage1D) {
3024 const std::string body = R"(
3025 %img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
3026 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3027 )";
3028
3029 CompileSuccessfully(GenerateShaderCode(body).c_str());
3030 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3031 EXPECT_THAT(getDiagnosticString(),
3032 HasSubstr("Capability Image1D is required to access storage "
3033 "image"));
3034 }
3035
TEST_F(ValidateImage,WriteNeedCapabilityImageCubeArray)3036 TEST_F(ValidateImage, WriteNeedCapabilityImageCubeArray) {
3037 const std::string body = R"(
3038 %img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
3039 OpImageWrite %img %u32vec3_012 %f32vec4_0000
3040 )";
3041
3042 CompileSuccessfully(GenerateShaderCode(body).c_str());
3043 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3044 EXPECT_THAT(
3045 getDiagnosticString(),
3046 HasSubstr(
3047 "Capability ImageCubeArray is required to access storage image"));
3048 }
3049
TEST_F(ValidateImage,WriteNotImage)3050 TEST_F(ValidateImage, WriteNotImage) {
3051 const std::string body = R"(
3052 %sampler = OpLoad %type_sampler %uniform_sampler
3053 OpImageWrite %sampler %u32vec2_01 %f32vec4_0000
3054 )";
3055
3056 CompileSuccessfully(GenerateShaderCode(body).c_str());
3057 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3058 EXPECT_THAT(getDiagnosticString(),
3059 HasSubstr("Expected Image to be of type OpTypeImage"));
3060 }
3061
TEST_F(ValidateImage,WriteImageSampled)3062 TEST_F(ValidateImage, WriteImageSampled) {
3063 const std::string body = R"(
3064 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3065 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3066 )";
3067
3068 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3069 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3070 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3071 EXPECT_THAT(getDiagnosticString(),
3072 HasSubstr("Expected Image 'Sampled' parameter to be 0 or 2"));
3073 }
3074
TEST_F(ValidateImage,WriteWrongCoordinateType)3075 TEST_F(ValidateImage, WriteWrongCoordinateType) {
3076 const std::string body = R"(
3077 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3078 OpImageWrite %img %f32vec2_00 %u32vec4_0123
3079 )";
3080
3081 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3082 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3083 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3084 EXPECT_THAT(getDiagnosticString(),
3085 HasSubstr("Expected Coordinate to be int scalar or vector"));
3086 }
3087
TEST_F(ValidateImage,WriteCoordinateSizeTooSmall)3088 TEST_F(ValidateImage, WriteCoordinateSizeTooSmall) {
3089 const std::string body = R"(
3090 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3091 OpImageWrite %img %u32_1 %u32vec4_0123
3092 )";
3093
3094 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3095 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3096 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3097 EXPECT_THAT(getDiagnosticString(),
3098 HasSubstr("Expected Coordinate to have at least 2 components, "
3099 "but given only 1"));
3100 }
3101
TEST_F(ValidateImage,WriteTexelWrongType)3102 TEST_F(ValidateImage, WriteTexelWrongType) {
3103 const std::string body = R"(
3104 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3105 OpImageWrite %img %u32vec2_01 %img
3106 )";
3107
3108 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3109 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3110 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3111 EXPECT_THAT(getDiagnosticString(),
3112 HasSubstr("Expected Texel to be int or float vector or scalar"));
3113 }
3114
TEST_F(ValidateImage,DISABLED_WriteTexelNotVector4)3115 TEST_F(ValidateImage, DISABLED_WriteTexelNotVector4) {
3116 const std::string body = R"(
3117 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3118 OpImageWrite %img %u32vec2_01 %u32vec3_012
3119 )";
3120
3121 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3122 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3123 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3124 EXPECT_THAT(getDiagnosticString(),
3125 HasSubstr("Expected Texel to have 4 components"));
3126 }
3127
TEST_F(ValidateImage,WriteTexelWrongComponentType)3128 TEST_F(ValidateImage, WriteTexelWrongComponentType) {
3129 const std::string body = R"(
3130 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
3131 OpImageWrite %img %u32vec2_01 %f32vec4_0000
3132 )";
3133
3134 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3135 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3136 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3137 EXPECT_THAT(
3138 getDiagnosticString(),
3139 HasSubstr(
3140 "Expected Image 'Sampled Type' to be the same as Texel components"));
3141 }
3142
TEST_F(ValidateImage,WriteSampleNotInteger)3143 TEST_F(ValidateImage, WriteSampleNotInteger) {
3144 const std::string body = R"(
3145 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3146 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1
3147 )";
3148
3149 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3150 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3151 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3152 EXPECT_THAT(getDiagnosticString(),
3153 HasSubstr("Expected Image Operand Sample to be int scalar"));
3154 }
3155
TEST_F(ValidateImage,SampleNotMultisampled)3156 TEST_F(ValidateImage, SampleNotMultisampled) {
3157 const std::string body = R"(
3158 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
3159 OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
3160 )";
3161
3162 const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
3163 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
3164 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3165 EXPECT_THAT(
3166 getDiagnosticString(),
3167 HasSubstr("Image Operand Sample requires non-zero 'MS' parameter"));
3168 }
3169
TEST_F(ValidateImage,SampleWrongOpcode)3170 TEST_F(ValidateImage, SampleWrongOpcode) {
3171 const std::string body = R"(
3172 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3173 %sampler = OpLoad %type_sampler %uniform_sampler
3174 %simg = OpSampledImage %type_sampled_image_f32_2d_0010 %img %sampler
3175 %res1 = OpImageSampleExplicitLod %f32vec4 %simg %f32vec2_00 Sample %u32_1
3176 )";
3177
3178 CompileSuccessfully(GenerateShaderCode(body).c_str());
3179 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3180 EXPECT_THAT(getDiagnosticString(),
3181 HasSubstr("Image Operand Sample can only be used with "
3182 "OpImageFetch, OpImageRead, OpImageWrite, "
3183 "OpImageSparseFetch and OpImageSparseRead"));
3184 }
3185
TEST_F(ValidateImage,SampleImageToImageSuccess)3186 TEST_F(ValidateImage, SampleImageToImageSuccess) {
3187 const std::string body = R"(
3188 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3189 %sampler = OpLoad %type_sampler %uniform_sampler
3190 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3191 %img2 = OpImage %type_image_f32_2d_0001 %simg
3192 )";
3193
3194 CompileSuccessfully(GenerateShaderCode(body).c_str());
3195 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3196 }
3197
TEST_F(ValidateImage,SampleImageToImageWrongResultType)3198 TEST_F(ValidateImage, SampleImageToImageWrongResultType) {
3199 const std::string body = R"(
3200 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3201 %sampler = OpLoad %type_sampler %uniform_sampler
3202 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3203 %img2 = OpImage %type_sampled_image_f32_2d_0001 %simg
3204 )";
3205
3206 CompileSuccessfully(GenerateShaderCode(body).c_str());
3207 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3208 EXPECT_THAT(getDiagnosticString(),
3209 HasSubstr("Expected Result Type to be OpTypeImage"));
3210 }
3211
TEST_F(ValidateImage,SampleImageToImageNotSampledImage)3212 TEST_F(ValidateImage, SampleImageToImageNotSampledImage) {
3213 const std::string body = R"(
3214 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3215 %img2 = OpImage %type_image_f32_2d_0001 %img
3216 )";
3217
3218 CompileSuccessfully(GenerateShaderCode(body).c_str());
3219 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3220 EXPECT_THAT(
3221 getDiagnosticString(),
3222 HasSubstr("Expected Sample Image to be of type OpTypeSampleImage"));
3223 }
3224
TEST_F(ValidateImage,SampleImageToImageNotTheSameImageType)3225 TEST_F(ValidateImage, SampleImageToImageNotTheSameImageType) {
3226 const std::string body = R"(
3227 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3228 %sampler = OpLoad %type_sampler %uniform_sampler
3229 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3230 %img2 = OpImage %type_image_f32_2d_0002 %simg
3231 )";
3232
3233 CompileSuccessfully(GenerateShaderCode(body).c_str());
3234 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3235 EXPECT_THAT(getDiagnosticString(),
3236 HasSubstr("Expected Sample Image image type to be equal to "
3237 "Result Type"));
3238 }
3239
TEST_F(ValidateImage,QueryFormatSuccess)3240 TEST_F(ValidateImage, QueryFormatSuccess) {
3241 const std::string body = R"(
3242 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3243 %res1 = OpImageQueryFormat %u32 %img
3244 )";
3245
3246 CompileSuccessfully(GenerateKernelCode(body).c_str());
3247 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3248 }
3249
TEST_F(ValidateImage,QueryFormatWrongResultType)3250 TEST_F(ValidateImage, QueryFormatWrongResultType) {
3251 const std::string body = R"(
3252 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3253 %res1 = OpImageQueryFormat %bool %img
3254 )";
3255
3256 CompileSuccessfully(GenerateKernelCode(body).c_str());
3257 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3258 EXPECT_THAT(getDiagnosticString(),
3259 HasSubstr("Expected Result Type to be int scalar type"));
3260 }
3261
TEST_F(ValidateImage,QueryFormatNotImage)3262 TEST_F(ValidateImage, QueryFormatNotImage) {
3263 const std::string body = R"(
3264 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3265 %sampler = OpLoad %type_sampler %uniform_sampler
3266 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3267 %res1 = OpImageQueryFormat %u32 %sampler
3268 )";
3269
3270 CompileSuccessfully(GenerateKernelCode(body).c_str());
3271 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3272 EXPECT_THAT(getDiagnosticString(),
3273 HasSubstr("Expected operand to be of type OpTypeImage"));
3274 }
3275
TEST_F(ValidateImage,QueryOrderSuccess)3276 TEST_F(ValidateImage, QueryOrderSuccess) {
3277 const std::string body = R"(
3278 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3279 %res1 = OpImageQueryOrder %u32 %img
3280 )";
3281
3282 CompileSuccessfully(GenerateKernelCode(body).c_str());
3283 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3284 }
3285
TEST_F(ValidateImage,QueryOrderWrongResultType)3286 TEST_F(ValidateImage, QueryOrderWrongResultType) {
3287 const std::string body = R"(
3288 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3289 %res1 = OpImageQueryOrder %bool %img
3290 )";
3291
3292 CompileSuccessfully(GenerateKernelCode(body).c_str());
3293 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3294 EXPECT_THAT(getDiagnosticString(),
3295 HasSubstr("Expected Result Type to be int scalar type"));
3296 }
3297
TEST_F(ValidateImage,QueryOrderNotImage)3298 TEST_F(ValidateImage, QueryOrderNotImage) {
3299 const std::string body = R"(
3300 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3301 %sampler = OpLoad %type_sampler %uniform_sampler
3302 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3303 %res1 = OpImageQueryOrder %u32 %sampler
3304 )";
3305
3306 CompileSuccessfully(GenerateKernelCode(body).c_str());
3307 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3308 EXPECT_THAT(getDiagnosticString(),
3309 HasSubstr("Expected operand to be of type OpTypeImage"));
3310 }
3311
TEST_F(ValidateImage,QuerySizeLodSuccess)3312 TEST_F(ValidateImage, QuerySizeLodSuccess) {
3313 const std::string body = R"(
3314 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3315 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
3316 )";
3317
3318 CompileSuccessfully(GenerateKernelCode(body).c_str());
3319 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3320 }
3321
TEST_F(ValidateImage,QuerySizeLodWrongResultType)3322 TEST_F(ValidateImage, QuerySizeLodWrongResultType) {
3323 const std::string body = R"(
3324 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3325 %res1 = OpImageQuerySizeLod %f32vec2 %img %u32_1
3326 )";
3327
3328 CompileSuccessfully(GenerateKernelCode(body).c_str());
3329 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3330 EXPECT_THAT(
3331 getDiagnosticString(),
3332 HasSubstr("Expected Result Type to be int scalar or vector type"));
3333 }
3334
TEST_F(ValidateImage,QuerySizeLodResultTypeWrongSize)3335 TEST_F(ValidateImage, QuerySizeLodResultTypeWrongSize) {
3336 const std::string body = R"(
3337 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3338 %res1 = OpImageQuerySizeLod %u32 %img %u32_1
3339 )";
3340
3341 CompileSuccessfully(GenerateKernelCode(body).c_str());
3342 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3343 EXPECT_THAT(getDiagnosticString(),
3344 HasSubstr("Result Type has 1 components, but 2 expected"));
3345 }
3346
TEST_F(ValidateImage,QuerySizeLodNotImage)3347 TEST_F(ValidateImage, QuerySizeLodNotImage) {
3348 const std::string body = R"(
3349 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3350 %sampler = OpLoad %type_sampler %uniform_sampler
3351 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3352 %res1 = OpImageQuerySizeLod %u32vec2 %sampler %u32_1
3353 )";
3354
3355 CompileSuccessfully(GenerateKernelCode(body).c_str());
3356 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3357 EXPECT_THAT(getDiagnosticString(),
3358 HasSubstr("Expected Image to be of type OpTypeImage"));
3359 }
3360
TEST_F(ValidateImage,QuerySizeLodSampledImageDirectly)3361 TEST_F(ValidateImage, QuerySizeLodSampledImageDirectly) {
3362 const std::string body = R"(
3363 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3364 %sampler = OpLoad %type_sampler %uniform_sampler
3365 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3366 %res1 = OpImageQuerySizeLod %u32vec2 %simg %u32_1
3367 )";
3368
3369 CompileSuccessfully(GenerateShaderCode(body).c_str());
3370 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3371 EXPECT_THAT(getDiagnosticString(),
3372 HasSubstr("OpSampledImage instruction must not appear as operand "
3373 "for OpImageQuerySizeLod"));
3374 }
3375
TEST_F(ValidateImage,QuerySizeLodWrongImageDim)3376 TEST_F(ValidateImage, QuerySizeLodWrongImageDim) {
3377 const std::string body = R"(
3378 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3379 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
3380 )";
3381
3382 CompileSuccessfully(GenerateKernelCode(body).c_str());
3383 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3384 EXPECT_THAT(getDiagnosticString(),
3385 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
3386 }
3387
TEST_F(ValidateImage,QuerySizeLodMultisampled)3388 TEST_F(ValidateImage, QuerySizeLodMultisampled) {
3389 const std::string body = R"(
3390 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3391 %res1 = OpImageQuerySizeLod %u32vec2 %img %u32_1
3392 )";
3393
3394 CompileSuccessfully(GenerateKernelCode(body).c_str());
3395 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3396 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 0"));
3397 }
3398
TEST_F(ValidateImage,QuerySizeLodWrongLodType)3399 TEST_F(ValidateImage, QuerySizeLodWrongLodType) {
3400 const std::string body = R"(
3401 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3402 %res1 = OpImageQuerySizeLod %u32vec2 %img %f32_0
3403 )";
3404
3405 CompileSuccessfully(GenerateKernelCode(body).c_str());
3406 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3407 EXPECT_THAT(getDiagnosticString(),
3408 HasSubstr("Expected Level of Detail to be int scalar"));
3409 }
3410
TEST_F(ValidateImage,QuerySizeSuccess)3411 TEST_F(ValidateImage, QuerySizeSuccess) {
3412 const std::string body = R"(
3413 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3414 %res1 = OpImageQuerySize %u32vec2 %img
3415 )";
3416
3417 CompileSuccessfully(GenerateKernelCode(body).c_str());
3418 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3419 }
3420
TEST_F(ValidateImage,QuerySizeWrongResultType)3421 TEST_F(ValidateImage, QuerySizeWrongResultType) {
3422 const std::string body = R"(
3423 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3424 %res1 = OpImageQuerySize %f32vec2 %img
3425 )";
3426
3427 CompileSuccessfully(GenerateKernelCode(body).c_str());
3428 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3429 EXPECT_THAT(
3430 getDiagnosticString(),
3431 HasSubstr("Expected Result Type to be int scalar or vector type"));
3432 }
3433
TEST_F(ValidateImage,QuerySizeNotImage)3434 TEST_F(ValidateImage, QuerySizeNotImage) {
3435 const std::string body = R"(
3436 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3437 %sampler = OpLoad %type_sampler %uniform_sampler
3438 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3439 %res1 = OpImageQuerySize %u32vec2 %sampler
3440 )";
3441
3442 CompileSuccessfully(GenerateKernelCode(body).c_str());
3443 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3444 EXPECT_THAT(getDiagnosticString(),
3445 HasSubstr("Expected Image to be of type OpTypeImage"));
3446 }
3447
TEST_F(ValidateImage,QuerySizeSampledImageDirectly)3448 TEST_F(ValidateImage, QuerySizeSampledImageDirectly) {
3449 const std::string body = R"(
3450 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3451 %sampler = OpLoad %type_sampler %uniform_sampler
3452 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3453 %res1 = OpImageQuerySize %u32vec2 %simg
3454 )";
3455
3456 CompileSuccessfully(GenerateShaderCode(body).c_str());
3457 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3458 EXPECT_THAT(getDiagnosticString(),
3459 HasSubstr("OpSampledImage instruction must not appear as operand "
3460 "for OpImageQuerySize"));
3461 }
3462
TEST_F(ValidateImage,QuerySizeDimSubpassDataBad)3463 TEST_F(ValidateImage, QuerySizeDimSubpassDataBad) {
3464 const std::string body = R"(
3465 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3466 %res1 = OpImageQuerySize %u32vec2 %img
3467 )";
3468
3469 CompileSuccessfully(GenerateShaderCode(body).c_str());
3470 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3471 EXPECT_THAT(
3472 getDiagnosticString(),
3473 HasSubstr("Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"));
3474 }
3475
TEST_F(ValidateImage,QuerySizeWrongSampling)3476 TEST_F(ValidateImage, QuerySizeWrongSampling) {
3477 const std::string body = R"(
3478 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3479 %res1 = OpImageQuerySize %u32vec2 %img
3480 )";
3481
3482 CompileSuccessfully(GenerateKernelCode(body).c_str());
3483 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3484 EXPECT_THAT(
3485 getDiagnosticString(),
3486 HasSubstr("Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"));
3487 }
3488
TEST_F(ValidateImage,QuerySizeWrongNumberOfComponents)3489 TEST_F(ValidateImage, QuerySizeWrongNumberOfComponents) {
3490 const std::string body = R"(
3491 %img = OpLoad %type_image_f32_3d_0111 %uniform_image_f32_3d_0111
3492 %res1 = OpImageQuerySize %u32vec2 %img
3493 )";
3494
3495 CompileSuccessfully(GenerateShaderCode(body).c_str());
3496 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3497 EXPECT_THAT(getDiagnosticString(),
3498 HasSubstr("Result Type has 2 components, but 4 expected"));
3499 }
3500
TEST_F(ValidateImage,QueryLodSuccessKernel)3501 TEST_F(ValidateImage, QueryLodSuccessKernel) {
3502 const std::string body = R"(
3503 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3504 %sampler = OpLoad %type_sampler %uniform_sampler
3505 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3506 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3507 %res2 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
3508 )";
3509
3510 CompileSuccessfully(GenerateKernelCode(body).c_str());
3511 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3512 }
3513
TEST_F(ValidateImage,QueryLodSuccessShader)3514 TEST_F(ValidateImage, QueryLodSuccessShader) {
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 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3520 )";
3521
3522 CompileSuccessfully(GenerateShaderCode(body).c_str());
3523 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3524 }
3525
TEST_F(ValidateImage,QueryLodWrongResultType)3526 TEST_F(ValidateImage, QueryLodWrongResultType) {
3527 const std::string body = R"(
3528 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3529 %sampler = OpLoad %type_sampler %uniform_sampler
3530 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3531 %res1 = OpImageQueryLod %u32vec2 %simg %f32vec2_hh
3532 )";
3533
3534 CompileSuccessfully(GenerateKernelCode(body).c_str());
3535 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3536 EXPECT_THAT(getDiagnosticString(),
3537 HasSubstr("Expected Result Type to be float vector type"));
3538 }
3539
TEST_F(ValidateImage,QueryLodResultTypeWrongSize)3540 TEST_F(ValidateImage, QueryLodResultTypeWrongSize) {
3541 const std::string body = R"(
3542 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3543 %sampler = OpLoad %type_sampler %uniform_sampler
3544 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3545 %res1 = OpImageQueryLod %f32vec3 %simg %f32vec2_hh
3546 )";
3547
3548 CompileSuccessfully(GenerateKernelCode(body).c_str());
3549 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3550 EXPECT_THAT(getDiagnosticString(),
3551 HasSubstr("Expected Result Type to have 2 components"));
3552 }
3553
TEST_F(ValidateImage,QueryLodNotSampledImage)3554 TEST_F(ValidateImage, QueryLodNotSampledImage) {
3555 const std::string body = R"(
3556 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3557 %res1 = OpImageQueryLod %f32vec2 %img %f32vec2_hh
3558 )";
3559
3560 CompileSuccessfully(GenerateKernelCode(body).c_str());
3561 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3562 EXPECT_THAT(
3563 getDiagnosticString(),
3564 HasSubstr("Expected Image operand to be of type OpTypeSampledImage"));
3565 }
3566
TEST_F(ValidateImage,QueryLodWrongDim)3567 TEST_F(ValidateImage, QueryLodWrongDim) {
3568 const std::string body = R"(
3569 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3570 %sampler = OpLoad %type_sampler %uniform_sampler
3571 %simg = OpSampledImage %type_sampled_image_f32_rect_0001 %img %sampler
3572 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3573 )";
3574
3575 CompileSuccessfully(GenerateKernelCode(body).c_str());
3576 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3577 EXPECT_THAT(getDiagnosticString(),
3578 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
3579 }
3580
TEST_F(ValidateImage,QueryLodWrongCoordinateType)3581 TEST_F(ValidateImage, QueryLodWrongCoordinateType) {
3582 const std::string body = R"(
3583 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3584 %sampler = OpLoad %type_sampler %uniform_sampler
3585 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3586 %res1 = OpImageQueryLod %f32vec2 %simg %u32vec2_01
3587 )";
3588
3589 CompileSuccessfully(GenerateShaderCode(body).c_str());
3590 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3591 EXPECT_THAT(getDiagnosticString(),
3592 HasSubstr("Expected Coordinate to be float scalar or vector"));
3593 }
3594
TEST_F(ValidateImage,QueryLodCoordinateSizeTooSmall)3595 TEST_F(ValidateImage, QueryLodCoordinateSizeTooSmall) {
3596 const std::string body = R"(
3597 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3598 %sampler = OpLoad %type_sampler %uniform_sampler
3599 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3600 %res1 = OpImageQueryLod %f32vec2 %simg %f32_0
3601 )";
3602
3603 CompileSuccessfully(GenerateShaderCode(body).c_str());
3604 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3605 EXPECT_THAT(getDiagnosticString(),
3606 HasSubstr("Expected Coordinate to have at least 2 components, "
3607 "but given only 1"));
3608 }
3609
TEST_F(ValidateImage,QueryLevelsSuccess)3610 TEST_F(ValidateImage, QueryLevelsSuccess) {
3611 const std::string body = R"(
3612 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3613 %res1 = OpImageQueryLevels %u32 %img
3614 )";
3615
3616 CompileSuccessfully(GenerateKernelCode(body).c_str());
3617 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3618 }
3619
TEST_F(ValidateImage,QueryLevelsWrongResultType)3620 TEST_F(ValidateImage, QueryLevelsWrongResultType) {
3621 const std::string body = R"(
3622 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3623 %res1 = OpImageQueryLevels %f32 %img
3624 )";
3625
3626 CompileSuccessfully(GenerateKernelCode(body).c_str());
3627 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3628 EXPECT_THAT(getDiagnosticString(),
3629 HasSubstr("Expected Result Type to be int scalar type"));
3630 }
3631
TEST_F(ValidateImage,QueryLevelsNotImage)3632 TEST_F(ValidateImage, QueryLevelsNotImage) {
3633 const std::string body = R"(
3634 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3635 %sampler = OpLoad %type_sampler %uniform_sampler
3636 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3637 %res1 = OpImageQueryLevels %u32 %sampler
3638 )";
3639
3640 CompileSuccessfully(GenerateKernelCode(body).c_str());
3641 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3642 EXPECT_THAT(getDiagnosticString(),
3643 HasSubstr("Expected Image to be of type OpTypeImage"));
3644 }
3645
TEST_F(ValidateImage,QueryLevelsSampledImageDirectly)3646 TEST_F(ValidateImage, QueryLevelsSampledImageDirectly) {
3647 const std::string body = R"(
3648 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3649 %sampler = OpLoad %type_sampler %uniform_sampler
3650 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3651 %res1 = OpImageQueryLevels %u32 %simg
3652 )";
3653
3654 CompileSuccessfully(GenerateShaderCode(body).c_str());
3655 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3656 EXPECT_THAT(getDiagnosticString(),
3657 HasSubstr("OpSampledImage instruction must not appear as operand "
3658 "for OpImageQueryLevels"));
3659 }
3660
TEST_F(ValidateImage,QueryLevelsWrongDim)3661 TEST_F(ValidateImage, QueryLevelsWrongDim) {
3662 const std::string body = R"(
3663 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
3664 %res1 = OpImageQueryLevels %u32 %img
3665 )";
3666
3667 CompileSuccessfully(GenerateKernelCode(body).c_str());
3668 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3669 EXPECT_THAT(getDiagnosticString(),
3670 HasSubstr("Image 'Dim' must be 1D, 2D, 3D or Cube"));
3671 }
3672
TEST_F(ValidateImage,QuerySamplesSuccess)3673 TEST_F(ValidateImage, QuerySamplesSuccess) {
3674 const std::string body = R"(
3675 %img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
3676 %res1 = OpImageQuerySamples %u32 %img
3677 )";
3678
3679 CompileSuccessfully(GenerateKernelCode(body).c_str());
3680 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3681 }
3682
TEST_F(ValidateImage,QuerySamplesNot2D)3683 TEST_F(ValidateImage, QuerySamplesNot2D) {
3684 const std::string body = R"(
3685 %img = OpLoad %type_image_f32_3d_0010 %uniform_image_f32_3d_0010
3686 %res1 = OpImageQuerySamples %u32 %img
3687 )";
3688
3689 CompileSuccessfully(GenerateKernelCode(body).c_str());
3690 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3691 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'Dim' must be 2D"));
3692 }
3693
TEST_F(ValidateImage,QuerySamplesNotMultisampled)3694 TEST_F(ValidateImage, QuerySamplesNotMultisampled) {
3695 const std::string body = R"(
3696 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3697 %res1 = OpImageQuerySamples %u32 %img
3698 )";
3699
3700 CompileSuccessfully(GenerateKernelCode(body).c_str());
3701 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3702 EXPECT_THAT(getDiagnosticString(), HasSubstr("Image 'MS' must be 1"));
3703 }
3704
TEST_F(ValidateImage,QueryLodWrongExecutionModel)3705 TEST_F(ValidateImage, QueryLodWrongExecutionModel) {
3706 const std::string body = R"(
3707 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3708 %sampler = OpLoad %type_sampler %uniform_sampler
3709 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3710 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3711 )";
3712
3713 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
3714 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3715 EXPECT_THAT(
3716 getDiagnosticString(),
3717 HasSubstr(
3718 "OpImageQueryLod requires Fragment or GLCompute execution model"));
3719 }
3720
TEST_F(ValidateImage,QueryLodWrongExecutionModelWithFunc)3721 TEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) {
3722 const std::string body = R"(
3723 %call_ret = OpFunctionCall %void %my_func
3724 OpReturn
3725 OpFunctionEnd
3726 %my_func = OpFunction %void None %func
3727 %my_func_entry = OpLabel
3728 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3729 %sampler = OpLoad %type_sampler %uniform_sampler
3730 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3731 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3732 )";
3733
3734 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
3735 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3736 EXPECT_THAT(
3737 getDiagnosticString(),
3738 HasSubstr(
3739 "OpImageQueryLod requires Fragment or GLCompute execution model"));
3740 }
3741
TEST_F(ValidateImage,QueryLodComputeShaderDerivatives)3742 TEST_F(ValidateImage, QueryLodComputeShaderDerivatives) {
3743 const std::string body = R"(
3744 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3745 %sampler = OpLoad %type_sampler %uniform_sampler
3746 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3747 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3748 )";
3749
3750 const std::string extra = R"(
3751 OpCapability ComputeDerivativeGroupLinearNV
3752 OpExtension "SPV_NV_compute_shader_derivatives"
3753 )";
3754 const std::string mode = R"(
3755 OpExecutionMode %main LocalSize 8 8 1
3756 OpExecutionMode %main DerivativeGroupLinearNV
3757 )";
3758 CompileSuccessfully(
3759 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
3760 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3761 }
3762
TEST_F(ValidateImage,QueryLodComputeShaderDerivativesMissingMode)3763 TEST_F(ValidateImage, QueryLodComputeShaderDerivativesMissingMode) {
3764 const std::string body = R"(
3765 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3766 %sampler = OpLoad %type_sampler %uniform_sampler
3767 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3768 %res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
3769 )";
3770
3771 const std::string extra = R"(
3772 OpCapability ComputeDerivativeGroupLinearNV
3773 OpExtension "SPV_NV_compute_shader_derivatives"
3774 )";
3775 const std::string mode = R"(
3776 OpExecutionMode %main LocalSize 8 8 1
3777 )";
3778 CompileSuccessfully(
3779 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
3780 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3781 EXPECT_THAT(getDiagnosticString(),
3782 HasSubstr("OpImageQueryLod requires DerivativeGroupQuadsNV or "
3783 "DerivativeGroupLinearNV execution mode for GLCompute "
3784 "execution model"));
3785 }
3786
TEST_F(ValidateImage,ImplicitLodWrongExecutionModel)3787 TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
3788 const std::string body = R"(
3789 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3790 %sampler = OpLoad %type_sampler %uniform_sampler
3791 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3792 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
3793 )";
3794
3795 CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
3796 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3797 EXPECT_THAT(getDiagnosticString(),
3798 HasSubstr("ImplicitLod instructions require Fragment or "
3799 "GLCompute execution model"));
3800 }
3801
TEST_F(ValidateImage,ImplicitLodComputeShaderDerivatives)3802 TEST_F(ValidateImage, ImplicitLodComputeShaderDerivatives) {
3803 const std::string body = R"(
3804 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3805 %sampler = OpLoad %type_sampler %uniform_sampler
3806 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3807 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
3808 )";
3809
3810 const std::string extra = R"(
3811 OpCapability ComputeDerivativeGroupLinearNV
3812 OpExtension "SPV_NV_compute_shader_derivatives"
3813 )";
3814 const std::string mode = R"(
3815 OpExecutionMode %main LocalSize 8 8 1
3816 OpExecutionMode %main DerivativeGroupLinearNV
3817 )";
3818 CompileSuccessfully(
3819 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
3820 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3821 }
3822
TEST_F(ValidateImage,ImplicitLodComputeShaderDerivativesMissingMode)3823 TEST_F(ValidateImage, ImplicitLodComputeShaderDerivativesMissingMode) {
3824 const std::string body = R"(
3825 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3826 %sampler = OpLoad %type_sampler %uniform_sampler
3827 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3828 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
3829 )";
3830
3831 const std::string extra = R"(
3832 OpCapability ComputeDerivativeGroupLinearNV
3833 OpExtension "SPV_NV_compute_shader_derivatives"
3834 )";
3835 const std::string mode = R"(
3836 OpExecutionMode %main LocalSize 8 8 1
3837 )";
3838 CompileSuccessfully(
3839 GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
3840 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3841 EXPECT_THAT(
3842 getDiagnosticString(),
3843 HasSubstr("ImplicitLod instructions require DerivativeGroupQuadsNV or "
3844 "DerivativeGroupLinearNV execution mode for GLCompute "
3845 "execution model"));
3846 }
3847
TEST_F(ValidateImage,ReadSubpassDataWrongExecutionModel)3848 TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
3849 const std::string body = R"(
3850 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
3851 %res1 = OpImageRead %f32vec4 %img %u32vec2_01
3852 )";
3853
3854 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
3855 CompileSuccessfully(GenerateShaderCode(body, extra, "Vertex").c_str());
3856 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
3857 EXPECT_THAT(getDiagnosticString(),
3858 HasSubstr("Dim SubpassData requires Fragment execution model"));
3859 }
3860
TEST_F(ValidateImage,SparseSampleImplicitLodSuccess)3861 TEST_F(ValidateImage, SparseSampleImplicitLodSuccess) {
3862 const std::string body = R"(
3863 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3864 %sampler = OpLoad %type_sampler %uniform_sampler
3865 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3866 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh
3867 %res2 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Bias %f32_0_25
3868 %res4 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
3869 %res5 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
3870 %res6 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
3871 %res7 = OpImageSparseSampleImplicitLod %struct_u64_f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
3872 %res8 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh NonPrivateTexelKHR
3873 )";
3874
3875 const std::string extra = R"(
3876 OpCapability VulkanMemoryModelKHR
3877 OpExtension "SPV_KHR_vulkan_memory_model"
3878 )";
3879 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
3880 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
3881 .c_str());
3882 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3883 }
3884
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotStruct)3885 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotStruct) {
3886 const std::string body = R"(
3887 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3888 %sampler = OpLoad %type_sampler %uniform_sampler
3889 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3890 %res1 = OpImageSparseSampleImplicitLod %f32 %simg %f32vec2_hh
3891 )";
3892
3893 CompileSuccessfully(GenerateShaderCode(body).c_str());
3894 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3895 EXPECT_THAT(getDiagnosticString(),
3896 HasSubstr("Expected Result Type to be OpTypeStruct"));
3897 }
3898
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotTwoMembers1)3899 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers1) {
3900 const std::string body = R"(
3901 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3902 %sampler = OpLoad %type_sampler %uniform_sampler
3903 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3904 %res1 = OpImageSparseSampleImplicitLod %struct_u32 %simg %f32vec2_hh
3905 )";
3906
3907 CompileSuccessfully(GenerateShaderCode(body).c_str());
3908 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3909 EXPECT_THAT(getDiagnosticString(),
3910 HasSubstr("Expected Result Type to be a struct containing an int "
3911 "scalar and a texel"));
3912 }
3913
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeNotTwoMembers2)3914 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers2) {
3915 const std::string body = R"(
3916 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3917 %sampler = OpLoad %type_sampler %uniform_sampler
3918 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3919 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4_u32 %simg %f32vec2_hh
3920 )";
3921
3922 CompileSuccessfully(GenerateShaderCode(body).c_str());
3923 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3924 EXPECT_THAT(getDiagnosticString(),
3925 HasSubstr("Expected Result Type to be a struct containing an "
3926 "int scalar and a texel"));
3927 }
3928
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeFirstMemberNotInt)3929 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeFirstMemberNotInt) {
3930 const std::string body = R"(
3931 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3932 %sampler = OpLoad %type_sampler %uniform_sampler
3933 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3934 %res1 = OpImageSparseSampleImplicitLod %struct_f32_f32vec4 %simg %f32vec2_hh
3935 )";
3936
3937 CompileSuccessfully(GenerateShaderCode(body).c_str());
3938 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3939 EXPECT_THAT(getDiagnosticString(),
3940 HasSubstr("Expected Result Type to be a struct containing an "
3941 "int scalar and a texel"));
3942 }
3943
TEST_F(ValidateImage,SparseSampleImplicitLodResultTypeTexelNotVector)3944 TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeTexelNotVector) {
3945 const std::string body = R"(
3946 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3947 %sampler = OpLoad %type_sampler %uniform_sampler
3948 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3949 %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32 %simg %f32vec2_hh
3950 )";
3951
3952 CompileSuccessfully(GenerateShaderCode(body).c_str());
3953 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3954 EXPECT_THAT(getDiagnosticString(),
3955 HasSubstr("Expected Result Type's second member to be int or "
3956 "float vector type"));
3957 }
3958
TEST_F(ValidateImage,SparseSampleImplicitLodWrongNumComponentsTexel)3959 TEST_F(ValidateImage, SparseSampleImplicitLodWrongNumComponentsTexel) {
3960 const std::string body = R"(
3961 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3962 %sampler = OpLoad %type_sampler %uniform_sampler
3963 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3964 %res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec3 %simg %f32vec2_hh
3965 )";
3966
3967 CompileSuccessfully(GenerateShaderCode(body).c_str());
3968 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3969 EXPECT_THAT(getDiagnosticString(),
3970 HasSubstr("Expected Result Type's second member to have 4 "
3971 "components"));
3972 }
3973
TEST_F(ValidateImage,SparseSampleImplicitLodWrongComponentTypeTexel)3974 TEST_F(ValidateImage, SparseSampleImplicitLodWrongComponentTypeTexel) {
3975 const std::string body = R"(
3976 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
3977 %sampler = OpLoad %type_sampler %uniform_sampler
3978 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
3979 %res1 = OpImageSparseSampleImplicitLod %struct_u32_u32vec4 %simg %f32vec2_hh
3980 )";
3981
3982 CompileSuccessfully(GenerateShaderCode(body).c_str());
3983 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3984 EXPECT_THAT(getDiagnosticString(),
3985 HasSubstr("Expected Image 'Sampled Type' to be the same as "
3986 "Result Type's second member components"));
3987 }
3988
TEST_F(ValidateImage,SparseSampleDrefImplicitLodSuccess)3989 TEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) {
3990 const std::string body = R"(
3991 %img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
3992 %sampler = OpLoad %type_sampler %uniform_sampler
3993 %simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
3994 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
3995 %res2 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
3996 %res4 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
3997 %res5 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
3998 %res6 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
3999 %res7 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
4000 %res8 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 NonPrivateTexelKHR
4001 )";
4002
4003 const std::string extra = R"(
4004 OpCapability VulkanMemoryModelKHR
4005 OpExtension "SPV_KHR_vulkan_memory_model"
4006 )";
4007 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4008 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4009 .c_str());
4010 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4011 }
4012
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotStruct)4013 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotStruct) {
4014 const std::string body = R"(
4015 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4016 %sampler = OpLoad %type_sampler %uniform_sampler
4017 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4018 %res1 = OpImageSparseSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1
4019 )";
4020
4021 CompileSuccessfully(GenerateShaderCode(body).c_str());
4022 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4023 EXPECT_THAT(getDiagnosticString(),
4024 HasSubstr("Expected Result Type to be OpTypeStruct"));
4025 }
4026
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotTwoMembers1)4027 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers1) {
4028 const std::string body = R"(
4029 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4030 %sampler = OpLoad %type_sampler %uniform_sampler
4031 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4032 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32 %simg %f32vec2_hh %f32_1
4033 )";
4034
4035 CompileSuccessfully(GenerateShaderCode(body).c_str());
4036 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4037 EXPECT_THAT(
4038 getDiagnosticString(),
4039 HasSubstr("Expected Result Type to be a struct containing an int scalar "
4040 "and a texel"));
4041 }
4042
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeNotTwoMembers2)4043 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers2) {
4044 const std::string body = R"(
4045 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4046 %sampler = OpLoad %type_sampler %uniform_sampler
4047 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4048 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_f32_u32 %simg %f32vec2_hh %f32_1
4049 )";
4050
4051 CompileSuccessfully(GenerateShaderCode(body).c_str());
4052 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4053 EXPECT_THAT(
4054 getDiagnosticString(),
4055 HasSubstr("Expected Result Type to be a struct containing an int scalar "
4056 "and a texel"));
4057 }
4058
TEST_F(ValidateImage,SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt)4059 TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt) {
4060 const std::string body = R"(
4061 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4062 %sampler = OpLoad %type_sampler %uniform_sampler
4063 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4064 %res1 = OpImageSparseSampleDrefImplicitLod %struct_f32_f32 %simg %f32vec2_hh %f32_1
4065 )";
4066
4067 CompileSuccessfully(GenerateShaderCode(body).c_str());
4068 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4069 EXPECT_THAT(
4070 getDiagnosticString(),
4071 HasSubstr("Expected Result Type to be a struct containing an int scalar "
4072 "and a texel"));
4073 }
4074
TEST_F(ValidateImage,SparseSampleDrefImplicitLodDifferentSampledType)4075 TEST_F(ValidateImage, SparseSampleDrefImplicitLodDifferentSampledType) {
4076 const std::string body = R"(
4077 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4078 %sampler = OpLoad %type_sampler %uniform_sampler
4079 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4080 %res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
4081 )";
4082
4083 CompileSuccessfully(GenerateShaderCode(body).c_str());
4084 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4085 EXPECT_THAT(getDiagnosticString(),
4086 HasSubstr("Expected Image 'Sampled Type' to be the same as "
4087 "Result Type's second member"));
4088 }
4089
TEST_F(ValidateImage,SparseFetchSuccess)4090 TEST_F(ValidateImage, SparseFetchSuccess) {
4091 const std::string body = R"(
4092 %img = OpLoad %type_image_f32_1d_0001 %uniform_image_f32_1d_0001
4093 %res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
4094 %res2 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01 NonPrivateTexelKHR
4095 )";
4096
4097 const std::string extra = R"(
4098 OpCapability VulkanMemoryModelKHR
4099 OpExtension "SPV_KHR_vulkan_memory_model"
4100 )";
4101 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4102 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4103 .c_str());
4104 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4105 }
4106
TEST_F(ValidateImage,SparseFetchResultTypeNotStruct)4107 TEST_F(ValidateImage, SparseFetchResultTypeNotStruct) {
4108 const std::string body = R"(
4109 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4110 %res1 = OpImageSparseFetch %f32 %img %u32vec2_01
4111 )";
4112
4113 CompileSuccessfully(GenerateShaderCode(body).c_str());
4114 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4115 EXPECT_THAT(getDiagnosticString(),
4116 HasSubstr("Expected Result Type to be OpTypeStruct"));
4117 }
4118
TEST_F(ValidateImage,SparseFetchResultTypeNotTwoMembers1)4119 TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers1) {
4120 const std::string body = R"(
4121 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4122 %res1 = OpImageSparseFetch %struct_u32 %img %u32vec2_01
4123 )";
4124
4125 CompileSuccessfully(GenerateShaderCode(body).c_str());
4126 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4127 EXPECT_THAT(getDiagnosticString(),
4128 HasSubstr("Expected Result Type to be a struct containing an "
4129 "int scalar and a texel"));
4130 }
4131
TEST_F(ValidateImage,SparseFetchResultTypeNotTwoMembers2)4132 TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers2) {
4133 const std::string body = R"(
4134 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4135 %res1 = OpImageSparseFetch %struct_u32_f32vec4_u32 %img %u32vec2_01
4136 )";
4137
4138 CompileSuccessfully(GenerateShaderCode(body).c_str());
4139 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4140 EXPECT_THAT(getDiagnosticString(),
4141 HasSubstr("Expected Result Type to be a struct containing an "
4142 "int scalar and a texel"));
4143 }
4144
TEST_F(ValidateImage,SparseFetchResultTypeFirstMemberNotInt)4145 TEST_F(ValidateImage, SparseFetchResultTypeFirstMemberNotInt) {
4146 const std::string body = R"(
4147 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4148 %res1 = OpImageSparseFetch %struct_f32_f32vec4 %img %u32vec2_01
4149 )";
4150
4151 CompileSuccessfully(GenerateShaderCode(body).c_str());
4152 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4153 EXPECT_THAT(getDiagnosticString(),
4154 HasSubstr("Expected Result Type to be a struct containing an "
4155 "int scalar and a texel"));
4156 }
4157
TEST_F(ValidateImage,SparseFetchResultTypeTexelNotVector)4158 TEST_F(ValidateImage, SparseFetchResultTypeTexelNotVector) {
4159 const std::string body = R"(
4160 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4161 %res1 = OpImageSparseFetch %struct_u32_u32 %img %u32vec2_01
4162 )";
4163
4164 CompileSuccessfully(GenerateShaderCode(body).c_str());
4165 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4166 EXPECT_THAT(getDiagnosticString(),
4167 HasSubstr("Expected Result Type's second member to be int or "
4168 "float vector type"));
4169 }
4170
TEST_F(ValidateImage,SparseFetchWrongNumComponentsTexel)4171 TEST_F(ValidateImage, SparseFetchWrongNumComponentsTexel) {
4172 const std::string body = R"(
4173 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4174 %res1 = OpImageSparseFetch %struct_u32_f32vec3 %img %u32vec2_01
4175 )";
4176
4177 CompileSuccessfully(GenerateShaderCode(body).c_str());
4178 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4179 EXPECT_THAT(getDiagnosticString(),
4180 HasSubstr("Expected Result Type's second member to have 4 "
4181 "components"));
4182 }
4183
TEST_F(ValidateImage,SparseFetchWrongComponentTypeTexel)4184 TEST_F(ValidateImage, SparseFetchWrongComponentTypeTexel) {
4185 const std::string body = R"(
4186 %img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
4187 %res1 = OpImageSparseFetch %struct_u32_u32vec4 %img %u32vec2_01
4188 )";
4189
4190 CompileSuccessfully(GenerateShaderCode(body).c_str());
4191 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4192 EXPECT_THAT(getDiagnosticString(),
4193 HasSubstr("Expected Image 'Sampled Type' to be the same as "
4194 "Result Type's second member components"));
4195 }
4196
TEST_F(ValidateImage,SparseReadSuccess)4197 TEST_F(ValidateImage, SparseReadSuccess) {
4198 const std::string body = R"(
4199 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4200 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
4201 )";
4202
4203 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4204 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4205 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4206 }
4207
TEST_F(ValidateImage,SparseReadResultTypeNotStruct)4208 TEST_F(ValidateImage, SparseReadResultTypeNotStruct) {
4209 const std::string body = R"(
4210 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4211 %res1 = OpImageSparseRead %f32 %img %u32vec2_01
4212 )";
4213
4214 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4215 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4216 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4217 EXPECT_THAT(getDiagnosticString(),
4218 HasSubstr("Expected Result Type to be OpTypeStruct"));
4219 }
4220
TEST_F(ValidateImage,SparseReadResultTypeNotTwoMembers1)4221 TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers1) {
4222 const std::string body = R"(
4223 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4224 %res1 = OpImageSparseRead %struct_u32 %img %u32vec2_01
4225 )";
4226
4227 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4228 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4229 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4230 EXPECT_THAT(getDiagnosticString(),
4231 HasSubstr("Expected Result Type to be a struct containing an "
4232 "int scalar and a texel"));
4233 }
4234
TEST_F(ValidateImage,SparseReadResultTypeNotTwoMembers2)4235 TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers2) {
4236 const std::string body = R"(
4237 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4238 %res1 = OpImageSparseRead %struct_u32_f32vec4_u32 %img %u32vec2_01
4239 )";
4240
4241 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4242 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4243 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4244 EXPECT_THAT(getDiagnosticString(),
4245 HasSubstr("Expected Result Type to be a struct containing an "
4246 "int scalar and a texel"));
4247 }
4248
TEST_F(ValidateImage,SparseReadResultTypeFirstMemberNotInt)4249 TEST_F(ValidateImage, SparseReadResultTypeFirstMemberNotInt) {
4250 const std::string body = R"(
4251 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4252 %res1 = OpImageSparseRead %struct_f32_f32vec4 %img %u32vec2_01
4253 )";
4254
4255 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4256 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4257 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4258 EXPECT_THAT(getDiagnosticString(),
4259 HasSubstr("Expected Result Type to be a struct containing an "
4260 "int scalar and a texel"));
4261 }
4262
TEST_F(ValidateImage,SparseReadResultTypeTexelWrongType)4263 TEST_F(ValidateImage, SparseReadResultTypeTexelWrongType) {
4264 const std::string body = R"(
4265 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4266 %res1 = OpImageSparseRead %struct_u32_u32arr4 %img %u32vec2_01
4267 )";
4268
4269 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4270 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4271 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4272 EXPECT_THAT(getDiagnosticString(),
4273 HasSubstr("Expected Result Type's second member to be int or "
4274 "float scalar or vector type"));
4275 }
4276
TEST_F(ValidateImage,SparseReadWrongComponentTypeTexel)4277 TEST_F(ValidateImage, SparseReadWrongComponentTypeTexel) {
4278 const std::string body = R"(
4279 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4280 %res1 = OpImageSparseRead %struct_u32_u32vec4 %img %u32vec2_01
4281 )";
4282
4283 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4284 CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
4285 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4286 EXPECT_THAT(getDiagnosticString(),
4287 HasSubstr("Expected Image 'Sampled Type' to be the same as "
4288 "Result Type's second member components"));
4289 }
4290
TEST_F(ValidateImage,SparseReadSubpassDataNotAllowed)4291 TEST_F(ValidateImage, SparseReadSubpassDataNotAllowed) {
4292 const std::string body = R"(
4293 %img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
4294 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
4295 )";
4296
4297 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4298 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment").c_str());
4299 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4300 EXPECT_THAT(
4301 getDiagnosticString(),
4302 HasSubstr("Image Dim SubpassData cannot be used with ImageSparseRead"));
4303 }
4304
TEST_F(ValidateImage,SparseGatherSuccess)4305 TEST_F(ValidateImage, SparseGatherSuccess) {
4306 const std::string body = R"(
4307 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4308 %sampler = OpLoad %type_sampler %uniform_sampler
4309 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4310 %res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1
4311 %res2 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1 NonPrivateTexelKHR
4312 )";
4313
4314 const std::string extra = R"(
4315 OpCapability VulkanMemoryModelKHR
4316 OpExtension "SPV_KHR_vulkan_memory_model"
4317 )";
4318 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4319 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4320 .c_str());
4321 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4322 }
4323
TEST_F(ValidateImage,SparseGatherResultTypeNotStruct)4324 TEST_F(ValidateImage, SparseGatherResultTypeNotStruct) {
4325 const std::string body = R"(
4326 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4327 %sampler = OpLoad %type_sampler %uniform_sampler
4328 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4329 %res1 = OpImageSparseGather %f32 %simg %f32vec2_hh %u32_1
4330 )";
4331
4332 CompileSuccessfully(GenerateShaderCode(body).c_str());
4333 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4334 EXPECT_THAT(getDiagnosticString(),
4335 HasSubstr("Expected Result Type to be OpTypeStruct"));
4336 }
4337
TEST_F(ValidateImage,SparseGatherResultTypeNotTwoMembers1)4338 TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers1) {
4339 const std::string body = R"(
4340 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4341 %sampler = OpLoad %type_sampler %uniform_sampler
4342 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4343 %res1 = OpImageSparseGather %struct_u32 %simg %f32vec2_hh %u32_1
4344 )";
4345
4346 CompileSuccessfully(GenerateShaderCode(body).c_str());
4347 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4348 EXPECT_THAT(getDiagnosticString(),
4349 HasSubstr("Expected Result Type to be a struct containing an int "
4350 "scalar and a texel"));
4351 }
4352
TEST_F(ValidateImage,SparseGatherResultTypeNotTwoMembers2)4353 TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers2) {
4354 const std::string body = R"(
4355 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4356 %sampler = OpLoad %type_sampler %uniform_sampler
4357 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4358 %res1 = OpImageSparseGather %struct_u32_f32vec4_u32 %simg %f32vec2_hh %u32_1
4359 )";
4360
4361 CompileSuccessfully(GenerateShaderCode(body).c_str());
4362 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4363 EXPECT_THAT(getDiagnosticString(),
4364 HasSubstr("Expected Result Type to be a struct containing an int "
4365 "scalar and a texel"));
4366 }
4367
TEST_F(ValidateImage,SparseGatherResultTypeFirstMemberNotInt)4368 TEST_F(ValidateImage, SparseGatherResultTypeFirstMemberNotInt) {
4369 const std::string body = R"(
4370 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4371 %sampler = OpLoad %type_sampler %uniform_sampler
4372 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4373 %res1 = OpImageSparseGather %struct_f32_f32vec4 %simg %f32vec2_hh %u32_1
4374 )";
4375
4376 CompileSuccessfully(GenerateShaderCode(body).c_str());
4377 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4378 EXPECT_THAT(getDiagnosticString(),
4379 HasSubstr("Expected Result Type to be a struct containing an "
4380 "int scalar and a texel"));
4381 }
4382
TEST_F(ValidateImage,SparseGatherResultTypeTexelNotVector)4383 TEST_F(ValidateImage, SparseGatherResultTypeTexelNotVector) {
4384 const std::string body = R"(
4385 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4386 %sampler = OpLoad %type_sampler %uniform_sampler
4387 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4388 %res1 = OpImageSparseGather %struct_u32_u32 %simg %f32vec2_hh %u32_1
4389 )";
4390
4391 CompileSuccessfully(GenerateShaderCode(body).c_str());
4392 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4393 EXPECT_THAT(getDiagnosticString(),
4394 HasSubstr("Expected Result Type's second member to be int or "
4395 "float vector type"));
4396 }
4397
TEST_F(ValidateImage,SparseGatherWrongNumComponentsTexel)4398 TEST_F(ValidateImage, SparseGatherWrongNumComponentsTexel) {
4399 const std::string body = R"(
4400 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4401 %sampler = OpLoad %type_sampler %uniform_sampler
4402 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4403 %res1 = OpImageSparseGather %struct_u32_f32vec3 %simg %f32vec2_hh %u32_1
4404 )";
4405
4406 CompileSuccessfully(GenerateShaderCode(body).c_str());
4407 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4408 EXPECT_THAT(getDiagnosticString(),
4409 HasSubstr("Expected Result Type's second member to have 4 "
4410 "components"));
4411 }
4412
TEST_F(ValidateImage,SparseGatherWrongComponentTypeTexel)4413 TEST_F(ValidateImage, SparseGatherWrongComponentTypeTexel) {
4414 const std::string body = R"(
4415 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4416 %sampler = OpLoad %type_sampler %uniform_sampler
4417 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4418 %res1 = OpImageSparseGather %struct_u32_u32vec4 %simg %f32vec2_hh %u32_1
4419 )";
4420
4421 CompileSuccessfully(GenerateShaderCode(body).c_str());
4422 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4423 EXPECT_THAT(getDiagnosticString(),
4424 HasSubstr("Expected Image 'Sampled Type' to be the same as "
4425 "Result Type's second member components"));
4426 }
4427
TEST_F(ValidateImage,SparseTexelsResidentSuccess)4428 TEST_F(ValidateImage, SparseTexelsResidentSuccess) {
4429 const std::string body = R"(
4430 %res1 = OpImageSparseTexelsResident %bool %u32_1
4431 )";
4432
4433 CompileSuccessfully(GenerateShaderCode(body).c_str());
4434 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4435 }
4436
TEST_F(ValidateImage,SparseTexelsResidentResultTypeNotBool)4437 TEST_F(ValidateImage, SparseTexelsResidentResultTypeNotBool) {
4438 const std::string body = R"(
4439 %res1 = OpImageSparseTexelsResident %u32 %u32_1
4440 )";
4441
4442 CompileSuccessfully(GenerateShaderCode(body).c_str());
4443 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4444 EXPECT_THAT(getDiagnosticString(),
4445 HasSubstr("Expected Result Type to be bool scalar type"));
4446 }
4447
TEST_F(ValidateImage,MakeTexelVisibleKHRSuccessImageRead)4448 TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageRead) {
4449 const std::string body = R"(
4450 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4451 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
4452 )";
4453
4454 const std::string extra = R"(
4455 OpCapability StorageImageReadWithoutFormat
4456 OpCapability VulkanMemoryModelKHR
4457 OpExtension "SPV_KHR_vulkan_memory_model"
4458 )";
4459 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4460 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4461 .c_str());
4462 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4463 }
4464
TEST_F(ValidateImage,MakeTexelVisibleKHRSuccessImageSparseRead)4465 TEST_F(ValidateImage, MakeTexelVisibleKHRSuccessImageSparseRead) {
4466 const std::string body = R"(
4467 %img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
4468 %res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_2
4469 )";
4470
4471 const std::string extra = R"(
4472 OpCapability StorageImageReadWithoutFormat
4473 OpCapability VulkanMemoryModelKHR
4474 OpExtension "SPV_KHR_vulkan_memory_model"
4475 )";
4476 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4477 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4478 .c_str());
4479 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4480 }
4481
TEST_F(ValidateImage,MakeTexelVisibleKHRFailureOpcode)4482 TEST_F(ValidateImage, MakeTexelVisibleKHRFailureOpcode) {
4483 const std::string body = R"(
4484 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4485 %sampler = OpLoad %type_sampler %uniform_sampler
4486 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4487 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
4488 )";
4489
4490 const std::string extra = R"(
4491 OpCapability StorageImageReadWithoutFormat
4492 OpCapability VulkanMemoryModelKHR
4493 OpExtension "SPV_KHR_vulkan_memory_model"
4494 )";
4495 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4496 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4497 .c_str());
4498 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4499 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4500 EXPECT_THAT(
4501 getDiagnosticString(),
4502 HasSubstr("Image Operand MakeTexelVisibleKHR can only be used with "
4503 "OpImageRead or OpImageSparseRead: OpImageSampleImplicitLod"));
4504 }
4505
TEST_F(ValidateImage,MakeTexelVisibleKHRFailureMissingNonPrivate)4506 TEST_F(ValidateImage, MakeTexelVisibleKHRFailureMissingNonPrivate) {
4507 const std::string body = R"(
4508 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4509 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR %u32_1
4510 )";
4511
4512 const std::string extra = R"(
4513 OpCapability StorageImageReadWithoutFormat
4514 OpCapability VulkanMemoryModelKHR
4515 OpExtension "SPV_KHR_vulkan_memory_model"
4516 )";
4517 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4518 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4519 .c_str());
4520 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4521 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4522 EXPECT_THAT(getDiagnosticString(),
4523 HasSubstr("Image Operand MakeTexelVisibleKHR requires "
4524 "NonPrivateTexelKHR is also specified: OpImageRead"));
4525 }
4526
TEST_F(ValidateImage,MakeTexelAvailableKHRSuccessImageWrite)4527 TEST_F(ValidateImage, MakeTexelAvailableKHRSuccessImageWrite) {
4528 const std::string body = R"(
4529 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4530 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2
4531 )";
4532
4533 const std::string extra = R"(
4534 OpCapability StorageImageWriteWithoutFormat
4535 OpCapability VulkanMemoryModelKHR
4536 OpExtension "SPV_KHR_vulkan_memory_model"
4537 )";
4538 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4539 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4540 .c_str());
4541 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4542 }
4543
TEST_F(ValidateImage,MakeTexelAvailableKHRFailureOpcode)4544 TEST_F(ValidateImage, MakeTexelAvailableKHRFailureOpcode) {
4545 const std::string body = R"(
4546 %img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
4547 %sampler = OpLoad %type_sampler %uniform_sampler
4548 %simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
4549 %res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
4550 )";
4551
4552 const std::string extra = R"(
4553 OpCapability StorageImageReadWithoutFormat
4554 OpCapability VulkanMemoryModelKHR
4555 OpExtension "SPV_KHR_vulkan_memory_model"
4556 )";
4557 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4558 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4559 .c_str());
4560 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4561 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4562 EXPECT_THAT(getDiagnosticString(),
4563 HasSubstr("Image Operand MakeTexelAvailableKHR can only be used "
4564 "with OpImageWrite: OpImageSampleImplicitLod"));
4565 }
4566
TEST_F(ValidateImage,MakeTexelAvailableKHRFailureMissingNonPrivate)4567 TEST_F(ValidateImage, MakeTexelAvailableKHRFailureMissingNonPrivate) {
4568 const std::string body = R"(
4569 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4570 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1
4571 )";
4572
4573 const std::string extra = R"(
4574 OpCapability StorageImageWriteWithoutFormat
4575 OpCapability VulkanMemoryModelKHR
4576 OpExtension "SPV_KHR_vulkan_memory_model"
4577 )";
4578 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4579 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4580 .c_str());
4581 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4582 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4583 EXPECT_THAT(getDiagnosticString(),
4584 HasSubstr("Image Operand MakeTexelAvailableKHR requires "
4585 "NonPrivateTexelKHR is also specified: OpImageWrite"));
4586 }
4587
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageWriteBad)4588 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteBad) {
4589 const std::string body = R"(
4590 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4591 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
4592 )";
4593
4594 const std::string extra = R"(
4595 OpCapability StorageImageWriteWithoutFormat
4596 OpCapability VulkanMemoryModelKHR
4597 OpExtension "SPV_KHR_vulkan_memory_model"
4598 )";
4599 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4600 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4601 .c_str());
4602 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4603 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4604 EXPECT_THAT(
4605 getDiagnosticString(),
4606 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
4607 "VulkanMemoryModelDeviceScopeKHR capability"));
4608 }
4609
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageWriteGood)4610 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteGood) {
4611 const std::string body = R"(
4612 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4613 OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
4614 )";
4615
4616 const std::string extra = R"(
4617 OpCapability StorageImageWriteWithoutFormat
4618 OpCapability VulkanMemoryModelKHR
4619 OpCapability VulkanMemoryModelDeviceScopeKHR
4620 OpExtension "SPV_KHR_vulkan_memory_model"
4621 )";
4622 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4623 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4624 .c_str());
4625 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4626 }
4627
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageReadBad)4628 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadBad) {
4629 const std::string body = R"(
4630 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4631 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
4632 )";
4633
4634 const std::string extra = R"(
4635 OpCapability StorageImageReadWithoutFormat
4636 OpCapability VulkanMemoryModelKHR
4637 OpExtension "SPV_KHR_vulkan_memory_model"
4638 )";
4639 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4640 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4641 .c_str());
4642 ASSERT_EQ(SPV_ERROR_INVALID_DATA,
4643 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4644 EXPECT_THAT(
4645 getDiagnosticString(),
4646 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
4647 "VulkanMemoryModelDeviceScopeKHR capability"));
4648 }
4649
TEST_F(ValidateImage,VulkanMemoryModelDeviceScopeImageReadGood)4650 TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageReadGood) {
4651 const std::string body = R"(
4652 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4653 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 MakeTexelVisibleKHR|NonPrivateTexelKHR %u32_1
4654 )";
4655
4656 const std::string extra = R"(
4657 OpCapability StorageImageReadWithoutFormat
4658 OpCapability VulkanMemoryModelKHR
4659 OpCapability VulkanMemoryModelDeviceScopeKHR
4660 OpExtension "SPV_KHR_vulkan_memory_model"
4661 )";
4662 CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
4663 SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
4664 .c_str());
4665 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4666 }
4667
4668 // This example used to cause a seg fault on OpReturnValue, verifying it doesn't
4669 // anymore.
TEST_F(ValidateImage,Issue2463NoSegFault)4670 TEST_F(ValidateImage, Issue2463NoSegFault) {
4671 const std::string spirv = R"(
4672 OpCapability Linkage
4673 OpCapability Shader
4674 %1 = OpExtInstImport "GLSL.std.450"
4675 OpMemoryModel Logical GLSL450
4676 %void = OpTypeVoid
4677 %6 = OpTypeFunction %void
4678 %float = OpTypeFloat 32
4679 %8 = OpTypeImage %float 3D 0 0 0 1 Unknown
4680 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
4681 %10 = OpTypeSampler
4682 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
4683 %12 = OpTypeSampledImage %8
4684 %13 = OpTypeFunction %12 %_ptr_UniformConstant_8 %_ptr_UniformConstant_10
4685 %23 = OpFunction %12 None %13
4686 %24 = OpFunctionParameter %_ptr_UniformConstant_8
4687 %25 = OpFunctionParameter %_ptr_UniformConstant_10
4688 %26 = OpLabel
4689 %27 = OpLoad %8 %24
4690 %28 = OpLoad %10 %25
4691 %29 = OpSampledImage %12 %27 %28
4692 OpReturnValue %29
4693 OpFunctionEnd
4694 )";
4695
4696 CompileSuccessfully(spirv);
4697 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4698 EXPECT_THAT(getDiagnosticString(),
4699 HasSubstr("OpSampledImage instruction must not appear as operand "
4700 "for OpReturnValue"));
4701 }
4702
TEST_F(ValidateImage,SignExtendV13Bad)4703 TEST_F(ValidateImage, SignExtendV13Bad) {
4704 const std::string body = R"(
4705 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4706 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
4707 )";
4708
4709 EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
4710 SPV_ENV_UNIVERSAL_1_3)),
4711 HasSubstr("Invalid image operand 'SignExtend'"));
4712 }
4713
TEST_F(ValidateImage,ZeroExtendV13Bad)4714 TEST_F(ValidateImage, ZeroExtendV13Bad) {
4715 const std::string body = R"(
4716 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4717 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
4718 )";
4719
4720 EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
4721 SPV_ENV_UNIVERSAL_1_3)),
4722 HasSubstr("Invalid image operand 'ZeroExtend'"));
4723 }
4724
TEST_F(ValidateImage,SignExtendScalarUIntTexelV14Good)4725 TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) {
4726 // Unsigned int sampled type
4727 const std::string body = R"(
4728 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4729 %res1 = OpImageRead %u32 %img %u32vec2_01 SignExtend
4730 )";
4731 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4732
4733 CompileSuccessfully(
4734 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4735 SPV_ENV_UNIVERSAL_1_4);
4736 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4737 EXPECT_THAT(getDiagnosticString(), Eq(""));
4738 }
4739
TEST_F(ValidateImage,SignExtendScalarSIntTexelV14Good)4740 TEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) {
4741 // Signed int sampled type
4742 const std::string body = R"(
4743 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
4744 %res1 = OpImageRead %s32 %img %u32vec2_01 SignExtend
4745 )";
4746 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4747
4748 CompileSuccessfully(
4749 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4750 SPV_ENV_UNIVERSAL_1_4);
4751 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4752 EXPECT_THAT(getDiagnosticString(), Eq(""));
4753 }
4754
TEST_F(ValidateImage,SignExtendScalarVectorUIntTexelV14Good)4755 TEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) {
4756 const std::string body = R"(
4757 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4758 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
4759 )";
4760 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4761
4762 CompileSuccessfully(
4763 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4764 SPV_ENV_UNIVERSAL_1_4);
4765 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4766 EXPECT_THAT(getDiagnosticString(), Eq(""));
4767 }
4768
TEST_F(ValidateImage,SignExtendVectorSIntTexelV14Good)4769 TEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) {
4770 const std::string body = R"(
4771 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
4772 %res1 = OpImageRead %s32vec4 %img %u32vec2_01 SignExtend
4773 )";
4774 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4775
4776 CompileSuccessfully(
4777 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4778 SPV_ENV_UNIVERSAL_1_4);
4779 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4780 EXPECT_THAT(getDiagnosticString(), Eq(""));
4781 }
4782
4783 // No negative tests for SignExtend since we don't truly know the
4784 // texel format.
4785
TEST_F(ValidateImage,ZeroExtendScalarUIntTexelV14Good)4786 TEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) {
4787 // Unsigned int sampled type
4788 const std::string body = R"(
4789 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4790 %res1 = OpImageRead %u32 %img %u32vec2_01 ZeroExtend
4791 )";
4792 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4793
4794 CompileSuccessfully(
4795 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4796 SPV_ENV_UNIVERSAL_1_4);
4797 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4798 EXPECT_THAT(getDiagnosticString(), Eq(""));
4799 }
4800
TEST_F(ValidateImage,ZeroExtendScalarSIntTexelV14Good)4801 TEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) {
4802 // Zeroed int sampled type
4803 const std::string body = R"(
4804 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
4805 %res1 = OpImageRead %s32 %img %u32vec2_01 ZeroExtend
4806 )";
4807 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4808
4809 CompileSuccessfully(
4810 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4811 SPV_ENV_UNIVERSAL_1_4);
4812 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4813 EXPECT_THAT(getDiagnosticString(), Eq(""));
4814 }
4815
TEST_F(ValidateImage,ZeroExtendScalarVectorUIntTexelV14Good)4816 TEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) {
4817 const std::string body = R"(
4818 %img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
4819 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
4820 )";
4821 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4822
4823 CompileSuccessfully(
4824 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4825 SPV_ENV_UNIVERSAL_1_4);
4826 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4827 EXPECT_THAT(getDiagnosticString(), Eq(""));
4828 }
4829
TEST_F(ValidateImage,ZeroExtendVectorSIntTexelV14Good)4830 TEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) {
4831 const std::string body = R"(
4832 %img = OpLoad %type_image_s32_2d_0002 %uniform_image_s32_2d_0002
4833 %res1 = OpImageRead %s32vec4 %img %u32vec2_01 ZeroExtend
4834 )";
4835 const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
4836
4837 CompileSuccessfully(
4838 GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
4839 SPV_ENV_UNIVERSAL_1_4);
4840 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
4841 EXPECT_THAT(getDiagnosticString(), Eq(""));
4842 }
4843
4844 // No negative tests for ZeroExtend since we don't truly know the
4845 // texel format.
4846
4847 } // namespace
4848 } // namespace val
4849 } // namespace spvtools
4850