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