Merge vk-gl-cts/opengl-es-cts-3.2.8 into vk-gl-cts/main
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / renderpass / vktRenderPassTests.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 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 RenderPass tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
26 #include "vktRenderPassGroupParams.hpp"
27 #include "vktRenderPassMultisampleTests.hpp"
28 #include "vktRenderPassMultisampleResolveTests.hpp"
29 #include "vktRenderPassSampleReadTests.hpp"
30 #ifndef CTS_USES_VULKANSC
31 #include "vktRenderPassSparseRenderTargetTests.hpp"
32 #endif // CTS_USES_VULKANSC
33 #include "vktRenderPassSubpassDependencyTests.hpp"
34 #include "vktRenderPassUnusedAttachmentTests.hpp"
35 #include "vktRenderPassUnusedClearAttachmentTests.hpp"
36 #include "vktRenderPassDepthStencilResolveTests.hpp"
37 #include "vktRenderPassUnusedAttachmentSparseFillingTests.hpp"
38 #include "vktRenderPassFragmentDensityMapTests.hpp"
39 #include "vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.hpp"
40 #ifndef CTS_USES_VULKANSC
41 #include "vktRenderPassLoadStoreOpNoneTests.hpp"
42 #include "vktDynamicRenderingTests.hpp"
43 #endif // CTS_USES_VULKANSC
44 #include "vktRenderPassDepthStencilWriteConditionsTests.hpp"
45 #include "vktRenderPassSubpassMergeFeedbackTests.hpp"
46 #include "vktDynamicRenderingRandomTests.hpp"
47 #include "vktRenderPassDitheringTests.hpp"
48
49 #include "vktTestCaseUtil.hpp"
50 #include "vktTestGroupUtil.hpp"
51
52 #include "vkDefs.hpp"
53 #include "vkDeviceUtil.hpp"
54 #include "vkImageUtil.hpp"
55 #include "vkMemUtil.hpp"
56 #include "vkPlatform.hpp"
57 #include "vkPrograms.hpp"
58 #include "vkQueryUtil.hpp"
59 #include "vkRef.hpp"
60 #include "vkRefUtil.hpp"
61 #include "vkStrUtil.hpp"
62 #include "vkTypeUtil.hpp"
63 #include "vkCmdUtil.hpp"
64 #include "vkObjUtil.hpp"
65
66 #include "tcuFloat.hpp"
67 #include "tcuFormatUtil.hpp"
68 #include "tcuMaybe.hpp"
69 #include "tcuResultCollector.hpp"
70 #include "tcuTestLog.hpp"
71 #include "tcuTextureUtil.hpp"
72 #include "tcuVectorUtil.hpp"
73
74 #include "deRandom.hpp"
75 #include "deSTLUtil.hpp"
76 #include "deSharedPtr.hpp"
77 #include "deStringUtil.hpp"
78 #include "deUniquePtr.hpp"
79
80 #include <limits>
81 #include <set>
82 #include <string>
83 #include <vector>
84 #include <memory>
85
86 using namespace vk;
87
88 using tcu::BVec4;
89 using tcu::IVec2;
90 using tcu::IVec4;
91 using tcu::UVec2;
92 using tcu::UVec4;
93 using tcu::Vec2;
94 using tcu::Vec4;
95
96 using tcu::Maybe;
97 using tcu::just;
98
99 using tcu::ConstPixelBufferAccess;
100 using tcu::PixelBufferAccess;
101
102 using tcu::TestLog;
103
104 using de::UniquePtr;
105
106 using std::pair;
107 using std::set;
108 using std::string;
109 using std::vector;
110
111 namespace vkt
112 {
113 namespace
114 {
115 using namespace renderpass;
116
117 typedef vector<deUint8> DepthValuesArray;
118
119 static const deUint8    DEPTH_VALUES[]  = { 0u, 255u, 1u };
120
121 enum AllocationKind
122 {
123         ALLOCATION_KIND_SUBALLOCATED,
124         ALLOCATION_KIND_DEDICATED,
125 };
126
127 struct TestConfigExternal
128 {
129         TestConfigExternal (AllocationKind                              allocationKind_,
130                                                 const SharedGroupParams         groupParams_)
131         : allocationKind        (allocationKind_)
132         , groupParams           (groupParams_)
133         {
134         }
135
136         AllocationKind                  allocationKind;
137         const SharedGroupParams groupParams;
138 };
139
140 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&        vki,
141                                                                                 const DeviceInterface&          vkd,
142                                                                                 const VkPhysicalDevice&         physDevice,
143                                                                                 const VkDevice                          device,
144                                                                                 const VkBuffer&                         buffer,
145                                                                                 const MemoryRequirement         requirement,
146                                                                                 Allocator&                                      allocator,
147                                                                                 AllocationKind                          allocationKind)
148 {
149         switch (allocationKind)
150         {
151                 case ALLOCATION_KIND_SUBALLOCATED:
152                 {
153                         const VkMemoryRequirements      memoryRequirements      = getBufferMemoryRequirements(vkd, device, buffer);
154
155                         return allocator.allocate(memoryRequirements, requirement);
156                 }
157
158                 case ALLOCATION_KIND_DEDICATED:
159                 {
160                         return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
161                 }
162
163                 default:
164                 {
165                         TCU_THROW(InternalError, "Invalid allocation kind");
166                 }
167         }
168 }
169
170 de::MovePtr<Allocation> allocateImage (const InstanceInterface&         vki,
171                                                                            const DeviceInterface&               vkd,
172                                                                            const VkPhysicalDevice&              physDevice,
173                                                                            const VkDevice                               device,
174                                                                            const VkImage&                               image,
175                                                                            const MemoryRequirement              requirement,
176                                                                            Allocator&                                   allocator,
177                                                                            AllocationKind                               allocationKind)
178 {
179         switch (allocationKind)
180         {
181                 case ALLOCATION_KIND_SUBALLOCATED:
182                 {
183                         const VkMemoryRequirements      memoryRequirements      = getImageMemoryRequirements(vkd, device, image);
184
185                         return allocator.allocate(memoryRequirements, requirement);
186                 }
187
188                 case ALLOCATION_KIND_DEDICATED:
189                 {
190                         return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
191                 }
192
193                 default:
194                 {
195                         TCU_THROW(InternalError, "Invalid allocation kind");
196                 }
197         }
198 }
199
200 enum BoolOp
201 {
202         BOOLOP_AND,
203         BOOLOP_OR,
204         BOOLOP_EQ,
205         BOOLOP_NEQ
206 };
207
208 const char* boolOpToString (BoolOp op)
209 {
210         switch (op)
211         {
212                 case BOOLOP_OR:
213                         return "||";
214
215                 case BOOLOP_AND:
216                         return "&&";
217
218                 case BOOLOP_EQ:
219                         return "==";
220
221                 case BOOLOP_NEQ:
222                         return "!=";
223
224                 default:
225                         DE_FATAL("Unknown boolean operation.");
226                         return DE_NULL;
227         }
228 }
229
230 bool performBoolOp (BoolOp op, bool a, bool b)
231 {
232         switch (op)
233         {
234                 case BOOLOP_OR:
235                         return a || b;
236
237                 case BOOLOP_AND:
238                         return a && b;
239
240                 case BOOLOP_EQ:
241                         return a == b;
242
243                 case BOOLOP_NEQ:
244                         return a != b;
245
246                 default:
247                         DE_FATAL("Unknown boolean operation.");
248                         return false;
249         }
250 }
251
252 BoolOp boolOpFromIndex (size_t index)
253 {
254         const BoolOp ops[] =
255         {
256                 BOOLOP_OR,
257                 BOOLOP_AND,
258                 BOOLOP_EQ,
259                 BOOLOP_NEQ
260         };
261
262         return ops[index % DE_LENGTH_OF_ARRAY(ops)];
263 }
264
265 static float requiredDepthEpsilon(VkFormat format)
266 {
267         // Possible precision loss in the unorm depth pipeline means that we need to check depths
268         // that go in and back out of the depth buffer with an epsilon rather than an exact match
269         deUint32 unormBits = 0;
270
271         switch (format)
272         {
273         case VK_FORMAT_D16_UNORM:
274                 unormBits = 16;
275                 break;
276         case VK_FORMAT_X8_D24_UNORM_PACK32:
277         case VK_FORMAT_D24_UNORM_S8_UINT:
278                 unormBits = 24;
279                 break;
280         case VK_FORMAT_D32_SFLOAT:
281         case VK_FORMAT_D32_SFLOAT_S8_UINT:
282         default:
283                 unormBits = 0;
284                 break;
285         }
286
287         if (unormBits > 0)
288                 return 1.0f / (float)((1 << unormBits) - 1);
289
290         return 0.0f; // Require exact match
291 }
292
293 static bool depthsEqual(float a, float b, float epsilon)
294 {
295         return fabs(a - b) <= epsilon;
296 }
297
298 Move<VkFramebuffer> createFramebuffer (const DeviceInterface&   vk,
299                                                                            VkDevice                                     device,
300                                                                            VkFramebufferCreateFlags     pCreateInfo_flags,
301                                                                            VkRenderPass                         pCreateInfo_renderPass,
302                                                                            deUint32                                     pCreateInfo_attachmentCount,
303                                                                            const VkImageView*           pCreateInfo_pAttachments,
304                                                                            deUint32                                     pCreateInfo_width,
305                                                                            deUint32                                     pCreateInfo_height,
306                                                                            deUint32                                     pCreateInfo_layers)
307 {
308         const VkFramebufferCreateInfo pCreateInfo =
309         {
310                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
311                 DE_NULL,
312                 pCreateInfo_flags,
313                 pCreateInfo_renderPass,
314                 pCreateInfo_attachmentCount,
315                 pCreateInfo_pAttachments,
316                 pCreateInfo_width,
317                 pCreateInfo_height,
318                 pCreateInfo_layers,
319         };
320         return createFramebuffer(vk, device, &pCreateInfo);
321 }
322
323 Move<VkImage> createImage (const DeviceInterface&       vk,
324                                                    VkDevice                                     device,
325                                                    VkImageCreateFlags           pCreateInfo_flags,
326                                                    VkImageType                          pCreateInfo_imageType,
327                                                    VkFormat                                     pCreateInfo_format,
328                                                    VkExtent3D                           pCreateInfo_extent,
329                                                    deUint32                                     pCreateInfo_mipLevels,
330                                                    deUint32                                     pCreateInfo_arrayLayers,
331                                                    VkSampleCountFlagBits        pCreateInfo_samples,
332                                                    VkImageTiling                        pCreateInfo_tiling,
333                                                    VkImageUsageFlags            pCreateInfo_usage,
334                                                    VkSharingMode                        pCreateInfo_sharingMode,
335                                                    deUint32                                     pCreateInfo_queueFamilyCount,
336                                                    const deUint32*                      pCreateInfo_pQueueFamilyIndices,
337                                                    VkImageLayout                        pCreateInfo_initialLayout)
338 {
339         const VkImageCreateInfo pCreateInfo =
340         {
341                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
342                 DE_NULL,
343                 pCreateInfo_flags,
344                 pCreateInfo_imageType,
345                 pCreateInfo_format,
346                 pCreateInfo_extent,
347                 pCreateInfo_mipLevels,
348                 pCreateInfo_arrayLayers,
349                 pCreateInfo_samples,
350                 pCreateInfo_tiling,
351                 pCreateInfo_usage,
352                 pCreateInfo_sharingMode,
353                 pCreateInfo_queueFamilyCount,
354                 pCreateInfo_pQueueFamilyIndices,
355                 pCreateInfo_initialLayout
356         };
357         return createImage(vk, device, &pCreateInfo);
358 }
359
360 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
361 {
362         VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
363 }
364
365 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
366 {
367         VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
368 }
369
370 Move<VkImageView> createImageView (const DeviceInterface&       vk,
371                                                                         VkDevice                                device,
372                                                                         VkImageViewCreateFlags  pCreateInfo_flags,
373                                                                         VkImage                                 pCreateInfo_image,
374                                                                         VkImageViewType                 pCreateInfo_viewType,
375                                                                         VkFormat                                pCreateInfo_format,
376                                                                         VkComponentMapping              pCreateInfo_components,
377                                                                         VkImageSubresourceRange pCreateInfo_subresourceRange)
378 {
379         const VkImageViewCreateInfo pCreateInfo =
380         {
381                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
382                 DE_NULL,
383                 pCreateInfo_flags,
384                 pCreateInfo_image,
385                 pCreateInfo_viewType,
386                 pCreateInfo_format,
387                 pCreateInfo_components,
388                 pCreateInfo_subresourceRange,
389         };
390         return createImageView(vk, device, &pCreateInfo);
391 }
392
393 Move<VkBuffer> createBuffer (const DeviceInterface&     vk,
394                                                          VkDevice                               device,
395                                                          VkBufferCreateFlags    pCreateInfo_flags,
396                                                          VkDeviceSize                   pCreateInfo_size,
397                                                          VkBufferUsageFlags             pCreateInfo_usage,
398                                                          VkSharingMode                  pCreateInfo_sharingMode,
399                                                          deUint32                               pCreateInfo_queueFamilyCount,
400                                                          const deUint32*                pCreateInfo_pQueueFamilyIndices)
401 {
402         const VkBufferCreateInfo pCreateInfo =
403         {
404                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
405                 DE_NULL,
406                 pCreateInfo_flags,
407                 pCreateInfo_size,
408                 pCreateInfo_usage,
409                 pCreateInfo_sharingMode,
410                 pCreateInfo_queueFamilyCount,
411                 pCreateInfo_pQueueFamilyIndices,
412         };
413         return createBuffer(vk, device, &pCreateInfo);
414 }
415
416 VkRenderPassBeginInfo createRenderPassBeginInfo (VkRenderPass                   pRenderPassBegin_renderPass,
417                                                                                                  VkFramebuffer                  pRenderPassBegin_framebuffer,
418                                                                                                  VkRect2D                               pRenderPassBegin_renderArea,
419                                                                                                  deUint32                               pRenderPassBegin_clearValueCount,
420                                                                                                  const VkClearValue*    pRenderPassBegin_pAttachmentClearValues)
421 {
422         const VkRenderPassBeginInfo renderPassBeginInfo =
423         {
424                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
425                 DE_NULL,
426                 pRenderPassBegin_renderPass,
427                 pRenderPassBegin_framebuffer,
428                 pRenderPassBegin_renderArea,
429                 pRenderPassBegin_clearValueCount,
430                 pRenderPassBegin_pAttachmentClearValues,
431         };
432
433         return renderPassBeginInfo;
434 }
435
436 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
437 {
438         const VkSubmitInfo submitInfo =
439         {
440                 VK_STRUCTURE_TYPE_SUBMIT_INFO,
441                 DE_NULL,
442                 0u,                                                             // waitSemaphoreCount
443                 (const VkSemaphore*)DE_NULL,    // pWaitSemaphores
444                 (const VkPipelineStageFlags*)DE_NULL,
445                 cmdBufferCount,                                 // commandBufferCount
446                 pCmdBuffers,
447                 0u,                                                             // signalSemaphoreCount
448                 (const VkSemaphore*)DE_NULL,    // pSignalSemaphores
449         };
450         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
451 }
452
453 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
454 {
455         VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
456 }
457
458 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
459 {
460         const tcu::TextureFormat format = mapVkFormat(vkFormat);
461
462         DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 22);
463
464         switch (format.order)
465         {
466                 case tcu::TextureFormat::DS:
467                         return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
468
469                 case tcu::TextureFormat::D:
470                         return VK_IMAGE_ASPECT_DEPTH_BIT;
471
472                 case tcu::TextureFormat::S:
473                         return VK_IMAGE_ASPECT_STENCIL_BIT;
474
475                 default:
476                         return VK_IMAGE_ASPECT_COLOR_BIT;
477         }
478 }
479
480 VkAccessFlags getAllMemoryReadFlags (void)
481 {
482         return VK_ACCESS_TRANSFER_READ_BIT
483                    | VK_ACCESS_UNIFORM_READ_BIT
484                    | VK_ACCESS_HOST_READ_BIT
485                    | VK_ACCESS_INDEX_READ_BIT
486                    | VK_ACCESS_SHADER_READ_BIT
487                    | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
488                    | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
489                    | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
490                    | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
491                    | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
492 }
493
494 VkAccessFlags getAllMemoryWriteFlags (void)
495 {
496         return VK_ACCESS_TRANSFER_WRITE_BIT
497                    | VK_ACCESS_HOST_WRITE_BIT
498                    | VK_ACCESS_SHADER_WRITE_BIT
499                    | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
500                    | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
501 }
502
503 VkAccessFlags getMemoryFlagsForLayout (const VkImageLayout layout)
504 {
505         switch (layout)
506         {
507                 case VK_IMAGE_LAYOUT_GENERAL:                                                                           return getAllMemoryReadFlags() | getAllMemoryWriteFlags();
508                 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:                                          return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
509                 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:                          return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
510                 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:                           return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
511                 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:                                          return VK_ACCESS_SHADER_READ_BIT;
512                 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:                                                      return VK_ACCESS_TRANSFER_READ_BIT;
513                 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:                                                      return VK_ACCESS_TRANSFER_WRITE_BIT;
514                 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:        return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
515                 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:        return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
516                 default:
517                         return (VkAccessFlags)0;
518         }
519 }
520
521 VkPipelineStageFlags getAllPipelineStageFlags (void)
522 {
523         /* All relevant flags for a pipeline containing VS+PS. */
524         return VK_PIPELINE_STAGE_TRANSFER_BIT
525                    | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
526                    | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
527                    | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
528                    | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
529                    | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
530                    | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
531                    | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
532                    | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
533                    | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
534                    | VK_PIPELINE_STAGE_HOST_BIT;
535 }
536
537 class AttachmentReference
538 {
539 public:
540                                                 AttachmentReference             (deUint32                       attachment,
541                                                                                                  VkImageLayout          layout,
542                                                                                                  VkImageAspectFlags     aspectMask = static_cast<VkImageAspectFlags>(0u))
543                 : m_attachment  (attachment)
544                 , m_layout              (layout)
545                 , m_aspectMask  (aspectMask)
546         {
547         }
548
549         deUint32                        getAttachment                   (void) const { return m_attachment;     }
550         VkImageLayout           getImageLayout                  (void) const { return m_layout;         }
551         VkImageAspectFlags      getAspectMask                   (void) const { return m_aspectMask;     }
552         void                            setImageLayout                  (VkImageLayout layout) { m_layout = layout;     }
553
554 private:
555         deUint32                        m_attachment;
556         VkImageLayout           m_layout;
557         VkImageAspectFlags      m_aspectMask;
558 };
559
560 class Subpass
561 {
562 public:
563                                                                                 Subpass                                         (VkPipelineBindPoint                            pipelineBindPoint,
564                                                                                                                                          VkSubpassDescriptionFlags                      flags,
565                                                                                                                                          const vector<AttachmentReference>&     inputAttachments,
566                                                                                                                                          const vector<AttachmentReference>&     colorAttachments,
567                                                                                                                                          const vector<AttachmentReference>&     resolveAttachments,
568                                                                                                                                          AttachmentReference                            depthStencilAttachment,
569                                                                                                                                          const vector<deUint32>&                        preserveAttachments,
570                                                                                                                                          bool                                                           omitBlendState = false)
571                 : m_pipelineBindPoint           (pipelineBindPoint)
572                 , m_flags                                       (flags)
573                 , m_inputAttachments            (inputAttachments)
574                 , m_colorAttachments            (colorAttachments)
575                 , m_resolveAttachments          (resolveAttachments)
576                 , m_depthStencilAttachment      (depthStencilAttachment)
577                 , m_preserveAttachments         (preserveAttachments)
578                 , m_omitBlendState                      (omitBlendState)
579         {
580         }
581
582         VkPipelineBindPoint                                     getPipelineBindPoint            (void) const { return m_pipelineBindPoint;              }
583         VkSubpassDescriptionFlags                       getFlags                                        (void) const { return m_flags;                                  }
584         const vector<AttachmentReference>&      getInputAttachments                     (void) const { return m_inputAttachments;               }
585         const vector<AttachmentReference>&      getColorAttachments                     (void) const { return m_colorAttachments;               }
586         const vector<AttachmentReference>&      getResolveAttachments           (void) const { return m_resolveAttachments;             }
587         const AttachmentReference&                      getDepthStencilAttachment       (void) const { return m_depthStencilAttachment; }
588         const vector<deUint32>&                         getPreserveAttachments          (void) const { return m_preserveAttachments;    }
589         bool                                                            getOmitBlendState                       (void) const { return m_omitBlendState;                 }
590
591 private:
592         VkPipelineBindPoint                                     m_pipelineBindPoint;
593         VkSubpassDescriptionFlags                       m_flags;
594
595         vector<AttachmentReference>                     m_inputAttachments;
596         vector<AttachmentReference>                     m_colorAttachments;
597         vector<AttachmentReference>                     m_resolveAttachments;
598         AttachmentReference                                     m_depthStencilAttachment;
599
600         vector<deUint32>                                        m_preserveAttachments;
601         bool                                                            m_omitBlendState;
602 };
603
604 class SubpassDependency
605 {
606 public:
607                                                         SubpassDependency       (deUint32                               srcPass,
608                                                                                                  deUint32                               dstPass,
609
610                                                                                                  VkPipelineStageFlags   srcStageMask,
611                                                                                                  VkPipelineStageFlags   dstStageMask,
612
613                                                                                                  VkAccessFlags                  srcAccessMask,
614                                                                                                  VkAccessFlags                  dstAccessMask,
615
616                                                                                                  VkDependencyFlags              flags)
617                 : m_srcPass                     (srcPass)
618                 , m_dstPass                     (dstPass)
619
620                 , m_srcStageMask        (srcStageMask)
621                 , m_dstStageMask        (dstStageMask)
622
623                 , m_srcAccessMask       (srcAccessMask)
624                 , m_dstAccessMask       (dstAccessMask)
625                 , m_flags                       (flags)
626         {
627         }
628
629         deUint32                                getSrcPass                      (void) const { return m_srcPass;                }
630         deUint32                                getDstPass                      (void) const { return m_dstPass;                }
631
632         VkPipelineStageFlags    getSrcStageMask         (void) const { return m_srcStageMask;   }
633         VkPipelineStageFlags    getDstStageMask         (void) const { return m_dstStageMask;   }
634
635         VkAccessFlags                   getSrcAccessMask        (void) const { return m_srcAccessMask;  }
636         VkAccessFlags                   getDstAccessMask        (void) const { return m_dstAccessMask;  }
637
638         VkDependencyFlags               getFlags                        (void) const { return m_flags;          }
639
640         void                                    setSrcAccessMask        (const VkAccessFlags& flags) { m_srcAccessMask = flags; }
641         void                                    setDstAccessMask        (const VkAccessFlags& flags) { m_dstAccessMask = flags; }
642
643 private:
644         deUint32                                m_srcPass;
645         deUint32                                m_dstPass;
646
647         VkPipelineStageFlags    m_srcStageMask;
648         VkPipelineStageFlags    m_dstStageMask;
649
650         VkAccessFlags                   m_srcAccessMask;
651         VkAccessFlags                   m_dstAccessMask;
652         VkDependencyFlags               m_flags;
653 };
654
655 class Attachment
656 {
657 public:
658                                                         Attachment                      (VkFormat                               format,
659                                                                                                  VkSampleCountFlagBits  samples,
660
661                                                                                                  VkAttachmentLoadOp             loadOp,
662                                                                                                  VkAttachmentStoreOp    storeOp,
663
664                                                                                                  VkAttachmentLoadOp             stencilLoadOp,
665                                                                                                  VkAttachmentStoreOp    stencilStoreOp,
666
667                                                                                                  VkImageLayout                  initialLayout,
668                                                                                                  VkImageLayout                  finalLayout)
669                 : m_format                      (format)
670                 , m_samples                     (samples)
671
672                 , m_loadOp                      (loadOp)
673                 , m_storeOp                     (storeOp)
674
675                 , m_stencilLoadOp       (stencilLoadOp)
676                 , m_stencilStoreOp      (stencilStoreOp)
677
678                 , m_initialLayout       (initialLayout)
679                 , m_finalLayout         (finalLayout)
680         {
681         }
682
683         VkFormat                                getFormat                       (void) const { return m_format;                 }
684         VkSampleCountFlagBits   getSamples                      (void) const { return m_samples;                }
685
686         VkAttachmentLoadOp              getLoadOp                       (void) const { return m_loadOp;                 }
687         VkAttachmentStoreOp             getStoreOp                      (void) const { return m_storeOp;                }
688
689
690         VkAttachmentLoadOp              getStencilLoadOp        (void) const { return m_stencilLoadOp;  }
691         VkAttachmentStoreOp             getStencilStoreOp       (void) const { return m_stencilStoreOp; }
692
693         VkImageLayout                   getInitialLayout        (void) const { return m_initialLayout;  }
694         VkImageLayout                   getFinalLayout          (void) const { return m_finalLayout;    }
695
696 private:
697         VkFormat                                m_format;
698         VkSampleCountFlagBits   m_samples;
699
700         VkAttachmentLoadOp              m_loadOp;
701         VkAttachmentStoreOp             m_storeOp;
702
703         VkAttachmentLoadOp              m_stencilLoadOp;
704         VkAttachmentStoreOp             m_stencilStoreOp;
705
706         VkImageLayout                   m_initialLayout;
707         VkImageLayout                   m_finalLayout;
708 };
709
710 class RenderPass
711 {
712 public:
713                                                                                                                 RenderPass              (const vector<Attachment>&                                              attachments,
714                                                                                                                                                  const vector<Subpass>&                                                 subpasses,
715                                                                                                                                                  const vector<SubpassDependency>&                               dependencies,
716                                                                                                                                                  const vector<VkInputAttachmentAspectReference> inputAspects = vector<VkInputAttachmentAspectReference>())
717                 : m_attachments         (attachments)
718                 , m_subpasses           (subpasses)
719                 , m_dependencies        (dependencies)
720                 , m_inputAspects        (inputAspects)
721         {
722         }
723
724         const vector<Attachment>&                                                       getAttachments  (void) const { return m_attachments;    }
725         const vector<Subpass>&                                                          getSubpasses    (void) const { return m_subpasses;              }
726         const vector<SubpassDependency>&                                        getDependencies (void) const { return m_dependencies;   }
727         const vector<VkInputAttachmentAspectReference>&         getInputAspects (void) const { return m_inputAspects;   }
728
729 private:
730         const vector<Attachment>                                                        m_attachments;
731         const vector<Subpass>                                                           m_subpasses;
732         const vector<SubpassDependency>                                         m_dependencies;
733         const vector<VkInputAttachmentAspectReference>          m_inputAspects;
734 };
735
736 struct TestConfig
737 {
738         enum RenderTypes
739         {
740                 RENDERTYPES_NONE        = 0,
741                 RENDERTYPES_CLEAR       = (1<<1),
742                 RENDERTYPES_DRAW        = (1<<2)
743         };
744
745         enum CommandBufferTypes
746         {
747                 COMMANDBUFFERTYPES_INLINE               = (1<<0),
748                 COMMANDBUFFERTYPES_SECONDARY    = (1<<1)
749         };
750
751         enum ImageMemory
752         {
753                 IMAGEMEMORY_STRICT              = (1<<0),
754                 IMAGEMEMORY_LAZY                = (1<<1)
755         };
756
757                                                 TestConfig (const RenderPass&                   renderPass_,
758                                                                         RenderTypes                                     renderTypes_,
759                                                                         CommandBufferTypes                      commandBufferTypes_,
760                                                                         ImageMemory                                     imageMemory_,
761                                                                         const UVec2&                            targetSize_,
762                                                                         const UVec2&                            renderPos_,
763                                                                         const UVec2&                            renderSize_,
764                                                                         deBool                                          useFormatCompCount_,
765                                                                         deUint32                                        seed_,
766                                                                         deUint32                                        drawStartNdx_,
767                                                                         AllocationKind                          allocationKind_,
768                                                                         SharedGroupParams                       groupParams_,
769                                                                         vector<DeviceCoreFeature>       requiredFeatures_ = vector<DeviceCoreFeature>())
770                 : renderPass                    (renderPass_)
771                 , renderTypes                   (renderTypes_)
772                 , commandBufferTypes    (commandBufferTypes_)
773                 , imageMemory                   (imageMemory_)
774                 , targetSize                    (targetSize_)
775                 , renderPos                             (renderPos_)
776                 , renderSize                    (renderSize_)
777                 , useFormatCompCount    (useFormatCompCount_)
778                 , seed                                  (seed_)
779                 , drawStartNdx                  (drawStartNdx_)
780                 , allocationKind                (allocationKind_)
781                 , groupParams                   (groupParams_)
782                 , requiredFeatures              (requiredFeatures_)
783         {
784                 DepthValuesArray        shuffledDepthValues     (&DEPTH_VALUES[0], &DEPTH_VALUES[DE_LENGTH_OF_ARRAY(DEPTH_VALUES)]);
785                 de::Random                      rng                                     (seed + 1);
786
787                 rng.shuffle(shuffledDepthValues.begin(), shuffledDepthValues.end());
788
789                 depthValues.push_back(shuffledDepthValues[0]);
790                 depthValues.push_back(shuffledDepthValues[1]);
791         }
792
793         RenderPass                                      renderPass;
794         RenderTypes                                     renderTypes;
795         CommandBufferTypes                      commandBufferTypes;
796         ImageMemory                                     imageMemory;
797         UVec2                                           targetSize;
798         UVec2                                           renderPos;
799         UVec2                                           renderSize;
800         deBool                                          useFormatCompCount;
801         deUint32                                        seed;
802         deUint32                                        drawStartNdx;
803         AllocationKind                          allocationKind;
804         SharedGroupParams                       groupParams;
805         vector<DeviceCoreFeature>       requiredFeatures;
806         DepthValuesArray                        depthValues;
807 };
808
809 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
810 {
811         return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
812 }
813
814 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
815 {
816         return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
817 }
818
819 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
820 {
821         return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
822 }
823
824 void checkSupport (Context& context, TestConfig config)
825 {
826         for (size_t featureNdx = 0; featureNdx < config.requiredFeatures.size(); featureNdx++)
827                 context.requireDeviceCoreFeature(config.requiredFeatures[featureNdx]);
828 }
829
830 void logRenderPassInfo (TestLog&                        log,
831                                                 const RenderPass&       renderPass)
832 {
833         const bool                                      useExternalInputAspect  = !renderPass.getInputAspects().empty();
834         const tcu::ScopedLogSection     section                                 (log, "RenderPass", "RenderPass");
835
836         {
837                 const tcu::ScopedLogSection     attachmentsSection      (log, "Attachments", "Attachments");
838                 const vector<Attachment>&       attachments                     = renderPass.getAttachments();
839
840                 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
841                 {
842                         const tcu::ScopedLogSection     attachmentSection       (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
843                         const Attachment&                       attachment                      = attachments[attachmentNdx];
844
845                         log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
846                         log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
847
848                         log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
849                         log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
850
851                         log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
852                         log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
853
854                         log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
855                         log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
856                 }
857         }
858
859         if (useExternalInputAspect)
860         {
861                 const tcu::ScopedLogSection     inputAspectSection      (log, "InputAspects", "InputAspects");
862
863                 for (size_t aspectNdx = 0; aspectNdx < renderPass.getInputAspects().size(); aspectNdx++)
864                 {
865                         const VkInputAttachmentAspectReference& inputAspect     (renderPass.getInputAspects()[aspectNdx]);
866
867                         log << TestLog::Message << "Subpass: " << inputAspect.subpass << TestLog::EndMessage;
868                         log << TestLog::Message << "InputAttachmentIndex: " << inputAspect.inputAttachmentIndex << TestLog::EndMessage;
869                         log << TestLog::Message << "AspectFlags: " << getImageAspectFlagsStr(inputAspect.aspectMask) << TestLog::EndMessage;
870                 }
871         }
872
873         {
874                 const tcu::ScopedLogSection     subpassesSection        (log, "Subpasses", "Subpasses");
875                 const vector<Subpass>&          subpasses                       = renderPass.getSubpasses();
876
877                 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
878                 {
879                         const tcu::ScopedLogSection                     subpassSection          (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
880                         const Subpass&                                          subpass                         = subpasses[subpassNdx];
881
882                         const vector<AttachmentReference>&      inputAttachments        = subpass.getInputAttachments();
883                         const vector<AttachmentReference>&      colorAttachments        = subpass.getColorAttachments();
884                         const vector<AttachmentReference>&      resolveAttachments      = subpass.getResolveAttachments();
885                         const vector<deUint32>&                         preserveAttachments     = subpass.getPreserveAttachments();
886
887                         if (!inputAttachments.empty())
888                         {
889                                 const tcu::ScopedLogSection     inputAttachmentsSection (log, "Inputs", "Inputs");
890
891                                 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
892                                 {
893                                         const tcu::ScopedLogSection     inputAttachmentSection  (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
894                                         const AttachmentReference&      inputAttachment                 = inputAttachments[inputNdx];
895
896                                         log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
897                                         log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
898                                         if (!useExternalInputAspect)
899                                                 log << TestLog::Message << "AspectMask: " << inputAttachment.getAspectMask() << TestLog::EndMessage;
900                                 }
901                         }
902
903                         if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
904                         {
905                                 const tcu::ScopedLogSection     depthStencilAttachmentSection   (log, "DepthStencil", "DepthStencil");
906                                 const AttachmentReference&      depthStencilAttachment                  = subpass.getDepthStencilAttachment();
907
908                                 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
909                                 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
910                         }
911
912                         if (!colorAttachments.empty())
913                         {
914                                 const tcu::ScopedLogSection     colorAttachmentsSection (log, "Colors", "Colors");
915
916                                 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
917                                 {
918                                         const tcu::ScopedLogSection     colorAttachmentSection  (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
919                                         const AttachmentReference&      colorAttachment                 = colorAttachments[colorNdx];
920
921                                         log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
922                                         log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
923                                 }
924                         }
925
926                         if (!resolveAttachments.empty())
927                         {
928                                 const tcu::ScopedLogSection     resolveAttachmentsSection       (log, "Resolves", "Resolves");
929
930                                 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
931                                 {
932                                         const tcu::ScopedLogSection     resolveAttachmentSection        (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
933                                         const AttachmentReference&      resolveAttachment                       = resolveAttachments[resolveNdx];
934
935                                         log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
936                                         log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
937                                 }
938                         }
939
940                         if (!preserveAttachments.empty())
941                         {
942                                 const tcu::ScopedLogSection     preserveAttachmentsSection      (log, "Preserves", "Preserves");
943
944                                 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
945                                 {
946                                         const tcu::ScopedLogSection     preserveAttachmentSection       (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
947                                         const deUint32                          preserveAttachment                      = preserveAttachments[preserveNdx];
948
949                                         log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage;
950                                 }
951                         }
952                 }
953
954         }
955
956         if (!renderPass.getDependencies().empty())
957         {
958                 const tcu::ScopedLogSection     dependenciesSection     (log, "Dependencies", "Dependencies");
959
960                 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
961                 {
962                         const tcu::ScopedLogSection     dependencySection       (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
963                         const SubpassDependency&        dep                                     = renderPass.getDependencies()[depNdx];
964
965                         log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
966                         log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
967
968                         log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
969                         log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
970
971                         log << TestLog::Message << "Input Mask: " << dep.getDstAccessMask() << TestLog::EndMessage;
972                         log << TestLog::Message << "Output Mask: " << dep.getSrcAccessMask() << TestLog::EndMessage;
973                         log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
974                 }
975         }
976 }
977
978 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value, deBool useFormatCompCount)
979 {
980         const tcu::TextureFormat                format                  = mapVkFormat(vkFormat);
981         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
982         const tcu::BVec4                                channelMask             = tcu::getTextureFormatChannelMask(format);
983         const deUint32                                  componentCount  = (useFormatCompCount ? (deUint32)tcu::getNumUsedChannels(format.order) : 4);
984
985         std::ostringstream                              stream;
986
987         stream << "(";
988
989         switch (channelClass)
990         {
991                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
992                         for (deUint32 i = 0; i < componentCount; i++)
993                         {
994                                 if (i > 0)
995                                         stream << ", ";
996
997                                 if (channelMask[i])
998                                         stream << value.int32[i];
999                                 else
1000                                         stream << "Undef";
1001                         }
1002                         break;
1003
1004                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1005                         for (deUint32 i = 0; i < componentCount; i++)
1006                         {
1007                                 if (i > 0)
1008                                         stream << ", ";
1009
1010                                 if (channelMask[i])
1011                                         stream << value.uint32[i];
1012                                 else
1013                                         stream << "Undef";
1014                         }
1015                         break;
1016
1017                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1018                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1019                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1020                         for (deUint32 i = 0; i < componentCount; i++)
1021                         {
1022                                 if (i > 0)
1023                                         stream << ", ";
1024
1025                                 if (channelMask[i])
1026                                         stream << value.float32[i];
1027                                 else
1028                                         stream << "Undef";
1029                         }
1030                         break;
1031
1032                 default:
1033                         DE_FATAL("Unknown channel class");
1034         }
1035
1036         stream << ")";
1037
1038         return stream.str();
1039 }
1040
1041 std::string clearValueToString (VkFormat vkFormat, VkClearValue value, deBool useFormatCompCount)
1042 {
1043         const tcu::TextureFormat        format  = mapVkFormat(vkFormat);
1044
1045         if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1046         {
1047                 std::ostringstream stream;
1048
1049                 stream << "(";
1050
1051                 if (tcu::hasStencilComponent(format.order))
1052                         stream << "stencil: " << value.depthStencil.stencil;
1053
1054                 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
1055                         stream << ", ";
1056
1057                 if (tcu::hasDepthComponent(format.order))
1058                         stream << "depth: " << value.depthStencil.depth;
1059
1060                 stream << ")";
1061
1062                 return stream.str();
1063         }
1064         else
1065                 return clearColorToString(vkFormat, value.color, useFormatCompCount);
1066 }
1067
1068 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng, deBool useFormatCompCount)
1069 {
1070         const float                                             clearNan                = tcu::Float32::nan().asFloat();
1071         const tcu::TextureFormat                format                  = mapVkFormat(attachment.getFormat());
1072         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
1073         const tcu::BVec4                                channelMask             = tcu::getTextureFormatChannelMask(format);
1074         const deUint32                                  componentCount  = (useFormatCompCount ? (deUint32)tcu::getNumUsedChannels(format.order) : 4);
1075         VkClearColorValue                               clearColor;
1076
1077         switch (channelClass)
1078         {
1079                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1080                 {
1081                         for (deUint32 ndx = 0; ndx < componentCount; ndx++)
1082                         {
1083                                 if (!channelMask[ndx])
1084                                         clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
1085                                 else
1086                                         clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1087                         }
1088                         break;
1089                 }
1090
1091                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1092                 {
1093                         for (deUint32 ndx = 0; ndx < componentCount; ndx++)
1094                         {
1095                                 if (!channelMask[ndx])
1096                                         clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
1097                                 else
1098                                         clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1099                         }
1100                         break;
1101                 }
1102
1103                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1104                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1105                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1106                 {
1107                         for (deUint32 ndx = 0; ndx < componentCount; ndx++)
1108                         {
1109                                 if (!channelMask[ndx])
1110                                         clearColor.float32[ndx] = clearNan;
1111                                 else
1112                                         clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f;
1113                         }
1114                         break;
1115                 }
1116
1117                 default:
1118                         DE_FATAL("Unknown channel class");
1119         }
1120
1121         return clearColor;
1122 }
1123
1124 template <typename AttachmentDesc>
1125 AttachmentDesc createAttachmentDescription (const Attachment& attachment)
1126 {
1127         const AttachmentDesc    attachmentDescription   //  VkAttachmentDescription                                                                             ||  VkAttachmentDescription2KHR
1128         (
1129                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
1130                 DE_NULL,                                                                        //                                                                                                                              ||  const void*                                                 pNext;
1131                 0u,                                                                                     //  VkAttachmentDescriptionFlags        flags;                                          ||  VkAttachmentDescriptionFlags                flags;
1132                 attachment.getFormat(),                                         //  VkFormat                                            format;                                         ||  VkFormat                                                    format;
1133                 attachment.getSamples(),                                        //  VkSampleCountFlagBits                       samples;                                        ||  VkSampleCountFlagBits                               samples;
1134                 attachment.getLoadOp(),                                         //  VkAttachmentLoadOp                          loadOp;                                         ||  VkAttachmentLoadOp                                  loadOp;
1135                 attachment.getStoreOp(),                                        //  VkAttachmentStoreOp                         storeOp;                                        ||  VkAttachmentStoreOp                                 storeOp;
1136                 attachment.getStencilLoadOp(),                          //  VkAttachmentLoadOp                          stencilLoadOp;                          ||  VkAttachmentLoadOp                                  stencilLoadOp;
1137                 attachment.getStencilStoreOp(),                         //  VkAttachmentStoreOp                         stencilStoreOp;                         ||  VkAttachmentStoreOp                                 stencilStoreOp;
1138                 attachment.getInitialLayout(),                          //  VkImageLayout                                       initialLayout;                          ||  VkImageLayout                                               initialLayout;
1139                 attachment.getFinalLayout()                                     //  VkImageLayout                                       finalLayout;                            ||  VkImageLayout                                               finalLayout;
1140         );
1141
1142         return attachmentDescription;
1143 }
1144
1145 template <typename AttachmentRef>
1146 AttachmentRef createAttachmentReference (const AttachmentReference& referenceInfo)
1147 {
1148         const AttachmentRef     reference                                       //  VkAttachmentReference                                                                               ||  VkAttachmentReference2KHR
1149         (
1150                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
1151                 DE_NULL,                                                                        //                                                                                                                              ||  const void*                                                 pNext;
1152                 referenceInfo.getAttachment(),                          //  deUint32                                            attachment;                                     ||  deUint32                                                    attachment;
1153                 referenceInfo.getImageLayout(),                         //  VkImageLayout                                       layout;                                         ||  VkImageLayout                                               layout;
1154                 referenceInfo.getAspectMask()                           //                                                                                                                              ||  VkImageAspectFlags                                  aspectMask;
1155         );
1156
1157         return reference;
1158 }
1159
1160 template <typename SubpassDesc, typename AttachmentRef>
1161 SubpassDesc createSubpassDescription (const Subpass&                    subpass,
1162                                                                           vector<AttachmentRef>*        attachmentReferenceLists,
1163                                                                           vector<deUint32>*                     preserveAttachmentReferences)
1164 {
1165         vector<AttachmentRef>&  inputAttachmentReferences                       = attachmentReferenceLists[0];
1166         vector<AttachmentRef>&  colorAttachmentReferences                       = attachmentReferenceLists[1];
1167         vector<AttachmentRef>&  resolveAttachmentReferences                     = attachmentReferenceLists[2];
1168         vector<AttachmentRef>&  depthStencilAttachmentReferences        = attachmentReferenceLists[3];
1169
1170         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
1171                 colorAttachmentReferences.push_back(createAttachmentReference<AttachmentRef>(subpass.getColorAttachments()[attachmentNdx]));
1172
1173         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
1174                 inputAttachmentReferences.push_back(createAttachmentReference<AttachmentRef>(subpass.getInputAttachments()[attachmentNdx]));
1175
1176         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
1177                 resolveAttachmentReferences.push_back(createAttachmentReference<AttachmentRef>(subpass.getResolveAttachments()[attachmentNdx]));
1178
1179         depthStencilAttachmentReferences.push_back(createAttachmentReference<AttachmentRef>(subpass.getDepthStencilAttachment()));
1180
1181         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
1182                 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]);
1183
1184         DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
1185
1186         {
1187                 const SubpassDesc subpassDescription                                                                                                            //  VkSubpassDescription                                                                                ||  VkSubpassDescription2KHR
1188                 (
1189                                                                                                                                                                                                         //                                                                                                                              ||  VkStructureType                                             sType;
1190                         DE_NULL,                                                                                                                                                                //                                                                                                                              ||  const void*                                                 pNext;
1191                         subpass.getFlags(),                                                                                                                                             //  VkSubpassDescriptionFlags           flags;                                          ||  VkSubpassDescriptionFlags                   flags;
1192                         subpass.getPipelineBindPoint(),                                                                                                                 //  VkPipelineBindPoint                         pipelineBindPoint;                      ||  VkPipelineBindPoint                                 pipelineBindPoint;
1193                         0u,                                                                                                                                                                             //                                                                                                                              ||  deUint32                                                    viewMask;
1194                         (deUint32)inputAttachmentReferences.size(),                                                                                             //  deUint32                                            inputAttachmentCount;           ||  deUint32                                                    inputAttachmentCount;
1195                         inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0],                    //  const VkAttachmentReference*        pInputAttachments;                      ||  const VkAttachmentReference2KHR*    pInputAttachments;
1196                         (deUint32)colorAttachmentReferences.size(),                                                                                             //  deUint32                                            colorAttachmentCount;           ||  deUint32                                                    colorAttachmentCount;
1197                         colorAttachmentReferences.empty() ? DE_NULL :  &colorAttachmentReferences[0],                   //  const VkAttachmentReference*        pColorAttachments;                      ||  const VkAttachmentReference2KHR*    pColorAttachments;
1198                         resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0],                //  const VkAttachmentReference*        pResolveAttachments;            ||  const VkAttachmentReference2KHR*    pResolveAttachments;
1199                         &depthStencilAttachmentReferences[0],                                                                                                   //  const VkAttachmentReference*        pDepthStencilAttachment;        ||  const VkAttachmentReference2KHR*    pDepthStencilAttachment;
1200                         (deUint32)preserveAttachmentReferences->size(),                                                                                 //  deUint32                                            preserveAttachmentCount;        ||  deUint32                                                    preserveAttachmentCount;
1201                         preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0]   //  const deUint32*                                     pPreserveAttachments;           ||  const deUint32*                                             pPreserveAttachments;
1202                 );
1203
1204                 return subpassDescription;
1205         }
1206 }
1207
1208 template <typename SubpassDep>
1209 SubpassDep createSubpassDependency (const SubpassDependency& dependencyInfo)
1210 {
1211         const SubpassDep        dependency                      //  VkSubpassDependency                                                                                 ||  VkSubpassDependency2KHR
1212         (
1213                                                                                         //                                                                                                                              ||      VkStructureType                                         sType;
1214                 DE_NULL,                                                        //                                                                                                                              ||      const void*                                                     pNext;
1215                 dependencyInfo.getSrcPass(),            //  deUint32                                            srcSubpass;                                     ||      deUint32                                                        srcSubpass;
1216                 dependencyInfo.getDstPass(),            //  deUint32                                            dstSubpass;                                     ||      deUint32                                                        dstSubpass;
1217                 dependencyInfo.getSrcStageMask(),       //  VkPipelineStageFlags                        srcStageMask;                           ||      VkPipelineStageFlags                            srcStageMask;
1218                 dependencyInfo.getDstStageMask(),       //  VkPipelineStageFlags                        dstStageMask;                           ||      VkPipelineStageFlags                            dstStageMask;
1219                 dependencyInfo.getSrcAccessMask(),      //  VkAccessFlags                                       srcAccessMask;                          ||      VkAccessFlags                                           srcAccessMask;
1220                 dependencyInfo.getDstAccessMask(),      //  VkAccessFlags                                       dstAccessMask;                          ||      VkAccessFlags                                           dstAccessMask;
1221                 dependencyInfo.getFlags(),                      //  VkDependencyFlags                           dependencyFlags;                        ||      VkDependencyFlags                                       dependencyFlags;
1222                 0u                                                                      //                                                                                                                              ||      deInt32                                                         viewOffset;
1223         );
1224
1225         return dependency;
1226 }
1227
1228 de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo> createRenderPassInputAttachmentAspectCreateInfo(const RenderPass& renderPassInfo)
1229 {
1230         de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo>        result  (DE_NULL);
1231
1232         if (!renderPassInfo.getInputAspects().empty())
1233         {
1234                 const VkRenderPassInputAttachmentAspectCreateInfo       inputAspectCreateInfo   =
1235                 {
1236                         VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
1237                         DE_NULL,
1238
1239                         (deUint32)renderPassInfo.getInputAspects().size(),
1240                         renderPassInfo.getInputAspects().data(),
1241                 };
1242
1243                 result = de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo>(new VkRenderPassInputAttachmentAspectCreateInfo(inputAspectCreateInfo));
1244         }
1245
1246         return result;
1247 }
1248
1249 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
1250 Move<VkRenderPass> createRenderPass (const DeviceInterface&     vk,
1251                                                                          VkDevice                               device,
1252                                                                          const RenderPass&              renderPassInfo)
1253 {
1254         const size_t                                                                                            perSubpassAttachmentReferenceLists = 4;
1255         vector<AttachmentDesc>                                                                          attachments;
1256         vector<SubpassDesc>                                                                                     subpasses;
1257         vector<SubpassDep>                                                                                      dependencies;
1258         vector<vector<AttachmentRef> >                                                          attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
1259         vector<vector<deUint32> >                                                                       preserveAttachments(renderPassInfo.getSubpasses().size());
1260         de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo>        inputAspectCreateInfo(createRenderPassInputAttachmentAspectCreateInfo(renderPassInfo));
1261
1262         for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1263                 attachments.push_back(createAttachmentDescription<AttachmentDesc>(renderPassInfo.getAttachments()[attachmentNdx]));
1264
1265         for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1266                 subpasses.push_back(createSubpassDescription<SubpassDesc>(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));
1267
1268         for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1269                 dependencies.push_back(createSubpassDependency<SubpassDep>(renderPassInfo.getDependencies()[depNdx]));
1270
1271         const RenderPassCreateInfo      renderPassCreator                               //  VkRenderPassCreateInfo                                                                              ||  VkRenderPassCreateInfo2KHR
1272         (
1273                                                                                                                                 //  VkStructureType                                     sType;                                          ||  VkStructureType                                             sType;
1274                 inputAspectCreateInfo.get(),                                                    //  const void*                                         pNext;                                          ||  const void*                                                 pNext;
1275                 (VkRenderPassCreateFlags)0u,                                                    //  VkRenderPassCreateFlags                     flags;                                          ||  VkRenderPassCreateFlags                             flags;
1276                 (deUint32)attachments.size(),                                                   //  deUint32                                            attachmentCount;                        ||  deUint32                                                    attachmentCount;
1277                 (attachments.empty() ? DE_NULL : &attachments[0]),              //  const VkAttachmentDescription*      pAttachments;                           ||  const VkAttachmentDescription2KHR*  pAttachments;
1278                 (deUint32)subpasses.size(),                                                             //  deUint32                                            subpassCount;                           ||  deUint32                                                    subpassCount;
1279                 (subpasses.empty() ? DE_NULL : &subpasses[0]),                  //  const VkSubpassDescription*         pSubpasses;                                     ||  const VkSubpassDescription2KHR*             pSubpasses;
1280                 (deUint32)dependencies.size(),                                                  //  deUint32                                            dependencyCount;                        ||  deUint32                                                    dependencyCount;
1281                 (dependencies.empty() ? DE_NULL : &dependencies[0]),    //  const VkSubpassDependency*          pDependencies;                          ||  const VkSubpassDependency2KHR*              pDependencies;
1282                 0u,                                                                                                             //                                                                                                                              ||  deUint32                                                    correlatedViewMaskCount;
1283                 DE_NULL                                                                                                 //                                                                                                                              ||  const deUint32*                                             pCorrelatedViewMasks;
1284         );
1285
1286         return renderPassCreator.createRenderPass(vk, device);
1287 }
1288
1289 Move<VkRenderPass> createRenderPass (const DeviceInterface&     vk,
1290                                                                          VkDevice                               device,
1291                                                                          const RenderPass&              renderPassInfo,
1292                                                                          const RenderingType    renderPassType)
1293 {
1294         switch (renderPassType)
1295         {
1296                 case RENDERING_TYPE_RENDERPASS_LEGACY:
1297                         return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, renderPassInfo);
1298                 case RENDERING_TYPE_RENDERPASS2:
1299                         return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, renderPassInfo);
1300                 default:
1301                         TCU_THROW(InternalError, "Impossible");
1302         }
1303 }
1304
1305 Move<VkFramebuffer> createFramebuffer (const DeviceInterface&           vk,
1306                                                                            VkDevice                                             device,
1307                                                                            VkRenderPass                                 renderPass,
1308                                                                            const UVec2&                                 size,
1309                                                                            const vector<VkImageView>&   attachments)
1310 {
1311         return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1312 }
1313
1314 Move<VkImage> createAttachmentImage (const DeviceInterface&     vk,
1315                                                                          VkDevice                               device,
1316                                                                          deUint32                               queueIndex,
1317                                                                          const UVec2&                   size,
1318                                                                          VkFormat                               format,
1319                                                                          VkSampleCountFlagBits  samples,
1320                                                                          VkImageUsageFlags              usageFlags,
1321                                                                          VkImageLayout                  layout)
1322 {
1323         VkImageUsageFlags                       targetUsageFlags        = 0;
1324         const tcu::TextureFormat        textureFormat           = mapVkFormat(format);
1325
1326         DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1327                                         || ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0));
1328
1329         DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1330                                         || ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0));
1331
1332         if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1333                 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1334         else
1335                 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1336
1337         return createImage(vk, device,
1338                                            (VkImageCreateFlags)0,
1339                                            VK_IMAGE_TYPE_2D,
1340                                            format,
1341                                            vk::makeExtent3D(size.x(), size.y(), 1u),
1342                                            1u /* mipLevels */,
1343                                            1u /* arraySize */,
1344                                            samples,
1345                                            VK_IMAGE_TILING_OPTIMAL,
1346                                            usageFlags | targetUsageFlags,
1347                                            VK_SHARING_MODE_EXCLUSIVE,
1348                                            1,
1349                                            &queueIndex,
1350                                            layout);
1351 }
1352
1353 de::MovePtr<Allocation> createImageMemory (const InstanceInterface&     vki,
1354                                                                                    const VkPhysicalDevice&      vkd,
1355                                                                                    const DeviceInterface&       vk,
1356                                                                                    VkDevice                                     device,
1357                                                                                    Allocator&                           allocator,
1358                                                                                    VkImage                                      image,
1359                                                                                    bool                                         lazy,
1360                                                                                    AllocationKind                       allocationKind)
1361 {
1362         const MemoryRequirement memoryRequirement       = lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any;
1363         de::MovePtr<Allocation> allocation                      = allocateImage(vki, vk, vkd, device, image, memoryRequirement, allocator, allocationKind);
1364
1365         bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1366
1367         return allocation;
1368 }
1369
1370 Move<VkImageView> createImageAttachmentView (const DeviceInterface&     vk,
1371                                                                                          VkDevice                               device,
1372                                                                                          VkImage                                image,
1373                                                                                          VkFormat                               format,
1374                                                                                          VkImageAspectFlags             aspect)
1375 {
1376         const VkImageSubresourceRange range =
1377         {
1378                 aspect,
1379                 0,
1380                 1,
1381                 0,
1382                 1
1383         };
1384
1385         return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1386 }
1387
1388 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng, deBool useFormatCompCount, const DepthValuesArray& depthValues)
1389 {
1390         const float                                     clearNan        = tcu::Float32::nan().asFloat();
1391         const tcu::TextureFormat        format          = mapVkFormat(attachment.getFormat());
1392
1393         if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1394         {
1395                 VkClearValue clearValue;
1396
1397                 clearValue.depthStencil.depth   = clearNan;
1398                 clearValue.depthStencil.stencil = 0xCDu;
1399
1400                 if (tcu::hasStencilComponent(format.order))
1401                         clearValue.depthStencil.stencil = rng.getBool()
1402                                                                                         ? 0xFFu
1403                                                                                         : 0x0u;
1404
1405                 if (tcu::hasDepthComponent(format.order))
1406                         clearValue.depthStencil.depth   = float(depthValues[rng.getBool() ? 1 : 0]) / 255.0f;
1407
1408                 return clearValue;
1409         }
1410         else
1411         {
1412                 VkClearValue clearValue;
1413
1414                 clearValue.color = randomColorClearValue(attachment, rng, useFormatCompCount);
1415
1416                 return clearValue;
1417         }
1418 }
1419
1420 class AttachmentResources
1421 {
1422 public:
1423         AttachmentResources (const InstanceInterface&   vki,
1424                                                  const VkPhysicalDevice&        physDevice,
1425                                                  const DeviceInterface&         vk,
1426                                                  VkDevice                                       device,
1427                                                  Allocator&                                     allocator,
1428                                                  deUint32                                       queueIndex,
1429                                                  const UVec2&                           size,
1430                                                  const Attachment&                      attachmentInfo,
1431                                                  VkImageUsageFlags                      usageFlags,
1432                                                  const AllocationKind           allocationKind)
1433                 : m_image                       (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
1434                 , m_imageMemory         (createImageMemory(vki, physDevice, vk, device, allocator, *m_image, ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0), allocationKind))
1435                 , m_attachmentView      (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
1436         {
1437                 const tcu::TextureFormat        format                  = mapVkFormat(attachmentInfo.getFormat());
1438                 const bool                                      isDepthFormat   = tcu::hasDepthComponent(format.order);
1439                 const bool                                      isStencilFormat = tcu::hasStencilComponent(format.order);
1440
1441                 if (isDepthFormat && isStencilFormat)
1442                 {
1443                         m_depthInputAttachmentView              = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT);
1444                         m_stencilInputAttachmentView    = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_STENCIL_BIT);
1445
1446                         m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView);
1447                 }
1448                 else
1449                         m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u);
1450
1451                 if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
1452                 {
1453                         if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1454                         {
1455                                 const tcu::TextureFormat        depthFormat             = getDepthCopyFormat(attachmentInfo.getFormat());
1456                                 const tcu::TextureFormat        stencilFormat   = getStencilCopyFormat(attachmentInfo.getFormat());
1457
1458                                 m_bufferSize                    = size.x() * size.y() * depthFormat.getPixelSize();
1459                                 m_secondaryBufferSize   = size.x() * size.y() * stencilFormat.getPixelSize();
1460
1461                                 m_buffer                                = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1462                                 m_bufferMemory                  = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1463
1464                                 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1465
1466                                 m_secondaryBuffer               = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1467                                 m_secondaryBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_secondaryBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1468
1469                                 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
1470                         }
1471                         else
1472                         {
1473                                 m_bufferSize    = size.x() * size.y() * format.getPixelSize();
1474
1475                                 m_buffer                = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1476                                 m_bufferMemory  = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1477
1478                                 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1479                         }
1480                 }
1481         }
1482
1483         const pair<VkImageView, VkImageView>& getInputAttachmentViews (void) const
1484         {
1485                 return m_inputAttachmentViews;
1486         }
1487
1488         ~AttachmentResources (void)
1489         {
1490         }
1491
1492         VkImageView getAttachmentView (void) const
1493         {
1494                 return *m_attachmentView;
1495         }
1496
1497         VkImage getImage (void) const
1498         {
1499                 return *m_image;
1500         }
1501
1502         VkBuffer getBuffer (void) const
1503         {
1504                 DE_ASSERT(*m_buffer != DE_NULL);
1505                 return *m_buffer;
1506         }
1507
1508         VkDeviceSize getBufferSize (void) const
1509         {
1510                 DE_ASSERT(*m_buffer != DE_NULL);
1511                 return m_bufferSize;
1512         }
1513
1514         const Allocation& getResultMemory (void) const
1515         {
1516                 DE_ASSERT(m_bufferMemory);
1517                 return *m_bufferMemory;
1518         }
1519
1520         VkBuffer getSecondaryBuffer (void) const
1521         {
1522                 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1523                 return *m_secondaryBuffer;
1524         }
1525
1526         VkDeviceSize getSecondaryBufferSize (void) const
1527         {
1528                 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1529                 return m_secondaryBufferSize;
1530         }
1531
1532         const Allocation& getSecondaryResultMemory (void) const
1533         {
1534                 DE_ASSERT(m_secondaryBufferMemory);
1535                 return *m_secondaryBufferMemory;
1536         }
1537
1538 private:
1539         const Unique<VkImage>                   m_image;
1540         const UniquePtr<Allocation>             m_imageMemory;
1541         const Unique<VkImageView>               m_attachmentView;
1542
1543         Move<VkImageView>                               m_depthInputAttachmentView;
1544         Move<VkImageView>                               m_stencilInputAttachmentView;
1545         pair<VkImageView, VkImageView>  m_inputAttachmentViews;
1546
1547         Move<VkBuffer>                                  m_buffer;
1548         VkDeviceSize                                    m_bufferSize;
1549         de::MovePtr<Allocation>                 m_bufferMemory;
1550
1551         Move<VkBuffer>                                  m_secondaryBuffer;
1552         VkDeviceSize                                    m_secondaryBufferSize;
1553         de::MovePtr<Allocation>                 m_secondaryBufferMemory;
1554 };
1555
1556 void uploadBufferData (const DeviceInterface&   vk,
1557                                            VkDevice                                     device,
1558                                            const Allocation&            memory,
1559                                            size_t                                       size,
1560                                            const void*                          data,
1561                                            VkDeviceSize                         nonCoherentAtomSize)
1562 {
1563         // Expand the range to flush to account for the nonCoherentAtomSize
1564         const VkDeviceSize roundedOffset        = de::roundDown(memory.getOffset(), nonCoherentAtomSize);
1565         const VkDeviceSize roundedSize          = de::roundUp(memory.getOffset() - roundedOffset + static_cast<VkDeviceSize>(size), nonCoherentAtomSize);
1566
1567         const VkMappedMemoryRange range =
1568         {
1569                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  // sType;
1570                 DE_NULL,                                                                // pNext;
1571                 memory.getMemory(),                                             // mem;
1572                 roundedOffset,                                                  // offset;
1573                 roundedSize,                                                    // size;
1574         };
1575         void* const ptr = memory.getHostPtr();
1576
1577         deMemcpy(ptr, data, size);
1578         VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1579 }
1580
1581 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
1582 {
1583         DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 22);
1584
1585         switch (order)
1586         {
1587                 case tcu::TextureFormat::D:
1588                 case tcu::TextureFormat::DS:
1589                         return VK_IMAGE_ASPECT_DEPTH_BIT;
1590
1591                 case tcu::TextureFormat::S:
1592                         return VK_IMAGE_ASPECT_STENCIL_BIT;
1593
1594                 default:
1595                         return VK_IMAGE_ASPECT_COLOR_BIT;
1596         }
1597 }
1598
1599 deUint32 getAttachmentNdx (const vector<AttachmentReference>& colorAttachments, size_t ndx)
1600 {
1601         return (colorAttachments[ndx].getAttachment() == VK_ATTACHMENT_UNUSED) ? (deUint32)ndx : colorAttachments[ndx].getAttachment();
1602 }
1603
1604 class RenderQuad
1605 {
1606 public:
1607                                         RenderQuad                      (const Vec2& posA, const Vec2& posB)
1608                 : m_vertices(6)
1609         {
1610                 m_vertices[0] = posA;
1611                 m_vertices[1] = Vec2(posA[0], posB[1]);
1612                 m_vertices[2] = posB;
1613
1614                 m_vertices[3] = posB;
1615                 m_vertices[4] = Vec2(posB[0], posA[1]);
1616                 m_vertices[5] = posA;
1617         }
1618
1619         const Vec2&             getCornerA                      (void) const
1620         {
1621                 return m_vertices[0];
1622         }
1623
1624         const Vec2&             getCornerB                      (void) const
1625         {
1626                 return m_vertices[2];
1627         }
1628
1629         const void*             getVertexPointer        (void) const
1630         {
1631                 return &m_vertices[0];
1632         }
1633
1634         size_t                  getVertexDataSize       (void) const
1635         {
1636                 return sizeof(Vec2) * m_vertices.size();
1637         }
1638
1639 private:
1640         vector<Vec2>    m_vertices;
1641 };
1642
1643 class ColorClear
1644 {
1645 public:
1646                                                                 ColorClear      (const UVec2&                           offset,
1647                                                                                          const UVec2&                           size,
1648                                                                                          const VkClearColorValue&       color)
1649                 : m_offset      (offset)
1650                 , m_size        (size)
1651                 , m_color       (color)
1652         {
1653         }
1654
1655         const UVec2&                            getOffset       (void) const { return m_offset; }
1656         const UVec2&                            getSize         (void) const { return m_size;   }
1657         const VkClearColorValue&        getColor        (void) const { return m_color;  }
1658
1659 private:
1660         UVec2                                           m_offset;
1661         UVec2                                           m_size;
1662         VkClearColorValue                       m_color;
1663 };
1664
1665 class DepthStencilClear
1666 {
1667 public:
1668                                         DepthStencilClear       (const UVec2&   offset,
1669                                                                                  const UVec2&   size,
1670                                                                                  float                  depth,
1671                                                                                  deUint32               stencil)
1672                 : m_offset      (offset)
1673                 , m_size        (size)
1674                 , m_depth       (depth)
1675                 , m_stencil     (stencil)
1676         {
1677         }
1678
1679         const UVec2&    getOffset                       (void) const { return m_offset;         }
1680         const UVec2&    getSize                         (void) const { return m_size;           }
1681         float                   getDepth                        (void) const { return m_depth;          }
1682         deUint32                getStencil                      (void) const { return m_stencil;        }
1683
1684 private:
1685         const UVec2             m_offset;
1686         const UVec2             m_size;
1687
1688         const float             m_depth;
1689         const deUint32  m_stencil;
1690 };
1691
1692 class SubpassRenderInfo
1693 {
1694 public:
1695                                                                         SubpassRenderInfo                               (const RenderPass&                                      renderPass,
1696                                                                                                                                          deUint32                                                       subpassIndex,
1697                                                                                                                                          deUint32                                                       drawStartNdx,
1698
1699                                                                                                                                          bool                                                           isSecondary_,
1700                                                                                                                                          bool                                                           omitBlendState_,
1701
1702                                                                                                                                          const UVec2&                                           viewportOffset,
1703                                                                                                                                          const UVec2&                                           viewportSize,
1704
1705                                                                                                                                          const Maybe<RenderQuad>&                       renderQuad,
1706                                                                                                                                          const vector<ColorClear>&                      colorClears,
1707                                                                                                                                          const Maybe<DepthStencilClear>&        depthStencilClear)
1708                 : m_viewportOffset              (viewportOffset)
1709                 , m_viewportSize                (viewportSize)
1710                 , m_subpassIndex                (subpassIndex)
1711                 , m_drawStartNdx                (drawStartNdx)
1712                 , m_isSecondary                 (isSecondary_)
1713                 , m_omitBlendState              (omitBlendState_)
1714                 , m_flags                               (renderPass.getSubpasses()[subpassIndex].getFlags())
1715                 , m_renderQuad                  (renderQuad)
1716                 , m_colorClears                 (colorClears)
1717                 , m_depthStencilClear   (depthStencilClear)
1718                 , m_colorAttachments    (renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1719                 , m_inputAttachments    (renderPass.getSubpasses()[subpassIndex].getInputAttachments())
1720         {
1721                 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
1722                         m_colorAttachmentInfo.push_back(renderPass.getAttachments()[getAttachmentNdx(m_colorAttachments, attachmentNdx)]);
1723
1724                 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1725                 {
1726                         m_depthStencilAttachment                = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1727                         m_depthStencilAttachmentInfo    = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1728                 }
1729         }
1730
1731         const UVec2&                                    getViewportOffset                               (void) const { return m_viewportOffset;         }
1732         const UVec2&                                    getViewportSize                                 (void) const { return m_viewportSize;           }
1733
1734         deUint32                                                getSubpassIndex                                 (void) const { return m_subpassIndex;           }
1735         deUint32                                                getDrawStartNdx                                 (void) const { return m_drawStartNdx;           }
1736         bool                                                    isSecondary                                             (void) const { return m_isSecondary;            }
1737         bool                                                    getOmitBlendState                               (void) const { return m_omitBlendState;         }
1738
1739         const Maybe<RenderQuad>&                getRenderQuad                                   (void) const { return m_renderQuad;                     }
1740         const vector<ColorClear>&               getColorClears                                  (void) const { return m_colorClears;            }
1741         const Maybe<DepthStencilClear>& getDepthStencilClear                    (void) const { return m_depthStencilClear;      }
1742
1743         deUint32                                                getInputAttachmentCount                 (void) const { return (deUint32)m_inputAttachments.size(); }
1744         deUint32                                                getInputAttachmentIndex                 (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getAttachment(); }
1745         VkImageLayout                                   getInputAttachmentLayout                (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getImageLayout(); }
1746
1747         deUint32                                                getColorAttachmentCount                 (void) const { return (deUint32)m_colorAttachments.size(); }
1748         VkImageLayout                                   getColorAttachmentLayout                (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
1749         deUint32                                                getColorAttachmentIndex                 (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
1750         const Attachment&                               getColorAttachment                              (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
1751         Maybe<VkImageLayout>                    getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::Nothing; }
1752         Maybe<deUint32>                                 getDepthStencilAttachmentIndex  (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::Nothing; }
1753         const Maybe<Attachment>&                getDepthStencilAttachment               (void) const { return m_depthStencilAttachmentInfo; }
1754         VkSubpassDescriptionFlags               getSubpassFlags                                 (void) const { return m_flags; }
1755
1756 private:
1757         UVec2                                                   m_viewportOffset;
1758         UVec2                                                   m_viewportSize;
1759
1760         deUint32                                                m_subpassIndex;
1761         deUint32                                                m_drawStartNdx;
1762         bool                                                    m_isSecondary;
1763         bool                                                    m_omitBlendState;
1764         VkSubpassDescriptionFlags               m_flags;
1765
1766         Maybe<RenderQuad>                               m_renderQuad;
1767         vector<ColorClear>                              m_colorClears;
1768         Maybe<DepthStencilClear>                m_depthStencilClear;
1769
1770         vector<AttachmentReference>             m_colorAttachments;
1771         vector<Attachment>                              m_colorAttachmentInfo;
1772
1773         Maybe<AttachmentReference>              m_depthStencilAttachment;
1774         Maybe<Attachment>                               m_depthStencilAttachmentInfo;
1775
1776         vector<AttachmentReference>             m_inputAttachments;
1777 };
1778
1779 void beginCommandBuffer (const DeviceInterface&                 vk,
1780                                                  VkCommandBuffer                                cmdBuffer,
1781                                                  VkRenderPass                                   pInheritanceInfo_renderPass,
1782                                                  deUint32                                               pInheritanceInfo_subpass,
1783                                                  VkFramebuffer                                  pInheritanceInfo_framebuffer,
1784                                                  VkBool32                                               pInheritanceInfo_occlusionQueryEnable,
1785                                                  VkQueryControlFlags                    pInheritanceInfo_queryFlags,
1786                                                  VkQueryPipelineStatisticFlags  pInheritanceInfo_pipelineStatistics,
1787                                                  const SubpassRenderInfo*               pRenderInfo = 0,
1788                                                  bool                                                   dynamicRenderPass = false,
1789                                                  bool                                                   secondaryCmdBufferCompletelyContainsRenderpass = false)
1790 {
1791         VkCommandBufferUsageFlags               usageFlags = (VkCommandBufferUsageFlags)0;
1792         VkCommandBufferInheritanceInfo  pInheritanceInfo
1793         {
1794                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1795                 DE_NULL,
1796                 pInheritanceInfo_renderPass,
1797                 pInheritanceInfo_subpass,
1798                 pInheritanceInfo_framebuffer,
1799                 pInheritanceInfo_occlusionQueryEnable,
1800                 pInheritanceInfo_queryFlags,
1801                 pInheritanceInfo_pipelineStatistics,
1802         };
1803
1804 #ifndef CTS_USES_VULKANSC
1805
1806         std::vector<vk::VkFormat>                                       colorAttachmentFormats;
1807         VkCommandBufferInheritanceRenderingInfoKHR      inheritanceRenderingInfo = initVulkanStructure();
1808
1809         if (dynamicRenderPass && pRenderInfo)
1810         {
1811                 if (secondaryCmdBufferCompletelyContainsRenderpass)
1812                         inheritanceRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
1813                 else
1814                         usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1815
1816                 for (deUint32 i = 0; i < pRenderInfo->getColorAttachmentCount(); ++i)
1817                         colorAttachmentFormats.push_back(pRenderInfo->getColorAttachment(i).getFormat());
1818
1819                 inheritanceRenderingInfo.colorAttachmentCount = static_cast<deUint32>(colorAttachmentFormats.size());
1820                 inheritanceRenderingInfo.pColorAttachmentFormats = colorAttachmentFormats.data();
1821                 if (pRenderInfo->getDepthStencilAttachment())
1822                 {
1823                         const VkFormat dsFormat = pRenderInfo->getDepthStencilAttachment()->getFormat();
1824                         inheritanceRenderingInfo.depthAttachmentFormat          = tcu::hasDepthComponent(mapVkFormat(dsFormat).order) ? dsFormat : VK_FORMAT_UNDEFINED;
1825                         inheritanceRenderingInfo.stencilAttachmentFormat        = tcu::hasStencilComponent(mapVkFormat(dsFormat).order) ? dsFormat : VK_FORMAT_UNDEFINED;
1826                 }
1827
1828                 if (pRenderInfo->getColorAttachmentCount())
1829                         inheritanceRenderingInfo.rasterizationSamples = pRenderInfo->getColorAttachment(0).getSamples();
1830                 else if (pRenderInfo->getDepthStencilAttachment())
1831                         inheritanceRenderingInfo.rasterizationSamples = pRenderInfo->getDepthStencilAttachment()->getSamples();
1832                 else
1833                         inheritanceRenderingInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
1834
1835                 pInheritanceInfo.pNext = &inheritanceRenderingInfo;
1836         }
1837         else if (!secondaryCmdBufferCompletelyContainsRenderpass)
1838                 usageFlags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1839 #else
1840
1841         DE_UNREF(pRenderInfo);
1842         DE_UNREF(dynamicRenderPass);
1843         DE_UNREF(secondaryCmdBufferCompletelyContainsRenderpass);
1844
1845         usageFlags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1846
1847 #endif // CTS_USES_VULKANSC
1848
1849         const VkCommandBufferBeginInfo pBeginInfo
1850         {
1851                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1852                 DE_NULL,
1853                 usageFlags,
1854                 &pInheritanceInfo,
1855         };
1856         VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
1857 }
1858
1859 Move<VkPipeline> createSubpassPipeline (const DeviceInterface&          vk,
1860                                                                                 VkDevice                                        device,
1861                                                                                 VkRenderPass                            renderPass,
1862                                                                                 VkShaderModule                          vertexShaderModule,
1863                                                                                 VkShaderModule                          fragmentShaderModule,
1864                                                                                 VkPipelineLayout                        pipelineLayout,
1865                                                                                 const SubpassRenderInfo&        renderInfo)
1866 {
1867         Maybe<VkSampleCountFlagBits>                                    rasterSamples;
1868         vector<VkPipelineColorBlendAttachmentState>             attachmentBlendStates;
1869
1870         for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
1871         {
1872                 const Attachment& attachment = renderInfo.getColorAttachment(attachmentNdx);
1873
1874                 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1875
1876                 rasterSamples = attachment.getSamples();
1877
1878                 {
1879                         const VkPipelineColorBlendAttachmentState attachmentBlendState =
1880                         {
1881                                 VK_FALSE,                                                                                                                                                                                                       // blendEnable
1882                                 VK_BLEND_FACTOR_SRC_ALPHA,                                                                                                                                                                      // srcBlendColor
1883                                 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,                                                                                                                                            // destBlendColor
1884                                 VK_BLEND_OP_ADD,                                                                                                                                                                                        // blendOpColor
1885                                 VK_BLEND_FACTOR_ONE,                                                                                                                                                                            // srcBlendAlpha
1886                                 VK_BLEND_FACTOR_ONE,                                                                                                                                                                            // destBlendAlpha
1887                                 VK_BLEND_OP_ADD,                                                                                                                                                                                        // blendOpAlpha
1888                                 (attachmentNdx < renderInfo.getDrawStartNdx() ? (deUint32)0 :
1889                                         VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT)    // channelWriteMask
1890                         };
1891
1892                         attachmentBlendStates.push_back(attachmentBlendState);
1893                 }
1894         }
1895
1896         if (renderInfo.getDepthStencilAttachment())
1897         {
1898                 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
1899
1900                 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1901                 rasterSamples = attachment.getSamples();
1902         }
1903
1904         // If there are no attachment use single sample
1905         if (!rasterSamples)
1906                 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
1907
1908         const VkVertexInputBindingDescription                   vertexBinding           =
1909         {
1910                 0u,                                                                                                                     // binding
1911                 (deUint32)sizeof(tcu::Vec2),                                                            // strideInBytes
1912                 VK_VERTEX_INPUT_RATE_VERTEX,                                                            // stepRate
1913         };
1914
1915         const VkVertexInputAttributeDescription                 vertexAttrib            =
1916         {
1917                 0u,                                                                                                                     // location
1918                 0u,                                                                                                                     // binding
1919                 VK_FORMAT_R32G32_SFLOAT,                                                                        // format
1920                 0u,                                                                                                                     // offsetInBytes
1921         };
1922
1923         const VkPipelineVertexInputStateCreateInfo              vertexInputState        =
1924         {
1925                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      //      sType
1926                 DE_NULL,                                                                                                        //      pNext
1927                 (VkPipelineVertexInputStateCreateFlags)0u,
1928                 1u,                                                                                                                     //      bindingCount
1929                 &vertexBinding,                                                                                         //      pVertexBindingDescriptions
1930                 1u,                                                                                                                     //      attributeCount
1931                 &vertexAttrib,                                                                                          //      pVertexAttributeDescriptions
1932         };
1933
1934         const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyState      =
1935         {
1936                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                            sType
1937                 DE_NULL,                                                                                                                // const void*                                pNext
1938                 0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags    flags
1939                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                        topology
1940                 VK_FALSE                                                                                                                // VkBool32                                   primitiveRestartEnable
1941         };
1942
1943         const VkViewport                                                                viewport                        =
1944         {
1945                 (float)renderInfo.getViewportOffset().x(),      (float)renderInfo.getViewportOffset().y(),
1946                 (float)renderInfo.getViewportSize().x(),        (float)renderInfo.getViewportSize().y(),
1947                 0.0f, 1.0f
1948         };
1949
1950         const VkRect2D                                                                  scissor                         =
1951         {
1952                 { (deInt32)renderInfo.getViewportOffset().x(),  (deInt32)renderInfo.getViewportOffset().y() },
1953                 { renderInfo.getViewportSize().x(),                             renderInfo.getViewportSize().y() }
1954         };
1955
1956         const VkPipelineViewportStateCreateInfo                 viewportState           =
1957         {
1958                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                             sType
1959                 DE_NULL,                                                                                                // const void*                                 pNext
1960                 (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags          flags
1961                 1u,                                                                                                             // deUint32                                    viewportCount
1962                 &viewport,                                                                                              // const VkViewport*                           pViewports
1963                 1u,                                                                                                             // deUint32                                    scissorCount
1964                 &scissor                                                                                                // const VkRect2D*                             pScissors
1965         };
1966
1967         const VkPipelineRasterizationStateCreateInfo    rasterizationState      =
1968         {
1969                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     // VkStructureType                            sType
1970                 DE_NULL,                                                                                                        // const void*                                pNext
1971                 0u,                                                                                                                     // VkPipelineRasterizationStateCreateFlags    flags
1972                 VK_FALSE,                                                                                                       // VkBool32                                   depthClampEnable
1973                 VK_FALSE,                                                                                                       // VkBool32                                   rasterizerDiscardEnable
1974                 VK_POLYGON_MODE_FILL,                                                                           // VkPolygonMode                              polygonMode
1975                 VK_CULL_MODE_NONE,                                                                                      // VkCullModeFlags                            cullMode
1976                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                        // VkFrontFace                                frontFace
1977                 VK_FALSE,                                                                                                       // VkBool32                                   depthBiasEnable
1978                 0.0f,                                                                                                           // float                                      depthBiasConstantFactor
1979                 0.0f,                                                                                                           // float                                      depthBiasClamp
1980                 0.0f,                                                                                                           // float                                      depthBiasSlopeFactor
1981                 1.0f                                                                                                            // float                                      lineWidth
1982         };
1983
1984         const VkPipelineMultisampleStateCreateInfo              multisampleState        =
1985         {
1986                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // sType
1987                 DE_NULL,                                                                                                                // pNext
1988                 (VkPipelineMultisampleStateCreateFlags)0u,
1989                 *rasterSamples,                                                                                                 // rasterSamples
1990                 VK_FALSE,                                                                                                               // sampleShadingEnable
1991                 0.0f,                                                                                                                   // minSampleShading
1992                 DE_NULL,                                                                                                                // pSampleMask
1993                 VK_FALSE,                                                                                                               // alphaToCoverageEnable
1994                 VK_FALSE,                                                                                                               // alphaToOneEnable
1995         };
1996         const size_t    stencilIndex    = renderInfo.getSubpassIndex();
1997
1998         const VkBool32  writeDepth              = renderInfo.getDepthStencilAttachmentLayout()
1999                                                                                 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
2000                                                                                 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
2001                                                                         ? VK_TRUE
2002                                                                         : VK_FALSE;
2003
2004         const VkBool32  writeStencil    = renderInfo.getDepthStencilAttachmentLayout()
2005                                                                                 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
2006                                                                                 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
2007                                                                         ? VK_TRUE
2008                                                                         : VK_FALSE;
2009
2010         const VkPipelineDepthStencilStateCreateInfo depthStencilState =
2011         {
2012                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // sType
2013                 DE_NULL,                                                                                                        // pNext
2014                 (VkPipelineDepthStencilStateCreateFlags)0u,
2015                 writeDepth,                                                                                                     // depthTestEnable
2016                 writeDepth,                                                                                                     // depthWriteEnable
2017                 VK_COMPARE_OP_ALWAYS,                                                                           // depthCompareOp
2018                 VK_FALSE,                                                                                                       // depthBoundsEnable
2019                 writeStencil,                                                                                           // stencilTestEnable
2020                 {
2021                         VK_STENCIL_OP_REPLACE,                                                                  // stencilFailOp
2022                         VK_STENCIL_OP_REPLACE,                                                                  // stencilPassOp
2023                         VK_STENCIL_OP_REPLACE,                                                                  // stencilDepthFailOp
2024                         VK_COMPARE_OP_ALWAYS,                                                                   // stencilCompareOp
2025                         ~0u,                                                                                                    // stencilCompareMask
2026                         ~0u,                                                                                                    // stencilWriteMask
2027                         ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u                                // stencilReference
2028                 },                                                                                                                      // front
2029                 {
2030                         VK_STENCIL_OP_REPLACE,                                                                  // stencilFailOp
2031                         VK_STENCIL_OP_REPLACE,                                                                  // stencilPassOp
2032                         VK_STENCIL_OP_REPLACE,                                                                  // stencilDepthFailOp
2033                         VK_COMPARE_OP_ALWAYS,                                                                   // stencilCompareOp
2034                         ~0u,                                                                                                    // stencilCompareMask
2035                         ~0u,                                                                                                    // stencilWriteMask
2036                         ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u                                // stencilReference
2037                 },                                                                                                                      // back
2038
2039                 0.0f,                                                                                                           // minDepthBounds;
2040                 1.0f                                                                                                            // maxDepthBounds;
2041         };
2042
2043         const VkPipelineColorBlendStateCreateInfo blendState =
2044         {
2045                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,                       // sType
2046                 DE_NULL,                                                                                                                        // pNext
2047                 (VkPipelineColorBlendStateCreateFlags)0u,
2048                 VK_FALSE,                                                                                                                       // logicOpEnable
2049                 VK_LOGIC_OP_COPY,                                                                                                       // logicOp
2050                 (deUint32)attachmentBlendStates.size(),                                                         // attachmentCount
2051                 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
2052                 { 0.0f, 0.0f, 0.0f, 0.0f }                                                                                      // blendConst
2053         };
2054
2055 #ifndef CTS_USES_VULKANSC
2056         std::vector<vk::VkFormat> colorAttachmentFormats;
2057         for (deUint32 i = 0; i < renderInfo.getColorAttachmentCount(); ++i)
2058                 colorAttachmentFormats.push_back(renderInfo.getColorAttachment(i).getFormat());
2059
2060         vk::VkFormat depthFormat = VK_FORMAT_UNDEFINED;
2061         vk::VkFormat stencilFormat = VK_FORMAT_UNDEFINED;
2062         if (renderInfo.getDepthStencilAttachment())
2063         {
2064                 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
2065                 vk::VkFormat depthStencilFormat = attachment.getFormat();
2066                 if (depthStencilFormat != VK_FORMAT_UNDEFINED)
2067                 {
2068                         if (tcu::hasDepthComponent(mapVkFormat(depthStencilFormat).order))
2069                         {
2070                                 depthFormat = depthStencilFormat;
2071                         }
2072                         if (tcu::hasStencilComponent(mapVkFormat(depthStencilFormat).order))
2073                         {
2074                                 stencilFormat = depthStencilFormat;
2075                         }
2076                 }
2077         }
2078
2079
2080         VkPipelineRenderingCreateInfoKHR renderingCreateInfo
2081         {
2082                 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
2083                 DE_NULL,
2084                 0u,
2085                 static_cast<deUint32>(colorAttachmentFormats.size()),
2086                 colorAttachmentFormats.data(),
2087                 depthFormat,
2088                 stencilFormat
2089         };
2090 #endif // CTS_USES_VULKANSC
2091
2092         return makeGraphicsPipeline(vk,                                                                                         // const DeviceInterface&                        vk
2093                                                                 device,                                                                                 // const VkDevice                                device
2094                                                                 pipelineLayout,                                                                 // const VkPipelineLayout                        pipelineLayout
2095                                                                 vertexShaderModule,                                                             // const VkShaderModule                          vertexShaderModule
2096                                                                 DE_NULL,                                                                                // const VkShaderModule                          tessellationControlShaderModule
2097                                                                 DE_NULL,                                                                                // const VkShaderModule                          tessellationEvalShaderModule
2098                                                                 DE_NULL,                                                                                // const VkShaderModule                          geometryShaderModule
2099                                                                 fragmentShaderModule,                                                   // const VkShaderModule                          fragmentShaderModule
2100                                                                 renderPass,                                                                             // const VkRenderPass                            renderPass
2101                                                                 renderInfo.getSubpassIndex(),                                   // const deUint32                                subpass
2102                                                                 &vertexInputState,                                                              // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
2103                                                                 &inputAssemblyState,                                                    // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2104                                                                 DE_NULL,                                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2105                                                                 &viewportState,                                                                 // const VkPipelineViewportStateCreateInfo*      pViewportStat;
2106                                                                 &rasterizationState,                                                    // const VkPipelineRasterizationStateCreateInfo* pRasterizationState
2107                                                                 &multisampleState,                                                              // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
2108                                                                 &depthStencilState,                                                             // const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
2109                                                                 renderInfo.getOmitBlendState()
2110                                                                         ? DE_NULL : &blendState,                                        // const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
2111                                                                 DE_NULL,                                                                                // const VkPipelineDynamicStateCreateInfo*       dynamicStateCreateInfo
2112 #ifndef CTS_USES_VULKANSC
2113                                                                 (renderPass == DE_NULL)
2114                                                                         ? &renderingCreateInfo : DE_NULL);                      // const void*                                   pNext)
2115 #else
2116                                                                 DE_NULL);                                                                               // const void*                                   pNext)
2117 #endif // CTS_USES_VULKANSC
2118 }
2119
2120 #ifndef CTS_USES_VULKANSC
2121 void beginDynamicRendering(const DeviceInterface&                                                               vk,
2122                                                    VkCommandBuffer                                                                              commandBuffer,
2123                                                    const RenderPass&                                                                    renderPassInfo,
2124                                                    const vector<de::SharedPtr<AttachmentResources> >&   attachmentResources,
2125                                                    const VkRect2D&                                                                              renderArea,
2126                                                    const vector<Maybe<VkClearValue> >&                                  renderPassClearValues,
2127                                                    const VkRenderingFlagsKHR                                                    renderingFlags = 0u)
2128 {
2129         const float                     clearNan                = tcu::Float32::nan().asFloat();
2130         const VkClearValue      clearValueNan   = makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan);
2131
2132         // translate structures that were prepared to construct renderpass to structures needed for dynamic rendering
2133
2134         std::vector<vk::VkRenderingAttachmentInfoKHR>   colorAttachmentVect;
2135         const Subpass&                                                                  subpassInfo                             = renderPassInfo.getSubpasses()[0];
2136         const vector<AttachmentReference>&                              colorAttachmentsInfo    = subpassInfo.getColorAttachments();
2137         const vector<AttachmentReference>&                              resolveAttachmentsInfo  = subpassInfo.getResolveAttachments();
2138
2139         for (deUint32 i = 0; i < colorAttachmentsInfo.size(); ++i)
2140         {
2141                 const AttachmentReference&              colorAttachmentReference        = colorAttachmentsInfo[i];
2142                 const deUint32                                  colorAttachmentIndex            = colorAttachmentReference.getAttachment();
2143                 const Attachment&                               colorAttachmentInfo                     = renderPassInfo.getAttachments()[colorAttachmentIndex];
2144
2145                 VkResolveModeFlagBits                   resolveMode                                     = VK_RESOLVE_MODE_NONE;
2146                 VkImageView                                             resolveImageView                        = DE_NULL;
2147                 VkImageLayout                                   resolveImageLayout                      = VK_IMAGE_LAYOUT_UNDEFINED;
2148
2149                 // handle resolve attachments if they were specified
2150                 if (!resolveAttachmentsInfo.empty())
2151                 {
2152                         const AttachmentReference&      resolveAttachmentReference      = resolveAttachmentsInfo[i];
2153                         const deUint32                          resolveAttachmentIndex          = resolveAttachmentReference.getAttachment();
2154                         const Attachment&                       resolveAttachmentInfo           = renderPassInfo.getAttachments()[resolveAttachmentIndex];
2155
2156                         resolveMode                     = VK_RESOLVE_MODE_AVERAGE_BIT;
2157                         resolveImageView        = attachmentResources[resolveAttachmentIndex]->getAttachmentView();
2158                         resolveImageLayout      = resolveAttachmentInfo.getInitialLayout();
2159                 }
2160
2161                 colorAttachmentVect.push_back({
2162                         vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,                    // VkStructureType                      sType
2163                         DE_NULL,                                                                                                                // const void*                          pNext
2164                         attachmentResources[colorAttachmentIndex]->getAttachmentView(), // VkImageView                          imageView
2165                         colorAttachmentReference.getImageLayout(),                                              // VkImageLayout                        imageLayout
2166                         resolveMode,                                                                                                    // VkResolveModeFlagBits        resolveMode
2167                         resolveImageView,                                                                                               // VkImageView                          resolveImageView
2168                         resolveImageLayout,                                                                                             // VkImageLayout                        resolveImageLayout
2169                         colorAttachmentInfo.getLoadOp(),                                                                // VkAttachmentLoadOp           loadOp
2170                         colorAttachmentInfo.getStoreOp(),                                                               // VkAttachmentStoreOp          storeOp
2171                         (renderPassClearValues[colorAttachmentIndex] ?
2172                                 *renderPassClearValues[colorAttachmentIndex] :
2173                                 clearValueNan)                                                                                          // VkClearValue                         clearValue
2174                         });
2175         }
2176
2177         VkRenderingAttachmentInfoKHR*   pDepthAttachment        = DE_NULL;
2178         VkRenderingAttachmentInfoKHR*   pStencilAttachment      = DE_NULL;
2179         VkRenderingAttachmentInfoKHR    depthAttachment
2180         {
2181                 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,                            // VkStructureType                      sType;
2182                 DE_NULL,                                                                                                                        // const void*                          pNext;
2183                 DE_NULL,                                                                                                                        // VkImageView                          imageView;
2184                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                      // VkImageLayout                        imageLayout;
2185                 VK_RESOLVE_MODE_NONE,                                                                                           // VkResolveModeFlagBits        resolveMode;
2186                 DE_NULL,                                                                                                                        // VkImageView                          resolveImageView;
2187                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                      // VkImageLayout                        resolveImageLayout;
2188                 VK_ATTACHMENT_LOAD_OP_LOAD,                                                                                     // VkAttachmentLoadOp           loadOp;
2189                 VK_ATTACHMENT_STORE_OP_STORE,                                                                           // VkAttachmentStoreOp          storeOp;
2190                 clearValueNan                                                                                                           // VkClearValue                         clearValue;
2191         };
2192         VkRenderingAttachmentInfoKHR    stencilAttachment                                       = depthAttachment;
2193         const AttachmentReference&              depthStencilAttachmentReference         = subpassInfo.getDepthStencilAttachment();
2194         const deUint32                                  dsAttachmentIndex                                       = depthStencilAttachmentReference.getAttachment();
2195
2196         if (dsAttachmentIndex != VK_ATTACHMENT_UNUSED)
2197         {
2198                 const Attachment&                       dsAttachmentInfo        = renderPassInfo.getAttachments()[dsAttachmentIndex];
2199                 const tcu::TextureFormat        format                          = mapVkFormat(dsAttachmentInfo.getFormat());
2200
2201                 if (tcu::hasDepthComponent(format.order))
2202                 {
2203                         depthAttachment.imageView               = attachmentResources[dsAttachmentIndex]->getAttachmentView();
2204                         depthAttachment.imageLayout             = depthStencilAttachmentReference.getImageLayout();
2205                         depthAttachment.loadOp                  = dsAttachmentInfo.getLoadOp();
2206                         depthAttachment.storeOp                 = dsAttachmentInfo.getStoreOp();
2207
2208                         if (renderPassClearValues[dsAttachmentIndex])
2209                                 depthAttachment.clearValue = *renderPassClearValues[dsAttachmentIndex];
2210
2211                         pDepthAttachment = &depthAttachment;
2212                 }
2213
2214                 if (tcu::hasStencilComponent(format.order))
2215                 {
2216                         stencilAttachment.imageView = attachmentResources[dsAttachmentIndex]->getAttachmentView();
2217                         stencilAttachment.imageLayout = depthStencilAttachmentReference.getImageLayout();
2218                         stencilAttachment.loadOp = dsAttachmentInfo.getStencilLoadOp();
2219                         stencilAttachment.storeOp = dsAttachmentInfo.getStencilStoreOp();
2220
2221                         if (renderPassClearValues[dsAttachmentIndex])
2222                                 stencilAttachment.clearValue = *renderPassClearValues[dsAttachmentIndex];
2223
2224                         pStencilAttachment = &stencilAttachment;
2225                 }
2226         }
2227
2228         vk::VkRenderingInfoKHR renderingInfo
2229         {
2230                 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2231                 DE_NULL,
2232                 renderingFlags,                                                                                                         // VkRenderingFlagsKHR                                  flags;
2233                 renderArea,                                                                                                                     // VkRect2D                                                             renderArea;
2234                 1u,                                                                                                                                     // deUint32                                                             layerCount;
2235                 0u,                                                                                                                                     // deUint32                                                             viewMask;
2236                 static_cast<deUint32>(colorAttachmentVect.size()),                                      // deUint32                                                             colorAttachmentCount;
2237                 colorAttachmentVect.empty() ? DE_NULL : &colorAttachmentVect[0],        // const VkRenderingAttachmentInfoKHR*  pColorAttachments;
2238                 pDepthAttachment,                                                                                                       // const VkRenderingAttachmentInfoKHR*  pDepthAttachment;
2239                 pStencilAttachment                                                                                                      // const VkRenderingAttachmentInfoKHR*  pStencilAttachment;
2240         };
2241
2242         vk.cmdBeginRendering(commandBuffer, &renderingInfo);
2243 }
2244
2245 void endDynamicRendering(const DeviceInterface& vk, VkCommandBuffer commandBuffer)
2246 {
2247         vk.cmdEndRendering(commandBuffer);
2248 }
2249 #endif // CTS_USES_VULKANSC
2250
2251 class SubpassRenderer
2252 {
2253 public:
2254         SubpassRenderer (Context&                                                                                               context,
2255                                          const DeviceInterface&                                                                 vk,
2256                                          VkDevice                                                                                               device,
2257                                          Allocator&                                                                                             allocator,
2258                                          const RenderPass&                                                                              renderPassInfo,
2259                                          const vector<de::SharedPtr<AttachmentResources> >&             attachmentResources,
2260                                          const VkRect2D&                                                                                renderArea,
2261                                          const vector<Maybe<VkClearValue> >&                                    renderPassClearValues,
2262                                          VkRenderPass                                                                                   renderPass,
2263                                          VkFramebuffer                                                                                  framebuffer,
2264                                          VkCommandPool                                                                                  commandBufferPool,
2265                                          deUint32                                                                                               queueFamilyIndex,
2266                                          const vector<VkImage>&                                                                 attachmentImages,
2267                                          const vector<pair<VkImageView, VkImageView> >&                 attachmentViews,
2268                                          const SubpassRenderInfo&                                                               renderInfo,
2269                                          const AllocationKind                                                                   allocationKind,
2270                                          const bool                                                                                             dynamicRendering,
2271                                          const bool                                                                                             secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2272                 : m_renderInfo  (renderInfo)
2273         {
2274                 // unreference values not used by Vulkan SC, no need to pu this under ifdef
2275                 DE_UNREF(attachmentResources);
2276                 DE_UNREF(renderArea);
2277                 DE_UNREF(renderPassClearValues);
2278
2279                 const InstanceInterface&                                vki                             = context.getInstanceInterface();
2280                 const VkPhysicalDevice&                                 physDevice              = context.getPhysicalDevice();
2281                 const vector<Attachment>&                               attachmentInfos = renderPassInfo.getAttachments();
2282                 const deUint32                                                  subpassIndex    = renderInfo.getSubpassIndex();
2283                 vector<VkDescriptorSetLayoutBinding>    bindings;
2284
2285                 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount();  colorAttachmentNdx++)
2286                 {
2287                         const deUint32 attachmentNdx    = (renderInfo.getColorAttachmentIndex(colorAttachmentNdx) == VK_ATTACHMENT_UNUSED) ? colorAttachmentNdx
2288                                                                                         : renderInfo.getColorAttachmentIndex(colorAttachmentNdx);
2289
2290                         m_colorAttachmentImages.push_back(attachmentImages[attachmentNdx]);
2291                 }
2292
2293                 if (renderInfo.getDepthStencilAttachmentIndex())
2294                         m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];
2295
2296                 if (renderInfo.getRenderQuad())
2297                 {
2298                         const RenderQuad&       renderQuad      = *renderInfo.getRenderQuad();
2299
2300                         if (renderInfo.getInputAttachmentCount() > 0)
2301                         {
2302                                 deUint32                                                                bindingIndex    = 0;
2303
2304                                 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2305                                 {
2306                                         const Attachment                        attachmentInfo  = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2307                                         const VkImageLayout                     layout                  = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2308                                         const tcu::TextureFormat        format                  = mapVkFormat(attachmentInfo.getFormat());
2309                                         const bool                                      isDepthFormat   = tcu::hasDepthComponent(format.order);
2310                                         const bool                                      isStencilFormat = tcu::hasStencilComponent(format.order);
2311                                         const deUint32                          bindingCount    = (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2312                                                                                                                                         && (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
2313                                                                                                                                 ? 2u
2314                                                                                                                                 : 1u;
2315
2316                                         for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
2317                                         {
2318                                                 const VkDescriptorSetLayoutBinding binding =
2319                                                 {
2320                                                         bindingIndex,
2321                                                         vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2322                                                         1u,
2323                                                         vk::VK_SHADER_STAGE_FRAGMENT_BIT,
2324                                                         DE_NULL
2325                                                 };
2326
2327                                                 bindings.push_back(binding);
2328                                                 bindingIndex++;
2329                                         }
2330                                 }
2331
2332                                 const VkDescriptorSetLayoutCreateInfo createInfo =
2333                                 {
2334                                         vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
2335                                         DE_NULL,
2336
2337                                         0u,
2338                                         (deUint32)bindings.size(),
2339                                         &bindings[0]
2340                                 };
2341
2342                                 m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
2343                         }
2344
2345                         const VkDescriptorSetLayout                     descriptorSetLayout             = *m_descriptorSetLayout;
2346                         const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
2347                         {
2348                                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                  // sType;
2349                                 DE_NULL,                                                                                                // pNext;
2350                                 (vk::VkPipelineLayoutCreateFlags)0,
2351                                 m_descriptorSetLayout ? 1u :0u ,                                                // setLayoutCount;
2352                                 m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL, // pSetLayouts;
2353                                 0u,                                                                                                             // pushConstantRangeCount;
2354                                 DE_NULL,                                                                                                // pPushConstantRanges;
2355                         };
2356
2357                         m_vertexShaderModule    = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
2358                         m_fragmentShaderModule  = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
2359                         m_pipelineLayout                = createPipelineLayout(vk, device, &pipelineLayoutParams);
2360                         m_pipeline                              = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
2361
2362                         // Round up the vertex buffer size to honor nonCoherentAtomSize.
2363                         const auto      properties                      = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2364                         const auto      vertexBufferSize        = de::roundUp(static_cast<VkDeviceSize>(renderQuad.getVertexDataSize()), properties.limits.nonCoherentAtomSize);
2365
2366                         m_vertexBuffer                  = createBuffer(vk, device, 0u, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
2367                         m_vertexBufferMemory    = allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
2368
2369                         bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
2370
2371                         uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer(), properties.limits.nonCoherentAtomSize);
2372
2373                         if (renderInfo.getInputAttachmentCount() > 0)
2374                         {
2375                                 {
2376                                         const VkDescriptorPoolSize poolSize =
2377                                         {
2378                                                 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2379                                                 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2380                                                 renderInfo.getInputAttachmentCount() * 2u
2381                                         };
2382                                         const VkDescriptorPoolCreateInfo createInfo =
2383                                         {
2384                                                 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
2385                                                 DE_NULL,
2386                                                 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
2387
2388                                                 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2389                                                 renderInfo.getInputAttachmentCount() * 2u,
2390                                                 1u,
2391                                                 &poolSize
2392                                         };
2393
2394                                         m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
2395                                 }
2396                                 {
2397                                         const VkDescriptorSetAllocateInfo       allocateInfo =
2398                                         {
2399                                                 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2400                                                 DE_NULL,
2401
2402                                                 *m_descriptorPool,
2403                                                 1u,
2404                                                 &descriptorSetLayout
2405                                         };
2406
2407                                         m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
2408                                 }
2409                                 {
2410                                         vector<VkWriteDescriptorSet>    writes                  (bindings.size());
2411                                         vector<VkDescriptorImageInfo>   imageInfos              (bindings.size());
2412                                         deUint32                                                bindingIndex    = 0;
2413
2414                                         for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2415                                         {
2416                                                 const Attachment                        attachmentInfo                  = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2417                                                 const tcu::TextureFormat        format                                  = mapVkFormat(attachmentInfo.getFormat());
2418                                                 const bool                                      isDepthFormat                   = tcu::hasDepthComponent(format.order);
2419                                                 const bool                                      isStencilFormat                 = tcu::hasStencilComponent(format.order);
2420                                                 const VkImageLayout                     inputAttachmentLayout   = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2421
2422
2423                                                 if (isDepthFormat && isStencilFormat)
2424                                                 {
2425                                                         if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
2426                                                         {
2427                                                                 const VkDescriptorImageInfo     imageInfo =
2428                                                                 {
2429                                                                         (VkSampler)0,
2430                                                                         attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2431                                                                         inputAttachmentLayout
2432                                                                 };
2433                                                                 imageInfos[bindingIndex] = imageInfo;
2434
2435                                                                 {
2436                                                                         const VkWriteDescriptorSet      write =
2437                                                                         {
2438                                                                                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2439                                                                                 DE_NULL,
2440
2441                                                                                 *m_descriptorSet,
2442                                                                                 bindingIndex,
2443                                                                                 0u,
2444                                                                                 1u,
2445                                                                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2446                                                                                 &imageInfos[bindingIndex],
2447                                                                                 DE_NULL,
2448                                                                                 DE_NULL
2449                                                                         };
2450                                                                         writes[bindingIndex] = write;
2451
2452                                                                         bindingIndex++;
2453                                                                 }
2454                                                         }
2455
2456                                                         if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2457                                                         {
2458                                                                 const VkDescriptorImageInfo     imageInfo =
2459                                                                 {
2460                                                                         (VkSampler)0,
2461                                                                         attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
2462                                                                         inputAttachmentLayout
2463                                                                 };
2464                                                                 imageInfos[bindingIndex] = imageInfo;
2465
2466                                                                 {
2467                                                                         const VkWriteDescriptorSet      write =
2468                                                                         {
2469                                                                                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2470                                                                                 DE_NULL,
2471
2472                                                                                 *m_descriptorSet,
2473                                                                                 bindingIndex,
2474                                                                                 0u,
2475                                                                                 1u,
2476                                                                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2477                                                                                 &imageInfos[bindingIndex],
2478                                                                                 DE_NULL,
2479                                                                                 DE_NULL
2480                                                                         };
2481                                                                         writes[bindingIndex] = write;
2482
2483                                                                         bindingIndex++;
2484                                                                 }
2485                                                         }
2486                                                 }
2487                                                 else
2488                                                 {
2489                                                         const VkDescriptorImageInfo     imageInfo =
2490                                                         {
2491                                                                 (VkSampler)0,
2492                                                                 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2493                                                                 inputAttachmentLayout
2494                                                         };
2495                                                         imageInfos[bindingIndex] = imageInfo;
2496
2497                                                         {
2498                                                                 const VkWriteDescriptorSet      write =
2499                                                                 {
2500                                                                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2501                                                                         DE_NULL,
2502
2503                                                                         *m_descriptorSet,
2504                                                                         bindingIndex,
2505                                                                         0u,
2506                                                                         1u,
2507                                                                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2508                                                                         &imageInfos[bindingIndex],
2509                                                                         DE_NULL,
2510                                                                         DE_NULL
2511                                                                 };
2512                                                                 writes[bindingIndex] = write;
2513
2514                                                                 bindingIndex++;
2515                                                         }
2516                                                 }
2517                                         }
2518
2519                                         vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL);
2520                                 }
2521                         }
2522                 }
2523
2524                 if (renderInfo.isSecondary())
2525                 {
2526                         m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2527
2528                         beginCommandBuffer(vk, *m_commandBuffer, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0,
2529                                                            (VkQueryPipelineStatisticFlags)0, &renderInfo, dynamicRendering, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
2530
2531                         if (dynamicRendering && secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2532                         {
2533 #ifndef CTS_USES_VULKANSC
2534                                 beginDynamicRendering(vk, *m_commandBuffer, renderPassInfo, attachmentResources, renderArea, renderPassClearValues);
2535                                 pushRenderCommands(vk, *m_commandBuffer);
2536                                 endDynamicRendering(vk, *m_commandBuffer);
2537 #endif // CTS_USES_VULKANSC
2538                         }
2539                         else
2540                                 pushRenderCommands(vk, *m_commandBuffer);
2541
2542                         endCommandBuffer(vk, *m_commandBuffer);
2543                 }
2544         }
2545
2546         bool isSecondary (void) const
2547         {
2548                 return !!m_commandBuffer;
2549         }
2550
2551         VkCommandBuffer getCommandBuffer (void) const
2552         {
2553                 DE_ASSERT(isSecondary());
2554                 return *m_commandBuffer;
2555         }
2556
2557         void pushRenderCommands (const DeviceInterface&         vk,
2558                                                          VkCommandBuffer                        commandBuffer)
2559         {
2560                 if (!m_renderInfo.getColorClears().empty())
2561                 {
2562                         const vector<ColorClear>&       colorClears     (m_renderInfo.getColorClears());
2563
2564                         for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
2565                         {
2566                                 const ColorClear&               colorClear      = colorClears[attachmentNdx];
2567                                 const VkClearAttachment attachment      =
2568                                 {
2569                                         VK_IMAGE_ASPECT_COLOR_BIT,
2570                                         attachmentNdx,
2571                                         makeClearValue(colorClear.getColor()),
2572                                 };
2573                                 const VkClearRect               rect            =
2574                                 {
2575                                         {
2576                                                 { (deInt32)colorClear.getOffset().x(),  (deInt32)colorClear.getOffset().y()     },
2577                                                 { colorClear.getSize().x(),                             colorClear.getSize().y()                        }
2578                                         },                                      // rect
2579                                         0u,                                     // baseArrayLayer
2580                                         1u,                                     // layerCount
2581                                 };
2582
2583                                 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2584                         }
2585                 }
2586
2587                 if (m_renderInfo.getDepthStencilClear())
2588                 {
2589                         const DepthStencilClear&        depthStencilClear       = *m_renderInfo.getDepthStencilClear();
2590                         const deUint32                          attachmentNdx           = m_renderInfo.getColorAttachmentCount();
2591                         tcu::TextureFormat                      format                          = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2592                         const VkImageLayout                     layout                          = *m_renderInfo.getDepthStencilAttachmentLayout();
2593                         const VkClearAttachment         attachment                      =
2594                         {
2595                                 (VkImageAspectFlags)((hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2596                                         | (hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2597                                 attachmentNdx,
2598                                 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
2599                         };
2600                         const VkClearRect                               rect                            =
2601                         {
2602                                 {
2603                                         { (deInt32)depthStencilClear.getOffset().x(),   (deInt32)depthStencilClear.getOffset().y()      },
2604                                         { depthStencilClear.getSize().x(),                              depthStencilClear.getSize().y()                         }
2605                                 },                                                      // rect
2606                                 0u,                                                     // baseArrayLayer
2607                                 1u,                                                     // layerCount
2608                         };
2609
2610                         if ((tcu::hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2611                                 || (tcu::hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL))
2612                         {
2613                                 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2614                         }
2615                 }
2616
2617                 vector<VkImageMemoryBarrier>    selfDeps;
2618                 VkPipelineStageFlags                    srcStages = 0;
2619                 VkPipelineStageFlags                    dstStages = 0;
2620
2621                 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2622                 {
2623                         for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
2624                         {
2625                                 if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
2626                                 {
2627                                         const VkImageMemoryBarrier      barrier   =
2628                                         {
2629                                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // sType
2630                                                 DE_NULL,                                                                                // pNext
2631
2632                                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // srcAccessMask
2633                                                 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                    // dstAccessMask
2634
2635                                                 VK_IMAGE_LAYOUT_GENERAL,                                                // oldLayout
2636                                                 VK_IMAGE_LAYOUT_GENERAL,                                                // newLayout
2637
2638                                                 VK_QUEUE_FAMILY_IGNORED,                                                // srcQueueFamilyIndex
2639                                                 VK_QUEUE_FAMILY_IGNORED,                                                // destQueueFamilyIndex
2640
2641                                                 m_colorAttachmentImages[colorAttachmentNdx],    // image
2642                                                 {                                                                                               // subresourceRange
2643                                                         VK_IMAGE_ASPECT_COLOR_BIT,                                              // aspect
2644                                                         0,                                                                                              // baseMipLevel
2645                                                         1,                                                                                              // mipLevels
2646                                                         0,                                                                                              // baseArraySlice
2647                                                         1                                                                                               // arraySize
2648                                                 }
2649                                         };
2650
2651                                         srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2652                                         dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2653
2654                                         selfDeps.push_back(barrier);
2655                                 }
2656                         }
2657
2658                         if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex()))
2659                         {
2660                                 const tcu::TextureFormat        format          = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2661                                 const bool                                      hasDepth        = hasDepthComponent(format.order);
2662                                 const bool                                      hasStencil      = hasStencilComponent(format.order);
2663                                 const VkImageMemoryBarrier      barrier         =
2664                                 {
2665                                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                 // sType;
2666                                         DE_NULL,                                                                                                // pNext;
2667
2668                                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,                   // srcAccessMask
2669                                         VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                                    // dstAccessMask
2670
2671                                         m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx),      // oldLayout
2672                                         m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx),      // newLayout;
2673
2674                                         VK_QUEUE_FAMILY_IGNORED,                                                                // srcQueueFamilyIndex;
2675                                         VK_QUEUE_FAMILY_IGNORED,                                                                // destQueueFamilyIndex;
2676
2677                                         m_depthStencilAttachmentImage,                                                  // image;
2678                                         {                                                                                                               // subresourceRange;
2679                                                 (hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
2680                                                         | (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u),  // aspect;
2681                                                 0,                                                                                                                      // baseMipLevel;
2682                                                 1,                                                                                                                      // mipLevels;
2683                                                 0,                                                                                                                      // baseArraySlice;
2684                                                 1                                                                                                                       // arraySize;
2685                                         }
2686                                 };
2687
2688                                 srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
2689                                 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2690
2691                                 selfDeps.push_back(barrier);
2692                         }
2693                 }
2694
2695                 if (!selfDeps.empty())
2696                 {
2697                         DE_ASSERT(srcStages != 0);
2698                         DE_ASSERT(dstStages != 0);
2699                         vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]);
2700                 }
2701
2702                 if (m_renderInfo.getRenderQuad())
2703                 {
2704                         const VkDeviceSize      offset                  = 0;
2705                         const VkBuffer          vertexBuffer    = *m_vertexBuffer;
2706
2707                         vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2708
2709                         if (m_descriptorSet)
2710                         {
2711                                 const VkDescriptorSet descriptorSet = *m_descriptorSet;
2712                                 vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL);
2713                         }
2714
2715                         vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
2716                         vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
2717                 }
2718         }
2719
2720 private:
2721         const SubpassRenderInfo         m_renderInfo;
2722         Move<VkCommandBuffer>           m_commandBuffer;
2723         Move<VkPipeline>                        m_pipeline;
2724         Move<VkDescriptorSetLayout>     m_descriptorSetLayout;
2725         Move<VkPipelineLayout>          m_pipelineLayout;
2726
2727         Move<VkShaderModule>            m_vertexShaderModule;
2728         Move<VkShaderModule>            m_fragmentShaderModule;
2729
2730         Move<VkDescriptorPool>          m_descriptorPool;
2731         Move<VkDescriptorSet>           m_descriptorSet;
2732         Move<VkBuffer>                          m_vertexBuffer;
2733         de::MovePtr<Allocation>         m_vertexBufferMemory;
2734         vector<VkImage>                         m_colorAttachmentImages;
2735         VkImage                                         m_depthStencilAttachmentImage;
2736 };
2737
2738 void pushImageInitializationCommands (const DeviceInterface&                                                            vk,
2739                                                                           VkCommandBuffer                                                                               commandBuffer,
2740                                                                           const vector<Attachment>&                                                             attachmentInfo,
2741                                                                           const vector<de::SharedPtr<AttachmentResources> >&    attachmentResources,
2742                                                                           deUint32                                                                                              queueIndex,
2743                                                                           const vector<Maybe<VkClearValue> >&                                   clearValues)
2744 {
2745         {
2746                 vector<VkImageMemoryBarrier>    initializeLayouts;
2747
2748                 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2749                 {
2750                         if (!clearValues[attachmentNdx])
2751                                 continue;
2752
2753                         const VkImageMemoryBarrier barrier =
2754                         {
2755                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                 // sType;
2756                                 DE_NULL,                                                                                                                // pNext;
2757
2758                                 (VkAccessFlags)0,                                                                                               // srcAccessMask
2759                                 getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT,                 // dstAccessMask
2760
2761                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                              // oldLayout
2762                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                                                   // newLayout;
2763
2764                                 queueIndex,                                                                                                             // srcQueueFamilyIndex;
2765                                 queueIndex,                                                                                                             // destQueueFamilyIndex;
2766
2767                                 attachmentResources[attachmentNdx]->getImage(),                                 // image;
2768                                 {                                                                                                                               // subresourceRange;
2769                                         getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),         // aspect;
2770                                         0,                                                                                                                                      // baseMipLevel;
2771                                         1,                                                                                                                                      // mipLevels;
2772                                         0,                                                                                                                                      // baseArraySlice;
2773                                         1                                                                                                                                       // arraySize;
2774                                 }
2775                         };
2776
2777                         initializeLayouts.push_back(barrier);
2778                 }
2779
2780                 if (!initializeLayouts.empty())
2781                         vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2782                                                                   VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0,
2783                                                                   0, (const VkMemoryBarrier*)DE_NULL,
2784                                                                   0, (const VkBufferMemoryBarrier*)DE_NULL,
2785                                                                   (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
2786         }
2787
2788         for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2789         {
2790                 if (!clearValues[attachmentNdx])
2791                         continue;
2792
2793                 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
2794
2795                 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
2796                 {
2797                         const float                                             clearNan                = tcu::Float32::nan().asFloat();
2798                         const float                                             clearDepth              = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
2799                         const deUint32                                  clearStencil    = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
2800                         const VkClearDepthStencilValue  depthStencil    =
2801                         {
2802                                 clearDepth,
2803                                 clearStencil
2804                         };
2805                         const VkImageSubresourceRange range =
2806                         {
2807                                 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2808                                                                          | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2809                                 0,
2810                                 1,
2811                                 0,
2812                                 1
2813                         };
2814
2815                         vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
2816                 }
2817                 else
2818                 {
2819                         const VkImageSubresourceRange   range           =
2820                         {
2821                                 VK_IMAGE_ASPECT_COLOR_BIT,      // aspectMask;
2822                                 0,                                                      // baseMipLevel;
2823                                 1,                                                      // mipLevels;
2824                                 0,                                                      // baseArrayLayer;
2825                                 1                                                       // layerCount;
2826                         };
2827                         const VkClearColorValue                 clearColor      = clearValues[attachmentNdx]->color;
2828
2829                         vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
2830                 }
2831         }
2832
2833         {
2834                 vector<VkImageMemoryBarrier>    renderPassLayouts;
2835
2836                 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2837                 {
2838                         const VkImageLayout                     oldLayout       = clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
2839                         const VkImageMemoryBarrier      barrier         =
2840                         {
2841                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                 // sType;
2842                                 DE_NULL,                                                                                                // pNext;
2843
2844                                 getMemoryFlagsForLayout(oldLayout),                                                                                                                                             // srcAccessMask
2845                                 getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()),    // dstAccessMask
2846
2847                                 oldLayout,                                                                                              // oldLayout
2848                                 attachmentInfo[attachmentNdx].getInitialLayout(),               // newLayout;
2849
2850                                 queueIndex,                                                                                             // srcQueueFamilyIndex;
2851                                 queueIndex,                                                                                             // destQueueFamilyIndex;
2852
2853                                 attachmentResources[attachmentNdx]->getImage(),                 // image;
2854                                 {                                                                                                               // subresourceRange;
2855                                         getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),         // aspect;
2856                                         0,                                                                                                                                      // baseMipLevel;
2857                                         1,                                                                                                                                      // mipLevels;
2858                                         0,                                                                                                                                      // baseArraySlice;
2859                                         1                                                                                                                                       // arraySize;
2860                                 }
2861                         };
2862
2863                         renderPassLayouts.push_back(barrier);
2864                 }
2865
2866                 if (!renderPassLayouts.empty())
2867                         vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2868                                                                   VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0,
2869                                                                   0, (const VkMemoryBarrier*)DE_NULL,
2870                                                                   0, (const VkBufferMemoryBarrier*)DE_NULL,
2871                                                                   (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2872         }
2873 }
2874
2875 template<typename RenderpassSubpass>
2876 void pushRenderPassCommands (const DeviceInterface&                                                     vk,
2877                                                          VkCommandBuffer                                                                commandBuffer,
2878                                                          VkRenderPass                                                                   renderPass,
2879                                                          VkFramebuffer                                                                  framebuffer,
2880                                                          const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2881                                                          const VkRect2D&                                                                renderArea,
2882                                                          const vector<Maybe<VkClearValue> >&                    renderPassClearValues,
2883                                                          TestConfig::RenderTypes                                                render)
2884 {
2885         const float                                                                                     clearNan                                = tcu::Float32::nan().asFloat();
2886         vector<VkClearValue>                                                            attachmentClearValues;
2887         const typename RenderpassSubpass::SubpassEndInfo        subpassEndInfo                  (DE_NULL);
2888
2889         for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2890         {
2891                 if (renderPassClearValues[attachmentNdx])
2892                         attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2893                 else
2894                         attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2895         }
2896
2897         {
2898                 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2899                 {
2900                         const VkSubpassContents                                                         contents                        = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2901                         const typename RenderpassSubpass::SubpassBeginInfo      subpassBeginInfo        (DE_NULL, contents);
2902                         const VkRenderPassBeginInfo                                                     renderPassBeginInfo     = createRenderPassBeginInfo(renderPass,
2903                                                                                                                                                                                                                                 framebuffer,
2904                                                                                                                                                                                                                                 renderArea,
2905                                                                                                                                                                                                                                 (deUint32)attachmentClearValues.size(),
2906                                                                                                                                                                                                                                 attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0]);
2907
2908                         if (subpassNdx == 0)
2909                                 RenderpassSubpass::cmdBeginRenderPass(vk, commandBuffer, &renderPassBeginInfo, &subpassBeginInfo);
2910                         else
2911                                 RenderpassSubpass::cmdNextSubpass(vk, commandBuffer, &subpassBeginInfo, &subpassEndInfo);
2912
2913                         if (render)
2914                         {
2915                                 if (contents == VK_SUBPASS_CONTENTS_INLINE)
2916                                 {
2917                                         subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2918                                 }
2919                                 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2920                                 {
2921                                         const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2922                                         vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2923                                 }
2924                                 else
2925                                         DE_FATAL("Invalid contents");
2926                         }
2927                 }
2928
2929                 RenderpassSubpass::cmdEndRenderPass(vk, commandBuffer, &subpassEndInfo);
2930         }
2931 }
2932
2933 #ifndef CTS_USES_VULKANSC
2934 void pushDynamicRenderingCommands (const DeviceInterface&                                                               vk,
2935                                                                    VkCommandBuffer                                                                              commandBuffer,
2936                                                                    const RenderPass&                                                                    renderPassInfo,
2937                                                                    const vector<de::SharedPtr<AttachmentResources> >&   attachmentResources,
2938                                                                    const vector<de::SharedPtr<SubpassRenderer> >&               subpassRenderers,
2939                                                                    const VkRect2D&                                                                              renderArea,
2940                                                                    const vector<Maybe<VkClearValue> >&                                  renderPassClearValues,
2941                                                                    deUint32                                                                                             queueIndex,
2942                                                                    TestConfig::RenderTypes                                                              renderType,
2943                                                                    bool                                                                                                 secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2944 {
2945         DE_ASSERT(subpassRenderers.size() == 1);
2946
2947         vector<VkImageMemoryBarrier>            imageBarriersBeforeRendering;
2948         vector<VkImageMemoryBarrier>            imageBarriersAfterRendering;
2949
2950         const Subpass&                                          subpassInfo                                     = renderPassInfo.getSubpasses()[0];
2951         const vector<AttachmentReference>&      colorAttachmentsInfo            = subpassInfo.getColorAttachments();
2952
2953         for (deUint32 i = 0 ; i < colorAttachmentsInfo.size() ; ++i)
2954         {
2955                 const AttachmentReference&              colorAttachmentReference        = colorAttachmentsInfo[i];
2956                 const deUint32                                  colorAttachmentIndex            = colorAttachmentReference.getAttachment();
2957                 const Attachment&                               colorAttachmentInfo                     = renderPassInfo.getAttachments()[colorAttachmentIndex];
2958
2959                 const VkImageLayout                             initialLayout                           = colorAttachmentInfo.getInitialLayout();
2960                 const VkImageLayout                             renderingLayout                         = colorAttachmentReference.getImageLayout();
2961                 const VkImageLayout                             finalLayout                                     = colorAttachmentInfo.getFinalLayout();
2962
2963                 const VkImageMemoryBarrier barrierBeforeRendering
2964                 {
2965                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                         // sType
2966                         DE_NULL,                                                                                                                        // pNext
2967
2968                         getAllMemoryWriteFlags() | getMemoryFlagsForLayout(initialLayout),      // srcAccessMask
2969                         getMemoryFlagsForLayout(renderingLayout),                                                       // dstAccessMask
2970
2971                         initialLayout,                                                                                                          // oldLayout
2972                         renderingLayout,                                                                                                        // newLayout
2973
2974                         queueIndex,                                                                                                                     // srcQueueFamilyIndex
2975                         queueIndex,                                                                                                                     // destQueueFamilyIndex
2976
2977                         attachmentResources[colorAttachmentIndex]->getImage(),                          // image
2978                         {                                                                                                                                       // subresourceRange
2979                                 getImageAspectFlags(colorAttachmentInfo.getFormat()),                   // aspect;
2980                                 0,                                                                                                                              // baseMipLevel
2981                                 1,                                                                                                                              // mipLevels
2982                                 0,                                                                                                                              // baseArraySlice
2983                                 1                                                                                                                               // arraySize
2984                         }
2985                 };
2986                 imageBarriersBeforeRendering.push_back(barrierBeforeRendering);
2987
2988                 const VkImageMemoryBarrier barrierAfterRendering
2989                 {
2990                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                         // sType
2991                         DE_NULL,                                                                                                                        // pNext
2992
2993                         getMemoryFlagsForLayout(renderingLayout),                                                       // srcAccessMask
2994                         getAllMemoryReadFlags() | getMemoryFlagsForLayout(finalLayout),         // dstAccessMask
2995
2996                         renderingLayout,                                                                                                        // oldLayout
2997                         finalLayout,                                                                                                            // newLayout
2998
2999                         queueIndex,                                                                                                                     // srcQueueFamilyIndex
3000                         queueIndex,                                                                                                                     // destQueueFamilyIndex
3001
3002                         attachmentResources[colorAttachmentIndex]->getImage(),                          // image
3003                         {                                                                                                                                       // subresourceRange
3004                                 getImageAspectFlags(colorAttachmentInfo.getFormat()),                   // aspect;
3005                                 0,                                                                                                                              // baseMipLevel
3006                                 1,                                                                                                                              // mipLevels
3007                                 0,                                                                                                                              // baseArraySlice
3008                                 1                                                                                                                               // arraySize
3009                         }
3010                 };
3011                 imageBarriersAfterRendering.push_back(barrierAfterRendering);
3012         }
3013
3014         const AttachmentReference&              depthStencilAttachmentReference = subpassInfo.getDepthStencilAttachment();
3015         const deUint32                                  dsAttachmentIndex                               = depthStencilAttachmentReference.getAttachment();
3016
3017         if (dsAttachmentIndex != VK_ATTACHMENT_UNUSED)
3018         {
3019                 const Attachment&                       dsAttachmentInfo        = renderPassInfo.getAttachments()[dsAttachmentIndex];
3020
3021                 const VkImageLayout initialLayout               = dsAttachmentInfo.getInitialLayout();
3022                 const VkImageLayout renderingLayout             = depthStencilAttachmentReference.getImageLayout();
3023                 const VkImageLayout finalLayout                 = dsAttachmentInfo.getFinalLayout();
3024
3025                 const VkImageMemoryBarrier barrierBeforeRendering
3026                 {
3027                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                         // sType
3028                         DE_NULL,                                                                                                                        // pNext
3029
3030                         getAllMemoryWriteFlags() | getMemoryFlagsForLayout(initialLayout),      // srcAccessMask
3031                         getMemoryFlagsForLayout(renderingLayout),                                                       // dstAccessMask
3032
3033                         initialLayout,                                                                                                          // oldLayout
3034                         renderingLayout,                                                                                                        // newLayout
3035
3036                         queueIndex,                                                                                                                     // srcQueueFamilyIndex
3037                         queueIndex,                                                                                                                     // destQueueFamilyIndex
3038
3039                         attachmentResources[dsAttachmentIndex]->getImage(),                                     // image
3040                         {                                                                                                                                       // subresourceRange
3041                                 getImageAspectFlags(dsAttachmentInfo.getFormat()),                              // aspect;
3042                                 0,                                                                                                                              // baseMipLevel
3043                                 1,                                                                                                                              // mipLevels
3044                                 0,                                                                                                                              // baseArraySlice
3045                                 1                                                                                                                               // arraySize
3046                         }
3047                 };
3048                 imageBarriersBeforeRendering.push_back(barrierBeforeRendering);
3049
3050                 const VkImageMemoryBarrier barrierAfterRendering
3051                 {
3052                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                         // sType
3053                         DE_NULL,                                                                                                                        // pNext
3054
3055                         getMemoryFlagsForLayout(renderingLayout),                                                       // srcAccessMask
3056                         getAllMemoryReadFlags() | getMemoryFlagsForLayout(finalLayout),         // dstAccessMask
3057
3058                         renderingLayout,                                                                                                        // oldLayout
3059                         finalLayout,                                                                                                            // newLayout
3060
3061                         queueIndex,                                                                                                                     // srcQueueFamilyIndex
3062                         queueIndex,                                                                                                                     // destQueueFamilyIndex
3063
3064                         attachmentResources[dsAttachmentIndex]->getImage(),                                     // image
3065                         {                                                                                                                                       // subresourceRange
3066                                 getImageAspectFlags(dsAttachmentInfo.getFormat()),                              // aspect;
3067                                 0,                                                                                                                              // baseMipLevel
3068                                 1,                                                                                                                              // mipLevels
3069                                 0,                                                                                                                              // baseArraySlice
3070                                 1                                                                                                                               // arraySize
3071                         }
3072                 };
3073                 imageBarriersAfterRendering.push_back(barrierAfterRendering);
3074         }
3075
3076         if (!imageBarriersBeforeRendering.empty())
3077                 vk.cmdPipelineBarrier(commandBuffer,
3078                                                           getAllPipelineStageFlags(),
3079                                                           getAllPipelineStageFlags(),
3080                                                           (VkDependencyFlags)0,
3081                                                           0, (const VkMemoryBarrier*)DE_NULL,
3082                                                           0, (const VkBufferMemoryBarrier*)DE_NULL,
3083                                                           (deUint32)imageBarriersBeforeRendering.size(),
3084                                                           &imageBarriersBeforeRendering[0]);
3085
3086         bool executeRenderCommands = (renderType != TestConfig::RENDERTYPES_NONE);
3087
3088         if (secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3089         {
3090                 // when secondary command buffer completely contains dynamic renderpass
3091                 // then we need to execute it even when render type is none
3092                 executeRenderCommands = true;
3093         }
3094         else
3095         {
3096                 VkRenderingFlagsKHR renderingFlags = 0u;
3097                 if (subpassRenderers[0]->isSecondary())
3098                         renderingFlags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR;
3099
3100                 beginDynamicRendering(vk, commandBuffer, renderPassInfo, attachmentResources, renderArea, renderPassClearValues, renderingFlags);
3101         }
3102
3103         if (executeRenderCommands)
3104         {
3105                 if (subpassRenderers[0]->isSecondary())
3106                 {
3107                         const VkCommandBuffer cmd = subpassRenderers[0]->getCommandBuffer();
3108                         vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
3109                 }
3110                 else
3111                         subpassRenderers[0]->pushRenderCommands(vk, commandBuffer);
3112         }
3113
3114         if (!secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3115                 endDynamicRendering(vk, commandBuffer);
3116
3117         if (!imageBarriersAfterRendering.empty())
3118                 vk.cmdPipelineBarrier(commandBuffer,
3119                                                           getAllPipelineStageFlags(),
3120                                                           getAllPipelineStageFlags(),
3121                                                           (VkDependencyFlags)0,
3122                                                           0, (const VkMemoryBarrier*)DE_NULL,
3123                                                           0, (const VkBufferMemoryBarrier*)DE_NULL,
3124                                                           (deUint32)imageBarriersAfterRendering.size(),
3125                                                           &imageBarriersAfterRendering[0]);
3126 }
3127 #endif // CTS_USES_VULKANSC
3128
3129 void pushRenderPassCommands (const DeviceInterface&                                                             vk,
3130                                                          VkCommandBuffer                                                                        commandBuffer,
3131                                                          VkRenderPass                                                                           renderPass,
3132                                                          const RenderPass&                                                                      renderPassInfo,
3133                                                          const vector<de::SharedPtr<AttachmentResources> >&     attachmentResources,
3134                                                          VkFramebuffer                                                                          framebuffer,
3135                                                          const vector<de::SharedPtr<SubpassRenderer> >&         subpassRenderers,
3136                                                          const VkRect2D&                                                                        renderArea,
3137                                                          const vector<Maybe<VkClearValue> >&                            renderPassClearValues,
3138                                                          deUint32                                                                                       queueIndex,
3139                                                          TestConfig::RenderTypes                                                        render,
3140                                                          RenderingType                                                                          renderingType,
3141                                                          bool                                                                                           secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3142 {
3143         // unreference arguments not used by Vulkan SC, no need to put them under ifdef
3144         DE_UNREF(renderPassInfo);
3145         DE_UNREF(attachmentResources);
3146         DE_UNREF(queueIndex);
3147         DE_UNREF(secondaryCmdBufferCompletelyContainsDynamicRenderpass);
3148
3149         switch (renderingType)
3150         {
3151                 case RENDERING_TYPE_RENDERPASS_LEGACY:
3152                         return pushRenderPassCommands<RenderpassSubpass1>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers, renderArea, renderPassClearValues, render);
3153                 case RENDERING_TYPE_RENDERPASS2:
3154                         return pushRenderPassCommands<RenderpassSubpass2>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers, renderArea, renderPassClearValues, render);
3155
3156 #ifndef CTS_USES_VULKANSC
3157                 case RENDERING_TYPE_DYNAMIC_RENDERING:
3158                         return pushDynamicRenderingCommands(vk, commandBuffer, renderPassInfo, attachmentResources, subpassRenderers, renderArea, renderPassClearValues, queueIndex, render, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
3159 #endif // CTS_USES_VULKANSC
3160
3161                 default:
3162                         TCU_THROW(InternalError, "Impossible");
3163         }
3164 }
3165
3166 void pushReadImagesToBuffers (const DeviceInterface&                                                            vk,
3167                                                           VkCommandBuffer                                                                               commandBuffer,
3168                                                           deUint32                                                                                              queueIndex,
3169
3170                                                           const vector<de::SharedPtr<AttachmentResources> >&    attachmentResources,
3171                                                           const vector<Attachment>&                                                             attachmentInfo,
3172                                                           const vector<bool>&                                                                   isLazy,
3173
3174                                                           const UVec2&                                                                                  targetSize)
3175 {
3176         {
3177                 vector<VkImageMemoryBarrier>    imageBarriers;
3178
3179                 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3180                 {
3181                         if (isLazy[attachmentNdx])
3182                                 continue;
3183
3184                         const VkImageLayout                     oldLayout       = attachmentInfo[attachmentNdx].getFinalLayout();
3185                         const VkImageMemoryBarrier      barrier         =
3186                         {
3187                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                 // sType
3188                                 DE_NULL,                                                                                                                // pNext
3189
3190                                 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout),  // srcAccessMask
3191                                 getAllMemoryReadFlags(),                                                                                // dstAccessMask
3192
3193                                 oldLayout,                                                                                                              // oldLayout
3194                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                                                   // newLayout
3195
3196                                 queueIndex,                                                                                                             // srcQueueFamilyIndex
3197                                 queueIndex,                                                                                                             // destQueueFamilyIndex
3198
3199                                 attachmentResources[attachmentNdx]->getImage(),                                 // image
3200                                 {                                                                                                                               // subresourceRange
3201                                         getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),         // aspect;
3202                                         0,                                                                                                                                      // baseMipLevel
3203                                         1,                                                                                                                                      // mipLevels
3204                                         0,                                                                                                                                      // baseArraySlice
3205                                         1                                                                                                                                       // arraySize
3206                                 }
3207                         };
3208
3209                         imageBarriers.push_back(barrier);
3210                 }
3211
3212                 if (!imageBarriers.empty())
3213                         vk.cmdPipelineBarrier(commandBuffer,
3214                                                                   getAllPipelineStageFlags(),
3215                                                                   getAllPipelineStageFlags(),
3216                                                                   (VkDependencyFlags)0,
3217                                                                   0, (const VkMemoryBarrier*)DE_NULL,
3218                                                                   0, (const VkBufferMemoryBarrier*)DE_NULL,
3219                                                                   (deUint32)imageBarriers.size(), &imageBarriers[0]);
3220         }
3221
3222         for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3223         {
3224                 if (isLazy[attachmentNdx])
3225                         continue;
3226
3227                 const tcu::TextureFormat::ChannelOrder  order   = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
3228                 const VkBufferImageCopy                                 rect    =
3229                 {
3230                         0, // bufferOffset
3231                         0, // bufferRowLength
3232                         0, // bufferImageHeight
3233                         {                                                       // imageSubresource
3234                                 (vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order),    // aspect
3235                                 0,                                              // mipLevel
3236                                 0,                                              // arraySlice
3237                                 1                                               // arraySize
3238                         },
3239                         { 0, 0, 0 },                            // imageOffset
3240                         { targetSize.x(), targetSize.y(), 1u }          // imageExtent
3241                 };
3242
3243                 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
3244
3245                 if (tcu::TextureFormat::DS == order)
3246                 {
3247                         const VkBufferImageCopy stencilRect =
3248                         {
3249                                 0,                                                                              // bufferOffset
3250                                 0,                                                                              // bufferRowLength
3251                                 0,                                                                              // bufferImageHeight
3252                                 {                                                                       // imageSubresource
3253                                         VK_IMAGE_ASPECT_STENCIL_BIT,    // aspect
3254                                         0,                                                              // mipLevel
3255                                         0,                                                              // arraySlice
3256                                         1                                                               // arraySize
3257                                 },
3258                                 { 0, 0, 0 },                                                    // imageOffset
3259                                 { targetSize.x(), targetSize.y(), 1u }  // imageExtent
3260                         };
3261
3262                         vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
3263                 }
3264         }
3265
3266         {
3267                 vector<VkBufferMemoryBarrier>   bufferBarriers;
3268
3269                 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3270                 {
3271                         if (isLazy[attachmentNdx])
3272                                 continue;
3273
3274                         const tcu::TextureFormat::ChannelOrder  order                   = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
3275                         const VkBufferMemoryBarrier                             bufferBarrier   =
3276                         {
3277                                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3278                                 DE_NULL,
3279
3280                                 getAllMemoryWriteFlags(),
3281                                 getAllMemoryReadFlags(),
3282
3283                                 queueIndex,
3284                                 queueIndex,
3285
3286                                 attachmentResources[attachmentNdx]->getBuffer(),
3287                                 0,
3288                                 attachmentResources[attachmentNdx]->getBufferSize()
3289                         };
3290
3291                         bufferBarriers.push_back(bufferBarrier);
3292
3293                         if (tcu::TextureFormat::DS == order)
3294                         {
3295                                 const VkBufferMemoryBarrier secondaryBufferBarrier =
3296                                 {
3297                                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3298                                         DE_NULL,
3299
3300                                         getAllMemoryWriteFlags(),
3301                                         getAllMemoryReadFlags(),
3302
3303                                         queueIndex,
3304                                         queueIndex,
3305
3306                                         attachmentResources[attachmentNdx]->getSecondaryBuffer(),
3307                                         0,
3308                                         attachmentResources[attachmentNdx]->getSecondaryBufferSize()
3309                                 };
3310
3311                                 bufferBarriers.push_back(secondaryBufferBarrier);
3312                         }
3313                 }
3314
3315                 if (!bufferBarriers.empty())
3316                         vk.cmdPipelineBarrier(commandBuffer,
3317                                                                   getAllPipelineStageFlags(),
3318                                                                   getAllPipelineStageFlags(),
3319                                                                   (VkDependencyFlags)0,
3320                                                                   0, (const VkMemoryBarrier*)DE_NULL,
3321                                                                   (deUint32)bufferBarriers.size(), &bufferBarriers[0],
3322                                                                   0, (const VkImageMemoryBarrier*)DE_NULL);
3323         }
3324 }
3325
3326 class PixelValue
3327 {
3328 public:
3329                                 PixelValue              (const Maybe<bool>&     x = tcu::Nothing,
3330                                                                  const Maybe<bool>&     y = tcu::Nothing,
3331                                                                  const Maybe<bool>&     z = tcu::Nothing,
3332                                                                  const Maybe<bool>&     w = tcu::Nothing);
3333
3334         void            setUndefined    (size_t ndx);
3335         void            setValue                (size_t ndx, bool value);
3336         Maybe<bool>     getValue                (size_t ndx) const;
3337
3338 private:
3339         deUint16        m_status;
3340 };
3341
3342 PixelValue::PixelValue (const Maybe<bool>&      x,
3343                                                 const Maybe<bool>&      y,
3344                                                 const Maybe<bool>&      z,
3345                                                 const Maybe<bool>&      w)
3346         : m_status (0)
3347 {
3348         const Maybe<bool> values[] =
3349         {
3350                 x, y, z, w
3351         };
3352
3353         for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
3354         {
3355                 if (values[ndx])
3356                         setValue(ndx, *values[ndx]);
3357                 else
3358                         setUndefined(ndx);
3359         }
3360
3361         DE_ASSERT(m_status <= 0xFFu);
3362 }
3363
3364 void PixelValue::setUndefined (size_t ndx)
3365 {
3366         DE_ASSERT(ndx < 4);
3367         DE_ASSERT(m_status <= 0xFFu);
3368
3369         m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2));
3370         DE_ASSERT(m_status <= 0xFFu);
3371 }
3372
3373 void PixelValue::setValue (size_t ndx, bool value)
3374 {
3375         DE_ASSERT(ndx < 4);
3376         DE_ASSERT(m_status <= 0xFFu);
3377
3378         m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2)));
3379
3380         if (value)
3381                 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2 + 1)));
3382         else
3383                 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1));
3384
3385         DE_ASSERT(m_status <= 0xFFu);
3386 }
3387
3388 Maybe<bool> PixelValue::getValue (size_t ndx) const
3389 {
3390         DE_ASSERT(ndx < 4);
3391         DE_ASSERT(m_status <= 0xFFu);
3392
3393         if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0)
3394         {
3395                 return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0);
3396         }
3397         else
3398                 return tcu::Nothing;
3399 }
3400
3401 void clearReferenceValues (vector<PixelValue>&  values,
3402                                                    const UVec2&                 targetSize,
3403                                                    const UVec2&                 offset,
3404                                                    const UVec2&                 size,
3405                                                    const BVec4&                 mask,
3406                                                    const PixelValue&    value)
3407 {
3408         DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
3409         DE_ASSERT(offset.x() + size.x() <= targetSize.x());
3410         DE_ASSERT(offset.y() + size.y() <= targetSize.y());
3411
3412         for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
3413         for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
3414         {
3415                 for (int compNdx = 0; compNdx < 4; compNdx++)
3416                 {
3417                         if (mask[compNdx])
3418                         {
3419                                 if (value.getValue(compNdx))
3420                                         values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
3421                                 else
3422                                         values[x + y * targetSize.x()].setUndefined(compNdx);
3423                         }
3424                 }
3425         }
3426 }
3427
3428 void markUndefined (vector<PixelValue>& values,
3429                                         const BVec4&            mask,
3430                                         const UVec2&            targetSize,
3431                                         const UVec2&            offset,
3432                                         const UVec2&            size)
3433 {
3434         DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
3435
3436         for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
3437         for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
3438         {
3439                 for (int compNdx = 0; compNdx < 4; compNdx++)
3440                 {
3441                         if (mask[compNdx])
3442                                 values[x + y * targetSize.x()].setUndefined(compNdx);
3443                 }
3444         }
3445 }
3446
3447 PixelValue clearValueToPixelValue (const VkClearValue&                  value,
3448                                                                    const tcu::TextureFormat&    format,
3449                                                                    const DepthValuesArray&              depthValues)
3450 {
3451         const bool      isDepthAttachment                       = hasDepthComponent(format.order);
3452         const bool      isStencilAttachment                     = hasStencilComponent(format.order);
3453         const bool      isDepthOrStencilAttachment      = isDepthAttachment || isStencilAttachment;
3454         PixelValue      pixelValue;
3455
3456         if (isDepthOrStencilAttachment)
3457         {
3458                 if (isDepthAttachment)
3459                 {
3460                         if (value.depthStencil.depth == float(depthValues[1]) / 255.0f)
3461                                 pixelValue.setValue(0, true);
3462                         else if (value.depthStencil.depth == float(depthValues[0]) / 255.0f)
3463                                 pixelValue.setValue(0, false);
3464                         else
3465                                 DE_FATAL("Unknown depth value");
3466                 }
3467
3468                 if (isStencilAttachment)
3469                 {
3470                         if (value.depthStencil.stencil == 0xFFu)
3471                                 pixelValue.setValue(1, true);
3472                         else if (value.depthStencil.stencil == 0x0u)
3473                                 pixelValue.setValue(1, false);
3474                         else
3475                                 DE_FATAL("Unknown stencil value");
3476                 }
3477         }
3478         else
3479         {
3480                 const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
3481                 const tcu::BVec4                                channelMask             = tcu::getTextureFormatChannelMask(format);
3482
3483                 switch (channelClass)
3484                 {
3485                         case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3486                                 for (int i = 0; i < 4; i++)
3487                                 {
3488                                         if (channelMask[i])
3489                                         {
3490                                                 if (value.color.int32[i] == 1)
3491                                                         pixelValue.setValue(i, true);
3492                                                 else if (value.color.int32[i] == 0)
3493                                                         pixelValue.setValue(i, false);
3494                                                 else
3495                                                         DE_FATAL("Unknown clear color value");
3496                                         }
3497                                 }
3498                                 break;
3499
3500                         case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3501                                 for (int i = 0; i < 4; i++)
3502                                 {
3503                                         if (channelMask[i])
3504                                         {
3505                                                 if (value.color.uint32[i] == 1u)
3506                                                         pixelValue.setValue(i, true);
3507                                                 else if (value.color.uint32[i] == 0u)
3508                                                         pixelValue.setValue(i, false);
3509                                                 else
3510                                                         DE_FATAL("Unknown clear color value");
3511                                         }
3512                                 }
3513                                 break;
3514
3515                         case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3516                         case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3517                         case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3518                                 for (int i = 0; i < 4; i++)
3519                                 {
3520                                         if (channelMask[i])
3521                                         {
3522                                                 if (value.color.float32[i] == 1.0f)
3523                                                         pixelValue.setValue(i, true);
3524                                                 else if (value.color.float32[i] == 0.0f)
3525                                                         pixelValue.setValue(i, false);
3526                                                 else
3527                                                         DE_FATAL("Unknown clear color value");
3528                                         }
3529                                 }
3530                                 break;
3531
3532                         default:
3533                                 DE_FATAL("Unknown channel class");
3534                 }
3535         }
3536
3537         return pixelValue;
3538 }
3539
3540 void renderReferenceValues (vector<vector<PixelValue> >&                referenceAttachments,
3541                                                         const RenderPass&                                       renderPassInfo,
3542                                                         const UVec2&                                            targetSize,
3543                                                         const vector<Maybe<VkClearValue> >&     imageClearValues,
3544                                                         const vector<Maybe<VkClearValue> >&     renderPassClearValues,
3545                                                         const vector<SubpassRenderInfo>&        subpassRenderInfo,
3546                                                         const UVec2&                                            renderPos,
3547                                                         const UVec2&                                            renderSize,
3548                                                         const deUint32                                          drawStartNdx,
3549                                                         const DepthValuesArray&                         depthValues)
3550 {
3551         const vector<Subpass>&  subpasses               = renderPassInfo.getSubpasses();
3552         vector<bool>                    attachmentUsed  (renderPassInfo.getAttachments().size(), false);
3553
3554         referenceAttachments.resize(renderPassInfo.getAttachments().size());
3555
3556         for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3557         {
3558                 const Attachment                        attachment      = renderPassInfo.getAttachments()[attachmentNdx];
3559                 const tcu::TextureFormat        format          = mapVkFormat(attachment.getFormat());
3560                 vector<PixelValue>&                     reference       = referenceAttachments[attachmentNdx];
3561
3562                 reference.resize(targetSize.x() * targetSize.y());
3563
3564                 if (imageClearValues[attachmentNdx])
3565                         clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format, depthValues));
3566         }
3567
3568         for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3569         {
3570                 const Subpass&                                          subpass                         = subpasses[subpassNdx];
3571                 const SubpassRenderInfo&                        renderInfo                      = subpassRenderInfo[subpassNdx];
3572                 const vector<AttachmentReference>&      colorAttachments        = subpass.getColorAttachments();
3573
3574                 // Apply load op if attachment was used for the first time
3575                 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
3576                 {
3577                         const deUint32 attachmentIndex = getAttachmentNdx(colorAttachments, attachmentNdx);
3578
3579                         if (!attachmentUsed[attachmentIndex] && colorAttachments[attachmentNdx].getAttachment() != VK_ATTACHMENT_UNUSED)
3580                         {
3581                                 const Attachment&                       attachment      = renderPassInfo.getAttachments()[attachmentIndex];
3582                                 vector<PixelValue>&                     reference       = referenceAttachments[attachmentIndex];
3583                                 const tcu::TextureFormat        format          = mapVkFormat(attachment.getFormat());
3584
3585                                 DE_ASSERT(!tcu::hasDepthComponent(format.order));
3586                                 DE_ASSERT(!tcu::hasStencilComponent(format.order));
3587
3588                                 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3589                                         clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3590                                 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3591                                         markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3592
3593                                 attachmentUsed[attachmentIndex] = true;
3594                         }
3595                 }
3596
3597                 // Apply load op to depth/stencil attachment if it was used for the first time
3598                 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3599                 {
3600                         const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3601
3602                         // Apply load op if attachment was used for the first time
3603                         if (!attachmentUsed[attachmentIndex])
3604                         {
3605                                 const Attachment&                       attachment      = renderPassInfo.getAttachments()[attachmentIndex];
3606                                 vector<PixelValue>&                     reference       = referenceAttachments[attachmentIndex];
3607                                 const tcu::TextureFormat        format          = mapVkFormat(attachment.getFormat());
3608
3609                                 if (tcu::hasDepthComponent(format.order))
3610                                 {
3611                                         if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3612                                                 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3613                                         else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3614                                                 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3615                                 }
3616
3617                                 if (tcu::hasStencilComponent(format.order))
3618                                 {
3619                                         if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3620                                                 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3621                                         else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3622                                                 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3623                                 }
3624
3625                                 attachmentUsed[attachmentIndex] = true;
3626                         }
3627                 }
3628
3629                 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
3630                 {
3631                         const ColorClear&                       colorClear              = renderInfo.getColorClears()[colorClearNdx];
3632                         const UVec2                                     offset                  = colorClear.getOffset();
3633                         const UVec2                                     size                    = colorClear.getSize();
3634                         const deUint32                          attachmentIndex = subpass.getColorAttachments()[colorClearNdx].getAttachment();
3635                         const Attachment&                       attachment              = renderPassInfo.getAttachments()[attachmentIndex];
3636                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
3637                         vector<PixelValue>&                     reference               = referenceAttachments[attachmentIndex];
3638                         VkClearValue                            value;
3639
3640                         value.color = colorClear.getColor();
3641
3642                         clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format, depthValues));
3643                 }
3644
3645                 if (renderInfo.getDepthStencilClear())
3646                 {
3647                         const DepthStencilClear&        dsClear                 = *renderInfo.getDepthStencilClear();
3648                         const UVec2                                     offset                  = dsClear.getOffset();
3649                         const UVec2                                     size                    = dsClear.getSize();
3650                         const deUint32                          attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3651                         const VkImageLayout                     layout                  = subpass.getDepthStencilAttachment().getImageLayout();
3652                         const Attachment&                       attachment              = renderPassInfo.getAttachments()[attachmentIndex];
3653                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
3654                         const bool                                      hasStencil              = tcu::hasStencilComponent(format.order)
3655                                                                                                                 && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
3656                         const bool                                      hasDepth                = tcu::hasDepthComponent(format.order)
3657                                                                                                                 && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
3658                         vector<PixelValue>&                     reference               = referenceAttachments[attachmentIndex];
3659                         VkClearValue                            value;
3660
3661                         value.depthStencil.depth = dsClear.getDepth();
3662                         value.depthStencil.stencil = dsClear.getStencil();
3663
3664                         clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format, depthValues));
3665                 }
3666
3667                 if (renderInfo.getRenderQuad())
3668                 {
3669                         const RenderQuad&       renderQuad      = *renderInfo.getRenderQuad();
3670                         const Vec2                      posA            = renderQuad.getCornerA();
3671                         const Vec2                      posB            = renderQuad.getCornerB();
3672                         const Vec2                      origin          = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3673                         const Vec2                      p                       = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3674                         const IVec2                     posAI           (deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
3675                                                                                          deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
3676                         const IVec2                     posBI           (deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
3677                                                                                          deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));
3678
3679                         DE_ASSERT(posAI.x() < posBI.x());
3680                         DE_ASSERT(posAI.y() < posBI.y());
3681
3682                         if (subpass.getInputAttachments().empty())
3683                         {
3684                                 for (size_t attachmentRefNdx = drawStartNdx; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3685                                 {
3686                                         const deUint32                          attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3687
3688                                         if (attachmentIndex == VK_ATTACHMENT_UNUSED)
3689                                                 continue;
3690
3691                                         const Attachment&                       attachment              = renderPassInfo.getAttachments()[attachmentIndex];
3692                                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
3693                                         const tcu::BVec4                        channelMask             = tcu::getTextureFormatChannelMask(format);
3694                                         vector<PixelValue>&                     reference               = referenceAttachments[attachmentIndex];
3695
3696                                         for (int y = posAI.y(); y < (int)posBI.y(); y++)
3697                                         for (int x = posAI.x(); x < (int)posBI.x(); x++)
3698                                         {
3699                                                 for (int compNdx = 0; compNdx < 4; compNdx++)
3700                                                 {
3701                                                         const size_t    index   = subpassNdx + attachmentIndex + compNdx;
3702                                                         const BoolOp    op              = boolOpFromIndex(index);
3703                                                         const bool              boolX   = x % 2 == (int)(index % 2);
3704                                                         const bool              boolY   = y % 2 == (int)((index / 2) % 2);
3705
3706                                                         if (channelMask[compNdx])
3707                                                                 reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY));
3708                                                 }
3709                                         }
3710                                 }
3711
3712                                 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3713                                 {
3714                                         const deUint32                          attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3715                                         const VkImageLayout                     layout                  = subpass.getDepthStencilAttachment().getImageLayout();
3716                                         const Attachment&                       attachment              = renderPassInfo.getAttachments()[attachmentIndex];
3717                                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
3718                                         vector<PixelValue>&                     reference               = referenceAttachments[attachmentIndex];
3719
3720                                         for (int y = posAI.y(); y < (int)posBI.y(); y++)
3721                                         for (int x = posAI.x(); x < (int)posBI.x(); x++)
3722                                         {
3723                                                 if (tcu::hasDepthComponent(format.order)
3724                                                         && layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3725                                                         && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3726                                                 {
3727                                                         const size_t    index   = subpassNdx + 1;
3728                                                         const BoolOp    op              = boolOpFromIndex(index);
3729                                                         const bool              boolX   = x % 2 == (int)(index % 2);
3730                                                         const bool              boolY   = y % 2 == (int)((index / 2) % 2);
3731
3732                                                         reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
3733                                                 }
3734
3735                                                 if (tcu::hasStencilComponent(format.order)
3736                                                         && layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3737                                                         && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3738                                                 {
3739                                                         const size_t    index   = subpassNdx;
3740                                                         reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3741                                                 }
3742                                         }
3743                                 }
3744                         }
3745                         else
3746                         {
3747                                 size_t                                  outputComponentCount    = 0;
3748                                 vector<Maybe<bool> >    inputs;
3749
3750                                 DE_ASSERT(posAI.x() < posBI.x());
3751                                 DE_ASSERT(posAI.y() < posBI.y());
3752
3753                                 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3754                                 {
3755                                         const deUint32                          attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3756                                         const Attachment&                       attachment              = renderPassInfo.getAttachments()[attachmentIndex];
3757                                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
3758                                         const int                                       componentCount  = tcu::getNumUsedChannels(format.order);
3759
3760                                         outputComponentCount += (size_t)componentCount;
3761                                 }
3762
3763                                 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3764                                         && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3765                                         && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3766                                 {
3767                                         const Attachment&                       attachment      (renderPassInfo.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()]);
3768                                         const tcu::TextureFormat        format          (mapVkFormat(attachment.getFormat()));
3769
3770                                         if (tcu::hasDepthComponent(format.order))
3771                                                 outputComponentCount++;
3772                                 }
3773
3774                                 if (outputComponentCount > 0)
3775                                 {
3776                                         for (int y = posAI.y(); y < (int)posBI.y(); y++)
3777                                         for (int x = posAI.x(); x < (int)posBI.x(); x++)
3778                                         {
3779                                                 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
3780                                                 {
3781                                                         const deUint32                          attachmentIndex = subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
3782                                                         const VkImageLayout                     layout                  = subpass.getInputAttachments()[inputAttachmentNdx].getImageLayout();
3783                                                         const Attachment&                       attachment              = renderPassInfo.getAttachments()[attachmentIndex];
3784                                                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
3785                                                         const int                                       componentCount  = tcu::getNumUsedChannels(format.order);
3786
3787                                                         for (int compNdx = 0; compNdx < componentCount; compNdx++)
3788                                                         {
3789                                                                 if ((compNdx != 0 || layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3790                                                                         && (compNdx != 1 || layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL))
3791                                                                 {
3792                                                                         inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx));
3793                                                                 }
3794                                                         }
3795                                                 }
3796
3797                                                 const size_t inputsPerOutput = inputs.size() >= outputComponentCount
3798                                                                                                                 ? ((inputs.size() / outputComponentCount)
3799                                                                                                                         + ((inputs.size() % outputComponentCount) != 0 ? 1 : 0))
3800                                                                                                                 : 1;
3801
3802                                                 size_t outputValueNdx = 0;
3803
3804                                                 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3805                                                 {
3806                                                         const deUint32                          attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3807                                                         const Attachment&                       attachment              = renderPassInfo.getAttachments()[attachmentIndex];
3808                                                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
3809                                                         vector<PixelValue>&                     reference               = referenceAttachments[attachmentIndex];
3810                                                         const int                                       componentCount  = tcu::getNumUsedChannels(format.order);
3811
3812                                                         for (int compNdx = 0; compNdx < componentCount; compNdx++)
3813                                                         {
3814                                                                 const size_t    index   = subpassNdx + attachmentIndex + outputValueNdx;
3815                                                                 const BoolOp    op              = boolOpFromIndex(index);
3816                                                                 const bool              boolX   = x % 2 == (int)(index % 2);
3817                                                                 const bool              boolY   = y % 2 == (int)((index / 2) % 2);
3818                                                                 Maybe<bool>             output  = tcu::just(performBoolOp(op, boolX, boolY));
3819
3820                                                                 for (size_t i = 0; i < inputsPerOutput; i++)
3821                                                                 {
3822                                                                         if (!output)
3823                                                                                 break;
3824                                                                         else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()])
3825                                                                                 output = tcu::Nothing;
3826                                                                         else
3827                                                                                 output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]);
3828                                                                 }
3829
3830                                                                 if (output)
3831                                                                         reference[x + y * targetSize.x()].setValue(compNdx, *output);
3832                                                                 else
3833                                                                         reference[x + y * targetSize.x()].setUndefined(compNdx);
3834                                                         }
3835
3836                                                         outputValueNdx += componentCount;
3837                                                 }
3838
3839                                                 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3840                                                         && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3841                                                         && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3842                                                 {
3843                                                         const deUint32          attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3844                                                         vector<PixelValue>&     reference               = referenceAttachments[attachmentIndex];
3845                                                         const size_t            index                   = subpassNdx + attachmentIndex;
3846                                                         const BoolOp            op                              = boolOpFromIndex(index);
3847                                                         const bool                      boolX                   = x % 2 == (int)(index % 2);
3848                                                         const bool                      boolY                   = y % 2 == (int)((index / 2) % 2);
3849                                                         Maybe<bool>                     output                  = tcu::just(performBoolOp(op, boolX, boolY));
3850
3851                                                         for (size_t i = 0; i < inputsPerOutput; i++)
3852                                                         {
3853                                                                 if (!output)
3854                                                                         break;
3855                                                                 else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
3856                                                                         output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
3857                                                                 else
3858                                                                         output = tcu::Nothing;
3859                                                         }
3860
3861                                                         if (output)
3862                                                                 reference[x + y * targetSize.x()].setValue(0, *output);
3863                                                         else
3864                                                                 reference[x + y * targetSize.x()].setUndefined(0);
3865                                                 }
3866
3867                                                 inputs.clear();
3868                                         }
3869                                 }
3870
3871                                 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3872                                         && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3873                                         && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3874                                 {
3875                                         const deUint32                          attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3876                                         const Attachment&                       attachment              = renderPassInfo.getAttachments()[attachmentIndex];
3877                                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
3878                                         vector<PixelValue>&                     reference               = referenceAttachments[attachmentIndex];
3879
3880                                         if (tcu::hasStencilComponent(format.order))
3881                                         {
3882                                                 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3883                                                 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3884                                                 {
3885                                                         const size_t    index   = subpassNdx;
3886                                                         reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3887                                                 }
3888                                         }
3889                                 }
3890                         }
3891                 }
3892         }
3893
3894         // Mark all attachments that were used but not stored as undefined
3895         for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
3896         {
3897                 const Attachment                        attachment                                      = renderPassInfo.getAttachments()[attachmentIndex];
3898                 const tcu::TextureFormat        format                                          = mapVkFormat(attachment.getFormat());
3899                 vector<PixelValue>&                     reference                                       = referenceAttachments[attachmentIndex];
3900                 const bool                                      isStencilAttachment                     = hasStencilComponent(format.order);
3901                 const bool                                      isDepthOrStencilAttachment      = hasDepthComponent(format.order) || isStencilAttachment;
3902
3903                 if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3904                 {
3905                         if (isDepthOrStencilAttachment)
3906                                 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3907                         else
3908                                 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3909                 }
3910
3911                 if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3912                         markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3913         }
3914 }
3915
3916 void renderReferenceImagesFromValues (vector<tcu::TextureLevel>&                        referenceImages,
3917                                                                           const vector<vector<PixelValue> >&    referenceValues,
3918                                                                           const UVec2&                                                  targetSize,
3919                                                                           const RenderPass&                                             renderPassInfo,
3920                                                                           const DepthValuesArray&                               depthValues)
3921 {
3922         referenceImages.resize(referenceValues.size());
3923
3924         for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3925         {
3926                 const Attachment                        attachment                      = renderPassInfo.getAttachments()[attachmentNdx];
3927                 const tcu::TextureFormat        format                          = mapVkFormat(attachment.getFormat());
3928                 const vector<PixelValue>&       reference                       = referenceValues[attachmentNdx];
3929                 const bool                                      hasDepth                        = tcu::hasDepthComponent(format.order);
3930                 const bool                                      hasStencil                      = tcu::hasStencilComponent(format.order);
3931                 const bool                                      hasDepthOrStencil       = hasDepth || hasStencil;
3932                 tcu::TextureLevel&                      referenceImage          = referenceImages[attachmentNdx];
3933
3934                 referenceImage.setStorage(format, targetSize.x(), targetSize.y());
3935
3936                 if (hasDepthOrStencil)
3937                 {
3938                         if (hasDepth)
3939                         {
3940                                 const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));
3941
3942                                 for (deUint32 y = 0; y < targetSize.y(); y++)
3943                                 for (deUint32 x = 0; x < targetSize.x(); x++)
3944                                 {
3945                                         if (reference[x + y * targetSize.x()].getValue(0))
3946                                         {
3947                                                 if (*reference[x + y * targetSize.x()].getValue(0))
3948                                                         depthAccess.setPixDepth(float(depthValues[1]) / 255.0f, x, y);
3949                                                 else
3950                                                         depthAccess.setPixDepth(float(depthValues[0]) / 255.0f, x, y);
3951                                         }
3952                                         else // Fill with 3x3 grid
3953                                                 depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
3954                                 }
3955                         }
3956
3957                         if (hasStencil)
3958                         {
3959                                 const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));
3960
3961                                 for (deUint32 y = 0; y < targetSize.y(); y++)
3962                                 for (deUint32 x = 0; x < targetSize.x(); x++)
3963                                 {
3964                                         if (reference[x + y * targetSize.x()].getValue(1))
3965                                         {
3966                                                 if (*reference[x + y * targetSize.x()].getValue(1))
3967                                                         stencilAccess.setPixStencil(0xFFu, x, y);
3968                                                 else
3969                                                         stencilAccess.setPixStencil(0x0u, x, y);
3970                                         }
3971                                         else // Fill with 3x3 grid
3972                                                 stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
3973                                 }
3974                         }
3975                 }
3976                 else
3977                 {
3978                         for (deUint32 y = 0; y < targetSize.y(); y++)
3979                         for (deUint32 x = 0; x < targetSize.x(); x++)
3980                         {
3981                                 tcu::Vec4 color;
3982
3983                                 for (int compNdx = 0; compNdx < 4; compNdx++)
3984                                 {
3985                                         if (reference[x + y * targetSize.x()].getValue(compNdx))
3986                                         {
3987                                                 if (*reference[x + y * targetSize.x()].getValue(compNdx))
3988                                                         color[compNdx] = 1.0f;
3989                                                 else
3990                                                         color[compNdx] = 0.0f;
3991                                         }
3992                                         else // Fill with 3x3 grid
3993                                                 color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
3994                                 }
3995
3996                                 referenceImage.getAccess().setPixel(color, x, y);
3997                         }
3998                 }
3999         }
4000 }
4001
4002 bool verifyColorAttachment (const vector<PixelValue>&           reference,
4003                                                         const ConstPixelBufferAccess&   result,
4004                                                         const PixelBufferAccess&                errorImage,
4005                                                         const deBool                                    useFormatCompCount)
4006 {
4007         const Vec4      red             (1.0f, 0.0f, 0.0f, 1.0f);
4008         const Vec4      green   (0.0f, 1.0f, 0.0f, 1.0f);
4009         bool            ok              = true;
4010
4011         DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4012         DE_ASSERT(result.getWidth() == errorImage.getWidth());
4013         DE_ASSERT(result.getHeight() == errorImage.getHeight());
4014
4015         for (int y = 0; y < result.getHeight(); y++)
4016         for (int x = 0; x < result.getWidth(); x++)
4017         {
4018                 const Vec4                      resultColor             = result.getPixel(x, y);
4019                 const PixelValue&       referenceValue  = reference[x + y * result.getWidth()];
4020                 bool                            pixelOk                 = true;
4021                 const deUint32          componentCount  = useFormatCompCount ? (deUint32)tcu::getNumUsedChannels(result.getFormat().order) : 4;
4022
4023                 for (deUint32 compNdx = 0; compNdx < componentCount; compNdx++)
4024                 {
4025                         const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);
4026
4027                         if (maybeValue)
4028                         {
4029                                 const bool value = *maybeValue;
4030
4031                                 if ((value && (resultColor[compNdx] != 1.0f))
4032                                         || (!value && resultColor[compNdx] != 0.0f))
4033                                         pixelOk = false;
4034                         }
4035                 }
4036
4037                 if (!pixelOk)
4038                 {
4039                         errorImage.setPixel(red, x, y);
4040                         ok = false;
4041                 }
4042                 else
4043                         errorImage.setPixel(green, x, y);
4044         }
4045
4046         return ok;
4047 }
4048
4049 // Setting the alpha value to 1.0f by default helps visualization when the alpha channel is not used.
4050 const tcu::Vec4 kDefaultColorForLog     {0.0f, 0.0f, 0.0f, 1.0f};
4051 const float             kTrueComponent          = 1.0f;
4052 const float             kFalseComponent         = 0.5f;
4053 const float             kUnsetComponentLow      = 0.0f;
4054 const float             kUnsetComponentHigh     = 0.25f;
4055
4056 std::unique_ptr<tcu::TextureLevel> renderColorImageForLog (const ConstPixelBufferAccess& image, int numChannels)
4057 {
4058         // Same channel order, but using UNORM_INT8 for the color format.
4059         const auto                                                      order                   = image.getFormat().order;
4060         const tcu::TextureFormat                        loggableFormat  {order, tcu::TextureFormat::UNORM_INT8};
4061         const int                                                       width                   = image.getWidth();
4062         const int                                                       height                  = image.getHeight();
4063         std::unique_ptr<tcu::TextureLevel>      result                  {new tcu::TextureLevel{loggableFormat, width, height}};
4064         auto                                                            access                  = result->getAccess();
4065         tcu::Vec4                                                       outColor                = kDefaultColorForLog;
4066
4067         for (int x = 0; x < width; ++x)
4068         for (int y = 0; y < height; ++y)
4069         {
4070                 const auto value = image.getPixel(x, y);
4071                 for (int c = 0; c < numChannels; ++c)
4072                 {
4073                         if (value[c] == 0.0f)
4074                                 outColor[c] = kFalseComponent;
4075                         else if (value[c] == 1.0f)
4076                                 outColor[c] = kTrueComponent;
4077                         else
4078                                 DE_ASSERT(false);
4079                 }
4080                 access.setPixel(outColor, x, y);
4081         }
4082
4083         return result;
4084 }
4085
4086 std::unique_ptr<tcu::TextureLevel> renderColorImageForLog (const vector<PixelValue>& reference, const UVec2& targetSize, int numChannels)
4087 {
4088         const tcu::TextureFormat                        loggableFormat  {tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8};
4089         const int                                                       width                   = static_cast<int>(targetSize.x());
4090         const int                                                       height                  = static_cast<int>(targetSize.y());
4091         std::unique_ptr<tcu::TextureLevel>      result                  {new tcu::TextureLevel{loggableFormat, width, height}};
4092         auto                                                            access                  = result->getAccess();
4093         tcu::Vec4                                                       outColor                = kDefaultColorForLog;
4094
4095         for (int x = 0; x < width; ++x)
4096         for (int y = 0; y < height; ++y)
4097         {
4098                 const int index = x + y * width;
4099                 for (int c = 0; c < numChannels; ++c)
4100                 {
4101                         const auto maybeValue = reference[index].getValue(c);
4102                         if (maybeValue)
4103                                 outColor[c] = ((*maybeValue) ? kTrueComponent : kFalseComponent);
4104                         else
4105                                 outColor[c] = ((((x / 3) % 2) == ((y / 3) % 2)) ? kUnsetComponentLow : kUnsetComponentHigh);
4106                 }
4107                 access.setPixel(outColor, x, y);
4108         }
4109
4110         return result;
4111 }
4112
4113 bool verifyDepthAttachment (const vector<PixelValue>&           reference,
4114                                                         const ConstPixelBufferAccess&   result,
4115                                                         const PixelBufferAccess&                errorImage,
4116                                                         const DepthValuesArray&                 depthValues,
4117                                                         float                                                   epsilon)
4118 {
4119         const Vec4      red             (1.0f, 0.0f, 0.0f, 1.0f);
4120         const Vec4      green   (0.0f, 1.0f, 0.0f, 1.0f);
4121         bool            ok              = true;
4122
4123         DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4124         DE_ASSERT(result.getWidth() == errorImage.getWidth());
4125         DE_ASSERT(result.getHeight() == errorImage.getHeight());
4126
4127         for (int y = 0; y < result.getHeight(); y++)
4128         for (int x = 0; x < result.getWidth(); x++)
4129         {
4130                 bool pixelOk = true;
4131
4132                 const float                     resultDepth             = result.getPixDepth(x, y);
4133                 const PixelValue&       referenceValue  = reference[x + y * result.getWidth()];
4134                 const Maybe<bool>       maybeValue              = referenceValue.getValue(0);
4135
4136                 if (maybeValue)
4137                 {
4138                         const bool value = *maybeValue;
4139
4140                         if ((value && !depthsEqual(resultDepth, float(depthValues[1]) / 255.0f, epsilon))
4141                                 || (!value && !depthsEqual(resultDepth, float(depthValues[0]) / 255.0f, epsilon)))
4142                                 pixelOk = false;
4143                 }
4144
4145                 if (!pixelOk)
4146                 {
4147                         errorImage.setPixel(red, x, y);
4148                         ok = false;
4149                 }
4150                 else
4151                         errorImage.setPixel(green, x, y);
4152         }
4153
4154         return ok;
4155 }
4156
4157 bool verifyStencilAttachment (const vector<PixelValue>&         reference,
4158                                                           const ConstPixelBufferAccess& result,
4159                                                           const PixelBufferAccess&              errorImage)
4160 {
4161         const Vec4      red             (1.0f, 0.0f, 0.0f, 1.0f);
4162         const Vec4      green   (0.0f, 1.0f, 0.0f, 1.0f);
4163         bool            ok              = true;
4164
4165         DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4166         DE_ASSERT(result.getWidth() == errorImage.getWidth());
4167         DE_ASSERT(result.getHeight() == errorImage.getHeight());
4168
4169         for (int y = 0; y < result.getHeight(); y++)
4170         for (int x = 0; x < result.getWidth(); x++)
4171         {
4172                 bool pixelOk = true;
4173
4174                 const deUint32          resultStencil   = result.getPixStencil(x, y);
4175                 const PixelValue&       referenceValue  = reference[x + y * result.getWidth()];
4176                 const Maybe<bool>       maybeValue              = referenceValue.getValue(1);
4177
4178                 if (maybeValue)
4179                 {
4180                         const bool value = *maybeValue;
4181
4182                         if ((value && (resultStencil != 0xFFu))
4183                                 || (!value && resultStencil != 0x0u))
4184                                 pixelOk = false;
4185                 }
4186
4187                 if (!pixelOk)
4188                 {
4189                         errorImage.setPixel(red, x, y);
4190                         ok = false;
4191                 }
4192                 else
4193                         errorImage.setPixel(green, x, y);
4194         }
4195
4196         return ok;
4197 }
4198
4199 bool logAndVerifyImages (TestLog&                                                                                       log,
4200                                                  const DeviceInterface&                                                         vk,
4201                                                  VkDevice                                                                                       device,
4202                                                  const vector<de::SharedPtr<AttachmentResources> >&     attachmentResources,
4203                                                  const vector<bool>&                                                            attachmentIsLazy,
4204                                                  const RenderPass&                                                                      renderPassInfo,
4205                                                  const vector<Maybe<VkClearValue> >&                            renderPassClearValues,
4206                                                  const vector<Maybe<VkClearValue> >&                            imageClearValues,
4207                                                  const vector<SubpassRenderInfo>&                                       subpassRenderInfo,
4208                                                  const UVec2&                                                                           targetSize,
4209                                                  const TestConfig&                                                                      config)
4210 {
4211         vector<vector<PixelValue> >     referenceValues;
4212         vector<tcu::TextureLevel>       referenceAttachments;
4213         bool                                            isOk                                    = true;
4214
4215         log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;
4216
4217         renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize, config.drawStartNdx, config.depthValues);
4218         renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo, config.depthValues);
4219
4220         for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4221         {
4222                 if (!attachmentIsLazy[attachmentNdx])
4223                 {
4224                         bool                                            attachmentOK    = true;
4225                         const Attachment                        attachment              = renderPassInfo.getAttachments()[attachmentNdx];
4226                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
4227
4228                         if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
4229                         {
4230                                 const tcu::TextureFormat        depthFormat                     = getDepthCopyFormat(attachment.getFormat());
4231                                 void* const                                     depthPtr                        = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
4232
4233                                 const tcu::TextureFormat        stencilFormat           = getStencilCopyFormat(attachment.getFormat());
4234                                 void* const                                     stencilPtr                      = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
4235
4236                                 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
4237                                 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getSecondaryResultMemory());
4238
4239                                 {
4240                                         bool                                                    depthOK                         = true;
4241                                         bool                                                    stencilOK                       = true;
4242                                         const ConstPixelBufferAccess    depthAccess                     (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
4243                                         const ConstPixelBufferAccess    stencilAccess           (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
4244                                         tcu::TextureLevel                               depthErrorImage         (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
4245                                         tcu::TextureLevel                               stencilErrorImage       (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
4246
4247                                         if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
4248                                                 && !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess(), config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
4249                                         {
4250                                                 depthOK = false;
4251                                         }
4252
4253                                         if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
4254                                                 && !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess()))
4255                                         {
4256                                                 stencilOK = false;
4257                                         }
4258
4259                                         if (!depthOK || !stencilOK)
4260                                         {
4261                                                 const auto attachmentNdxStr = de::toString(attachmentNdx);
4262
4263                                                 // Output images.
4264                                                 log << TestLog::ImageSet("OutputAttachments" + attachmentNdxStr, "Output depth and stencil attachments " + attachmentNdxStr);
4265                                                 log << TestLog::Image("Attachment" + attachmentNdxStr + "Depth", "Attachment " + attachmentNdxStr + " Depth", depthAccess);
4266                                                 log << TestLog::Image("Attachment" + attachmentNdxStr + "Stencil", "Attachment " + attachmentNdxStr + " Stencil", stencilAccess);
4267                                                 log << TestLog::EndImageSet;
4268
4269                                                 // Reference images. These will be logged as image sets due to having depth and stencil aspects.
4270                                                 log << TestLog::Image("AttachmentReferences" + attachmentNdxStr, "Reference images " + attachmentNdxStr, referenceAttachments[attachmentNdx].getAccess());
4271
4272                                                 // Error masks.
4273                                                 log << TestLog::ImageSet("ErrorMasks" + attachmentNdxStr, "Error masks " + attachmentNdxStr);
4274                                                 if (!depthOK)
4275                                                         log << TestLog::Image("DepthAttachmentError" + attachmentNdxStr, "Depth Attachment Error " + attachmentNdxStr, depthErrorImage.getAccess());
4276                                                 if (!stencilOK)
4277                                                         log << TestLog::Image("StencilAttachmentError" + attachmentNdxStr, "Stencil Attachment Error " + attachmentNdxStr, stencilErrorImage.getAccess());
4278                                                 log << TestLog::EndImageSet;
4279
4280                                                 attachmentOK = false;
4281                                         }
4282                                 }
4283                         }
4284                         else
4285                         {
4286                                 void* const     ptr     = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
4287
4288                                 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
4289
4290                                 bool                                                    depthOK         = true;
4291                                 bool                                                    stencilOK       = true;
4292                                 bool                                                    colorOK         = true;
4293                                 const ConstPixelBufferAccess    access          (format, targetSize.x(), targetSize.y(), 1, ptr);
4294                                 tcu::TextureLevel                               errorImage      (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
4295
4296                                 if (tcu::hasDepthComponent(format.order))
4297                                 {
4298                                         if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
4299                                                 && !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(), config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
4300                                         {
4301                                                 depthOK = false;
4302                                         }
4303                                 }
4304                                 else if (tcu::hasStencilComponent(format.order))
4305                                 {
4306                                         if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
4307                                                 && !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
4308                                         {
4309                                                 stencilOK = false;
4310                                         }
4311                                 }
4312                                 else
4313                                 {
4314                                         if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
4315                                                 && !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(), config.useFormatCompCount))
4316                                         {
4317                                                 colorOK = false;
4318                                         }
4319                                 }
4320
4321                                 if (!depthOK || !stencilOK || !colorOK)
4322                                 {
4323                                         log << TestLog::ImageSet("TestImages", "Output attachment, reference image and error mask");
4324                                         if (!depthOK || !stencilOK)
4325                                         {
4326                                                 // Log without conversions.
4327                                                 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
4328                                                 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
4329                                         }
4330                                         else
4331                                         {
4332                                                 // Convert color images to better reflect test status and output in any format.
4333                                                 const auto numChannels          = tcu::getNumUsedChannels(access.getFormat().order);
4334                                                 const auto attachmentForLog     = renderColorImageForLog(access, numChannels);
4335                                                 const auto referenceForLog      = renderColorImageForLog(referenceValues[attachmentNdx], targetSize, numChannels);
4336
4337                                                 log << TestLog::Message << "Check the attachment formats and test data to verify which components affect the test result." << TestLog::EndMessage;
4338                                                 log << TestLog::Message << "In the reference image, unset pixel components are marked with a 3x3 grid storing values 0.0 and 0.25, pixel components set to false are stored as 0.5 and pixel components set to true are stored as 1.0." << TestLog::EndMessage;
4339                                                 log << TestLog::Message << "Output attachment pixel components are always set to 0.5 or 1.0 but may not be taken into account if not set in the reference image." << TestLog::EndMessage;
4340
4341                                                 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), attachmentForLog->getAccess());
4342                                                 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceForLog->getAccess());
4343                                         }
4344                                         log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
4345                                         log << TestLog::EndImageSet;
4346
4347                                         attachmentOK = false;
4348                                 }
4349                         }
4350
4351                         if (!attachmentOK)
4352                                 isOk = false;
4353                 }
4354         }
4355
4356         return isOk;
4357 }
4358
4359 std::string getInputAttachmentType (VkFormat vkFormat)
4360 {
4361         const tcu::TextureFormat                format                  = mapVkFormat(vkFormat);
4362         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
4363
4364         switch (channelClass)
4365         {
4366                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
4367                         return "isubpassInput";
4368
4369                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
4370                         return "usubpassInput";
4371
4372                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
4373                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
4374                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
4375                         return "subpassInput";
4376
4377                 default:
4378                         DE_FATAL("Unknown channel class");
4379                         return "";
4380         }
4381 }
4382
4383 std::string getAttachmentType (VkFormat vkFormat, deBool useFormatCompCount)
4384 {
4385         const tcu::TextureFormat                format                  = mapVkFormat(vkFormat);
4386         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
4387         const size_t                                    componentCount  = (size_t)tcu::getNumUsedChannels(format.order);
4388
4389         switch (channelClass)
4390         {
4391                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
4392                         if (useFormatCompCount)
4393                                 return (componentCount == 1 ? "int" : "ivec" + de::toString(componentCount));
4394                         else
4395                                 return "ivec4";
4396
4397                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
4398                         if (useFormatCompCount)
4399                                 return (componentCount == 1 ? "uint" : "uvec" + de::toString(componentCount));
4400                         else
4401                                 return "uvec4";
4402
4403                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
4404                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
4405                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
4406                         if (useFormatCompCount)
4407                                 return (componentCount == 1 ? "float" : "vec" + de::toString(componentCount));
4408                         else
4409                                 return "vec4";
4410
4411                 default:
4412                         DE_FATAL("Unknown channel class");
4413                         return "";
4414         }
4415 }
4416
4417 void createTestShaders (SourceCollections& dst, TestConfig config)
4418 {
4419         if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
4420         {
4421                 const vector<Subpass>&  subpasses       = config.renderPass.getSubpasses();
4422
4423                 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4424                 {
4425                         const Subpass&          subpass                                 = subpasses[subpassNdx];
4426                         deUint32                        inputAttachmentBinding  = 0;
4427                         std::ostringstream      vertexShader;
4428                         std::ostringstream      fragmentShader;
4429
4430                         vertexShader << "#version 310 es\n"
4431                                                  << "layout(location = 0) in highp vec2 a_position;\n"
4432                                                  << "void main (void) {\n"
4433                                                  << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
4434                                                  << "}\n";
4435
4436                         fragmentShader << "#version 310 es\n"
4437                                                    << "precision highp float;\n";
4438
4439                         bool hasAnyDepthFormats = false;
4440
4441                         for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4442                         {
4443                                 const deUint32                          attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
4444                                 const VkImageLayout                     layout                  = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4445                                 const Attachment                        attachment              = config.renderPass.getAttachments()[attachmentIndex];
4446                                 const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
4447                                 const bool                                      isDepthFormat   = tcu::hasDepthComponent(format.order);
4448                                 const bool                                      isStencilFormat = tcu::hasStencilComponent(format.order);
4449
4450                                 if (isDepthFormat || isStencilFormat)
4451                                 {
4452                                         if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4453                                         {
4454                                                 hasAnyDepthFormats = true;
4455                                                 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
4456                                                 inputAttachmentBinding++;
4457                                         }
4458
4459                                         if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4460                                         {
4461                                                 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
4462                                                 inputAttachmentBinding++;
4463                                         }
4464                                 }
4465                                 else
4466                                 {
4467                                         const std::string attachmentType = getInputAttachmentType(attachment.getFormat());
4468
4469                                         fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n";
4470                                         inputAttachmentBinding++;
4471                                 }
4472                         }
4473
4474                         for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4475                         {
4476                                 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[getAttachmentNdx(subpass.getColorAttachments(), attachmentNdx)].getFormat(), config.useFormatCompCount);
4477                                 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
4478                         }
4479
4480                         if (hasAnyDepthFormats)
4481                                 fragmentShader << "\nbool depthsEqual(float a, float b, float epsilon) {\n"
4482                                                                 << "\treturn abs(a - b) <= epsilon;\n}\n\n";
4483
4484                         fragmentShader << "void main (void) {\n";
4485
4486                         if (subpass.getInputAttachments().empty())
4487                         {
4488                                 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4489                                 {
4490                                         const deUint32                          attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
4491
4492                                         if (attachmentIndex == VK_ATTACHMENT_UNUSED)
4493                                                 continue;
4494
4495                                         const Attachment                        attachment              = config.renderPass.getAttachments()[attachmentIndex];
4496                                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
4497                                         const size_t                            componentCount  = config.useFormatCompCount ? (size_t)tcu::getNumUsedChannels(format.order) : 4;
4498                                         const std::string                       attachmentType  = getAttachmentType(attachment.getFormat(), config.useFormatCompCount);
4499
4500                                         fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(" << attachmentType + "(";
4501
4502                                         for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4503                                         {
4504                                                 const size_t    index   = subpassNdx + attachmentIndex + compNdx;
4505                                                 const BoolOp    op              = boolOpFromIndex(index);
4506
4507                                                 if (compNdx > 0)
4508                                                         fragmentShader << ",\n\t\t";
4509
4510                                                 fragmentShader  << "((int(gl_FragCoord.x) % 2 == " << (index % 2)
4511                                                                                 << ") " << boolOpToString(op) << " ("
4512                                                                                 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4513                                                                                 << ") ? 1.0 : 0.0)";
4514                                         }
4515
4516                                         fragmentShader << "));\n";
4517                                 }
4518
4519                                 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4520                                         && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4521                                         && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4522                                 {
4523                                         const size_t    index   = subpassNdx + 1;
4524                                         const BoolOp    op              = boolOpFromIndex(index);
4525
4526                                         fragmentShader  << "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2)
4527                                                                         << ") " << boolOpToString(op) << " ("
4528                                                                         << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4529                                                                         << ") ? " << deUint32(config.depthValues[1]) << ".0f/255.0f : " << deUint32(config.depthValues[0]) << ".0f/255.0f);\n";
4530                                 }
4531                         }
4532                         else
4533                         {
4534                                 size_t  inputComponentCount             = 0;
4535                                 size_t  outputComponentCount    = 0;
4536
4537                                 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4538                                 {
4539                                         const deUint32                          attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
4540                                         const VkImageLayout                     layout                  = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4541                                         const Attachment                        attachment              = config.renderPass.getAttachments()[attachmentIndex];
4542                                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
4543                                         const size_t                            componentCount  = (size_t)tcu::getNumUsedChannels(format.order);
4544
4545                                         if (layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4546                                                 inputComponentCount += 1;
4547                                         else if (layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4548                                                 inputComponentCount += 1;
4549                                         else
4550                                                 inputComponentCount += componentCount;
4551                                 }
4552
4553                                 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4554                                 {
4555                                         const deUint32                          attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
4556                                         const Attachment                        attachment              = config.renderPass.getAttachments()[attachmentIndex];
4557                                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
4558                                         const size_t                            componentCount  = (size_t)tcu::getNumUsedChannels(format.order);
4559
4560                                         outputComponentCount += componentCount;
4561                                 }
4562
4563                                 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4564                                         && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4565                                         && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4566                                 {
4567                                         outputComponentCount++;
4568                                 }
4569
4570                                 if (outputComponentCount > 0)
4571                                 {
4572                                         const size_t inputsPerOutput = inputComponentCount >= outputComponentCount
4573                                                                                                         ? ((inputComponentCount / outputComponentCount)
4574                                                                                                                 + ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0))
4575                                                                                                         : 1;
4576
4577                                         fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n";
4578
4579                                         if (outputComponentCount > 0)
4580                                                 fragmentShader << "\tbool outputs[" << outputComponentCount << "];\n";
4581
4582                                         size_t inputValueNdx = 0;
4583
4584                                         for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4585                                         {
4586                                                 const char* const       components[]    =
4587                                                 {
4588                                                         "x", "y", "z", "w"
4589                                                 };
4590                                                 const deUint32                          attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
4591                                                 const VkImageLayout                     layout                  = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4592                                                 const Attachment                        attachment              = config.renderPass.getAttachments()[attachmentIndex];
4593                                                 const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
4594                                                 const size_t                            componentCount  = (size_t)tcu::getNumUsedChannels(format.order);
4595                                                 const bool                                      isDepthFormat   = tcu::hasDepthComponent(format.order);
4596                                                 const bool                                      isStencilFormat = tcu::hasStencilComponent(format.order);
4597
4598                                                 if (isDepthFormat || isStencilFormat)
4599                                                 {
4600                                                         if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4601                                                         {
4602                                                                 fragmentShader << "\tinputs[" << inputValueNdx << "] = depthsEqual(" << deUint32(config.depthValues[1]) <<
4603                                                                         ".0f/255.0f, float(subpassLoad(i_depth" << attachmentNdx << ").x), " <<
4604                                                                         std::fixed << std::setprecision(12) << requiredDepthEpsilon(attachment.getFormat()) << ");\n";
4605                                                                 inputValueNdx++;
4606                                                         }
4607
4608                                                         if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4609                                                         {
4610                                                                 fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n";
4611                                                                 inputValueNdx++;
4612                                                         }
4613                                                 }
4614                                                 else
4615                                                 {
4616                                                         for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4617                                                         {
4618                                                                 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n";
4619                                                                 inputValueNdx++;
4620                                                         }
4621                                                 }
4622                                         }
4623
4624                                         size_t outputValueNdx = 0;
4625
4626                                         for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4627                                         {
4628                                                 const deUint32                          attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
4629                                                 const Attachment                        attachment              = config.renderPass.getAttachments()[attachmentIndex];
4630                                                 const std::string                       attachmentType  = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat(), config.useFormatCompCount);
4631                                                 const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
4632                                                 const size_t                            componentCount  = (size_t)tcu::getNumUsedChannels(format.order);
4633
4634                                                 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4635                                                 {
4636                                                         const size_t    index   = subpassNdx + attachmentIndex + outputValueNdx;
4637                                                         const BoolOp    op              = boolOpFromIndex(index);
4638
4639                                                         fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
4640                                                                                         << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
4641                                                                                         << ") " << boolOpToString(op) << " ("
4642                                                                                         << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4643                                                                                         << ");\n";
4644
4645                                                         for (size_t i = 0; i < inputsPerOutput; i++)
4646                                                                 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" <<  ((outputValueNdx + compNdx) * inputsPerOutput + i) %  inputComponentCount << "];\n";
4647                                                 }
4648
4649                                                 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";
4650
4651                                                 for (size_t compNdx = 0; compNdx < (config.useFormatCompCount ? componentCount : 4); compNdx++)
4652                                                 {
4653                                                         if (compNdx > 0)
4654                                                                 fragmentShader << ", ";
4655
4656                                                         if (compNdx < componentCount)
4657                                                                 fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
4658                                                         else
4659                                                                 fragmentShader << "0";
4660                                                 }
4661
4662                                                 outputValueNdx += componentCount;
4663
4664                                                 fragmentShader << ");\n";
4665                                         }
4666
4667                                         if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4668                                                 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4669                                                 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4670                                         {
4671                                                 const deUint32  attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
4672                                                 const size_t    index                   = subpassNdx + attachmentIndex;
4673                                                 const BoolOp    op                              = boolOpFromIndex(index);
4674
4675                                                 fragmentShader << "\toutputs[" << outputValueNdx << "] = "
4676                                                                                 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
4677                                                                                 << ") " << boolOpToString(op) << " ("
4678                                                                                 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4679                                                                                 << ");\n";
4680
4681                                                 for (size_t i = 0; i < inputsPerOutput; i++)
4682                                                         fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" <<  (outputValueNdx * inputsPerOutput + i) %  inputComponentCount << "];\n";
4683
4684                                                 fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? " << deUint32(config.depthValues[1]) << ".0f/255.0f : " << deUint32(config.depthValues[0]) << ".0f/255.0f;\n";
4685                                         }
4686                                 }
4687                         }
4688
4689                         fragmentShader << "}\n";
4690
4691                         dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
4692                         dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
4693                 }
4694         }
4695 }
4696
4697 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
4698 {
4699         bool lastAttachmentWasLazy      = false;
4700
4701         for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4702         {
4703                 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
4704                         && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
4705                         && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
4706                         && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
4707                 {
4708                         if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
4709                         {
4710                                 attachmentIsLazy.push_back(true);
4711
4712                                 lastAttachmentWasLazy   = true;
4713                         }
4714                         else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
4715                         {
4716                                 attachmentIsLazy.push_back(false);
4717                                 lastAttachmentWasLazy = false;
4718                         }
4719                         else
4720                                 DE_FATAL("Unknown imageMemory");
4721                 }
4722                 else
4723                         attachmentIsLazy.push_back(false);
4724         }
4725 }
4726
4727 enum AttachmentRefType
4728 {
4729         ATTACHMENTREFTYPE_COLOR,
4730         ATTACHMENTREFTYPE_DEPTH_STENCIL,
4731         ATTACHMENTREFTYPE_INPUT,
4732         ATTACHMENTREFTYPE_RESOLVE,
4733 };
4734
4735 VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout)
4736 {
4737         switch (layout)
4738         {
4739                 case VK_IMAGE_LAYOUT_GENERAL:
4740                 case VK_IMAGE_LAYOUT_PREINITIALIZED:
4741                         return 0;
4742
4743                 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
4744                         return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4745
4746                 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
4747                 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
4748                         return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4749
4750                 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
4751                         return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4752
4753                 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
4754                         return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4755
4756                 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
4757                         return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4758
4759                 default:
4760                         DE_FATAL("Unexpected image layout");
4761                         return 0;
4762         }
4763 }
4764
4765 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
4766 {
4767         for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
4768         {
4769                 const deUint32 attachment = references[referenceNdx].getAttachment();
4770
4771                 if (attachment != VK_ATTACHMENT_UNUSED)
4772                 {
4773                         VkImageUsageFlags usage;
4774
4775                         switch (refType)
4776                         {
4777                                 case ATTACHMENTREFTYPE_COLOR:
4778                                 case ATTACHMENTREFTYPE_RESOLVE:
4779                                         usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4780                                         break;
4781
4782                                 case ATTACHMENTREFTYPE_DEPTH_STENCIL:
4783                                         usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4784                                         break;
4785
4786                                 case ATTACHMENTREFTYPE_INPUT:
4787                                         usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4788                                         break;
4789
4790                                 default:
4791                                         DE_FATAL("Unexpected attachment reference type");
4792                                         usage = 0;
4793                                         break;
4794                         }
4795
4796                         attachmentImageUsage[attachment] |= usage;
4797                 }
4798         }
4799 }
4800
4801 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
4802 {
4803         if (!references.empty())
4804         {
4805                 getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
4806         }
4807 }
4808
4809 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
4810 {
4811         attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
4812
4813         for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
4814         {
4815                 const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];
4816
4817                 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
4818                 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
4819                 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
4820                 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
4821         }
4822
4823         for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4824         {
4825                 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
4826                 const VkFormatProperties        formatProperties        = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
4827                 const VkFormatFeatureFlags      supportedFeatures       = formatProperties.optimalTilingFeatures;
4828
4829                 if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
4830                         attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
4831
4832                 if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
4833                         attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
4834
4835                 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
4836                 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
4837
4838                 if (!attachmentIsLazy[attachmentNdx])
4839                 {
4840                         if (clearValues[attachmentNdx])
4841                                 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4842
4843                         attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4844                 }
4845                 else
4846                 {
4847                         const VkImageUsageFlags allowedTransientBits = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
4848
4849                         attachmentImageUsage[attachmentNdx] &= allowedTransientBits;
4850                         attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
4851                 }
4852         }
4853 }
4854
4855 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
4856 {
4857         bool lastSubpassWasSecondary = false;
4858
4859         for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4860         {
4861                 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
4862                 {
4863                         subpassIsSecondary.push_back(true);
4864                         lastSubpassWasSecondary = true;
4865                 }
4866                 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
4867                 {
4868                         subpassIsSecondary.push_back(false);
4869                         lastSubpassWasSecondary = false;
4870                 }
4871                 else
4872                         DE_FATAL("Unknown commandBuffer");
4873         }
4874 }
4875
4876 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy, deBool useFormatCompCount, const DepthValuesArray& depthValues)
4877 {
4878         for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4879         {
4880                 if (!isLazy[attachmentNdx])
4881                         clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
4882                 else
4883                         clearValues.push_back(tcu::Nothing);
4884         }
4885 }
4886
4887 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, deBool useFormatCompCount, const DepthValuesArray& depthValues)
4888 {
4889         for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4890         {
4891                 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
4892                         || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
4893                 {
4894                         clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
4895                 }
4896                 else
4897                         clearValues.push_back(tcu::Nothing);
4898         }
4899 }
4900
4901 void logSubpassRenderInfo (TestLog& log, const SubpassRenderInfo& info, TestConfig config)
4902 {
4903         log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
4904
4905         if (info.isSecondary())
4906                 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
4907         else
4908                 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
4909
4910         for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
4911         {
4912                 const ColorClear&       colorClear      = info.getColorClears()[attachmentNdx];
4913
4914                 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
4915                         << ". Offset: " << colorClear.getOffset()
4916                         << ", Size: " << colorClear.getSize()
4917                         << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor(), config.useFormatCompCount) << TestLog::EndMessage;
4918         }
4919
4920         if (info.getDepthStencilClear())
4921         {
4922                 const DepthStencilClear&        depthStencilClear       = *info.getDepthStencilClear();
4923
4924                 log << TestLog::Message << "Clearing depth stencil attachment"
4925                         << ". Offset: " << depthStencilClear.getOffset()
4926                         << ", Size: " << depthStencilClear.getSize()
4927                         << ", Depth: " << depthStencilClear.getDepth()
4928                         << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
4929         }
4930
4931         if (info.getRenderQuad())
4932         {
4933                 const RenderQuad&       renderQuad      = *info.getRenderQuad();
4934
4935                 log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
4936         }
4937 }
4938
4939 void logTestCaseInfo (TestLog&                                                          log,
4940                                           const TestConfig&                                             config,
4941                                           const vector<bool>&                                   attachmentIsLazy,
4942                                           const vector<Maybe<VkClearValue> >&   imageClearValues,
4943                                           const vector<Maybe<VkClearValue> >&   renderPassClearValues,
4944                                           const vector<SubpassRenderInfo>&              subpassRenderInfo)
4945 {
4946         const RenderPass&       renderPass      = config.renderPass;
4947
4948         logRenderPassInfo(log, renderPass);
4949
4950         DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
4951         DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
4952         DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
4953
4954         log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
4955         log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
4956
4957         for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
4958         {
4959                 const tcu::ScopedLogSection     section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
4960
4961                 if (attachmentIsLazy[attachmentNdx])
4962                         log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
4963
4964                 if (imageClearValues[attachmentNdx])
4965                         log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
4966                                         *imageClearValues[attachmentNdx], config.useFormatCompCount) << " before rendering." << TestLog::EndMessage;
4967
4968                 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
4969                         log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
4970                                         *renderPassClearValues[attachmentNdx], config.useFormatCompCount) << " in the beginning of the render pass." << TestLog::EndMessage;
4971         }
4972
4973         for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4974         {
4975                 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
4976
4977                 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx], config);
4978         }
4979 }
4980
4981 float roundToViewport (float x, deUint32 offset, deUint32 size)
4982 {
4983         const float             origin  = (float)(offset) + ((float(size) / 2.0f));
4984         const float             p               = (float)(size) / 2.0f;
4985         const deInt32   xi              = deRoundFloatToInt32(origin + (p * x));
4986
4987         return (((float)xi) - origin) / p;
4988 }
4989
4990 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
4991 {
4992         const TestConfig::CommandBufferTypes    commandBuffer                   = config.commandBufferTypes;
4993         const vector<Subpass>&                                  subpasses                               = renderPass.getSubpasses();
4994         bool                                                                    lastSubpassWasSecondary = false;
4995
4996         for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
4997         {
4998                 const Subpass&                          subpass                         = subpasses[subpassNdx];
4999                 const bool                                      subpassIsSecondary      = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
5000                                                                                                                 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
5001                 const bool                                      omitBlendState          = subpass.getOmitBlendState();
5002                 const UVec2                                     viewportSize            ((config.renderSize * UVec2(2)) / UVec2(3));
5003                 const UVec2                                     viewportOffset          (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
5004                                                                                                                  config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
5005
5006                 vector<ColorClear>                      colorClears;
5007                 Maybe<DepthStencilClear>        depthStencilClear;
5008                 Maybe<RenderQuad>                       renderQuad;
5009
5010                 lastSubpassWasSecondary         = subpassIsSecondary;
5011
5012                 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
5013                 {
5014                         const vector<AttachmentReference>&      colorAttachments        = subpass.getColorAttachments();
5015
5016                         for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
5017                         {
5018                                 const AttachmentReference&      attachmentRef   = colorAttachments[attachmentRefNdx];
5019                                 const Attachment&                       attachment              = renderPass.getAttachments()[attachmentRef.getAttachment()];
5020                                 const UVec2                                     size                    ((viewportSize * UVec2(2)) / UVec2(3));
5021                                 const UVec2                                     offset                  (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
5022                                                                                                                          viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
5023                                 const VkClearColorValue         color                   = randomColorClearValue(attachment, rng, config.useFormatCompCount);
5024
5025                                 colorClears.push_back(ColorClear(offset, size, color));
5026                         }
5027
5028                         if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
5029                         {
5030                                 const Attachment&       attachment      = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
5031                                 const UVec2                     size            ((viewportSize * UVec2(2)) / UVec2(3));
5032                                 const UVec2                     offset          (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
5033                                                                                                  viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
5034                                 const VkClearValue      value           = randomClearValue(attachment, rng, config.useFormatCompCount, config.depthValues);
5035
5036                                 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
5037                         }
5038                 }
5039
5040                 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
5041                 {
5042                         const float     w       = (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
5043                         const float     h       = (subpassNdx % 2) == 0 ? 1.25f : 1.0f;
5044
5045                         const float     x0      = roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
5046                         const float     x1      = roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());
5047
5048                         const float     y0      = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
5049                         const float     y1      = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());
5050
5051                         renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
5052                 }
5053
5054                 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, config.drawStartNdx, subpassIsSecondary, omitBlendState, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
5055         }
5056 }
5057
5058 void checkTextureFormatSupport (TestLog&                                        log,
5059                                                                 const InstanceInterface&        vk,
5060                                                                 VkPhysicalDevice                        device,
5061                                                                 const vector<Attachment>&       attachments)
5062 {
5063         bool supported = true;
5064
5065         for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
5066         {
5067                 const Attachment&                       attachment                                      = attachments[attachmentNdx];
5068                 const tcu::TextureFormat        format                                          = mapVkFormat(attachment.getFormat());
5069                 const bool                                      isDepthOrStencilAttachment      = hasDepthComponent(format.order) || hasStencilComponent(format.order);
5070                 const VkFormatFeatureFlags      flags                                           = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
5071                 VkFormatProperties                      properties;
5072
5073                 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
5074
5075                 if ((properties.optimalTilingFeatures & flags) != flags)
5076                 {
5077                         supported = false;
5078                         log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
5079                 }
5080         }
5081
5082         if (!supported)
5083                 TCU_THROW(NotSupportedError, "Format not supported");
5084 }
5085
5086 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
5087 {
5088         const UVec2                                                     targetSize                      = config.targetSize;
5089         const UVec2                                                     renderPos                       = config.renderPos;
5090         const UVec2                                                     renderSize                      = config.renderSize;
5091         const RenderPass&                                       renderPassInfo          = config.renderPass;
5092
5093         TestLog&                                                        log                                     = context.getTestContext().getLog();
5094         de::Random                                                      rng                                     (config.seed);
5095
5096         vector<bool>                                            attachmentIsLazy;
5097         vector<VkImageUsageFlags>                       attachmentImageUsage;
5098         vector<Maybe<VkClearValue> >            imageClearValues;
5099         vector<Maybe<VkClearValue> >            renderPassClearValues;
5100
5101         vector<bool>                                            subpassIsSecondary;
5102         vector<SubpassRenderInfo>                       subpassRenderInfo;
5103
5104         if (config.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
5105                 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
5106
5107         if (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
5108                 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
5109
5110         if (config.allocationKind == ALLOCATION_KIND_DEDICATED)
5111         {
5112                 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
5113                         TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
5114         }
5115
5116         if (!renderPassInfo.getInputAspects().empty())
5117         {
5118                 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
5119                         TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported.");
5120         }
5121
5122         {
5123                 bool requireDepthStencilLayout = false;
5124
5125                 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
5126                 {
5127                         if (renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5128                                 || renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
5129                                 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5130                                 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5131                         {
5132                                 requireDepthStencilLayout = true;
5133                                 break;
5134                         }
5135                 }
5136
5137                 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size() && !requireDepthStencilLayout; subpassNdx++)
5138                 {
5139                         const Subpass& subpass (renderPassInfo.getSubpasses()[subpassNdx]);
5140
5141                         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
5142                         {
5143                                 if (subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5144                                         || subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5145                                 {
5146                                         requireDepthStencilLayout = true;
5147                                         break;
5148                                 }
5149                         }
5150
5151                         for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
5152                         {
5153                                 if (subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5154                                         || subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5155                                 {
5156                                         requireDepthStencilLayout = true;
5157                                         break;
5158                                 }
5159                         }
5160
5161                         for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
5162                         {
5163                                 if (subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5164                                         || subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5165                                 {
5166                                         requireDepthStencilLayout = true;
5167                                         break;
5168                                 }
5169                         }
5170
5171                         if (subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5172                                 || subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5173                         {
5174                                 requireDepthStencilLayout = true;
5175                                 break;
5176                         }
5177                 }
5178
5179                 if (requireDepthStencilLayout && !context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
5180                         TCU_THROW(NotSupportedError, "VK_KHR_maintenance2 is not supported");
5181         }
5182
5183         initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
5184         initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy, config.useFormatCompCount, config.depthValues);
5185         initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
5186         initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments(), config.useFormatCompCount, config.depthValues);
5187
5188         initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
5189         initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
5190
5191         logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
5192
5193         checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
5194
5195         {
5196                 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
5197
5198                 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
5199
5200                 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
5201                 {
5202                          if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
5203                                  TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
5204                 }
5205         }
5206
5207         {
5208                 const InstanceInterface&                                        vki                                                                     = context.getInstanceInterface();
5209                 const VkPhysicalDevice&                                         physDevice                                                      = context.getPhysicalDevice();
5210                 const VkDevice                                                          device                                                          = context.getDevice();
5211                 const DeviceInterface&                                          vk                                                                      = context.getDeviceInterface();
5212                 const VkQueue                                                           queue                                                           = context.getUniversalQueue();
5213                 const deUint32                                                          queueIndex                                                      = context.getUniversalQueueFamilyIndex();
5214                 Allocator&                                                                      allocator                                                       = context.getDefaultAllocator();
5215
5216                 const Unique<VkCommandPool>                                     commandBufferPool                                       (createCommandPool(vk, device, 0, queueIndex));
5217                 const Unique<VkCommandBuffer>                           initializeImagesCommandBuffer           (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5218                 const Unique<VkCommandBuffer>                           renderCommandBuffer                                     (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5219                 const Unique<VkCommandBuffer>                           readImagesToBuffersCommandBuffer        (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5220
5221                 vector<de::SharedPtr<AttachmentResources> >     attachmentResources;
5222                 vector<de::SharedPtr<SubpassRenderer> >         subpassRenderers;
5223                 vector<VkImage>                                                         attachmentImages;
5224                 vector<VkImageView>                                                     attachmentViews;
5225                 vector<pair<VkImageView, VkImageView> >         inputAttachmentViews;
5226
5227                 Move<VkRenderPass> renderPass;
5228                 if (config.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
5229                         renderPass = createRenderPass(vk, device, renderPassInfo, config.groupParams->renderingType);
5230
5231                 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
5232                 {
5233                         const Attachment&       attachmentInfo  = renderPassInfo.getAttachments()[attachmentNdx];
5234
5235                         attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind)));
5236                         attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
5237                         attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
5238
5239                         inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
5240                 }
5241
5242                 beginCommandBuffer(vk, *initializeImagesCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
5243                 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
5244                 endCommandBuffer(vk, *initializeImagesCommandBuffer);
5245
5246                 {
5247                         Move<VkFramebuffer> framebuffer;
5248                         if (config.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
5249                                 framebuffer = createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews);
5250
5251                         const VkRect2D renderArea
5252                         {
5253                                 { (deInt32)renderPos.x(),       (deInt32)renderPos.y()  },
5254                                 { renderSize.x(),                       renderSize.y()                  }
5255                         };
5256                         const bool dynamicRendering = (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING);
5257                         const bool secondaryCmdBufferCompletelyContainsDynamicRenderpass = (config.commandBufferTypes == TestConfig::COMMANDBUFFERTYPES_SECONDARY) &&
5258                                                                                                                                                                 config.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass;
5259
5260                         for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
5261                         {
5262                                 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, renderPassInfo, attachmentResources,
5263                                                                                                                                                                                           renderArea, renderPassClearValues, *renderPass, *framebuffer,
5264                                                                                                                                                                                           *commandBufferPool, queueIndex, attachmentImages, inputAttachmentViews,
5265                                                                                                                                                                                           subpassRenderInfo[subpassNdx], config.allocationKind, dynamicRendering,
5266                                                                                                                                                                                           secondaryCmdBufferCompletelyContainsDynamicRenderpass)));
5267                         }
5268
5269                         beginCommandBuffer(vk, *renderCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
5270                         pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, renderPassInfo, attachmentResources, *framebuffer, subpassRenderers, renderArea,
5271                                                                    renderPassClearValues, queueIndex, config.renderTypes, config.groupParams->renderingType, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
5272                         endCommandBuffer(vk, *renderCommandBuffer);
5273
5274                         beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
5275                         pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
5276                         endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
5277                         {
5278                                 const VkCommandBuffer commandBuffers[] =
5279                                 {
5280                                         *initializeImagesCommandBuffer,
5281                                         *renderCommandBuffer,
5282                                         *readImagesToBuffersCommandBuffer
5283                                 };
5284                                 const Unique<VkFence>   fence           (createFence(vk, device, 0u));
5285
5286                                 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
5287                                 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
5288                         }
5289                 }
5290 #ifdef CTS_USES_VULKANSC
5291                 if (!context.getTestContext().getCommandLine().isSubProcess())
5292                         return tcu::TestStatus::pass("Pass");
5293 #endif
5294                 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
5295                         return tcu::TestStatus::pass("Pass");
5296                 else
5297                         return tcu::TestStatus::fail("Result verification failed");
5298         }
5299 }
5300
5301 static const VkFormat s_coreColorFormats[] =
5302 {
5303         VK_FORMAT_R5G6B5_UNORM_PACK16,
5304         VK_FORMAT_R8_UNORM,
5305         VK_FORMAT_R8_SNORM,
5306         VK_FORMAT_R8_UINT,
5307         VK_FORMAT_R8_SINT,
5308         VK_FORMAT_R8G8_UNORM,
5309         VK_FORMAT_R8G8_SNORM,
5310         VK_FORMAT_R8G8_UINT,
5311         VK_FORMAT_R8G8_SINT,
5312         VK_FORMAT_R8G8B8A8_UNORM,
5313         VK_FORMAT_R8G8B8A8_SNORM,
5314         VK_FORMAT_R8G8B8A8_UINT,
5315         VK_FORMAT_R8G8B8A8_SINT,
5316         VK_FORMAT_R8G8B8A8_SRGB,
5317         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
5318         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
5319         VK_FORMAT_A8B8G8R8_UINT_PACK32,
5320         VK_FORMAT_A8B8G8R8_SINT_PACK32,
5321         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
5322         VK_FORMAT_B8G8R8A8_UNORM,
5323         VK_FORMAT_B8G8R8A8_SRGB,
5324         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
5325         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
5326         VK_FORMAT_A2B10G10R10_UINT_PACK32,
5327         VK_FORMAT_R16_UNORM,
5328         VK_FORMAT_R16_SNORM,
5329         VK_FORMAT_R16_UINT,
5330         VK_FORMAT_R16_SINT,
5331         VK_FORMAT_R16_SFLOAT,
5332         VK_FORMAT_R16G16_UNORM,
5333         VK_FORMAT_R16G16_SNORM,
5334         VK_FORMAT_R16G16_UINT,
5335         VK_FORMAT_R16G16_SINT,
5336         VK_FORMAT_R16G16_SFLOAT,
5337         VK_FORMAT_R16G16B16A16_UNORM,
5338         VK_FORMAT_R16G16B16A16_SNORM,
5339         VK_FORMAT_R16G16B16A16_UINT,
5340         VK_FORMAT_R16G16B16A16_SINT,
5341         VK_FORMAT_R16G16B16A16_SFLOAT,
5342         VK_FORMAT_R32_UINT,
5343         VK_FORMAT_R32_SINT,
5344         VK_FORMAT_R32_SFLOAT,
5345         VK_FORMAT_R32G32_UINT,
5346         VK_FORMAT_R32G32_SINT,
5347         VK_FORMAT_R32G32_SFLOAT,
5348         VK_FORMAT_R32G32B32A32_UINT,
5349         VK_FORMAT_R32G32B32A32_SINT,
5350         VK_FORMAT_R32G32B32A32_SFLOAT
5351 };
5352
5353 static const VkFormat s_coreDepthStencilFormats[] =
5354 {
5355         VK_FORMAT_D16_UNORM,
5356
5357         VK_FORMAT_X8_D24_UNORM_PACK32,
5358         VK_FORMAT_D32_SFLOAT,
5359
5360         VK_FORMAT_D24_UNORM_S8_UINT,
5361         VK_FORMAT_D32_SFLOAT_S8_UINT
5362 };
5363
5364 void addAttachmentTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5365 {
5366         const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
5367         const VkAttachmentLoadOp loadOps[] =
5368         {
5369                 VK_ATTACHMENT_LOAD_OP_LOAD,
5370                 VK_ATTACHMENT_LOAD_OP_CLEAR,
5371                 VK_ATTACHMENT_LOAD_OP_DONT_CARE
5372         };
5373
5374         const VkAttachmentStoreOp storeOps[] =
5375         {
5376                 VK_ATTACHMENT_STORE_OP_STORE,
5377                 VK_ATTACHMENT_STORE_OP_DONT_CARE
5378         };
5379
5380         const VkImageLayout initialAndFinalColorLayouts[] =
5381         {
5382                 VK_IMAGE_LAYOUT_GENERAL,
5383                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5384                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5385                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5386                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5387         };
5388
5389         const VkImageLayout initialAndFinalColorLayoutsLazy[] =
5390         {
5391                 VK_IMAGE_LAYOUT_GENERAL,
5392                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5393                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
5394         };
5395
5396         const VkImageLayout initialAndFinalDepthStencilLayouts[] =
5397         {
5398                 VK_IMAGE_LAYOUT_GENERAL,
5399                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5400                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
5401                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5402                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5403                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5404         };
5405
5406         const VkImageLayout initialAndFinalDepthStencilLayoutsLazy[] =
5407         {
5408                 VK_IMAGE_LAYOUT_GENERAL,
5409                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5410                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
5411                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
5412         };
5413
5414         const VkImageLayout subpassLayouts[] =
5415         {
5416                 VK_IMAGE_LAYOUT_GENERAL,
5417                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
5418         };
5419
5420         const VkImageLayout depthStencilLayouts[] =
5421         {
5422                 VK_IMAGE_LAYOUT_GENERAL,
5423                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
5424         };
5425
5426         const TestConfig::RenderTypes renderCommands[] =
5427         {
5428                 TestConfig::RENDERTYPES_NONE,
5429                 TestConfig::RENDERTYPES_CLEAR,
5430                 TestConfig::RENDERTYPES_DRAW,
5431                 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
5432         };
5433
5434         const TestConfig::CommandBufferTypes commandBuffers[] =
5435         {
5436                 TestConfig::COMMANDBUFFERTYPES_INLINE,
5437                 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
5438                 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
5439         };
5440
5441         const TestConfig::ImageMemory imageMemories[] =
5442         {
5443                 TestConfig::IMAGEMEMORY_STRICT,
5444                 TestConfig::IMAGEMEMORY_LAZY,
5445                 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
5446         };
5447
5448         const UVec2 targetSizes[] =
5449         {
5450                 UVec2(64, 64),
5451                 UVec2(63, 65)
5452         };
5453
5454         const UVec2 renderPositions[] =
5455         {
5456                 UVec2(0, 0),
5457                 UVec2(3, 17)
5458         };
5459
5460         const UVec2 renderSizes[] =
5461         {
5462                 UVec2(32, 32),
5463                 UVec2(60, 47)
5464         };
5465
5466         tcu::TestContext&       testCtx                                 (group->getTestContext());
5467         bool                            useDynamicRendering             (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING);
5468         de::Random                      rng                                             (1433774382u);
5469
5470         for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
5471         {
5472                 const deUint32                                  attachmentCount                 = attachmentCounts[attachmentCountNdx];
5473                 const deUint32                                  testCaseCount                   = (attachmentCount == 1 ? 100 : 200);
5474                 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup    (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
5475
5476                 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
5477                 {
5478                         const bool                                              useDepthStencil         = rng.getBool();
5479                         const TestConfig::ImageMemory   imageMemory                     = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5480                         VkImageLayout                                   depthStencilLayout      = VK_IMAGE_LAYOUT_GENERAL;
5481                         vector<Attachment>                              attachments;
5482                         vector<AttachmentReference>             colorAttachmentReferences;
5483
5484                         // we want to make sure that dynamic rendering test cases have corresponding renderpass
5485                         // cases as this will allow drivers to easily compare GPU batches; since configurations
5486                         // for those tests are generated we need to generate configurations for all cases
5487                         // even when we know earlier that for dynamic rendering we will skip it
5488                         bool executeForDynamicRendering = true;
5489
5490                         for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5491                         {
5492                                 const VkSampleCountFlagBits     sampleCount             = VK_SAMPLE_COUNT_1_BIT;
5493                                 const VkFormat                          format                  = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
5494                                 const VkAttachmentLoadOp        loadOp                  = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5495                                 const VkAttachmentStoreOp       storeOp                 = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5496
5497                                 const VkImageLayout                     initialLayout   = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5498                                                                                                                                 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts))
5499                                                                                                                                 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy), DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
5500                                 VkImageLayout                           finalizeLayout  = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5501                                                                                                                                 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts))
5502                                                                                                                                 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy), DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
5503                                 const VkImageLayout                     subpassLayout   = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5504
5505                                 const VkAttachmentLoadOp        stencilLoadOp   = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5506                                 const VkAttachmentStoreOp       stencilStoreOp  = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5507
5508                                 if (useDynamicRendering)
5509                                 {
5510                                         // with renderpass we can have automatic layout transitions; to do the same with dynamic rendering cases
5511                                         // we would need to add addtional barries but since those tests won't add coverage we are skipping them
5512                                         if ((initialLayout == VK_IMAGE_LAYOUT_GENERAL) ||
5513                                                 (initialLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL))
5514                                                 finalizeLayout = initialLayout;
5515                                         else
5516                                                 executeForDynamicRendering = false;
5517                                 }
5518
5519                                 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5520                                 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5521                         }
5522
5523                         if (useDepthStencil)
5524                         {
5525                                 const VkSampleCountFlagBits     sampleCount             = VK_SAMPLE_COUNT_1_BIT;
5526                                 const VkFormat                          format                  = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
5527                                 const VkAttachmentLoadOp        loadOp                  = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5528                                 const VkAttachmentStoreOp       storeOp                 = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5529
5530                                 const VkImageLayout                     initialLayout   = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5531                                                                                                                                 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5532                                                                                                                                 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy), DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
5533                                 VkImageLayout                           finalizeLayout  = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5534                                                                                                                                 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5535                                                                                                                                 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy), DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
5536
5537                                 const VkAttachmentLoadOp        stencilLoadOp   = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5538                                 const VkAttachmentStoreOp       stencilStoreOp  = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5539
5540                                 if (useDynamicRendering)
5541                                 {
5542                                         if ((initialLayout == VK_IMAGE_LAYOUT_GENERAL) ||
5543                                                 (initialLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) ||
5544                                                 (initialLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL))
5545                                                 finalizeLayout = initialLayout;
5546                                         else
5547                                                 executeForDynamicRendering = false;
5548                                 }
5549
5550                                 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
5551                                 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5552                         }
5553
5554                         {
5555                                 const TestConfig::RenderTypes                   render                  = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5556                                 const TestConfig::CommandBufferTypes    commandBuffer   = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5557                                 const vector<Subpass>                                   subpasses               (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference((useDepthStencil ? (deUint32)(attachments.size() - 1) : VK_ATTACHMENT_UNUSED), depthStencilLayout), vector<deUint32>()));
5558                                 const vector<SubpassDependency>                 deps;
5559                                 const string                                                    testCaseName    = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
5560                                 const RenderPass                                                renderPass              (attachments, subpasses, deps);
5561                                 const UVec2                                                             targetSize              = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5562                                 const UVec2                                                             renderPos               = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5563                                 const UVec2                                                             renderSize              = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5564
5565                                 if (useDynamicRendering)
5566                                 {
5567                                         // skip dynamic rendering cases (that don't add coverage) this can be done not earlier than after grabbing all
5568                                         // random numbers as we need to make sure that those tests that will be created for dynamic rendering have
5569                                         // corresponding renderpass tests with the same name
5570                                         if (!executeForDynamicRendering)
5571                                                 continue;
5572
5573                                         // dont repeat non secondary buffer cases when testing secondaryCmdBufferCompletelyContainsDynamicRenderpass flag
5574                                         if (testConfigExternal.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass &&
5575                                                 (commandBuffer != TestConfig::COMMANDBUFFERTYPES_SECONDARY))
5576                                         {
5577                                                 continue;
5578                                         }
5579                                 }
5580
5581                                 const TestConfig                                                testConfig              (renderPass,
5582                                                                                                                                                  render,
5583                                                                                                                                                  commandBuffer,
5584                                                                                                                                                  imageMemory,
5585                                                                                                                                                  targetSize,
5586                                                                                                                                                  renderPos,
5587                                                                                                                                                  renderSize,
5588                                                                                                                                                  DE_FALSE,
5589                                                                                                                                                  1293809,
5590                                                                                                                                                  0,
5591                                                                                                                                                  testConfigExternal.allocationKind,
5592                                                                                                                                                  testConfigExternal.groupParams);
5593
5594                                 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
5595                         }
5596                 }
5597
5598                 group->addChild(attachmentCountGroup.release());
5599         }
5600 }
5601
5602 void addAttachmentWriteMaskTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5603 {
5604         const deUint32 attachmentCounts[]       = { 1, 2, 3, 4, 8 };
5605
5606         const VkFormat attachmentFormats[]      =
5607         {
5608                 VK_FORMAT_R8G8B8A8_UINT,
5609                 VK_FORMAT_R8G8B8A8_UNORM,
5610                 VK_FORMAT_R5G6B5_UNORM_PACK16,
5611                 VK_FORMAT_R8G8_UNORM
5612         };
5613
5614         tcu::TestContext&       testCtx                 = group->getTestContext();
5615
5616         for (deUint32 attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
5617         {
5618                 const deUint32  attachmentCount = attachmentCounts[attachmentCountNdx];
5619                 const string    groupName               = "attachment_count_" + de::toString(attachmentCount);
5620
5621                 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), de::toString(attachmentCount).c_str()));
5622
5623                 for (deUint32 drawStartNdx = 0; drawStartNdx < (attachmentCount); drawStartNdx++)
5624                 {
5625                         deUint32                                        formatNdx = 0;
5626                         vector<Attachment>                      attachments;
5627                         vector<AttachmentReference>     colorAttachmentReferences;
5628
5629                         for (deUint32 attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5630                         {
5631                                 const VkFormat                          format                          = attachmentFormats[formatNdx];
5632                                 const VkSampleCountFlagBits     sampleCount                     = VK_SAMPLE_COUNT_1_BIT;
5633                                 const VkAttachmentLoadOp        loadOp                          = VK_ATTACHMENT_LOAD_OP_CLEAR;
5634                                 const VkAttachmentStoreOp       storeOp                         = VK_ATTACHMENT_STORE_OP_STORE;
5635                                 const VkAttachmentLoadOp        stencilLoadOp           = VK_ATTACHMENT_LOAD_OP_CLEAR;
5636                                 const VkAttachmentStoreOp       stencilStoreOp          = VK_ATTACHMENT_STORE_OP_STORE;
5637                                 const VkImageLayout                     initialLayout           = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5638                                 const VkImageLayout                     finalizeLayout          = (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
5639                                                                                                                                         ? initialLayout : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5640                                 const VkImageLayout                     subpassLayout           = VK_IMAGE_LAYOUT_GENERAL;
5641
5642                                 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5643                                 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5644
5645                                 if (++formatNdx == DE_LENGTH_OF_ARRAY(attachmentFormats))
5646                                         formatNdx = 0;
5647                         }
5648
5649                         {
5650                                 const VkImageLayout                                             depthStencilLayout      = VK_IMAGE_LAYOUT_GENERAL;
5651                                 const vector<Subpass>                                   subpass                         (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
5652                                 const vector<SubpassDependency>                 deps;
5653
5654                                 const string                                                    testCaseName            = "start_index_" + de::toString(drawStartNdx);
5655                                 const RenderPass                                                renderPass                      (attachments, subpass, deps);
5656
5657                                 const TestConfig::RenderTypes                   render                          = TestConfig::RENDERTYPES_DRAW;
5658                                 const TestConfig::CommandBufferTypes    commandBuffer           = TestConfig::COMMANDBUFFERTYPES_INLINE;
5659                                 const TestConfig::ImageMemory                   imageMemory                     = TestConfig::IMAGEMEMORY_LAZY;
5660                                 const UVec2                                                             targetSize                      = UVec2(64, 64);
5661                                 const UVec2                                                             renderPos                       = UVec2(0, 0);
5662                                 const UVec2                                                             renderSize                      = UVec2(64, 64);
5663                                 const deBool                                                    useFormatCompCount      = DE_TRUE;
5664                                 const vector<DeviceCoreFeature>                 requiredFeatures        = {DEVICE_CORE_FEATURE_INDEPENDENT_BLEND};
5665                                 const TestConfig                                                testConfig                      (renderPass,
5666                                                                                                                                                          render,
5667                                                                                                                                                          commandBuffer,
5668                                                                                                                                                          imageMemory,
5669                                                                                                                                                          targetSize,
5670                                                                                                                                                          renderPos,
5671                                                                                                                                                          renderSize,
5672                                                                                                                                                          useFormatCompCount,
5673                                                                                                                                                          1293809,
5674                                                                                                                                                          drawStartNdx,
5675                                                                                                                                                          testConfigExternal.allocationKind,
5676                                                                                                                                                          testConfigExternal.groupParams,
5677                                                                                                                                                          requiredFeatures);
5678
5679                                 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), checkSupport, createTestShaders, renderPassTest, testConfig);
5680                         }
5681                 }
5682
5683                 group->addChild(attachmentCountGroup.release());
5684         }
5685 }
5686
5687 template<typename T>
5688 T chooseRandom (de::Random& rng, const set<T>& values)
5689 {
5690         size_t                                                  ndx             = ((size_t)rng.getUint32()) % values.size();
5691         typename set<T>::const_iterator iter    = values.begin();
5692
5693         for (; ndx > 0; ndx--)
5694                 iter++;
5695
5696         return *iter;
5697 }
5698
5699 void addAttachmentAllocationTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5700 {
5701         const deUint32 attachmentCounts[] = { 4, 8 };
5702         const VkAttachmentLoadOp loadOps[] =
5703         {
5704                 VK_ATTACHMENT_LOAD_OP_LOAD,
5705                 VK_ATTACHMENT_LOAD_OP_CLEAR,
5706                 VK_ATTACHMENT_LOAD_OP_DONT_CARE
5707         };
5708
5709         const VkAttachmentStoreOp storeOps[] =
5710         {
5711                 VK_ATTACHMENT_STORE_OP_STORE,
5712                 VK_ATTACHMENT_STORE_OP_DONT_CARE
5713         };
5714
5715         const VkImageLayout initialAndFinalColorLayouts[] =
5716         {
5717                 VK_IMAGE_LAYOUT_GENERAL,
5718                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5719                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5720                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5721                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5722         };
5723
5724         const VkImageLayout initialAndFinalDepthStencilLayouts[] =
5725         {
5726                 VK_IMAGE_LAYOUT_GENERAL,
5727                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5728                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
5729                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5730                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5731                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5732         };
5733
5734         const VkImageLayout subpassLayoutsColor[] =
5735         {
5736                 VK_IMAGE_LAYOUT_GENERAL,
5737                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
5738         };
5739
5740         const VkImageLayout subpassLayoutsDepthStencil[] =
5741         {
5742                 VK_IMAGE_LAYOUT_GENERAL,
5743                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
5744         };
5745
5746         const VkImageLayout subpassLayoutsInput[] =
5747         {
5748                 VK_IMAGE_LAYOUT_GENERAL,
5749                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
5750         };
5751
5752         enum AllocationType
5753         {
5754                 // Each pass uses one more attachmen than previous one
5755                 ALLOCATIONTYPE_GROW,
5756                 // Each pass uses one less attachment than previous one
5757                 ALLOCATIONTYPE_SHRINK,
5758                 // Each pass drops one attachment and picks up new one
5759                 ALLOCATIONTYPE_ROLL,
5760                 // Start by growing and end by shrinking
5761                 ALLOCATIONTYPE_GROW_SHRINK,
5762                 // Each subpass has single input and single output attachment
5763                 ALLOCATIONTYPE_IO_CHAIN,
5764                 // Each subpass has multiple inputs and multiple outputs attachment
5765                 ALLOCATIONTYPE_IO_GENERIC
5766         };
5767
5768         const AllocationType allocationTypes[] =
5769         {
5770                 ALLOCATIONTYPE_GROW,
5771                 ALLOCATIONTYPE_SHRINK,
5772                 ALLOCATIONTYPE_ROLL,
5773                 ALLOCATIONTYPE_GROW_SHRINK,
5774                 ALLOCATIONTYPE_IO_CHAIN,
5775                 ALLOCATIONTYPE_IO_GENERIC
5776         };
5777
5778         const char* const allocationTypeStr[] =
5779         {
5780                 "grow",
5781                 "shrink",
5782                 "roll",
5783                 "grow_shrink",
5784                 "input_output_chain",
5785                 "input_output",
5786         };
5787
5788         const TestConfig::RenderTypes renderCommands[] =
5789         {
5790                 TestConfig::RENDERTYPES_NONE,
5791                 TestConfig::RENDERTYPES_CLEAR,
5792                 TestConfig::RENDERTYPES_DRAW,
5793                 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
5794         };
5795
5796         const TestConfig::CommandBufferTypes commandBuffers[] =
5797         {
5798                 TestConfig::COMMANDBUFFERTYPES_INLINE,
5799                 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
5800                 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
5801         };
5802
5803         const TestConfig::ImageMemory imageMemories[] =
5804         {
5805                 TestConfig::IMAGEMEMORY_STRICT,
5806                 TestConfig::IMAGEMEMORY_LAZY,
5807                 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
5808         };
5809
5810         const UVec2 targetSizes[] =
5811         {
5812                 UVec2(64, 64),
5813                 UVec2(63, 65)
5814         };
5815
5816         const UVec2 renderPositions[] =
5817         {
5818                 UVec2(0, 0),
5819                 UVec2(3, 17)
5820         };
5821
5822         const UVec2 renderSizes[] =
5823         {
5824                 UVec2(32, 32),
5825                 UVec2(60, 47)
5826         };
5827
5828         tcu::TestContext&                               testCtx = group->getTestContext();
5829         de::Random                                              rng             (3700649827u);
5830
5831         for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
5832         {
5833                 const AllocationType                    allocationType          = allocationTypes[allocationTypeNdx];
5834                 const size_t                                    testCaseCount           = 100;
5835                 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup     (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
5836
5837                 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
5838                 {
5839                         if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
5840                         {
5841                                 const deUint32          attachmentCount = 4u + rng.getUint32() % 31u;
5842                                 const deUint32          subpassCount    = 4u + rng.getUint32() % 31u;
5843                                 vector<Attachment>      attachments;
5844
5845                                 set<deUint32>           definedAttachments;
5846
5847                                 vector<Subpass>         subpasses;
5848                                 set<deUint32>           colorAttachments;
5849                                 set<deUint32>           depthStencilAttachments;
5850
5851                                 for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
5852                                 {
5853                                         const bool                                      isDepthStencilAttachment        = rng.getFloat() < 0.01f;
5854                                         const VkSampleCountFlagBits     sampleCount                                     = VK_SAMPLE_COUNT_1_BIT;
5855                                         const VkAttachmentLoadOp        loadOp                                          = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5856                                         const VkAttachmentStoreOp       storeOp                                         = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5857
5858                                         const VkImageLayout                     initialLayout                           = isDepthStencilAttachment
5859                                                                                                                                                         ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5860                                                                                                                                                         : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5861                                         const VkImageLayout                     finalizeLayout                          = isDepthStencilAttachment
5862                                                                                                                                                         ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5863                                                                                                                                                         : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5864
5865                                         const VkAttachmentLoadOp        stencilLoadOp                           = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5866                                         const VkAttachmentStoreOp       stencilStoreOp                          = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5867
5868                                         if (isDepthStencilAttachment)
5869                                         {
5870                                                 const VkFormat  format  = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
5871
5872                                                 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
5873                                                         || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
5874                                                         definedAttachments.insert(attachmentIndex);
5875
5876                                                 depthStencilAttachments.insert(attachmentIndex);
5877
5878                                                 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5879                                         }
5880                                         else
5881                                         {
5882                                                 const VkFormat  format  = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
5883
5884                                                 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
5885                                                         definedAttachments.insert(attachmentIndex);
5886
5887                                                 colorAttachments.insert(attachmentIndex);
5888
5889                                                 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5890                                         }
5891                                 }
5892                                 vector<Maybe<deUint32> >        lastUseOfAttachment     (attachments.size(), tcu::Nothing);
5893                                 vector<SubpassDependency>       deps;
5894
5895                                 for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
5896                                 {
5897                                         const deUint32                          colorAttachmentCount            = depthStencilAttachments.empty()
5898                                                                                                                                                         ? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
5899                                                                                                                                                         : rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
5900                                         const deUint32                          inputAttachmentCount            = rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
5901                                         const bool                                      useDepthStencilAttachment       = !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
5902                                         std::vector<deUint32>           subpassColorAttachments         (colorAttachmentCount);
5903                                         std::vector<deUint32>           subpassInputAttachments         (inputAttachmentCount);
5904                                         Maybe<deUint32>                         depthStencilAttachment          (useDepthStencilAttachment
5905                                                                                                                                                         ? just(chooseRandom(rng, depthStencilAttachments))
5906                                                                                                                                                         : tcu::Nothing);
5907                                         std::vector<deUint32>           subpassPreserveAttachments;
5908
5909                                         rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
5910                                         rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);
5911
5912                                         for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
5913                                                 definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
5914
5915                                         if (depthStencilAttachment)
5916                                                 definedAttachments.insert(*depthStencilAttachment);
5917
5918                                         {
5919                                                 std::vector<AttachmentReference>        inputAttachmentReferences;
5920                                                 std::vector<AttachmentReference>        colorAttachmentReferences;
5921                                                 AttachmentReference                                     depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
5922
5923                                                 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
5924                                                 {
5925                                                         const deUint32          colorAttachmentIndex    = subpassColorAttachments[colorAttachmentNdx];
5926
5927                                                         if (lastUseOfAttachment[colorAttachmentIndex])
5928                                                         {
5929                                                                 deBool foundDuplicate = false;
5930
5931                                                                 const deUint32                  srcPass                 = *lastUseOfAttachment[colorAttachmentIndex];
5932                                                                 const deUint32                  dstPass                 = subpassIndex;
5933                                                                 const VkDependencyFlags dependencyFlags = rng.getBool() ? (VkDependencyFlags) VK_DEPENDENCY_BY_REGION_BIT : 0u;
5934
5935                                                                 const SubpassDependency newDependency(srcPass, dstPass,
5936                                                                                                                                           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5937                                                                                                                                           | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5938                                                                                                                                           | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5939                                                                                                                                           | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5940
5941                                                                                                                                           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5942                                                                                                                                           | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5943                                                                                                                                           | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5944                                                                                                                                           | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5945
5946                                                                                                                                           VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5947                                                                                                                                           VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
5948
5949                                                                                                                                           dependencyFlags);
5950
5951                                                                 for (SubpassDependency& dependency : deps)
5952                                                                 {
5953                                                                         if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
5954                                                                         {
5955                                                                                 const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
5956                                                                                 dependency.setDstAccessMask(newDstFlags);
5957                                                                                 foundDuplicate = true;
5958                                                                                 break;
5959                                                                         }
5960                                                                 }
5961
5962                                                                 if (!foundDuplicate)
5963                                                                 {
5964                                                                         deps.push_back(newDependency);
5965                                                                 }
5966                                                         }
5967
5968                                                         lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
5969
5970                                                         colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], VK_IMAGE_LAYOUT_GENERAL));
5971                                                 }
5972
5973                                                 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
5974                                                 {
5975                                                         const deUint32          inputAttachmentIndex    = subpassInputAttachments[inputAttachmentNdx];
5976
5977                                                         if(lastUseOfAttachment[inputAttachmentIndex])
5978                                                         {
5979                                                                 deBool foundDuplicate = false;
5980
5981                                                                 const deUint32                  srcPass                 = *lastUseOfAttachment[inputAttachmentIndex];
5982                                                                 const deUint32                  dstPass                 = subpassIndex;
5983                                                                 const VkDependencyFlags dependencyFlags = ((srcPass == subpassIndex) || rng.getBool()) ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u;
5984
5985                                                                 const SubpassDependency newDependency(srcPass, dstPass,
5986                                                                                                                                           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5987                                                                                                                                           | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5988                                                                                                                                           | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5989                                                                                                                                           | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5990
5991                                                                                                                                           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5992                                                                                                                                           | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5993                                                                                                                                           | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5994                                                                                                                                           | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5995
5996                                                                                                                                           VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5997                                                                                                                                           VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5998
5999                                                                                                                                           dependencyFlags);
6000                                                                 for (SubpassDependency& dependency : deps)
6001                                                                 {
6002                                                                         if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6003                                                                         {
6004                                                                                 const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
6005                                                                                 const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
6006                                                                                 dependency.setDstAccessMask(newSrcFlags);
6007                                                                                 dependency.setDstAccessMask(newDstFlags);
6008                                                                                 foundDuplicate = true;
6009                                                                                 break;
6010                                                                         }
6011                                                                 }
6012
6013                                                                 if (!foundDuplicate)
6014                                                                 {
6015                                                                         deps.push_back(newDependency);
6016                                                                 }
6017
6018                                                                 lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
6019
6020                                                                 VkImageAspectFlags aspect = 0u;
6021                                                                 if (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
6022                                                                 {
6023                                                                         bool col = colorAttachments.find(inputAttachmentIndex) != colorAttachments.end();
6024                                                                         aspect = col ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
6025                                                                 }
6026                                                                 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], VK_IMAGE_LAYOUT_GENERAL, aspect));
6027                                                         }
6028                                                 }
6029
6030                                                 if (depthStencilAttachment)
6031                                                 {
6032                                                         if (lastUseOfAttachment[*depthStencilAttachment])
6033                                                         {
6034                                                                 deBool foundDuplicate = false;
6035
6036                                                                 const deUint32                  srcPass                 = *lastUseOfAttachment[*depthStencilAttachment];
6037                                                                 const deUint32                  dstPass                 = subpassIndex;
6038                                                                 const VkDependencyFlags dependencyFlags = ((srcPass == subpassIndex) || rng.getBool()) ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u;
6039
6040                                                                 const SubpassDependency newDependency(srcPass, dstPass,
6041                                                                                                                                           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6042                                                                                                                                           | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6043                                                                                                                                           | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6044                                                                                                                                           | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6045
6046                                                                                                                                           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6047                                                                                                                                           | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6048                                                                                                                                           | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6049                                                                                                                                           | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6050
6051                                                                                                                                           VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6052                                                                                                                                           VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
6053                                                                                                                                           | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6054
6055                                                                                                                                           dependencyFlags);
6056                                                                 for (SubpassDependency& dependency : deps)
6057                                                                 {
6058                                                                         if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6059                                                                         {
6060                                                                                 const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
6061                                                                                 const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
6062                                                                                 dependency.setDstAccessMask(newSrcFlags);
6063                                                                                 dependency.setDstAccessMask(newDstFlags);
6064                                                                                 foundDuplicate = true;
6065                                                                                 break;
6066                                                                         }
6067                                                                 }
6068
6069                                                                 if (!foundDuplicate)
6070                                                                 {
6071                                                                         deps.push_back(newDependency);
6072                                                                 }
6073                                                         }
6074
6075                                                         lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
6076
6077                                                         depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
6078                                                 }
6079                                                 else
6080                                                         depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
6081
6082                                                 vector<deUint32>        preserveAttachments;
6083                                                 for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
6084                                                 {
6085                                                         if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
6086                                                                 preserveAttachments.push_back(attachmentIndex);
6087                                                 }
6088
6089                                                 // Use random image layout when possible
6090                                                 for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
6091                                                 {
6092                                                         bool usedAsInput = false;
6093                                                         for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6094                                                                 if (colorAttachmentReferences[colorRefIdx].getAttachment() == inputAttachmentReferences[inputRefIdx].getAttachment())
6095                                                                         usedAsInput = true;
6096
6097                                                         if (!usedAsInput)
6098                                                                 colorAttachmentReferences[colorRefIdx].setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)));
6099                                                 }
6100                                                 for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6101                                                 {
6102                                                         bool usedAsDepthStencil = inputAttachmentReferences[inputRefIdx].getAttachment() == depthStencilAttachmentReference.getAttachment();
6103                                                         bool usedAsColor                = false;
6104                                                         for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
6105                                                                 if (inputAttachmentReferences[inputRefIdx].getAttachment() == colorAttachmentReferences[colorRefIdx].getAttachment())
6106                                                                         usedAsColor = true;
6107
6108                                                         if (!usedAsColor && !usedAsDepthStencil)
6109                                                                 inputAttachmentReferences[inputRefIdx].setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsInput), DE_ARRAY_END(subpassLayoutsInput)));
6110                                                 }
6111                                                 {
6112                                                         bool usedAsInput = false;
6113                                                         for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6114                                                                 if (depthStencilAttachmentReference.getAttachment() == inputAttachmentReferences[inputRefIdx].getAttachment())
6115                                                                         usedAsInput = true;
6116
6117                                                         if (!usedAsInput)
6118                                                                 depthStencilAttachmentReference.setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsDepthStencil), DE_ARRAY_END(subpassLayoutsDepthStencil)));
6119                                                 }
6120
6121                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6122                                                                                                 inputAttachmentReferences,
6123                                                                                                 colorAttachmentReferences,
6124                                                                                                 vector<AttachmentReference>(),
6125                                                                                                 depthStencilAttachmentReference,
6126                                                                                                 preserveAttachments));
6127                                         }
6128                                 }
6129                                 {
6130                                         const TestConfig::RenderTypes                   render                  = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
6131                                         const TestConfig::CommandBufferTypes    commandBuffer   = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
6132                                         const TestConfig::ImageMemory                   imageMemory             = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
6133
6134                                         const string                                                    testCaseName    = de::toString(testCaseNdx);
6135                                         const UVec2                                                             targetSize              = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
6136                                         const UVec2                                                             renderPos               = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
6137                                         const UVec2                                                             renderSize              = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
6138
6139                                         const RenderPass                                                renderPass              (attachments, subpasses, deps);
6140                                         const TestConfig                                                testConfig              (renderPass,
6141                                                                                                                                                          render,
6142                                                                                                                                                          commandBuffer,
6143                                                                                                                                                          imageMemory,
6144                                                                                                                                                          targetSize,
6145                                                                                                                                                          renderPos,
6146                                                                                                                                                          renderSize,
6147                                                                                                                                                          DE_FALSE,
6148                                                                                                                                                          80329,
6149                                                                                                                                                          0,
6150                                                                                                                                                          testConfigExternal.allocationKind,
6151                                                                                                                                                          testConfigExternal.groupParams);
6152
6153                                         addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
6154                                 }
6155                         }
6156                         else
6157                         {
6158                                 const deUint32          attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
6159                                 vector<Attachment>      attachments;
6160                                 vector<Subpass>         subpasses;
6161
6162                                 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
6163                                 {
6164                                         const VkSampleCountFlagBits     sampleCount             = VK_SAMPLE_COUNT_1_BIT;
6165                                         const VkFormat                          format                  = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
6166                                         const VkAttachmentLoadOp        loadOp                  = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6167                                         const VkAttachmentStoreOp       storeOp                 = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6168
6169                                         const VkImageLayout                     initialLayout   = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
6170                                         const VkImageLayout                     finalizeLayout  = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
6171
6172                                         const VkAttachmentLoadOp        stencilLoadOp   = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6173                                         const VkAttachmentStoreOp       stencilStoreOp  = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6174
6175                                         attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
6176                                 }
6177
6178                                 if (allocationType == ALLOCATIONTYPE_GROW)
6179                                 {
6180                                         for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6181                                         {
6182                                                 vector<AttachmentReference>     colorAttachmentReferences;
6183
6184                                                 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
6185                                                 {
6186                                                         const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6187
6188                                                         colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6189                                                 }
6190
6191                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6192                                                                                                 vector<AttachmentReference>(),
6193                                                                                                 colorAttachmentReferences,
6194                                                                                                 vector<AttachmentReference>(),
6195                                                                                                 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6196                                                                                                 vector<deUint32>()));
6197                                         }
6198                                 }
6199                                 else if (allocationType == ALLOCATIONTYPE_SHRINK)
6200                                 {
6201                                         for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6202                                         {
6203                                                 vector<AttachmentReference>     colorAttachmentReferences;
6204
6205                                                 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
6206                                                 {
6207                                                         const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6208
6209                                                         colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6210                                                 }
6211
6212                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6213                                                                                                         vector<AttachmentReference>(),
6214                                                                                                         colorAttachmentReferences,
6215                                                                                                         vector<AttachmentReference>(),
6216                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6217                                                                                                         vector<deUint32>()));
6218                                         }
6219                                 }
6220                                 else if (allocationType == ALLOCATIONTYPE_ROLL)
6221                                 {
6222                                         for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
6223                                         {
6224                                                 vector<AttachmentReference>     colorAttachmentReferences;
6225
6226                                                 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
6227                                                 {
6228                                                         const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6229
6230                                                         colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
6231                                                 }
6232
6233                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6234                                                                                                         vector<AttachmentReference>(),
6235                                                                                                         colorAttachmentReferences,
6236                                                                                                         vector<AttachmentReference>(),
6237                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6238                                                                                                         vector<deUint32>()));
6239                                         }
6240                                 }
6241                                 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
6242                                 {
6243                                         for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6244                                         {
6245                                                 vector<AttachmentReference>     colorAttachmentReferences;
6246
6247                                                 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
6248                                                 {
6249                                                         const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6250
6251                                                         colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6252                                                 }
6253
6254                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6255                                                                                                         vector<AttachmentReference>(),
6256                                                                                                         colorAttachmentReferences,
6257                                                                                                         vector<AttachmentReference>(),
6258                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6259                                                                                                         vector<deUint32>()));
6260                                         }
6261                                         for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6262                                         {
6263                                                 vector<AttachmentReference>     colorAttachmentReferences;
6264
6265                                                 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
6266                                                 {
6267                                                         const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6268
6269                                                         colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6270                                                 }
6271
6272                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6273                                                                                                         vector<AttachmentReference>(),
6274                                                                                                         colorAttachmentReferences,
6275                                                                                                         vector<AttachmentReference>(),
6276                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6277                                                                                                         vector<deUint32>()));
6278                                         }
6279                                 }
6280                                 else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
6281                                 {
6282                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6283                                                                                         vector<AttachmentReference>(),
6284                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)))),
6285                                                                                         vector<AttachmentReference>(),
6286                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6287                                                                                         vector<deUint32>()));
6288
6289                                         for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
6290                                         {
6291                                                 const VkImageAspectFlags inputAttachmentAspectMask = (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ? VK_IMAGE_ASPECT_COLOR_BIT : static_cast<VkImageAspectFlagBits>(0);
6292                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6293                                                                                                 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
6294                                                                                                 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)))),
6295                                                                                                 vector<AttachmentReference>(),
6296                                                                                                 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6297                                                                                                 vector<deUint32>()));
6298                                         }
6299                                 }
6300                                 else
6301                                         DE_FATAL("Unknown allocation type");
6302
6303                                 {
6304                                         const TestConfig::RenderTypes                   render                  = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
6305                                         const TestConfig::CommandBufferTypes    commandBuffer   = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
6306                                         const TestConfig::ImageMemory                   imageMemory             = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
6307
6308                                         const string                                                    testCaseName    = de::toString(testCaseNdx);
6309                                         const UVec2                                                             targetSize              = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
6310                                         const UVec2                                                             renderPos               = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
6311                                         const UVec2                                                             renderSize              = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
6312
6313                                         vector<SubpassDependency>                               deps;
6314
6315                                         for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
6316                                         {
6317                                                 const bool byRegion                             = rng.getBool();
6318                                                 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
6319                                                                                                                  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6320                                                                                                                         | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6321                                                                                                                         | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6322                                                                                                                         | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6323
6324                                                                                                                  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6325                                                                                                                         | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6326                                                                                                                         | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6327                                                                                                                         | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6328
6329                                                                                                                  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6330                                                                                                                  (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT),
6331
6332                                                                                                                  byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
6333                                         }
6334
6335                                         const RenderPass                                        renderPass              (attachments, subpasses, deps);
6336                                         const TestConfig                                        testConfig              (renderPass,
6337                                                                                                                                                  render,
6338                                                                                                                                                  commandBuffer,
6339                                                                                                                                                  imageMemory,
6340                                                                                                                                                  targetSize,
6341                                                                                                                                                  renderPos,
6342                                                                                                                                                  renderSize,
6343                                                                                                                                                  DE_FALSE,
6344                                                                                                                                                  80329,
6345                                                                                                                                                  0,
6346                                                                                                                                                  testConfigExternal.allocationKind,
6347                                                                                                                                                  testConfigExternal.groupParams);
6348
6349                                         addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
6350                                 }
6351                         }
6352                 }
6353                 group->addChild(allocationTypeGroup.release());
6354         }
6355 }
6356
6357 void addSimpleTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
6358 {
6359         const UVec2     targetSize      (64, 64);
6360         const UVec2     renderPos       (0, 0);
6361         const UVec2     renderSize      (64, 64);
6362
6363         // color
6364         {
6365                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6366                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
6367                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
6368                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
6369                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6370                                                                                                                                                   VK_ATTACHMENT_STORE_OP_DONT_CARE,
6371                                                                                                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6372                                                                                                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6373                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6374                                                                                                                                         0u,
6375                                                                                                                                         vector<AttachmentReference>(),
6376                                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6377                                                                                                                                         vector<AttachmentReference>(),
6378                                                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6379                                                                                                                                         vector<deUint32>())),
6380                                                                                  vector<SubpassDependency>());
6381                 const TestConfig        testConfig      (renderPass,
6382                                                                                  TestConfig::RENDERTYPES_DRAW,
6383                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6384                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6385                                                                                  targetSize,
6386                                                                                  renderPos,
6387                                                                                  renderSize,
6388                                                                                  DE_FALSE,
6389                                                                                  90239,
6390                                                                                  0,
6391                                                                                  testConfigExternal.allocationKind,
6392                                                                                  testConfigExternal.groupParams);
6393
6394                 addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders, renderPassTest, testConfig);
6395         }
6396
6397         // depth
6398         {
6399                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
6400                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
6401                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
6402                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
6403                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6404                                                                                                                                                   VK_ATTACHMENT_STORE_OP_DONT_CARE,
6405                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6406                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6407                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6408                                                                                                                                         0u,
6409                                                                                                                                         vector<AttachmentReference>(),
6410                                                                                                                                         vector<AttachmentReference>(),
6411                                                                                                                                         vector<AttachmentReference>(),
6412                                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6413                                                                                                                                         vector<deUint32>())),
6414                                                                                  vector<SubpassDependency>());
6415                 const TestConfig        testConfig      (renderPass,
6416                                                                                  TestConfig::RENDERTYPES_DRAW,
6417                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6418                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6419                                                                                  targetSize,
6420                                                                                  renderPos,
6421                                                                                  renderSize,
6422                                                                                  DE_FALSE,
6423                                                                                  90239,
6424                                                                                  0,
6425                                                                                  testConfigExternal.allocationKind,
6426                                                                                  testConfigExternal.groupParams);
6427
6428                 addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders, renderPassTest, testConfig);
6429         }
6430
6431         // stencil
6432         {
6433                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
6434                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
6435                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6436                                                                                                                                                   VK_ATTACHMENT_STORE_OP_DONT_CARE,
6437                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
6438                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
6439                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6440                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6441                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6442                                                                                                                                         0u,
6443                                                                                                                                         vector<AttachmentReference>(),
6444                                                                                                                                         vector<AttachmentReference>(),
6445                                                                                                                                         vector<AttachmentReference>(),
6446                                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6447                                                                                                                                         vector<deUint32>())),
6448                                                                                  vector<SubpassDependency>());
6449                 const TestConfig        testConfig      (renderPass,
6450                                                                                  TestConfig::RENDERTYPES_DRAW,
6451                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6452                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6453                                                                                  targetSize,
6454                                                                                  renderPos,
6455                                                                                  renderSize,
6456                                                                                  DE_FALSE,
6457                                                                                  90239,
6458                                                                                  0,
6459                                                                                  testConfigExternal.allocationKind,
6460                                                                                  testConfigExternal.groupParams);
6461
6462                 addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6463         }
6464
6465         // depth_stencil
6466         {
6467                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
6468                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
6469                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
6470                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
6471                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
6472                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
6473                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6474                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6475                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6476                                                                                                                                         0u,
6477                                                                                                                                         vector<AttachmentReference>(),
6478                                                                                                                                         vector<AttachmentReference>(),
6479                                                                                                                                         vector<AttachmentReference>(),
6480                                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6481                                                                                                                                         vector<deUint32>())),
6482                                                                                  vector<SubpassDependency>());
6483                 const TestConfig        testConfig      (renderPass,
6484                                                                                  TestConfig::RENDERTYPES_DRAW,
6485                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6486                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6487                                                                                  targetSize,
6488                                                                                  renderPos,
6489                                                                                  renderSize,
6490                                                                                  DE_FALSE,
6491                                                                                  90239,
6492                                                                                  0,
6493                                                                                  testConfigExternal.allocationKind,
6494                                                                                  testConfigExternal.groupParams);
6495
6496                 addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6497         }
6498
6499         // color_depth
6500         {
6501                 const Attachment        attachments[] =
6502                 {
6503                         Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6504                                            VK_SAMPLE_COUNT_1_BIT,
6505                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
6506                                            VK_ATTACHMENT_STORE_OP_STORE,
6507                                            VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6508                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
6509                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6510                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6511                         Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
6512                                            VK_SAMPLE_COUNT_1_BIT,
6513                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
6514                                            VK_ATTACHMENT_STORE_OP_STORE,
6515                                            VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6516                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
6517                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6518                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6519                 };
6520
6521                 const RenderPass        renderPass      (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6522                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6523                                                                                                                                         0u,
6524                                                                                                                                         vector<AttachmentReference>(),
6525                                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6526                                                                                                                                         vector<AttachmentReference>(),
6527                                                                                                                                         AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6528                                                                                                                                         vector<deUint32>())),
6529                                                                                  vector<SubpassDependency>());
6530                 const TestConfig        testConfig      (renderPass,
6531                                                                                  TestConfig::RENDERTYPES_DRAW,
6532                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6533                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6534                                                                                  targetSize,
6535                                                                                  renderPos,
6536                                                                                  renderSize,
6537                                                                                  DE_FALSE,
6538                                                                                  90239,
6539                                                                                  0,
6540                                                                                  testConfigExternal.allocationKind,
6541                                                                                  testConfigExternal.groupParams);
6542
6543                 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, testConfig);
6544         }
6545
6546         // color_stencil
6547         {
6548                 const Attachment        attachments[] =
6549                 {
6550                         Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6551                                            VK_SAMPLE_COUNT_1_BIT,
6552                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
6553                                            VK_ATTACHMENT_STORE_OP_STORE,
6554                                            VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6555                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
6556                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6557                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6558                         Attachment(VK_FORMAT_S8_UINT,
6559                                            VK_SAMPLE_COUNT_1_BIT,
6560                                            VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6561                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
6562                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
6563                                            VK_ATTACHMENT_STORE_OP_STORE,
6564                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6565                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6566                 };
6567
6568                 const RenderPass        renderPass      (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6569                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6570                                                                                                                                         0u,
6571                                                                                                                                         vector<AttachmentReference>(),
6572                                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6573                                                                                                                                         vector<AttachmentReference>(),
6574                                                                                                                                         AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6575                                                                                                                                         vector<deUint32>())),
6576                                                                                  vector<SubpassDependency>());
6577                 const TestConfig        testConfig      (renderPass,
6578                                                                                  TestConfig::RENDERTYPES_DRAW,
6579                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6580                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6581                                                                                  targetSize,
6582                                                                                  renderPos,
6583                                                                                  renderSize,
6584                                                                                  DE_FALSE,
6585                                                                                  90239,
6586                                                                                  0,
6587                                                                                  testConfigExternal.allocationKind,
6588                                                                                  testConfigExternal.groupParams);
6589
6590                 addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6591         }
6592
6593         // color_depth_stencil
6594         {
6595                 const Attachment        attachments[] =
6596                 {
6597                         Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6598                                            VK_SAMPLE_COUNT_1_BIT,
6599                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
6600                                            VK_ATTACHMENT_STORE_OP_STORE,
6601                                            VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6602                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
6603                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6604                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6605                         Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
6606                                            VK_SAMPLE_COUNT_1_BIT,
6607                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
6608                                            VK_ATTACHMENT_STORE_OP_STORE,
6609                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
6610                                            VK_ATTACHMENT_STORE_OP_STORE,
6611                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6612                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6613                 };
6614
6615                 const RenderPass        renderPass      (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6616                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6617                                                                                                                                         0u,
6618                                                                                                                                         vector<AttachmentReference>(),
6619                                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6620                                                                                                                                         vector<AttachmentReference>(),
6621                                                                                                                                         AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6622                                                                                                                                         vector<deUint32>())),
6623                                                                                  vector<SubpassDependency>());
6624                 const TestConfig        testConfig      (renderPass,
6625                                                                                  TestConfig::RENDERTYPES_DRAW,
6626                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6627                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6628                                                                                  targetSize,
6629                                                                                  renderPos,
6630                                                                                  renderSize,
6631                                                                                  DE_FALSE,
6632                                                                                  90239,
6633                                                                                  0,
6634                                                                                  testConfigExternal.allocationKind,
6635                                                                                  testConfigExternal.groupParams);
6636
6637                 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6638         }
6639
6640         // no attachments
6641         {
6642                 const RenderPass        renderPass      (vector<Attachment>(),
6643                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6644                                                                                                                                         0u,
6645                                                                                                                                         vector<AttachmentReference>(),
6646                                                                                                                                         vector<AttachmentReference>(),
6647                                                                                                                                         vector<AttachmentReference>(),
6648                                                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6649                                                                                                                                         vector<deUint32>())),
6650                                                                                 vector<SubpassDependency>());
6651                 const TestConfig        testConfig      (renderPass,
6652                                                                                  TestConfig::RENDERTYPES_DRAW,
6653                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6654                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6655                                                                                  targetSize,
6656                                                                                  renderPos,
6657                                                                                  renderSize,
6658                                                                                  DE_FALSE,
6659                                                                                  90239,
6660                                                                                  0,
6661                                                                                  testConfigExternal.allocationKind,
6662                                                                                  testConfigExternal.groupParams);
6663
6664                 addFunctionCaseWithPrograms<TestConfig>(group, "no_attachments", "No attachments case.", createTestShaders, renderPassTest, testConfig);
6665         }
6666
6667         // color_unused_omit_blend_state
6668         if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
6669         {
6670                 vector<Subpass>         subpasses;
6671
6672                 // First subpass: use color attachment, create pipeline with color blend state
6673                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6674                                                                         0u,
6675                                                                         vector<AttachmentReference>(),
6676                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6677                                                                         vector<AttachmentReference>(),
6678                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6679                                                                         vector<deUint32>(),
6680                                                                         false));
6681
6682                 // Second subpass: don't use color attachment, create pipeline without color blend state
6683                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6684                                                                         0u,
6685                                                                         vector<AttachmentReference>(),
6686                                                                         vector<AttachmentReference>(1, AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6687                                                                         vector<AttachmentReference>(),
6688                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6689                                                                         vector<deUint32>(),
6690                                                                         true));
6691
6692                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6693                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
6694                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
6695                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
6696                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6697                                                                                                                                                   VK_ATTACHMENT_STORE_OP_DONT_CARE,
6698                                                                                                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6699                                                                                                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6700                                                                                  subpasses,
6701                                                                                  vector<SubpassDependency>());
6702
6703                 const TestConfig        testConfig      (renderPass,
6704                                                                                  TestConfig::RENDERTYPES_DRAW,
6705                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6706                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6707                                                                                  targetSize,
6708                                                                                  renderPos,
6709                                                                                  renderSize,
6710                                                                                  DE_FALSE,
6711                                                                                  90239,
6712                                                                                  0,
6713                                                                                  testConfigExternal.allocationKind,
6714                                                                                  testConfigExternal.groupParams);
6715                 addFunctionCaseWithPrograms<TestConfig>(group, "color_unused_omit_blend_state", "Two unused color attachment case without blend state", createTestShaders, renderPassTest, testConfig);
6716         }
6717 }
6718
6719 std::string formatToName (VkFormat format)
6720 {
6721         const std::string       formatStr       = de::toString(format);
6722         const std::string       prefix          = "VK_FORMAT_";
6723
6724         DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
6725
6726         return de::toLower(formatStr.substr(prefix.length()));
6727 }
6728
6729 void addFormatTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
6730 {
6731         tcu::TestContext&       testCtx         = group->getTestContext();
6732
6733         const UVec2                     targetSize      (64, 64);
6734         const UVec2                     renderPos       (0, 0);
6735         const UVec2                     renderSize      (64, 64);
6736
6737         const struct
6738         {
6739                 const char* const                       str;
6740                 const VkAttachmentStoreOp       op;
6741         } storeOps[] =
6742         {
6743                 { "store",              VK_ATTACHMENT_STORE_OP_STORE            },
6744                 { "dont_care",  VK_ATTACHMENT_STORE_OP_DONT_CARE        }
6745         };
6746
6747         const struct
6748         {
6749                 const char* const                       str;
6750                 const VkAttachmentLoadOp        op;
6751         } loadOps[] =
6752         {
6753                 { "clear",              VK_ATTACHMENT_LOAD_OP_CLEAR             },
6754                 { "load",               VK_ATTACHMENT_LOAD_OP_LOAD              },
6755                 { "dont_care",  VK_ATTACHMENT_LOAD_OP_DONT_CARE }
6756         };
6757
6758         const struct
6759         {
6760                  const char* const                              str;
6761                  const TestConfig::RenderTypes  types;
6762         } renderTypes[] =
6763         {
6764                 { "clear",              TestConfig::RENDERTYPES_CLEAR                                                           },
6765                 { "draw",               TestConfig::RENDERTYPES_DRAW                                                            },
6766                 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW      }
6767         };
6768
6769         // Color formats
6770         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
6771         {
6772                 const VkFormat                                  format          = s_coreColorFormats[formatNdx];
6773                 de::MovePtr<tcu::TestCaseGroup> formatGroup     (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
6774
6775                 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
6776                 {
6777                         const VkAttachmentLoadOp                loadOp  = loadOps[loadOpNdx].op;
6778                         de::MovePtr<tcu::TestCaseGroup> loadOpGroup     (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
6779
6780                         for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
6781                         {
6782                                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(format,
6783                                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
6784                                                                                                                                                                   loadOp,
6785                                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
6786                                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6787                                                                                                                                                                   VK_ATTACHMENT_STORE_OP_DONT_CARE,
6788                                                                                                                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6789                                                                                                                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6790                                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6791                                                                                                                                                         0u,
6792                                                                                                                                                         vector<AttachmentReference>(),
6793                                                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6794                                                                                                                                                         vector<AttachmentReference>(),
6795                                                                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6796                                                                                                                                                         vector<deUint32>())),
6797                                                                                                  vector<SubpassDependency>());
6798                                 const TestConfig        testConfig      (renderPass,
6799                                                                                                  renderTypes[renderTypeNdx].types,
6800                                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6801                                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6802                                                                                                  targetSize,
6803                                                                                                  renderPos,
6804                                                                                                  renderSize,
6805                                                                                                  DE_FALSE,
6806                                                                                                  90239,
6807                                                                                                  0,
6808                                                                                                  testConfigExternal.allocationKind,
6809                                                                                                  testConfigExternal.groupParams);
6810
6811                                 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6812                         }
6813
6814                         formatGroup->addChild(loadOpGroup.release());
6815                 }
6816
6817                 if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
6818                 {
6819                         de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
6820
6821                         for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
6822                         {
6823                                 const VkAttachmentLoadOp                loadOp          = loadOps[loadOpNdx].op;
6824                                 de::MovePtr<tcu::TestCaseGroup> loadOpGroup     (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
6825
6826                                 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
6827                                 {
6828                                         const VkImageAspectFlags                inputAttachmentAspectMask       = (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
6829                                                                                                                                                                 ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
6830                                                                                                                                                                 : static_cast<VkImageAspectFlags>(0);
6831                                         const VkAttachmentStoreOp               storeOp                                         = storeOps[storeOpNdx].op;
6832                                         de::MovePtr<tcu::TestCaseGroup> storeOpGroup                            (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
6833
6834                                         for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
6835                                         {
6836                                                 const bool useInputAspect = useInputAspectNdx != 0;
6837
6838                                                 if (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2 && useInputAspect)
6839                                                         continue;
6840
6841                                                 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
6842                                                 {
6843                                                         {
6844                                                                 vector<Attachment>                                                      attachments;
6845                                                                 vector<Subpass>                                                         subpasses;
6846                                                                 vector<SubpassDependency>                                       deps;
6847                                                                 vector<VkInputAttachmentAspectReference>        inputAspects;
6848
6849                                                                 attachments.push_back(Attachment(format,
6850                                                                                                                                  VK_SAMPLE_COUNT_1_BIT,
6851                                                                                                                                  loadOp,
6852                                                                                                                                  storeOp,
6853                                                                                                                                  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6854                                                                                                                                  VK_ATTACHMENT_STORE_OP_DONT_CARE,
6855                                                                                                                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6856                                                                                                                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6857
6858                                                                 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
6859                                                                                                                                  VK_SAMPLE_COUNT_1_BIT,
6860                                                                                                                                  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6861                                                                                                                                  VK_ATTACHMENT_STORE_OP_STORE,
6862                                                                                                                                  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6863                                                                                                                                  VK_ATTACHMENT_STORE_OP_DONT_CARE,
6864                                                                                                                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6865                                                                                                                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6866
6867                                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6868                                                                                                                         0u,
6869                                                                                                                         vector<AttachmentReference>(),
6870                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6871                                                                                                                         vector<AttachmentReference>(),
6872                                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6873                                                                                                                         vector<deUint32>()));
6874                                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6875                                                                                                                         0u,
6876                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
6877                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6878                                                                                                                         vector<AttachmentReference>(),
6879                                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6880                                                                                                                         vector<deUint32>()));
6881
6882                                                                 deps.push_back(SubpassDependency(0, 1,
6883
6884                                                                                                                                 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6885                                                                                                                                 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6886
6887                                                                                                                                 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6888                                                                                                                                 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6889                                                                                                                                 vk::VK_DEPENDENCY_BY_REGION_BIT));
6890
6891                                                                 if (useInputAspect)
6892                                                                 {
6893                                                                         const VkInputAttachmentAspectReference inputAspect =
6894                                                                         {
6895                                                                                 1u,
6896                                                                                 0u,
6897                                                                                 VK_IMAGE_ASPECT_COLOR_BIT
6898                                                                         };
6899
6900                                                                         inputAspects.push_back(inputAspect);
6901                                                                 }
6902
6903                                                                 {
6904                                                                         const RenderPass        renderPass      (attachments, subpasses, deps, inputAspects);
6905                                                                         const TestConfig        testConfig      (renderPass,
6906                                                                                                                                          renderTypes[renderTypeNdx].types,
6907                                                                                                                                          TestConfig::COMMANDBUFFERTYPES_INLINE,
6908                                                                                                                                          TestConfig::IMAGEMEMORY_STRICT,
6909                                                                                                                                          targetSize,
6910                                                                                                                                          renderPos,
6911                                                                                                                                          renderSize,
6912                                                                                                                                          DE_FALSE,
6913                                                                                                                                          89246,
6914                                                                                                                                          0,
6915                                                                                                                                          testConfigExternal.allocationKind,
6916                                                                                                                                          testConfigExternal.groupParams);
6917                                                                         const string            testName        (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""));
6918
6919                                                                         addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6920                                                                 }
6921                                                         }
6922                                                         {
6923                                                                 vector<Attachment>                                                      attachments;
6924                                                                 vector<Subpass>                                                         subpasses;
6925                                                                 vector<SubpassDependency>                                       deps;
6926                                                                 vector<VkInputAttachmentAspectReference>        inputAspects;
6927
6928                                                                 attachments.push_back(Attachment(format,
6929                                                                                                                                  VK_SAMPLE_COUNT_1_BIT,
6930                                                                                                                                  loadOp,
6931                                                                                                                                  storeOp,
6932                                                                                                                                  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6933                                                                                                                                  VK_ATTACHMENT_STORE_OP_DONT_CARE,
6934                                                                                                                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6935                                                                                                                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6936
6937                                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6938                                                                                                                         0u,
6939                                                                                                                         vector<AttachmentReference>(),
6940                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6941                                                                                                                         vector<AttachmentReference>(),
6942                                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6943                                                                                                                         vector<deUint32>()));
6944                                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6945                                                                                                                         0u,
6946                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
6947                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
6948                                                                                                                         vector<AttachmentReference>(),
6949                                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6950                                                                                                                         vector<deUint32>()));
6951
6952                                                                 deps.push_back(SubpassDependency(0, 1,
6953                                                                                                                                 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6954                                                                                                                                 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6955
6956                                                                                                                                 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6957                                                                                                                                 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6958                                                                                                                                 vk::VK_DEPENDENCY_BY_REGION_BIT));
6959
6960                                                                 deps.push_back(SubpassDependency(1, 1,
6961                                                                                                                                 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6962                                                                                                                                 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6963
6964                                                                                                                                 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6965                                                                                                                                 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6966                                                                                                                                 vk::VK_DEPENDENCY_BY_REGION_BIT));
6967
6968                                                                 if (useInputAspect)
6969                                                                 {
6970                                                                         const VkInputAttachmentAspectReference inputAspect =
6971                                                                         {
6972                                                                                 1u,
6973                                                                                 0u,
6974                                                                                 VK_IMAGE_ASPECT_COLOR_BIT
6975                                                                         };
6976
6977                                                                         inputAspects.push_back(inputAspect);
6978                                                                 }
6979
6980                                                                 {
6981                                                                         const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6982                                                                         const TestConfig testConfig (renderPass,
6983                                                                                                                                  renderTypes[renderTypeNdx].types,
6984                                                                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
6985                                                                                                                                  TestConfig::IMAGEMEMORY_STRICT,
6986                                                                                                                                  targetSize,
6987                                                                                                                                  renderPos,
6988                                                                                                                                  renderSize,
6989                                                                                                                                  DE_FALSE,
6990                                                                                                                                  89246,
6991                                                                                                                                  0,
6992                                                                                                                                  testConfigExternal.allocationKind,
6993                                                                                                                                  testConfigExternal.groupParams);
6994                                                                         const string    testName        (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""));
6995
6996                                                                         addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6997                                                                 }
6998                                                         }
6999                                                 }
7000                                         }
7001
7002                                         loadOpGroup->addChild(storeOpGroup.release());
7003                                 }
7004
7005                                 inputGroup->addChild(loadOpGroup.release());
7006                         }
7007
7008                         formatGroup->addChild(inputGroup.release());
7009                 }
7010
7011                 group->addChild(formatGroup.release());
7012         }
7013
7014         // Depth stencil formats
7015         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
7016         {
7017                 const VkFormat                                  vkFormat                        = s_coreDepthStencilFormats[formatNdx];
7018                 const tcu::TextureFormat                format                          = mapVkFormat(vkFormat);
7019                 const bool                                              isStencilAttachment     = hasStencilComponent(format.order);
7020                 const bool                                              isDepthAttachment       = hasDepthComponent(format.order);
7021                 const VkImageAspectFlags                formatAspectFlags       = (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7022                                                                                                                         | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u);
7023                 de::MovePtr<tcu::TestCaseGroup> formatGroup                     (new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
7024
7025                 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7026                 {
7027                         const VkAttachmentLoadOp                loadOp  = loadOps[loadOpNdx].op;
7028                         de::MovePtr<tcu::TestCaseGroup> loadOpGroup     (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
7029
7030                         for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7031                         {
7032                                 {
7033                                         const RenderPass        renderPass      (vector<Attachment>(1, Attachment(vkFormat,
7034                                                                                                                                                                           VK_SAMPLE_COUNT_1_BIT,
7035                                                                                                                                                                           isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7036                                                                                                                                                                           isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7037                                                                                                                                                                           isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7038                                                                                                                                                                           isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7039                                                                                                                                                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7040                                                                                                                                                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7041                                                                                                          vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7042                                                                                                                                                                 0u,
7043                                                                                                                                                                 vector<AttachmentReference>(),
7044                                                                                                                                                                 vector<AttachmentReference>(),
7045                                                                                                                                                                 vector<AttachmentReference>(),
7046                                                                                                                                                                 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7047                                                                                                                                                                 vector<deUint32>())),
7048                                                                                                          vector<SubpassDependency>());
7049                                         const TestConfig        testConfig      (renderPass,
7050                                                                                                          renderTypes[renderTypeNdx].types,
7051                                                                                                          TestConfig::COMMANDBUFFERTYPES_INLINE,
7052                                                                                                          TestConfig::IMAGEMEMORY_STRICT,
7053                                                                                                          targetSize,
7054                                                                                                          renderPos,
7055                                                                                                          renderSize,
7056                                                                                                          DE_FALSE,
7057                                                                                                          90239,
7058                                                                                                          0,
7059                                                                                                          testConfigExternal.allocationKind,
7060                                                                                                          testConfigExternal.groupParams);
7061
7062                                         addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7063                                 }
7064
7065                                 if (isStencilAttachment && isDepthAttachment && loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
7066                                 {
7067                                         {
7068                                                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(vkFormat,
7069                                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
7070                                                                                                                                                                   isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7071                                                                                                                                                                   isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7072                                                                                                                                                                   isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7073                                                                                                                                                                   isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7074                                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7075                                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7076                                                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7077                                                                                                                                                                         0u,
7078                                                                                                                                                                         vector<AttachmentReference>(),
7079                                                                                                                                                                         vector<AttachmentReference>(),
7080                                                                                                                                                                         vector<AttachmentReference>(),
7081                                                                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
7082                                                                                                                                                                         vector<deUint32>())),
7083                                                                                                                  vector<SubpassDependency>());
7084                                                 const TestConfig        testConfig      (renderPass,
7085                                                                                                                  renderTypes[renderTypeNdx].types,
7086                                                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
7087                                                                                                                  TestConfig::IMAGEMEMORY_STRICT,
7088                                                                                                                  targetSize,
7089                                                                                                                  renderPos,
7090                                                                                                                  renderSize,
7091                                                                                                                  DE_FALSE,
7092                                                                                                                  90239,
7093                                                                                                                  0,
7094                                                                                                                  testConfigExternal.allocationKind,
7095                                                                                                                  testConfigExternal.groupParams);
7096                                                 const string            testName        (string(renderTypes[renderTypeNdx].str) + "_depth_read_only");
7097
7098                                                 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7099                                         }
7100
7101                                         {
7102                                                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(vkFormat,
7103                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
7104                                                                                                                                                   isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7105                                                                                                                                                   isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7106                                                                                                                                                   isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7107                                                                                                                                                   isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7108                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7109                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7110                                                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7111                                                                                                                                                                         0u,
7112                                                                                                                                                                         vector<AttachmentReference>(),
7113                                                                                                                                                                         vector<AttachmentReference>(),
7114                                                                                                                                                                         vector<AttachmentReference>(),
7115                                                                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
7116                                                                                                                                                                         vector<deUint32>())),
7117                                                                                                                  vector<SubpassDependency>());
7118                                                 const TestConfig        testConfig      (renderPass,
7119                                                                                                                  renderTypes[renderTypeNdx].types,
7120                                                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
7121                                                                                                                  TestConfig::IMAGEMEMORY_STRICT,
7122                                                                                                                  targetSize,
7123                                                                                                                  renderPos,
7124                                                                                                                  renderSize,
7125                                                                                                                  DE_FALSE,
7126                                                                                                                  90239,
7127                                                                                                                  0,
7128                                                                                                                  testConfigExternal.allocationKind,
7129                                                                                                                  testConfigExternal.groupParams);
7130                                                 const string            testName        (string(renderTypes[renderTypeNdx].str) + "_stencil_read_only");
7131
7132                                                 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7133                                         }
7134                                 }
7135                         }
7136
7137                         formatGroup->addChild(loadOpGroup.release());
7138                 }
7139
7140                 if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7141                 {
7142                         de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
7143
7144                         for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7145                         {
7146                                 const VkAttachmentLoadOp                loadOp          = loadOps[loadOpNdx].op;
7147                                 de::MovePtr<tcu::TestCaseGroup> loadOpGroup     (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
7148
7149                                 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
7150                                 {
7151                                         const VkImageAspectFlags                inputAttachmentAspectMask       = (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
7152                                                                                                                                                                 ? formatAspectFlags
7153                                                                                                                                                                 : static_cast<VkImageAspectFlags>(0);
7154                                         const VkAttachmentStoreOp               storeOp                                         = storeOps[storeOpNdx].op;
7155                                         de::MovePtr<tcu::TestCaseGroup> storeOpGroup                            (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
7156
7157                                         for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
7158                                         {
7159                                                 const bool useInputAspect = useInputAspectNdx != 0;
7160
7161                                                 if (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2 && useInputAspect)
7162                                                         continue;
7163
7164                                                 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7165                                                 {
7166                                                         {
7167                                                                 vector<Attachment>                                                      attachments;
7168                                                                 vector<Subpass>                                                         subpasses;
7169                                                                 vector<SubpassDependency>                                       deps;
7170                                                                 vector<VkInputAttachmentAspectReference>        inputAspects;
7171
7172                                                                 attachments.push_back(Attachment(vkFormat,
7173                                                                                                                                  VK_SAMPLE_COUNT_1_BIT,
7174                                                                                                                                  loadOp,
7175                                                                                                                                  storeOp,
7176                                                                                                                                  loadOp,
7177                                                                                                                                  storeOp,
7178                                                                                                                                  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7179                                                                                                                                  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7180
7181                                                                 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7182                                                                                                                                  VK_SAMPLE_COUNT_1_BIT,
7183                                                                                                                                  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7184                                                                                                                                  VK_ATTACHMENT_STORE_OP_STORE,
7185                                                                                                                                  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7186                                                                                                                                  VK_ATTACHMENT_STORE_OP_DONT_CARE,
7187                                                                                                                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7188                                                                                                                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7189
7190                                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7191                                                                                                                         0u,
7192                                                                                                                         vector<AttachmentReference>(),
7193                                                                                                                         vector<AttachmentReference>(),
7194                                                                                                                         vector<AttachmentReference>(),
7195                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7196                                                                                                                         vector<deUint32>()));
7197                                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7198                                                                                                                         0u,
7199                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7200                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7201                                                                                                                         vector<AttachmentReference>(),
7202                                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7203                                                                                                                         vector<deUint32>()));
7204
7205                                                                 deps.push_back(SubpassDependency(0, 1,
7206                                                                                                                                 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7207                                                                                                                                 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7208
7209                                                                                                                                 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7210                                                                                                                                 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7211                                                                                                                                 0u));
7212
7213                                                                 if (useInputAspect)
7214                                                                 {
7215                                                                         const VkInputAttachmentAspectReference inputAspect =
7216                                                                         {
7217                                                                                 1u,
7218                                                                                 0u,
7219                                                                                 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7220                                                                                         | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7221                                                                         };
7222
7223                                                                         inputAspects.push_back(inputAspect);
7224                                                                 }
7225
7226                                                                 {
7227                                                                         const RenderPass        renderPass      (attachments, subpasses, deps, inputAspects);
7228                                                                         const TestConfig        testConfig      (renderPass,
7229                                                                                                                                          renderTypes[renderTypeNdx].types,
7230                                                                                                                                          TestConfig::COMMANDBUFFERTYPES_INLINE,
7231                                                                                                                                          TestConfig::IMAGEMEMORY_STRICT,
7232                                                                                                                                          targetSize,
7233                                                                                                                                          renderPos,
7234                                                                                                                                          renderSize,
7235                                                                                                                                          DE_FALSE,
7236                                                                                                                                          89246,
7237                                                                                                                                          0,
7238                                                                                                                                          testConfigExternal.allocationKind,
7239                                                                                                                                          testConfigExternal.groupParams);
7240                                                                         const string            testName        (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""));
7241
7242                                                                         addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7243                                                                 }
7244                                                         }
7245                                                         {
7246                                                                 vector<Attachment>                                                      attachments;
7247                                                                 vector<Subpass>                                                         subpasses;
7248                                                                 vector<SubpassDependency>                                       deps;
7249                                                                 vector<VkInputAttachmentAspectReference>        inputAspects;
7250
7251                                                                 attachments.push_back(Attachment(vkFormat,
7252                                                                                                                                  VK_SAMPLE_COUNT_1_BIT,
7253                                                                                                                                  loadOp,
7254                                                                                                                                  storeOp,
7255                                                                                                                                  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7256                                                                                                                                  VK_ATTACHMENT_STORE_OP_DONT_CARE,
7257                                                                                                                                  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7258                                                                                                                                  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7259
7260                                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7261                                                                                                                         0u,
7262                                                                                                                         vector<AttachmentReference>(),
7263                                                                                                                         vector<AttachmentReference>(),
7264                                                                                                                         vector<AttachmentReference>(),
7265                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7266                                                                                                                         vector<deUint32>()));
7267                                                                 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7268                                                                                                                         0u,
7269                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
7270                                                                                                                         vector<AttachmentReference>(),
7271                                                                                                                         vector<AttachmentReference>(),
7272                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL),
7273                                                                                                                         vector<deUint32>()));
7274
7275                                                                 deps.push_back(SubpassDependency(0, 1,
7276                                                                                                                                 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7277                                                                                                                                 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7278
7279                                                                                                                                 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7280                                                                                                                                 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7281                                                                                                                                 vk::VK_DEPENDENCY_BY_REGION_BIT));
7282
7283                                                                 deps.push_back(SubpassDependency(1, 1,
7284                                                                                                                                 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7285                                                                                                                                 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7286                                                                                                                                 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7287                                                                                                                                 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7288                                                                                                                                 vk::VK_DEPENDENCY_BY_REGION_BIT));
7289
7290
7291                                                                 if (useInputAspect)
7292                                                                 {
7293                                                                         const VkInputAttachmentAspectReference inputAspect =
7294                                                                         {
7295                                                                                 1u,
7296                                                                                 0u,
7297
7298                                                                                 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7299                                                                                         | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7300                                                                         };
7301
7302                                                                         inputAspects.push_back(inputAspect);
7303                                                                 }
7304
7305                                                                 {
7306                                                                         const RenderPass        renderPass      (attachments, subpasses, deps, inputAspects);
7307                                                                         const TestConfig        testConfig      (renderPass,
7308                                                                                                                                          renderTypes[renderTypeNdx].types,
7309                                                                                                                                          TestConfig::COMMANDBUFFERTYPES_INLINE,
7310                                                                                                                                          TestConfig::IMAGEMEMORY_STRICT,
7311                                                                                                                                          targetSize,
7312                                                                                                                                          renderPos,
7313                                                                                                                                          renderSize,
7314                                                                                                                                          DE_FALSE,
7315                                                                                                                                          89246,
7316                                                                                                                                          0,
7317                                                                                                                                          testConfigExternal.allocationKind,
7318                                                                                                                                          testConfigExternal.groupParams);
7319                                                                         const string            testName        (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""));
7320
7321                                                                         addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7322                                                                 }
7323                                                         }
7324
7325                                                         if (isStencilAttachment && isDepthAttachment)
7326                                                         {
7327                                                                 // Depth read only
7328                                                                 {
7329                                                                         vector<Attachment>                                                      attachments;
7330                                                                         vector<Subpass>                                                         subpasses;
7331                                                                         vector<SubpassDependency>                                       deps;
7332                                                                         vector<VkInputAttachmentAspectReference>        inputAspects;
7333
7334                                                                         attachments.push_back(Attachment(vkFormat,
7335                                                                                                                                          VK_SAMPLE_COUNT_1_BIT,
7336                                                                                                                                          loadOp,
7337                                                                                                                                          storeOp,
7338                                                                                                                                          loadOp,
7339                                                                                                                                          storeOp,
7340                                                                                                                                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7341                                                                                                                                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7342
7343                                                                         attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7344                                                                                                                                          VK_SAMPLE_COUNT_1_BIT,
7345                                                                                                                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7346                                                                                                                                          VK_ATTACHMENT_STORE_OP_STORE,
7347                                                                                                                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7348                                                                                                                                          VK_ATTACHMENT_STORE_OP_DONT_CARE,
7349                                                                                                                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7350                                                                                                                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7351
7352                                                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7353                                                                                                                                 0u,
7354                                                                                                                                 vector<AttachmentReference>(),
7355                                                                                                                                 vector<AttachmentReference>(),
7356                                                                                                                                 vector<AttachmentReference>(),
7357                                                                                                                                 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7358                                                                                                                                 vector<deUint32>()));
7359                                                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7360                                                                                                                                 0u,
7361                                                                                                                                 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, inputAttachmentAspectMask)),
7362                                                                                                                                 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7363                                                                                                                                 vector<AttachmentReference>(),
7364                                                                                                                                 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7365                                                                                                                                 vector<deUint32>()));
7366
7367                                                                         deps.push_back(SubpassDependency(0, 1,
7368                                                                                                                                         vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7369                                                                                                                                         vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7370
7371                                                                                                                                         vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7372                                                                                                                                         vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7373                                                                                                                                         0u));
7374
7375                                                                         if (useInputAspect)
7376                                                                         {
7377                                                                                 const VkInputAttachmentAspectReference inputAspect =
7378                                                                                 {
7379                                                                                         1u,
7380                                                                                         0u,
7381
7382                                                                                         (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7383                                                                                                 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7384                                                                                 };
7385
7386                                                                                 inputAspects.push_back(inputAspect);
7387                                                                         }
7388
7389                                                                         {
7390                                                                                 const RenderPass        renderPass       (attachments, subpasses, deps, inputAspects);
7391                                                                                 const TestConfig        testConfig       (renderPass,
7392                                                                                                                                                  renderTypes[renderTypeNdx].types,
7393                                                                                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
7394                                                                                                                                                  TestConfig::IMAGEMEMORY_STRICT,
7395                                                                                                                                                  targetSize,
7396                                                                                                                                                  renderPos,
7397                                                                                                                                                  renderSize,
7398                                                                                                                                                  DE_FALSE,
7399                                                                                                                                                  89246,
7400                                                                                                                                                  0,
7401                                                                                                                                                  testConfigExternal.allocationKind,
7402                                                                                                                                                  testConfigExternal.groupParams);
7403                                                                                 const string            testName        (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only");
7404
7405                                                                                 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7406                                                                         }
7407                                                                 }
7408                                                                 {
7409                                                                         vector<Attachment>                                                      attachments;
7410                                                                         vector<Subpass>                                                         subpasses;
7411                                                                         vector<SubpassDependency>                                       deps;
7412                                                                         vector<VkInputAttachmentAspectReference>        inputAspects;
7413
7414                                                                         attachments.push_back(Attachment(vkFormat,
7415                                                                                                                                          VK_SAMPLE_COUNT_1_BIT,
7416                                                                                                                                          loadOp,
7417                                                                                                                                          storeOp,
7418                                                                                                                                          loadOp,
7419                                                                                                                                          storeOp,
7420                                                                                                                                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7421                                                                                                                                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7422
7423                                                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7424                                                                                                                                 0u,
7425                                                                                                                                 vector<AttachmentReference>(),
7426                                                                                                                                 vector<AttachmentReference>(),
7427                                                                                                                                 vector<AttachmentReference>(),
7428                                                                                                                                 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7429                                                                                                                                 vector<deUint32>()));
7430                                                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7431                                                                                                                                 0u,
7432                                                                                                                                 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, inputAttachmentAspectMask)),
7433                                                                                                                                 vector<AttachmentReference>(),
7434                                                                                                                                 vector<AttachmentReference>(),
7435                                                                                                                                 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
7436                                                                                                                                 vector<deUint32>()));
7437
7438                                                                         deps.push_back(SubpassDependency(0, 1,
7439                                                                                                                                         vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7440                                                                                                                                         vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7441
7442                                                                                                                                         vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7443                                                                                                                                         vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7444                                                                                                                                         vk::VK_DEPENDENCY_BY_REGION_BIT));
7445
7446                                                                         deps.push_back(SubpassDependency(1, 1,
7447                                                                                                                                         vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7448                                                                                                                                         vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7449
7450                                                                                                                                         vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7451                                                                                                                                         vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7452                                                                                                                                         vk::VK_DEPENDENCY_BY_REGION_BIT));
7453
7454                                                                         if (useInputAspect)
7455                                                                         {
7456                                                                                 const VkInputAttachmentAspectReference inputAspect =
7457                                                                                 {
7458                                                                                         1u,
7459                                                                                         0u,
7460
7461                                                                                         (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7462                                                                                                 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7463                                                                                 };
7464
7465                                                                                 inputAspects.push_back(inputAspect);
7466                                                                         }
7467
7468                                                                         {
7469                                                                                 const RenderPass        renderPass      (attachments, subpasses, deps, inputAspects);
7470                                                                                 const TestConfig        testConfig      (renderPass,
7471                                                                                                                                                  renderTypes[renderTypeNdx].types,
7472                                                                                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
7473                                                                                                                                                  TestConfig::IMAGEMEMORY_STRICT,
7474                                                                                                                                                  targetSize,
7475                                                                                                                                                  renderPos,
7476                                                                                                                                                  renderSize,
7477                                                                                                                                                  DE_FALSE,
7478                                                                                                                                                  89246,
7479                                                                                                                                                  0,
7480                                                                                                                                                  testConfigExternal.allocationKind,
7481                                                                                                                                                  testConfigExternal.groupParams);
7482                                                                                 const string            testName        (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only");
7483
7484                                                                                 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7485                                                                         }
7486                                                                 }
7487                                                                 // Stencil read only
7488                                                                 {
7489                                                                         vector<Attachment>                                                      attachments;
7490                                                                         vector<Subpass>                                                         subpasses;
7491                                                                         vector<SubpassDependency>                                       deps;
7492                                                                         vector<VkInputAttachmentAspectReference>        inputAspects;
7493
7494                                                                         attachments.push_back(Attachment(vkFormat,
7495                                                                                                                                          VK_SAMPLE_COUNT_1_BIT,
7496                                                                                                                                          loadOp,
7497                                                                                                                                          storeOp,
7498                                                                                                                                          loadOp,
7499                                                                                                                                          storeOp,
7500                                                                                                                                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7501                                                                                                                                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7502
7503                                                                         attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7504                                                                                                                                          VK_SAMPLE_COUNT_1_BIT,
7505                                                                                                                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7506                                                                                                                                          VK_ATTACHMENT_STORE_OP_STORE,
7507                                                                                                                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7508                                                                                                                                          VK_ATTACHMENT_STORE_OP_DONT_CARE,
7509                                                                                                                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7510                                                                                                                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7511
7512                                                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7513                                                                                                                                 0u,
7514                                                                                                                                 vector<AttachmentReference>(),
7515                                                                                                                                 vector<AttachmentReference>(),
7516                                                                                                                                 vector<AttachmentReference>(),
7517                                                                                                                                 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7518                                                                                                                                 vector<deUint32>()));
7519                                                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7520                                                                                                                                 0u,
7521                                                                                                                                 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7522                                                                                                                                 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7523                                                                                                                                 vector<AttachmentReference>(),
7524                                                                                                                                 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7525                                                                                                                                 vector<deUint32>()));
7526
7527                                                                         deps.push_back(SubpassDependency(0, 1,
7528                                                                                                                                         vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7529                                                                                                                                         vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7530
7531                                                                                                                                         vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7532                                                                                                                                         vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7533                                                                                                                                         0u));
7534
7535                                                                         if (useInputAspect)
7536                                                                         {
7537                                                                                 const VkInputAttachmentAspectReference inputAspect =
7538                                                                                 {
7539                                                                                         1u,
7540                                                                                         0u,
7541
7542                                                                                         (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7543                                                                                                 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7544                                                                                 };
7545
7546                                                                                 inputAspects.push_back(inputAspect);
7547                                                                         }
7548
7549                                                                         {
7550                                                                                 const RenderPass        renderPass      (attachments, subpasses, deps, inputAspects);
7551                                                                                 const TestConfig        testConfig      (renderPass,
7552                                                                                                                                                  renderTypes[renderTypeNdx].types,
7553                                                                                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
7554                                                                                                                                                  TestConfig::IMAGEMEMORY_STRICT,
7555                                                                                                                                                  targetSize,
7556                                                                                                                                                  renderPos,
7557                                                                                                                                                  renderSize,
7558                                                                                                                                                  DE_FALSE,
7559                                                                                                                                                  89246,
7560                                                                                                                                                  0,
7561                                                                                                                                                  testConfigExternal.allocationKind,
7562                                                                                                                                                  testConfigExternal.groupParams);
7563                                                                                 const string            testName        (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only");
7564
7565                                                                                 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7566                                                                         }
7567                                                                 }
7568                                                                 {
7569                                                                         vector<Attachment>                                                      attachments;
7570                                                                         vector<Subpass>                                                         subpasses;
7571                                                                         vector<SubpassDependency>                                       deps;
7572                                                                         vector<VkInputAttachmentAspectReference>        inputAspects;
7573
7574                                                                         attachments.push_back(Attachment(vkFormat,
7575                                                                                                                                          VK_SAMPLE_COUNT_1_BIT,
7576                                                                                                                                          loadOp,
7577                                                                                                                                          storeOp,
7578                                                                                                                                          loadOp,
7579                                                                                                                                          storeOp,
7580                                                                                                                                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7581                                                                                                                                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7582
7583                                                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7584                                                                                                                                 0u,
7585                                                                                                                                 vector<AttachmentReference>(),
7586                                                                                                                                 vector<AttachmentReference>(),
7587                                                                                                                                 vector<AttachmentReference>(),
7588                                                                                                                                 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7589                                                                                                                                 vector<deUint32>()));
7590                                                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7591                                                                                                                                 0u,
7592                                                                                                                                 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7593                                                                                                                                 vector<AttachmentReference>(),
7594                                                                                                                                 vector<AttachmentReference>(),
7595                                                                                                                                 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
7596                                                                                                                                 vector<deUint32>()));
7597
7598                                                                         deps.push_back(SubpassDependency(0, 1,
7599                                                                                                                                         vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7600                                                                                                                                         vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7601
7602                                                                                                                                         vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7603                                                                                                                                         vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7604                                                                                                                                         vk::VK_DEPENDENCY_BY_REGION_BIT));
7605
7606                                                                         deps.push_back(SubpassDependency(1, 1,
7607                                                                                                                                         vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7608                                                                                                                                         vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7609
7610                                                                                                                                         vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7611                                                                                                                                         vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7612                                                                                                                                         vk::VK_DEPENDENCY_BY_REGION_BIT));
7613
7614
7615                                                                         if (useInputAspect)
7616                                                                         {
7617                                                                                 const VkInputAttachmentAspectReference inputAspect =
7618                                                                                 {
7619                                                                                         1u,
7620                                                                                         0u,
7621
7622                                                                                         (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7623                                                                                                 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7624                                                                                 };
7625
7626                                                                                 inputAspects.push_back(inputAspect);
7627                                                                         }
7628
7629                                                                         {
7630                                                                                 const RenderPass        renderPass      (attachments, subpasses, deps, inputAspects);
7631                                                                                 const TestConfig        testConfig      (renderPass,
7632                                                                                                                                                  renderTypes[renderTypeNdx].types,
7633                                                                                                                                                  TestConfig::COMMANDBUFFERTYPES_INLINE,
7634                                                                                                                                                  TestConfig::IMAGEMEMORY_STRICT,
7635                                                                                                                                                  targetSize,
7636                                                                                                                                                  renderPos,
7637                                                                                                                                                  renderSize,
7638                                                                                                                                                  DE_FALSE,
7639                                                                                                                                                  89246,
7640                                                                                                                                                  0,
7641                                                                                                                                                  testConfigExternal.allocationKind,
7642                                                                                                                                                  testConfigExternal.groupParams);
7643                                                                                 const string            testName        (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only");
7644
7645                                                                                 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7646                                                                         }
7647                                                                 }
7648                                                         }
7649                                                 }
7650                                         }
7651
7652                                         loadOpGroup->addChild(storeOpGroup.release());
7653                                 }
7654
7655                                 inputGroup->addChild(loadOpGroup.release());
7656                         }
7657
7658                         formatGroup->addChild(inputGroup.release());
7659                 }
7660
7661                 group->addChild(formatGroup.release());
7662         }
7663 }
7664
7665 void addRenderPassTests (tcu::TestCaseGroup* group, const AllocationKind allocationKind, const SharedGroupParams groupParams)
7666 {
7667         // tests added by this function have both primary and secondary cases and there is no need to repeat them for useSecondaryCmdBuffer flag;
7668         // but cases defined in other files that are later added to those groups in createRenderPassTestsInternal had to be adjusted and run
7669         // for useSecondaryCmdBuffer flag
7670         if (groupParams->useSecondaryCmdBuffer && !groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
7671                 return;
7672
7673         const TestConfigExternal        testConfigExternal      (allocationKind, groupParams);
7674
7675         // don't repeat cases that don't use CommandBufferTypes::COMMANDBUFFERTYPES_SECONDARY
7676         if (!groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
7677         {
7678                 addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, testConfigExternal);
7679                 addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, testConfigExternal);
7680         }
7681
7682         addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, testConfigExternal);
7683
7684         // don't repeat cases that don't use CommandBufferTypes::COMMANDBUFFERTYPES_SECONDARY
7685         if (!groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
7686                 addTestGroup(group, "attachment_write_mask", "Attachment write mask tests", addAttachmentWriteMaskTests, testConfigExternal);
7687
7688         if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7689                 addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, testConfigExternal);
7690 }
7691
7692 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx, const SharedGroupParams groupParams)
7693 {
7694         de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests"));
7695
7696         addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED, groupParams);
7697
7698         return suballocationTestsGroup;
7699 }
7700
7701 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx, const SharedGroupParams groupParams)
7702 {
7703         de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation"));
7704
7705         addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED, groupParams);
7706
7707         return dedicatedAllocationTestsGroup;
7708 }
7709
7710 tcu::TestCaseGroup* createRenderPassTestsInternal (tcu::TestContext& testCtx, const char* groupName, const SharedGroupParams groupParams)
7711 {
7712         de::MovePtr<tcu::TestCaseGroup> renderingTests                                  (new tcu::TestCaseGroup(testCtx, groupName, ""));
7713         de::MovePtr<tcu::TestCaseGroup> suballocationTestGroup                  = createSuballocationTests(testCtx, groupParams);
7714         de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestGroup    = createDedicatedAllocationTests(testCtx, groupParams);
7715
7716         const RenderingType renderingType = groupParams->renderingType;
7717
7718         switch (renderingType)
7719         {
7720         case RENDERING_TYPE_RENDERPASS_LEGACY:
7721                 suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx));
7722                 suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx, groupParams));
7723                 suballocationTestGroup->addChild(createRenderPassSubpassDependencyTests(testCtx));
7724                 suballocationTestGroup->addChild(createRenderPassSampleReadTests(testCtx));
7725
7726 #ifndef CTS_USES_VULKANSC
7727                 suballocationTestGroup->addChild(createRenderPassSparseRenderTargetTests(testCtx, groupParams));
7728                 renderingTests->addChild(createDepthStencilWriteConditionsTests(testCtx));
7729 #endif // CTS_USES_VULKANSC
7730
7731                 renderingTests->addChild(createRenderPassMultipleSubpassesMultipleCommandBuffersTests(testCtx));
7732
7733                 break;
7734
7735         case RENDERING_TYPE_RENDERPASS2:
7736                 suballocationTestGroup->addChild(createRenderPass2MultisampleTests(testCtx));
7737                 suballocationTestGroup->addChild(createRenderPass2MultisampleResolveTests(testCtx, groupParams));
7738                 suballocationTestGroup->addChild(createRenderPass2SubpassDependencyTests(testCtx));
7739                 suballocationTestGroup->addChild(createRenderPass2SampleReadTests(testCtx));
7740
7741 #ifndef CTS_USES_VULKANSC
7742                 suballocationTestGroup->addChild(createRenderPass2SparseRenderTargetTests(testCtx, groupParams));
7743 #endif // CTS_USES_VULKANSC
7744
7745                 renderingTests->addChild(createRenderPass2DepthStencilResolveTests(testCtx));
7746                 break;
7747
7748 #ifndef CTS_USES_VULKANSC
7749         case RENDERING_TYPE_DYNAMIC_RENDERING:
7750                 suballocationTestGroup->addChild(createDynamicRenderingMultisampleResolveTests(testCtx, groupParams));
7751                 suballocationTestGroup->addChild(createDynamicRenderingSparseRenderTargetTests(testCtx, groupParams));
7752
7753                 if (groupParams->useSecondaryCmdBuffer == false)
7754                 {
7755                         renderingTests->addChild(createDynamicRenderingRandomTests(testCtx));
7756                         renderingTests->addChild(createDynamicRenderingBasicTests(testCtx));
7757                 }
7758                 break;
7759 #endif // CTS_USES_VULKANSC
7760
7761         default:
7762                 break;
7763         }
7764
7765         if (renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7766         {
7767                 suballocationTestGroup->addChild(createRenderPassUnusedAttachmentTests(testCtx, renderingType));
7768                 suballocationTestGroup->addChild(createRenderPassUnusedAttachmentSparseFillingTests(testCtx, renderingType));
7769         }
7770
7771         suballocationTestGroup->addChild(createRenderPassUnusedClearAttachmentTests(testCtx, groupParams));
7772
7773 #ifndef CTS_USES_VULKANSC
7774         suballocationTestGroup->addChild(createRenderPassLoadStoreOpNoneTests(testCtx, groupParams));
7775
7776         if (renderingType == RENDERING_TYPE_RENDERPASS2)
7777         {
7778                 suballocationTestGroup->addChild(createRenderPassSubpassMergeFeedbackTests(testCtx, renderingType));
7779         }
7780
7781         renderingTests->addChild(createFragmentDensityMapTests(testCtx, groupParams));
7782         renderingTests->addChild(createRenderPassDitheringTests(testCtx, renderingType));
7783 #endif // CTS_USES_VULKANSC
7784
7785         renderingTests->addChild(suballocationTestGroup.release());
7786         renderingTests->addChild(dedicatedAllocationTestGroup.release());
7787
7788         return renderingTests.release();
7789 }
7790
7791 } // anonymous
7792
7793 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
7794 {
7795         SharedGroupParams groupParams(
7796                 new GroupParams
7797                 {
7798                         RENDERING_TYPE_RENDERPASS_LEGACY,       // RenderingType renderingType;
7799                         false,                                                          // bool useSecondaryCmdBuffer;
7800                         false,                                                          // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
7801                 });
7802         return createRenderPassTestsInternal(testCtx, "renderpass", groupParams);
7803 }
7804
7805 tcu::TestCaseGroup* createRenderPass2Tests (tcu::TestContext& testCtx)
7806 {
7807         SharedGroupParams groupParams(
7808                 new GroupParams
7809                 {
7810                         RENDERING_TYPE_RENDERPASS2,                     // RenderingType renderingType;
7811                         false,                                                          // bool useSecondaryCmdBuffer;
7812                         false,                                                          // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
7813                 });
7814         return createRenderPassTestsInternal(testCtx, "renderpass2", groupParams);
7815 }
7816
7817 tcu::TestCaseGroup* createDynamicRenderingTests(tcu::TestContext& testCtx)
7818 {
7819         de::MovePtr<tcu::TestCaseGroup> dynamicRenderingGroup(new tcu::TestCaseGroup(testCtx, "dynamic_rendering", "Draw using VK_KHR_dynamic_rendering"));
7820
7821         dynamicRenderingGroup->addChild(createRenderPassTestsInternal(testCtx, "primary_cmd_buff", SharedGroupParams(
7822                 new GroupParams
7823                 {
7824                         RENDERING_TYPE_DYNAMIC_RENDERING,       // RenderingType renderingType;
7825                         false,                                                          // bool useSecondaryCmdBuffer;
7826                         false,                                                          // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
7827                 })));
7828         dynamicRenderingGroup->addChild(createRenderPassTestsInternal(testCtx, "partial_secondary_cmd_buff", SharedGroupParams(
7829                 new GroupParams
7830                 {
7831                         RENDERING_TYPE_DYNAMIC_RENDERING,       // RenderingType renderingType;
7832                         true,                                                           // bool useSecondaryCmdBuffer;
7833                         false,                                                          // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
7834                 })));
7835         dynamicRenderingGroup->addChild(createRenderPassTestsInternal(testCtx, "complete_secondary_cmd_buff", SharedGroupParams(
7836                 new GroupParams
7837                 {
7838                         RENDERING_TYPE_DYNAMIC_RENDERING,       // RenderingType renderingType;
7839                         true,                                                           // bool useSecondaryCmdBuffer;
7840                         true,                                                           // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
7841                 })));
7842
7843         return dynamicRenderingGroup.release();
7844 }
7845
7846 } // vkt