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