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