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