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