Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / renderpass / vktRenderPassMultisampleTests.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 Tests for render passses with multisample attachments
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassMultisampleTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
29
30 #include "vkDefs.hpp"
31 #include "vkDeviceUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPlatform.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
42
43 #include "tcuFloat.hpp"
44 #include "tcuImageCompare.hpp"
45 #include "tcuFormatUtil.hpp"
46 #include "tcuMaybe.hpp"
47 #include "tcuResultCollector.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuTextureUtil.hpp"
50 #include "tcuVectorUtil.hpp"
51
52 #include "deUniquePtr.hpp"
53 #include "deSharedPtr.hpp"
54
55 using namespace vk;
56
57 using tcu::BVec4;
58 using tcu::IVec2;
59 using tcu::IVec4;
60 using tcu::UVec2;
61 using tcu::UVec4;
62 using tcu::Vec2;
63 using tcu::Vec4;
64
65 using tcu::Maybe;
66 using tcu::just;
67
68 using tcu::ConstPixelBufferAccess;
69 using tcu::PixelBufferAccess;
70
71 using tcu::TestLog;
72
73 using std::pair;
74 using std::string;
75 using std::vector;
76
77 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp;
78 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
79 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp;
80 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp;
81
82 namespace vkt
83 {
84 namespace
85 {
86 using namespace renderpass;
87
88 enum
89 {
90         MAX_COLOR_ATTACHMENT_COUNT = 4u
91 };
92
93 enum TestSeparateUsage
94 {
95         TEST_DEPTH       = (1 << 0),
96         TEST_STENCIL = (1 << 1)
97 };
98
99 template<typename T>
100 de::SharedPtr<T> safeSharedPtr (T* ptr)
101 {
102         try
103         {
104                 return de::SharedPtr<T>(ptr);
105         }
106         catch (...)
107         {
108                 delete ptr;
109                 throw;
110         }
111 }
112
113 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
114 {
115         const tcu::TextureFormat        format          (mapVkFormat(vkFormat));
116         const bool                                      hasDepth        (tcu::hasDepthComponent(format.order));
117         const bool                                      hasStencil      (tcu::hasStencilComponent(format.order));
118
119         if (hasDepth || hasStencil)
120         {
121                 return (hasDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : (VkImageAspectFlagBits)0u)
122                                 | (hasStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : (VkImageAspectFlagBits)0u);
123         }
124         else
125                 return VK_IMAGE_ASPECT_COLOR_BIT;
126 }
127
128 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
129 {
130         VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
131 }
132
133 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
134 {
135         VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
136 }
137
138 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface&      vk,
139                                                                                         VkDevice                                device,
140                                                                                         Allocator&                              allocator,
141                                                                                         VkBuffer                                buffer)
142 {
143         de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
144         bindBufferMemory(vk, device, buffer, allocation->getMemory(), allocation->getOffset());
145         return allocation;
146 }
147
148 de::MovePtr<Allocation> createImageMemory (const DeviceInterface&       vk,
149                                                                                    VkDevice                                     device,
150                                                                                    Allocator&                           allocator,
151                                                                                    VkImage                                      image)
152 {
153         de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
154         bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
155         return allocation;
156 }
157
158 Move<VkImage> createImage (const DeviceInterface&       vk,
159                                                    VkDevice                                     device,
160                                                    VkImageCreateFlags           flags,
161                                                    VkImageType                          imageType,
162                                                    VkFormat                                     format,
163                                                    VkExtent3D                           extent,
164                                                    deUint32                                     mipLevels,
165                                                    deUint32                                     arrayLayers,
166                                                    VkSampleCountFlagBits        samples,
167                                                    VkImageTiling                        tiling,
168                                                    VkImageUsageFlags            usage,
169                                                    VkSharingMode                        sharingMode,
170                                                    deUint32                                     queueFamilyCount,
171                                                    const deUint32*                      pQueueFamilyIndices,
172                                                    VkImageLayout                        initialLayout,
173                                                    TestSeparateUsage            separateStencilUsage)
174 {
175         VkImageUsageFlags depthUsage    = (separateStencilUsage == TEST_DEPTH)   ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
176         VkImageUsageFlags stencilUsage  = (separateStencilUsage == TEST_STENCIL) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
177
178         const VkImageStencilUsageCreateInfo stencilUsageInfo =
179         {
180                 VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
181                 DE_NULL,
182                 stencilUsage
183         };
184
185         const VkImageCreateInfo pCreateInfo =
186         {
187                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
188                 separateStencilUsage ? &stencilUsageInfo : DE_NULL,
189                 flags,
190                 imageType,
191                 format,
192                 extent,
193                 mipLevels,
194                 arrayLayers,
195                 samples,
196                 tiling,
197                 separateStencilUsage ? depthUsage : usage,
198                 sharingMode,
199                 queueFamilyCount,
200                 pQueueFamilyIndices,
201                 initialLayout
202         };
203
204         return createImage(vk, device, &pCreateInfo);
205 }
206
207 Move<VkImageView> createImageView (const DeviceInterface&       vk,
208                                                                    VkDevice                                     device,
209                                                                    VkImageViewCreateFlags       flags,
210                                                                    VkImage                                      image,
211                                                                    VkImageViewType                      viewType,
212                                                                    VkFormat                                     format,
213                                                                    VkComponentMapping           components,
214                                                                    VkImageSubresourceRange      subresourceRange)
215 {
216         const VkImageViewCreateInfo pCreateInfo =
217         {
218                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
219                 DE_NULL,
220                 flags,
221                 image,
222                 viewType,
223                 format,
224                 components,
225                 subresourceRange,
226         };
227         return createImageView(vk, device, &pCreateInfo);
228 }
229
230 Move<VkImage> createImage (const InstanceInterface&     vki,
231                                                    VkPhysicalDevice                     physicalDevice,
232                                                    const DeviceInterface&       vkd,
233                                                    VkDevice                                     device,
234                                                    VkFormat                                     vkFormat,
235                                                    VkSampleCountFlagBits        sampleCountBit,
236                                                    VkImageUsageFlags            usage,
237                                                    deUint32                                     width,
238                                                    deUint32                                     height,
239                                                    TestSeparateUsage            separateStencilUsage = (TestSeparateUsage)0u)
240 {
241         try
242         {
243                 const tcu::TextureFormat                format                                  (mapVkFormat(vkFormat));
244                 const VkImageType                               imageType                               (VK_IMAGE_TYPE_2D);
245                 const VkImageTiling                             imageTiling                             (VK_IMAGE_TILING_OPTIMAL);
246                 const VkFormatProperties                formatProperties                (getPhysicalDeviceFormatProperties(vki, physicalDevice, vkFormat));
247                 const VkImageFormatProperties   imageFormatProperties   (getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
248                 const VkImageUsageFlags                 depthUsage                              = (separateStencilUsage == TEST_DEPTH)   ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
249                 const VkImageUsageFlags                 stencilUsage                    = (separateStencilUsage == TEST_STENCIL) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
250                 const VkExtent3D                                imageExtent                             =
251                 {
252                         width,
253                         height,
254                         1u
255                 };
256
257                 if ((tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
258                         && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
259                         TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
260
261                 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
262                         && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
263                         TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
264
265                 if (imageFormatProperties.maxExtent.width < imageExtent.width
266                         || imageFormatProperties.maxExtent.height < imageExtent.height
267                         || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0))
268                 {
269                         TCU_THROW(NotSupportedError, "Image type not supported");
270                 }
271
272                 if (separateStencilUsage)
273                 {
274                         const VkImageStencilUsageCreateInfo     stencilUsageInfo =
275                         {
276                                 VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,                              //      VkStructureType                 sType
277                                 DE_NULL,                                                                                                                //      const void*                             pNext
278                                 stencilUsage                                                                                                    //      VkImageUsageFlags               stencilUsage
279                         };
280
281                         const VkPhysicalDeviceImageFormatInfo2 formatInfo2 =
282                         {
283                                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,                  //      VkStructureType                 sType
284                                 &stencilUsageInfo,                                                                                              //      const void*                             pNext
285                                 vkFormat,                                                                                                               //      VkFormat                                format
286                                 imageType,                                                                                                              //      VkImageType                             type
287                                 imageTiling,                                                                                                    //      VkImageTiling                   tiling
288                                 depthUsage,                                                                                                             //      VkImageUsageFlags               usage
289                                 (VkImageCreateFlags)0u                                                                                  //      VkImageCreateFlags              flags
290                         };
291
292                         VkImageFormatProperties2                                extProperties =
293                         {
294                                 VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
295                                 DE_NULL,
296                         {
297                                 {
298                                         0,      // width
299                                         0,      // height
300                                         0,      // depth
301                                 },
302                                 0u,             // maxMipLevels
303                                 0u,             // maxArrayLayers
304                                 0,              // sampleCounts
305                                 0u,             // maxResourceSize
306                         },
307                         };
308
309                         if ((vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &formatInfo2, &extProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
310                                 || extProperties.imageFormatProperties.maxExtent.width < imageExtent.width
311                                 || extProperties.imageFormatProperties.maxExtent.height < imageExtent.height
312                                 || ((extProperties.imageFormatProperties.sampleCounts & sampleCountBit) == 0))
313                         {
314                                 TCU_THROW(NotSupportedError, "Image format not supported");
315                         }
316
317                 }
318
319                 return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, 1u, sampleCountBit, imageTiling, usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED, separateStencilUsage);
320         }
321         catch (const vk::Error& error)
322         {
323                 if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
324                         TCU_THROW(NotSupportedError, "Image format not supported");
325
326                 throw;
327         }
328 }
329
330 Move<VkImageView> createImageAttachmentView (const DeviceInterface&     vkd,
331                                                                                          VkDevice                               device,
332                                                                                          VkImage                                image,
333                                                                                          VkFormat                               format,
334                                                                                          VkImageAspectFlags             aspect)
335 {
336         const VkImageSubresourceRange   range =
337         {
338                 aspect,
339                 0u,
340                 1u,
341                 0u,
342                 1u
343         };
344
345         return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
346 }
347
348 Move<VkImageView> createSrcPrimaryInputImageView (const DeviceInterface&        vkd,
349                                                                                                   VkDevice                                      device,
350                                                                                                   VkImage                                       image,
351                                                                                                   VkFormat                                      format,
352                                                                                                   VkImageAspectFlags            aspect,
353                                                                                                   TestSeparateUsage                     testSeparateUsage)
354 {
355         VkImageAspectFlags primaryDepthStencilAspect = (testSeparateUsage == TEST_STENCIL) ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
356
357         const VkImageSubresourceRange   range =
358         {
359                 aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)
360                         ? primaryDepthStencilAspect
361                         : aspect,
362                 0u,
363                 1u,
364                 0u,
365                 1u
366         };
367
368         return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
369 }
370
371 Move<VkImageView> createSrcSecondaryInputImageView (const DeviceInterface&      vkd,
372                                                                                                         VkDevice                                device,
373                                                                                                         VkImage                                 image,
374                                                                                                         VkFormat                                format,
375                                                                                                         VkImageAspectFlags              aspect,
376                                                                                                         TestSeparateUsage               separateStencilUsage)
377 {
378         if ((aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)) && !separateStencilUsage)
379         {
380                 const VkImageSubresourceRange   range =
381                 {
382                         VK_IMAGE_ASPECT_STENCIL_BIT,
383                         0u,
384                         1u,
385                         0u,
386                         1u
387                 };
388
389                 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
390         }
391         else
392                 return Move<VkImageView>();
393 }
394
395 VkDeviceSize getPixelSize (VkFormat vkFormat)
396 {
397         const tcu::TextureFormat        format  (mapVkFormat(vkFormat));
398
399         return format.getPixelSize();
400 }
401
402 Move<VkBuffer> createBuffer (const DeviceInterface&             vkd,
403                                                          VkDevice                                       device,
404                                                          VkFormat                                       format,
405                                                          deUint32                                       width,
406                                                          deUint32                                       height)
407 {
408         const VkBufferUsageFlags        bufferUsage                     (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
409         const VkDeviceSize                      pixelSize                       (getPixelSize(format));
410         const VkBufferCreateInfo        createInfo                      =
411         {
412                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
413                 DE_NULL,
414                 0u,
415
416                 width * height * pixelSize,
417                 bufferUsage,
418
419                 VK_SHARING_MODE_EXCLUSIVE,
420                 0u,
421                 DE_NULL
422         };
423         return createBuffer(vkd, device, &createInfo);
424 }
425
426 VkSampleCountFlagBits sampleCountBitFromomSampleCount (deUint32 count)
427 {
428         switch (count)
429         {
430                 case 1:  return VK_SAMPLE_COUNT_1_BIT;
431                 case 2:  return VK_SAMPLE_COUNT_2_BIT;
432                 case 4:  return VK_SAMPLE_COUNT_4_BIT;
433                 case 8:  return VK_SAMPLE_COUNT_8_BIT;
434                 case 16: return VK_SAMPLE_COUNT_16_BIT;
435                 case 32: return VK_SAMPLE_COUNT_32_BIT;
436                 case 64: return VK_SAMPLE_COUNT_64_BIT;
437
438                 default:
439                         DE_FATAL("Invalid sample count");
440                         return (VkSampleCountFlagBits)(0x1u << count);
441         }
442 }
443
444 std::vector<VkImageSp> createMultisampleImages (const InstanceInterface&        vki,
445                                                                                                 VkPhysicalDevice                        physicalDevice,
446                                                                                                 const DeviceInterface&          vkd,
447                                                                                                 VkDevice                                        device,
448                                                                                                 VkFormat                                        format,
449                                                                                                 deUint32                                        sampleCount,
450                                                                                                 deUint32                                        width,
451                                                                                                 deUint32                                        height)
452 {
453         std::vector<VkImageSp> images (sampleCount);
454
455         for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
456                 images[imageNdx] = safeSharedPtr(new vk::Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, sampleCountBitFromomSampleCount(sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, width, height)));
457
458         return images;
459 }
460
461 std::vector<VkImageSp> createSingleSampleImages (const InstanceInterface&       vki,
462                                                                                                  VkPhysicalDevice                       physicalDevice,
463                                                                                                  const DeviceInterface&         vkd,
464                                                                                                  VkDevice                                       device,
465                                                                                                  VkFormat                                       format,
466                                                                                                  deUint32                                       sampleCount,
467                                                                                                  deUint32                                       width,
468                                                                                                  deUint32                                       height)
469 {
470         std::vector<VkImageSp> images (sampleCount);
471
472         for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
473                 images[imageNdx] = safeSharedPtr(new vk::Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, width, height)));
474
475         return images;
476 }
477
478 std::vector<de::SharedPtr<Allocation> > createImageMemory (const DeviceInterface&               vkd,
479                                                                                                                    VkDevice                                             device,
480                                                                                                                    Allocator&                                   allocator,
481                                                                                                                    const std::vector<VkImageSp> images)
482 {
483         std::vector<de::SharedPtr<Allocation> > memory (images.size());
484
485         for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
486                 memory[memoryNdx] = safeSharedPtr(createImageMemory(vkd, device, allocator, **images[memoryNdx]).release());
487
488         return memory;
489 }
490
491 std::vector<VkImageViewSp> createImageAttachmentViews (const DeviceInterface&                   vkd,
492                                                                                                            VkDevice                                                     device,
493                                                                                                            const std::vector<VkImageSp>&        images,
494                                                                                                            VkFormat                                                     format,
495                                                                                                            VkImageAspectFlagBits                        aspect)
496 {
497         std::vector<VkImageViewSp> views (images.size());
498
499         for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
500                 views[imageNdx] = safeSharedPtr(new vk::Unique<VkImageView>(createImageAttachmentView(vkd, device, **images[imageNdx], format, aspect)));
501
502         return views;
503 }
504
505 std::vector<VkBufferSp> createBuffers (const DeviceInterface&   vkd,
506                                                                            VkDevice                                     device,
507                                                                            VkFormat                                     format,
508                                                                            deUint32                                     sampleCount,
509                                                                            deUint32                                     width,
510                                                                            deUint32                                     height)
511 {
512         std::vector<VkBufferSp> buffers (sampleCount);
513
514         for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
515                 buffers[bufferNdx] = safeSharedPtr(new vk::Unique<VkBuffer>(createBuffer(vkd, device, format, width, height)));
516
517         return buffers;
518 }
519
520 std::vector<de::SharedPtr<Allocation> > createBufferMemory (const DeviceInterface&                      vkd,
521                                                                                                                         VkDevice                                                device,
522                                                                                                                         Allocator&                                              allocator,
523                                                                                                                         const std::vector<VkBufferSp>   buffers)
524 {
525         std::vector<de::SharedPtr<Allocation> > memory (buffers.size());
526
527         for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
528                 memory[memoryNdx] = safeSharedPtr(createBufferMemory(vkd, device, allocator, **buffers[memoryNdx]).release());
529
530         return memory;
531 }
532
533 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
534 Move<VkRenderPass> createRenderPass (const DeviceInterface&     vkd,
535                                                                          VkDevice                               device,
536                                                                          VkFormat                               srcFormat,
537                                                                          VkFormat                               dstFormat,
538                                                                          deUint32                               sampleCount,
539                                                                          RenderingType                  renderingType,
540                                                                          TestSeparateUsage              separateStencilUsage)
541 {
542         const VkSampleCountFlagBits             samples                                         (sampleCountBitFromomSampleCount(sampleCount));
543         const deUint32                                  splitSubpassCount                       (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT));
544         const tcu::TextureFormat                format                                          (mapVkFormat(srcFormat));
545         const bool                                              isDepthStencilFormat            (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
546         const VkImageAspectFlags                inputAspect                                     (separateStencilUsage == TEST_DEPTH ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT
547                                                                                                                                 : separateStencilUsage == TEST_STENCIL ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT
548                                                                                                                                                                                                            : getImageAspectFlags(srcFormat));
549         vector<SubpassDesc>                             subpasses;
550         vector<vector<AttachmentRef> >  dstAttachmentRefs                       (splitSubpassCount);
551         vector<vector<AttachmentRef> >  dstResolveAttachmentRefs        (splitSubpassCount);
552         vector<AttachmentDesc>                  attachments;
553         vector<SubpassDep>                              dependencies;
554         const AttachmentRef                             srcAttachmentRef                                //  VkAttachmentReference                                                                               ||  VkAttachmentReference2KHR
555         (
556                                                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
557                 DE_NULL,                                                                                                        //                                                                                                                              ||  const void*                                                 pNext;
558                 0u,                                                                                                                     //  deUint32                                            attachment;                                     ||  deUint32                                                    attachment;
559                 isDepthStencilFormat                                                                            //  VkImageLayout                                       layout;                                         ||  VkImageLayout                                               layout;
560                         ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
561                         : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
562                 0u                                                                                                                      //                                                                                                                              ||  VkImageAspectFlags                                  aspectMask;
563         );
564         const AttachmentRef                             srcAttachmentInputRef                   //  VkAttachmentReference                                                                               ||  VkAttachmentReference2KHR
565         (
566                                                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
567                 DE_NULL,                                                                                                        //                                                                                                                              ||  const void*                                                 pNext;
568                 0u,                                                                                                                     //  deUint32                                            attachment;                                     ||  deUint32                                                    attachment;
569                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,                                       //  VkImageLayout                                       layout;                                         ||  VkImageLayout                                               layout;
570                 (renderingType == RENDERING_TYPE_RENDERPASS2)                           //                                                                                                                              ||  VkImageAspectFlags                                  aspectMask;
571                         ? inputAspect
572                         : 0u
573         );
574
575         {
576                 const AttachmentDesc srcAttachment                                                      //  VkAttachmentDescription                                                                             ||  VkAttachmentDescription2KHR
577                 (
578                                                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
579                         DE_NULL,                                                                                                //                                                                                                                              ||  const void*                                                 pNext;
580                         0u,                                                                                                             //  VkAttachmentDescriptionFlags        flags;                                          ||  VkAttachmentDescriptionFlags                flags;
581                         srcFormat,                                                                                              //  VkFormat                                            format;                                         ||  VkFormat                                                    format;
582                         samples,                                                                                                //  VkSampleCountFlagBits                       samples;                                        ||  VkSampleCountFlagBits                               samples;
583                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                                //  VkAttachmentLoadOp                          loadOp;                                         ||  VkAttachmentLoadOp                                  loadOp;
584                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                               //  VkAttachmentStoreOp                         storeOp;                                        ||  VkAttachmentStoreOp                                 storeOp;
585                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                                //  VkAttachmentLoadOp                          stencilLoadOp;                          ||  VkAttachmentLoadOp                                  stencilLoadOp;
586                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                               //  VkAttachmentStoreOp                         stencilStoreOp;                         ||  VkAttachmentStoreOp                                 stencilStoreOp;
587                         VK_IMAGE_LAYOUT_UNDEFINED,                                                              //  VkImageLayout                                       initialLayout;                          ||  VkImageLayout                                               initialLayout;
588                         VK_IMAGE_LAYOUT_GENERAL                                                                 //  VkImageLayout                                       finalLayout;                            ||  VkImageLayout                                               finalLayout;
589                 );
590
591                 attachments.push_back(srcAttachment);
592         }
593
594         for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
595         {
596                 for (deUint32 sampleNdx = 0; sampleNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount  - splitSubpassIndex * MAX_COLOR_ATTACHMENT_COUNT); sampleNdx++)
597                 {
598                         // Multisample color attachment
599                         {
600                                 const AttachmentDesc dstAttachment                                      //  VkAttachmentDescription                                                                             ||  VkAttachmentDescription2KHR
601                                 (
602                                                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
603                                         DE_NULL,                                                                                //                                                                                                                              ||  const void*                                                 pNext;
604                                         0u,                                                                                             //  VkAttachmentDescriptionFlags        flags;                                          ||  VkAttachmentDescriptionFlags                flags;
605                                         dstFormat,                                                                              //  VkFormat                                            format;                                         ||  VkFormat                                                    format;
606                                         samples,                                                                                //  VkSampleCountFlagBits                       samples;                                        ||  VkSampleCountFlagBits                               samples;
607                                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                //  VkAttachmentLoadOp                          loadOp;                                         ||  VkAttachmentLoadOp                                  loadOp;
608                                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                               //  VkAttachmentStoreOp                         storeOp;                                        ||  VkAttachmentStoreOp                                 storeOp;
609                                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                //  VkAttachmentLoadOp                          stencilLoadOp;                          ||  VkAttachmentLoadOp                                  stencilLoadOp;
610                                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                               //  VkAttachmentStoreOp                         stencilStoreOp;                         ||  VkAttachmentStoreOp                                 stencilStoreOp;
611                                         VK_IMAGE_LAYOUT_UNDEFINED,                                              //  VkImageLayout                                       initialLayout;                          ||  VkImageLayout                                               initialLayout;
612                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                //  VkImageLayout                                       finalLayout;                            ||  VkImageLayout                                               finalLayout;
613                                 );
614                                 const AttachmentRef dstAttachmentRef                            //  VkAttachmentReference                                                                               ||  VkAttachmentReference2KHR
615                                 (
616                                                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
617                                         DE_NULL,                                                                                //                                                                                                                              ||  const void*                                                 pNext;
618                                         (deUint32)attachments.size(),                                   //  deUint32                                            attachment;                                     ||  deUint32                                                    attachment;
619                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               //  VkImageLayout                                       layout;                                         ||  VkImageLayout                                               layout;
620                                         0u                                                                                              //                                                                                                                              ||  VkImageAspectFlags                                  aspectMask;
621                                 );
622
623                                 attachments.push_back(dstAttachment);
624                                 dstAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
625                         }
626                         // Resolve attachment
627                         {
628                                 const AttachmentDesc dstAttachment                                      //  VkAttachmentDescription                                                                             ||  VkAttachmentDescription2KHR
629                                 (
630                                                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
631                                         DE_NULL,                                                                                //                                                                                                                              ||  const void*                                                 pNext;
632                                         0u,                                                                                             //  VkAttachmentDescriptionFlags        flags;                                          ||  VkAttachmentDescriptionFlags                flags;
633                                         dstFormat,                                                                              //  VkFormat                                            format;                                         ||  VkFormat                                                    format;
634                                         VK_SAMPLE_COUNT_1_BIT,                                                  //  VkSampleCountFlagBits                       samples;                                        ||  VkSampleCountFlagBits                               samples;
635                                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                //  VkAttachmentLoadOp                          loadOp;                                         ||  VkAttachmentLoadOp                                  loadOp;
636                                         VK_ATTACHMENT_STORE_OP_STORE,                                   //  VkAttachmentStoreOp                         storeOp;                                        ||  VkAttachmentStoreOp                                 storeOp;
637                                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                //  VkAttachmentLoadOp                          stencilLoadOp;                          ||  VkAttachmentLoadOp                                  stencilLoadOp;
638                                         VK_ATTACHMENT_STORE_OP_STORE,                                   //  VkAttachmentStoreOp                         stencilStoreOp;                         ||  VkAttachmentStoreOp                                 stencilStoreOp;
639                                         VK_IMAGE_LAYOUT_UNDEFINED,                                              //  VkImageLayout                                       initialLayout;                          ||  VkImageLayout                                               initialLayout;
640                                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL                    //  VkImageLayout                                       finalLayout;                            ||  VkImageLayout                                               finalLayout;
641                                 );
642                                 const AttachmentRef dstAttachmentRef                            //  VkAttachmentReference                                                                               ||  VkAttachmentReference2KHR
643                                 (
644                                                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
645                                         DE_NULL,                                                                                //                                                                                                                              ||  const void*                                                 pNext;
646                                         (deUint32)attachments.size(),                                   //  deUint32                                            attachment;                                     ||  deUint32                                                    attachment;
647                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               //  VkImageLayout                                       layout;                                         ||  VkImageLayout                                               layout;
648                                         0u                                                                                              //                                                                                                                              ||  VkImageAspectFlags                                  aspectMask;
649                                 );
650
651                                 attachments.push_back(dstAttachment);
652                                 dstResolveAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
653                         }
654                 }
655         }
656
657         {
658                 {
659                         const SubpassDesc       subpass                                                         //  VkSubpassDescription                                                                                ||  VkSubpassDescription2KHR
660                         (
661                                                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
662                                 DE_NULL,                                                                                        //                                                                                                                              ||  const void*                                                 pNext;
663                                 (VkSubpassDescriptionFlags)0,                                           //  VkSubpassDescriptionFlags           flags;                                          ||  VkSubpassDescriptionFlags                   flags;
664                                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                        //  VkPipelineBindPoint                         pipelineBindPoint;                      ||  VkPipelineBindPoint                                 pipelineBindPoint;
665                                 0u,                                                                                                     //                                                                                                                              ||  deUint32                                                    viewMask;
666                                 0u,                                                                                                     //  deUint32                                            inputAttachmentCount;           ||  deUint32                                                    inputAttachmentCount;
667                                 DE_NULL,                                                                                        //  const VkAttachmentReference*        pInputAttachments;                      ||  const VkAttachmentReference2KHR*    pInputAttachments;
668                                 isDepthStencilFormat ? 0u : 1u,                                         //  deUint32                                            colorAttachmentCount;           ||  deUint32                                                    colorAttachmentCount;
669                                 isDepthStencilFormat ? DE_NULL : &srcAttachmentRef,     //  const VkAttachmentReference*        pColorAttachments;                      ||  const VkAttachmentReference2KHR*    pColorAttachments;
670                                 DE_NULL,                                                                                        //  const VkAttachmentReference*        pResolveAttachments;            ||  const VkAttachmentReference2KHR*    pResolveAttachments;
671                                 isDepthStencilFormat ? &srcAttachmentRef : DE_NULL,     //  const VkAttachmentReference*        pDepthStencilAttachment;        ||  const VkAttachmentReference2KHR*    pDepthStencilAttachment;
672                                 0u,                                                                                                     //  deUint32                                            preserveAttachmentCount;        ||  deUint32                                                    preserveAttachmentCount;
673                                 DE_NULL                                                                                         //  const deUint32*                                     pPreserveAttachments;           ||  const deUint32*                                             pPreserveAttachments;
674                         );
675
676                         subpasses.push_back(subpass);
677                 }
678
679                 for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
680                 {
681                         {
682                                 const SubpassDesc       subpass                                                                 //  VkSubpassDescription                                                                                ||  VkSubpassDescription2KHR
683                                 (
684                                                                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
685                                         DE_NULL,                                                                                                //                                                                                                                              ||  const void*                                                 pNext;
686                                         (VkSubpassDescriptionFlags)0,                                                   //  VkSubpassDescriptionFlags           flags;                                          ||  VkSubpassDescriptionFlags                   flags;
687                                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                                //  VkPipelineBindPoint                         pipelineBindPoint;                      ||  VkPipelineBindPoint                                 pipelineBindPoint;
688                                         0u,                                                                                                             //                                                                                                                              ||  deUint32                                                    viewMask;
689                                         1u,                                                                                                             //  deUint32                                            inputAttachmentCount;           ||  deUint32                                                    inputAttachmentCount;
690                                         &srcAttachmentInputRef,                                                                 //  const VkAttachmentReference*        pInputAttachments;                      ||  const VkAttachmentReference2KHR*    pInputAttachments;
691                                         (deUint32)dstAttachmentRefs[splitSubpassIndex].size(),  //  deUint32                                            colorAttachmentCount;           ||  deUint32                                                    colorAttachmentCount;
692                                         &dstAttachmentRefs[splitSubpassIndex][0],                               //  const VkAttachmentReference*        pColorAttachments;                      ||  const VkAttachmentReference2KHR*    pColorAttachments;
693                                         &dstResolveAttachmentRefs[splitSubpassIndex][0],                //  const VkAttachmentReference*        pResolveAttachments;            ||  const VkAttachmentReference2KHR*    pResolveAttachments;
694                                         DE_NULL,                                                                                                //  const VkAttachmentReference*        pDepthStencilAttachment;        ||  const VkAttachmentReference2KHR*    pDepthStencilAttachment;
695                                         0u,                                                                                                             //  deUint32                                            preserveAttachmentCount;        ||  deUint32                                                    preserveAttachmentCount;
696                                         DE_NULL                                                                                                 //  const deUint32*                                     pPreserveAttachments;           ||  const deUint32*                                             pPreserveAttachments;
697                                 );
698                                 subpasses.push_back(subpass);
699                         }
700                         {
701                                 const SubpassDep        dependency                                                                                                                              //  VkSubpassDependency                                                 ||  VkSubpassDependency2KHR
702                                 (
703                                                                                                                                                                                                                         //                                                                                              ||      VkStructureType                 sType;
704                                         DE_NULL,                                                                                                                                                                //                                                                                              ||      const void*                             pNext;
705                                         0u,                                                                                                                                                                             //  deUint32                            srcSubpass;                     ||      deUint32                                srcSubpass;
706                                         splitSubpassIndex + 1,                                                                                                                                  //  deUint32                            dstSubpass;                     ||      deUint32                                dstSubpass;
707                                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,                                                                                 //  VkPipelineStageFlags        srcStageMask;           ||      VkPipelineStageFlags    srcStageMask;
708                                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                                                                                                  //  VkPipelineStageFlags        dstStageMask;           ||      VkPipelineStageFlags    dstStageMask;
709                                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,    //  VkAccessFlags                       srcAccessMask;          ||      VkAccessFlags                   srcAccessMask;
710                                         VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                                                                                                    //  VkAccessFlags                       dstAccessMask;          ||      VkAccessFlags                   dstAccessMask;
711                                         VK_DEPENDENCY_BY_REGION_BIT,                                                                                                                    //  VkDependencyFlags           dependencyFlags;        ||      VkDependencyFlags               dependencyFlags;
712                                         0u                                                                                                                                                                              //                                                                                              ||      deInt32                                 viewOffset;
713                                 );
714
715                                 dependencies.push_back(dependency);
716                         }
717                 }
718                 // the last subpass must synchronize with all prior subpasses
719                 for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < (splitSubpassCount - 1); splitSubpassIndex++)
720                 {
721                                 const SubpassDep        dependency                                                                                                                              //  VkSubpassDependency                                                 ||  VkSubpassDependency2KHR
722                                 (
723                                                                                                                                                                                                                         //                                                                                              ||      VkStructureType                 sType;
724                                         DE_NULL,                                                                                                                                                                //                                                                                              ||      const void*                             pNext;
725                                         splitSubpassIndex + 1,                                                                                                                                  //  deUint32                            srcSubpass;                     ||      deUint32                                srcSubpass;
726                                         splitSubpassCount,                                                                                                                                              //  deUint32                            dstSubpass;                     ||      deUint32                                dstSubpass;
727                                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
728                                         | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,                                                                                    //  VkPipelineStageFlags        srcStageMask;           ||      VkPipelineStageFlags    srcStageMask;
729                                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                                                                                                  //  VkPipelineStageFlags        dstStageMask;           ||      VkPipelineStageFlags    dstStageMask;
730                                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,    //  VkAccessFlags                       srcAccessMask;          ||      VkAccessFlags                   srcAccessMask;
731                                         VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                                                                                                    //  VkAccessFlags                       dstAccessMask;          ||      VkAccessFlags                   dstAccessMask;
732                                         VK_DEPENDENCY_BY_REGION_BIT,                                                                                                                    //  VkDependencyFlags           dependencyFlags;        ||      VkDependencyFlags               dependencyFlags;
733                                         0u                                                                                                                                                                              //                                                                                              ||      deInt32                                 viewOffset;
734                                 );
735                                 dependencies.push_back(dependency);
736                 }
737                 const RenderPassCreateInfo      renderPassCreator                                               //  VkRenderPassCreateInfo                                                                              ||  VkRenderPassCreateInfo2KHR
738                 (
739                                                                                                                                                         //  VkStructureType                                     sType;                                          ||  VkStructureType                                             sType;
740                         DE_NULL,                                                                                                                //  const void*                                         pNext;                                          ||  const void*                                                 pNext;
741                         (VkRenderPassCreateFlags)0u,                                                                    //  VkRenderPassCreateFlags                     flags;                                          ||  VkRenderPassCreateFlags                             flags;
742                         (deUint32)attachments.size(),                                                                   //  deUint32                                            attachmentCount;                        ||  deUint32                                                    attachmentCount;
743                         &attachments[0],                                                                                                //  const VkAttachmentDescription*      pAttachments;                           ||  const VkAttachmentDescription2KHR*  pAttachments;
744                         (deUint32)subpasses.size(),                                                                             //  deUint32                                            subpassCount;                           ||  deUint32                                                    subpassCount;
745                         &subpasses[0],                                                                                                  //  const VkSubpassDescription*         pSubpasses;                                     ||  const VkSubpassDescription2KHR*             pSubpasses;
746                         (deUint32)dependencies.size(),                                                                  //  deUint32                                            dependencyCount;                        ||  deUint32                                                    dependencyCount;
747                         &dependencies[0],                                                                                               //  const VkSubpassDependency*          pDependencies;                          ||  const VkSubpassDependency2KHR*              pDependencies;
748                         0u,                                                                                                                             //                                                                                                                              ||  deUint32                                                    correlatedViewMaskCount;
749                         DE_NULL                                                                                                                 //                                                                                                                              ||  const deUint32*                                             pCorrelatedViewMasks;
750                 );
751
752                 return renderPassCreator.createRenderPass(vkd, device);
753         }
754 }
755
756 Move<VkRenderPass> createRenderPass (const DeviceInterface&             vkd,
757                                                                          VkDevice                                       device,
758                                                                          VkFormat                                       srcFormat,
759                                                                          VkFormat                                       dstFormat,
760                                                                          deUint32                                       sampleCount,
761                                                                          const RenderingType            renderingType,
762                                                                          const TestSeparateUsage        separateStencilUsage)
763 {
764         switch (renderingType)
765         {
766                 case RENDERING_TYPE_RENDERPASS_LEGACY:
767                         return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType, separateStencilUsage);
768                 case RENDERING_TYPE_RENDERPASS2:
769                         return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType, separateStencilUsage);
770                 default:
771                         TCU_THROW(InternalError, "Impossible");
772         }
773 }
774
775 Move<VkFramebuffer> createFramebuffer (const DeviceInterface&                           vkd,
776                                                                            VkDevice                                                             device,
777                                                                            VkRenderPass                                                 renderPass,
778                                                                            VkImageView                                                  srcImageView,
779                                                                            const std::vector<VkImageViewSp>&    dstMultisampleImageViews,
780                                                                            const std::vector<VkImageViewSp>&    dstSinglesampleImageViews,
781                                                                            deUint32                                                             width,
782                                                                            deUint32                                                             height)
783 {
784         std::vector<VkImageView> attachments;
785
786         attachments.reserve(dstMultisampleImageViews.size() + dstSinglesampleImageViews.size() + 1u);
787
788         attachments.push_back(srcImageView);
789
790         DE_ASSERT(dstMultisampleImageViews.size() == dstSinglesampleImageViews.size());
791
792         for (size_t ndx = 0; ndx < dstMultisampleImageViews.size(); ndx++)
793         {
794                 attachments.push_back(**dstMultisampleImageViews[ndx]);
795                 attachments.push_back(**dstSinglesampleImageViews[ndx]);
796         }
797
798         const VkFramebufferCreateInfo createInfo =
799         {
800                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
801                 DE_NULL,
802                 0u,
803
804                 renderPass,
805                 (deUint32)attachments.size(),
806                 &attachments[0],
807
808                 width,
809                 height,
810                 1u
811         };
812
813         return createFramebuffer(vkd, device, &createInfo);
814 }
815
816 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface&       vkd,
817                                                                                                    VkDevice                                     device)
818 {
819         const VkPushConstantRange                       pushConstant                    =
820         {
821                 VK_SHADER_STAGE_FRAGMENT_BIT,
822                 0u,
823                 4u
824         };
825         const VkPipelineLayoutCreateInfo        createInfo      =
826         {
827                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
828                 DE_NULL,
829                 (vk::VkPipelineLayoutCreateFlags)0,
830
831                 0u,
832                 DE_NULL,
833
834                 1u,
835                 &pushConstant
836         };
837
838         return createPipelineLayout(vkd, device, &createInfo);
839 }
840
841 Move<VkPipeline> createRenderPipeline (const DeviceInterface&           vkd,
842                                                                            VkDevice                                             device,
843                                                                            VkFormat                                             srcFormat,
844                                                                            VkRenderPass                                 renderPass,
845                                                                            VkPipelineLayout                             pipelineLayout,
846                                                                            const vk::BinaryCollection&  binaryCollection,
847                                                                            deUint32                                             width,
848                                                                            deUint32                                             height,
849                                                                            deUint32                                             sampleCount)
850 {
851         const tcu::TextureFormat                format                                          (mapVkFormat(srcFormat));
852         const bool                                              isDepthStencilFormat            (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
853
854         const Unique<VkShaderModule>    vertexShaderModule                      (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
855         const Unique<VkShaderModule>    fragmentShaderModule            (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
856         // Disable blending
857         const VkPipelineColorBlendAttachmentState attachmentBlendState =
858         {
859                 VK_FALSE,
860                 VK_BLEND_FACTOR_SRC_ALPHA,
861                 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
862                 VK_BLEND_OP_ADD,
863                 VK_BLEND_FACTOR_ONE,
864                 VK_BLEND_FACTOR_ONE,
865                 VK_BLEND_OP_ADD,
866                 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
867         };
868         const VkPipelineVertexInputStateCreateInfo vertexInputState =
869         {
870                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
871                 DE_NULL,
872                 (VkPipelineVertexInputStateCreateFlags)0u,
873
874                 0u,
875                 DE_NULL,
876
877                 0u,
878                 DE_NULL
879         };
880         const std::vector<VkViewport>   viewports       (1, makeViewport(tcu::UVec2(width, height)));
881         const std::vector<VkRect2D>             scissors        (1, makeRect2D(tcu::UVec2(width, height)));
882
883         const VkPipelineMultisampleStateCreateInfo multisampleState =
884         {
885                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
886                 DE_NULL,
887                 (VkPipelineMultisampleStateCreateFlags)0u,
888
889                 sampleCountBitFromomSampleCount(sampleCount),
890                 VK_FALSE,
891                 0.0f,
892                 DE_NULL,
893                 VK_FALSE,
894                 VK_FALSE,
895         };
896         const VkPipelineDepthStencilStateCreateInfo depthStencilState =
897         {
898                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
899                 DE_NULL,
900                 (VkPipelineDepthStencilStateCreateFlags)0u,
901
902                 VK_TRUE,
903                 VK_TRUE,
904                 VK_COMPARE_OP_ALWAYS,
905                 VK_FALSE,
906                 VK_TRUE,
907                 {
908                         VK_STENCIL_OP_KEEP,
909                         VK_STENCIL_OP_INCREMENT_AND_WRAP,
910                         VK_STENCIL_OP_KEEP,
911                         VK_COMPARE_OP_ALWAYS,
912                         ~0u,
913                         ~0u,
914                         0xFFu / (sampleCount + 1)
915                 },
916                 {
917                         VK_STENCIL_OP_KEEP,
918                         VK_STENCIL_OP_INCREMENT_AND_WRAP,
919                         VK_STENCIL_OP_KEEP,
920                         VK_COMPARE_OP_ALWAYS,
921                         ~0u,
922                         ~0u,
923                         0xFFu / (sampleCount + 1)
924                 },
925
926                 0.0f,
927                 1.0f
928         };
929         const VkPipelineColorBlendStateCreateInfo blendState =
930         {
931                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
932                 DE_NULL,
933                 (VkPipelineColorBlendStateCreateFlags)0u,
934
935                 VK_FALSE,
936                 VK_LOGIC_OP_COPY,
937                 (isDepthStencilFormat ? 0u : 1u),
938                 (isDepthStencilFormat ? DE_NULL : &attachmentBlendState),
939                 { 0.0f, 0.0f, 0.0f, 0.0f }
940         };
941
942         return makeGraphicsPipeline(vkd,                                                                        // const DeviceInterface&                        vk
943                                                                 device,                                                                 // const VkDevice                                device
944                                                                 pipelineLayout,                                                 // const VkPipelineLayout                        pipelineLayout
945                                                                 *vertexShaderModule,                                    // const VkShaderModule                          vertexShaderModule
946                                                                 DE_NULL,                                                                // const VkShaderModule                          tessellationControlShaderModule
947                                                                 DE_NULL,                                                                // const VkShaderModule                          tessellationEvalShaderModule
948                                                                 DE_NULL,                                                                // const VkShaderModule                          geometryShaderModule
949                                                                 *fragmentShaderModule,                                  // const VkShaderModule                          fragmentShaderModule
950                                                                 renderPass,                                                             // const VkRenderPass                            renderPass
951                                                                 viewports,                                                              // const std::vector<VkViewport>&                viewports
952                                                                 scissors,                                                               // const std::vector<VkRect2D>&                  scissors
953                                                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    // const VkPrimitiveTopology                     topology
954                                                                 0u,                                                                             // const deUint32                                subpass
955                                                                 0u,                                                                             // const deUint32                                patchControlPoints
956                                                                 &vertexInputState,                                              // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
957                                                                 DE_NULL,                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
958                                                                 &multisampleState,                                              // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
959                                                                 &depthStencilState,                                             // const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
960                                                                 &blendState);                                                   // const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
961 }
962
963 Move<VkDescriptorSetLayout> createSplitDescriptorSetLayout (const DeviceInterface&      vkd,
964                                                                                                                         VkDevice                                device,
965                                                                                                                         VkFormat                                vkFormat)
966 {
967         const tcu::TextureFormat                                format          (mapVkFormat(vkFormat));
968         const bool                                                              hasDepth        (tcu::hasDepthComponent(format.order));
969         const bool                                                              hasStencil      (tcu::hasStencilComponent(format.order));
970         const VkDescriptorSetLayoutBinding              bindings[]      =
971         {
972                 {
973                         0u,
974                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
975                         1u,
976                         VK_SHADER_STAGE_FRAGMENT_BIT,
977                         DE_NULL
978                 },
979                 {
980                         1u,
981                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
982                         1u,
983                         VK_SHADER_STAGE_FRAGMENT_BIT,
984                         DE_NULL
985                 }
986         };
987         const VkDescriptorSetLayoutCreateInfo   createInfo      =
988         {
989                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
990                 DE_NULL,
991                 0u,
992
993                 hasDepth && hasStencil ? 2u : 1u,
994                 bindings
995         };
996
997         return createDescriptorSetLayout(vkd, device, &createInfo);
998 }
999
1000 Move<VkPipelineLayout> createSplitPipelineLayout (const DeviceInterface&        vkd,
1001                                                                                                   VkDevice                                      device,
1002                                                                                                   VkDescriptorSetLayout         descriptorSetLayout)
1003 {
1004         const VkPushConstantRange                       pushConstant                    =
1005         {
1006                 VK_SHADER_STAGE_FRAGMENT_BIT,
1007                 0u,
1008                 4u
1009         };
1010         const VkPipelineLayoutCreateInfo        createInfo      =
1011         {
1012                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1013                 DE_NULL,
1014                 (vk::VkPipelineLayoutCreateFlags)0,
1015
1016                 1u,
1017                 &descriptorSetLayout,
1018
1019                 1u,
1020                 &pushConstant
1021         };
1022
1023         return createPipelineLayout(vkd, device, &createInfo);
1024 }
1025
1026 Move<VkPipeline> createSplitPipeline (const DeviceInterface&            vkd,
1027                                                                           VkDevice                                              device,
1028                                                                           VkRenderPass                                  renderPass,
1029                                                                           deUint32                                              subpassIndex,
1030                                                                           VkPipelineLayout                              pipelineLayout,
1031                                                                           const vk::BinaryCollection&   binaryCollection,
1032                                                                           deUint32                                              width,
1033                                                                           deUint32                                              height,
1034                                                                           deUint32                                              sampleCount)
1035 {
1036         const Unique<VkShaderModule>    vertexShaderModule                      (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
1037         const Unique<VkShaderModule>    fragmentShaderModule            (createShaderModule(vkd, device, binaryCollection.get("quad-split-frag"), 0u));
1038         // Disable blending
1039         const VkPipelineColorBlendAttachmentState attachmentBlendState =
1040         {
1041                 VK_FALSE,
1042                 VK_BLEND_FACTOR_SRC_ALPHA,
1043                 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1044                 VK_BLEND_OP_ADD,
1045                 VK_BLEND_FACTOR_ONE,
1046                 VK_BLEND_FACTOR_ONE,
1047                 VK_BLEND_OP_ADD,
1048                 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
1049         };
1050         const std::vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates (de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount), attachmentBlendState);
1051         const VkPipelineVertexInputStateCreateInfo vertexInputState =
1052         {
1053                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1054                 DE_NULL,
1055                 (VkPipelineVertexInputStateCreateFlags)0u,
1056
1057                 0u,
1058                 DE_NULL,
1059
1060                 0u,
1061                 DE_NULL
1062         };
1063         const std::vector<VkViewport>   viewports       (1, makeViewport(tcu::UVec2(width, height)));
1064         const std::vector<VkRect2D>             scissors        (1, makeRect2D(tcu::UVec2(width, height)));
1065
1066         const VkPipelineMultisampleStateCreateInfo multisampleState =
1067         {
1068                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1069                 DE_NULL,
1070                 (VkPipelineMultisampleStateCreateFlags)0u,
1071
1072                 sampleCountBitFromomSampleCount(sampleCount),
1073                 VK_FALSE,
1074                 0.0f,
1075                 DE_NULL,
1076                 VK_FALSE,
1077                 VK_FALSE,
1078         };
1079         const VkPipelineColorBlendStateCreateInfo blendState =
1080         {
1081                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1082                 DE_NULL,
1083                 (VkPipelineColorBlendStateCreateFlags)0u,
1084
1085                 VK_FALSE,
1086                 VK_LOGIC_OP_COPY,
1087
1088                 (deUint32)attachmentBlendStates.size(),
1089                 &attachmentBlendStates[0],
1090
1091                 { 0.0f, 0.0f, 0.0f, 0.0f }
1092         };
1093
1094         return makeGraphicsPipeline(vkd,                                                                        // const DeviceInterface&                        vk
1095                                                                 device,                                                                 // const VkDevice                                device
1096                                                                 pipelineLayout,                                                 // const VkPipelineLayout                        pipelineLayout
1097                                                                 *vertexShaderModule,                                    // const VkShaderModule                          vertexShaderModule
1098                                                                 DE_NULL,                                                                // const VkShaderModule                          tessellationControlShaderModule
1099                                                                 DE_NULL,                                                                // const VkShaderModule                          tessellationEvalShaderModule
1100                                                                 DE_NULL,                                                                // const VkShaderModule                          geometryShaderModule
1101                                                                 *fragmentShaderModule,                                  // const VkShaderModule                          fragmentShaderModule
1102                                                                 renderPass,                                                             // const VkRenderPass                            renderPass
1103                                                                 viewports,                                                              // const std::vector<VkViewport>&                viewports
1104                                                                 scissors,                                                               // const std::vector<VkRect2D>&                  scissors
1105                                                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    // const VkPrimitiveTopology                     topology
1106                                                                 subpassIndex,                                                   // const deUint32                                subpass
1107                                                                 0u,                                                                             // const deUint32                                patchControlPoints
1108                                                                 &vertexInputState,                                              // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
1109                                                                 DE_NULL,                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1110                                                                 &multisampleState,                                              // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
1111                                                                 DE_NULL,                                                                // const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
1112                                                                 &blendState);                                                   // const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
1113 }
1114
1115 vector<VkPipelineSp> createSplitPipelines (const DeviceInterface&               vkd,
1116                                                                                  VkDevice                                               device,
1117                                                                                  VkRenderPass                                   renderPass,
1118                                                                                  VkPipelineLayout                               pipelineLayout,
1119                                                                                  const vk::BinaryCollection&    binaryCollection,
1120                                                                                  deUint32                                               width,
1121                                                                                  deUint32                                               height,
1122                                                                                  deUint32                                               sampleCount)
1123 {
1124         std::vector<VkPipelineSp> pipelines (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT), (VkPipelineSp)0u);
1125
1126         for (size_t ndx = 0; ndx < pipelines.size(); ndx++)
1127                 pipelines[ndx] = safeSharedPtr(new Unique<VkPipeline>(createSplitPipeline(vkd, device, renderPass, (deUint32)(ndx + 1), pipelineLayout, binaryCollection, width, height, sampleCount)));
1128
1129         return pipelines;
1130 }
1131
1132 Move<VkDescriptorPool> createSplitDescriptorPool (const DeviceInterface&        vkd,
1133                                                                                                   VkDevice                                      device)
1134 {
1135         const VkDescriptorPoolSize                      size            =
1136         {
1137                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2u
1138         };
1139         const VkDescriptorPoolCreateInfo        createInfo      =
1140         {
1141                 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1142                 DE_NULL,
1143                 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1144
1145
1146                 2u,
1147                 1u,
1148                 &size
1149         };
1150
1151         return createDescriptorPool(vkd, device, &createInfo);
1152 }
1153
1154 Move<VkDescriptorSet> createSplitDescriptorSet (const DeviceInterface&  vkd,
1155                                                                                                 VkDevice                                device,
1156                                                                                                 VkDescriptorPool                pool,
1157                                                                                                 VkDescriptorSetLayout   layout,
1158                                                                                                 VkImageView                             primaryImageView,
1159                                                                                                 VkImageView                             secondaryImageView)
1160 {
1161         const VkDescriptorSetAllocateInfo       allocateInfo    =
1162         {
1163                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1164                 DE_NULL,
1165
1166                 pool,
1167                 1u,
1168                 &layout
1169         };
1170         Move<VkDescriptorSet> set (allocateDescriptorSet(vkd, device, &allocateInfo));
1171
1172         {
1173                 const VkDescriptorImageInfo     imageInfos[]    =
1174                 {
1175                         {
1176                                 (VkSampler)0u,
1177                                 primaryImageView,
1178                                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1179                         },
1180                         {
1181                                 (VkSampler)0u,
1182                                 secondaryImageView,
1183                                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1184                         }
1185                 };
1186                 const VkWriteDescriptorSet      writes[]        =
1187                 {
1188                         {
1189                                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1190                                 DE_NULL,
1191
1192                                 *set,
1193                                 0u,
1194                                 0u,
1195                                 1u,
1196                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1197                                 &imageInfos[0],
1198                                 DE_NULL,
1199                                 DE_NULL
1200                         },
1201                         {
1202                                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1203                                 DE_NULL,
1204
1205                                 *set,
1206                                 1u,
1207                                 0u,
1208                                 1u,
1209                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1210                                 &imageInfos[1],
1211                                 DE_NULL,
1212                                 DE_NULL
1213                         }
1214                 };
1215                 const deUint32  count   = secondaryImageView != (VkImageView)0
1216                                                                 ? 2u
1217                                                                 : 1u;
1218
1219                 vkd.updateDescriptorSets(device, count, writes, 0u, DE_NULL);
1220         }
1221         return set;
1222 }
1223
1224 struct TestConfig
1225 {
1226                                 TestConfig              (VkFormat                       format_,
1227                                                                  deUint32                       sampleCount_,
1228                                                                  RenderingType          renderingType_,
1229                                                                  TestSeparateUsage      separateStencilUsage_ = (TestSeparateUsage)0u)
1230                 : format                        (format_)
1231                 , sampleCount           (sampleCount_)
1232                 , renderingType         (renderingType_)
1233                 , separateStencilUsage(separateStencilUsage_)
1234         {
1235         }
1236
1237         VkFormat                        format;
1238         deUint32                        sampleCount;
1239         RenderingType           renderingType;
1240         TestSeparateUsage       separateStencilUsage;
1241 };
1242
1243 VkImageUsageFlags getSrcImageUsage (VkFormat vkFormat)
1244 {
1245         const tcu::TextureFormat        format          (mapVkFormat(vkFormat));
1246         const bool                                      hasDepth        (tcu::hasDepthComponent(format.order));
1247         const bool                                      hasStencil      (tcu::hasStencilComponent(format.order));
1248
1249         if (hasDepth || hasStencil)
1250                 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1251         else
1252                 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1253 }
1254
1255 VkFormat getDstFormat (VkFormat vkFormat, TestSeparateUsage separateStencilUsage)
1256 {
1257         const tcu::TextureFormat        format          (mapVkFormat(vkFormat));
1258         const bool                                      hasDepth        (tcu::hasDepthComponent(format.order));
1259         const bool                                      hasStencil      (tcu::hasStencilComponent(format.order));
1260
1261         if (hasDepth && hasStencil && !separateStencilUsage)
1262                 return VK_FORMAT_R32G32_SFLOAT;
1263         else if (hasDepth || hasStencil)
1264                 return VK_FORMAT_R32_SFLOAT;
1265         else
1266                 return vkFormat;
1267 }
1268
1269 bool isExtensionSupported(Context& context, RenderingType renderingType, TestSeparateUsage separateStencilUsage)
1270 {
1271         if (renderingType == RENDERING_TYPE_RENDERPASS2)
1272                 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
1273
1274         if (separateStencilUsage)
1275         {
1276                 context.requireDeviceFunctionality      ("VK_EXT_separate_stencil_usage");
1277                 context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
1278         }
1279
1280         return true;
1281 }
1282
1283
1284 class MultisampleRenderPassTestInstance : public TestInstance
1285 {
1286 public:
1287                                         MultisampleRenderPassTestInstance       (Context& context, TestConfig config);
1288                                         ~MultisampleRenderPassTestInstance      (void);
1289
1290         tcu::TestStatus iterate                                                         (void);
1291
1292         template<typename RenderpassSubpass>
1293         tcu::TestStatus iterateInternal                                         (void);
1294
1295 private:
1296         const bool                                                                              m_extensionSupported;
1297         const RenderingType                                                             m_renderingType;
1298         const TestSeparateUsage                                                 m_separateStencilUsage;
1299
1300         const VkFormat                                                                  m_srcFormat;
1301         const VkFormat                                                                  m_dstFormat;
1302         const deUint32                                                                  m_sampleCount;
1303         const deUint32                                                                  m_width;
1304         const deUint32                                                                  m_height;
1305
1306         const VkImageAspectFlags                                                m_srcImageAspect;
1307         const VkImageUsageFlags                                                 m_srcImageUsage;
1308         const Unique<VkImage>                                                   m_srcImage;
1309         const de::UniquePtr<Allocation>                                 m_srcImageMemory;
1310         const Unique<VkImageView>                                               m_srcImageView;
1311         const Unique<VkImageView>                                               m_srcPrimaryInputImageView;
1312         const Unique<VkImageView>                                               m_srcSecondaryInputImageView;
1313
1314         const std::vector<VkImageSp>                                    m_dstMultisampleImages;
1315         const std::vector<de::SharedPtr<Allocation> >   m_dstMultisampleImageMemory;
1316         const std::vector<VkImageViewSp>                                m_dstMultisampleImageViews;
1317
1318         const std::vector<VkImageSp>                                    m_dstSinglesampleImages;
1319         const std::vector<de::SharedPtr<Allocation> >   m_dstSinglesampleImageMemory;
1320         const std::vector<VkImageViewSp>                                m_dstSinglesampleImageViews;
1321
1322         const std::vector<VkBufferSp>                                   m_dstBuffers;
1323         const std::vector<de::SharedPtr<Allocation> >   m_dstBufferMemory;
1324
1325         const Unique<VkRenderPass>                                              m_renderPass;
1326         const Unique<VkFramebuffer>                                             m_framebuffer;
1327
1328         const Unique<VkPipelineLayout>                                  m_renderPipelineLayout;
1329         const Unique<VkPipeline>                                                m_renderPipeline;
1330
1331         const Unique<VkDescriptorSetLayout>                             m_splitDescriptorSetLayout;
1332         const Unique<VkPipelineLayout>                                  m_splitPipelineLayout;
1333         const std::vector<VkPipelineSp>                                 m_splitPipelines;
1334         const Unique<VkDescriptorPool>                                  m_splitDescriptorPool;
1335         const Unique<VkDescriptorSet>                                   m_splitDescriptorSet;
1336
1337         const Unique<VkCommandPool>                                             m_commandPool;
1338         tcu::ResultCollector                                                    m_resultCollector;
1339 };
1340
1341 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
1342         : TestInstance                                  (context)
1343         , m_extensionSupported                  (isExtensionSupported(context, config.renderingType, config.separateStencilUsage))
1344         , m_renderingType                               (config.renderingType)
1345         , m_separateStencilUsage                (config.separateStencilUsage)
1346         , m_srcFormat                                   (config.format)
1347         , m_dstFormat                                   (getDstFormat(config.format, config.separateStencilUsage))
1348         , m_sampleCount                                 (config.sampleCount)
1349         , m_width                                               (32u)
1350         , m_height                                              (32u)
1351
1352         , m_srcImageAspect                              (getImageAspectFlags(m_srcFormat))
1353         , m_srcImageUsage                               (getSrcImageUsage(m_srcFormat))
1354         , m_srcImage                                    (createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_srcFormat, sampleCountBitFromomSampleCount(m_sampleCount), m_srcImageUsage, m_width, m_height, m_separateStencilUsage))
1355         , m_srcImageMemory                              (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_srcImage))
1356         , m_srcImageView                                (createImageAttachmentView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1357         , m_srcPrimaryInputImageView    (createSrcPrimaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
1358         , m_srcSecondaryInputImageView  (createSrcSecondaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
1359
1360         , m_dstMultisampleImages                (createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1361         , m_dstMultisampleImageMemory   (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstMultisampleImages))
1362         , m_dstMultisampleImageViews    (createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstMultisampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1363
1364         , m_dstSinglesampleImages               (createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1365         , m_dstSinglesampleImageMemory  (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstSinglesampleImages))
1366         , m_dstSinglesampleImageViews   (createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstSinglesampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1367
1368         , m_dstBuffers                                  (createBuffers(context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1369         , m_dstBufferMemory                             (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstBuffers))
1370
1371         , m_renderPass                                  (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_srcFormat, m_dstFormat, m_sampleCount, config.renderingType, m_separateStencilUsage))
1372         , m_framebuffer                                 (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_srcImageView, m_dstMultisampleImageViews, m_dstSinglesampleImageViews, m_width, m_height))
1373
1374         , m_renderPipelineLayout                (createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
1375         , m_renderPipeline                              (createRenderPipeline(context.getDeviceInterface(), context.getDevice(), m_srcFormat, *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1376
1377         , m_splitDescriptorSetLayout    (createSplitDescriptorSetLayout(context.getDeviceInterface(), context.getDevice(), m_srcFormat))
1378         , m_splitPipelineLayout                 (createSplitPipelineLayout(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorSetLayout))
1379         , m_splitPipelines                              (createSplitPipelines(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_splitPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1380         , m_splitDescriptorPool                 (createSplitDescriptorPool(context.getDeviceInterface(), context.getDevice()))
1381         , m_splitDescriptorSet                  (createSplitDescriptorSet(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorPool, *m_splitDescriptorSetLayout, *m_srcPrimaryInputImageView, *m_srcSecondaryInputImageView))
1382         , m_commandPool                                 (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1383 {
1384 }
1385
1386 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
1387 {
1388 }
1389
1390 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1391 {
1392         switch (m_renderingType)
1393         {
1394                 case RENDERING_TYPE_RENDERPASS_LEGACY:
1395                         return iterateInternal<RenderpassSubpass1>();
1396                 case RENDERING_TYPE_RENDERPASS2:
1397                         return iterateInternal<RenderpassSubpass2>();
1398                 default:
1399                         TCU_THROW(InternalError, "Impossible");
1400         }
1401 }
1402
1403 template<typename RenderpassSubpass>
1404 tcu::TestStatus MultisampleRenderPassTestInstance::iterateInternal (void)
1405 {
1406         const DeviceInterface&                                                          vkd                                     (m_context.getDeviceInterface());
1407         const VkDevice                                                                          device                          (m_context.getDevice());
1408         const Unique<VkCommandBuffer>                                           commandBuffer           (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1409         const typename RenderpassSubpass::SubpassBeginInfo      subpassBeginInfo        (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1410         const typename RenderpassSubpass::SubpassEndInfo        subpassEndInfo          (DE_NULL);
1411
1412         beginCommandBuffer(vkd, *commandBuffer);
1413
1414         {
1415                 const VkRenderPassBeginInfo beginInfo =
1416                 {
1417                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1418                         DE_NULL,
1419
1420                         *m_renderPass,
1421                         *m_framebuffer,
1422
1423                         {
1424                                 { 0u, 0u },
1425                                 { m_width, m_height }
1426                         },
1427
1428                         0u,
1429                         DE_NULL
1430                 };
1431                 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
1432
1433                 // Stencil needs to be cleared if it exists.
1434                 if (tcu::hasStencilComponent(mapVkFormat(m_srcFormat).order))
1435                 {
1436                         const VkClearAttachment clearAttachment =
1437                         {
1438                                 VK_IMAGE_ASPECT_STENCIL_BIT,                                            // VkImageAspectFlags   aspectMask;
1439                                 0,                                                                                                      // deUint32                             colorAttachment;
1440                                 makeClearValueDepthStencil(0, 0)                                        // VkClearValue                 clearValue;
1441                         };
1442
1443                         const VkClearRect clearRect =
1444                         {
1445                                 {
1446                                         { 0u, 0u },
1447                                         { m_width, m_height }
1448                                 },
1449                                 0,                                                                                                      // deUint32     baseArrayLayer;
1450                                 1                                                                                                       // deUint32     layerCount;
1451                         };
1452
1453                         vkd.cmdClearAttachments(*commandBuffer, 1, &clearAttachment, 1, &clearRect);
1454                 }
1455         }
1456
1457         vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
1458
1459         for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1460         {
1461                 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleNdx), &sampleNdx);
1462                 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1463         }
1464
1465         for (deUint32 splitPipelineNdx = 0; splitPipelineNdx < m_splitPipelines.size(); splitPipelineNdx++)
1466         {
1467                 RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
1468
1469                 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_splitPipelines[splitPipelineNdx]);
1470                 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_splitPipelineLayout, 0u, 1u,  &*m_splitDescriptorSet, 0u, DE_NULL);
1471                 vkd.cmdPushConstants(*commandBuffer, *m_splitPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(splitPipelineNdx), &splitPipelineNdx);
1472                 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1473         }
1474
1475         RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1476
1477         for (size_t dstNdx = 0; dstNdx < m_dstSinglesampleImages.size(); dstNdx++)
1478                 copyImageToBuffer(vkd, *commandBuffer, **m_dstSinglesampleImages[dstNdx], **m_dstBuffers[dstNdx], tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1479
1480         endCommandBuffer(vkd, *commandBuffer);
1481
1482         submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
1483
1484         {
1485                 const tcu::TextureFormat                format                  (mapVkFormat(m_dstFormat));
1486                 const tcu::TextureFormat                srcFormat               (mapVkFormat(m_srcFormat));
1487                 const bool                                              verifyDepth             (m_separateStencilUsage ? (m_separateStencilUsage == TEST_DEPTH)   : tcu::hasDepthComponent(srcFormat.order));
1488                 const bool                                              verifyStencil   (m_separateStencilUsage ? (m_separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(srcFormat.order));
1489
1490                 for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1491                 {
1492                         Allocation *dstBufMem = m_dstBufferMemory[sampleNdx].get();
1493                         invalidateAlloc(vkd, device, *dstBufMem);
1494
1495                         const std::string                                       name            ("Sample" + de::toString(sampleNdx));
1496                         const void* const                                       ptr                     (dstBufMem->getHostPtr());
1497                         const tcu::ConstPixelBufferAccess       access          (format, m_width, m_height, 1, ptr);
1498                         tcu::TextureLevel                                       reference       (format, m_width, m_height);
1499
1500                         if (verifyDepth || verifyStencil)
1501                         {
1502                                 if (verifyDepth)
1503                                 {
1504                                         for (deUint32 y = 0; y < m_height; y++)
1505                                         for (deUint32 x = 0; x < m_width; x++)
1506                                         {
1507                                                 const deUint32  x1                              = x ^ sampleNdx;
1508                                                 const deUint32  y1                              = y ^ sampleNdx;
1509                                                 const float             range                   = 1.0f;
1510                                                 float                   depth                   = 0.0f;
1511                                                 deUint32                divider                 = 2;
1512
1513                                                 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1514                                                 for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1515                                                 {
1516                                                         depth += (range / (float)divider)
1517                                                                         * (((bitNdx % 2 == 0 ? x1 : y1) & (0x1u << (bitNdx / 2u))) == 0u ? 0u : 1u);
1518                                                         divider *= 2;
1519                                                 }
1520
1521                                                 reference.getAccess().setPixel(Vec4(depth, 0.0f, 0.0f, 0.0f), x, y);
1522                                         }
1523                                 }
1524                                 if (verifyStencil)
1525                                 {
1526                                         for (deUint32 y = 0; y < m_height; y++)
1527                                         for (deUint32 x = 0; x < m_width; x++)
1528                                         {
1529                                                 const deUint32  stencil = sampleNdx + 1u;
1530
1531                                                 if (verifyDepth)
1532                                                 {
1533                                                         const Vec4 src (reference.getAccess().getPixel(x, y));
1534
1535                                                         reference.getAccess().setPixel(Vec4(src.x(), (float)stencil, 0.0f, 0.0f), x, y);
1536                                                 }
1537                                                 else
1538                                                         reference.getAccess().setPixel(Vec4((float)stencil, 0.0f, 0.0f, 0.0f), x, y);
1539                                         }
1540                                 }
1541                                 {
1542                                         const Vec4 threshold (verifyDepth ? (1.0f / 1024.0f) : 0.0f, 0.0f, 0.0f, 0.0f);
1543
1544                                         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1545                                                 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1546                                 }
1547                         }
1548                         else
1549                         {
1550                                 const tcu::TextureChannelClass  channelClass    (tcu::getTextureChannelClass(format.type));
1551
1552                                 switch (channelClass)
1553                                 {
1554                                         case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1555                                         {
1556                                                 const UVec4             bits                    (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1557                                                 const UVec4             minValue                (0);
1558                                                 const UVec4             range                   (UVec4(1u) << tcu::min(bits, UVec4(31)));
1559                                                 const int               componentCount  (tcu::getNumUsedChannels(format.order));
1560                                                 const deUint32  bitSize                 (bits[0] + bits[1] + bits[2] + bits[3]);
1561
1562                                                 for (deUint32 y = 0; y < m_height; y++)
1563                                                 for (deUint32 x = 0; x < m_width; x++)
1564                                                 {
1565                                                         const deUint32  x1                              = x ^ sampleNdx;
1566                                                         const deUint32  y1                              = y ^ sampleNdx;
1567                                                         UVec4                   color                   (minValue);
1568                                                         deUint32                dstBitsUsed[4]  = { 0u, 0u, 0u, 0u };
1569                                                         deUint32                nextSrcBit              = 0;
1570                                                         deUint32                divider                 = 2;
1571
1572                                                         // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1573                                                         while (nextSrcBit < de::min(bitSize, 10u))
1574                                                         {
1575                                                                 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1576                                                                 {
1577                                                                         if (dstBitsUsed[compNdx] > bits[compNdx])
1578                                                                                 continue;
1579
1580                                                                         color[compNdx] += (range[compNdx] / divider)
1581                                                                                                         * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1582
1583                                                                         nextSrcBit++;
1584                                                                         dstBitsUsed[compNdx]++;
1585                                                                 }
1586
1587                                                                 divider *= 2;
1588                                                         }
1589
1590                                                         reference.getAccess().setPixel(color, x, y);
1591                                                 }
1592
1593                                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1594                                                         m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1595
1596                                                 break;
1597                                         }
1598
1599                                         case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1600                                         {
1601                                                 const UVec4             bits                    (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1602                                                 const IVec4             minValue                (0);
1603                                                 const IVec4             range                   ((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1604                                                 const int               componentCount  (tcu::getNumUsedChannels(format.order));
1605                                                 const deUint32  bitSize                 (bits[0] + bits[1] + bits[2] + bits[3]);
1606
1607                                                 for (deUint32 y = 0; y < m_height; y++)
1608                                                 for (deUint32 x = 0; x < m_width; x++)
1609                                                 {
1610                                                         const deUint32  x1                              = x ^ sampleNdx;
1611                                                         const deUint32  y1                              = y ^ sampleNdx;
1612                                                         IVec4                   color                   (minValue);
1613                                                         deUint32                dstBitsUsed[4]  = { 0u, 0u, 0u, 0u };
1614                                                         deUint32                nextSrcBit              = 0;
1615                                                         deUint32                divider                 = 2;
1616
1617                                                         // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1618                                                         while (nextSrcBit < de::min(bitSize, 10u))
1619                                                         {
1620                                                                 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1621                                                                 {
1622                                                                         if (dstBitsUsed[compNdx] > bits[compNdx])
1623                                                                                 continue;
1624
1625                                                                         color[compNdx] += (range[compNdx] / divider)
1626                                                                                                         * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1627
1628                                                                         nextSrcBit++;
1629                                                                         dstBitsUsed[compNdx]++;
1630                                                                 }
1631
1632                                                                 divider *= 2;
1633                                                         }
1634
1635                                                         reference.getAccess().setPixel(color, x, y);
1636                                                 }
1637
1638                                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1639                                                         m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1640
1641                                                 break;
1642                                         }
1643
1644                                         case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1645                                         case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1646                                         case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1647                                         {
1648                                                 const tcu::TextureFormatInfo    info                    (tcu::getTextureFormatInfo(format));
1649                                                 const UVec4                                             bits                    (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1650                                                 const Vec4                                              minLimit                (-65536.0);
1651                                                 const Vec4                                              maxLimit                (65536.0);
1652                                                 const Vec4                                              minValue                (tcu::max(info.valueMin, minLimit));
1653                                                 const Vec4                                              range                   (tcu::min(info.valueMax, maxLimit) - minValue);
1654                                                 const int                                               componentCount  (tcu::getNumUsedChannels(format.order));
1655                                                 const deUint32                                  bitSize                 (bits[0] + bits[1] + bits[2] + bits[3]);
1656
1657                                                 for (deUint32 y = 0; y < m_height; y++)
1658                                                 for (deUint32 x = 0; x < m_width; x++)
1659                                                 {
1660                                                         const deUint32  x1                              = x ^ sampleNdx;
1661                                                         const deUint32  y1                              = y ^ sampleNdx;
1662                                                         Vec4                    color                   (minValue);
1663                                                         deUint32                dstBitsUsed[4]  = { 0u, 0u, 0u, 0u };
1664                                                         deUint32                nextSrcBit              = 0;
1665                                                         deUint32                divider                 = 2;
1666
1667                                                         // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1668                                                         while (nextSrcBit < de::min(bitSize, 10u))
1669                                                         {
1670                                                                 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1671                                                                 {
1672                                                                         if (dstBitsUsed[compNdx] > bits[compNdx])
1673                                                                                 continue;
1674
1675                                                                         color[compNdx] += (range[compNdx] / (float)divider)
1676                                                                                                         * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1677
1678                                                                         nextSrcBit++;
1679                                                                         dstBitsUsed[compNdx]++;
1680                                                                 }
1681
1682                                                                 divider *= 2;
1683                                                         }
1684
1685                                                         if (tcu::isSRGB(format))
1686                                                                 reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
1687                                                         else
1688                                                                 reference.getAccess().setPixel(color, x, y);
1689                                                 }
1690
1691                                                 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1692                                                 {
1693                                                         // Convert target format ulps to float ulps and allow 64ulp differences
1694                                                         const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
1695
1696                                                         if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1697                                                                 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1698                                                 }
1699                                                 else
1700                                                 {
1701                                                         // Allow error of 4 times the minimum presentable difference
1702                                                         const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
1703
1704                                                         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1705                                                                 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1706                                                 }
1707
1708                                                 break;
1709                                         }
1710
1711                                         default:
1712                                                 DE_FATAL("Unknown channel class");
1713                                 }
1714                         }
1715                 }
1716         }
1717
1718         return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1719 }
1720
1721 struct Programs
1722 {
1723         void init (vk::SourceCollections& dst, TestConfig config) const
1724         {
1725                 const tcu::TextureFormat                format                  (mapVkFormat(config.format));
1726                 const tcu::TextureChannelClass  channelClass    (tcu::getTextureChannelClass(format.type));
1727                 const bool                                              testDepth               (config.separateStencilUsage ? (config.separateStencilUsage == TEST_DEPTH) : tcu::hasDepthComponent(format.order));
1728                 const bool                                              testStencil             (config.separateStencilUsage ? (config.separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(format.order));
1729
1730                 dst.glslSources.add("quad-vert") << glu::VertexSource(
1731                         "#version 450\n"
1732                         "out gl_PerVertex {\n"
1733                         "\tvec4 gl_Position;\n"
1734                         "};\n"
1735                         "highp float;\n"
1736                         "void main (void) {\n"
1737                         "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1738                         "\t                   ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1739                         "}\n");
1740
1741                 if (testDepth)
1742                 {
1743                         const Vec4                      minValue                (0.0f);
1744                         const Vec4                      range                   (1.0f);
1745                         std::ostringstream      fragmentShader;
1746
1747                         fragmentShader <<
1748                                 "#version 450\n"
1749                                 "layout(push_constant) uniform PushConstant {\n"
1750                                 "\thighp uint sampleIndex;\n"
1751                                 "} pushConstants;\n"
1752                                 "void main (void)\n"
1753                                 "{\n"
1754                                 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1755                                 "\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1756                                 "\thighp float depth;\n"
1757                                 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1758                                 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1759
1760                         fragmentShader << "\tdepth = "  << minValue[0] << ";\n";
1761
1762                         {
1763                                 deUint32 divider = 2;
1764
1765                                 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1766                                 for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1767                                 {
1768                                         fragmentShader <<
1769                                                         "\tdepth += " << (range[0] / (float)divider)
1770                                                         << " * float(bitfieldExtract(" << (bitNdx % 2 == 0 ? "x" : "y") << ", " << (bitNdx / 2) << ", 1));\n";
1771
1772                                         divider *= 2;
1773                                 }
1774                         }
1775
1776                         fragmentShader <<
1777                                 "\tgl_FragDepth = depth;\n"
1778                                 "}\n";
1779
1780                         dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1781                 }
1782                 else if (testStencil)
1783                 {
1784                         dst.glslSources.add("quad-frag") << glu::FragmentSource(
1785                                 "#version 450\n"
1786                                 "layout(push_constant) uniform PushConstant {\n"
1787                                 "\thighp uint sampleIndex;\n"
1788                                 "} pushConstants;\n"
1789                                 "void main (void)\n"
1790                                 "{\n"
1791                                 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1792                                 "\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1793                                 "}\n");
1794                 }
1795                 else
1796                 {
1797                         switch (channelClass)
1798                         {
1799                                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1800                                 {
1801                                         const UVec4     bits            (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1802                                         const UVec4 minValue    (0);
1803                                         const UVec4 range               (UVec4(1u) << tcu::min(bits, UVec4(31)));
1804                                         std::ostringstream              fragmentShader;
1805
1806                                         fragmentShader <<
1807                                                 "#version 450\n"
1808                                                 "layout(location = 0) out highp uvec4 o_color;\n"
1809                                                 "layout(push_constant) uniform PushConstant {\n"
1810                                                 "\thighp uint sampleIndex;\n"
1811                                                 "} pushConstants;\n"
1812                                                 "void main (void)\n"
1813                                                 "{\n"
1814                                                 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1815                                                 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1816                                                 "\thighp uint color[4];\n"
1817                                                 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1818                                                 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1819
1820                                         for (int ndx = 0; ndx < 4; ndx++)
1821                                                 fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";
1822
1823                                         {
1824                                                 const int               componentCount  = tcu::getNumUsedChannels(format.order);
1825                                                 const deUint32  bitSize                 (bits[0] + bits[1] + bits[2] + bits[3]);
1826                                                 deUint32                dstBitsUsed[4]  = { 0u, 0u, 0u, 0u };
1827                                                 deUint32                nextSrcBit              = 0;
1828                                                 deUint32                divider                 = 2;
1829
1830                                                 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1831                                                 while (nextSrcBit < de::min(bitSize, 10u))
1832                                                 {
1833                                                         for (int compNdx = 0; compNdx < componentCount; compNdx++)
1834                                                         {
1835                                                                 if (dstBitsUsed[compNdx] > bits[compNdx])
1836                                                                         continue;
1837
1838                                                                 fragmentShader <<
1839                                                                                 "\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1840                                                                                 << " * bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1);\n";
1841
1842                                                                 nextSrcBit++;
1843                                                                 dstBitsUsed[compNdx]++;
1844                                                         }
1845
1846                                                         divider *= 2;
1847                                                 }
1848                                         }
1849
1850                                         fragmentShader <<
1851                                                 "\to_color = uvec4(color[0], color[1], color[2], color[3]);\n"
1852                                                 "}\n";
1853
1854                                         dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1855                                         break;
1856                                 }
1857
1858                                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1859                                 {
1860                                         const UVec4     bits            (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1861                                         const IVec4 minValue    (0);
1862                                         const IVec4 range               ((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1863                                         const IVec4 maxV                ((UVec4(1u) << (bits - UVec4(1u))).cast<deInt32>());
1864                                         const IVec4 clampMax    (maxV - 1);
1865                                         const IVec4 clampMin    (-maxV);
1866                                         std::ostringstream              fragmentShader;
1867
1868                                         fragmentShader <<
1869                                                 "#version 450\n"
1870                                                 "layout(location = 0) out highp ivec4 o_color;\n"
1871                                                 "layout(push_constant) uniform PushConstant {\n"
1872                                                 "\thighp uint sampleIndex;\n"
1873                                                 "} pushConstants;\n"
1874                                                 "void main (void)\n"
1875                                                 "{\n"
1876                                                 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1877                                                 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1878                                                 "\thighp int color[4];\n"
1879                                                 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1880                                                 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1881
1882                                         for (int ndx = 0; ndx < 4; ndx++)
1883                                                 fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";
1884
1885                                         {
1886                                                 const int               componentCount  = tcu::getNumUsedChannels(format.order);
1887                                                 const deUint32  bitSize                 (bits[0] + bits[1] + bits[2] + bits[3]);
1888                                                 deUint32                dstBitsUsed[4]  = { 0u, 0u, 0u, 0u };
1889                                                 deUint32                nextSrcBit              = 0;
1890                                                 deUint32                divider                 = 2;
1891
1892                                                 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1893                                                 while (nextSrcBit < de::min(bitSize, 10u))
1894                                                 {
1895                                                         for (int compNdx = 0; compNdx < componentCount; compNdx++)
1896                                                         {
1897                                                                 if (dstBitsUsed[compNdx] > bits[compNdx])
1898                                                                         continue;
1899
1900                                                                 fragmentShader <<
1901                                                                                 "\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1902                                                                                 << " * int(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
1903
1904                                                                 nextSrcBit++;
1905                                                                 dstBitsUsed[compNdx]++;
1906                                                         }
1907
1908                                                         divider *= 2;
1909                                                 }
1910                                         }
1911
1912                                         // The spec doesn't define whether signed-integers are clamped on output,
1913                                         // so we'll clamp them explicitly to have well-defined outputs.
1914                                         fragmentShader <<
1915                                                 "\to_color = clamp(ivec4(color[0], color[1], color[2], color[3]), " <<
1916                                                 "ivec4" << clampMin << ", ivec4" << clampMax << ");\n" <<
1917                                                 "}\n";
1918
1919                                         dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1920                                         break;
1921                                 }
1922
1923                                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1924                                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1925                                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1926                                 {
1927                                         const tcu::TextureFormatInfo    info                    (tcu::getTextureFormatInfo(format));
1928                                         const UVec4                                             bits                    (tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>());
1929                                         const Vec4                                              minLimit                (-65536.0);
1930                                         const Vec4                                              maxLimit                (65536.0);
1931                                         const Vec4                                              minValue                (tcu::max(info.valueMin, minLimit));
1932                                         const Vec4                                              range                   (tcu::min(info.valueMax, maxLimit) - minValue);
1933                                         std::ostringstream                              fragmentShader;
1934
1935                                         fragmentShader <<
1936                                                 "#version 450\n"
1937                                                 "layout(location = 0) out highp vec4 o_color;\n"
1938                                                 "layout(push_constant) uniform PushConstant {\n"
1939                                                 "\thighp uint sampleIndex;\n"
1940                                                 "} pushConstants;\n"
1941                                                 "void main (void)\n"
1942                                                 "{\n"
1943                                                 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1944                                                 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1945                                                 "\thighp float color[4];\n"
1946                                                 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1947                                                 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1948
1949                                         for (int ndx = 0; ndx < 4; ndx++)
1950                                                 fragmentShader << "\tcolor[" << ndx << "] = "  << minValue[ndx] << ";\n";
1951
1952                                         {
1953                                                 const int               componentCount  = tcu::getNumUsedChannels(format.order);
1954                                                 const deUint32  bitSize                 (bits[0] + bits[1] + bits[2] + bits[3]);
1955                                                 deUint32                dstBitsUsed[4]  = { 0u, 0u, 0u, 0u };
1956                                                 deUint32                nextSrcBit              = 0;
1957                                                 deUint32                divider                 = 2;
1958
1959                                                 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1960                                                 while (nextSrcBit < de::min(bitSize, 10u))
1961                                                 {
1962                                                         for (int compNdx = 0; compNdx < componentCount; compNdx++)
1963                                                         {
1964                                                                 if (dstBitsUsed[compNdx] > bits[compNdx])
1965                                                                         continue;
1966
1967                                                                 fragmentShader <<
1968                                                                                 "\tcolor[" << compNdx << "] += " << (range[compNdx] / (float)divider)
1969                                                                                 << " * float(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
1970
1971                                                                 nextSrcBit++;
1972                                                                 dstBitsUsed[compNdx]++;
1973                                                         }
1974
1975                                                         divider *= 2;
1976                                                 }
1977                                         }
1978
1979                                         fragmentShader <<
1980                                                 "\to_color = vec4(color[0], color[1], color[2], color[3]);\n"
1981                                                 "}\n";
1982
1983                                         dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1984                                         break;
1985                                 }
1986
1987                                 default:
1988                                         DE_FATAL("Unknown channel class");
1989                         }
1990                 }
1991
1992                 if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
1993                 {
1994                         std::ostringstream splitShader;
1995
1996                         splitShader <<
1997                                 "#version 450\n";
1998
1999                         if (testDepth && testStencil)
2000                         {
2001                                 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n"
2002                                                         << "layout(input_attachment_index = 0, set = 0, binding = 1) uniform highp usubpassInputMS i_stencil;\n";
2003                         }
2004                         else if (testDepth)
2005                                 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n";
2006                         else if (testStencil)
2007                                 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp usubpassInputMS i_stencil;\n";
2008
2009                         splitShader <<
2010                                 "layout(push_constant) uniform PushConstant {\n"
2011                                 "\thighp uint splitSubpassIndex;\n"
2012                                 "} pushConstants;\n";
2013
2014                         for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2015                         {
2016                                 if (testDepth && testStencil)
2017                                         splitShader << "layout(location = " << attachmentNdx << ") out highp vec2 o_color" << attachmentNdx << ";\n";
2018                                 else
2019                                         splitShader << "layout(location = " << attachmentNdx << ") out highp float o_color" << attachmentNdx << ";\n";
2020                         }
2021
2022                         splitShader <<
2023                                 "void main (void)\n"
2024                                 "{\n";
2025
2026                         for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2027                         {
2028                                 if (testDepth)
2029                                         splitShader << "\thighp float depth" << attachmentNdx << " = subpassLoad(i_depth, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2030
2031                                 if (testStencil)
2032                                         splitShader << "\thighp uint stencil" << attachmentNdx << " = subpassLoad(i_stencil, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2033
2034                                 if (testDepth && testStencil)
2035                                         splitShader << "\to_color" << attachmentNdx << " = vec2(depth" << attachmentNdx << ", float(stencil" << attachmentNdx << "));\n";
2036                                 else if (testDepth)
2037                                         splitShader << "\to_color" << attachmentNdx << " = float(depth" << attachmentNdx << ");\n";
2038                                 else if (testStencil)
2039                                         splitShader << "\to_color" << attachmentNdx << " = float(stencil" << attachmentNdx << ");\n";
2040                         }
2041
2042                         splitShader <<
2043                                 "}\n";
2044
2045                         dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2046                 }
2047                 else
2048                 {
2049                         std::string subpassType;
2050                         std::string outputType;
2051
2052                         switch (channelClass)
2053                         {
2054                                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2055                                         subpassType     = "usubpassInputMS";
2056                                         outputType      = "uvec4";
2057                                         break;
2058
2059                                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2060                                         subpassType     = "isubpassInputMS";
2061                                         outputType      = "ivec4";
2062                                         break;
2063
2064                                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2065                                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2066                                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2067                                         subpassType     = "subpassInputMS";
2068                                         outputType      = "vec4";
2069                                         break;
2070
2071                                 default:
2072                                         DE_FATAL("Unknown channel class");
2073                         }
2074
2075                         std::ostringstream splitShader;
2076                         splitShader <<
2077                                 "#version 450\n"
2078                                 "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp " << subpassType << " i_color;\n"
2079                                 "layout(push_constant) uniform PushConstant {\n"
2080                                 "\thighp uint splitSubpassIndex;\n"
2081                                 "} pushConstants;\n";
2082
2083                         for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2084                                 splitShader << "layout(location = " << attachmentNdx << ") out highp " << outputType << " o_color" << attachmentNdx << ";\n";
2085
2086                         splitShader <<
2087                                 "void main (void)\n"
2088                                 "{\n";
2089
2090                         for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2091                                 splitShader << "\to_color" << attachmentNdx << " = subpassLoad(i_color, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u));\n";
2092
2093                         splitShader <<
2094                                 "}\n";
2095
2096                         dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2097                 }
2098         }
2099 };
2100
2101 std::string formatToName (VkFormat format)
2102 {
2103         const std::string       formatStr       = de::toString(format);
2104         const std::string       prefix          = "VK_FORMAT_";
2105
2106         DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
2107
2108         return de::toLower(formatStr.substr(prefix.length()));
2109 }
2110
2111 void initTests (tcu::TestCaseGroup* group, RenderingType renderingType)
2112 {
2113         static const VkFormat   formats[]       =
2114         {
2115                 VK_FORMAT_R5G6B5_UNORM_PACK16,
2116                 VK_FORMAT_R8_UNORM,
2117                 VK_FORMAT_R8_SNORM,
2118                 VK_FORMAT_R8_UINT,
2119                 VK_FORMAT_R8_SINT,
2120                 VK_FORMAT_R8G8_UNORM,
2121                 VK_FORMAT_R8G8_SNORM,
2122                 VK_FORMAT_R8G8_UINT,
2123                 VK_FORMAT_R8G8_SINT,
2124                 VK_FORMAT_R8G8B8A8_UNORM,
2125                 VK_FORMAT_R8G8B8A8_SNORM,
2126                 VK_FORMAT_R8G8B8A8_UINT,
2127                 VK_FORMAT_R8G8B8A8_SINT,
2128                 VK_FORMAT_R8G8B8A8_SRGB,
2129                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
2130                 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2131                 VK_FORMAT_A8B8G8R8_UINT_PACK32,
2132                 VK_FORMAT_A8B8G8R8_SINT_PACK32,
2133                 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
2134                 VK_FORMAT_B8G8R8A8_UNORM,
2135                 VK_FORMAT_B8G8R8A8_SRGB,
2136                 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2137                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2138                 VK_FORMAT_A2B10G10R10_UINT_PACK32,
2139                 VK_FORMAT_R16_UNORM,
2140                 VK_FORMAT_R16_SNORM,
2141                 VK_FORMAT_R16_UINT,
2142                 VK_FORMAT_R16_SINT,
2143                 VK_FORMAT_R16_SFLOAT,
2144                 VK_FORMAT_R16G16_UNORM,
2145                 VK_FORMAT_R16G16_SNORM,
2146                 VK_FORMAT_R16G16_UINT,
2147                 VK_FORMAT_R16G16_SINT,
2148                 VK_FORMAT_R16G16_SFLOAT,
2149                 VK_FORMAT_R16G16B16A16_UNORM,
2150                 VK_FORMAT_R16G16B16A16_SNORM,
2151                 VK_FORMAT_R16G16B16A16_UINT,
2152                 VK_FORMAT_R16G16B16A16_SINT,
2153                 VK_FORMAT_R16G16B16A16_SFLOAT,
2154                 VK_FORMAT_R32_UINT,
2155                 VK_FORMAT_R32_SINT,
2156                 VK_FORMAT_R32_SFLOAT,
2157                 VK_FORMAT_R32G32_UINT,
2158                 VK_FORMAT_R32G32_SINT,
2159                 VK_FORMAT_R32G32_SFLOAT,
2160                 VK_FORMAT_R32G32B32A32_UINT,
2161                 VK_FORMAT_R32G32B32A32_SINT,
2162                 VK_FORMAT_R32G32B32A32_SFLOAT,
2163                 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
2164
2165                 VK_FORMAT_D16_UNORM,
2166                 VK_FORMAT_X8_D24_UNORM_PACK32,
2167                 VK_FORMAT_D32_SFLOAT,
2168                 VK_FORMAT_S8_UINT,
2169                 VK_FORMAT_D16_UNORM_S8_UINT,
2170                 VK_FORMAT_D24_UNORM_S8_UINT,
2171                 VK_FORMAT_D32_SFLOAT_S8_UINT
2172         };
2173         const deUint32                  sampleCounts[] =
2174         {
2175                 2u, 4u, 8u, 16u, 32u
2176         };
2177         tcu::TestContext&                               testCtx         (group->getTestContext());
2178         de::MovePtr<tcu::TestCaseGroup> extGroup        (new tcu::TestCaseGroup(testCtx, "separate_stencil_usage", "test VK_EXT_separate_stencil_usage"));
2179
2180         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2181         {
2182                 const VkFormat                                  format                  (formats[formatNdx]);
2183                 const std::string                               formatName              (formatToName(format));
2184                 de::MovePtr<tcu::TestCaseGroup> formatGroup             (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
2185                 de::MovePtr<tcu::TestCaseGroup> extFormatGroup  (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
2186
2187                 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
2188                 {
2189                         const deUint32          sampleCount     (sampleCounts[sampleCountNdx]);
2190                         const TestConfig        testConfig      (format, sampleCount, renderingType);
2191                         const std::string       testName        ("samples_" + de::toString(sampleCount));
2192
2193                         formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
2194
2195                         // create tests for VK_EXT_separate_stencil_usage
2196                         if (tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order))
2197                         {
2198                                 de::MovePtr<tcu::TestCaseGroup> sampleGroup     (new tcu::TestCaseGroup(testCtx, testName.c_str(), testName.c_str()));
2199                                 {
2200                                         const TestConfig        separateUsageDepthTestConfig    (format, sampleCount, renderingType, TEST_DEPTH);
2201                                         sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_depth", "depth with input attachment bit", separateUsageDepthTestConfig));
2202
2203                                         const TestConfig        separateUsageStencilTestConfig  (format, sampleCount, renderingType, TEST_STENCIL);
2204                                         sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_stencil", "stencil with input attachment bit", separateUsageStencilTestConfig));
2205                                 }
2206
2207                                 extFormatGroup->addChild(sampleGroup.release());
2208                         }
2209                 }
2210
2211                 group->addChild(formatGroup.release());
2212                 extGroup->addChild(extFormatGroup.release());
2213         }
2214
2215         group->addChild(extGroup.release());
2216 }
2217
2218 } // anonymous
2219
2220 tcu::TestCaseGroup* createRenderPassMultisampleTests (tcu::TestContext& testCtx)
2221 {
2222         return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests, RENDERING_TYPE_RENDERPASS_LEGACY);
2223 }
2224
2225 tcu::TestCaseGroup* createRenderPass2MultisampleTests (tcu::TestContext& testCtx)
2226 {
2227         return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests, RENDERING_TYPE_RENDERPASS2);
2228 }
2229
2230 } // vkt