dEQP-VK.renderpass.grow and others: do not use DEPTH layouts for color images, and...
[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  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and/or associated documentation files (the
9  * "Materials"), to deal in the Materials without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Materials, and to
12  * permit persons to whom the Materials are furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice(s) and this permission notice shall be
16  * included in all copies or substantial portions of the Materials.
17  *
18  * The Materials are Confidential Information as defined by the
19  * Khronos Membership Agreement until designated non-confidential by
20  * Khronos, at which point this condition clause shall be removed.
21  *
22  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
29  *
30  *//*!
31  * \file
32  * \brief RenderPass tests
33  *//*--------------------------------------------------------------------*/
34
35 #include "vktRenderPassTests.hpp"
36
37 #include "vktTestCaseUtil.hpp"
38
39 #include "vkDefs.hpp"
40 #include "vkDeviceUtil.hpp"
41 #include "vkImageUtil.hpp"
42 #include "vkMemUtil.hpp"
43 #include "vkPlatform.hpp"
44 #include "vkPrograms.hpp"
45 #include "vkQueryUtil.hpp"
46 #include "vkRef.hpp"
47 #include "vkRefUtil.hpp"
48 #include "vkStrUtil.hpp"
49 #include "vkTypeUtil.hpp"
50
51 #include "tcuTestLog.hpp"
52 #include "tcuResultCollector.hpp"
53 #include "tcuFormatUtil.hpp"
54 #include "tcuTextureUtil.hpp"
55 #include "tcuFloat.hpp"
56 #include "tcuMaybe.hpp"
57 #include "tcuVectorUtil.hpp"
58
59 #include "deUniquePtr.hpp"
60 #include "deSharedPtr.hpp"
61 #include "deStringUtil.hpp"
62 #include "deSTLUtil.hpp"
63 #include "deRandom.hpp"
64
65 #include <limits>
66
67 using namespace vk;
68
69 using tcu::Maybe;
70 using tcu::nothing;
71 using tcu::just;
72 using tcu::TestLog;
73 using tcu::Vec2;
74 using tcu::IVec2;
75 using tcu::UVec2;
76 using tcu::IVec4;
77 using tcu::UVec4;
78 using tcu::Vec4;
79 using tcu::BVec4;
80 using tcu::ConstPixelBufferAccess;
81 using tcu::PixelBufferAccess;
82
83 using de::UniquePtr;
84
85 using std::vector;
86 using std::string;
87
88 namespace vkt
89 {
90 namespace
91 {
92 enum
93 {
94         STENCIL_VALUE = 84u,
95         // Limit integer values that are representable as floats
96         MAX_INTEGER_VALUE = ((1u<<22u)-1u)
97 };
98
99 // Utility functions using flattened structs
100 Move<VkFence> createFence (const DeviceInterface& vk, VkDevice device, VkFenceCreateFlags flags)
101 {
102         const VkFenceCreateInfo pCreateInfo =
103         {
104                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
105                 DE_NULL,
106
107                 flags
108         };
109         return createFence(vk, device, &pCreateInfo);
110 }
111
112 Move<VkFramebuffer> createFramebuffer (const DeviceInterface&   vk,
113                                                                            VkDevice                                     device,
114                                                                            VkFramebufferCreateFlags     pCreateInfo_flags,
115                                                                            VkRenderPass                         pCreateInfo_renderPass,
116                                                                            deUint32                                     pCreateInfo_attachmentCount,
117                                                                            const VkImageView*           pCreateInfo_pAttachments,
118                                                                            deUint32                                     pCreateInfo_width,
119                                                                            deUint32                                     pCreateInfo_height,
120                                                                            deUint32                                     pCreateInfo_layers)
121 {
122         const VkFramebufferCreateInfo pCreateInfo =
123         {
124                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
125                 DE_NULL,
126                 pCreateInfo_flags,
127                 pCreateInfo_renderPass,
128                 pCreateInfo_attachmentCount,
129                 pCreateInfo_pAttachments,
130                 pCreateInfo_width,
131                 pCreateInfo_height,
132                 pCreateInfo_layers,
133         };
134         return createFramebuffer(vk, device, &pCreateInfo);
135 }
136
137 Move<VkImage> createImage (const DeviceInterface&       vk,
138                                                    VkDevice                                     device,
139                                                    VkImageCreateFlags           pCreateInfo_flags,
140                                                    VkImageType                          pCreateInfo_imageType,
141                                                    VkFormat                                     pCreateInfo_format,
142                                                    VkExtent3D                           pCreateInfo_extent,
143                                                    deUint32                                     pCreateInfo_mipLevels,
144                                                    deUint32                                     pCreateInfo_arrayLayers,
145                                                    VkSampleCountFlagBits        pCreateInfo_samples,
146                                                    VkImageTiling                        pCreateInfo_tiling,
147                                                    VkImageUsageFlags            pCreateInfo_usage,
148                                                    VkSharingMode                        pCreateInfo_sharingMode,
149                                                    deUint32                                     pCreateInfo_queueFamilyCount,
150                                                    const deUint32*                      pCreateInfo_pQueueFamilyIndices,
151                                                    VkImageLayout                        pCreateInfo_initialLayout)
152 {
153         const VkImageCreateInfo pCreateInfo =
154         {
155                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
156                 DE_NULL,
157                 pCreateInfo_flags,
158                 pCreateInfo_imageType,
159                 pCreateInfo_format,
160                 pCreateInfo_extent,
161                 pCreateInfo_mipLevels,
162                 pCreateInfo_arrayLayers,
163                 pCreateInfo_samples,
164                 pCreateInfo_tiling,
165                 pCreateInfo_usage,
166                 pCreateInfo_sharingMode,
167                 pCreateInfo_queueFamilyCount,
168                 pCreateInfo_pQueueFamilyIndices,
169                 pCreateInfo_initialLayout
170         };
171         return createImage(vk, device, &pCreateInfo);
172 }
173
174 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
175 {
176         VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
177 }
178
179 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
180 {
181         VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
182 }
183
184 Move<VkImageView> createImageView (const DeviceInterface&       vk,
185                                                                         VkDevice                                device,
186                                                                         VkImageViewCreateFlags  pCreateInfo_flags,
187                                                                         VkImage                                 pCreateInfo_image,
188                                                                         VkImageViewType                 pCreateInfo_viewType,
189                                                                         VkFormat                                pCreateInfo_format,
190                                                                         VkComponentMapping              pCreateInfo_components,
191                                                                         VkImageSubresourceRange pCreateInfo_subresourceRange)
192 {
193         const VkImageViewCreateInfo pCreateInfo =
194         {
195                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
196                 DE_NULL,
197                 pCreateInfo_flags,
198                 pCreateInfo_image,
199                 pCreateInfo_viewType,
200                 pCreateInfo_format,
201                 pCreateInfo_components,
202                 pCreateInfo_subresourceRange,
203         };
204         return createImageView(vk, device, &pCreateInfo);
205 }
206
207 Move<VkBuffer> createBuffer (const DeviceInterface&     vk,
208                                                          VkDevice                               device,
209                                                          VkBufferCreateFlags    pCreateInfo_flags,
210                                                          VkDeviceSize                   pCreateInfo_size,
211                                                          VkBufferUsageFlags             pCreateInfo_usage,
212                                                          VkSharingMode                  pCreateInfo_sharingMode,
213                                                          deUint32                               pCreateInfo_queueFamilyCount,
214                                                          const deUint32*                pCreateInfo_pQueueFamilyIndices)
215 {
216         const VkBufferCreateInfo pCreateInfo =
217         {
218                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
219                 DE_NULL,
220                 pCreateInfo_flags,
221                 pCreateInfo_size,
222                 pCreateInfo_usage,
223                 pCreateInfo_sharingMode,
224                 pCreateInfo_queueFamilyCount,
225                 pCreateInfo_pQueueFamilyIndices,
226         };
227         return createBuffer(vk, device, &pCreateInfo);
228 }
229
230 Move<VkCommandPool> createCommandPool (const DeviceInterface&   vk,
231                                                                            VkDevice                                     device,
232                                                                            VkCommandPoolCreateFlags     pCreateInfo_flags,
233                                                                            deUint32                                     pCreateInfo_queueFamilyIndex)
234 {
235         const VkCommandPoolCreateInfo pCreateInfo =
236         {
237                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
238                 DE_NULL,
239                 pCreateInfo_flags,
240                 pCreateInfo_queueFamilyIndex,
241         };
242         return createCommandPool(vk, device, &pCreateInfo);
243 }
244
245 void cmdBeginRenderPass (const DeviceInterface& vk,
246                                                  VkCommandBuffer                cmdBuffer,
247                                                  VkRenderPass                   pRenderPassBegin_renderPass,
248                                                  VkFramebuffer                  pRenderPassBegin_framebuffer,
249                                                  VkRect2D                               pRenderPassBegin_renderArea,
250                                                  deUint32                               pRenderPassBegin_clearValueCount,
251                                                  const VkClearValue*    pRenderPassBegin_pAttachmentClearValues,
252                                                  VkSubpassContents              contents)
253 {
254         const VkRenderPassBeginInfo pRenderPassBegin =
255         {
256                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
257                 DE_NULL,
258                 pRenderPassBegin_renderPass,
259                 pRenderPassBegin_framebuffer,
260                 pRenderPassBegin_renderArea,
261                 pRenderPassBegin_clearValueCount,
262                 pRenderPassBegin_pAttachmentClearValues,
263         };
264         vk.cmdBeginRenderPass(cmdBuffer, &pRenderPassBegin, contents);
265 }
266
267 Move<VkCommandBuffer> allocateCommandBuffer (const DeviceInterface&     vk,
268                                                                                          VkDevice                               device,
269                                                                                          VkCommandPool                  pCreateInfo_commandPool,
270                                                                                          VkCommandBufferLevel   pCreateInfo_level)
271 {
272         const VkCommandBufferAllocateInfo pAllocateInfo =
273         {
274                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
275                 DE_NULL,
276                 pCreateInfo_commandPool,
277                 pCreateInfo_level,
278                 1u,                                                                                             // bufferCount
279         };
280         return allocateCommandBuffer(vk, device, &pAllocateInfo);
281 }
282
283 void beginCommandBuffer (const DeviceInterface&                 vk,
284                                                  VkCommandBuffer                                cmdBuffer,
285                                                  VkCommandBufferUsageFlags              pBeginInfo_flags,
286                                                  VkRenderPass                                   pInheritanceInfo_renderPass,
287                                                  deUint32                                               pInheritanceInfo_subpass,
288                                                  VkFramebuffer                                  pInheritanceInfo_framebuffer,
289                                                  VkBool32                                               pInheritanceInfo_occlusionQueryEnable,
290                                                  VkQueryControlFlags                    pInheritanceInfo_queryFlags,
291                                                  VkQueryPipelineStatisticFlags  pInheritanceInfo_pipelineStatistics)
292 {
293         const VkCommandBufferInheritanceInfo    pInheritanceInfo        =
294         {
295                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
296                 DE_NULL,
297                 pInheritanceInfo_renderPass,
298                 pInheritanceInfo_subpass,
299                 pInheritanceInfo_framebuffer,
300                 pInheritanceInfo_occlusionQueryEnable,
301                 pInheritanceInfo_queryFlags,
302                 pInheritanceInfo_pipelineStatistics,
303         };
304         const VkCommandBufferBeginInfo                  pBeginInfo                      =
305         {
306                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
307                 DE_NULL,
308                 pBeginInfo_flags,
309                 &pInheritanceInfo,
310         };
311         VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
312 }
313
314 void endCommandBuffer (const DeviceInterface& vk, VkCommandBuffer cmdBuffer)
315 {
316         VK_CHECK(vk.endCommandBuffer(cmdBuffer));
317 }
318
319 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
320 {
321         const VkSubmitInfo submitInfo =
322         {
323                 VK_STRUCTURE_TYPE_SUBMIT_INFO,
324                 DE_NULL,
325                 0u,                                                             // waitSemaphoreCount
326                 (const VkSemaphore*)DE_NULL,    // pWaitSemaphores
327                 (const VkPipelineStageFlags*)DE_NULL,
328                 cmdBufferCount,                                 // commandBufferCount
329                 pCmdBuffers,
330                 0u,                                                             // signalSemaphoreCount
331                 (const VkSemaphore*)DE_NULL,    // pSignalSemaphores
332         };
333         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
334 }
335
336 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
337 {
338         VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
339 }
340
341 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
342 {
343         const tcu::TextureFormat format = mapVkFormat(vkFormat);
344
345         DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
346
347         switch (format.order)
348         {
349                 case tcu::TextureFormat::DS:
350                         return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
351
352                 case tcu::TextureFormat::D:
353                         return VK_IMAGE_ASPECT_DEPTH_BIT;
354
355                 case tcu::TextureFormat::S:
356                         return VK_IMAGE_ASPECT_STENCIL_BIT;
357
358                 default:
359                         return VK_IMAGE_ASPECT_COLOR_BIT;
360         }
361 }
362
363 VkAccessFlags getAllMemoryReadFlags (void)
364 {
365         return VK_ACCESS_TRANSFER_READ_BIT
366                    | VK_ACCESS_UNIFORM_READ_BIT
367                    | VK_ACCESS_HOST_READ_BIT
368                    | VK_ACCESS_INDEX_READ_BIT
369                    | VK_ACCESS_SHADER_READ_BIT
370                    | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
371                    | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
372                    | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
373                    | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
374                    | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
375 }
376
377 VkAccessFlags getAllMemoryWriteFlags (void)
378 {
379         return VK_ACCESS_TRANSFER_WRITE_BIT
380                    | VK_ACCESS_HOST_WRITE_BIT
381                    | VK_ACCESS_SHADER_WRITE_BIT
382                    | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
383                    | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
384 }
385
386 VkPipelineStageFlags getAllPipelineStageFlags (void)
387 {
388         return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
389                    | VK_PIPELINE_STAGE_TRANSFER_BIT
390                    | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
391                    | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
392                    | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
393                    | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
394                    | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
395                    | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
396                    | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
397                    | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
398                    | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
399                    | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
400                    | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
401 }
402
403 class AttachmentReference
404 {
405 public:
406                                         AttachmentReference             (deUint32               attachment,
407                                                                                          VkImageLayout  layout)
408                 : m_attachment  (attachment)
409                 , m_layout              (layout)
410         {
411         }
412
413         deUint32                getAttachment                   (void) const { return m_attachment;     }
414         VkImageLayout   getImageLayout                  (void) const { return m_layout;         }
415
416 private:
417         deUint32                m_attachment;
418         VkImageLayout   m_layout;
419 };
420
421 class Subpass
422 {
423 public:
424                                                                                 Subpass                                         (VkPipelineBindPoint                            pipelineBindPoint,
425                                                                                                                                          VkSubpassDescriptionFlags                      flags,
426                                                                                                                                          const vector<AttachmentReference>&     inputAttachments,
427                                                                                                                                          const vector<AttachmentReference>&     colorAttachments,
428                                                                                                                                          const vector<AttachmentReference>&     resolveAttachments,
429                                                                                                                                          AttachmentReference                            depthStencilAttachment,
430                                                                                                                                          const vector<AttachmentReference>&     preserveAttachments)
431                 : m_pipelineBindPoint           (pipelineBindPoint)
432                 , m_flags                                       (flags)
433                 , m_inputAttachments            (inputAttachments)
434                 , m_colorAttachments            (colorAttachments)
435                 , m_resolveAttachments          (resolveAttachments)
436                 , m_depthStencilAttachment      (depthStencilAttachment)
437                 , m_preserveAttachments         (preserveAttachments)
438         {
439         }
440
441         VkPipelineBindPoint                                     getPipelineBindPoint            (void) const { return m_pipelineBindPoint;              }
442         VkSubpassDescriptionFlags                       getFlags                                        (void) const { return m_flags;                                  }
443         const vector<AttachmentReference>&      getInputAttachments                     (void) const { return m_inputAttachments;               }
444         const vector<AttachmentReference>&      getColorAttachments                     (void) const { return m_colorAttachments;               }
445         const vector<AttachmentReference>&      getResolveAttachments           (void) const { return m_resolveAttachments;             }
446         const AttachmentReference&                      getDepthStencilAttachment       (void) const { return m_depthStencilAttachment; }
447         const vector<AttachmentReference>&      getPreserveAttachments          (void) const { return m_preserveAttachments;    }
448
449 private:
450         VkPipelineBindPoint                                     m_pipelineBindPoint;
451         VkSubpassDescriptionFlags                       m_flags;
452
453         vector<AttachmentReference>                     m_inputAttachments;
454         vector<AttachmentReference>                     m_colorAttachments;
455         vector<AttachmentReference>                     m_resolveAttachments;
456         AttachmentReference                                     m_depthStencilAttachment;
457
458         vector<AttachmentReference>                     m_preserveAttachments;
459 };
460
461 class SubpassDependency
462 {
463 public:
464                                                         SubpassDependency       (deUint32                               srcPass,
465                                                                                                  deUint32                               dstPass,
466
467                                                                                                  VkPipelineStageFlags   srcStageMask,
468                                                                                                  VkPipelineStageFlags   dstStageMask,
469
470                                                                                                  VkAccessFlags                  outputMask,
471                                                                                                  VkAccessFlags                  inputMask,
472
473                                                                                                  VkDependencyFlags              flags)
474                 : m_srcPass                     (srcPass)
475                 , m_dstPass                     (dstPass)
476
477                 , m_srcStageMask        (srcStageMask)
478                 , m_dstStageMask        (dstStageMask)
479
480                 , m_outputMask          (outputMask)
481                 , m_inputMask           (inputMask)
482                 , m_flags                       (flags)
483         {
484         }
485
486         deUint32                                getSrcPass                      (void) const { return m_srcPass;                }
487         deUint32                                getDstPass                      (void) const { return m_dstPass;                }
488
489         VkPipelineStageFlags    getSrcStageMask         (void) const { return m_srcStageMask;   }
490         VkPipelineStageFlags    getDstStageMask         (void) const { return m_dstStageMask;   }
491
492         VkAccessFlags                   getOutputMask           (void) const { return m_outputMask;             }
493         VkAccessFlags                   getInputMask            (void) const { return m_inputMask;              }
494
495         VkDependencyFlags               getFlags                        (void) const { return m_flags;          }
496
497 private:
498         deUint32                                m_srcPass;
499         deUint32                                m_dstPass;
500
501         VkPipelineStageFlags    m_srcStageMask;
502         VkPipelineStageFlags    m_dstStageMask;
503
504         VkAccessFlags                   m_outputMask;
505         VkAccessFlags                   m_inputMask;
506         VkDependencyFlags               m_flags;
507 };
508
509 class Attachment
510 {
511 public:
512                                                 Attachment                      (VkFormat                               format,
513                                                                                          VkSampleCountFlagBits  samples,
514
515                                                                                          VkAttachmentLoadOp             loadOp,
516                                                                                          VkAttachmentStoreOp    storeOp,
517
518                                                                                          VkAttachmentLoadOp             stencilLoadOp,
519                                                                                          VkAttachmentStoreOp    stencilStoreOp,
520
521                                                                                          VkImageLayout                  initialLayout,
522                                                                                          VkImageLayout                  finalLayout)
523                 : m_format                      (format)
524                 , m_samples                     (samples)
525
526                 , m_loadOp                      (loadOp)
527                 , m_storeOp                     (storeOp)
528
529                 , m_stencilLoadOp       (stencilLoadOp)
530                 , m_stencilStoreOp      (stencilStoreOp)
531
532                 , m_initialLayout       (initialLayout)
533                 , m_finalLayout         (finalLayout)
534         {
535         }
536
537         VkFormat                                getFormat                       (void) const { return m_format;                 }
538         VkSampleCountFlagBits   getSamples                      (void) const { return m_samples;                }
539
540         VkAttachmentLoadOp              getLoadOp                       (void) const { return m_loadOp;                 }
541         VkAttachmentStoreOp             getStoreOp                      (void) const { return m_storeOp;                }
542
543
544         VkAttachmentLoadOp              getStencilLoadOp        (void) const { return m_stencilLoadOp;  }
545         VkAttachmentStoreOp             getStencilStoreOp       (void) const { return m_stencilStoreOp; }
546
547         VkImageLayout                   getInitialLayout        (void) const { return m_initialLayout;  }
548         VkImageLayout                   getFinalLayout          (void) const { return m_finalLayout;    }
549
550 private:
551         VkFormat                                m_format;
552         VkSampleCountFlagBits   m_samples;
553
554         VkAttachmentLoadOp              m_loadOp;
555         VkAttachmentStoreOp             m_storeOp;
556
557         VkAttachmentLoadOp              m_stencilLoadOp;
558         VkAttachmentStoreOp             m_stencilStoreOp;
559
560         VkImageLayout                   m_initialLayout;
561         VkImageLayout                   m_finalLayout;
562 };
563
564 class RenderPass
565 {
566 public:
567                                                                                 RenderPass              (const vector<Attachment>&                      attachments,
568                                                                                                                  const vector<Subpass>&                         subpasses,
569                                                                                                                  const vector<SubpassDependency>&       dependencies)
570                 : m_attachments         (attachments)
571                 , m_subpasses           (subpasses)
572                 , m_dependencies        (dependencies)
573         {
574         }
575
576         const vector<Attachment>&                       getAttachments  (void) const { return m_attachments;    }
577         const vector<Subpass>&                          getSubpasses    (void) const { return m_subpasses;              }
578         const vector<SubpassDependency>&        getDependencies (void) const { return m_dependencies;   }
579
580 private:
581         const vector<Attachment>                        m_attachments;
582         const vector<Subpass>                           m_subpasses;
583         const vector<SubpassDependency>         m_dependencies;
584 };
585
586 struct TestConfig
587 {
588         enum RenderTypes
589         {
590                 RENDERTYPES_NONE        = 0,
591                 RENDERTYPES_CLEAR       = (1<<1),
592                 RENDERTYPES_DRAW        = (1<<2)
593         };
594
595         enum CommandBufferTypes
596         {
597                 COMMANDBUFFERTYPES_INLINE               = (1<<0),
598                 COMMANDBUFFERTYPES_SECONDARY    = (1<<1)
599         };
600
601         enum ImageMemory
602         {
603                 IMAGEMEMORY_STRICT              = (1<<0),
604                 IMAGEMEMORY_LAZY                = (1<<1)
605         };
606
607         TestConfig (const RenderPass&   renderPass_,
608                                 RenderTypes                     renderTypes_,
609                                 CommandBufferTypes      commandBufferTypes_,
610                                 ImageMemory                     imageMemory_,
611                                 const UVec2&            targetSize_,
612                                 const UVec2&            renderPos_,
613                                 const UVec2&            renderSize_,
614                                 deUint32                        seed_)
615                 : renderPass                    (renderPass_)
616                 , renderTypes                   (renderTypes_)
617                 , commandBufferTypes    (commandBufferTypes_)
618                 , imageMemory                   (imageMemory_)
619                 , targetSize                    (targetSize_)
620                 , renderPos                             (renderPos_)
621                 , renderSize                    (renderSize_)
622                 , seed                                  (seed_)
623         {
624         }
625
626         RenderPass                      renderPass;
627         RenderTypes                     renderTypes;
628         CommandBufferTypes      commandBufferTypes;
629         ImageMemory                     imageMemory;
630         UVec2                           targetSize;
631         UVec2                           renderPos;
632         UVec2                           renderSize;
633         deUint32                        seed;
634 };
635
636 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
637 {
638         return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
639 }
640
641 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
642 {
643         return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
644 }
645
646 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
647 {
648         return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
649 }
650
651 void logRenderPassInfo (TestLog&                        log,
652                                                 const RenderPass&       renderPass)
653 {
654         const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");
655
656         {
657                 const tcu::ScopedLogSection     attachmentsSection      (log, "Attachments", "Attachments");
658                 const vector<Attachment>&       attachments                     = renderPass.getAttachments();
659
660                 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
661                 {
662                         const tcu::ScopedLogSection     attachmentSection       (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
663                         const Attachment&                       attachment                      = attachments[attachmentNdx];
664
665                         log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
666                         log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
667
668                         log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
669                         log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
670
671                         log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
672                         log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
673
674                         log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
675                         log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
676                 }
677         }
678
679         {
680                 const tcu::ScopedLogSection     subpassesSection        (log, "Subpasses", "Subpasses");
681                 const vector<Subpass>&          subpasses                       = renderPass.getSubpasses();
682
683                 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
684                 {
685                         const tcu::ScopedLogSection                     subpassSection          (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
686                         const Subpass&                                          subpass                         = subpasses[subpassNdx];
687
688                         const vector<AttachmentReference>&      inputAttachments        = subpass.getInputAttachments();
689                         const vector<AttachmentReference>&      colorAttachments        = subpass.getColorAttachments();
690                         const vector<AttachmentReference>&      resolveAttachments      = subpass.getResolveAttachments();
691                         const vector<AttachmentReference>&      preserveAttachments     = subpass.getPreserveAttachments();
692
693                         if (!inputAttachments.empty())
694                         {
695                                 const tcu::ScopedLogSection             inputAttachmentsSection (log, "Inputs", "Inputs");
696
697                                 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
698                                 {
699                                         const tcu::ScopedLogSection             inputAttachmentSection  (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
700                                         const AttachmentReference&              inputAttachment                 = inputAttachments[inputNdx];
701
702                                         log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
703                                         log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
704                                 }
705                         }
706
707                         if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
708                         {
709                                 const tcu::ScopedLogSection             depthStencilAttachmentSection   (log, "DepthStencil", "DepthStencil");
710                                 const AttachmentReference&              depthStencilAttachment                  = subpass.getDepthStencilAttachment();
711
712                                 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
713                                 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
714                         }
715
716                         if (!colorAttachments.empty())
717                         {
718                                 const tcu::ScopedLogSection             colorAttachmentsSection (log, "Colors", "Colors");
719
720                                 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
721                                 {
722                                         const tcu::ScopedLogSection             colorAttachmentSection  (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
723                                         const AttachmentReference&              colorAttachment                 = colorAttachments[colorNdx];
724
725                                         log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
726                                         log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
727                                 }
728                         }
729
730                         if (!resolveAttachments.empty())
731                         {
732                                 const tcu::ScopedLogSection             resolveAttachmentsSection       (log, "Resolves", "Resolves");
733
734                                 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
735                                 {
736                                         const tcu::ScopedLogSection             resolveAttachmentSection        (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
737                                         const AttachmentReference&              resolveAttachment                       = resolveAttachments[resolveNdx];
738
739                                         log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
740                                         log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
741                                 }
742                         }
743
744                         if (!preserveAttachments.empty())
745                         {
746                                 const tcu::ScopedLogSection             preserveAttachmentsSection      (log, "Preserves", "Preserves");
747
748                                 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
749                                 {
750                                         const tcu::ScopedLogSection             preserveAttachmentSection       (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
751                                         const AttachmentReference&              preserveAttachment                      = preserveAttachments[preserveNdx];
752
753                                         log << TestLog::Message << "Attachment: " << preserveAttachment.getAttachment() << TestLog::EndMessage;
754                                         log << TestLog::Message << "Layout: " << preserveAttachment.getImageLayout() << TestLog::EndMessage;
755                                 }
756                         }
757                 }
758
759         }
760
761         if (!renderPass.getDependencies().empty())
762         {
763                 const tcu::ScopedLogSection     dependenciesSection     (log, "Dependencies", "Dependencies");
764
765                 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
766                 {
767                         const tcu::ScopedLogSection     dependencySection       (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
768                         const SubpassDependency&        dep                                     = renderPass.getDependencies()[depNdx];
769
770                         log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
771                         log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
772
773                         log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
774                         log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
775
776                         log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage;
777                         log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage;
778                         log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
779                 }
780         }
781 }
782
783 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value)
784 {
785         const tcu::TextureFormat                format                  = mapVkFormat(vkFormat);
786         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
787         const tcu::BVec4                                channelMask             = tcu::getTextureFormatChannelMask(format);
788
789         std::ostringstream                              stream;
790
791         stream << "(";
792
793         switch (channelClass)
794         {
795                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
796                         for (int i = 0; i < 4; i++)
797                         {
798                                 if (i > 0)
799                                         stream << ", ";
800
801                                 if (channelMask[i])
802                                         stream << value.int32[i];
803                                 else
804                                         stream << "Undef";
805                         }
806                         break;
807
808                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
809                         for (int i = 0; i < 4; i++)
810                         {
811                                 if (i > 0)
812                                         stream << ", ";
813
814                                 if (channelMask[i])
815                                         stream << value.uint32[i];
816                                 else
817                                         stream << "Undef";
818                         }
819                         break;
820
821                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
822                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
823                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
824                         for (int i = 0; i < 4; i++)
825                         {
826                                 if (i > 0)
827                                         stream << ", ";
828
829                                 if (channelMask[i])
830                                         stream << value.float32[i];
831                                 else
832                                         stream << "Undef";
833                         }
834                         break;
835
836                 default:
837                         DE_FATAL("Unknown channel class");
838         }
839
840         stream << ")";
841
842         return stream.str();
843 }
844
845 std::string clearValueToString (VkFormat vkFormat, VkClearValue value)
846 {
847         const tcu::TextureFormat        format  = mapVkFormat(vkFormat);
848
849         if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
850         {
851                 std::ostringstream stream;
852
853                 stream << "(";
854
855                 if (tcu::hasStencilComponent(format.order))
856                         stream << "stencil: " << value.depthStencil.stencil;
857
858                 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
859                         stream << ", ";
860
861                 if (tcu::hasDepthComponent(format.order))
862                         stream << "depth: " << value.depthStencil.depth;
863
864                 stream << ")";
865
866                 return stream.str();
867         }
868         else
869                 return clearColorToString(vkFormat, value.color);
870 }
871
872 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng)
873 {
874         const float                                             clearNan                = tcu::Float32::nan().asFloat();
875         const tcu::TextureFormat                format                  = mapVkFormat(attachment.getFormat());
876         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
877         const tcu::BVec4                                channelMask             = tcu::getTextureFormatChannelMask(format);
878         VkClearColorValue                               clearColor;
879
880         switch (channelClass)
881         {
882                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
883                 {
884                         const tcu::IVec4 valueMin = tcu::getFormatMinIntValue(format);
885                         const tcu::IVec4 valueMax = tcu::getFormatMaxIntValue(format);
886
887                         for (int ndx = 0; ndx < 4; ndx++)
888                         {
889                                 if (!channelMask[ndx])
890                                         clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
891                                 else
892                                         clearColor.uint32[ndx] = rng.getInt(valueMin[ndx], valueMax[ndx]);
893                         }
894                         break;
895                 }
896
897                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
898                 {
899                         const UVec4 valueMax = tcu::getFormatMaxUintValue(format);
900
901                         for (int ndx = 0; ndx < 4; ndx++)
902                         {
903                                 if (!channelMask[ndx])
904                                         clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
905                                 else
906                                         clearColor.uint32[ndx] = rng.getUint32() % valueMax[ndx];
907                         }
908                         break;
909                 }
910
911                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
912                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
913                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
914                 {
915                         const tcu::TextureFormatInfo    formatInfo              = tcu::getTextureFormatInfo(format);
916
917                         for (int ndx = 0; ndx < 4; ndx++)
918                         {
919                                 if (!channelMask[ndx])
920                                         clearColor.float32[ndx] = clearNan;
921                                 else
922                                         clearColor.float32[ndx] = formatInfo.valueMin[ndx] + rng.getFloat() * (formatInfo.valueMax[ndx] - formatInfo.valueMin[ndx]);
923                         }
924                         break;
925                 }
926
927                 default:
928                         DE_FATAL("Unknown channel class");
929         }
930
931         return clearColor;
932 }
933
934 VkAttachmentDescription createAttachmentDescription (const Attachment& attachment)
935 {
936         const VkAttachmentDescription attachmentDescription =
937         {
938                 0,                                                                                      // flags
939
940                 attachment.getFormat(),                                         // format
941                 attachment.getSamples(),                                        // samples
942
943                 attachment.getLoadOp(),                                         // loadOp
944                 attachment.getStoreOp(),                                        // storeOp
945
946                 attachment.getStencilLoadOp(),                          // stencilLoadOp
947                 attachment.getStencilStoreOp(),                         // stencilStoreOp
948
949                 attachment.getInitialLayout(),                          // initialLayout
950                 attachment.getFinalLayout(),                            // finalLayout
951         };
952
953         return attachmentDescription;
954 }
955
956 VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo)
957 {
958         const VkAttachmentReference reference =
959         {
960                 referenceInfo.getAttachment(),  // attachment;
961                 referenceInfo.getImageLayout()  // layout;
962         };
963
964         return reference;
965 }
966
967 VkSubpassDescription createSubpassDescription (const Subpass&                                   subpass,
968                                                                                            vector<VkAttachmentReference>*       attachmentReferenceLists,
969                                                                                            vector<deUint32>*                            preserveAttachmentReferences)
970 {
971         vector<VkAttachmentReference>&  inputAttachmentReferences                       = attachmentReferenceLists[0];
972         vector<VkAttachmentReference>&  colorAttachmentReferences                       = attachmentReferenceLists[1];
973         vector<VkAttachmentReference>&  resolveAttachmentReferences                     = attachmentReferenceLists[2];
974         vector<VkAttachmentReference>&  depthStencilAttachmentReferences        = attachmentReferenceLists[3];
975
976         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
977                 colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx]));
978
979         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
980                 inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx]));
981
982         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
983                 resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx]));
984
985         depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment()));
986
987         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
988                 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx].getAttachment());
989
990         DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
991
992         {
993                 const VkSubpassDescription subpassDescription =
994                 {
995                         subpass.getFlags(),                                                                                                                                             // flags;
996                         subpass.getPipelineBindPoint(),                                                                                                                 // pipelineBindPoint;
997
998                         (deUint32)inputAttachmentReferences.size(),                                                                                             // inputCount;
999                         inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0],                    // inputAttachments;
1000
1001                         (deUint32)colorAttachmentReferences.size(),                                                                                             // colorCount;
1002                         colorAttachmentReferences.empty() ? DE_NULL :  &colorAttachmentReferences[0],                   // colorAttachments;
1003                         resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0],                // resolveAttachments;
1004
1005                         &depthStencilAttachmentReferences[0],                                                                                                   // pDepthStencilAttachment;
1006                         (deUint32)preserveAttachmentReferences->size(),                                                                                 // preserveCount;
1007                         preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0]   // preserveAttachments;
1008                 };
1009
1010                 return subpassDescription;
1011         }
1012 }
1013
1014 VkSubpassDependency createSubpassDependency     (const SubpassDependency& dependencyInfo)
1015 {
1016         const VkSubpassDependency dependency =
1017         {
1018                 dependencyInfo.getSrcPass(),                    // srcSubpass;
1019                 dependencyInfo.getDstPass(),                    // destSubpass;
1020
1021                 dependencyInfo.getSrcStageMask(),               // srcStageMask;
1022                 dependencyInfo.getDstStageMask(),               // destStageMask;
1023
1024                 dependencyInfo.getOutputMask(),                 // outputMask;
1025                 dependencyInfo.getInputMask(),                  // inputMask;
1026
1027                 dependencyInfo.getFlags()                               // dependencyFlags;
1028         };
1029
1030         return dependency;
1031 }
1032
1033 Move<VkRenderPass> createRenderPass (const DeviceInterface&     vk,
1034                                                                          VkDevice                               device,
1035                                                                          const RenderPass&              renderPassInfo)
1036 {
1037         const size_t                                                    perSubpassAttachmentReferenceLists = 4;
1038         vector<VkAttachmentDescription>                 attachments;
1039         vector<VkSubpassDescription>                    subpasses;
1040         vector<VkSubpassDependency>                             dependencies;
1041         vector<vector<VkAttachmentReference> >  attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
1042         vector<vector<deUint32> >                               preserveAttachments(renderPassInfo.getSubpasses().size());
1043
1044         for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1045                 attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx]));
1046
1047         for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1048                 subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));
1049
1050         for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1051                 dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx]));
1052
1053         {
1054                 const VkRenderPassCreateInfo    createInfo      =
1055                 {
1056                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1057                         DE_NULL,
1058                         (VkRenderPassCreateFlags)0u,
1059                         (deUint32)attachments.size(),
1060                         (attachments.empty() ? DE_NULL : &attachments[0]),
1061                         (deUint32)subpasses.size(),
1062                         (subpasses.empty() ? DE_NULL : &subpasses[0]),
1063                         (deUint32)dependencies.size(),
1064                         (dependencies.empty() ? DE_NULL : &dependencies[0])
1065                 };
1066
1067                 return createRenderPass(vk, device, &createInfo);
1068         }
1069 }
1070
1071 Move<VkFramebuffer> createFramebuffer (const DeviceInterface&           vk,
1072                                                                            VkDevice                                             device,
1073                                                                            VkRenderPass                                 renderPass,
1074                                                                            const UVec2&                                 size,
1075                                                                            const vector<VkImageView>&   attachments)
1076 {
1077         return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1078 }
1079
1080 Move<VkImage> createAttachmentImage (const DeviceInterface&     vk,
1081                                                                          VkDevice                               device,
1082                                                                          deUint32                               queueIndex,
1083                                                                          const UVec2&                   size,
1084                                                                          VkFormat                               format,
1085                                                                          VkSampleCountFlagBits  samples,
1086                                                                          VkImageUsageFlags              usageFlags,
1087                                                                          VkImageLayout                  layout)
1088 {
1089         const VkExtent3D size_                                  = { size.x(), size.y(), 1u };
1090         VkImageUsageFlags targetUsageFlags              = 0;
1091         const tcu::TextureFormat textureFormat  = mapVkFormat(format);
1092
1093         if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1094         {
1095                 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1096         }
1097         else
1098         {
1099                 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1100         }
1101
1102         return createImage(vk, device,
1103                                            (VkImageCreateFlags)0,
1104                                            VK_IMAGE_TYPE_2D,
1105                                            format,
1106                                            size_,
1107                                            1u /* mipLevels */,
1108                                            1u /* arraySize */,
1109                                            samples,
1110                                            VK_IMAGE_TILING_OPTIMAL,
1111                                            usageFlags | targetUsageFlags,
1112                                            VK_SHARING_MODE_EXCLUSIVE,
1113                                            1,
1114                                            &queueIndex,
1115                                            layout);
1116 }
1117
1118 de::MovePtr<Allocation> createImageMemory (const DeviceInterface&       vk,
1119                                                                                    VkDevice                                     device,
1120                                                                                    Allocator&                           allocator,
1121                                                                                    VkImage                                      image,
1122                                                                                    bool                                         lazy)
1123 {
1124         de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any));
1125         bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1126         return allocation;
1127 }
1128
1129 Move<VkImageView> createImageAttachmentView (const DeviceInterface&     vk,
1130                                                                                          VkDevice                               device,
1131                                                                                          VkImage                                image,
1132                                                                                          VkFormat                               format,
1133                                                                                          VkImageAspectFlags             aspect)
1134 {
1135         const VkImageSubresourceRange range =
1136         {
1137                 aspect,
1138                 0,
1139                 1,
1140                 0,
1141                 1
1142         };
1143
1144         return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1145 }
1146
1147 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng)
1148 {
1149         const float                                     clearNan        = tcu::Float32::nan().asFloat();
1150         const tcu::TextureFormat        format          = mapVkFormat(attachment.getFormat());
1151
1152         if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1153         {
1154                 VkClearValue clearValue;
1155
1156                 clearValue.depthStencil.depth   = clearNan;
1157                 clearValue.depthStencil.stencil = 255;
1158
1159                 if (tcu::hasStencilComponent(format.order))
1160                         clearValue.depthStencil.stencil = rng.getInt(0, 255);
1161
1162                 if (tcu::hasDepthComponent(format.order))
1163                         clearValue.depthStencil.depth   = rng.getFloat();
1164
1165                 return clearValue;
1166         }
1167         else
1168         {
1169                 VkClearValue clearValue;
1170
1171                 clearValue.color = randomColorClearValue(attachment, rng);
1172
1173                 return clearValue;
1174         }
1175 }
1176
1177 class AttachmentResources
1178 {
1179 public:
1180         AttachmentResources (const DeviceInterface&             vk,
1181                                                  VkDevice                                       device,
1182                                                  Allocator&                                     allocator,
1183                                                  deUint32                                       queueIndex,
1184                                                  const UVec2&                           size,
1185                                                  const Attachment&                      attachmentInfo,
1186                                                  bool                                           lazy)
1187                 : m_image                       (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), lazy ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : 0, VK_IMAGE_LAYOUT_UNDEFINED))
1188                 , m_imageMemory         (createImageMemory(vk, device, allocator, *m_image, lazy))
1189                 , m_attachmentView      (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
1190         {
1191                 if (!lazy)
1192                 {
1193                         const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1194
1195                         if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1196                         {
1197                                 const tcu::TextureFormat        depthFormat             = getDepthCopyFormat(attachmentInfo.getFormat());
1198                                 const tcu::TextureFormat        stencilFormat   = getStencilCopyFormat(attachmentInfo.getFormat());
1199
1200                                 m_bufferSize                    = size.x() * size.y() * depthFormat.getPixelSize();
1201                                 m_secondaryBufferSize   = size.x() * size.y() * stencilFormat.getPixelSize();
1202
1203                                 m_buffer                                = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1204                                 m_bufferMemory                  = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
1205
1206                                 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1207
1208                                 m_secondaryBuffer               = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1209                                 m_secondaryBufferMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_secondaryBuffer), MemoryRequirement::HostVisible);
1210
1211                                 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
1212                         }
1213                         else
1214                         {
1215                                 m_bufferSize    = size.x() * size.y() * format.getPixelSize();
1216
1217                                 m_buffer                = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1218                                 m_bufferMemory  = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
1219
1220                                 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1221                         }
1222                 }
1223         }
1224
1225         ~AttachmentResources (void)
1226         {
1227         }
1228
1229         VkImageView getAttachmentView (void) const
1230         {
1231                 return *m_attachmentView;
1232         }
1233
1234         VkImage getImage (void) const
1235         {
1236                 return *m_image;
1237         }
1238
1239         VkBuffer getBuffer (void) const
1240         {
1241                 DE_ASSERT(*m_buffer != DE_NULL);
1242                 return *m_buffer;
1243         }
1244
1245         VkDeviceSize getBufferSize (void) const
1246         {
1247                 DE_ASSERT(*m_buffer != DE_NULL);
1248                 return m_bufferSize;
1249         }
1250
1251         const Allocation& getResultMemory (void) const
1252         {
1253                 DE_ASSERT(m_bufferMemory);
1254                 return *m_bufferMemory;
1255         }
1256
1257         VkBuffer getSecondaryBuffer (void) const
1258         {
1259                 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1260                 return *m_secondaryBuffer;
1261         }
1262
1263         VkDeviceSize getSecondaryBufferSize (void) const
1264         {
1265                 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1266                 return m_secondaryBufferSize;
1267         }
1268
1269         const Allocation& getSecondaryResultMemory (void) const
1270         {
1271                 DE_ASSERT(m_secondaryBufferMemory);
1272                 return *m_secondaryBufferMemory;
1273         }
1274
1275 private:
1276         const Unique<VkImage>                   m_image;
1277         const UniquePtr<Allocation>             m_imageMemory;
1278         const Unique<VkImageView>               m_attachmentView;
1279
1280         Move<VkBuffer>                                  m_buffer;
1281         VkDeviceSize                                    m_bufferSize;
1282         de::MovePtr<Allocation>                 m_bufferMemory;
1283
1284         Move<VkBuffer>                                  m_secondaryBuffer;
1285         VkDeviceSize                                    m_secondaryBufferSize;
1286         de::MovePtr<Allocation>                 m_secondaryBufferMemory;
1287 };
1288
1289 void uploadBufferData (const DeviceInterface&   vk,
1290                                            VkDevice                                     device,
1291                                            const Allocation&            memory,
1292                                            size_t                                       size,
1293                                            const void*                          data)
1294 {
1295         const VkMappedMemoryRange range =
1296         {
1297                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  // sType;
1298                 DE_NULL,                                                                // pNext;
1299                 memory.getMemory(),                                             // mem;
1300                 memory.getOffset(),                                             // offset;
1301                 (VkDeviceSize)size                                              // size;
1302         };
1303         void* const ptr = memory.getHostPtr();
1304
1305         deMemcpy(ptr, data, size);
1306         VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1307 }
1308
1309 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
1310 {
1311         DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
1312
1313         switch (order)
1314         {
1315                 case tcu::TextureFormat::D:
1316                 case tcu::TextureFormat::DS:
1317                         return VK_IMAGE_ASPECT_DEPTH_BIT;
1318
1319                 case tcu::TextureFormat::S:
1320                         return VK_IMAGE_ASPECT_STENCIL_BIT;
1321
1322                 default:
1323                         return VK_IMAGE_ASPECT_COLOR_BIT;
1324         }
1325 }
1326
1327 class RenderQuad
1328 {
1329 public:
1330         RenderQuad (const Vec4& posA, const Vec4& posB)
1331                 : m_vertices(6)
1332         {
1333                 m_vertices[0] = posA;
1334                 m_vertices[1] = Vec4(posA[0], posB[1], posA[2], posA[3]);
1335                 m_vertices[2] = posB;
1336
1337                 m_vertices[3] = posB;
1338                 m_vertices[4] = Vec4(posB[0], posA[1], posB[2], posA[3]);
1339                 m_vertices[5] = posA;
1340         }
1341
1342         const Vec4&             getCornerA                      (void) const
1343         {
1344                 return m_vertices[0];
1345         }
1346
1347         const Vec4&             getCornerB                      (void) const
1348         {
1349                 return m_vertices[2];
1350         }
1351
1352         const void*             getVertexPointer        (void) const
1353         {
1354                 return &m_vertices[0];
1355         }
1356
1357         size_t                  getVertexDataSize       (void) const
1358         {
1359                 return sizeof(Vec4) * m_vertices.size();
1360         }
1361
1362 private:
1363         vector<Vec4>    m_vertices;
1364 };
1365
1366 class ColorClear
1367 {
1368 public:
1369         ColorClear      (const UVec2&                           offset,
1370                                  const UVec2&                           size,
1371                                  const VkClearColorValue&       color)
1372                 : m_offset      (offset)
1373                 , m_size        (size)
1374                 , m_color       (color)
1375         {
1376         }
1377
1378         const UVec2&                            getOffset               (void) const { return m_offset;         }
1379         const UVec2&                            getSize                 (void) const { return m_size;           }
1380         const VkClearColorValue&        getColor                (void) const { return m_color;          }
1381
1382 private:
1383         UVec2                           m_offset;
1384         UVec2                           m_size;
1385         VkClearColorValue       m_color;
1386 };
1387
1388 class DepthStencilClear
1389 {
1390 public:
1391         DepthStencilClear       (const UVec2&                           offset,
1392                                                  const UVec2&                           size,
1393                                                  float                                          depth,
1394                                                  deUint32                                       stencil)
1395                 : m_offset      (offset)
1396                 , m_size        (size)
1397                 , m_depth       (depth)
1398                 , m_stencil     (stencil)
1399         {
1400         }
1401
1402         const UVec2&            getOffset               (void) const { return m_offset;         }
1403         const UVec2&            getSize                 (void) const { return m_size;           }
1404         float                           getDepth                (void) const { return m_depth;          }
1405         deUint32                        getStencil              (void) const { return m_stencil;        }
1406
1407 private:
1408         UVec2                           m_offset;
1409         UVec2                           m_size;
1410
1411         float                           m_depth;
1412         deUint32                        m_stencil;
1413 };
1414
1415 class SubpassRenderInfo
1416 {
1417 public:
1418         SubpassRenderInfo       (const RenderPass&                                      renderPass,
1419                                                  deUint32                                                       subpassIndex,
1420
1421                                                  bool                                                           isSecondary_,
1422
1423                                                  const UVec2&                                           viewportOffset,
1424                                                  const UVec2&                                           viewportSize,
1425
1426                                                  const Maybe<RenderQuad>&                       renderQuad,
1427                                                  const vector<ColorClear>&                      colorClears,
1428                                                  const Maybe<DepthStencilClear>&        depthStencilClear)
1429                 : m_viewportOffset              (viewportOffset)
1430                 , m_viewportSize                (viewportSize)
1431                 , m_subpassIndex                (subpassIndex)
1432                 , m_isSecondary                 (isSecondary_)
1433                 , m_flags                               (renderPass.getSubpasses()[subpassIndex].getFlags())
1434                 , m_renderQuad                  (renderQuad)
1435                 , m_colorClears                 (colorClears)
1436                 , m_depthStencilClear   (depthStencilClear)
1437                 , m_colorAttachments    (renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1438         {
1439                 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
1440                         m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]);
1441
1442                 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1443                 {
1444                         m_depthStencilAttachment                = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1445                         m_depthStencilAttachmentInfo    = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1446                 }
1447         }
1448
1449         const UVec2&                                            getViewportOffset                               (void) const { return m_viewportOffset;         }
1450         const UVec2&                                            getViewportSize                                 (void) const { return m_viewportSize;           }
1451
1452         deUint32                                                        getSubpassIndex                                 (void) const { return m_subpassIndex;           }
1453         bool                                                            isSecondary                                             (void) const { return m_isSecondary;            }
1454
1455         const Maybe<RenderQuad>&                        getRenderQuad                                   (void) const { return m_renderQuad;                     }
1456         const vector<ColorClear>&                       getColorClears                                  (void) const { return m_colorClears;            }
1457         const Maybe<DepthStencilClear>&         getDepthStencilClear                    (void) const { return m_depthStencilClear;      }
1458
1459         deUint32                                                        getColorAttachmentCount                 (void) const { return (deUint32)m_colorAttachments.size(); }
1460         VkImageLayout                                           getColorAttachmentLayout                (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
1461         deUint32                                                        getColorAttachmentIndex                 (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
1462         const Attachment&                                       getColorAttachment                              (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
1463         Maybe<VkImageLayout>                            getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
1464         Maybe<deUint32>                                         getDepthStencilAttachmentIndex  (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
1465         const Maybe<Attachment>&                        getDepthStencilAttachment               (void) const { return m_depthStencilAttachmentInfo; }
1466         VkSubpassDescriptionFlags                       getSubpassFlags                                 (void) const { return m_flags; }
1467 private:
1468         UVec2                                                           m_viewportOffset;
1469         UVec2                                                           m_viewportSize;
1470
1471         deUint32                                                        m_subpassIndex;
1472         bool                                                            m_isSecondary;
1473         VkSubpassDescriptionFlags                       m_flags;
1474
1475         Maybe<RenderQuad>                                       m_renderQuad;
1476         vector<ColorClear>                                      m_colorClears;
1477         Maybe<DepthStencilClear>                        m_depthStencilClear;
1478
1479         vector<AttachmentReference>                     m_colorAttachments;
1480         vector<Attachment>                                      m_colorAttachmentInfo;
1481
1482         Maybe<AttachmentReference>                      m_depthStencilAttachment;
1483         Maybe<Attachment>                                       m_depthStencilAttachmentInfo;
1484 };
1485
1486 Move<VkPipeline> createSubpassPipeline (const DeviceInterface&          vk,
1487                                                                                 VkDevice                                        device,
1488                                                                                 VkRenderPass                            renderPass,
1489                                                                                 VkShaderModule                          vertexShaderModule,
1490                                                                                 VkShaderModule                          fragmentShaderModule,
1491                                                                                 VkPipelineLayout                        pipelineLayout,
1492                                                                                 const SubpassRenderInfo&        renderInfo)
1493 {
1494         const VkSpecializationInfo emptyShaderSpecializations =
1495         {
1496                 0u,                     // mapEntryCount
1497                 DE_NULL,        // pMap
1498                 0u,                     // dataSize
1499                 DE_NULL,        // pData
1500         };
1501
1502         Maybe<VkSampleCountFlagBits>                            rasterSamples;
1503         vector<VkPipelineColorBlendAttachmentState>     attachmentBlendStates;
1504
1505         for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
1506         {
1507                 const Attachment&                       attachment              = renderInfo.getColorAttachment(attachmentNdx);
1508
1509                 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1510
1511                 rasterSamples = attachment.getSamples();
1512
1513                 {
1514                         const VkPipelineColorBlendAttachmentState       attachmentBlendState =
1515                         {
1516                                 VK_FALSE,                                                                                                                                                                                               // blendEnable
1517                                 VK_BLEND_FACTOR_SRC_ALPHA,                                                                                                                                                              // srcBlendColor
1518                                 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,                                                                                                                                    // destBlendColor
1519                                 VK_BLEND_OP_ADD,                                                                                                                                                                                // blendOpColor
1520                                 VK_BLEND_FACTOR_ONE,                                                                                                                                                                    // srcBlendAlpha
1521                                 VK_BLEND_FACTOR_ONE,                                                                                                                                                                    // destBlendAlpha
1522                                 VK_BLEND_OP_ADD,                                                                                                                                                                                // blendOpAlpha
1523                                 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT,    // channelWriteMask
1524                         };
1525
1526                         attachmentBlendStates.push_back(attachmentBlendState);
1527                 }
1528         }
1529
1530         if (renderInfo.getDepthStencilAttachment())
1531         {
1532                 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
1533
1534                 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1535                 rasterSamples = attachment.getSamples();
1536         }
1537
1538         // If there are no attachment use single sample
1539         if (!rasterSamples)
1540                 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
1541
1542         const VkPipelineShaderStageCreateInfo shaderStages[2] =
1543         {
1544                 {
1545                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // sType
1546                         DE_NULL,                                                                                                // pNext
1547                         (VkPipelineShaderStageCreateFlags)0u,
1548                         VK_SHADER_STAGE_VERTEX_BIT,                                                             // stage
1549                         vertexShaderModule,                                                                             // shader
1550                         "main",
1551                         &emptyShaderSpecializations
1552                 },
1553                 {
1554                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // sType
1555                         DE_NULL,                                                                                                // pNext
1556                         (VkPipelineShaderStageCreateFlags)0u,
1557                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                   // stage
1558                         fragmentShaderModule,                                                                   // shader
1559                         "main",
1560                         &emptyShaderSpecializations
1561                 }
1562         };
1563         const VkVertexInputBindingDescription vertexBinding =
1564         {
1565                 0u,                                                                                                                     // binding
1566                 (deUint32)sizeof(tcu::Vec4),                                                            // strideInBytes
1567                 VK_VERTEX_INPUT_RATE_VERTEX,                                                            // stepRate
1568         };
1569         const VkVertexInputAttributeDescription vertexAttrib =
1570         {
1571                 0u,                                                                                                                     // location
1572                 0u,                                                                                                                     // binding
1573                 VK_FORMAT_R32G32B32A32_SFLOAT,                                                          // format
1574                 0u,                                                                                                                     // offsetInBytes
1575         };
1576         const VkPipelineVertexInputStateCreateInfo vertexInputState =
1577         {
1578                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      //      sType
1579                 DE_NULL,                                                                                                        //      pNext
1580                 (VkPipelineVertexInputStateCreateFlags)0u,
1581                 1u,                                                                                                                     //      bindingCount
1582                 &vertexBinding,                                                                                         //      pVertexBindingDescriptions
1583                 1u,                                                                                                                     //      attributeCount
1584                 &vertexAttrib,                                                                                          //      pVertexAttributeDescriptions
1585         };
1586         const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1587         {
1588                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // sType
1589                 DE_NULL,                                                                                                                // pNext
1590                 (VkPipelineInputAssemblyStateCreateFlags)0u,
1591                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // topology
1592                 VK_FALSE,                                                                                                               // primitiveRestartEnable
1593         };
1594         const VkViewport viewport =
1595         {
1596                 (float)renderInfo.getViewportOffset().x(),      (float)renderInfo.getViewportOffset().y(),
1597                 (float)renderInfo.getViewportSize().x(),        (float)renderInfo.getViewportSize().y(),
1598                 0.0f, 1.0f
1599         };
1600         const VkRect2D scissor =
1601         {
1602                 { (deInt32)renderInfo.getViewportOffset().x(),  (deInt32)renderInfo.getViewportOffset().y() },
1603                 { renderInfo.getViewportSize().x(),                             renderInfo.getViewportSize().y() }
1604         };
1605         const VkPipelineViewportStateCreateInfo viewportState =
1606         {
1607                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1608                 DE_NULL,
1609                 (VkPipelineViewportStateCreateFlags)0u,
1610                 1u,
1611                 &viewport,
1612                 1u,
1613                 &scissor
1614         };
1615         const VkPipelineRasterizationStateCreateInfo rasterState =
1616         {
1617                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // sType
1618                 DE_NULL,                                                                                                                // pNext
1619                 (VkPipelineRasterizationStateCreateFlags)0u,
1620                 VK_TRUE,                                                                                                                // depthClipEnable
1621                 VK_FALSE,                                                                                                               // rasterizerDiscardEnable
1622                 VK_POLYGON_MODE_FILL,                                                                                   // fillMode
1623                 VK_CULL_MODE_NONE,                                                                                              // cullMode
1624                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // frontFace
1625                 VK_FALSE,                                                                                                               // depthBiasEnable
1626                 0.0f,                                                                                                                   // depthBias
1627                 0.0f,                                                                                                                   // depthBiasClamp
1628                 0.0f,                                                                                                                   // slopeScaledDepthBias
1629                 1.0f                                                                                                                    // lineWidth
1630         };
1631         const VkPipelineMultisampleStateCreateInfo multisampleState =
1632         {
1633                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // sType
1634                 DE_NULL,                                                                                                                // pNext
1635                 (VkPipelineMultisampleStateCreateFlags)0u,
1636                 *rasterSamples,                                                                                                 // rasterSamples
1637                 VK_FALSE,                                                                                                               // sampleShadingEnable
1638                 0.0f,                                                                                                                   // minSampleShading
1639                 DE_NULL,                                                                                                                // pSampleMask
1640                 VK_FALSE,                                                                                                               // alphaToCoverageEnable
1641                 VK_FALSE,                                                                                                               // alphaToOneEnable
1642         };
1643         const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1644         {
1645                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // sType
1646                 DE_NULL,                                                                                                        // pNext
1647                 (VkPipelineDepthStencilStateCreateFlags)0u,
1648                 VK_TRUE,                                                                                                        // depthTestEnable
1649                 VK_TRUE,                                                                                                        // depthWriteEnable
1650                 VK_COMPARE_OP_ALWAYS,                                                                           // depthCompareOp
1651                 VK_FALSE,                                                                                                       // depthBoundsEnable
1652                 VK_TRUE,                                                                                                        // stencilTestEnable
1653                 {
1654                         VK_STENCIL_OP_REPLACE,                                                                  // stencilFailOp
1655                         VK_STENCIL_OP_REPLACE,                                                                  // stencilPassOp
1656                         VK_STENCIL_OP_REPLACE,                                                                  // stencilDepthFailOp
1657                         VK_COMPARE_OP_ALWAYS,                                                                   // stencilCompareOp
1658                         ~0u,                                                                                                    // stencilCompareMask
1659                         ~0u,                                                                                                    // stencilWriteMask
1660                         STENCIL_VALUE                                                                                   // stencilReference
1661                 },                                                                                                                      // front
1662                 {
1663                         VK_STENCIL_OP_REPLACE,                                                                  // stencilFailOp
1664                         VK_STENCIL_OP_REPLACE,                                                                  // stencilPassOp
1665                         VK_STENCIL_OP_REPLACE,                                                                  // stencilDepthFailOp
1666                         VK_COMPARE_OP_ALWAYS,                                                                   // stencilCompareOp
1667                         ~0u,                                                                                                    // stencilCompareMask
1668                         ~0u,                                                                                                    // stencilWriteMask
1669                         STENCIL_VALUE                                                                                   // stencilReference
1670                 },                                                                                                                      // back
1671
1672                 -1.0f,                                                                                                          // minDepthBounds;
1673                 1.0f                                                                                                            // maxDepthBounds;
1674         };
1675         const VkPipelineColorBlendStateCreateInfo blendState =
1676         {
1677                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,                       // sType
1678                 DE_NULL,                                                                                                                        // pNext
1679                 (VkPipelineColorBlendStateCreateFlags)0u,
1680                 VK_FALSE,                                                                                                                       // logicOpEnable
1681                 VK_LOGIC_OP_COPY,                                                                                                       // logicOp
1682                 (deUint32)attachmentBlendStates.size(),                                                         // attachmentCount
1683                 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
1684                 { 0.0f, 0.0f, 0.0f, 0.0f }                                                                                      // blendConst
1685         };
1686         const VkPipelineDynamicStateCreateInfo dynamicState =
1687         {
1688                 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1689                 DE_NULL,
1690                 (VkPipelineDynamicStateCreateFlags)0u,
1691                 0,
1692                 DE_NULL
1693         };
1694         const VkGraphicsPipelineCreateInfo createInfo =
1695         {
1696                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                // sType
1697                 DE_NULL,                                                                                                // pNext
1698                 (VkPipelineCreateFlags)0u,
1699
1700                 2,                                                                                                              // stageCount
1701                 shaderStages,                                                                                   // pStages
1702
1703                 &vertexInputState,                                                                              // pVertexInputState
1704                 &inputAssemblyState,                                                                    // pInputAssemblyState
1705                 DE_NULL,                                                                                                // pTessellationState
1706                 &viewportState,                                                                                 // pViewportState
1707                 &rasterState,                                                                                   // pRasterState
1708                 &multisampleState,                                                                              // pMultisampleState
1709                 &depthStencilState,                                                                             // pDepthStencilState
1710                 &blendState,                                                                                    // pColorBlendState
1711                 &dynamicState,                                                                                  // pDynamicState
1712                 pipelineLayout,                                                                                 // layout
1713
1714                 renderPass,                                                                                             // renderPass
1715                 renderInfo.getSubpassIndex(),                                                   // subpass
1716                 DE_NULL,                                                                                                // basePipelineHandle
1717                 0u                                                                                                              // basePipelineIndex
1718         };
1719
1720         return createGraphicsPipeline(vk, device, DE_NULL, &createInfo);
1721 }
1722
1723 class SubpassRenderer
1724 {
1725 public:
1726         SubpassRenderer (Context&                                       context,
1727                                          const DeviceInterface&         vk,
1728                                          VkDevice                                       device,
1729                                          Allocator&                                     allocator,
1730                                          VkRenderPass                           renderPass,
1731                                          VkFramebuffer                          framebuffer,
1732                                          VkCommandPool                          commandBufferPool,
1733                                          deUint32                                       queueFamilyIndex,
1734                                          const SubpassRenderInfo&       renderInfo)
1735                 : m_renderInfo  (renderInfo)
1736         {
1737                 const deUint32 subpassIndex = renderInfo.getSubpassIndex();
1738
1739                 if (renderInfo.getRenderQuad())
1740                 {
1741                         const RenderQuad&                                       renderQuad                              = *renderInfo.getRenderQuad();
1742                         const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
1743                         {
1744                                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // sType;
1745                                 DE_NULL,                                                                                // pNext;
1746                                 (vk::VkPipelineLayoutCreateFlags)0,
1747                                 0u,                                                                                             // descriptorSetCount;
1748                                 DE_NULL,                                                                                // pSetLayouts;
1749                                 0u,                                                                                             // pushConstantRangeCount;
1750                                 DE_NULL,                                                                                // pPushConstantRanges;
1751                         };
1752
1753                         m_vertexShaderModule    = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
1754                         m_fragmentShaderModule  = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
1755                         m_pipelineLayout                = createPipelineLayout(vk, device, &pipelineLayoutParams);
1756                         m_pipeline                              = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
1757
1758                         m_vertexBuffer                  = createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
1759                         m_vertexBufferMemory    = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_vertexBuffer), MemoryRequirement::HostVisible);
1760
1761                         bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
1762                         uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer());
1763                 }
1764
1765                 if (renderInfo.isSecondary())
1766                 {
1767                         m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1768
1769                         beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
1770                         pushRenderCommands(vk, *m_commandBuffer);
1771                         endCommandBuffer(vk, *m_commandBuffer);
1772                 }
1773         }
1774
1775         bool isSecondary (void) const
1776         {
1777                 return m_commandBuffer;
1778         }
1779
1780         VkCommandBuffer getCommandBuffer (void) const
1781         {
1782                 DE_ASSERT(isSecondary());
1783                 return *m_commandBuffer;
1784         }
1785
1786         void pushRenderCommands (const DeviceInterface&         vk,
1787                                                          VkCommandBuffer                        commandBuffer)
1788         {
1789                 if (!m_renderInfo.getColorClears().empty())
1790                 {
1791                         const vector<ColorClear>&       colorClears     (m_renderInfo.getColorClears());
1792
1793                         for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
1794                         {
1795                                 const ColorClear&               colorClear      = colorClears[attachmentNdx];
1796                                 const VkClearAttachment attachment      =
1797                                 {
1798                                         VK_IMAGE_ASPECT_COLOR_BIT,
1799                                         attachmentNdx,
1800                                         makeClearValue(colorClear.getColor()),
1801                                 };
1802                                 const VkClearRect               rect            =
1803                                 {
1804                                         {
1805                                                 { (deInt32)colorClear.getOffset().x(),  (deInt32)colorClear.getOffset().y()     },
1806                                                 { colorClear.getSize().x(),                             colorClear.getSize().y()                        }
1807                                         },                                      // rect
1808                                         0u,                                     // baseArrayLayer
1809                                         1u,                                     // layerCount
1810                                 };
1811
1812                                 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
1813                         }
1814                 }
1815
1816                 if (m_renderInfo.getDepthStencilClear())
1817                 {
1818                         const DepthStencilClear&                depthStencilClear       = *m_renderInfo.getDepthStencilClear();
1819                         const deUint32                                  attachmentNdx           = m_renderInfo.getColorAttachmentCount();
1820                         tcu::TextureFormat                              format                          = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
1821                         const VkClearAttachment                 attachment                      =
1822                         {
1823                                 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
1824                                         | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
1825                                 attachmentNdx,
1826                                 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
1827                         };
1828                         const VkClearRect                               rect                            =
1829                         {
1830                                 {
1831                                         { (deInt32)depthStencilClear.getOffset().x(),   (deInt32)depthStencilClear.getOffset().y()      },
1832                                         { depthStencilClear.getSize().x(),                              depthStencilClear.getSize().y()                         }
1833                                 },                                                      // rect
1834                                 0u,                                                     // baseArrayLayer
1835                                 1u,                                                     // layerCount
1836                         };
1837
1838                         vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
1839                 }
1840
1841                 if (m_renderInfo.getRenderQuad())
1842                 {
1843                         const VkDeviceSize      offset                  = 0;
1844                         const VkBuffer          vertexBuffer    = *m_vertexBuffer;
1845
1846                         vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1847                         vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
1848                         vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
1849                 }
1850         }
1851
1852 private:
1853         const SubpassRenderInfo                         m_renderInfo;
1854         Move<VkCommandBuffer>                           m_commandBuffer;
1855         Move<VkPipeline>                                        m_pipeline;
1856         Move<VkPipelineLayout>                          m_pipelineLayout;
1857
1858         Move<VkShaderModule>                            m_vertexShaderModule;
1859
1860         Move<VkShaderModule>                            m_fragmentShaderModule;
1861
1862         Move<VkBuffer>                                          m_vertexBuffer;
1863         de::MovePtr<Allocation>                         m_vertexBufferMemory;
1864 };
1865
1866 void pushImageInitializationCommands (const DeviceInterface&                                                            vk,
1867                                                                           VkCommandBuffer                                                                               commandBuffer,
1868                                                                           const vector<Attachment>&                                                             attachmentInfo,
1869                                                                           const vector<de::SharedPtr<AttachmentResources> >&    attachmentResources,
1870                                                                           deUint32                                                                                              queueIndex,
1871                                                                           const vector<Maybe<VkClearValue> >&                                   clearValues)
1872 {
1873         {
1874                 vector<VkImageMemoryBarrier>    initializeLayouts;
1875
1876                 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1877                 {
1878                         if (!clearValues[attachmentNdx])
1879                                 continue;
1880
1881                         const VkImageMemoryBarrier barrier =
1882                         {
1883                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                         // sType;
1884                                 DE_NULL,                                                                                                                        // pNext;
1885
1886                                 getAllMemoryWriteFlags(),                                                                                       // srcAccessMask
1887                                 getAllMemoryReadFlags(),                                                                                        // dstAccessMask
1888
1889                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                      // oldLayout
1890                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                                                           // newLayout;
1891
1892                                 queueIndex,                                                                                                                     // srcQueueFamilyIndex;
1893                                 queueIndex,                                                                                                                     // destQueueFamilyIndex;
1894
1895                                 attachmentResources[attachmentNdx]->getImage(),                                         // image;
1896                                 {                                                                                                                                       // subresourceRange;
1897                                         getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
1898                                         0,                                                                                                                              // baseMipLevel;
1899                                         1,                                                                                                                              // mipLevels;
1900                                         0,                                                                                                                              // baseArraySlice;
1901                                         1                                                                                                                               // arraySize;
1902                                 }
1903                         };
1904
1905                         initializeLayouts.push_back(barrier);
1906                 }
1907
1908                 if (!initializeLayouts.empty())
1909                         vk.cmdPipelineBarrier(commandBuffer, (VkPipelineStageFlags)0, (VkPipelineStageFlags)0, (VkDependencyFlags)0,
1910                                                                   0, (const VkMemoryBarrier*)DE_NULL,
1911                                                                   0, (const VkBufferMemoryBarrier*)DE_NULL,
1912                                                                   (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
1913         }
1914
1915         for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1916         {
1917                 if (!clearValues[attachmentNdx])
1918                         continue;
1919
1920                 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
1921
1922                 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
1923                 {
1924                         const float                                             clearNan                = tcu::Float32::nan().asFloat();
1925                         const float                                             clearDepth              = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
1926                         const deUint32                                  clearStencil    = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : ~0u;
1927                         const VkClearDepthStencilValue  depthStencil    =
1928                         {
1929                                 clearDepth,
1930                                 clearStencil
1931                         };
1932                         const VkImageSubresourceRange range =
1933                         {
1934                                 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
1935                                                                          | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
1936                                 0,
1937                                 1,
1938                                 0,
1939                                 1
1940                         };
1941
1942                         vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
1943                 }
1944                 else
1945                 {
1946                         const VkImageSubresourceRange   range           =
1947                         {
1948                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // aspectMask;
1949                                 0,                                                                              // baseMipLevel;
1950                                 1,                                                                              // mipLevels;
1951                                 0,                                                                              // baseArrayLayer;
1952                                 1                                                                               // layerCount;
1953                         };
1954                         const VkClearColorValue                 clearColor      = clearValues[attachmentNdx]->color;
1955
1956                         vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
1957                 }
1958         }
1959
1960         {
1961                 vector<VkImageMemoryBarrier>    renderPassLayouts;
1962
1963                 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
1964                 {
1965                         const VkImageMemoryBarrier barrier =
1966                         {
1967                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                         // sType;
1968                                 DE_NULL,                                                                                                                        // pNext;
1969
1970                                 getAllMemoryWriteFlags(),                                                                                       // srcAccessMask
1971                                 getAllMemoryReadFlags(),                                                                                        // dstAccessMask
1972
1973                                 clearValues[attachmentNdx] ?
1974                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
1975                                         : VK_IMAGE_LAYOUT_UNDEFINED,                                                                    // oldLayout
1976
1977                                 attachmentInfo[attachmentNdx].getInitialLayout(),                                       // newLayout;
1978
1979                                 queueIndex,                                                                                                                     // srcQueueFamilyIndex;
1980                                 queueIndex,                                                                                                                     // destQueueFamilyIndex;
1981
1982                                 attachmentResources[attachmentNdx]->getImage(),                                         // image;
1983                                 {                                                                                                                                       // subresourceRange;
1984                                         getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
1985                                         0,                                                                                                                              // baseMipLevel;
1986                                         1,                                                                                                                              // mipLevels;
1987                                         0,                                                                                                                              // baseArraySlice;
1988                                         1                                                                                                                               // arraySize;
1989                                 }
1990                         };
1991
1992                         renderPassLayouts.push_back(barrier);
1993                 }
1994
1995                 if (!renderPassLayouts.empty())
1996                         vk.cmdPipelineBarrier(commandBuffer, 0, 0, (VkDependencyFlags)0,
1997                                                                   0, (const VkMemoryBarrier*)DE_NULL,
1998                                                                   0, (const VkBufferMemoryBarrier*)DE_NULL,
1999                                                                   (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2000         }
2001 }
2002
2003 void pushRenderPassCommands (const DeviceInterface&                                                             vk,
2004                                                          VkCommandBuffer                                                                        commandBuffer,
2005                                                          VkRenderPass                                                                           renderPass,
2006                                                          VkFramebuffer                                                                          framebuffer,
2007                                                          const vector<de::SharedPtr<SubpassRenderer> >&         subpassRenderers,
2008                                                          const UVec2&                                                                           renderPos,
2009                                                          const UVec2&                                                                           renderSize,
2010                                                          const vector<Maybe<VkClearValue> >&                            renderPassClearValues,
2011                                                          TestConfig::RenderTypes                                                        render)
2012 {
2013         const float                             clearNan                                = tcu::Float32::nan().asFloat();
2014         vector<VkClearValue>    attachmentClearValues;
2015
2016         for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2017         {
2018                 if (renderPassClearValues[attachmentNdx])
2019                         attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2020                 else
2021                         attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2022         }
2023
2024         {
2025                 const VkRect2D renderArea =
2026                 {
2027                         { (deInt32)renderPos.x(),       (deInt32)renderPos.y()  },
2028                         { renderSize.x(),                       renderSize.y()                  }
2029                 };
2030
2031                 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2032                 {
2033                         const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2034
2035                         if (subpassNdx == 0)
2036                                 cmdBeginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, (deUint32)attachmentClearValues.size(), attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0], contents);
2037                         else
2038                                 vk.cmdNextSubpass(commandBuffer, contents);
2039
2040                         if (render)
2041                         {
2042                                 if (contents == VK_SUBPASS_CONTENTS_INLINE)
2043                                 {
2044                                         subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2045                                 }
2046                                 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2047                                 {
2048                                         const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2049                                         vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2050                                 }
2051                                 else
2052                                         DE_FATAL("Invalid contents");
2053                         }
2054                 }
2055
2056                 vk.cmdEndRenderPass(commandBuffer);
2057         }
2058 }
2059
2060 void pushReadImagesToBuffers (const DeviceInterface&                                                            vk,
2061                                                           VkCommandBuffer                                                                               commandBuffer,
2062                                                           deUint32                                                                                              queueIndex,
2063
2064                                                           const vector<de::SharedPtr<AttachmentResources> >&    attachmentResources,
2065                                                           const vector<Attachment>&                                                             attachmentInfo,
2066                                                           const vector<bool>&                                                                   isLazy,
2067
2068                                                           const UVec2&                                                                                  targetSize)
2069 {
2070         {
2071                 vector<VkImageMemoryBarrier>    imageBarriers;
2072
2073                 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2074                 {
2075                         if (isLazy[attachmentNdx])
2076                                 continue;
2077
2078                         const VkImageMemoryBarrier barrier =
2079                         {
2080                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // sType
2081                                 DE_NULL,                                                                                        // pNext
2082
2083                                 getAllMemoryWriteFlags(),                                                       // srcAccessMask
2084                                 getAllMemoryReadFlags(),                                                        // dstAccessMask
2085
2086                                 attachmentInfo[attachmentNdx].getFinalLayout(),         // oldLayout
2087                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                           // newLayout
2088
2089                                 queueIndex,                                                                                     // srcQueueFamilyIndex
2090                                 queueIndex,                                                                                     // destQueueFamilyIndex
2091
2092                                 attachmentResources[attachmentNdx]->getImage(),         // image
2093                                 {                                                                                                       // subresourceRange
2094                                         getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2095                                         0,                                                                              // baseMipLevel
2096                                         1,                                                                              // mipLevels
2097                                         0,                                                                              // baseArraySlice
2098                                         1                                                                               // arraySize
2099                                 }
2100                         };
2101
2102                         imageBarriers.push_back(barrier);
2103                 }
2104
2105                 if (!imageBarriers.empty())
2106                         vk.cmdPipelineBarrier(commandBuffer,
2107                                                                   getAllPipelineStageFlags(),
2108                                                                   getAllPipelineStageFlags(),
2109                                                                   (VkDependencyFlags)0,
2110                                                                   0, (const VkMemoryBarrier*)DE_NULL,
2111                                                                   0, (const VkBufferMemoryBarrier*)DE_NULL,
2112                                                                   (deUint32)imageBarriers.size(), &imageBarriers[0]);
2113         }
2114
2115         for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2116         {
2117                 if (isLazy[attachmentNdx])
2118                         continue;
2119
2120                 const tcu::TextureFormat::ChannelOrder  order   = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2121                 const VkBufferImageCopy                                 rect    =
2122                 {
2123                         0, // bufferOffset
2124                         0, // bufferRowLength
2125                         0, // bufferImageHeight
2126                         {                                                       // imageSubresource
2127                                 getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order),    // aspect
2128                                 0,                                              // mipLevel
2129                                 0,                                              // arraySlice
2130                                 1                                               // arraySize
2131                         },
2132                         { 0, 0, 0 },                            // imageOffset
2133                         { targetSize.x(), targetSize.y(), 1u }          // imageExtent
2134                 };
2135
2136                 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
2137
2138                 if (tcu::TextureFormat::DS == order)
2139                 {
2140                         const VkBufferImageCopy stencilRect =
2141                         {
2142                                 0, // bufferOffset
2143                                 0, // bufferRowLength
2144                                 0, // bufferImageHeight
2145                                 {                                                                       // imageSubresource
2146                                         VK_IMAGE_ASPECT_STENCIL_BIT,    // aspect
2147                                         0,                                                              // mipLevel
2148                                         0,                                                              // arraySlice
2149                                         1                                               // arraySize
2150                                 },
2151                                 { 0, 0, 0 },                            // imageOffset
2152                                 { targetSize.x(), targetSize.y(), 1u }          // imageExtent
2153                         };
2154
2155                         vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
2156                 }
2157         }
2158
2159         {
2160                 vector<VkBufferMemoryBarrier>   bufferBarriers;
2161
2162                 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2163                 {
2164                         if (isLazy[attachmentNdx])
2165                                 continue;
2166
2167                         const tcu::TextureFormat::ChannelOrder  order                   = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2168                         const VkBufferMemoryBarrier                             bufferBarrier   =
2169                         {
2170                                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2171                                 DE_NULL,
2172
2173                                 getAllMemoryWriteFlags(),
2174                                 getAllMemoryReadFlags(),
2175
2176                                 queueIndex,
2177                                 queueIndex,
2178
2179                                 attachmentResources[attachmentNdx]->getBuffer(),
2180                                 0,
2181                                 attachmentResources[attachmentNdx]->getBufferSize()
2182                         };
2183
2184                         bufferBarriers.push_back(bufferBarrier);
2185
2186                         if (tcu::TextureFormat::DS == order)
2187                         {
2188                                 const VkBufferMemoryBarrier secondaryBufferBarrier =
2189                                 {
2190                                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2191                                         DE_NULL,
2192
2193                                         getAllMemoryWriteFlags(),
2194                                         getAllMemoryReadFlags(),
2195
2196                                         queueIndex,
2197                                         queueIndex,
2198
2199                                         attachmentResources[attachmentNdx]->getSecondaryBuffer(),
2200                                         0,
2201                                         attachmentResources[attachmentNdx]->getSecondaryBufferSize()
2202                                 };
2203
2204                                 bufferBarriers.push_back(secondaryBufferBarrier);
2205                         }
2206
2207                         bufferBarriers.push_back(bufferBarrier);
2208                 }
2209
2210                 if (!bufferBarriers.empty())
2211                         vk.cmdPipelineBarrier(commandBuffer,
2212                                                                   getAllPipelineStageFlags(),
2213                                                                   getAllPipelineStageFlags(),
2214                                                                   (VkDependencyFlags)0,
2215                                                                   0, (const VkMemoryBarrier*)DE_NULL,
2216                                                                   (deUint32)bufferBarriers.size(), &bufferBarriers[0],
2217                                                                   0, (const VkImageMemoryBarrier*)DE_NULL);
2218         }
2219 }
2220
2221 void clear (const PixelBufferAccess& access, const VkClearValue& value)
2222 {
2223         const tcu::TextureFormat&       format  = access.getFormat();
2224
2225         if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
2226         {
2227                 if (tcu::hasDepthComponent(format.order))
2228                         tcu::clearDepth(access, value.depthStencil.depth);
2229
2230                 if (tcu::hasStencilComponent(format.order))
2231                         tcu::clearStencil(access, value.depthStencil.stencil);
2232         }
2233         else
2234         {
2235                 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT
2236                                 || tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
2237                                 || tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
2238                 {
2239                         const tcu::Vec4         color   (value.color.float32[0],
2240                                                                                  value.color.float32[1],
2241                                                                                  value.color.float32[2],
2242                                                                                  value.color.float32[3]);
2243
2244                         if (tcu::isSRGB(format))
2245                                 tcu::clear(access, tcu::linearToSRGB(color));
2246                         else
2247                                 tcu::clear(access, color);
2248                 }
2249                 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
2250                 {
2251                         const tcu::UVec4        color   (value.color.uint32[0],
2252                                                                                  value.color.uint32[1],
2253                                                                                  value.color.uint32[2],
2254                                                                                  value.color.uint32[3]);
2255
2256                         tcu::clear(access, color);
2257                 }
2258                 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2259                 {
2260                         const tcu::IVec4        color   (value.color.int32[0],
2261                                                                                  value.color.int32[1],
2262                                                                                  value.color.int32[2],
2263                                                                                  value.color.int32[3]);
2264
2265                         tcu::clear(access, color);
2266                 }
2267                 else
2268                         DE_FATAL("Unknown channel class");
2269         }
2270 }
2271
2272 Vec4 computeUvs (const IVec2& posA, const IVec2& posB, const IVec2& pos)
2273 {
2274         const float u = de::clamp((float)(pos.x() - posA.x()) / (float)(posB.x() - posA.x()), 0.0f, 1.0f);
2275         const float v = de::clamp((float)(pos.y() - posA.y()) / (float)(posB.y() - posA.y()), 0.0f, 1.0f);
2276
2277         return Vec4(u, v, u * v, (u + v) / 2.0f);
2278 }
2279
2280 void renderReferenceImages (vector<tcu::TextureLevel>&                  referenceAttachments,
2281                                                         const RenderPass&                                       renderPassInfo,
2282                                                         const UVec2&                                            targetSize,
2283                                                         const vector<Maybe<VkClearValue> >&     imageClearValues,
2284                                                         const vector<Maybe<VkClearValue> >&     renderPassClearValues,
2285                                                         const vector<SubpassRenderInfo>&        subpassRenderInfo,
2286                                                         const UVec2&                                            renderPos,
2287                                                         const UVec2&                                            renderSize)
2288 {
2289         const vector<Subpass>&  subpasses               = renderPassInfo.getSubpasses();
2290         vector<bool>                    attachmentUsed  (renderPassInfo.getAttachments().size(), false);
2291
2292         referenceAttachments.resize(renderPassInfo.getAttachments().size());
2293
2294         for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2295         {
2296                 const Attachment                                attachment                                      = renderPassInfo.getAttachments()[attachmentNdx];
2297                 const tcu::TextureFormat                format                                          = mapVkFormat(attachment.getFormat());
2298                 const tcu::TextureFormatInfo    textureInfo                                     = tcu::getTextureFormatInfo(format);
2299                 tcu::TextureLevel&                              reference                                       = referenceAttachments[attachmentNdx];
2300                 const bool                                              isDepthOrStencilAttachment      = hasDepthComponent(format.order) || hasStencilComponent(format.order);
2301
2302                 reference = tcu::TextureLevel(format, targetSize.x(), targetSize.y());
2303
2304                 if (imageClearValues[attachmentNdx])
2305                         clear(reference.getAccess(), *imageClearValues[attachmentNdx]);
2306                 else
2307                 {
2308                         // Fill with grid if image contentst are undefined before renderpass
2309                         if (isDepthOrStencilAttachment)
2310                         {
2311                                 if (tcu::hasDepthComponent(format.order))
2312                                         tcu::fillWithGrid(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH), 2, textureInfo.valueMin, textureInfo.valueMax);
2313
2314                                 if (tcu::hasStencilComponent(format.order))
2315                                         tcu::fillWithGrid(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL), 2, textureInfo.valueMin, textureInfo.valueMax);
2316                         }
2317                         else
2318                                 tcu::fillWithGrid(reference.getAccess(), 2, textureInfo.valueMin, textureInfo.valueMax);
2319                 }
2320         }
2321
2322         for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
2323         {
2324                 const Subpass&                                          subpass                         = subpasses[subpassNdx];
2325                 const SubpassRenderInfo&                        renderInfo                      = subpassRenderInfo[subpassNdx];
2326                 const vector<AttachmentReference>&      colorAttachments        = subpass.getColorAttachments();
2327
2328                 // Apply load op if attachment was used for the first time
2329                 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
2330                 {
2331                         const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment();
2332
2333                         if (!attachmentUsed[attachmentIndex])
2334                         {
2335                                 const Attachment&       attachment      = renderPassInfo.getAttachments()[attachmentIndex];
2336                                 tcu::TextureLevel&      reference       = referenceAttachments[attachmentIndex];
2337
2338                                 DE_ASSERT(!tcu::hasDepthComponent(reference.getFormat().order));
2339                                 DE_ASSERT(!tcu::hasStencilComponent(reference.getFormat().order));
2340
2341                                 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2342                                         clear(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2343                                 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2344                                 {
2345                                         const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2346
2347                                         tcu::fillWithGrid(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2348                                 }
2349
2350                                 attachmentUsed[attachmentIndex] = true;
2351                         }
2352                 }
2353
2354                 // Apply load op to depth/stencil attachment if it was used for the first time
2355                 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED && !attachmentUsed[subpass.getDepthStencilAttachment().getAttachment()])
2356                 {
2357                         const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2358
2359                         // Apply load op if attachment was used for the first time
2360                         if (!attachmentUsed[attachmentIndex])
2361                         {
2362                                 const Attachment&       attachment      = renderPassInfo.getAttachments()[attachmentIndex];
2363                                 tcu::TextureLevel&      reference               = referenceAttachments[attachmentIndex];
2364
2365                                 if (tcu::hasDepthComponent(reference.getFormat().order))
2366                                 {
2367                                         if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2368                                                 clear(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2369                                         else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2370                                         {
2371                                                 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2372
2373                                                 tcu::fillWithGrid(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2374                                         }
2375                                 }
2376
2377                                 if (tcu::hasStencilComponent(reference.getFormat().order))
2378                                 {
2379                                         if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2380                                                 clear(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), *renderPassClearValues[attachmentIndex]);
2381                                         else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2382                                         {
2383                                                 const tcu::TextureFormatInfo textureInfo = tcu::getTextureFormatInfo(reference.getFormat());
2384
2385                                                 tcu::fillWithGrid(tcu::getSubregion(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2386                                         }
2387                                 }
2388                         }
2389
2390                         attachmentUsed[attachmentIndex] = true;
2391                 }
2392
2393                 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
2394                 {
2395                         const ColorClear&       colorClear      = renderInfo.getColorClears()[colorClearNdx];
2396                         const UVec2                     offset          = colorClear.getOffset();
2397                         const UVec2                     size            = colorClear.getSize();
2398                         tcu::TextureLevel&      reference       = referenceAttachments[subpass.getColorAttachments()[colorClearNdx].getAttachment()];
2399                         VkClearValue            value;
2400
2401                         value.color = colorClear.getColor();
2402
2403                         clear(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), value);
2404                 }
2405
2406                 if (renderInfo.getDepthStencilClear())
2407                 {
2408                         const DepthStencilClear&        dsClear         = *renderInfo.getDepthStencilClear();
2409                         const UVec2                                     offset          = dsClear.getOffset();
2410                         const UVec2                                     size            = dsClear.getSize();
2411                         tcu::TextureLevel&                      reference       = referenceAttachments[subpass.getDepthStencilAttachment().getAttachment()];
2412
2413                         if (tcu::hasDepthComponent(reference.getFormat().order))
2414                                 clearDepth(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), dsClear.getDepth());
2415
2416                         if (tcu::hasStencilComponent(reference.getFormat().order))
2417                                 clearStencil(tcu::getSubregion(reference.getAccess(), offset.x(), offset.y(), 0, size.x(), size.y(), 1), dsClear.getStencil());
2418                 }
2419
2420                 if (renderInfo.getRenderQuad())
2421                 {
2422                         const RenderQuad&       renderQuad      = *renderInfo.getRenderQuad();
2423                         const Vec4                      posA            = renderQuad.getCornerA();
2424                         const Vec4                      posB            = renderQuad.getCornerB();
2425                         const Vec2                      origin          = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2426                         const Vec2                      p                       = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2427                         const IVec2                     posAI           ((deInt32)(origin.x() + (p.x() * posA.x())),
2428                                                                                          (deInt32)(origin.y() + (p.y() * posA.y())));
2429                         const IVec2                     posBI           ((deInt32)(origin.x() + (p.x() * posB.x())),
2430                                                                                          (deInt32)(origin.y() + (p.y() * posB.y())));
2431
2432                         for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
2433                         {
2434                                 const Attachment                                attachment                      = renderPassInfo.getAttachments()[subpass.getColorAttachments()[attachmentRefNdx].getAttachment()];
2435                                 const tcu::TextureFormatInfo    textureInfo                     = tcu::getTextureFormatInfo(mapVkFormat(attachment.getFormat()));
2436                                 tcu::TextureLevel&                              referenceTexture        = referenceAttachments[subpass.getColorAttachments()[attachmentRefNdx].getAttachment()];
2437                                 const bool                                              srgb                            = tcu::isSRGB(referenceTexture.getFormat());
2438                                 const PixelBufferAccess reference                       = referenceTexture.getAccess();
2439                                 const float                                             clampMin                        = (float)(-MAX_INTEGER_VALUE);
2440                                 const float                                             clampMax                        = (float)(MAX_INTEGER_VALUE);
2441                                 const Vec4                                              valueMax                        (de::clamp(textureInfo.valueMax[0], clampMin, clampMax),
2442                                                                                                                                          de::clamp(textureInfo.valueMax[1], clampMin, clampMax),
2443                                                                                                                                          de::clamp(textureInfo.valueMax[2], clampMin, clampMax),
2444                                                                                                                                          de::clamp(textureInfo.valueMax[3], clampMin, clampMax));
2445
2446                                 const Vec4                                              valueMin                        (de::clamp(textureInfo.valueMin[0], clampMin, clampMax),
2447                                                                                                                                          de::clamp(textureInfo.valueMin[1], clampMin, clampMax),
2448                                                                                                                                          de::clamp(textureInfo.valueMin[2], clampMin, clampMax),
2449                                                                                                                                          de::clamp(textureInfo.valueMin[3], clampMin, clampMax));
2450
2451                                 DE_ASSERT(posAI.x() < posBI.x());
2452                                 DE_ASSERT(posAI.y() < posBI.y());
2453
2454                                 for (int y = posAI.y(); y <= (int)posBI.y(); y++)
2455                                 for (int x = posAI.x(); x <= (int)posBI.x(); x++)
2456                                 {
2457                                         const Vec4      uvs             = computeUvs(posAI, posBI, IVec2(x, y));
2458                                         const Vec4      color   = valueMax * uvs + valueMin * (Vec4(1.0f) - uvs);
2459
2460                                         if (srgb)
2461                                                 reference.setPixel(tcu::linearToSRGB(color), x, y);
2462                                         else
2463                                                 reference.setPixel(color, x, y);
2464                                 }
2465                         }
2466
2467                         if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
2468                         {
2469                                 tcu::TextureLevel&                              referenceTexture        = referenceAttachments[subpass.getDepthStencilAttachment().getAttachment()];
2470                                 const PixelBufferAccess reference                       = referenceTexture.getAccess();
2471
2472                                 DE_ASSERT(posAI.x() < posBI.x());
2473                                 DE_ASSERT(posAI.y() < posBI.y());
2474
2475                                 for (int y = posAI.y(); y <= (int)posBI.y(); y++)
2476                                 for (int x = posAI.x(); x <= (int)posBI.x(); x++)
2477                                 {
2478                                         const Vec4 uvs = computeUvs(posAI, posBI, IVec2(x, y));
2479
2480                                         if (tcu::hasDepthComponent(reference.getFormat().order))
2481                                                 reference.setPixDepth(uvs.x(), x, y);
2482
2483                                         if (tcu::hasStencilComponent(reference.getFormat().order))
2484                                                 reference.setPixStencil(STENCIL_VALUE, x, y);
2485                                 }
2486                         }
2487                 }
2488         }
2489
2490         // Mark all attachments that were used but not stored as undefined
2491         for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2492         {
2493                 const Attachment                                attachment      = renderPassInfo.getAttachments()[attachmentNdx];
2494                 const tcu::TextureFormat                format          = mapVkFormat(attachment.getFormat());
2495                 const tcu::TextureFormatInfo    textureInfo     = tcu::getTextureFormatInfo(format);
2496                 tcu::TextureLevel&                              reference       = referenceAttachments[attachmentNdx];
2497
2498                 if (attachmentUsed[attachmentNdx] && renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
2499                         tcu::fillWithGrid(tcu::getSubregion(reference.getAccess(), renderPos.x(), renderPos.y(), renderSize.x(), renderSize.y()), 2, textureInfo.valueMin, textureInfo.valueMax);
2500         }
2501 }
2502
2503 Maybe<deUint32> findColorAttachment (const Subpass&                             subpass,
2504                                                                          deUint32                                       attachmentIndex)
2505 {
2506         for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpass.getColorAttachments().size(); colorAttachmentNdx++)
2507         {
2508                 if (subpass.getColorAttachments()[colorAttachmentNdx].getAttachment() == attachmentIndex)
2509                         return tcu::just((deUint32)colorAttachmentNdx);
2510         }
2511
2512         return tcu::nothing<deUint32>();
2513 }
2514
2515 int calcFloatDiff (float a, float b)
2516 {
2517         const deUint32          au              = tcu::Float32(a).bits();
2518         const deUint32          bu              = tcu::Float32(b).bits();
2519
2520         const bool                      asign   = (au & (0x1u << 31u)) != 0u;
2521         const bool                      bsign   = (bu & (0x1u << 31u)) != 0u;
2522
2523         const deUint32          avalue  = (au & ((0x1u << 31u) - 1u));
2524         const deUint32          bvalue  = (bu & ((0x1u << 31u) - 1u));
2525
2526         if (asign != bsign)
2527                 return avalue + bvalue + 1u;
2528         else if (avalue < bvalue)
2529                 return bvalue - avalue;
2530         else
2531                 return avalue - bvalue;
2532 }
2533
2534 bool comparePixelToDepthClearValue (const ConstPixelBufferAccess&       access,
2535                                                                         int                                                             x,
2536                                                                         int                                                             y,
2537                                                                         float                                                   ref)
2538 {
2539         const tcu::TextureFormat                format                  = tcu::getEffectiveDepthStencilTextureFormat(access.getFormat(), tcu::Sampler::MODE_DEPTH);
2540         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
2541
2542         switch (channelClass)
2543         {
2544                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2545                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2546                 {
2547                         const int       bitDepth        = tcu::getTextureFormatBitDepth(format).x();
2548                         const float     depth           = access.getPixDepth(x, y);
2549                         const float     threshold       = 2.0f / (float)((1 << bitDepth) - 1);
2550
2551                         return deFloatAbs(depth - ref) <= threshold;
2552                 }
2553
2554                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2555                 {
2556                         const float     depth                   = access.getPixDepth(x, y);
2557                         const int       mantissaBits    = tcu::getTextureFormatMantissaBitDepth(format).x();
2558                         const int       threshold               = 10 * 1 << (23 - mantissaBits);
2559
2560                         DE_ASSERT(mantissaBits <= 23);
2561
2562                         return calcFloatDiff(depth, ref) <= threshold;
2563                 }
2564
2565                 default:
2566                         DE_FATAL("Invalid channel class");
2567                         return false;
2568         }
2569 }
2570
2571 bool comparePixelToStencilClearValue (const ConstPixelBufferAccess&     access,
2572                                                                           int                                                   x,
2573                                                                           int                                                   y,
2574                                                                           deUint32                                              ref)
2575 {
2576         const deUint32 stencil = access.getPixStencil(x, y);
2577
2578         return stencil == ref;
2579 }
2580
2581 bool comparePixelToColorClearValue (const ConstPixelBufferAccess&       access,
2582                                                                         int                                                             x,
2583                                                                         int                                                             y,
2584                                                                         const VkClearColorValue&                ref)
2585 {
2586         const tcu::TextureFormat                format                  = access.getFormat();
2587         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
2588         const BVec4                                             channelMask             = tcu::getTextureFormatChannelMask(format);
2589
2590         switch (channelClass)
2591         {
2592                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2593                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2594                 {
2595                         const IVec4     bitDepth        (tcu::getTextureFormatBitDepth(format));
2596                         const Vec4      resColor        (access.getPixel(x, y));
2597                         const Vec4      refColor        (ref.float32[0],
2598                                                                          ref.float32[1],
2599                                                                          ref.float32[2],
2600                                                                          ref.float32[3]);
2601                         const Vec4      threshold       (bitDepth[0] > 0 ? 20.0f / (float)((1 << bitDepth[0]) - 1) : 1.0f,
2602                                                                          bitDepth[1] > 0 ? 20.0f / (float)((1 << bitDepth[1]) - 1) : 1.0f,
2603                                                                          bitDepth[2] > 0 ? 20.0f / (float)((1 << bitDepth[2]) - 1) : 1.0f,
2604                                                                          bitDepth[3] > 0 ? 20.0f / (float)((1 << bitDepth[3]) - 1) : 1.0f);
2605
2606                         if (tcu::isSRGB(access.getFormat()))
2607                                 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, tcu::linearToSRGB(refColor)), threshold), channelMask), channelMask));
2608                         else
2609                                 return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2610                 }
2611
2612                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2613                 {
2614                         const UVec4     resColor        (access.getPixelUint(x, y));
2615                         const UVec4     refColor        (ref.uint32[0],
2616                                                                          ref.uint32[1],
2617                                                                          ref.uint32[2],
2618                                                                          ref.uint32[3]);
2619                         const UVec4     threshold       (1);
2620
2621                         return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2622                 }
2623
2624                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2625                 {
2626                         const IVec4     resColor        (access.getPixelInt(x, y));
2627                         const IVec4     refColor        (ref.int32[0],
2628                                                                          ref.int32[1],
2629                                                                          ref.int32[2],
2630                                                                          ref.int32[3]);
2631                         const IVec4     threshold       (1);
2632
2633                         return !(tcu::anyNotEqual(tcu::logicalAnd(lessThanEqual(tcu::absDiff(resColor, refColor), threshold), channelMask), channelMask));
2634                 }
2635
2636                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2637                 {
2638                         const Vec4      resColor                (access.getPixel(x, y));
2639                         const Vec4      refColor                (ref.float32[0],
2640                                                                                  ref.float32[1],
2641                                                                                  ref.float32[2],
2642                                                                                  ref.float32[3]);
2643                         const IVec4     mantissaBits    (tcu::getTextureFormatMantissaBitDepth(format));
2644                         const IVec4     threshold               (10 * IVec4(1) << (23 - mantissaBits));
2645
2646                         DE_ASSERT(tcu::allEqual(greaterThanEqual(threshold, IVec4(0)), BVec4(true)));
2647
2648                         for (int ndx = 0; ndx < 4; ndx++)
2649                         {
2650                                 if (calcFloatDiff(resColor[ndx], refColor[ndx]) > threshold[ndx] && channelMask[ndx])
2651                                         return false;
2652                         }
2653
2654                         return true;
2655                 }
2656
2657                 default:
2658                         DE_FATAL("Invalid channel class");
2659                         return false;
2660         }
2661 }
2662
2663 class PixelStatus
2664 {
2665 public:
2666         enum Status
2667         {
2668                 STATUS_UNDEFINED        = 0,
2669                 STATUS_OK                       = 1,
2670                 STATUS_FAIL                     = 2,
2671
2672                 STATUS_LAST
2673         };
2674
2675                         PixelStatus                     (Status color, Status depth, Status stencil)
2676                 : m_status      ((deUint8)(color << COLOR_OFFSET)
2677                                         | (deUint8)((deUint8)depth << DEPTH_OFFSET)
2678                                         | (deUint8)((deUint8)stencil << STENCIL_OFFSET))
2679         {
2680         }
2681
2682         Status  getColorStatus          (void) const { return (Status)((m_status & COLOR_MASK) >> COLOR_OFFSET); }
2683         Status  getDepthStatus          (void) const { return (Status)((m_status & DEPTH_MASK) >> DEPTH_OFFSET); }
2684         Status  getStencilStatus        (void) const { return (Status)((m_status & STENCIL_MASK) >> STENCIL_OFFSET); }
2685
2686         void    setColorStatus          (Status status)
2687         {
2688                 DE_ASSERT(getColorStatus() == STATUS_UNDEFINED);
2689                 m_status |= (deUint8)(status << COLOR_OFFSET);
2690         }
2691
2692         void    setDepthStatus          (Status status)
2693         {
2694                 DE_ASSERT(getDepthStatus() == STATUS_UNDEFINED);
2695                 m_status |= (deUint8)(status << DEPTH_OFFSET);
2696         }
2697
2698         void    setStencilStatus        (Status status)
2699         {
2700                 DE_ASSERT(getStencilStatus() == STATUS_UNDEFINED);
2701                 m_status |= (deUint8)(status << STENCIL_OFFSET);
2702         }
2703
2704 private:
2705         enum
2706         {
2707                 COLOR_OFFSET    = 0,
2708                 DEPTH_OFFSET    = 2,
2709                 STENCIL_OFFSET  = 4,
2710
2711                 COLOR_MASK              = (3<<COLOR_OFFSET),
2712                 DEPTH_MASK              = (3<<DEPTH_OFFSET),
2713                 STENCIL_MASK    = (3<<STENCIL_OFFSET),
2714         };
2715         deUint8 m_status;
2716 };
2717
2718 void checkDepthRenderQuad (const ConstPixelBufferAccess&        result,
2719                                                    const IVec2&                                         posA,
2720                                                    const IVec2&                                         posB,
2721                                                    vector<PixelStatus>&                         status)
2722 {
2723         for (int y = posA.y(); y <= posB.y(); y++)
2724         for (int x = posA.x(); x <= posB.x(); x++)
2725         {
2726                 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2727
2728                 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED)
2729                 {
2730                         const Vec4      minUvs          = computeUvs(posA, posB, IVec2(x-1, y-1));
2731                         const Vec4      maxUvs          = computeUvs(posA, posB, IVec2(x+1, y+1));
2732                         const bool      softCheck       = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2733                                                                         || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2734                         const float     resDepth        = result.getPixDepth(x, y);
2735
2736                         if (resDepth >= minUvs.x() && resDepth <= maxUvs.x())
2737                                 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
2738                         else if (!softCheck)
2739                                 pixelStatus.setDepthStatus(PixelStatus::STATUS_FAIL);
2740                 }
2741         }
2742 }
2743
2744 void checkStencilRenderQuad (const ConstPixelBufferAccess&              result,
2745                                                          const IVec2&                                           posA,
2746                                                          const IVec2&                                           posB,
2747                                                          vector<PixelStatus>&                           status)
2748 {
2749         for (int y = posA.y(); y <= posB.y(); y++)
2750         for (int x = posA.x(); x <= posB.x(); x++)
2751         {
2752                 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2753
2754                 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED)
2755                 {
2756                         const bool      softCheck       = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2757                                                                         || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2758
2759                         if (result.getPixStencil(x, y) == STENCIL_VALUE)
2760                                 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
2761                         else if (!softCheck)
2762                                 pixelStatus.setStencilStatus(PixelStatus::STATUS_FAIL);
2763                 }
2764         }
2765 }
2766
2767 void checkColorRenderQuad (const ConstPixelBufferAccess&        result,
2768                                                    const IVec2&                                         posA,
2769                                                    const IVec2&                                         posB,
2770                                                    vector<PixelStatus>&                         status)
2771 {
2772         const tcu::TextureFormat&               format                          = result.getFormat();
2773         const bool                                              srgb                            = tcu::isSRGB(format);
2774         const tcu::TextureChannelClass  channelClass            = tcu::getTextureChannelClass(format.type);
2775         const tcu::TextureFormatInfo    textureInfo                     = tcu::getTextureFormatInfo(format);
2776         const float                                             clampMin                        = (float)(-MAX_INTEGER_VALUE);
2777         const float                                             clampMax                        = (float)(MAX_INTEGER_VALUE);
2778         const Vec4                                              valueMax                        (de::clamp(textureInfo.valueMax[0], clampMin, clampMax),
2779                                                                                                                  de::clamp(textureInfo.valueMax[1], clampMin, clampMax),
2780                                                                                                                  de::clamp(textureInfo.valueMax[2], clampMin, clampMax),
2781                                                                                                                  de::clamp(textureInfo.valueMax[3], clampMin, clampMax));
2782
2783         const Vec4                                              valueMin                        (de::clamp(textureInfo.valueMin[0], clampMin, clampMax),
2784                                                                                                                  de::clamp(textureInfo.valueMin[1], clampMin, clampMax),
2785                                                                                                                  de::clamp(textureInfo.valueMin[2], clampMin, clampMax),
2786                                                                                                                  de::clamp(textureInfo.valueMin[3], clampMin, clampMax));
2787         const BVec4                                             channelMask                     = tcu::getTextureFormatChannelMask(format);
2788
2789         IVec4                                           formatBitDepths = tcu::getTextureFormatBitDepth(format);
2790         Vec4                                            threshold = Vec4(1.0f) / Vec4((float)(1 << formatBitDepths.x()),
2791                                                                                                                                 (float)(1 << formatBitDepths.y()),
2792                                                                                                                                 (float)(1 << formatBitDepths.z()),
2793                                                                                                                                 (float)(1 << formatBitDepths.w()));
2794
2795         switch (channelClass)
2796         {
2797                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2798                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2799                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2800                 {
2801                         for (int y = posA.y(); y <= posB.y(); y++)
2802                         for (int x = posA.x(); x <= posB.x(); x++)
2803                         {
2804                                 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2805
2806                                 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2807                                 {
2808                                         const Vec4      minUvs          = computeUvs(posA, posB, IVec2(x-1, y-1));
2809                                         const Vec4      maxUvs          = computeUvs(posA, posB, IVec2(x+1, y+1));
2810                                         const bool      softCheck       = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2811                                                                                         || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2812
2813                                         const Vec4      resColor        (result.getPixel(x, y));
2814
2815                                         const Vec4      minRefColor     = srgb ? tcu::linearToSRGB(valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs))
2816                                                                                                          : valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs) - threshold;
2817                                         const Vec4      maxRefColor     = srgb ? tcu::linearToSRGB(valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs))
2818                                                                                                          : valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs) + threshold;
2819
2820                                         DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2821                                         DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2822                                         DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2823                                         DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2824
2825                                         if (tcu::anyNotEqual(tcu::logicalAnd(
2826                                                                                         tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2827                                                                                                                         lessThanEqual(resColor, maxRefColor)),
2828                                                                                         channelMask), channelMask))
2829                                         {
2830                                                 if (!softCheck)
2831                                                         pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2832                                         }
2833                                         else
2834                                                 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2835                                 }
2836                         }
2837
2838                         break;
2839                 }
2840
2841                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2842                 {
2843                         for (int y = posA.y(); y <= posB.y(); y++)
2844                         for (int x = posA.x(); x <= posB.x(); x++)
2845                         {
2846                                 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2847
2848                                 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2849                                 {
2850                                         const Vec4      minUvs                  = computeUvs(posA, posB, IVec2(x-1, y-1));
2851                                         const Vec4      maxUvs                  = computeUvs(posA, posB, IVec2(x+1, y+1));
2852                                         const bool      softCheck               = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2853                                                                                                 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2854
2855                                         const UVec4     resColor                (result.getPixelUint(x, y));
2856
2857                                         const Vec4      minRefColorF    = valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs);
2858                                         const Vec4      maxRefColorF    = valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs);
2859
2860                                         const UVec4     minRefColor             (minRefColorF.asUint());
2861                                         const UVec4     maxRefColor             (maxRefColorF.asUint());
2862
2863                                         DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2864                                         DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2865                                         DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2866                                         DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2867
2868                                         if (tcu::anyNotEqual(tcu::logicalAnd(
2869                                                                                         tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2870                                                                                                                         lessThanEqual(resColor, maxRefColor)),
2871                                                                                         channelMask), channelMask))
2872                                         {
2873                                                 if (!softCheck)
2874                                                         pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2875                                         }
2876                                         else
2877                                                 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2878                                 }
2879                         }
2880
2881                         break;
2882                 }
2883
2884                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2885                 {
2886                         for (int y = posA.y(); y <= posB.y(); y++)
2887                         for (int x = posA.x(); x <= posB.x(); x++)
2888                         {
2889                                 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2890
2891                                 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2892                                 {
2893                                         const Vec4      minUvs                  = computeUvs(posA, posB, IVec2(x-1, y-1));
2894                                         const Vec4      maxUvs                  = computeUvs(posA, posB, IVec2(x+1, y+1));
2895                                         const bool      softCheck               = std::abs(x - posA.x()) <= 1 || std::abs(x - posB.x()) <= 1
2896                                                                                                 || std::abs(y - posA.y()) <= 1 || std::abs(y - posB.y()) <= 1;
2897
2898                                         const IVec4     resColor                (result.getPixelInt(x, y));
2899
2900                                         const Vec4      minRefColorF    = valueMax * minUvs + valueMin * (Vec4(1.0f) - minUvs);
2901                                         const Vec4      maxRefColorF    = valueMax * maxUvs + valueMin * (Vec4(1.0f) - maxUvs);
2902
2903                                         const IVec4     minRefColor             (minRefColorF.asInt());
2904                                         const IVec4     maxRefColor             (maxRefColorF.asInt());
2905
2906                                         DE_ASSERT(minRefColor[0] <= maxRefColor[0]);
2907                                         DE_ASSERT(minRefColor[1] <= maxRefColor[1]);
2908                                         DE_ASSERT(minRefColor[2] <= maxRefColor[2]);
2909                                         DE_ASSERT(minRefColor[3] <= maxRefColor[3]);
2910
2911                                         if (tcu::anyNotEqual(tcu::logicalAnd(
2912                                                                                         tcu::logicalAnd(greaterThanEqual(resColor, minRefColor),
2913                                                                                                                         lessThanEqual(resColor, maxRefColor)),
2914                                                                                         channelMask), channelMask))
2915                                         {
2916                                                 if (!softCheck)
2917                                                         pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2918                                         }
2919                                         else
2920                                                 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2921                                 }
2922                         }
2923
2924                         break;
2925                 }
2926
2927                 default:
2928                         DE_FATAL("Invalid channel class");
2929         }
2930 }
2931
2932 void checkColorClear (const ConstPixelBufferAccess&     result,
2933                                           const UVec2&                                  offset,
2934                                           const UVec2&                                  size,
2935                                           vector<PixelStatus>&                  status,
2936                                           const VkClearColorValue&              color)
2937 {
2938         DE_ASSERT(offset.x() + size.x() <= (deUint32)result.getWidth());
2939         DE_ASSERT(offset.y() + size.y() <= (deUint32)result.getHeight());
2940
2941         DE_ASSERT(result.getWidth() * result.getHeight() == (int)status.size());
2942
2943         for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2944         for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2945         {
2946                 PixelStatus& pixelStatus = status[x + y * result.getWidth()];
2947
2948                 DE_ASSERT(x + y * result.getWidth() < (int)status.size());
2949
2950                 if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
2951                 {
2952                         if (comparePixelToColorClearValue(result, x, y, color))
2953                                 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
2954                         else
2955                                 pixelStatus.setColorStatus(PixelStatus::STATUS_FAIL);
2956                 }
2957         }
2958 }
2959
2960 void checkDepthClear (const ConstPixelBufferAccess&     result,
2961                                           const UVec2&                                  offset,
2962                                           const UVec2&                                  size,
2963                                           vector<PixelStatus>&                  status,
2964                                           float                                                 depth)
2965 {
2966         for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2967         for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2968         {
2969                 PixelStatus&    pixelStatus     = status[x + y * result.getWidth()];
2970
2971                 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED)
2972                 {
2973                         if (comparePixelToDepthClearValue(result, x, y, depth))
2974                                 pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
2975                         else
2976                                 pixelStatus.setDepthStatus(PixelStatus::STATUS_FAIL);
2977                 }
2978         }
2979 }
2980
2981 void checkStencilClear (const ConstPixelBufferAccess&   result,
2982                                                 const UVec2&                                    offset,
2983                                                 const UVec2&                                    size,
2984                                                 vector<PixelStatus>&                    status,
2985                                                 deUint32                                                stencil)
2986 {
2987         for (int y = offset.y(); y < (int)(offset.y() + size.y()); y++)
2988         for (int x = offset.x(); x < (int)(offset.x() + size.x()); x++)
2989         {
2990                 PixelStatus&    pixelStatus     = status[x + y * result.getWidth()];
2991
2992                 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED)
2993                 {
2994                         if (comparePixelToStencilClearValue(result, x, y, stencil))
2995                                 pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
2996                         else
2997                                 pixelStatus.setStencilStatus(PixelStatus::STATUS_FAIL);
2998                 }
2999         }
3000 }
3001
3002 bool verifyAttachment (const ConstPixelBufferAccess&            result,
3003                                            const Maybe<ConstPixelBufferAccess>& secondaryResult,
3004                                            const RenderPass&                                    renderPassInfo,
3005                                            const Maybe<VkClearValue>&                   renderPassClearValue,
3006                                            const Maybe<VkClearValue>&                   imageClearValue,
3007                                            const vector<Subpass>&                               subpasses,
3008                                            const vector<SubpassRenderInfo>&             subpassRenderInfo,
3009                                            const PixelBufferAccess&                             errorImage,
3010                                            deUint32                                                             attachmentIndex,
3011                                            const UVec2&                                                 renderPos,
3012                                            const UVec2&                                                 renderSize)
3013 {
3014         const tcu::TextureFormat&               format                          = result.getFormat();
3015         const bool                                              hasDepth                        = tcu::hasDepthComponent(format.order);
3016         const bool                                              hasStencil                      = tcu::hasStencilComponent(format.order);
3017         const bool                                              isColorFormat           = !hasDepth && !hasStencil;
3018         const PixelStatus                               initialStatus           (isColorFormat ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK,
3019                                                                                                                  hasDepth ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK,
3020                                                                                                                  hasStencil ? PixelStatus::STATUS_UNDEFINED : PixelStatus::STATUS_OK);
3021
3022         bool                                                    attachmentIsUsed        = false;
3023         vector<PixelStatus>                             status                          (result.getWidth() * result.getHeight(), initialStatus);
3024         tcu::clear(errorImage, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
3025
3026         // Check if attachment is used
3027         for (int subpassNdx = 0; subpassNdx < (int)subpasses.size(); subpassNdx++)
3028         {
3029                 const Subpass&                  subpass                 = subpasses[subpassNdx];
3030                 const Maybe<deUint32>   attachmentNdx   = findColorAttachment(subpass, attachmentIndex);
3031
3032                 if (attachmentNdx || subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex)
3033                         attachmentIsUsed = true;
3034         }
3035
3036         // Set all pixels that have undefined values to OK
3037         if (attachmentIsUsed && (((isColorFormat || hasDepth) && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3038                                                         || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)))
3039         {
3040                 for(int y = renderPos.y(); y < (int)(renderPos.y() + renderSize.y()); y++)
3041                 for(int x = renderPos.x(); x < (int)(renderPos.x() + renderSize.x()); x++)
3042                 {
3043                         PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3044
3045                         if (isColorFormat && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3046                                 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
3047                         else
3048                         {
3049                                 if (hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3050                                         pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
3051
3052                                 if (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3053                                         pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3054                         }
3055                 }
3056         }
3057
3058         // Check renderpass rendering results
3059         if (renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3060                 || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE))
3061         {
3062                 // Check subpass rendering results
3063                 for (int subpassNdx = (int)subpasses.size() - 1; subpassNdx >= 0; subpassNdx--)
3064                 {
3065                         const Subpass&                          subpass                 = subpasses[subpassNdx];
3066                         const SubpassRenderInfo&        renderInfo              = subpassRenderInfo[subpassNdx];
3067                         const Maybe<deUint32>           attachmentNdx   = findColorAttachment(subpass, attachmentIndex);
3068
3069                         // Check rendered quad
3070                         if (renderInfo.getRenderQuad() && (attachmentNdx || subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex))
3071                         {
3072                                 const RenderQuad&       renderQuad      = *renderInfo.getRenderQuad();
3073                                 const Vec4                      posA            = renderQuad.getCornerA();
3074                                 const Vec4                      posB            = renderQuad.getCornerB();
3075                                 const Vec2                      origin          = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3076                                 const Vec2                      p                       = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3077                                 const IVec2                     posAI           ((deInt32)(origin.x() + (p.x() * posA.x())),
3078                                                                                                  (deInt32)(origin.y() + (p.y() * posA.y())));
3079                                 const IVec2                     posBI           ((deInt32)(origin.x() + (p.x() * posB.x())),
3080                                                                                                  (deInt32)(origin.y() + (p.y() * posB.y())));
3081
3082                                 if (isColorFormat)
3083                                         checkColorRenderQuad(result, posAI, posBI, status);
3084                                 else
3085                                 {
3086                                         if (hasDepth)
3087                                                 checkDepthRenderQuad(result, posAI, posBI, status);
3088
3089                                         if (hasDepth && hasStencil)
3090                                                 checkStencilRenderQuad(*secondaryResult, posAI, posBI, status);
3091                                         else if (hasStencil)
3092                                                 checkStencilRenderQuad(result, posAI, posBI, status);
3093                                 }
3094                         }
3095
3096                         // Check color attachment clears
3097                         if (attachmentNdx && !renderInfo.getColorClears().empty())
3098                         {
3099                                 const ColorClear& clear = renderInfo.getColorClears()[*attachmentNdx];
3100
3101                                 checkColorClear(result, clear.getOffset(), clear.getSize(), status, clear.getColor());
3102                         }
3103
3104                         // Check depth/stencil attachment clears
3105                         if (subpass.getDepthStencilAttachment().getAttachment() == attachmentIndex && renderInfo.getDepthStencilClear())
3106                         {
3107                                 const DepthStencilClear clear = *renderInfo.getDepthStencilClear();
3108
3109                                 if (hasDepth)
3110                                         checkDepthClear(result, clear.getOffset(), clear.getSize(), status, clear.getDepth());
3111
3112                                 if (hasDepth && hasStencil)
3113                                         checkStencilClear(*secondaryResult, clear.getOffset(), clear.getSize(), status, clear.getStencil());
3114                                 else if (hasStencil)
3115                                         checkStencilClear(result, clear.getOffset(), clear.getSize(), status, clear.getStencil());
3116                         }
3117                 }
3118
3119                 // Check renderpas clear results
3120                 if (attachmentIsUsed && renderPassClearValue)
3121                 {
3122                         if (isColorFormat)
3123                         {
3124                                 if (renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3125                                         checkColorClear(result, renderPos, renderSize, status, renderPassClearValue->color);
3126                         }
3127                         else
3128                         {
3129                                 if (hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3130                                         checkDepthClear(result, renderPos, renderSize, status, renderPassClearValue->depthStencil.depth);
3131
3132                                 if (hasDepth && hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3133                                         checkStencilClear(*secondaryResult, renderPos, renderSize, status, renderPassClearValue->depthStencil.stencil);
3134                                 else if (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3135                                         checkStencilClear(result, renderPos, renderSize, status, renderPassClearValue->depthStencil.stencil);
3136                         }
3137                 }
3138         }
3139
3140         // Set all pixels that have undefined values fater renderpass to OK
3141         if (attachmentIsUsed && (((isColorFormat || hasDepth) && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3142                                                         || (hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)))
3143         {
3144                 for(int y = renderPos.y(); y < (int)(renderPos.y() + renderSize.y()); y++)
3145                 for(int x = renderPos.x(); x < (int)(renderPos.x() + renderSize.x()); x++)
3146                 {
3147                         PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3148
3149                         if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED
3150                                 && isColorFormat && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3151                                 pixelStatus.setColorStatus(PixelStatus::STATUS_OK);
3152                         else
3153                         {
3154                                 if (pixelStatus.getDepthStatus() == PixelStatus::STATUS_UNDEFINED
3155                                         && hasDepth && renderPassInfo.getAttachments()[attachmentIndex].getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3156                                         pixelStatus.setDepthStatus(PixelStatus::STATUS_OK);
3157
3158                                 if (pixelStatus.getStencilStatus() == PixelStatus::STATUS_UNDEFINED
3159                                         && hasStencil && renderPassInfo.getAttachments()[attachmentIndex].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3160                                         pixelStatus.setStencilStatus(PixelStatus::STATUS_OK);
3161                         }
3162                 }
3163         }
3164
3165         if (imageClearValue)
3166         {
3167                 if (isColorFormat)
3168                         checkColorClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->color);
3169                 else
3170                 {
3171                         if (hasDepth)
3172                                 checkDepthClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->depthStencil.depth);
3173
3174                         if (hasDepth && hasStencil)
3175                                 checkStencilClear(*secondaryResult, UVec2(0, 0), UVec2(secondaryResult->getWidth(), result.getHeight()), status, imageClearValue->depthStencil.stencil);
3176                         else if (hasStencil)
3177                                 checkStencilClear(result, UVec2(0, 0), UVec2(result.getWidth(), result.getHeight()), status, imageClearValue->depthStencil.stencil);
3178                 }
3179         }
3180
3181         {
3182                 bool isOk = true;
3183
3184                 for(int y = 0; y < result.getHeight(); y++)
3185                 for(int x = 0; x < result.getWidth(); x++)
3186                 {
3187                         const PixelStatus& pixelStatus = status[x + y * result.getWidth()];
3188
3189                         if (isColorFormat)
3190                         {
3191                                 if (pixelStatus.getColorStatus() != PixelStatus::STATUS_OK)
3192                                 {
3193                                         if (pixelStatus.getColorStatus() == PixelStatus::STATUS_UNDEFINED)
3194                                                 errorImage.setPixel(Vec4(1.0f, 1.0f, 0.0f, 1.0f), x, y);
3195                                         else if (pixelStatus.getColorStatus() == PixelStatus::STATUS_FAIL)
3196                                                 errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3197
3198                                         isOk = false;
3199                                 }
3200                         }
3201                         else
3202                         {
3203                                 if (hasDepth && pixelStatus.getDepthStatus() != PixelStatus::STATUS_OK)
3204                                 {
3205                                         errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3206                                         isOk = false;
3207                                 }
3208
3209                                 if (hasStencil && pixelStatus.getStencilStatus() != PixelStatus::STATUS_OK)
3210                                 {
3211                                         errorImage.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
3212                                         isOk = false;
3213                                 }
3214                         }
3215                 }
3216
3217                 return isOk;
3218         }
3219 }
3220
3221 bool logAndVerifyImages (TestLog&                                                                                       log,
3222                                                  const DeviceInterface&                                                         vk,
3223                                                  VkDevice                                                                                       device,
3224                                                  const vector<de::SharedPtr<AttachmentResources> >&     attachmentResources,
3225                                                  const vector<bool>&                                                            attachmentIsLazy,
3226                                                  const RenderPass&                                                                      renderPassInfo,
3227                                                  const vector<Maybe<VkClearValue> >&                            renderPassClearValues,
3228                                                  const vector<Maybe<VkClearValue> >&                            imageClearValues,
3229                                                  const vector<SubpassRenderInfo>&                                       subpassRenderInfo,
3230                                                  const UVec2&                                                                           targetSize,
3231                                                  const TestConfig&                                                                      config)
3232 {
3233         vector<tcu::TextureLevel>       referenceAttachments;
3234         bool                                            isOk                                    = true;
3235
3236         log << TestLog::Message << "Reference images fill undefined pixels with grid pattern." << TestLog::EndMessage;
3237
3238         renderReferenceImages(referenceAttachments, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
3239
3240         for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3241         {
3242                 if (!attachmentIsLazy[attachmentNdx])
3243                 {
3244                         const Attachment                        attachment              = renderPassInfo.getAttachments()[attachmentNdx];
3245                         const tcu::TextureFormat        format                  = mapVkFormat(attachment.getFormat());
3246
3247                         if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
3248                         {
3249                                 const tcu::TextureFormat        depthFormat             = getDepthCopyFormat(attachment.getFormat());
3250                                 const VkDeviceSize                      depthBufferSize = targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
3251                                 void* const                                     depthPtr                = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3252
3253                                 const tcu::TextureFormat        stencilFormat           = getStencilCopyFormat(attachment.getFormat());
3254                                 const VkDeviceSize                      stencilBufferSize       = targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
3255                                 void* const                                     stencilPtr                      = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
3256
3257                                 const VkMappedMemoryRange       ranges[] =
3258                                 {
3259                                         {
3260                                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,                                                          // sType;
3261                                                 DE_NULL,                                                                                                                        // pNext;
3262                                                 attachmentResources[attachmentNdx]->getResultMemory().getMemory(),      // mem;
3263                                                 attachmentResources[attachmentNdx]->getResultMemory().getOffset(),      // offset;
3264                                                 depthBufferSize                                                                                                         // size;
3265                                         },
3266                                         {
3267                                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,                                                                          // sType;
3268                                                 DE_NULL,                                                                                                                                        // pNext;
3269                                                 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(),     // mem;
3270                                                 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(),     // offset;
3271                                                 stencilBufferSize                                                                                                                       // size;
3272                                         }
3273                                 };
3274                                 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));
3275
3276                                 {
3277                                         const ConstPixelBufferAccess    depthAccess             (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
3278                                         const ConstPixelBufferAccess    stencilAccess   (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
3279                                         tcu::TextureLevel                               errorImage              (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3280
3281                                         log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
3282                                         log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);
3283
3284                                         log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3285
3286                                         if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3287                                                 && !verifyAttachment(depthAccess, tcu::just(stencilAccess), renderPassInfo, renderPassClearValues[attachmentNdx], imageClearValues[attachmentNdx], renderPassInfo.getSubpasses(), subpassRenderInfo, errorImage.getAccess(), (deUint32)attachmentNdx, config.renderPos, config.renderSize))
3288                                         {
3289                                                 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3290                                                 isOk = false;
3291                                         }
3292                                 }
3293                         }
3294                         else
3295                         {
3296                                 const VkDeviceSize                      bufferSize      = targetSize.x() * targetSize.y() * format.getPixelSize();
3297                                 void* const                                     ptr                     = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3298
3299                                 const VkMappedMemoryRange       range   =
3300                                 {
3301                                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,                                                          // sType;
3302                                         DE_NULL,                                                                                                                        // pNext;
3303                                         attachmentResources[attachmentNdx]->getResultMemory().getMemory(),      // mem;
3304                                         attachmentResources[attachmentNdx]->getResultMemory().getOffset(),      // offset;
3305                                         bufferSize                                                                                                                      // size;
3306                                 };
3307                                 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3308
3309                                 {
3310                                         const ConstPixelBufferAccess    access          (format, targetSize.x(), targetSize.y(), 1, ptr);
3311                                         tcu::TextureLevel                               errorImage      (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3312
3313                                         log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3314                                         log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3315
3316                                         if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3317                                                 && !verifyAttachment(access, tcu::nothing<ConstPixelBufferAccess>(), renderPassInfo, renderPassClearValues[attachmentNdx], imageClearValues[attachmentNdx], renderPassInfo.getSubpasses(), subpassRenderInfo, errorImage.getAccess(), (deUint32)attachmentNdx, config.renderPos, config.renderSize))
3318                                         {
3319                                                 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3320                                                 isOk = false;
3321                                         }
3322                                 }
3323                         }
3324                 }
3325         }
3326
3327         return isOk;
3328 }
3329
3330 std::string getAttachmentType (VkFormat vkFormat)
3331 {
3332         const tcu::TextureFormat                format                  = mapVkFormat(vkFormat);
3333         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
3334
3335         switch (channelClass)
3336         {
3337                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3338                         return "ivec4";
3339
3340                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3341                         return "uvec4";
3342
3343                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3344                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3345                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3346                         return "vec4";
3347
3348                 default:
3349                         DE_FATAL("Unknown channel class");
3350                         return "";
3351         }
3352 }
3353
3354 void createTestShaders (SourceCollections& dst, TestConfig config)
3355 {
3356         if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3357         {
3358                 const vector<Subpass>&  subpasses       = config.renderPass.getSubpasses();
3359
3360                 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3361                 {
3362                         const Subpass&          subpass         = subpasses[subpassNdx];
3363                         std::ostringstream      vertexShader;
3364                         std::ostringstream      fragmentShader;
3365
3366                         vertexShader << "#version 310 es\n"
3367                                                  << "layout(location = 0) in highp vec4 a_position;\n"
3368                                                  << "layout(location = 0) out highp vec2 v_color;\n"
3369                                                  << "void main (void) {\n"
3370                                                  << "\thighp float a = 0.5 + a_position.x;\n"
3371                                                  << "\thighp float b = 0.5 + a_position.y;\n"
3372                                                  << "\tv_color = vec2(a, b);\n"
3373                                                  << "\tgl_Position = a_position;\n"
3374                                                  << "}\n";
3375
3376                         fragmentShader << "#version 310 es\n"
3377                                                    << "layout(location = 0) in highp vec2 v_color;\n";
3378
3379                         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3380                         {
3381                                 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3382                                 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
3383                         }
3384
3385                         fragmentShader  << "void main (void) {\n"
3386                                                         << "\thighp vec4 scale = vec4(v_color.x, v_color.y, v_color.x * v_color.y, (v_color.x + v_color.y) / 2.0);\n";
3387
3388                         for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3389                         {
3390                                 const tcu::TextureFormat                format                  = mapVkFormat(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3391                                 const tcu::TextureFormatInfo    formatInfo              = tcu::getTextureFormatInfo(format);
3392                                 const float                                             clampMin                = (float)(-MAX_INTEGER_VALUE);
3393                                 const float                                             clampMax                = (float)(MAX_INTEGER_VALUE);
3394                                 const Vec4                                              valueMax                (de::clamp(formatInfo.valueMax[0], clampMin, clampMax),
3395                                                                                                                                  de::clamp(formatInfo.valueMax[1], clampMin, clampMax),
3396                                                                                                                                  de::clamp(formatInfo.valueMax[2], clampMin, clampMax),
3397                                                                                                                                  de::clamp(formatInfo.valueMax[3], clampMin, clampMax));
3398
3399                                 const Vec4                                              valueMin                (de::clamp(formatInfo.valueMin[0], clampMin, clampMax),
3400                                                                                                                                  de::clamp(formatInfo.valueMin[1], clampMin, clampMax),
3401                                                                                                                                  de::clamp(formatInfo.valueMin[2], clampMin, clampMax),
3402                                                                                                                                  de::clamp(formatInfo.valueMin[3], clampMin, clampMax));
3403                                 const std::string                               attachmentType  = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3404
3405                                 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4" << valueMin << " + vec4" << (valueMax - valueMin)  << " * scale);\n";
3406                         }
3407
3408                         fragmentShader << "}\n";
3409
3410                         dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
3411                         dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
3412                 }
3413         }
3414 }
3415
3416 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
3417 {
3418         bool lastAttachmentWasLazy = false;
3419
3420         for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3421         {
3422                 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3423                         && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
3424                         && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3425                         && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
3426                 {
3427                         if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
3428                         {
3429                                 attachmentIsLazy.push_back(true);
3430                                 lastAttachmentWasLazy = true;
3431                         }
3432                         else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
3433                         {
3434                                 attachmentIsLazy.push_back(false);
3435                                 lastAttachmentWasLazy = false;
3436                         }
3437                         else
3438                                 DE_FATAL("Unknown imageMemory");
3439                 }
3440                 else
3441                         attachmentIsLazy.push_back(false);
3442         }
3443 }
3444
3445 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
3446 {
3447         bool lastSubpassWasSecondary = false;
3448
3449         for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3450         {
3451                 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
3452                 {
3453                         subpassIsSecondary.push_back(true);
3454                         lastSubpassWasSecondary = true;
3455                 }
3456                 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
3457                 {
3458                         subpassIsSecondary.push_back(false);
3459                         lastSubpassWasSecondary = false;
3460                 }
3461                 else
3462                         DE_FATAL("Unknown commandBuffer");
3463         }
3464 }
3465
3466 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
3467 {
3468         for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3469         {
3470                 if (!isLazy[attachmentNdx])
3471                         clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3472                 else
3473                         clearValues.push_back(nothing<VkClearValue>());
3474         }
3475 }
3476
3477 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
3478 {
3479         for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3480         {
3481                 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
3482                         || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3483                 {
3484                         clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
3485                 }
3486                 else
3487                         clearValues.push_back(nothing<VkClearValue>());
3488         }
3489 }
3490
3491 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
3492 {
3493         clearValues.resize(renderPass.getSubpasses().size());
3494
3495         for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
3496         {
3497                 const Subpass&                                          subpass                         = renderPass.getSubpasses()[subpassNdx];
3498                 const vector<AttachmentReference>&      colorAttachments        = subpass.getColorAttachments();
3499
3500                 clearValues[subpassNdx].resize(colorAttachments.size());
3501
3502                 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
3503                 {
3504                         const AttachmentReference&      attachmentRef   = colorAttachments[attachmentRefNdx];
3505                         const Attachment&                       attachment              = renderPass.getAttachments()[attachmentRef.getAttachment()];
3506
3507                         clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
3508                 }
3509         }
3510 }
3511
3512 void logSubpassRenderInfo (TestLog&                                     log,
3513                                                    const SubpassRenderInfo&     info)
3514 {
3515         log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
3516
3517         if (info.isSecondary())
3518                 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
3519         else
3520                 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
3521
3522         for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
3523         {
3524                 const ColorClear&       colorClear      = info.getColorClears()[attachmentNdx];
3525
3526                 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
3527                         << ". Offset: " << colorClear.getOffset()
3528                         << ", Size: " << colorClear.getSize()
3529                         << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
3530         }
3531
3532         if (info.getDepthStencilClear())
3533         {
3534                 const DepthStencilClear&        depthStencilClear       = *info.getDepthStencilClear();
3535
3536                 log << TestLog::Message << "Clearing depth stencil attachment"
3537                         << ". Offset: " << depthStencilClear.getOffset()
3538                         << ", Size: " << depthStencilClear.getSize()
3539                         << ", Depth: " << depthStencilClear.getDepth()
3540                         << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
3541         }
3542
3543         if (info.getRenderQuad())
3544         {
3545                 const RenderQuad&       renderQuad      = *info.getRenderQuad();
3546
3547                 log << TestLog::Message << "Rendering gradient quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
3548         }
3549 }
3550
3551 void logTestCaseInfo (TestLog&                                                                  log,
3552                                           const TestConfig&                                                     config,
3553                                           const vector<bool>&                                           attachmentIsLazy,
3554                                           const vector<Maybe<VkClearValue> >&           imageClearValues,
3555                                           const vector<Maybe<VkClearValue> >&           renderPassClearValues,
3556                                           const vector<SubpassRenderInfo>&                      subpassRenderInfo)
3557 {
3558         const RenderPass&       renderPass      = config.renderPass;
3559
3560         logRenderPassInfo(log, renderPass);
3561
3562         DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
3563         DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
3564         DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
3565
3566         log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
3567         log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
3568
3569         for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
3570         {
3571                 const tcu::ScopedLogSection     section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
3572
3573                 if (attachmentIsLazy[attachmentNdx])
3574                         log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
3575
3576                 if (imageClearValues[attachmentNdx])
3577                         log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;
3578
3579                 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
3580                         log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
3581         }
3582
3583         for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
3584         {
3585                 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
3586
3587                 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
3588         }
3589 }
3590
3591 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
3592 {
3593         const TestConfig::CommandBufferTypes    commandBuffer                   = config.commandBufferTypes;
3594         const vector<Subpass>&                                  subpasses                               = renderPass.getSubpasses();
3595         bool                                                                    lastSubpassWasSecondary = false;
3596
3597         for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
3598         {
3599                 const Subpass&                          subpass                         = subpasses[subpassNdx];
3600                 const bool                                      subpassIsSecondary      = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
3601                                                                                                                 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
3602                 const UVec2                                     viewportSize            ((config.renderSize * UVec2(2)) / UVec2(3));
3603                 const UVec2                                     viewportOffset          (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
3604                                                                                                                  config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
3605
3606                 vector<ColorClear>                      colorClears;
3607                 Maybe<DepthStencilClear>        depthStencilClear;
3608                 Maybe<RenderQuad>                       renderQuad;
3609
3610                 lastSubpassWasSecondary         = subpassIsSecondary;
3611
3612                 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
3613                 {
3614                         const vector<AttachmentReference>&      colorAttachments        = subpass.getColorAttachments();
3615
3616                         for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
3617                         {
3618                                 const AttachmentReference&      attachmentRef   = colorAttachments[attachmentRefNdx];
3619                                 const Attachment&                       attachment              = renderPass.getAttachments()[attachmentRef.getAttachment()];
3620                                 const UVec2                                     size                    ((viewportSize * UVec2(2)) / UVec2(3));
3621                                 const UVec2                                     offset                  (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
3622                                                                                                                          viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
3623                                 const VkClearColorValue         color                   = randomColorClearValue(attachment, rng);
3624
3625                                 colorClears.push_back(ColorClear(offset, size, color));
3626                         }
3627
3628                         if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3629                         {
3630                                 const Attachment&       attachment              = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
3631                                 const UVec2                     size                    ((viewportSize * UVec2(2)) / UVec2(3));
3632                                 const UVec2                     offset                  (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
3633                                                                                                          viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
3634                                 const VkClearValue      value                   = randomClearValue(attachment, rng);
3635
3636                                 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
3637                         }
3638                 }
3639
3640                 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3641                         renderQuad = tcu::just(RenderQuad(tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f), tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f)));
3642
3643                 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
3644         }
3645 }
3646
3647 void checkTextureFormatSupport (TestLog&                                        log,
3648                                                                 const InstanceInterface&        vk,
3649                                                                 VkPhysicalDevice                        device,
3650                                                                 const vector<Attachment>&       attachments)
3651 {
3652         bool supported = true;
3653
3654         for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3655         {
3656                 const Attachment&                       attachment                                      = attachments[attachmentNdx];
3657                 const tcu::TextureFormat        format                                          = mapVkFormat(attachment.getFormat());
3658                 const bool                                      isDepthOrStencilAttachment      = hasDepthComponent(format.order) || hasStencilComponent(format.order);
3659                 const VkFormatFeatureFlags      flags                                           = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
3660                 VkFormatProperties                      properties;
3661
3662                 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
3663
3664                 if ((properties.optimalTilingFeatures & flags) != flags)
3665                 {
3666                         supported = false;
3667                         log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
3668                 }
3669         }
3670
3671         if (!supported)
3672                 TCU_THROW(NotSupportedError, "Format not supported");
3673 }
3674
3675 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
3676 {
3677         const UVec2                                                     targetSize                      = config.targetSize;
3678         const UVec2                                                     renderPos                       = config.renderPos;
3679         const UVec2                                                     renderSize                      = config.renderSize;
3680         const RenderPass&                                       renderPassInfo          = config.renderPass;
3681
3682         TestLog&                                                        log                                     = context.getTestContext().getLog();
3683         de::Random                                                      rng                                     (config.seed);
3684
3685         vector<bool>                                            attachmentIsLazy;
3686         vector<Maybe<VkClearValue> >            imageClearValues;
3687         vector<Maybe<VkClearValue> >            renderPassClearValues;
3688
3689         vector<bool>                                            subpassIsSecondary;
3690         vector<SubpassRenderInfo>                       subpassRenderInfo;
3691         vector<vector<VkClearColorValue> >      subpassColorClearValues;
3692
3693         initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
3694         initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
3695         initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
3696
3697         initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
3698         initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
3699         initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
3700
3701         logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
3702
3703         checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
3704
3705         {
3706                 const VkDevice                                                          device                                                          = context.getDevice();
3707                 const DeviceInterface&                                          vk                                                                      = context.getDeviceInterface();
3708                 const VkQueue                                                           queue                                                           = context.getUniversalQueue();
3709                 const deUint32                                                          queueIndex                                                      = context.getUniversalQueueFamilyIndex();
3710                 Allocator&                                                                      allocator                                                       = context.getDefaultAllocator();
3711
3712                 const Unique<VkRenderPass>                                      renderPass                                                      (createRenderPass(vk, device, renderPassInfo));
3713                 const Unique<VkCommandPool>                                     commandBufferPool                                       (createCommandPool(vk, device, queueIndex, 0));
3714                 const Unique<VkCommandBuffer>                           initializeImagesCommandBuffer           (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3715                 const Unique<VkCommandBuffer>                           renderCommandBuffer                                     (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3716                 const Unique<VkCommandBuffer>                           readImagesToBuffersCommandBuffer        (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3717
3718                 vector<de::SharedPtr<AttachmentResources> >     attachmentResources;
3719                 vector<de::SharedPtr<SubpassRenderer> >         subpassRenderers;
3720                 vector<VkImageView>                                                     attachmentViews;
3721
3722                 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3723                 {
3724                         const Attachment&       attachmentInfo  = renderPassInfo.getAttachments()[attachmentNdx];
3725
3726                         attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentIsLazy[attachmentNdx])));
3727                         attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
3728                 }
3729
3730                 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3731                 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
3732                 endCommandBuffer(vk, *initializeImagesCommandBuffer);
3733
3734                 {
3735                         const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
3736
3737                         for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
3738                                 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, subpassRenderInfo[subpassNdx])));
3739
3740                         beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3741                         pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
3742                         endCommandBuffer(vk, *renderCommandBuffer);
3743
3744                         beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
3745                         pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
3746                         endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
3747                         {
3748                                 const VkCommandBuffer commandBuffers[] =
3749                                 {
3750                                         *initializeImagesCommandBuffer,
3751                                         *renderCommandBuffer,
3752                                         *readImagesToBuffersCommandBuffer
3753                                 };
3754                                 const Unique<VkFence>   fence           (createFence(vk, device, 0u));
3755
3756                                 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
3757                                 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
3758                         }
3759                 }
3760
3761                 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
3762                         return tcu::TestStatus::pass("Pass");
3763                 else
3764                         return tcu::TestStatus::fail("Result verification failed");
3765         }
3766 }
3767
3768 static const VkFormat s_coreColorFormats[] =
3769 {
3770         VK_FORMAT_R5G6B5_UNORM_PACK16,
3771         VK_FORMAT_R8_UNORM,
3772         VK_FORMAT_R8_SNORM,
3773         VK_FORMAT_R8_UINT,
3774         VK_FORMAT_R8_SINT,
3775         VK_FORMAT_R8G8_UNORM,
3776         VK_FORMAT_R8G8_SNORM,
3777         VK_FORMAT_R8G8_UINT,
3778         VK_FORMAT_R8G8_SINT,
3779         VK_FORMAT_R8G8B8A8_UNORM,
3780         VK_FORMAT_R8G8B8A8_SNORM,
3781         VK_FORMAT_R8G8B8A8_UINT,
3782         VK_FORMAT_R8G8B8A8_SINT,
3783         VK_FORMAT_R8G8B8A8_SRGB,
3784         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3785         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3786         VK_FORMAT_A8B8G8R8_UINT_PACK32,
3787         VK_FORMAT_A8B8G8R8_SINT_PACK32,
3788         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3789         VK_FORMAT_B8G8R8A8_UNORM,
3790         VK_FORMAT_B8G8R8A8_SRGB,
3791         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3792         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3793         VK_FORMAT_A2B10G10R10_UINT_PACK32,
3794         VK_FORMAT_R16_UNORM,
3795         VK_FORMAT_R16_SNORM,
3796         VK_FORMAT_R16_UINT,
3797         VK_FORMAT_R16_SINT,
3798         VK_FORMAT_R16_SFLOAT,
3799         VK_FORMAT_R16G16_UNORM,
3800         VK_FORMAT_R16G16_SNORM,
3801         VK_FORMAT_R16G16_UINT,
3802         VK_FORMAT_R16G16_SINT,
3803         VK_FORMAT_R16G16_SFLOAT,
3804         VK_FORMAT_R16G16B16A16_UNORM,
3805         VK_FORMAT_R16G16B16A16_SNORM,
3806         VK_FORMAT_R16G16B16A16_UINT,
3807         VK_FORMAT_R16G16B16A16_SINT,
3808         VK_FORMAT_R16G16B16A16_SFLOAT,
3809         VK_FORMAT_R32_UINT,
3810         VK_FORMAT_R32_SINT,
3811         VK_FORMAT_R32_SFLOAT,
3812         VK_FORMAT_R32G32_UINT,
3813         VK_FORMAT_R32G32_SINT,
3814         VK_FORMAT_R32G32_SFLOAT,
3815         VK_FORMAT_R32G32B32A32_UINT,
3816         VK_FORMAT_R32G32B32A32_SINT,
3817         VK_FORMAT_R32G32B32A32_SFLOAT
3818 };
3819
3820 static const VkFormat s_coreDepthStencilFormats[] =
3821 {
3822         VK_FORMAT_D16_UNORM,
3823
3824         VK_FORMAT_X8_D24_UNORM_PACK32,
3825         VK_FORMAT_D32_SFLOAT,
3826
3827         VK_FORMAT_D24_UNORM_S8_UINT,
3828         VK_FORMAT_D32_SFLOAT_S8_UINT
3829 };
3830
3831 de::MovePtr<tcu::TestCaseGroup> createAttachmentTestCaseGroup (tcu::TestContext& testCtx)
3832 {
3833         const deUint32 attachmentCounts[] = { 1, 3, 8 };
3834         const VkAttachmentLoadOp loadOps[] =
3835         {
3836                 VK_ATTACHMENT_LOAD_OP_LOAD,
3837                 VK_ATTACHMENT_LOAD_OP_CLEAR,
3838                 VK_ATTACHMENT_LOAD_OP_DONT_CARE
3839         };
3840
3841         const VkAttachmentStoreOp storeOps[] =
3842         {
3843                 VK_ATTACHMENT_STORE_OP_STORE,
3844                 VK_ATTACHMENT_STORE_OP_DONT_CARE
3845         };
3846
3847         const VkImageLayout initialAndFinalColorLayouts[] =
3848         {
3849                 VK_IMAGE_LAYOUT_GENERAL,
3850                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3851                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3852                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3853                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
3854         };
3855
3856         const VkImageLayout initialAndFinalDepthStencilLayouts[] =
3857         {
3858                 VK_IMAGE_LAYOUT_GENERAL,
3859                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3860                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
3861                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3862                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3863                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
3864         };
3865
3866         const VkImageLayout subpassLayouts[] =
3867         {
3868                 VK_IMAGE_LAYOUT_GENERAL,
3869                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
3870         };
3871
3872         const VkImageLayout depthStencilLayouts[] =
3873         {
3874                 VK_IMAGE_LAYOUT_GENERAL,
3875                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
3876         };
3877
3878         const TestConfig::RenderTypes renderCommands[] =
3879         {
3880                 TestConfig::RENDERTYPES_NONE,
3881                 TestConfig::RENDERTYPES_CLEAR,
3882                 TestConfig::RENDERTYPES_DRAW,
3883                 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
3884         };
3885
3886         const TestConfig::CommandBufferTypes commandBuffers[] =
3887         {
3888                 TestConfig::COMMANDBUFFERTYPES_INLINE,
3889                 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
3890                 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
3891         };
3892
3893         const TestConfig::ImageMemory imageMemories[] =
3894         {
3895                 TestConfig::IMAGEMEMORY_STRICT,
3896                 TestConfig::IMAGEMEMORY_LAZY,
3897                 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
3898         };
3899
3900         const UVec2 targetSizes[] =
3901         {
3902                 UVec2(64, 64),
3903                 UVec2(63, 65)
3904         };
3905
3906         const UVec2 renderPositions[] =
3907         {
3908                 UVec2(0, 0),
3909                 UVec2(3, 17)
3910         };
3911
3912         const UVec2 renderSizes[] =
3913         {
3914                 UVec2(32, 32),
3915                 UVec2(60, 47)
3916         };
3917
3918         de::Random rng (1433774382u);
3919         de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "attachment", "Attachment format and count tests with load and store ops and image layouts"));
3920
3921         for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
3922         {
3923                 const deUint32                                  attachmentCount                 = attachmentCounts[attachmentCountNdx];
3924                 const deUint32                                  testCaseCount                   = (attachmentCount == 1 ? 100 : 200);
3925                 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup    (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
3926
3927                 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
3928                 {
3929                         const bool                                      useDepthStencil         = rng.getBool();
3930                         VkImageLayout                           depthStencilLayout      = VK_IMAGE_LAYOUT_GENERAL;
3931                         vector<Attachment>                      attachments;
3932                         vector<AttachmentReference>     colorAttachmentReferences;
3933
3934                         for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
3935                         {
3936                                 const VkSampleCountFlagBits     sampleCount             = VK_SAMPLE_COUNT_1_BIT;
3937                                 const VkFormat                          format                  = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
3938                                 const VkAttachmentLoadOp        loadOp                  = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3939                                 const VkAttachmentStoreOp       storeOp                 = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3940
3941                                 const VkImageLayout                     initialLayout   = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
3942                                 const VkImageLayout                     finalizeLayout  = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
3943                                 const VkImageLayout                     subpassLayout   = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
3944
3945                                 const VkAttachmentLoadOp        stencilLoadOp   = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3946                                 const VkAttachmentStoreOp       stencilStoreOp  = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3947
3948                                 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
3949                                 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
3950                         }
3951
3952                         if (useDepthStencil)
3953                         {
3954                                 const VkSampleCountFlagBits     sampleCount                     = VK_SAMPLE_COUNT_1_BIT;
3955                                 const VkFormat                          format                          = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
3956                                 const VkAttachmentLoadOp        loadOp                          = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3957                                 const VkAttachmentStoreOp       storeOp                         = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3958
3959                                 const VkImageLayout                     initialLayout           = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
3960                                 const VkImageLayout                     finalizeLayout          = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
3961
3962                                 const VkAttachmentLoadOp        stencilLoadOp           = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
3963                                 const VkAttachmentStoreOp       stencilStoreOp          = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
3964
3965                                 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
3966                                 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
3967                         }
3968
3969                         {
3970                                 const TestConfig::RenderTypes                   render                  = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
3971                                 const TestConfig::CommandBufferTypes    commandBuffer   = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
3972                                 const TestConfig::ImageMemory                   imageMemory             = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
3973                                 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<AttachmentReference>()));
3974                                 const vector<SubpassDependency>                 deps;
3975
3976                                 const string                                                    testCaseName    = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
3977                                 const RenderPass                                                renderPass              (attachments, subpasses, deps);
3978                                 const UVec2                                                             targetSize              = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
3979                                 const UVec2                                                             renderPos               = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
3980                                 const UVec2                                                             renderSize              = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
3981
3982                                 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809));
3983                         }
3984                 }
3985
3986                 group->addChild(attachmentCountGroup.release());
3987         }
3988
3989         return group;
3990 }
3991
3992 de::MovePtr<tcu::TestCaseGroup> createAttachmentAllocationTestGroup (tcu::TestContext& testCtx)
3993 {
3994         const deUint32 attachmentCounts[] = { 4, 8 };
3995         const VkAttachmentLoadOp loadOps[] =
3996         {
3997                 VK_ATTACHMENT_LOAD_OP_LOAD,
3998                 VK_ATTACHMENT_LOAD_OP_CLEAR,
3999                 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4000         };
4001
4002         const VkAttachmentStoreOp storeOps[] =
4003         {
4004                 VK_ATTACHMENT_STORE_OP_STORE,
4005                 VK_ATTACHMENT_STORE_OP_DONT_CARE
4006         };
4007
4008         const VkImageLayout initialAndFinalColorLayouts[] =
4009         {
4010                 VK_IMAGE_LAYOUT_GENERAL,
4011                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4012                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4013                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4014                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4015         };
4016
4017         const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4018         {
4019                 VK_IMAGE_LAYOUT_GENERAL,
4020                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4021                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4022                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4023                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4024                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4025         };
4026
4027         const VkImageLayout subpassLayouts[] =
4028         {
4029                 VK_IMAGE_LAYOUT_GENERAL,
4030                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4031         };
4032
4033         enum AllocationType
4034         {
4035                 // Each pass uses one more attachmen than previous one
4036                 ALLOCATIONTYPE_GROW,
4037                 // Each pass uses one less attachment than previous one
4038                 ALLOCATIONTYPE_SHRINK,
4039                 // Each pass drops one attachment and picks up new one
4040                 ALLOCATIONTYPE_ROLL,
4041                 // Start by growing and end by shrinking
4042                 ALLOCATIONTYPE_GROW_SHRINK
4043         };
4044
4045         const AllocationType allocationTypes[] =
4046         {
4047                 ALLOCATIONTYPE_GROW,
4048                 ALLOCATIONTYPE_SHRINK,
4049                 ALLOCATIONTYPE_ROLL,
4050                 ALLOCATIONTYPE_GROW_SHRINK
4051         };
4052
4053         const char* const allocationTypeStr[] =
4054         {
4055                 "grow",
4056                 "shrink",
4057                 "roll",
4058                 "grow_shrink"
4059         };
4060
4061         const TestConfig::RenderTypes renderCommands[] =
4062         {
4063                 TestConfig::RENDERTYPES_NONE,
4064                 TestConfig::RENDERTYPES_CLEAR,
4065                 TestConfig::RENDERTYPES_DRAW,
4066                 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4067         };
4068
4069         const TestConfig::CommandBufferTypes commandBuffers[] =
4070         {
4071                 TestConfig::COMMANDBUFFERTYPES_INLINE,
4072                 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4073                 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4074         };
4075
4076         const TestConfig::ImageMemory imageMemories[] =
4077         {
4078                 TestConfig::IMAGEMEMORY_STRICT,
4079                 TestConfig::IMAGEMEMORY_LAZY,
4080                 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4081         };
4082
4083         const UVec2 targetSizes[] =
4084         {
4085                 UVec2(64, 64),
4086                 UVec2(63, 65)
4087         };
4088
4089         const UVec2 renderPositions[] =
4090         {
4091                 UVec2(0, 0),
4092                 UVec2(3, 17)
4093         };
4094
4095         const UVec2 renderSizes[] =
4096         {
4097                 UVec2(32, 32),
4098                 UVec2(60, 47)
4099         };
4100
4101         de::MovePtr<tcu::TestCaseGroup> group   (new tcu::TestCaseGroup(testCtx, "attachment_allocation", "Attachment allocation tests"));
4102         de::Random                                              rng             (3700649827u);
4103
4104         for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
4105         {
4106                 const AllocationType                    allocationType          = allocationTypes[allocationTypeNdx];
4107                 const size_t                                    testCaseCount           = 100;
4108                 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup     (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
4109
4110                 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4111                 {
4112                         const deUint32          attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
4113                         vector<Attachment>      attachments;
4114                         vector<Subpass>         subpasses;
4115
4116                         for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4117                         {
4118                                 const VkSampleCountFlagBits     sampleCount             = VK_SAMPLE_COUNT_1_BIT;
4119                                 const VkFormat                          format                  = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4120                                 const VkAttachmentLoadOp        loadOp                  = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4121                                 const VkAttachmentStoreOp       storeOp                 = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4122
4123                                 const VkImageLayout                     initialLayout   = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4124                                 const VkImageLayout                     finalizeLayout  = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4125
4126                                 const VkAttachmentLoadOp        stencilLoadOp   = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4127                                 const VkAttachmentStoreOp       stencilStoreOp  = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4128
4129                                 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4130                         }
4131
4132                         if (allocationType == ALLOCATIONTYPE_GROW)
4133                         {
4134                                 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4135                                 {
4136                                         vector<AttachmentReference>     colorAttachmentReferences;
4137
4138                                         for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4139                                         {
4140                                                 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4141
4142                                                 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4143                                         }
4144
4145                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4146                                 }
4147                         }
4148                         else if (allocationType == ALLOCATIONTYPE_SHRINK)
4149                         {
4150                                 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4151                                 {
4152                                         vector<AttachmentReference>     colorAttachmentReferences;
4153
4154                                         for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4155                                         {
4156                                                 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4157
4158                                                 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4159                                         }
4160
4161                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4162                                 }
4163                         }
4164                         else if (allocationType == ALLOCATIONTYPE_ROLL)
4165                         {
4166                                 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
4167                                 {
4168                                         vector<AttachmentReference>     colorAttachmentReferences;
4169
4170                                         for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
4171                                         {
4172                                                 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4173
4174                                                 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
4175                                         }
4176
4177                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4178                                 }
4179                         }
4180                         else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
4181                         {
4182                                 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4183                                 {
4184                                         vector<AttachmentReference>     colorAttachmentReferences;
4185
4186                                         for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
4187                                         {
4188                                                 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4189
4190                                                 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4191                                         }
4192
4193                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4194                                 }
4195
4196                                 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
4197                                 {
4198                                         vector<AttachmentReference>     colorAttachmentReferences;
4199
4200                                         for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
4201                                         {
4202                                                 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4203
4204                                                 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4205                                         }
4206
4207                                         subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<AttachmentReference>()));
4208                                 }
4209                         }
4210                         else
4211                                 DE_FATAL("Unknown allocation type");
4212
4213                         {
4214                                 const TestConfig::RenderTypes                   render                  = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4215                                 const TestConfig::CommandBufferTypes    commandBuffer   = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4216                                 const TestConfig::ImageMemory                   imageMemory             = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4217
4218                                 const string                                                    testCaseName    = de::toString(testCaseNdx);
4219                                 const UVec2                                                             targetSize              = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4220                                 const UVec2                                                             renderPos               = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4221                                 const UVec2                                                             renderSize              = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4222
4223                                 vector<SubpassDependency>                               deps;
4224
4225                                 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
4226                                 {
4227                                         const bool byRegion                             = rng.getBool();
4228                                         deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
4229                                                                                                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4230                                                                                                                 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4231                                                                                                                 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4232                                                                                                                 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4233
4234                                                                                                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4235                                                                                                                 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4236                                                                                                                 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4237                                                                                                                 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4238
4239                                                                                                          VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4240                                                                                                          VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, // \todo [pyry] Correct?
4241
4242                                                                                                          byRegion ? (VkBool32)VK_TRUE : (VkBool32)VK_FALSE));
4243                                 }
4244
4245                                 const RenderPass                                        renderPass              (attachments, subpasses, deps);
4246
4247                                 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329));
4248                         }
4249                 }
4250
4251                 group->addChild(allocationTypeGroup.release());
4252         }
4253
4254         return group;
4255 }
4256
4257 de::MovePtr<tcu::TestCaseGroup> createSimpleTestGroup (tcu::TestContext& testCtx)
4258 {
4259         const UVec2                                             targetSize      (64, 64);
4260         const UVec2                                             renderPos       (0, 0);
4261         const UVec2                                             renderSize      (64, 64);
4262         de::MovePtr<tcu::TestCaseGroup> group           (new tcu::TestCaseGroup(testCtx, "simple", "Simple basic render pass tests"));
4263
4264         // color
4265         {
4266                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4267                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
4268                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
4269                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
4270                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4271                                                                                                                                                   VK_ATTACHMENT_STORE_OP_DONT_CARE,
4272                                                                                                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4273                                                                                                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4274                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4275                                                                                                                                         0u,
4276                                                                                                                                         vector<AttachmentReference>(),
4277                                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4278                                                                                                                                         vector<AttachmentReference>(),
4279                                                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4280                                                                                                                                         vector<AttachmentReference>())),
4281                                                                                  vector<SubpassDependency>());
4282
4283                 addFunctionCaseWithPrograms<TestConfig>(group.get(), "color", "Single color attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4284         }
4285
4286         // depth
4287         {
4288                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
4289                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
4290                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
4291                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
4292                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4293                                                                                                                                                   VK_ATTACHMENT_STORE_OP_DONT_CARE,
4294                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4295                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4296                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4297                                                                                                                                         0u,
4298                                                                                                                                         vector<AttachmentReference>(),
4299                                                                                                                                         vector<AttachmentReference>(),
4300                                                                                                                                         vector<AttachmentReference>(),
4301                                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4302                                                                                                                                         vector<AttachmentReference>())),
4303                                                                                  vector<SubpassDependency>());
4304
4305                 addFunctionCaseWithPrograms<TestConfig>(group.get(), "depth", "Single depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4306         }
4307
4308         // stencil
4309         {
4310                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
4311                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
4312                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4313                                                                                                                                                   VK_ATTACHMENT_STORE_OP_DONT_CARE,
4314                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
4315                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
4316                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4317                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4318                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4319                                                                                                                                         0u,
4320                                                                                                                                         vector<AttachmentReference>(),
4321                                                                                                                                         vector<AttachmentReference>(),
4322                                                                                                                                         vector<AttachmentReference>(),
4323                                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4324                                                                                                                                         vector<AttachmentReference>())),
4325                                                                                  vector<SubpassDependency>());
4326
4327                 addFunctionCaseWithPrograms<TestConfig>(group.get(), "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4328         }
4329
4330         // depth_stencil
4331         {
4332                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
4333                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
4334                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
4335                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
4336                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_CLEAR,
4337                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
4338                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4339                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4340                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4341                                                                                                                                         0u,
4342                                                                                                                                         vector<AttachmentReference>(),
4343                                                                                                                                         vector<AttachmentReference>(),
4344                                                                                                                                         vector<AttachmentReference>(),
4345                                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4346                                                                                                                                         vector<AttachmentReference>())),
4347                                                                                  vector<SubpassDependency>());
4348
4349                 addFunctionCaseWithPrograms<TestConfig>(group.get(), "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4350         }
4351
4352         // color_depth
4353         {
4354                 const Attachment        attachments[] =
4355                 {
4356                         Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4357                                            VK_SAMPLE_COUNT_1_BIT,
4358                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
4359                                            VK_ATTACHMENT_STORE_OP_STORE,
4360                                            VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4361                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
4362                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4363                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4364                         Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
4365                                            VK_SAMPLE_COUNT_1_BIT,
4366                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
4367                                            VK_ATTACHMENT_STORE_OP_STORE,
4368                                            VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4369                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
4370                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4371                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4372                 };
4373
4374                 const RenderPass        renderPass      (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4375                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4376                                                                                                                                         0u,
4377                                                                                                                                         vector<AttachmentReference>(),
4378                                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4379                                                                                                                                         vector<AttachmentReference>(),
4380                                                                                                                                         AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4381                                                                                                                                         vector<AttachmentReference>())),
4382                                                                                  vector<SubpassDependency>());
4383
4384                 addFunctionCaseWithPrograms<TestConfig>(group.get(), "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4385         }
4386
4387         // color_stencil
4388         {
4389                 const Attachment        attachments[] =
4390                 {
4391                         Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4392                                            VK_SAMPLE_COUNT_1_BIT,
4393                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
4394                                            VK_ATTACHMENT_STORE_OP_STORE,
4395                                            VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4396                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
4397                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4398                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4399                         Attachment(VK_FORMAT_S8_UINT,
4400                                            VK_SAMPLE_COUNT_1_BIT,
4401                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
4402                                            VK_ATTACHMENT_STORE_OP_STORE,
4403                                            VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4404                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
4405                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4406                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4407                 };
4408
4409                 const RenderPass        renderPass      (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4410                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4411                                                                                                                                         0u,
4412                                                                                                                                         vector<AttachmentReference>(),
4413                                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4414                                                                                                                                         vector<AttachmentReference>(),
4415                                                                                                                                         AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4416                                                                                                                                         vector<AttachmentReference>())),
4417                                                                                  vector<SubpassDependency>());
4418
4419
4420                 addFunctionCaseWithPrograms<TestConfig>(group.get(), "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
4421         }
4422
4423         // color_depth_stencil
4424         {
4425                 const Attachment        attachments[] =
4426                 {
4427                         Attachment(VK_FORMAT_R8G8B8A8_UNORM,
4428                                            VK_SAMPLE_COUNT_1_BIT,
4429                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
4430                                            VK_ATTACHMENT_STORE_OP_STORE,
4431                                            VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4432                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
4433                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4434                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
4435                         Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
4436                                            VK_SAMPLE_COUNT_1_BIT,
4437                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
4438                                            VK_ATTACHMENT_STORE_OP_STORE,
4439                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
4440                                            VK_ATTACHMENT_STORE_OP_STORE,
4441                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4442                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4443                 };
4444
4445                 const RenderPass        renderPass      (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
4446                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4447                                                                                                                                         0u,
4448                                                                                                                                         vector<AttachmentReference>(),
4449                                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4450                                                                                                                                         vector<AttachmentReference>(),
4451                                                                                                                                         AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4452                                                                                                                                         vector<AttachmentReference>())),
4453                                                                                  vector<SubpassDependency>());
4454
4455                 addFunctionCaseWithPrograms<TestConfig>(group.get(), "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));
4456         }
4457
4458         return group;
4459 }
4460
4461 std::string formatToName (VkFormat format)
4462 {
4463         const std::string       formatStr       = de::toString(format);
4464         const std::string       prefix          = "VK_FORMAT_";
4465
4466         DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
4467
4468         return de::toLower(formatStr.substr(prefix.length()));
4469 }
4470
4471 de::MovePtr<tcu::TestCaseGroup> createFormatTestGroup(tcu::TestContext& testCtx)
4472 {
4473         de::MovePtr<tcu::TestCaseGroup> group   (new tcu::TestCaseGroup(testCtx, "formats", "Tests for different image formats."));
4474
4475         const UVec2 targetSize  (64, 64);
4476         const UVec2 renderPos   (0, 0);
4477         const UVec2 renderSize  (64, 64);
4478
4479         const struct
4480         {
4481                 const char* const                       str;
4482                 const VkAttachmentLoadOp        op;
4483         } loadOps[] =
4484         {
4485                 { "clear",              VK_ATTACHMENT_LOAD_OP_CLEAR             },
4486                 { "load",               VK_ATTACHMENT_LOAD_OP_LOAD              },
4487                 { "dont_care",  VK_ATTACHMENT_LOAD_OP_DONT_CARE }
4488         };
4489
4490         const struct
4491         {
4492                  const char* const                              str;
4493                  const TestConfig::RenderTypes  types;
4494         } renderTypes[] =
4495         {
4496                 { "clear",              TestConfig::RENDERTYPES_CLEAR                                                           },
4497                 { "draw",               TestConfig::RENDERTYPES_DRAW                                                            },
4498                 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW      }
4499         };
4500
4501         // Color formats
4502         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
4503         {
4504                 const VkFormat                                  format          = s_coreColorFormats[formatNdx];
4505                 de::MovePtr<tcu::TestCaseGroup> formatGroup     (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
4506
4507                 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
4508                 {
4509                         const VkAttachmentLoadOp                loadOp  = loadOps[loadOpNdx].op;
4510                         de::MovePtr<tcu::TestCaseGroup> loadOpGroup     (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
4511
4512                         for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
4513                         {
4514                                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(format,
4515                                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
4516                                                                                                                                                                   loadOp,
4517                                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
4518                                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4519                                                                                                                                                                   VK_ATTACHMENT_STORE_OP_DONT_CARE,
4520                                                                                                                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4521                                                                                                                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4522                                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4523                                                                                                                                                         0u,
4524                                                                                                                                                         vector<AttachmentReference>(),
4525                                                                                                                                                         vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
4526                                                                                                                                                         vector<AttachmentReference>(),
4527                                                                                                                                                         AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
4528                                                                                                                                                         vector<AttachmentReference>())),
4529                                                                                                  vector<SubpassDependency>());
4530
4531                                 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));
4532                         }
4533
4534                         formatGroup->addChild(loadOpGroup.release());
4535                 }
4536
4537                 group->addChild(formatGroup.release());
4538         }
4539
4540         // Depth stencil formats
4541         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
4542         {
4543                 const VkFormat                                  format          = s_coreDepthStencilFormats[formatNdx];
4544                 de::MovePtr<tcu::TestCaseGroup> formatGroup     (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
4545
4546                 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
4547                 {
4548                         const VkAttachmentLoadOp                loadOp  = loadOps[loadOpNdx].op;
4549                         de::MovePtr<tcu::TestCaseGroup> loadOpGroup     (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
4550
4551                         for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
4552                         {
4553                                 const RenderPass        renderPass      (vector<Attachment>(1, Attachment(format,
4554                                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT,
4555                                                                                                                                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
4556                                                                                                                                                                   VK_ATTACHMENT_STORE_OP_DONT_CARE,
4557                                                                                                                                                                   loadOp,
4558                                                                                                                                                                   VK_ATTACHMENT_STORE_OP_STORE,
4559                                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4560                                                                                                                                                                   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
4561                                                                                                  vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
4562                                                                                                                                                         0u,
4563                                                                                                                                                         vector<AttachmentReference>(),
4564                                                                                                                                                         vector<AttachmentReference>(),
4565                                                                                                                                                         vector<AttachmentReference>(),
4566                                                                                                                                                         AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4567                                                                                                                                                         vector<AttachmentReference>())),
4568                                                                                                  vector<SubpassDependency>());
4569
4570                                 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));
4571                         }
4572
4573                         formatGroup->addChild(loadOpGroup.release());
4574                 }
4575
4576                 group->addChild(formatGroup.release());
4577         }
4578
4579         return group;
4580 }
4581
4582 } // anonymous
4583
4584 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
4585 {
4586         de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
4587
4588         renderpassTests->addChild(createSimpleTestGroup(testCtx).release());
4589         renderpassTests->addChild(createFormatTestGroup(testCtx).release());
4590         renderpassTests->addChild(createAttachmentTestCaseGroup(testCtx).release());
4591         renderpassTests->addChild(createAttachmentAllocationTestGroup(testCtx).release());
4592
4593         return renderpassTests.release();
4594 }
4595
4596 } // vkt