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