1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief SPIR-V Assembly Tests for images and samplers.
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktSpvAsmImageSamplerTests.hpp"
25 #include "vktSpvAsmComputeShaderCase.hpp"
26 #include "vktSpvAsmComputeShaderTestUtil.hpp"
27 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
28
29 #include "vkImageUtil.hpp"
30 #include "tcuTextureUtil.hpp"
31
32 namespace vkt
33 {
34 namespace SpirVAssembly
35 {
36
37 using namespace vk;
38 using std::map;
39 using std::string;
40 using std::vector;
41 using tcu::IVec3;
42 using tcu::RGBA;
43 using tcu::Vec4;
44
45 namespace
46 {
47 enum TestType
48 {
49 TESTTYPE_LOCAL_VARIABLES = 0,
50 TESTTYPE_PASS_IMAGE_TO_FUNCTION,
51 TESTTYPE_PASS_SAMPLER_TO_FUNCTION,
52 TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION,
53 TESTTYPE_OPTYPEIMAGE_MISMATCH,
54
55 TESTTYPE_LAST
56 };
57
58 enum ReadOp
59 {
60 READOP_IMAGEREAD = 0,
61 READOP_IMAGEFETCH,
62 READOP_IMAGESAMPLE,
63 READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD,
64 READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD,
65
66 READOP_LAST
67 };
68
69 enum DescriptorType
70 {
71 DESCRIPTOR_TYPE_STORAGE_IMAGE = 0, // Storage image
72 DESCRIPTOR_TYPE_SAMPLED_IMAGE, // Sampled image
73 DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // Combined image sampler
74 DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES, // Combined image sampler with separate shader variables
75 DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS, // Combined image sampler where image and sampler variables are taken from two different desciptors
76
77 DESCRIPTOR_TYPE_LAST
78 };
79
80 enum DepthProperty
81 {
82 DEPTH_PROPERTY_NON_DEPTH = 0,
83 DEPTH_PROPERTY_DEPTH,
84 DEPTH_PROPERTY_UNKNOWN,
85
86 DEPTH_PROPERTY_LAST
87 };
88
isValidTestCase(TestType testType,DescriptorType descriptorType,ReadOp readOp)89 bool isValidTestCase (TestType testType, DescriptorType descriptorType, ReadOp readOp)
90 {
91 // Check valid descriptor type and test type combinations
92 switch (testType)
93 {
94 case TESTTYPE_PASS_IMAGE_TO_FUNCTION:
95 if (descriptorType != DESCRIPTOR_TYPE_STORAGE_IMAGE &&
96 descriptorType != DESCRIPTOR_TYPE_SAMPLED_IMAGE &&
97 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES &&
98 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
99 return false;
100 break;
101
102 case TESTTYPE_PASS_SAMPLER_TO_FUNCTION:
103 if (descriptorType != DESCRIPTOR_TYPE_SAMPLED_IMAGE &&
104 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES &&
105 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
106 return false;
107 break;
108
109 case TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION:
110 if (descriptorType != DESCRIPTOR_TYPE_SAMPLED_IMAGE &&
111 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES &&
112 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
113 return false;
114 break;
115
116 default:
117 break;
118 }
119
120 // Check valid descriptor type and read operation combinations
121 switch (readOp)
122 {
123 case READOP_IMAGEREAD:
124 if (descriptorType != DESCRIPTOR_TYPE_STORAGE_IMAGE)
125 return false;
126 break;
127
128 case READOP_IMAGEFETCH:
129 if (descriptorType != DESCRIPTOR_TYPE_SAMPLED_IMAGE &&
130 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
131 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES &&
132 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
133 return false;
134 break;
135
136 case READOP_IMAGESAMPLE:
137 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
138 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
139 if (descriptorType != DESCRIPTOR_TYPE_SAMPLED_IMAGE &&
140 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
141 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES &&
142 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
143 return false;
144 break;
145
146 default:
147 break;
148 }
149
150 return true;
151 }
152
getTestTypeName(TestType testType)153 const char* getTestTypeName (TestType testType)
154 {
155 switch (testType)
156 {
157 case TESTTYPE_LOCAL_VARIABLES:
158 return "all_local_variables";
159
160 case TESTTYPE_PASS_IMAGE_TO_FUNCTION:
161 return "pass_image_to_function";
162
163 case TESTTYPE_PASS_SAMPLER_TO_FUNCTION:
164 return "pass_sampler_to_function";
165
166 case TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION:
167 return "pass_image_and_sampler_to_function";
168
169 case TESTTYPE_OPTYPEIMAGE_MISMATCH:
170 return "optypeimage_mismatch";
171
172 default:
173 DE_FATAL("Unknown test type");
174 return "";
175 }
176 }
177
getReadOpName(ReadOp readOp)178 const char* getReadOpName (ReadOp readOp)
179 {
180 switch (readOp)
181 {
182 case READOP_IMAGEREAD:
183 return "imageread";
184
185 case READOP_IMAGEFETCH:
186 return "imagefetch";
187
188 case READOP_IMAGESAMPLE:
189 return "imagesample";
190
191 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
192 return "imagesample_dref_implicit_lod";
193
194 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
195 return "imagesample_dref_explicit_lod";
196
197 default:
198 DE_FATAL("Unknown readop");
199 return "";
200 }
201 }
202
getDescriptorName(DescriptorType descType)203 const char* getDescriptorName (DescriptorType descType)
204 {
205 switch (descType)
206 {
207 case DESCRIPTOR_TYPE_STORAGE_IMAGE:
208 return "storage_image";
209
210 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
211 return "sampled_image";
212
213 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
214 return "combined_image_sampler";
215
216 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
217 return "combined_image_sampler_separate_variables";
218
219 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
220 return "combined_image_sampler_separate_descriptors";
221
222 default:
223 DE_FATAL("Unknown descriptor type");
224 return "";
225 }
226 }
227
getDepthPropertyName(DepthProperty depthProperty)228 const char* getDepthPropertyName (DepthProperty depthProperty)
229 {
230 switch (depthProperty)
231 {
232 case DEPTH_PROPERTY_NON_DEPTH:
233 return "non_depth";
234
235 case DEPTH_PROPERTY_DEPTH:
236 return "depth";
237
238 case DEPTH_PROPERTY_UNKNOWN:
239 return "unknown";
240
241 default:
242 DE_FATAL("Unknown depth property");
243 return "";
244 }
245 }
246
getVkDescriptorType(DescriptorType descType)247 VkDescriptorType getVkDescriptorType (DescriptorType descType)
248 {
249 switch (descType)
250 {
251 case DESCRIPTOR_TYPE_STORAGE_IMAGE:
252 return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
253
254 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
255 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
256
257 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
258 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
259 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
260 return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
261
262 default:
263 DE_FATAL("Unknown descriptor type");
264 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
265 }
266 }
267
getImageFormat(ReadOp readOp)268 VkFormat getImageFormat (ReadOp readOp)
269 {
270 switch (readOp)
271 {
272 case READOP_IMAGEREAD:
273 case READOP_IMAGEFETCH:
274 case READOP_IMAGESAMPLE:
275 return VK_FORMAT_R32G32B32A32_SFLOAT;
276
277 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
278 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
279 return VK_FORMAT_D32_SFLOAT;
280
281 default:
282 DE_FATAL("Unknown readop");
283 return VK_FORMAT_UNDEFINED;
284 }
285 }
286
287 // Get variables that are declared in the read function, ie. not passed as parameters
getFunctionDstVariableStr(ReadOp readOp,DescriptorType descType,TestType testType)288 std::string getFunctionDstVariableStr (ReadOp readOp, DescriptorType descType, TestType testType)
289 {
290 const bool passNdx = (testType == TESTTYPE_LOCAL_VARIABLES) || (testType == TESTTYPE_OPTYPEIMAGE_MISMATCH);
291 const bool passImg = ((testType == TESTTYPE_PASS_IMAGE_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
292 const bool passSmp = ((testType == TESTTYPE_PASS_SAMPLER_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
293
294 std::string result = "";
295
296 switch (descType)
297 {
298 case DESCRIPTOR_TYPE_STORAGE_IMAGE:
299 {
300 switch (readOp)
301 {
302 case READOP_IMAGEREAD:
303 if (passNdx)
304 return " %func_img = OpLoad %Image %InputData\n";
305 break;
306
307 default:
308 DE_FATAL("Not possible");
309 break;
310 }
311 break;
312 }
313 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
314 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
315 {
316 switch (readOp)
317 {
318 case READOP_IMAGEFETCH:
319 if (passNdx)
320 return " %func_img = OpLoad %Image %InputData\n";
321
322 if (passSmp && !passImg)
323 return " %func_tmp = OpLoad %Image %InputData\n"
324 " %func_smi = OpSampledImage %SampledImage %func_tmp %func_smp\n"
325 " %func_img = OpImage %Image %func_smi\n";
326
327 if (passSmp && passImg)
328 return " %func_smi = OpSampledImage %SampledImage %func_tmp %func_smp\n"
329 " %func_img = OpImage %Image %func_smi\n";
330 break;
331
332 case READOP_IMAGESAMPLE:
333 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
334 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
335 if (passNdx)
336 return " %func_img = OpLoad %Image %InputData\n"
337 " %func_smp = OpLoad %Sampler %SamplerData\n"
338 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
339
340 if (passImg && !passSmp)
341 return " %func_smp = OpLoad %Sampler %SamplerData\n"
342 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
343
344 if (passSmp && !passImg)
345 return " %func_img = OpLoad %Image %InputData\n"
346 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
347
348 if (passSmp && passImg)
349 return " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
350 break;
351
352 default:
353 DE_FATAL("Not possible");
354 }
355 break;
356 }
357
358 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
359 {
360 switch (readOp)
361 {
362 case READOP_IMAGEFETCH:
363 if (passNdx)
364 return " %func_smi = OpLoad %SampledImage %InputData\n"
365 " %func_img = OpImage %Image %func_smi\n";
366 break;
367
368 case READOP_IMAGESAMPLE:
369 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
370 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
371 if (passNdx)
372 return " %func_smi = OpLoad %SampledImage %InputData\n";
373 break;
374
375 default:
376 DE_FATAL("Not possible");
377 }
378 break;
379 }
380
381 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
382 {
383 switch (readOp)
384 {
385 case READOP_IMAGEFETCH:
386 if (passNdx)
387 return " %func_img = OpLoad %Image %InputData2\n";
388
389 if (passSmp && !passImg)
390 return " %func_tmp = OpLoad %Image %InputData2\n"
391 " %func_smi = OpSampledImage %SampledImage %func_tmp %func_smp\n"
392 " %func_img = OpImage %Image %func_smi\n";
393
394 if (passSmp && passImg)
395 return " %func_smi = OpSampledImage %SampledImage %func_tmp %func_smp\n"
396 " %func_img = OpImage %Image %func_smi\n";
397 break;
398
399 case READOP_IMAGESAMPLE:
400 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
401 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
402 if (passNdx)
403 return " %func_img = OpLoad %Image %InputData2\n"
404 " %func_smp = OpLoad %Sampler %SamplerData\n"
405 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
406
407 if (passImg && !passSmp)
408 return " %func_smp = OpLoad %Sampler %SamplerData\n"
409 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
410
411 if (passSmp && !passImg)
412 return " %func_img = OpLoad %Image %InputData2\n"
413 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
414
415 if (passSmp && passImg)
416 return " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
417 break;
418
419 default:
420 DE_FATAL("Not possible");
421 }
422 break;
423 }
424
425 default:
426 DE_FATAL("Unknown descriptor type");
427 }
428
429 return result;
430 }
431
432 // Get variables that are passed to the read function
getFunctionSrcVariableStr(ReadOp readOp,DescriptorType descType,TestType testType)433 std::string getFunctionSrcVariableStr (ReadOp readOp, DescriptorType descType, TestType testType)
434 {
435 const bool passImg = ((testType == TESTTYPE_PASS_IMAGE_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
436 const bool passSmp = ((testType == TESTTYPE_PASS_SAMPLER_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
437
438 string result = "";
439
440 switch (descType)
441 {
442 case DESCRIPTOR_TYPE_STORAGE_IMAGE:
443 {
444 switch (readOp)
445 {
446 case READOP_IMAGEREAD:
447 if (passImg)
448 result += " %call_img = OpLoad %Image %InputData\n";
449 break;
450
451 default:
452 DE_FATAL("Not possible");
453 }
454 break;
455 }
456 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
457 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
458 {
459 switch (readOp)
460 {
461 case READOP_IMAGEFETCH:
462 case READOP_IMAGESAMPLE:
463 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
464 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
465 if (passImg)
466 result += " %call_img = OpLoad %Image %InputData\n";
467
468 if (passSmp)
469 result += " %call_smp = OpLoad %Sampler %SamplerData\n";
470 break;
471
472 default:
473 DE_FATAL("Not possible");
474 }
475 break;
476 }
477 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
478 {
479 break;
480 }
481 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
482 {
483 switch (readOp)
484 {
485 case READOP_IMAGEFETCH:
486 case READOP_IMAGESAMPLE:
487 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
488 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
489 if (passImg)
490 result += " %call_img = OpLoad %Image %InputData2\n";
491
492 if (passSmp)
493 result += " %call_smp = OpLoad %Sampler %SamplerData\n";
494 break;
495
496 default:
497 DE_FATAL("Not possible");
498 }
499 break;
500 }
501 default:
502 DE_FATAL("Unknown descriptor type");
503 }
504
505 return result;
506 }
507
508 // Get parameter types for OpTypeFunction
getFunctionParamTypeStr(TestType testType)509 std::string getFunctionParamTypeStr (TestType testType)
510 {
511 const bool passImg = ((testType == TESTTYPE_PASS_IMAGE_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
512 const bool passSmp = ((testType == TESTTYPE_PASS_SAMPLER_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
513
514 string result = "";
515
516 if (passImg)
517 result += " %Image";
518
519 if (passSmp)
520 result += " %Sampler";
521
522 return result;
523 }
524
525 // Get argument names for OpFunctionCall
getFunctionSrcParamStr(TestType testType)526 std::string getFunctionSrcParamStr (TestType testType)
527 {
528 const bool passImg = ((testType == TESTTYPE_PASS_IMAGE_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
529 const bool passSmp = ((testType == TESTTYPE_PASS_SAMPLER_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
530
531 string result = "";
532
533 if (passImg)
534 result += " %call_img";
535
536 if (passSmp)
537 result += " %call_smp";
538
539 return result;
540 }
541
542 // Get OpFunctionParameters
getFunctionDstParamStr(ReadOp readOp,TestType testType)543 std::string getFunctionDstParamStr (ReadOp readOp, TestType testType)
544 {
545 const bool passImg = ((testType == TESTTYPE_PASS_IMAGE_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
546 const bool passSmp = ((testType == TESTTYPE_PASS_SAMPLER_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
547
548 string result = "";
549
550 if (readOp == READOP_IMAGESAMPLE)
551 {
552 if (passImg)
553 result += " %func_img = OpFunctionParameter %Image\n";
554
555 if (passSmp)
556 result += " %func_smp = OpFunctionParameter %Sampler\n";
557 }
558 else
559 {
560 if (passImg && !passSmp)
561 result += " %func_img = OpFunctionParameter %Image\n";
562
563 if (passSmp && !passImg)
564 result += " %func_smp = OpFunctionParameter %Sampler\n";
565
566 if (passImg && passSmp)
567 result += " %func_tmp = OpFunctionParameter %Image\n"
568 " %func_smp = OpFunctionParameter %Sampler\n";
569 }
570
571 return result;
572 }
573
574 // Get read operation
getImageReadOpStr(ReadOp readOp)575 std::string getImageReadOpStr (ReadOp readOp)
576 {
577 switch (readOp)
578 {
579 case READOP_IMAGEREAD:
580 return "OpImageRead %v4f32 %func_img %coord";
581
582 case READOP_IMAGEFETCH:
583 return "OpImageFetch %v4f32 %func_img %coord";
584
585 case READOP_IMAGESAMPLE:
586 return "OpImageSampleExplicitLod %v4f32 %func_smi %normalcoordf Lod %c_f32_0";
587
588 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
589 return "OpImageSampleDrefImplicitLod %f32 %func_smi %normalcoordf %c_f32_0_5 Bias %c_f32_0";
590
591 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
592 return "OpImageSampleDrefExplicitLod %f32 %func_smi %normalcoordf %c_f32_0_5 Lod %c_f32_0";
593
594 default:
595 DE_FATAL("Unknown readop");
596 return "";
597 }
598 }
599
isImageSampleDrefReadOp(ReadOp readOp)600 bool isImageSampleDrefReadOp (ReadOp readOp)
601 {
602 return (readOp == READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD) || (readOp == READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD);
603 }
604
605 static const VkFormat optypeimageFormatMismatchVkFormat[] =
606 {
607 VK_FORMAT_R8G8B8A8_UNORM,
608 VK_FORMAT_R8G8B8A8_SNORM,
609 VK_FORMAT_R8G8B8A8_UINT,
610 VK_FORMAT_R8G8B8A8_SINT,
611 VK_FORMAT_R16G16B16A16_UINT,
612 VK_FORMAT_R16G16B16A16_SINT,
613 VK_FORMAT_R16G16B16A16_SFLOAT,
614 VK_FORMAT_R32_UINT,
615 VK_FORMAT_R32_SINT,
616 VK_FORMAT_R32G32B32A32_UINT,
617 VK_FORMAT_R32G32B32A32_SINT,
618 VK_FORMAT_R32G32B32A32_SFLOAT
619 };
620
621 static const size_t optypeimageFormatMismatchFormatCount = sizeof(optypeimageFormatMismatchVkFormat) / sizeof(VkFormat);
622
623 static const char *optypeimageFormatMismatchSpirvFormat[] =
624 {
625 "Rgba8",
626 "Rgba8Snorm",
627 "Rgba8ui",
628 "Rgba8i",
629 "Rgba16ui",
630 "Rgba16i",
631 "Rgba16f",
632 "R32ui",
633 "R32i",
634 "Rgba32ui",
635 "Rgba32i",
636 "Rgba32f"
637 };
638
639 static const char *optypeimageFormatMismatchCase[] =
640 {
641 "rgba8",
642 "rgba8snorm",
643 "rgba8ui",
644 "rgba8i",
645 "rgba16ui",
646 "rgba16i",
647 "rgba16f",
648 "r32ui",
649 "r32i",
650 "rgba32ui",
651 "rgba32i",
652 "rgba32f"
653 };
654
655 // Get types and pointers for input images and samplers
getImageSamplerTypeStr(DescriptorType descType,ReadOp readOp,deUint32 depthProperty,TestType testType,int formatIndex)656 std::string getImageSamplerTypeStr (DescriptorType descType, ReadOp readOp, deUint32 depthProperty, TestType testType, int formatIndex)
657 {
658 const string imageFormat = (testType == TESTTYPE_OPTYPEIMAGE_MISMATCH) ? optypeimageFormatMismatchSpirvFormat[formatIndex] :
659 isImageSampleDrefReadOp(readOp) ? "R32f" : "Rgba32f";
660
661 switch (descType)
662 {
663 case DESCRIPTOR_TYPE_STORAGE_IMAGE:
664 return " %Image = OpTypeImage %f32 2D " + de::toString(depthProperty) + " 0 0 2 " + imageFormat + "\n"
665 " %ImagePtr = OpTypePointer UniformConstant %Image\n"
666 " %InputData = OpVariable %ImagePtr UniformConstant\n";
667
668 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
669 return " %Image = OpTypeImage %f32 2D " + de::toString(depthProperty) + " 0 0 1 " + imageFormat + "\n"
670 " %ImagePtr = OpTypePointer UniformConstant %Image\n"
671 " %InputData = OpVariable %ImagePtr UniformConstant\n"
672
673 " %Sampler = OpTypeSampler\n"
674 " %SamplerPtr = OpTypePointer UniformConstant %Sampler\n"
675 " %SamplerData = OpVariable %SamplerPtr UniformConstant\n"
676 " %SampledImage = OpTypeSampledImage %Image\n";
677
678 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
679 return " %Image = OpTypeImage %f32 2D " + de::toString(depthProperty) + " 0 0 1 " + imageFormat + "\n"
680 " %SampledImage = OpTypeSampledImage %Image\n"
681 " %SamplerPtr = OpTypePointer UniformConstant %SampledImage\n"
682 " %InputData = OpVariable %SamplerPtr UniformConstant\n";
683
684 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
685 return " %Image = OpTypeImage %f32 2D " + de::toString(depthProperty) + " 0 0 1 " + imageFormat + "\n"
686 " %ImagePtr = OpTypePointer UniformConstant %Image\n"
687 " %InputData = OpVariable %ImagePtr UniformConstant\n"
688
689 " %Sampler = OpTypeSampler\n"
690 " %SamplerPtr = OpTypePointer UniformConstant %Sampler\n"
691 " %SamplerData = OpVariable %SamplerPtr UniformConstant\n"
692 " %SampledImage = OpTypeSampledImage %Image\n";
693
694 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
695 return " %Image = OpTypeImage %f32 2D " + de::toString(depthProperty) + " 0 0 1 " + imageFormat + "\n"
696 " %ImagePtr = OpTypePointer UniformConstant %Image\n"
697 " %InputData = OpVariable %ImagePtr UniformConstant\n"
698 " %InputData2 = OpVariable %ImagePtr UniformConstant\n"
699
700 " %Sampler = OpTypeSampler\n"
701 " %SamplerPtr = OpTypePointer UniformConstant %Sampler\n"
702 " %SamplerData = OpVariable %SamplerPtr UniformConstant\n"
703 " %SamplerData2 = OpVariable %SamplerPtr UniformConstant\n"
704 " %SampledImage = OpTypeSampledImage %Image\n";
705
706 default:
707 DE_FATAL("Unknown descriptor type");
708 return "";
709 }
710 }
711
getSamplerDecoration(DescriptorType descType)712 std::string getSamplerDecoration (DescriptorType descType)
713 {
714 switch (descType)
715 {
716 // Separate image and sampler
717 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
718 return " OpDecorate %SamplerData DescriptorSet 0\n"
719 " OpDecorate %SamplerData Binding 1\n";
720
721 // Combined image sampler with separate variables
722 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
723 return " OpDecorate %SamplerData DescriptorSet 0\n"
724 " OpDecorate %SamplerData Binding 0\n";
725
726 // Two combined image samplers with separate variables
727 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
728 return " OpDecorate %SamplerData DescriptorSet 0\n"
729 " OpDecorate %SamplerData Binding 0\n"
730 " OpDecorate %InputData2 DescriptorSet 0\n"
731 " OpDecorate %InputData2 Binding 1\n"
732 " OpDecorate %SamplerData2 DescriptorSet 0\n"
733 " OpDecorate %SamplerData2 Binding 1\n";
734
735 default:
736 return "";
737 }
738 }
739
740 // no-operation verify functon to ignore test results (optypeimage_mismatch)
nopVerifyFunction(const std::vector<Resource> &,const std::vector<AllocationSp> &,const std::vector<Resource> &,tcu::TestLog &)741 bool nopVerifyFunction (const std::vector<Resource>&,
742 const std::vector<AllocationSp>&,
743 const std::vector<Resource>&,
744 tcu::TestLog&)
745 {
746 return true;
747 }
748
addComputeImageSamplerTest(tcu::TestCaseGroup * group)749 void addComputeImageSamplerTest (tcu::TestCaseGroup* group)
750 {
751 tcu::TestContext& testCtx = group->getTestContext();
752
753 de::Random rnd (deStringHash(group->getName()));
754 const deUint32 numDataPoints = 64;
755 RGBA defaultColors[4];
756 vector<tcu::Vec4> inputData;
757
758 inputData.reserve(numDataPoints);
759
760 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
761 inputData.push_back(tcu::Vec4(rnd.getFloat(), rnd.getFloat(), rnd.getFloat(), rnd.getFloat()));
762
763 for (deUint32 opNdx = 0u; opNdx <= READOP_IMAGESAMPLE; opNdx++)
764 {
765 de::MovePtr<tcu::TestCaseGroup> readOpGroup (new tcu::TestCaseGroup(testCtx, getReadOpName((ReadOp)opNdx), ""));
766
767 for (deUint32 descNdx = 0u; descNdx < DESCRIPTOR_TYPE_LAST; descNdx++)
768 {
769 de::MovePtr<tcu::TestCaseGroup> descGroup (new tcu::TestCaseGroup(testCtx, getDescriptorName((DescriptorType)descNdx), ""));
770
771 for (deUint32 testNdx = 0u; testNdx < TESTTYPE_LAST; testNdx++)
772 {
773 if (!isValidTestCase((TestType)testNdx, (DescriptorType)descNdx, (ReadOp)opNdx))
774 continue;
775
776 deUint32 numFormats = 1;
777 if (testNdx == TESTTYPE_OPTYPEIMAGE_MISMATCH)
778 numFormats = optypeimageFormatMismatchFormatCount;
779
780 for (deUint32 formatIndex = 0; formatIndex < numFormats; formatIndex++)
781 {
782
783 const std::string imageReadOp = getImageReadOpStr((ReadOp)opNdx);
784
785 const std::string imageSamplerTypes = getImageSamplerTypeStr((DescriptorType)descNdx, (ReadOp)opNdx, DEPTH_PROPERTY_NON_DEPTH, (TestType)testNdx, formatIndex);
786 const std::string functionParamTypes = getFunctionParamTypeStr((TestType)testNdx);
787
788 const std::string functionSrcVariables = getFunctionSrcVariableStr((ReadOp)opNdx, (DescriptorType)descNdx, (TestType)testNdx);
789 const std::string functionDstVariables = getFunctionDstVariableStr((ReadOp)opNdx, (DescriptorType)descNdx, (TestType)testNdx);
790
791 const std::string functionSrcParams = getFunctionSrcParamStr((TestType)testNdx);
792 const std::string functionDstParams = getFunctionDstParamStr((ReadOp)opNdx, (TestType)testNdx);
793
794 getDefaultColors(defaultColors);
795
796 ComputeShaderSpec spec;
797
798 spec.numWorkGroups = IVec3(numDataPoints, 1, 1);
799
800 spec.inputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), getVkDescriptorType((DescriptorType)descNdx)));
801
802 // Separate sampler for sampled images
803 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_SAMPLED_IMAGE)
804 {
805 vector<tcu::Vec4> dummyData;
806 spec.inputs.push_back(Resource(BufferSp(new Vec4Buffer(dummyData))));
807 spec.inputs[1].setDescriptorType(VK_DESCRIPTOR_TYPE_SAMPLER);
808 }
809
810 // Second combined image sampler with different image data
811 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
812 {
813 for (size_t i = 0; i < inputData.size(); i++)
814 inputData[i] = tcu::Vec4(1.0f) - inputData[i];
815
816 spec.inputs.push_back(BufferSp(new Vec4Buffer(inputData)));
817 spec.inputs[1].setDescriptorType(getVkDescriptorType((DescriptorType)descNdx));
818 }
819
820 // Shader is expected to pass the input image data to the output buffer
821 spec.outputs.push_back(BufferSp(new Vec4Buffer(inputData)));
822
823 const std::string samplerDecoration = getSamplerDecoration((DescriptorType)descNdx);
824
825 const string shaderSource =
826 " OpCapability Shader\n"
827 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
828 " OpMemoryModel Logical GLSL450\n"
829 " OpEntryPoint GLCompute %main \"main\" %id\n"
830 " OpExecutionMode %main LocalSize 1 1 1\n"
831 " OpSource GLSL 430\n"
832 " OpDecorate %id BuiltIn GlobalInvocationId\n"
833 " OpDecorate %_arr_v4f_u32_64 ArrayStride 16\n"
834 " OpMemberDecorate %Output 0 Offset 0\n"
835 " OpDecorate %Output BufferBlock\n"
836 " OpDecorate %InputData DescriptorSet 0\n"
837 " OpDecorate %InputData Binding 0\n"
838
839 + samplerDecoration +
840
841 " OpDecorate %OutputData DescriptorSet 0\n"
842 " OpDecorate %OutputData Binding " + de::toString(spec.inputs.size()) + "\n"
843
844 " %void = OpTypeVoid\n"
845 " %3 = OpTypeFunction %void\n"
846 " %u32 = OpTypeInt 32 0\n"
847 " %i32 = OpTypeInt 32 1\n"
848 " %f32 = OpTypeFloat 32\n"
849 " %_ptr_Function_uint = OpTypePointer Function %u32\n"
850 " %v3u32 = OpTypeVector %u32 3\n"
851 " %_ptr_Input_v3u32 = OpTypePointer Input %v3u32\n"
852 " %id = OpVariable %_ptr_Input_v3u32 Input\n"
853 " %c_f32_0 = OpConstant %f32 0.0\n"
854 " %c_u32_0 = OpConstant %u32 0\n"
855 " %c_i32_0 = OpConstant %i32 0\n"
856 " %_ptr_Input_uint = OpTypePointer Input %u32\n"
857 " %v2u32 = OpTypeVector %u32 2\n"
858 " %v2f32 = OpTypeVector %f32 2\n"
859 " %v4f32 = OpTypeVector %f32 4\n"
860 " %uint_128 = OpConstant %u32 128\n"
861 " %c_u32_64 = OpConstant %u32 64\n"
862 " %c_u32_8 = OpConstant %u32 8\n"
863 " %c_f32_8 = OpConstant %f32 8.0\n"
864 " %c_v2f32_8_8 = OpConstantComposite %v2f32 %c_f32_8 %c_f32_8\n"
865 " %_arr_v4f_u32_64 = OpTypeArray %v4f32 %c_u32_64\n"
866 " %_ptr_Uniform_v4f = OpTypePointer Uniform %v4f32\n"
867 " %Output = OpTypeStruct %_arr_v4f_u32_64\n"
868 "%_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
869 " %OutputData = OpVariable %_ptr_Uniform_Output Uniform\n"
870
871 + imageSamplerTypes +
872
873 " %read_func_type = OpTypeFunction %void %u32" + functionParamTypes + "\n"
874
875 " %read_func = OpFunction %void None %read_func_type\n"
876 " %func_ndx = OpFunctionParameter %u32\n"
877
878 + functionDstParams +
879
880 " %funcentry = OpLabel\n"
881 " %row = OpUMod %u32 %func_ndx %c_u32_8\n"
882 " %col = OpUDiv %u32 %func_ndx %c_u32_8\n"
883 " %coord = OpCompositeConstruct %v2u32 %row %col\n"
884 " %coordf = OpConvertUToF %v2f32 %coord\n"
885 " %normalcoordf = OpFDiv %v2f32 %coordf %c_v2f32_8_8\n"
886
887 + functionDstVariables +
888
889 " %color = " + imageReadOp + "\n"
890 " %36 = OpAccessChain %_ptr_Uniform_v4f %OutputData %c_u32_0 %func_ndx\n"
891 " OpStore %36 %color\n"
892 " OpReturn\n"
893 " OpFunctionEnd\n"
894
895 " %main = OpFunction %void None %3\n"
896 " %5 = OpLabel\n"
897 " %i = OpVariable %_ptr_Function_uint Function\n"
898 " %14 = OpAccessChain %_ptr_Input_uint %id %c_u32_0\n"
899 " %15 = OpLoad %u32 %14\n"
900 " OpStore %i %15\n"
901 " %index = OpLoad %u32 %14\n"
902
903 + functionSrcVariables +
904
905 " %res = OpFunctionCall %void %read_func %index" + functionSrcParams + "\n"
906 " OpReturn\n"
907 " OpFunctionEnd\n";
908
909 spec.assembly = shaderSource;
910
911 // If testing for mismatched optypeimage, ignore the
912 // result (we're only interested to see if we crash)
913 if (testNdx == TESTTYPE_OPTYPEIMAGE_MISMATCH)
914 spec.verifyIO = nopVerifyFunction;
915
916 string testname = getTestTypeName((TestType)testNdx);
917
918 if (testNdx == TESTTYPE_OPTYPEIMAGE_MISMATCH)
919 testname = testname + string("_") + string(optypeimageFormatMismatchCase[formatIndex]);
920
921 descGroup->addChild(new SpvAsmComputeShaderCase(testCtx, testname.c_str(), "", spec));
922 }
923 }
924 readOpGroup->addChild(descGroup.release());
925 }
926 group->addChild(readOpGroup.release());
927 }
928 }
929
generateGraphicsImageSamplerSource(ReadOp readOp,DescriptorType descriptorType,TestType testType,DepthProperty depthProperty,deUint32 outputBinding,deUint32 formatIndex)930 map<string, string> generateGraphicsImageSamplerSource (ReadOp readOp, DescriptorType descriptorType, TestType testType, DepthProperty depthProperty, deUint32 outputBinding, deUint32 formatIndex)
931 {
932 map<string, string> source;
933
934 const std::string imageReadOp = getImageReadOpStr(readOp);
935 const std::string imageSamplerTypes = getImageSamplerTypeStr(descriptorType, readOp, depthProperty, testType, formatIndex);
936 const std::string functionParamTypes = getFunctionParamTypeStr(testType);
937 const std::string functionSrcVariables = getFunctionSrcVariableStr(readOp, descriptorType, testType);
938 const std::string functionDstVariables = getFunctionDstVariableStr(readOp, descriptorType, testType);
939 const std::string functionSrcParams = getFunctionSrcParamStr(testType);
940 const std::string functionDstParams = getFunctionDstParamStr(readOp, testType);
941 const std::string samplerDecoration = getSamplerDecoration(descriptorType);
942 const std::string outputUniformPtr = isImageSampleDrefReadOp(readOp) ? "%_ptr_Uniform_f32" : "%_ptr_Uniform_v4f32";
943 const std::string outputArrayStruct = isImageSampleDrefReadOp(readOp) ? "%_arr_f32_u32_64" : "%_arr_v4f32_u32_64";
944
945 source["pre_main"] =
946 " %c_u32_64 = OpConstant %u32 64\n"
947 " %c_i32_64 = OpConstant %i32 64\n"
948 " %c_i32_8 = OpConstant %i32 8\n"
949 " %c_v2f32_8_8 = OpConstantComposite %v2f32 %c_f32_8 %c_f32_8\n"
950
951 " %_arr_f32_u32_64 = OpTypeArray %f32 %c_u32_64\n"
952 " %_arr_v4f32_u32_64 = OpTypeArray %v4f32 %c_u32_64\n"
953 " %_ptr_Uniform_f32 = OpTypePointer Uniform %f32\n"
954 " %_ptr_Uniform_v4f32 = OpTypePointer Uniform %v4f32\n"
955
956 " %Output = OpTypeStruct " + outputArrayStruct + "\n"
957 "%_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
958 " %OutputData = OpVariable %_ptr_Uniform_Output Uniform\n"
959
960 + imageSamplerTypes +
961
962 " %read_func_type = OpTypeFunction %void %i32" + functionParamTypes + "\n";
963
964 source["decoration"] =
965 " OpDecorate %_arr_f32_u32_64 ArrayStride 4\n"
966 " OpDecorate %_arr_v4f32_u32_64 ArrayStride 16\n"
967 " OpMemberDecorate %Output 0 Offset 0\n"
968 " OpDecorate %Output BufferBlock\n"
969 " OpDecorate %InputData DescriptorSet 0\n"
970 " OpDecorate %InputData Binding 0\n"
971
972 + samplerDecoration +
973
974 "OpDecorate %OutputData DescriptorSet 0\n"
975 "OpDecorate %OutputData Binding " + de::toString(outputBinding) + "\n";
976
977 source["testfun"] =
978 " %read_func = OpFunction %void None %read_func_type\n"
979 " %func_ndx = OpFunctionParameter %i32\n"
980
981 + functionDstParams +
982
983 " %funcentry = OpLabel\n"
984
985 " %row = OpSRem %i32 %func_ndx %c_i32_8\n"
986 " %col = OpSDiv %i32 %func_ndx %c_i32_8\n"
987 " %coord = OpCompositeConstruct %v2i32 %row %col\n"
988 " %coordf = OpConvertSToF %v2f32 %coord\n"
989 " %normalcoordf = OpFDiv %v2f32 %coordf %c_v2f32_8_8\n"
990
991 + functionDstVariables +
992
993 " %color = " + imageReadOp + "\n"
994 " %36 = OpAccessChain " + outputUniformPtr + " %OutputData %c_i32_0 %func_ndx\n"
995 " OpStore %36 %color\n"
996
997 " OpReturn\n"
998 " OpFunctionEnd\n"
999
1000 " %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
1001 " %param = OpFunctionParameter %v4f32\n"
1002
1003 " %entry = OpLabel\n"
1004
1005 " %i = OpVariable %fp_i32 Function\n"
1006 " OpStore %i %c_i32_0\n"
1007 " OpBranch %loop\n"
1008
1009 " %loop = OpLabel\n"
1010 " %15 = OpLoad %i32 %i\n"
1011 " %lt = OpSLessThan %bool %15 %c_i32_64\n"
1012 " OpLoopMerge %merge %inc None\n"
1013 " OpBranchConditional %lt %write %merge\n"
1014
1015 " %write = OpLabel\n"
1016 " %index = OpLoad %i32 %i\n"
1017
1018 + functionSrcVariables +
1019
1020 " %res = OpFunctionCall %void %read_func %index" + functionSrcParams + "\n"
1021 " OpBranch %inc\n"
1022
1023 " %inc = OpLabel\n"
1024
1025 " %37 = OpLoad %i32 %i\n"
1026 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
1027 " OpStore %i %39\n"
1028 " OpBranch %loop\n"
1029
1030 " %merge = OpLabel\n"
1031 " OpReturnValue %param\n"
1032 " OpFunctionEnd\n";
1033
1034 return source;
1035 }
1036
addGraphicsImageSamplerTest(tcu::TestCaseGroup * group)1037 void addGraphicsImageSamplerTest (tcu::TestCaseGroup* group)
1038 {
1039 tcu::TestContext& testCtx = group->getTestContext();
1040
1041 de::Random rnd (deStringHash(group->getName()));
1042 const deUint32 numDataPoints = 64;
1043 RGBA defaultColors[4];
1044
1045 SpecConstants noSpecConstants;
1046 PushConstants noPushConstants;
1047 GraphicsInterfaces noInterfaces;
1048 std::vector<std::string> noExtensions;
1049 VulkanFeatures vulkanFeatures = VulkanFeatures();
1050
1051 vector<tcu::Vec4> inputData(numDataPoints);
1052 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
1053 inputData[numIdx] = tcu::Vec4(rnd.getFloat(), rnd.getFloat(), rnd.getFloat(), rnd.getFloat());
1054
1055 for (deUint32 opNdx = 0u; opNdx <= READOP_IMAGESAMPLE; opNdx++)
1056 {
1057 de::MovePtr<tcu::TestCaseGroup> readOpGroup (new tcu::TestCaseGroup(testCtx, getReadOpName((ReadOp)opNdx), ""));
1058
1059 for (deUint32 descNdx = 0u; descNdx < DESCRIPTOR_TYPE_LAST; descNdx++)
1060 {
1061 de::MovePtr<tcu::TestCaseGroup> descGroup (new tcu::TestCaseGroup(testCtx, getDescriptorName((DescriptorType)descNdx), ""));
1062
1063 for (deUint32 testNdx = 0u; testNdx < TESTTYPE_LAST; testNdx++)
1064 {
1065 if (!isValidTestCase((TestType)testNdx, (DescriptorType)descNdx, (ReadOp)opNdx))
1066 continue;
1067
1068 deUint32 formatCount = 1;
1069 if (testNdx == TESTTYPE_OPTYPEIMAGE_MISMATCH)
1070 formatCount = optypeimageFormatMismatchFormatCount;
1071
1072 // this group is only used for optypeimage_mismatch case
1073 de::MovePtr<tcu::TestCaseGroup> testtypeGroup(new tcu::TestCaseGroup(testCtx, getTestTypeName((TestType)testNdx), ""));
1074
1075 for (deUint32 formatIndex = 0; formatIndex < formatCount; formatIndex++)
1076 {
1077 // optypeimage_mismatch uses an additional level of test hierarchy
1078 const char *groupname = testNdx == TESTTYPE_OPTYPEIMAGE_MISMATCH ? optypeimageFormatMismatchCase[formatIndex] : getTestTypeName((TestType)testNdx);
1079 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, groupname, ""));
1080
1081 GraphicsResources resources;
1082
1083 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), getVkDescriptorType((DescriptorType)descNdx)));
1084
1085 // Separate sampler for sampled images
1086 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1087 {
1088 vector<tcu::Vec4> dummyData;
1089 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(dummyData)), VK_DESCRIPTOR_TYPE_SAMPLER));
1090 }
1091
1092 // Second combined image sampler with different image data
1093 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
1094 {
1095 for (size_t i = 0; i < inputData.size(); i++)
1096 inputData[i] = tcu::Vec4(1.0f) - inputData[i];
1097
1098 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), getVkDescriptorType((DescriptorType)descNdx)));
1099 }
1100
1101 // Shader is expected to pass the input image data to output buffer
1102 resources.outputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
1103
1104 getDefaultColors(defaultColors);
1105
1106 const map<string, string> fragments = generateGraphicsImageSamplerSource((ReadOp)opNdx, (DescriptorType)descNdx, (TestType)testNdx, DEPTH_PROPERTY_NON_DEPTH, (deUint32)resources.inputs.size(), (formatIndex + 1) % optypeimageFormatMismatchFormatCount);
1107
1108 // If testing for mismatched optypeimage, ignore the rendered
1109 // result (we're only interested to see if we crash)
1110 if (testNdx == TESTTYPE_OPTYPEIMAGE_MISMATCH)
1111 {
1112 resources.verifyIO = nopVerifyFunction;
1113 resources.inputFormat = optypeimageFormatMismatchVkFormat[formatIndex];
1114 }
1115
1116 vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
1117 vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_FALSE;
1118 createTestForStage(VK_SHADER_STAGE_VERTEX_BIT, "shader_vert", defaultColors, defaultColors, fragments, noSpecConstants,
1119 noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, typeGroup.get());
1120
1121 createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "shader_tessc", defaultColors, defaultColors, fragments, noSpecConstants,
1122 noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, typeGroup.get());
1123
1124 createTestForStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "shader_tesse", defaultColors, defaultColors, fragments, noSpecConstants,
1125 noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, typeGroup.get());
1126
1127 createTestForStage(VK_SHADER_STAGE_GEOMETRY_BIT, "shader_geom", defaultColors, defaultColors, fragments, noSpecConstants,
1128 noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, typeGroup.get());
1129
1130 vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE;
1131 vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_TRUE;
1132 createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, "shader_frag", defaultColors, defaultColors, fragments, noSpecConstants,
1133 noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, typeGroup.get());
1134
1135 if (testNdx == TESTTYPE_OPTYPEIMAGE_MISMATCH)
1136 testtypeGroup->addChild(typeGroup.release());
1137 else
1138 descGroup->addChild(typeGroup.release());
1139 }
1140 if (testNdx == TESTTYPE_OPTYPEIMAGE_MISMATCH)
1141 descGroup->addChild(testtypeGroup.release());
1142 }
1143 readOpGroup->addChild(descGroup.release());
1144 }
1145 group->addChild(readOpGroup.release());
1146 }
1147 }
1148
verifyDepthCompareResult(const std::vector<Resource> & originalFloats,const std::vector<AllocationSp> & outputAllocs,const std::vector<Resource> & expectedOutputs,tcu::TestLog &)1149 bool verifyDepthCompareResult (const std::vector<Resource>& originalFloats,
1150 const std::vector<AllocationSp>& outputAllocs,
1151 const std::vector<Resource>& expectedOutputs,
1152 tcu::TestLog&)
1153 {
1154 DE_UNREF(originalFloats);
1155
1156 if (outputAllocs.size() != expectedOutputs.size())
1157 return false;
1158
1159 vector<deUint8> expectedBytes;
1160 expectedOutputs[0].getBytes(expectedBytes);
1161
1162 const float* returnedAsFloat = static_cast<const float*>(outputAllocs[0]->getHostPtr());
1163 const float* expectedAsFloat = reinterpret_cast<const float*>(&expectedBytes.front());
1164
1165 for (deUint32 elementNdx = 0; elementNdx < static_cast<deUint32>(expectedBytes.size() / sizeof(float)); ++elementNdx)
1166 {
1167 const float input = expectedAsFloat[elementNdx];
1168 const float result = returnedAsFloat[elementNdx];
1169
1170 // VK_COMPARE_OP_LESS: D = 1.0 if D < Dref, otherwise D = 0.0
1171 if ((input < 0.5f && result != 0.0f) || (input >= 0.5f && result != 1.0f))
1172 return false;
1173 }
1174
1175 return true;
1176 }
1177
addGraphicsDepthPropertyTest(tcu::TestCaseGroup * group)1178 void addGraphicsDepthPropertyTest (tcu::TestCaseGroup* group)
1179 {
1180 tcu::TestContext& testCtx = group->getTestContext();
1181
1182 de::Random rnd (deStringHash(group->getName()));
1183 const deUint32 numDataPoints = 64;
1184 RGBA defaultColors[4];
1185 vector<Vec4> inputDataVec4;
1186
1187 SpecConstants noSpecConstants;
1188 PushConstants noPushConstants;
1189 GraphicsInterfaces noInterfaces;
1190 std::vector<std::string> noExtensions;
1191 VulkanFeatures vulkanFeatures = VulkanFeatures();
1192
1193 vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE;
1194 vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_TRUE;
1195
1196 inputDataVec4.reserve(numDataPoints);
1197
1198 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
1199 inputDataVec4.push_back(Vec4(rnd.getFloat(), rnd.getFloat(), rnd.getFloat(), rnd.getFloat()));
1200
1201 de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, "depth_property", ""));
1202
1203 for (deUint32 propertyNdx = 0u; propertyNdx < DEPTH_PROPERTY_LAST; propertyNdx++)
1204 {
1205 de::MovePtr<tcu::TestCaseGroup> depthPropertyGroup (new tcu::TestCaseGroup(testCtx, getDepthPropertyName((DepthProperty)propertyNdx), ""));
1206
1207 for (deUint32 opNdx = 0u; opNdx < READOP_LAST; opNdx++)
1208 {
1209 de::MovePtr<tcu::TestCaseGroup> readOpGroup (new tcu::TestCaseGroup(testCtx, getReadOpName((ReadOp)opNdx), ""));
1210
1211 for (deUint32 descNdx = DESCRIPTOR_TYPE_SAMPLED_IMAGE; descNdx < DESCRIPTOR_TYPE_LAST; descNdx++)
1212 {
1213 de::MovePtr<tcu::TestCaseGroup> descGroup (new tcu::TestCaseGroup(testCtx, getDescriptorName((DescriptorType)descNdx), ""));
1214
1215 if (!isValidTestCase(TESTTYPE_LOCAL_VARIABLES, (DescriptorType)descNdx, (ReadOp)opNdx))
1216 continue;
1217
1218 const VkFormat imageFormat = getImageFormat((ReadOp)opNdx);
1219 const bool hasDpethComponent = tcu::hasDepthComponent(vk::mapVkFormat(imageFormat).order);
1220
1221 GraphicsResources resources;
1222 resources.inputFormat = imageFormat;
1223
1224 std::vector<Vec4> inputData = inputDataVec4;
1225
1226 // Depth images have one channel, thus only needing 1/4 of the data
1227 if (hasDpethComponent)
1228 inputData.resize(numDataPoints / 4u);
1229
1230 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), getVkDescriptorType((DescriptorType)descNdx)));
1231
1232 // Separate sampler for sampled images
1233 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1234 {
1235 vector<Vec4> dummyData;
1236 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(dummyData)), VK_DESCRIPTOR_TYPE_SAMPLER));
1237 }
1238
1239 // Second combined image sampler with different image data
1240 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
1241 {
1242 for (size_t i = 0; i < inputData.size(); i++)
1243 inputData[i] = Vec4(1.0f) - inputData[i];
1244
1245 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), getVkDescriptorType((DescriptorType)descNdx)));
1246 }
1247
1248 // Read image without depth reference: shader is expected to pass the input image data to output buffer
1249 resources.outputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
1250
1251 // Read image with depth reference: shader is expected to pass the depth comparison result to output buffer
1252 if (hasDpethComponent)
1253 resources.verifyIO = verifyDepthCompareResult;
1254
1255 const map<string, string> fragments = generateGraphicsImageSamplerSource((ReadOp)opNdx, (DescriptorType)descNdx, TESTTYPE_LOCAL_VARIABLES, (DepthProperty)propertyNdx, (deUint32)resources.inputs.size(), 0);
1256
1257 getDefaultColors(defaultColors);
1258
1259 createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, "shader_frag", defaultColors, defaultColors, fragments, noSpecConstants,
1260 noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, descGroup.get());
1261
1262 readOpGroup->addChild(descGroup.release());
1263 }
1264 depthPropertyGroup->addChild(readOpGroup.release());
1265 }
1266 testGroup->addChild(depthPropertyGroup.release());
1267 }
1268 group->addChild(testGroup.release());
1269 }
1270 } // anonymous
1271
createImageSamplerComputeGroup(tcu::TestContext & testCtx)1272 tcu::TestCaseGroup* createImageSamplerComputeGroup (tcu::TestContext& testCtx)
1273 {
1274 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "image_sampler", "Compute tests for combining images and samplers."));
1275 addComputeImageSamplerTest(group.get());
1276
1277 return group.release();
1278 }
1279
createImageSamplerGraphicsGroup(tcu::TestContext & testCtx)1280 tcu::TestCaseGroup* createImageSamplerGraphicsGroup (tcu::TestContext& testCtx)
1281 {
1282 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "image_sampler", "Graphics tests for combining images and samplers."));
1283
1284 addGraphicsImageSamplerTest(group.get());
1285 addGraphicsDepthPropertyTest(group.get());
1286
1287 return group.release();
1288 }
1289
1290 } // SpirVAssembly
1291 } // vkt
1292