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