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