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