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