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