Rename various things for more inclusive language
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / multiview / vktMultiViewRenderTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vulkan Multi View Render Tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktMultiViewRenderTests.hpp"
25 #include "vktMultiViewRenderUtil.hpp"
26 #include "vktMultiViewRenderPassUtil.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28
29 #include "vktTestCase.hpp"
30 #include "vkBuilderUtil.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkPlatform.hpp"
36 #include "vkMemUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkObjUtil.hpp"
40
41 #include "tcuTestLog.hpp"
42 #include "tcuResource.hpp"
43 #include "tcuImageCompare.hpp"
44 #include "tcuCommandLine.hpp"
45 #include "tcuTextureUtil.hpp"
46 #include "tcuRGBA.hpp"
47
48 #include "deRandom.hpp"
49 #include "deMath.h"
50 #include "deSharedPtr.hpp"
51
52 namespace vkt
53 {
54 namespace MultiView
55 {
56 namespace
57 {
58
59 using namespace vk;
60 using de::MovePtr;
61 using de::UniquePtr;
62 using std::vector;
63 using std::map;
64 using std::string;
65
66 enum TestType
67 {
68         TEST_TYPE_VIEW_MASK,
69         TEST_TYPE_VIEW_INDEX_IN_VERTEX,
70         TEST_TYPE_VIEW_INDEX_IN_FRAGMENT,
71         TEST_TYPE_VIEW_INDEX_IN_GEOMETRY,
72         TEST_TYPE_VIEW_INDEX_IN_TESELLATION,
73         TEST_TYPE_INPUT_ATTACHMENTS,
74         TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY,
75         TEST_TYPE_INSTANCED_RENDERING,
76         TEST_TYPE_INPUT_RATE_INSTANCE,
77         TEST_TYPE_DRAW_INDIRECT,
78         TEST_TYPE_DRAW_INDIRECT_INDEXED,
79         TEST_TYPE_DRAW_INDEXED,
80         TEST_TYPE_CLEAR_ATTACHMENTS,
81         TEST_TYPE_SECONDARY_CMD_BUFFER,
82         TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY,
83         TEST_TYPE_POINT_SIZE,
84         TEST_TYPE_MULTISAMPLE,
85         TEST_TYPE_QUERIES,
86         TEST_TYPE_NON_PRECISE_QUERIES,
87         TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR,
88         TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR,
89         TEST_TYPE_DEPTH,
90         TEST_TYPE_STENCIL,
91         TEST_TYPE_LAST
92 };
93
94 enum RenderPassType
95 {
96         RENDERPASS_TYPE_LEGACY = 0,
97         RENDERPASS_TYPE_RENDERPASS2,
98 };
99
100 struct TestParameters
101 {
102         VkExtent3D                              extent;
103         vector<deUint32>                viewMasks;
104         TestType                                viewIndex;
105         VkSampleCountFlagBits   samples;
106         VkFormat                                colorFormat;
107         RenderPassType                  renderPassType;
108 };
109
110 const int       TEST_POINT_SIZE_SMALL   = 2;
111 const int       TEST_POINT_SIZE_WIDE    = 4;
112
113 vk::Move<vk::VkRenderPass> makeRenderPass (const DeviceInterface&               vk,
114                                                                                    const VkDevice                               device,
115                                                                                    const VkFormat                               colorFormat,
116                                                                                    const vector<deUint32>&              viewMasks,
117                                                                                    RenderPassType                               renderPassType,
118                                                                                    const VkSampleCountFlagBits  samples = VK_SAMPLE_COUNT_1_BIT,
119                                                                                    const VkAttachmentLoadOp             colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
120                                                                                    const VkFormat                               dsFormat = VK_FORMAT_UNDEFINED)
121 {
122         switch (renderPassType)
123         {
124                 case RENDERPASS_TYPE_LEGACY:
125                         return MultiView::makeRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, samples, colorLoadOp, dsFormat);
126                 case RENDERPASS_TYPE_RENDERPASS2:
127                         return MultiView::makeRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, samples, colorLoadOp, dsFormat);
128                 default:
129                         TCU_THROW(InternalError, "Impossible");
130         }
131 }
132
133 vk::Move<vk::VkRenderPass> makeRenderPassWithAttachments (const DeviceInterface&        vk,
134                                                                                                                   const VkDevice                        device,
135                                                                                                                   const VkFormat                        colorFormat,
136                                                                                                                   const vector<deUint32>&       viewMasks,
137                                                                                                                   RenderPassType                        renderPassType)
138 {
139         switch (renderPassType)
140         {
141                 case RENDERPASS_TYPE_LEGACY:
142                         return MultiView::makeRenderPassWithAttachments<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, renderPassType == RENDERPASS_TYPE_RENDERPASS2);
143                 case RENDERPASS_TYPE_RENDERPASS2:
144                         return MultiView::makeRenderPassWithAttachments<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, renderPassType == RENDERPASS_TYPE_RENDERPASS2);
145                 default:
146                         TCU_THROW(InternalError, "Impossible");
147         }
148 }
149
150 vk::Move<vk::VkRenderPass> makeRenderPassWithDepth (const DeviceInterface&      vk,
151                                                                                                         const VkDevice                  device,
152                                                                                                         const VkFormat                  colorFormat,
153                                                                                                         const vector<deUint32>& viewMasks,
154                                                                                                         const                                   VkFormat dsFormat,
155                                                                                                         RenderPassType                  renderPassType)
156 {
157         switch (renderPassType)
158         {
159                 case RENDERPASS_TYPE_LEGACY:
160                         return MultiView::makeRenderPassWithDepth<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, dsFormat);
161                 case RENDERPASS_TYPE_RENDERPASS2:
162                         return MultiView::makeRenderPassWithDepth<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, dsFormat);
163                 default:
164                         TCU_THROW(InternalError, "Impossible");
165         }
166 }
167
168 template<typename RenderpassSubpass>
169 void cmdBeginRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassContents contents)
170 {
171         const typename RenderpassSubpass::SubpassBeginInfo      subpassBeginInfo        (DE_NULL, contents);
172
173         RenderpassSubpass::cmdBeginRenderPass(vkd, cmdBuffer, pRenderPassBegin, &subpassBeginInfo);
174 }
175
176 void cmdBeginRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassContents contents, RenderPassType renderPassType)
177 {
178         switch (renderPassType)
179         {
180                 case RENDERPASS_TYPE_LEGACY:            cmdBeginRenderPass<RenderpassSubpass1>(vkd, cmdBuffer, pRenderPassBegin, contents);     break;
181                 case RENDERPASS_TYPE_RENDERPASS2:       cmdBeginRenderPass<RenderpassSubpass2>(vkd, cmdBuffer, pRenderPassBegin, contents);     break;
182                 default:                                                        TCU_THROW(InternalError, "Impossible");
183         }
184 }
185
186 template<typename RenderpassSubpass>
187 void cmdNextSubpass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkSubpassContents contents)
188 {
189         const typename RenderpassSubpass::SubpassBeginInfo      subpassBeginInfo        (DE_NULL, contents);
190         const typename RenderpassSubpass::SubpassEndInfo        subpassEndInfo          (DE_NULL);
191
192         RenderpassSubpass::cmdNextSubpass(vkd, cmdBuffer, &subpassBeginInfo, &subpassEndInfo);
193 }
194
195 void cmdNextSubpass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkSubpassContents contents, RenderPassType renderPassType)
196 {
197         switch (renderPassType)
198         {
199                 case RENDERPASS_TYPE_LEGACY:            cmdNextSubpass<RenderpassSubpass1>(vkd, cmdBuffer, contents);   break;
200                 case RENDERPASS_TYPE_RENDERPASS2:       cmdNextSubpass<RenderpassSubpass2>(vkd, cmdBuffer, contents);   break;
201                 default:                                                        TCU_THROW(InternalError, "Impossible");
202         }
203 }
204
205 template<typename RenderpassSubpass>
206 void cmdEndRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer)
207 {
208         const typename RenderpassSubpass::SubpassEndInfo        subpassEndInfo  (DE_NULL);
209
210         RenderpassSubpass::cmdEndRenderPass(vkd, cmdBuffer, &subpassEndInfo);
211 }
212
213 void cmdEndRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, RenderPassType renderPassType)
214 {
215         switch (renderPassType)
216         {
217                 case RENDERPASS_TYPE_LEGACY:            cmdEndRenderPass<RenderpassSubpass1>(vkd, cmdBuffer);   break;
218                 case RENDERPASS_TYPE_RENDERPASS2:       cmdEndRenderPass<RenderpassSubpass2>(vkd, cmdBuffer);   break;
219                 default:                                                        TCU_THROW(InternalError, "Impossible");
220         }
221 }
222
223 class ImageAttachment
224 {
225 public:
226                                 ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat, const VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT);
227         VkImageView     getImageView    (void) const
228         {
229                 return *m_imageView;
230         }
231         VkImage         getImage                (void) const
232         {
233                 return *m_image;
234         }
235 private:
236         Move<VkImage>                   m_image;
237         MovePtr<Allocation>             m_allocationImage;
238         Move<VkImageView>               m_imageView;
239 };
240
241 ImageAttachment::ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat, const VkSampleCountFlagBits samples)
242 {
243         const bool                                              depthStencilFormat                      = isDepthStencilFormat(colorFormat);
244         const VkImageAspectFlags                aspectFlags                                     = depthStencilFormat ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
245         const VkImageSubresourceRange   colorImageSubresourceRange      = makeImageSubresourceRange(aspectFlags, 0u, 1u, 0u, extent.depth);
246         const VkImageUsageFlags                 imageUsageFlagsDependent        = depthStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
247         const VkImageUsageFlags                 imageUsageFlags                         = imageUsageFlagsDependent | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
248         const VkImageCreateInfo                 colorAttachmentImageInfo        = makeImageCreateInfo(VK_IMAGE_TYPE_2D, extent, colorFormat, imageUsageFlags, samples);
249
250         m_image                                                 = createImage(device, logicalDevice, &colorAttachmentImageInfo);
251         m_allocationImage                               = allocator.allocate(getImageMemoryRequirements(device, logicalDevice, *m_image), MemoryRequirement::Any);
252         VK_CHECK(device.bindImageMemory(logicalDevice, *m_image, m_allocationImage->getMemory(), m_allocationImage->getOffset()));
253         m_imageView                                             = makeImageView(device, logicalDevice, *m_image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, colorFormat, colorImageSubresourceRange);
254 }
255
256 class MultiViewRenderTestInstance : public TestInstance
257 {
258 public:
259                                                                         MultiViewRenderTestInstance     (Context& context, const TestParameters& parameters);
260 protected:
261         typedef de::SharedPtr<Unique<VkPipeline> >              PipelineSp;
262         typedef de::SharedPtr<Unique<VkShaderModule> >  ShaderModuleSP;
263
264         virtual tcu::TestStatus                 iterate                                 (void);
265         virtual void                                    beforeDraw                              (void);
266         virtual void                                    afterDraw                               (void);
267         virtual void                                    draw                                    (const deUint32                 subpassCount,
268                                                                                                                          VkRenderPass                   renderPass,
269                                                                                                                          VkFramebuffer                  frameBuffer,
270                                                                                                                          vector<PipelineSp>&    pipelines);
271         virtual void                                    createVertexData                (void);
272         TestParameters                                  fillMissingParameters   (const TestParameters&  parameters);
273         void                                                    createVertexBuffer              (void);
274         void                                                    createMultiViewDevices  (void);
275         void                                                    createCommandBuffer             (void);
276         void                                                    madeShaderModule                (map<VkShaderStageFlagBits,ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams);
277         Move<VkPipeline>                                makeGraphicsPipeline    (const VkRenderPass                                                     renderPass,
278                                                                                                                          const VkPipelineLayout                                         pipelineLayout,
279                                                                                                                          const deUint32                                                         pipelineShaderStageCount,
280                                                                                                                          const VkPipelineShaderStageCreateInfo*         pipelineShaderStageCreate,
281                                                                                                                          const deUint32                                                         subpass,
282                                                                                                                          const VkVertexInputRate                                        vertexInputRate = VK_VERTEX_INPUT_RATE_VERTEX,
283                                                                                                                          const bool                                                                     useDepthTest = false,
284                                                                                                                          const bool                                                                     useStencilTest = false);
285         void                                                    readImage                               (VkImage image, const tcu::PixelBufferAccess& dst);
286         bool                                                    checkImage                              (tcu::ConstPixelBufferAccess& dst);
287         MovePtr<tcu::Texture2DArray>    imageData                               (void);
288         const tcu::Vec4                                 getQuarterRefColor              (const deUint32 quarterNdx, const int colorNdx, const int layerNdx, const bool background = true, const deUint32 subpassNdx = 0u);
289         void                                                    appendVertex                    (const tcu::Vec4& coord, const tcu::Vec4& color);
290         void                                                    setPoint                                (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& pointColor, const int pointSize, const int layerNdx, const deUint32 quarter);
291         void                                                    fillTriangle                    (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter);
292         void                                                    fillLayer                               (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx);
293         void                                                    fillQuarter                             (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter, const deUint32 subpassNdx);
294
295         const bool                                              m_extensionSupported;
296         const TestParameters                    m_parameters;
297         const int                                               m_seed;
298         const deUint32                                  m_squareCount;
299         Move<VkDevice>                                  m_logicalDevice;
300         MovePtr<DeviceInterface>                m_device;
301         MovePtr<Allocator>                              m_allocator;
302         deUint32                                                m_queueFamilyIndex;
303         VkQueue                                                 m_queue;
304         vector<tcu::Vec4>                               m_vertexCoord;
305         Move<VkBuffer>                                  m_vertexCoordBuffer;
306         MovePtr<Allocation>                             m_vertexCoordAlloc;
307         vector<tcu::Vec4>                               m_vertexColor;
308         Move<VkBuffer>                                  m_vertexColorBuffer;
309         MovePtr<Allocation>                             m_vertexColorAlloc;
310         vector<deUint32>                                m_vertexIndices;
311         Move<VkBuffer>                                  m_vertexIndicesBuffer;
312         MovePtr<Allocation>                             m_vertexIndicesAllocation;
313         Move<VkCommandPool>                             m_cmdPool;
314         Move<VkCommandBuffer>                   m_cmdBuffer;
315         de::SharedPtr<ImageAttachment>  m_colorAttachment;
316         VkBool32                                                m_hasMultiDrawIndirect;
317         vector<tcu::Vec4>                               m_colorTable;
318 };
319
320 MultiViewRenderTestInstance::MultiViewRenderTestInstance (Context& context, const TestParameters& parameters)
321         : TestInstance                  (context)
322         , m_extensionSupported  ((parameters.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
323         , m_parameters                  (fillMissingParameters(parameters))
324         , m_seed                                (context.getTestContext().getCommandLine().getBaseSeed())
325         , m_squareCount                 (4u)
326         , m_queueFamilyIndex    (0u)
327 {
328         const float v   = 0.75f;
329         const float o   = 0.25f;
330
331         m_colorTable.push_back(tcu::Vec4(v, o, o, 1.0f));
332         m_colorTable.push_back(tcu::Vec4(o, v, o, 1.0f));
333         m_colorTable.push_back(tcu::Vec4(o, o, v, 1.0f));
334         m_colorTable.push_back(tcu::Vec4(o, v, v, 1.0f));
335         m_colorTable.push_back(tcu::Vec4(v, o, v, 1.0f));
336         m_colorTable.push_back(tcu::Vec4(v, v, o, 1.0f));
337         m_colorTable.push_back(tcu::Vec4(o, o, o, 1.0f));
338         m_colorTable.push_back(tcu::Vec4(v, v, v, 1.0f));
339
340         createMultiViewDevices();
341
342         // Color attachment
343         m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, m_parameters.samples));
344 }
345
346 tcu::TestStatus MultiViewRenderTestInstance::iterate (void)
347 {
348         const deUint32                                                          subpassCount                            = static_cast<deUint32>(m_parameters.viewMasks.size());
349
350         // FrameBuffer & renderPass
351         Unique<VkRenderPass>                                            renderPass                                      (makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderPassType));
352
353         Unique<VkFramebuffer>                                           frameBuffer                                     (makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height));
354
355         // pipelineLayout
356         Unique<VkPipelineLayout>                                        pipelineLayout                          (makePipelineLayout(*m_device, *m_logicalDevice));
357
358         // pipelines
359         map<VkShaderStageFlagBits, ShaderModuleSP>      shaderModule;
360         vector<PipelineSp>                                                      pipelines(subpassCount);
361         const VkVertexInputRate                                         vertexInputRate                         = (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
362
363         {
364                 vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
365                 madeShaderModule(shaderModule, shaderStageParams);
366                 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
367                         pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate))));
368         }
369
370         createCommandBuffer();
371         createVertexData();
372         createVertexBuffer();
373
374         draw(subpassCount, *renderPass, *frameBuffer, pipelines);
375
376         {
377                 vector<deUint8>                 pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
378                 tcu::PixelBufferAccess  dst                             (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
379
380                 readImage(m_colorAttachment->getImage(), dst);
381
382                 if (!checkImage(dst))
383                         return tcu::TestStatus::fail("Fail");
384         }
385
386         return tcu::TestStatus::pass("Pass");
387 }
388
389 void MultiViewRenderTestInstance::beforeDraw (void)
390 {
391         const VkImageSubresourceRange   subresourceRange                =
392         {
393                 VK_IMAGE_ASPECT_COLOR_BIT,      //VkImageAspectFlags    aspectMask;
394                 0u,                                                     //deUint32                              baseMipLevel;
395                 1u,                                                     //deUint32                              levelCount;
396                 0u,                                                     //deUint32                              baseArrayLayer;
397                 m_parameters.extent.depth,      //deUint32                              layerCount;
398         };
399         imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
400                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
401                 0, VK_ACCESS_TRANSFER_WRITE_BIT,
402                 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
403
404         const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
405         m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange);
406
407         imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
408                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
409                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
410                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
411 }
412
413 void MultiViewRenderTestInstance::afterDraw (void)
414 {
415         const VkImageSubresourceRange   subresourceRange                =
416         {
417                 VK_IMAGE_ASPECT_COLOR_BIT,      //VkImageAspectFlags    aspectMask;
418                 0u,                                                     //deUint32                              baseMipLevel;
419                 1u,                                                     //deUint32                              levelCount;
420                 0u,                                                     //deUint32                              baseArrayLayer;
421                 m_parameters.extent.depth,      //deUint32                              layerCount;
422         };
423
424         imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
425                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
426                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
427                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
428 }
429
430 void MultiViewRenderTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
431 {
432         const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
433         const VkClearValue                              renderPassClearValue    = makeClearValueColor(tcu::Vec4(0.0f));
434         const VkBuffer                                  vertexBuffers[]                 = { *m_vertexCoordBuffer, *m_vertexColorBuffer };
435         const VkDeviceSize                              vertexBufferOffsets[]   = {                   0u,                   0u };
436         const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
437
438         const VkRenderPassBeginInfo             renderPassBeginInfo             =
439         {
440                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
441                 DE_NULL,                                                                        // const void*                  pNext;
442                 renderPass,                                                                     // VkRenderPass                 renderPass;
443                 frameBuffer,                                                            // VkFramebuffer                framebuffer;
444                 renderArea,                                                                     // VkRect2D                             renderArea;
445                 1u,                                                                                     // uint32_t                             clearValueCount;
446                 &renderPassClearValue,                                          // const VkClearValue*  pClearValues;
447         };
448
449         beginCommandBuffer(*m_device, *m_cmdBuffer);
450
451         beforeDraw();
452
453         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
454
455         m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
456
457         if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED)
458                 m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32);
459
460         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
461         {
462                 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
463
464                 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
465                         if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED)
466                                 m_device->cmdDrawIndexed(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u, 0u);
467                         else
468                                 m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
469
470                 if (subpassNdx < subpassCount - 1u)
471                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
472         }
473
474         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
475
476         afterDraw();
477
478         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
479         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
480 }
481
482 void MultiViewRenderTestInstance::createVertexData (void)
483 {
484         tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
485
486         appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color);
487         appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
488         appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
489         appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
490
491         color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
492         appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
493         appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color);
494         appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
495         appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);
496
497         color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
498         appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
499         appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
500         appendVertex(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color);
501         appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);
502
503         color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
504         appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
505         appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);
506         appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);
507         appendVertex(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), color);
508
509         if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
510         {
511                 const size_t            verticesCount   = m_vertexCoord.size();
512                 vector<tcu::Vec4>       vertexColor             (verticesCount);
513                 vector<tcu::Vec4>       vertexCoord             (verticesCount);
514
515                 m_vertexIndices.clear();
516                 m_vertexIndices.reserve(verticesCount);
517                 for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
518                         m_vertexIndices.push_back(vertexIdx);
519
520                 de::Random(m_seed).shuffle(m_vertexIndices.begin(), m_vertexIndices.end());
521
522                 for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
523                         vertexColor[m_vertexIndices[vertexIdx]] = m_vertexColor[vertexIdx];
524                 m_vertexColor.assign(vertexColor.begin(), vertexColor.end());
525
526                 for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
527                         vertexCoord[m_vertexIndices[vertexIdx]] = m_vertexCoord[vertexIdx];
528                 m_vertexCoord.assign(vertexCoord.begin(), vertexCoord.end());
529         }
530 }
531
532 TestParameters MultiViewRenderTestInstance::fillMissingParameters (const TestParameters& parameters)
533 {
534         if (!parameters.viewMasks.empty())
535                 return parameters;
536         else
537         {
538                 const InstanceInterface&                        instance                        = m_context.getInstanceInterface();
539                 const VkPhysicalDevice                          physicalDevice          = m_context.getPhysicalDevice();
540
541                 VkPhysicalDeviceMultiviewProperties multiviewProperties =
542                 {
543                         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR,     // VkStructureType      sType;
544                         DE_NULL,                                                                                                        // void*                        pNext;
545                         0u,                                                                                                                     // deUint32                     maxMultiviewViewCount;
546                         0u                                                                                                                      // deUint32                     maxMultiviewInstanceIndex;
547                 };
548
549                 VkPhysicalDeviceProperties2 deviceProperties2;
550                 deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
551                 deviceProperties2.pNext = &multiviewProperties;
552
553                 instance.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2);
554
555                 TestParameters newParameters = parameters;
556                 newParameters.extent.depth = multiviewProperties.maxMultiviewViewCount;
557
558                 vector<deUint32> viewMasks(multiviewProperties.maxMultiviewViewCount);
559                 for (deUint32 i = 0; i < multiviewProperties.maxMultiviewViewCount; i++)
560                         viewMasks[i] = 1 << i;
561                 newParameters.viewMasks = viewMasks;
562
563                 return newParameters;
564         }
565 }
566
567 void MultiViewRenderTestInstance::createVertexBuffer (void)
568 {
569         DE_ASSERT(m_vertexCoord.size() == m_vertexColor.size());
570         DE_ASSERT(m_vertexCoord.size() != 0);
571
572         const size_t    nonCoherentAtomSize     = static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize);
573
574         // Upload vertex coordinates
575         {
576                 const size_t                            dataSize                = static_cast<size_t>(m_vertexCoord.size() * sizeof(m_vertexCoord[0]));
577                 const VkDeviceSize                      bufferDataSize  = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
578                 const VkBufferCreateInfo        bufferInfo              = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
579
580                 m_vertexCoordBuffer     = createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
581                 m_vertexCoordAlloc      = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexCoordBuffer), MemoryRequirement::HostVisible);
582
583                 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexCoordBuffer, m_vertexCoordAlloc->getMemory(), m_vertexCoordAlloc->getOffset()));
584                 deMemcpy(m_vertexCoordAlloc->getHostPtr(), m_vertexCoord.data(), static_cast<size_t>(dataSize));
585                 flushAlloc(*m_device, *m_logicalDevice, *m_vertexCoordAlloc);
586         }
587
588         // Upload vertex colors
589         {
590                 const size_t                            dataSize                = static_cast<size_t>(m_vertexColor.size() * sizeof(m_vertexColor[0]));
591                 const VkDeviceSize                      bufferDataSize  = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
592                 const VkBufferCreateInfo        bufferInfo              = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
593
594                 m_vertexColorBuffer     = createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
595                 m_vertexColorAlloc      = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexColorBuffer), MemoryRequirement::HostVisible);
596
597                 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexColorBuffer, m_vertexColorAlloc->getMemory(), m_vertexColorAlloc->getOffset()));
598                 deMemcpy(m_vertexColorAlloc->getHostPtr(), m_vertexColor.data(), static_cast<size_t>(dataSize));
599                 flushAlloc(*m_device, *m_logicalDevice, *m_vertexColorAlloc);
600         }
601
602         // Upload vertex indices
603         if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
604         {
605                 const size_t                            dataSize                = static_cast<size_t>(m_vertexIndices.size() * sizeof(m_vertexIndices[0]));
606                 const VkDeviceSize                      bufferDataSize  = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
607                 const VkBufferCreateInfo        bufferInfo              = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
608
609                 DE_ASSERT(m_vertexIndices.size() == m_vertexCoord.size());
610
611                 m_vertexIndicesBuffer           = createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
612                 m_vertexIndicesAllocation       = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexIndicesBuffer), MemoryRequirement::HostVisible);
613
614                 // Init host buffer data
615                 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexIndicesBuffer, m_vertexIndicesAllocation->getMemory(), m_vertexIndicesAllocation->getOffset()));
616                 deMemcpy(m_vertexIndicesAllocation->getHostPtr(), m_vertexIndices.data(), static_cast<size_t>(dataSize));
617                 flushAlloc(*m_device, *m_logicalDevice, *m_vertexIndicesAllocation);
618         }
619         else
620                 DE_ASSERT(m_vertexIndices.empty());
621 }
622
623 void MultiViewRenderTestInstance::createMultiViewDevices (void)
624 {
625         const InstanceInterface&                                instance                                = m_context.getInstanceInterface();
626         const VkPhysicalDevice                                  physicalDevice                  = m_context.getPhysicalDevice();
627         const vector<VkQueueFamilyProperties>   queueFamilyProperties   = getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice);
628
629         for (; m_queueFamilyIndex < queueFamilyProperties.size(); ++m_queueFamilyIndex)
630         {
631                 if ((queueFamilyProperties[m_queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
632                         break;
633         }
634
635         const float                                                             queuePriorities                 = 1.0f;
636         const VkDeviceQueueCreateInfo                   queueInfo                               =
637         {
638                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,                                     //VkStructureType                       sType;
639                 DE_NULL,                                                                                                        //const void*                           pNext;
640                 (VkDeviceQueueCreateFlags)0u,                                                           //VkDeviceQueueCreateFlags      flags;
641                 m_queueFamilyIndex,                                                                                     //deUint32                                      queueFamilyIndex;
642                 1u,                                                                                                                     //deUint32                                      queueCount;
643                 &queuePriorities                                                                                        //const float*                          pQueuePriorities;
644         };
645
646         VkPhysicalDeviceMultiviewFeatures               multiviewFeatures               =
647         {
648                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR,       // VkStructureType                      sType;
649                 DE_NULL,                                                                                                        // void*                                        pNext;
650                 DE_FALSE,                                                                                                       // VkBool32                                     multiview;
651                 DE_FALSE,                                                                                                       // VkBool32                                     multiviewGeometryShader;
652                 DE_FALSE,                                                                                                       // VkBool32                                     multiviewTessellationShader;
653         };
654
655         VkPhysicalDeviceFeatures2                               enabledFeatures;
656         enabledFeatures.sType                                   = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
657         enabledFeatures.pNext                                   = &multiviewFeatures;
658
659         instance.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);
660
661         if (!multiviewFeatures.multiview)
662                 TCU_THROW(NotSupportedError, "MultiView not supported");
663
664         bool requiresGeomShader = (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex) ||
665                                                                 (TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY == m_parameters.viewIndex) ||
666                                                                 (TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == m_parameters.viewIndex);
667
668         if (requiresGeomShader && !multiviewFeatures.multiviewGeometryShader)
669                 TCU_THROW(NotSupportedError, "Geometry shader is not supported");
670
671         if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex && !multiviewFeatures.multiviewTessellationShader)
672                 TCU_THROW(NotSupportedError, "Tessellation shader is not supported");
673
674         VkPhysicalDeviceMultiviewProperties     multiviewProperties                     =
675         {
676                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR,     //VkStructureType       sType;
677                 DE_NULL,                                                                                                        //void*                         pNext;
678                 0u,                                                                                                                     //deUint32                      maxMultiviewViewCount;
679                 0u                                                                                                                      //deUint32                      maxMultiviewInstanceIndex;
680         };
681
682         VkPhysicalDeviceProperties2                     propertiesDeviceProperties2;
683         propertiesDeviceProperties2.sType       = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
684         propertiesDeviceProperties2.pNext       = &multiviewProperties;
685
686         instance.getPhysicalDeviceProperties2(physicalDevice, &propertiesDeviceProperties2);
687
688         if (multiviewProperties.maxMultiviewViewCount < 6u)
689                 TCU_FAIL("maxMultiviewViewCount below min value");
690
691         if (multiviewProperties.maxMultiviewInstanceIndex < 134217727u) //134217727u = 2^27 -1
692                 TCU_FAIL("maxMultiviewInstanceIndex below min value");
693
694         if (multiviewProperties.maxMultiviewViewCount <m_parameters.extent.depth)
695                 TCU_THROW(NotSupportedError, "Limit MaxMultiviewViewCount to small to run this test");
696
697         m_hasMultiDrawIndirect = enabledFeatures.features.multiDrawIndirect;
698
699         {
700                 vector<const char*>                             deviceExtensions;
701
702                 if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_multiview"))
703                         deviceExtensions.push_back("VK_KHR_multiview");
704
705                 if (m_parameters.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
706                         if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_create_renderpass2"))
707                                 deviceExtensions.push_back("VK_KHR_create_renderpass2");
708
709                 const VkDeviceCreateInfo                deviceInfo                      =
710                 {
711                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                                                   //VkStructureType                                       sType;
712                         &enabledFeatures,                                                                                               //const void*                                           pNext;
713                         0u,                                                                                                                             //VkDeviceCreateFlags                           flags;
714                         1u,                                                                                                                             //deUint32                                                      queueCreateInfoCount;
715                         &queueInfo,                                                                                                             //const VkDeviceQueueCreateInfo*        pQueueCreateInfos;
716                         0u,                                                                                                                             //deUint32                                                      enabledLayerCount;
717                         DE_NULL,                                                                                                                //const char* const*                            ppEnabledLayerNames;
718                         static_cast<deUint32>(deviceExtensions.size()),                                 //deUint32                                                      enabledExtensionCount;
719                         deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],              //const char* const*                            pEnabledExtensionNames;
720                         DE_NULL                                                                                                                 //const VkPhysicalDeviceFeatures*       pEnabledFeatures;
721                 };
722
723                 m_logicalDevice                                 = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), m_context.getPlatformInterface(), m_context.getInstance(), instance, physicalDevice, &deviceInfo);
724                 m_device                                                = MovePtr<DeviceDriver>(new DeviceDriver(m_context.getPlatformInterface(), m_context.getInstance(), *m_logicalDevice));
725                 m_allocator                                             = MovePtr<Allocator>(new SimpleAllocator(*m_device, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instance, physicalDevice)));
726                 m_device->getDeviceQueue                (*m_logicalDevice, m_queueFamilyIndex, 0u, &m_queue);
727         }
728 }
729
730 void MultiViewRenderTestInstance::createCommandBuffer (void)
731 {
732         // cmdPool
733         {
734                 const VkCommandPoolCreateInfo cmdPoolParams =
735                 {
736                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType              sType;
737                         DE_NULL,                                                                                        // const void*                  pNext;
738                         VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCmdPoolCreateFlags flags;
739                         m_queueFamilyIndex,                                                                     // deUint32                             queueFamilyIndex;
740                 };
741                 m_cmdPool = createCommandPool(*m_device, *m_logicalDevice, &cmdPoolParams);
742         }
743
744         // cmdBuffer
745         {
746                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
747                 {
748                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,         // VkStructureType              sType;
749                         DE_NULL,                                                                                        // const void*                  pNext;
750                         *m_cmdPool,                                                                                     // VkCommandPool                commandPool;
751                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                        // VkCommandBufferLevel level;
752                         1u,                                                                                                     // deUint32                             bufferCount;
753                 };
754                 m_cmdBuffer     = allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo);
755         }
756 }
757
758 void MultiViewRenderTestInstance::madeShaderModule (map<VkShaderStageFlagBits, ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams)
759 {
760         // create shaders modules
761         switch (m_parameters.viewIndex)
762         {
763                 case TEST_TYPE_VIEW_MASK:
764                 case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
765                 case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
766                 case TEST_TYPE_INSTANCED_RENDERING:
767                 case TEST_TYPE_INPUT_RATE_INSTANCE:
768                 case TEST_TYPE_DRAW_INDIRECT:
769                 case TEST_TYPE_DRAW_INDIRECT_INDEXED:
770                 case TEST_TYPE_DRAW_INDEXED:
771                 case TEST_TYPE_CLEAR_ATTACHMENTS:
772                 case TEST_TYPE_SECONDARY_CMD_BUFFER:
773                 case TEST_TYPE_INPUT_ATTACHMENTS:
774                 case TEST_TYPE_POINT_SIZE:
775                 case TEST_TYPE_MULTISAMPLE:
776                 case TEST_TYPE_QUERIES:
777                 case TEST_TYPE_NON_PRECISE_QUERIES:
778                 case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR:
779                 case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR:
780                 case TEST_TYPE_DEPTH:
781                 case TEST_TYPE_STENCIL:
782                         shaderModule[VK_SHADER_STAGE_VERTEX_BIT]                                        = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
783                         shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]                                      = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
784                         break;
785                 case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
786                 case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY:
787                 case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY:
788                         shaderModule[VK_SHADER_STAGE_VERTEX_BIT]                                        = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
789                         shaderModule[VK_SHADER_STAGE_GEOMETRY_BIT]                                      = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("geometry"), 0))));
790                         shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]                                      = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
791                         break;
792                 case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
793                         shaderModule[VK_SHADER_STAGE_VERTEX_BIT]                                        = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
794                         shaderModule[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT]          = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_control"), 0))));
795                         shaderModule[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT]       = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_evaluation"), 0))));
796                         shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]                                      = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
797                         break;
798                 default:
799                         DE_ASSERT(0);
800                 break;
801         };
802
803         VkPipelineShaderStageCreateInfo pipelineShaderStage     =
804         {
805                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
806                         DE_NULL,                                                                                                // const void*                                                  pNext;
807                         (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
808                         (VkShaderStageFlagBits)0,                                                               // VkShaderStageFlagBits                                stage;
809                         (VkShaderModule)0,                                                                              // VkShaderModule                                               module;
810                         "main",                                                                                                 // const char*                                                  pName;
811                         (const VkSpecializationInfo*)DE_NULL,                                   // const VkSpecializationInfo*                  pSpecializationInfo;
812         };
813
814         for (map<VkShaderStageFlagBits, ShaderModuleSP>::iterator it=shaderModule.begin(); it!=shaderModule.end(); ++it)
815         {
816                 pipelineShaderStage.stage       = it->first;
817                 pipelineShaderStage.module      = **it->second;
818                 shaderStageParams.push_back(pipelineShaderStage);
819         }
820 }
821
822 Move<VkPipeline> MultiViewRenderTestInstance::makeGraphicsPipeline (const VkRenderPass                                                  renderPass,
823                                                                                                                                         const VkPipelineLayout                                          pipelineLayout,
824                                                                                                                                         const deUint32                                                          pipelineShaderStageCount,
825                                                                                                                                         const VkPipelineShaderStageCreateInfo*          pipelineShaderStageCreate,
826                                                                                                                                         const deUint32                                                          subpass,
827                                                                                                                                         const VkVertexInputRate                                         vertexInputRate,
828                                                                                                                                         const bool                                                                      useDepthTest,
829                                                                                                                                         const bool                                                                      useStencilTest)
830 {
831         const VkVertexInputBindingDescription                   vertexInputBindingDescriptions[]        =
832         {
833                 {
834                         0u,                                                                                                     // binding;
835                         static_cast<deUint32>(sizeof(m_vertexCoord[0])),        // stride;
836                         vertexInputRate                                                                         // inputRate
837                 },
838                 {
839                         1u,                                                                                                     // binding;
840                         static_cast<deUint32>(sizeof(m_vertexColor[0])),        // stride;
841                         vertexInputRate                                                                         // inputRate
842                 }
843         };
844
845         const VkVertexInputAttributeDescription                 vertexInputAttributeDescriptions[]      =
846         {
847                 {
848                         0u,                                                                                     // deUint32     location;
849                         0u,                                                                                     // deUint32     binding;
850                         VK_FORMAT_R32G32B32A32_SFLOAT,                          // VkFormat     format;
851                         0u                                                                                      // deUint32     offset;
852                 },      // VertexElementData::position
853                 {
854                         1u,                                                                                     // deUint32     location;
855                         1u,                                                                                     // deUint32     binding;
856                         VK_FORMAT_R32G32B32A32_SFLOAT,                          // VkFormat     format;
857                         0u                                                                                      // deUint32     offset;
858                 },      // VertexElementData::color
859         };
860
861         const VkPipelineVertexInputStateCreateInfo              vertexInputStateParams                          =
862         {
863                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
864                 NULL,                                                                                                                   // const void*                                                          pNext;
865                 0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
866                 DE_LENGTH_OF_ARRAY(vertexInputBindingDescriptions),                             // deUint32                                                                     vertexBindingDescriptionCount;
867                 vertexInputBindingDescriptions,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
868                 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),                   // deUint32                                                                     vertexAttributeDescriptionCount;
869                 vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
870         };
871
872         const VkPrimitiveTopology                                               topology                                                        = (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST :
873                                                                                                                                                                                   (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST :
874                                                                                                                                                                                   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
875
876         const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams                        =
877         {
878                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
879                 DE_NULL,                                                                                                                // const void*                                                          pNext;
880                 0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
881                 topology,                                                                                                               // VkPrimitiveTopology                                          topology;
882                 VK_FALSE,                                                                                                               // VkBool32                                                                     primitiveRestartEnable;
883         };
884
885         const VkViewport                                                                viewport                                                        = makeViewport(m_parameters.extent);
886         const VkRect2D                                                                  scissor                                                         = makeRect2D(m_parameters.extent);
887
888         const VkPipelineViewportStateCreateInfo                 viewportStateParams                                     =
889         {
890                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                              sType;
891                 DE_NULL,                                                                                                // const void*                                                  pNext;
892                 0u,                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
893                 1u,                                                                                                             // deUint32                                                             viewportCount;
894                 &viewport,                                                                                              // const VkViewport*                                    pViewports;
895                 1u,                                                                                                             // deUint32                                                             scissorCount;
896                 &scissor                                                                                                // const VkRect2D*                                              pScissors;
897         };
898
899         const VkPipelineRasterizationStateCreateInfo    rasterStateParams                                       =
900         {
901                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
902                 DE_NULL,                                                                                                        // const void*                                                          pNext;
903                 0u,                                                                                                                     // VkPipelineRasterizationStateCreateFlags      flags;
904                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthClampEnable;
905                 VK_FALSE,                                                                                                       // VkBool32                                                                     rasterizerDiscardEnable;
906                 VK_POLYGON_MODE_FILL,                                                                           // VkPolygonMode                                                        polygonMode;
907                 VK_CULL_MODE_NONE,                                                                                      // VkCullModeFlags                                                      cullMode;
908                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                        // VkFrontFace                                                          frontFace;
909                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBiasEnable;
910                 0.0f,                                                                                                           // float                                                                        depthBiasConstantFactor;
911                 0.0f,                                                                                                           // float                                                                        depthBiasClamp;
912                 0.0f,                                                                                                           // float                                                                        depthBiasSlopeFactor;
913                 1.0f,                                                                                                           // float                                                                        lineWidth;
914         };
915
916         const VkSampleCountFlagBits                                             sampleCountFlagBits                                     = (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex) ? VK_SAMPLE_COUNT_4_BIT :
917                                                                                                                                                                                   VK_SAMPLE_COUNT_1_BIT;
918         const VkPipelineMultisampleStateCreateInfo              multisampleStateParams                          =
919         {
920                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
921                 DE_NULL,                                                                                                        // const void*                                                          pNext;
922                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
923                 sampleCountFlagBits,                                                                            // VkSampleCountFlagBits                                        rasterizationSamples;
924                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
925                 0.0f,                                                                                                           // float                                                                        minSampleShading;
926                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
927                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
928                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToOneEnable;
929         };
930
931         VkPipelineDepthStencilStateCreateInfo                   depthStencilStateParams                         =
932         {
933                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
934                 DE_NULL,                                                                                                        // const void*                                                          pNext;
935                 0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
936                 useDepthTest ? VK_TRUE : VK_FALSE,                                                      // VkBool32                                                                     depthTestEnable;
937                 useDepthTest ? VK_TRUE : VK_FALSE,                                                      // VkBool32                                                                     depthWriteEnable;
938                 VK_COMPARE_OP_LESS_OR_EQUAL,                                                            // VkCompareOp                                                          depthCompareOp;
939                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
940                 useStencilTest ? VK_TRUE : VK_FALSE,                                            // VkBool32                                                                     stencilTestEnable;
941                 // VkStencilOpState front;
942                 {
943                         VK_STENCIL_OP_KEEP,                                     // VkStencilOp  failOp;
944                         VK_STENCIL_OP_INCREMENT_AND_CLAMP,      // VkStencilOp  passOp;
945                         VK_STENCIL_OP_KEEP,                                     // VkStencilOp  depthFailOp;
946                         VK_COMPARE_OP_ALWAYS,                           // VkCompareOp  compareOp;
947                         ~0u,                                                            // deUint32             compareMask;
948                         ~0u,                                                            // deUint32             writeMask;
949                         0u,                                                                     // deUint32             reference;
950                 },
951                 // VkStencilOpState back;
952                 {
953                         VK_STENCIL_OP_KEEP,                                     // VkStencilOp  failOp;
954                         VK_STENCIL_OP_INCREMENT_AND_CLAMP,      // VkStencilOp  passOp;
955                         VK_STENCIL_OP_KEEP,                                     // VkStencilOp  depthFailOp;
956                         VK_COMPARE_OP_ALWAYS,                           // VkCompareOp  compareOp;
957                         ~0u,                                                            // deUint32             compareMask;
958                         ~0u,                                                            // deUint32             writeMask;
959                         0u,                                                                     // deUint32             reference;
960                 },
961                 0.0f,   // float        minDepthBounds;
962                 1.0f,   // float        maxDepthBounds;
963         };
964
965         const VkPipelineColorBlendAttachmentState               colorBlendAttachmentState                       =
966         {
967                 VK_FALSE,                                                               // VkBool32                                     blendEnable;
968                 VK_BLEND_FACTOR_SRC_ALPHA,                              // VkBlendFactor                        srcColorBlendFactor;
969                 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,    // VkBlendFactor                        dstColorBlendFactor;
970                 VK_BLEND_OP_ADD,                                                // VkBlendOp                            colorBlendOp;
971                 VK_BLEND_FACTOR_ONE,                                    // VkBlendFactor                        srcAlphaBlendFactor;
972                 VK_BLEND_FACTOR_ONE,                                    // VkBlendFactor                        dstAlphaBlendFactor;
973                 VK_BLEND_OP_ADD,                                                // VkBlendOp                            alphaBlendOp;
974                 VK_COLOR_COMPONENT_R_BIT |                              // VkColorComponentFlags        colorWriteMask;
975                 VK_COLOR_COMPONENT_G_BIT |
976                 VK_COLOR_COMPONENT_B_BIT |
977                 VK_COLOR_COMPONENT_A_BIT
978         };
979
980         const VkPipelineColorBlendStateCreateInfo               colorBlendStateParams                           =
981         {
982                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
983                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
984                 0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
985                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
986                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
987                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
988                 &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
989                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
990         };
991
992         VkPipelineTessellationStateCreateInfo                   TessellationState                                       =
993         {
994                 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
995                 DE_NULL,                                                                                                        // const void*                                                          pNext;
996                 (VkPipelineTessellationStateCreateFlags)0,                                      // VkPipelineTessellationStateCreateFlags       flags;
997                 4u                                                                                                                      // deUint32                                                                     patchControlPoints;
998         };
999
1000         const VkGraphicsPipelineCreateInfo                              graphicsPipelineParams                          =
1001         {
1002                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                                                                                // VkStructureType                                                                      sType;
1003                 DE_NULL,                                                                                                                                                                                // const void*                                                                          pNext;
1004                 (VkPipelineCreateFlags)0u,                                                                                                                                              // VkPipelineCreateFlags                                                        flags;
1005                 pipelineShaderStageCount,                                                                                                                                               // deUint32                                                                                     stageCount;
1006                 pipelineShaderStageCreate,                                                                                                                                              // const VkPipelineShaderStageCreateInfo*                       pStages;
1007                 &vertexInputStateParams,                                                                                                                                                // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
1008                 &inputAssemblyStateParams,                                                                                                                                              // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
1009                 (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)? &TessellationState : DE_NULL,  // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
1010                 &viewportStateParams,                                                                                                                                                   // const VkPipelineViewportStateCreateInfo*                     pViewportState;
1011                 &rasterStateParams,                                                                                                                                                             // const VkPipelineRasterizationStateCreateInfo*        pRasterState;
1012                 &multisampleStateParams,                                                                                                                                                // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
1013                 &depthStencilStateParams,                                                                                                                                               // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
1014                 &colorBlendStateParams,                                                                                                                                                 // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
1015                 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,                                                                                               // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
1016                 pipelineLayout,                                                                                                                                                                 // VkPipelineLayout                                                                     layout;
1017                 renderPass,                                                                                                                                                                             // VkRenderPass                                                                         renderPass;
1018                 subpass,                                                                                                                                                                                // deUint32                                                                                     subpass;
1019                 0u,                                                                                                                                                                                             // VkPipeline                                                                           basePipelineHandle;
1020                 0,                                                                                                                                                                                              // deInt32                                                                                      basePipelineIndex;
1021         };
1022
1023         return createGraphicsPipeline(*m_device, *m_logicalDevice, DE_NULL, &graphicsPipelineParams);
1024 }
1025
1026 void MultiViewRenderTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst)
1027 {
1028         Move<VkBuffer>                          buffer;
1029         MovePtr<Allocation>                     bufferAlloc;
1030         const VkDeviceSize                      pixelDataSize   = dst.getWidth() * dst.getHeight() * dst.getDepth() * mapVkFormat(m_parameters.colorFormat).getPixelSize();
1031
1032         // Create destination buffer
1033         {
1034                 const VkBufferCreateInfo bufferParams   =
1035                 {
1036                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
1037                         DE_NULL,                                                                // const void*                  pNext;
1038                         0u,                                                                             // VkBufferCreateFlags  flags;
1039                         pixelDataSize,                                                  // VkDeviceSize                 size;
1040                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,               // VkBufferUsageFlags   usage;
1041                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1042                         1u,                                                                             // deUint32                             queueFamilyIndexCount;
1043                         &m_queueFamilyIndex,                                    // const deUint32*              pQueueFamilyIndices;
1044                 };
1045
1046                 buffer          = createBuffer(*m_device, *m_logicalDevice, &bufferParams);
1047                 bufferAlloc     = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
1048                 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1049
1050                 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
1051                 flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
1052         }
1053
1054         const VkBufferMemoryBarrier     bufferBarrier   =
1055         {
1056                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1057                 DE_NULL,                                                                        // const void*          pNext;
1058                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1059                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1060                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1061                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1062                 *buffer,                                                                        // VkBuffer                     buffer;
1063                 0u,                                                                                     // VkDeviceSize         offset;
1064                 pixelDataSize                                                           // VkDeviceSize         size;
1065         };
1066
1067         // Copy image to buffer
1068         const VkImageAspectFlags        aspect                  = getAspectFlags(dst.getFormat());
1069         const VkBufferImageCopy         copyRegion              =
1070         {
1071                 0u,                                                                             // VkDeviceSize                         bufferOffset;
1072                 (deUint32)dst.getWidth(),                               // deUint32                                     bufferRowLength;
1073                 (deUint32)dst.getHeight(),                              // deUint32                                     bufferImageHeight;
1074                 {
1075                         aspect,                                                         // VkImageAspectFlags           aspect;
1076                         0u,                                                                     // deUint32                                     mipLevel;
1077                         0u,                                                                     // deUint32                                     baseArrayLayer;
1078                         m_parameters.extent.depth,                      // deUint32                                     layerCount;
1079                 },                                                                              // VkImageSubresourceLayers     imageSubresource;
1080                 { 0, 0, 0 },                                                    // VkOffset3D                           imageOffset;
1081                 { m_parameters.extent.width, m_parameters.extent.height, 1u }   // VkExtent3D                           imageExtent;
1082         };
1083
1084         beginCommandBuffer (*m_device, *m_cmdBuffer);
1085         {
1086                 VkImageSubresourceRange subresourceRange        =
1087                 {
1088                         aspect,                                         // VkImageAspectFlags   aspectMask;
1089                         0u,                                                     // deUint32                             baseMipLevel;
1090                         1u,                                                     // deUint32                             mipLevels;
1091                         0u,                                                     // deUint32                             baseArraySlice;
1092                         m_parameters.extent.depth,      // deUint32                             arraySize;
1093                 };
1094
1095                 imageBarrier (*m_device, *m_cmdBuffer, image, subresourceRange,
1096                         VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1097                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1098                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1099
1100                 m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
1101                 m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0u, DE_NULL);
1102         }
1103         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
1104         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
1105
1106         // Read buffer data
1107         invalidateAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
1108         tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
1109 }
1110
1111 bool MultiViewRenderTestInstance::checkImage (tcu::ConstPixelBufferAccess& renderedFrame)
1112 {
1113         const MovePtr<tcu::Texture2DArray>      referenceFrame  = imageData();
1114         const bool                                                      result                  = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1115                                                                                                                         "Result", "Image comparison result", referenceFrame->getLevel(0), renderedFrame, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR);
1116
1117         if (!result)
1118                 for (deUint32 layerNdx = 0u; layerNdx < m_parameters.extent.depth; layerNdx++)
1119                 {
1120                         tcu::ConstPixelBufferAccess ref (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx));
1121                         tcu::ConstPixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, renderedFrame.getPixelPtr(0 ,0, layerNdx));
1122                         tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", ref, dst, tcu::Vec4(0.01f), tcu::COMPARE_LOG_EVERYTHING);
1123                 }
1124
1125         return result;
1126 }
1127
1128 const tcu::Vec4 MultiViewRenderTestInstance::getQuarterRefColor (const deUint32 quarterNdx, const int colorNdx, const int layerNdx, const bool background, const deUint32 subpassNdx)
1129 {
1130         switch (m_parameters.viewIndex)
1131         {
1132                 case TEST_TYPE_VIEW_MASK:
1133                         return m_vertexColor[colorNdx];
1134
1135                 case TEST_TYPE_DRAW_INDEXED:
1136                         return m_vertexColor[m_vertexIndices[colorNdx]];
1137
1138                 case TEST_TYPE_INSTANCED_RENDERING:
1139                         return m_vertexColor[0] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, static_cast<float>(quarterNdx + 1u) * 0.10f, 0.0);
1140
1141                 case TEST_TYPE_INPUT_RATE_INSTANCE:
1142                         return m_vertexColor[colorNdx / 4] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, static_cast<float>(quarterNdx + 1u) * 0.10f, 0.0);
1143
1144                 case TEST_TYPE_DRAW_INDIRECT_INDEXED:
1145                         return m_vertexColor[m_vertexIndices[colorNdx]] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
1146
1147                 case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
1148                 case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
1149                 case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
1150                 case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
1151                 case TEST_TYPE_INPUT_ATTACHMENTS:
1152                 case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY:
1153                 case TEST_TYPE_DRAW_INDIRECT:
1154                 case TEST_TYPE_CLEAR_ATTACHMENTS:
1155                 case TEST_TYPE_SECONDARY_CMD_BUFFER:
1156                 case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY:
1157                         return m_vertexColor[colorNdx] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
1158
1159                 case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR:
1160                         if (background)
1161                                 return m_colorTable[4 + quarterNdx % 4];
1162                         else
1163                                 return m_colorTable[layerNdx % 4];
1164
1165                 case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR:
1166                         if (background)
1167                                 return m_colorTable[4 + quarterNdx % 4];
1168                         else
1169                                 return m_colorTable[0];
1170
1171                 case TEST_TYPE_POINT_SIZE:
1172                 case TEST_TYPE_MULTISAMPLE:
1173                         if (background)
1174                                 return tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
1175                         else
1176                                 return m_vertexColor[colorNdx];
1177
1178                 case TEST_TYPE_DEPTH:
1179                         if (background)
1180                                 if (subpassNdx < 4)
1181                                         return tcu::Vec4(0.66f, 0.0f, 0.0f, 1.0f);
1182                                 else
1183                                         return tcu::Vec4(0.33f, 0.0f, 0.0f, 1.0f);
1184                         else
1185                                 return tcu::Vec4(0.99f, 0.0f, 0.0f, 1.0f);
1186
1187                 case TEST_TYPE_STENCIL:
1188                         if (background)
1189                                 return tcu::Vec4(0.33f, 0.0f, 0.0f, 0.0f); // Increment value
1190                         else
1191                                 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1192
1193                 default:
1194                         TCU_THROW(InternalError, "Impossible");
1195         }
1196 }
1197
1198 void MultiViewRenderTestInstance::setPoint (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& pointColor, const int pointSize, const int layerNdx, const deUint32 quarter)
1199 {
1200         DE_ASSERT(TEST_POINT_SIZE_WIDE > TEST_POINT_SIZE_SMALL);
1201
1202         const int       pointOffset     = 1 + TEST_POINT_SIZE_WIDE / 2 - (pointSize + 1) / 2;
1203         const int       offsetX         = pointOffset + static_cast<int>((quarter == 0u || quarter == 1u) ? 0 : m_parameters.extent.width / 2u);
1204         const int       offsetY         = pointOffset + static_cast<int>((quarter == 0u || quarter == 2u) ? 0 : m_parameters.extent.height / 2u);
1205
1206         for (int y = 0; y < pointSize; ++y)
1207         for (int x = 0; x < pointSize; ++x)
1208                 pixelBuffer.setPixel(pointColor, offsetX + x, offsetY + y, layerNdx);
1209 }
1210
1211 void MultiViewRenderTestInstance::fillTriangle (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter)
1212 {
1213         const int               offsetX                         = static_cast<int>((quarter == 0u || quarter == 1u) ? 0 : m_parameters.extent.width / 2u);
1214         const int               offsetY                         = static_cast<int>((quarter == 0u || quarter == 2u) ? 0 : m_parameters.extent.height / 2u);
1215         const int               maxY                            = static_cast<int>(m_parameters.extent.height / 2u);
1216         const tcu::Vec4 multisampledColor       = tcu::Vec4(color[0], color[1], color[2], color[3]) * 0.5f;
1217
1218         for (int y = 0; y < maxY; ++y)
1219         {
1220                 for (int x = 0; x < y; ++x)
1221                         pixelBuffer.setPixel(color, offsetX + x, offsetY + (maxY - 1) - y, layerNdx);
1222
1223                 // Multisampled pixel is on the triangle margin
1224                 pixelBuffer.setPixel(multisampledColor, offsetX + y, offsetY + (maxY - 1) - y, layerNdx);
1225         }
1226 }
1227
1228 void MultiViewRenderTestInstance::fillLayer (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx)
1229 {
1230         for (deUint32 y = 0u; y < m_parameters.extent.height; ++y)
1231         for (deUint32 x = 0u; x < m_parameters.extent.width; ++x)
1232                 pixelBuffer.setPixel(color, x, y, layerNdx);
1233 }
1234
1235 void MultiViewRenderTestInstance::fillQuarter (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter, const deUint32 subpassNdx)
1236 {
1237         const int h             = m_parameters.extent.height;
1238         const int h2    = h / 2;
1239         const int w             = m_parameters.extent.width;
1240         const int w2    = w / 2;
1241         int xStart              = 0;
1242         int xEnd                = 0;
1243         int yStart              = 0;
1244         int yEnd                = 0;
1245
1246         switch (quarter)
1247         {
1248                 case 0: xStart = 0u; xEnd = w2; yStart = 0u; yEnd = h2; break;
1249                 case 1: xStart = 0u; xEnd = w2; yStart = h2; yEnd = h;  break;
1250                 case 2: xStart = w2; xEnd = w;  yStart = 0u; yEnd = h2; break;
1251                 case 3: xStart = w2; xEnd = w;  yStart = h2; yEnd = h;  break;
1252                 default: TCU_THROW(InternalError, "Impossible");
1253         }
1254
1255         if (TEST_TYPE_STENCIL == m_parameters.viewIndex || TEST_TYPE_DEPTH == m_parameters.viewIndex)
1256         {
1257                 if (subpassNdx < 4)
1258                 {       // Part A: Horizontal bars near X axis
1259                         yStart  = h2 + (yStart - h2) / 2;
1260                         yEnd    = h2 + (yEnd - h2) / 2;
1261                 }
1262                 else
1263                 {       // Part B: Vertical bars near Y axis (drawn twice)
1264                         xStart  = w2 + (xStart - w2) / 2;
1265                         xEnd    = w2 + (xEnd - w2) / 2;
1266                 }
1267
1268                 // Update pixels in area
1269                 if (TEST_TYPE_STENCIL == m_parameters.viewIndex)
1270                 {
1271                         for (int y = yStart; y < yEnd; ++y)
1272                         for (int x = xStart; x < xEnd; ++x)
1273                                 pixelBuffer.setPixel(pixelBuffer.getPixel(x, y, layerNdx) + color, x, y, layerNdx);
1274                 }
1275
1276                 if (TEST_TYPE_DEPTH == m_parameters.viewIndex)
1277                 {
1278                         for (int y = yStart; y < yEnd; ++y)
1279                         for (int x = xStart; x < xEnd; ++x)
1280                         {
1281                                 const tcu::Vec4         currentColor    = pixelBuffer.getPixel(x, y, layerNdx);
1282                                 const tcu::Vec4&        newColor                = (currentColor[0] < color[0]) ? currentColor : color;
1283
1284                                 pixelBuffer.setPixel(newColor, x, y, layerNdx);
1285                         }
1286                 }
1287         }
1288         else
1289         {
1290                 for (int y = yStart; y < yEnd; ++y)
1291                 for (int x = xStart; x < xEnd; ++x)
1292                         pixelBuffer.setPixel(color , x, y, layerNdx);
1293         }
1294 }
1295
1296 MovePtr<tcu::Texture2DArray> MultiViewRenderTestInstance::imageData (void)
1297 {
1298         MovePtr<tcu::Texture2DArray>    referenceFrame  = MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth));
1299         const deUint32                                  subpassCount    = static_cast<deUint32>(m_parameters.viewMasks.size());
1300         referenceFrame->allocLevel(0);
1301
1302         deMemset (referenceFrame->getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_parameters.colorFormat).getPixelSize());
1303
1304         if (TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR == m_parameters.viewIndex || TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR == m_parameters.viewIndex)
1305         {
1306                 deUint32        clearedViewMask = 0;
1307
1308                 // Start from last clear command color, which actually takes effect
1309                 for (int subpassNdx = static_cast<int>(subpassCount) - 1; subpassNdx >= 0; --subpassNdx)
1310                 {
1311                         deUint32        subpassToClearViewMask  = m_parameters.viewMasks[subpassNdx] & ~clearedViewMask;
1312
1313                         if (subpassToClearViewMask == 0)
1314                                 continue;
1315
1316                         for (deUint32 layerNdx = 0; layerNdx < m_parameters.extent.depth; ++layerNdx)
1317                                 if ((subpassToClearViewMask & (1 << layerNdx)) != 0 && (clearedViewMask & (1 << layerNdx)) == 0)
1318                                         fillLayer(referenceFrame->getLevel(0), getQuarterRefColor(0u, 0u, subpassNdx, false), layerNdx);
1319
1320                         // These has been cleared. Exclude these layers from upcoming attempts to clear
1321                         clearedViewMask |= subpassToClearViewMask;
1322                 }
1323         }
1324
1325         if (TEST_TYPE_DEPTH == m_parameters.viewIndex || TEST_TYPE_STENCIL == m_parameters.viewIndex)
1326                 for (deUint32 layerNdx = 0; layerNdx < m_parameters.extent.depth; ++layerNdx)
1327                         fillLayer(referenceFrame->getLevel(0), getQuarterRefColor(0u, 0u, 0u, false), layerNdx);
1328
1329         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
1330         {
1331                 int                     layerNdx        = 0;
1332                 deUint32        mask            = m_parameters.viewMasks[subpassNdx];
1333
1334                 while (mask > 0u)
1335                 {
1336                         int colorNdx    = 0;
1337
1338                         if (mask & 1u)
1339                         {
1340                                 if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
1341                                 {
1342                                         struct ColorDataRGBA
1343                                         {
1344                                                 deUint8 r;
1345                                                 deUint8 g;
1346                                                 deUint8 b;
1347                                                 deUint8 a;
1348                                         };
1349
1350                                         ColorDataRGBA   clear           =
1351                                         {
1352                                                 tcu::floatToU8 (1.0f),
1353                                                 tcu::floatToU8 (0.0f),
1354                                                 tcu::floatToU8 (0.0f),
1355                                                 tcu::floatToU8 (1.0f)
1356                                         };
1357
1358                                         ColorDataRGBA*  dataSrc         = (ColorDataRGBA*)referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx);
1359                                         ColorDataRGBA*  dataDes         = dataSrc + 1;
1360                                         deUint32                copySize        = 1u;
1361                                         deUint32                layerSize       = m_parameters.extent.width * m_parameters.extent.height - copySize;
1362                                         deMemcpy(dataSrc, &clear, sizeof(ColorDataRGBA));
1363
1364                                         while (layerSize > 0)
1365                                         {
1366                                                 deMemcpy(dataDes, dataSrc, copySize * sizeof(ColorDataRGBA));
1367                                                 dataDes = dataDes + copySize;
1368                                                 layerSize = layerSize - copySize;
1369                                                 copySize = 2u * copySize;
1370                                                 if (copySize >= layerSize)
1371                                                         copySize = layerSize;
1372                                         }
1373                                 }
1374
1375                                 const deUint32 subpassQuarterNdx = subpassNdx % m_squareCount;
1376                                 if (subpassQuarterNdx == 0u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
1377                                 {
1378                                         const tcu::Vec4 color = getQuarterRefColor(0u, colorNdx, layerNdx, true, subpassNdx);
1379
1380                                         fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 0u, subpassNdx);
1381                                 }
1382
1383                                 colorNdx += 4;
1384                                 if (subpassQuarterNdx == 1u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
1385                                 {
1386                                         const tcu::Vec4 color = getQuarterRefColor(1u, colorNdx, layerNdx, true, subpassNdx);
1387
1388                                         fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 1u, subpassNdx);
1389                                 }
1390
1391                                 colorNdx += 4;
1392                                 if (subpassQuarterNdx == 2u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
1393                                 {
1394                                         const tcu::Vec4 color = getQuarterRefColor(2u, colorNdx, layerNdx, true, subpassNdx);
1395
1396                                         fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 2u, subpassNdx);
1397                                 }
1398
1399                                 colorNdx += 4;
1400                                 if (subpassQuarterNdx == 3u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
1401                                 {
1402                                         const tcu::Vec4 color = getQuarterRefColor(3u, colorNdx, layerNdx, true, subpassNdx);
1403
1404                                         fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 3u, subpassNdx);
1405                                 }
1406
1407                                 if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
1408                                 {
1409                                         const tcu::Vec4 color   (0.0f, 0.0f, 1.0f, 1.0f);
1410                                         const int               maxY    = static_cast<int>(static_cast<float>(m_parameters.extent.height) * 0.75f);
1411                                         const int               maxX    = static_cast<int>(static_cast<float>(m_parameters.extent.width) * 0.75f);
1412                                         for (int y = static_cast<int>(m_parameters.extent.height / 4u); y < maxY; ++y)
1413                                         for (int x = static_cast<int>(m_parameters.extent.width / 4u); x < maxX; ++x)
1414                                                 referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx);
1415                                 }
1416
1417                                 if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
1418                                 {
1419                                         const deUint32  vertexPerPrimitive      = 1u;
1420                                         const deUint32  unusedQuarterNdx        = 0u;
1421                                         const int               pointSize                       = static_cast<int>(layerNdx == 0u ? TEST_POINT_SIZE_WIDE : TEST_POINT_SIZE_SMALL);
1422
1423                                         if (subpassCount == 1)
1424                                                 for (deUint32 drawNdx = 0u; drawNdx < m_squareCount; ++drawNdx)
1425                                                         setPoint(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * drawNdx, layerNdx, false), pointSize, layerNdx, drawNdx);
1426                                         else
1427                                                 setPoint(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * subpassQuarterNdx, layerNdx, false), pointSize, layerNdx, subpassQuarterNdx);
1428                                 }
1429
1430                                 if (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex)
1431                                 {
1432                                         const deUint32  vertexPerPrimitive      = 3u;
1433                                         const deUint32  unusedQuarterNdx        = 0u;
1434
1435                                         if (subpassCount == 1)
1436                                                 for (deUint32 drawNdx = 0u; drawNdx < m_squareCount; ++drawNdx)
1437                                                         fillTriangle(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * drawNdx, layerNdx, false), layerNdx, drawNdx);
1438                                         else
1439                                                 fillTriangle(referenceFrame->getLevel(0), getQuarterRefColor(unusedQuarterNdx, vertexPerPrimitive * subpassQuarterNdx, layerNdx, false), layerNdx, subpassQuarterNdx);
1440                                 }
1441                         }
1442
1443                         mask = mask >> 1;
1444                         ++layerNdx;
1445                 }
1446         }
1447         return referenceFrame;
1448 }
1449
1450 void MultiViewRenderTestInstance::appendVertex (const tcu::Vec4& coord, const tcu::Vec4& color)
1451 {
1452         m_vertexCoord.push_back(coord);
1453         m_vertexColor.push_back(color);
1454 }
1455
1456 class MultiViewAttachmentsTestInstance : public MultiViewRenderTestInstance
1457 {
1458 public:
1459                                                 MultiViewAttachmentsTestInstance        (Context& context, const TestParameters& parameters);
1460 protected:
1461         tcu::TestStatus         iterate                                                         (void);
1462         void                            beforeDraw                                                      (void);
1463         void                            setImageData                                            (VkImage image);
1464         de::SharedPtr<ImageAttachment>  m_inputAttachment;
1465         Move<VkDescriptorPool>                  m_descriptorPool;
1466         Move<VkDescriptorSet>                   m_descriptorSet;
1467         Move<VkDescriptorSetLayout>             m_descriptorSetLayout;
1468         Move<VkPipelineLayout>                  m_pipelineLayout;
1469
1470 };
1471
1472 MultiViewAttachmentsTestInstance::MultiViewAttachmentsTestInstance (Context& context, const TestParameters& parameters)
1473         : MultiViewRenderTestInstance   (context, parameters)
1474 {
1475 }
1476
1477 tcu::TestStatus MultiViewAttachmentsTestInstance::iterate (void)
1478 {
1479         const deUint32                                                          subpassCount                    = static_cast<deUint32>(m_parameters.viewMasks.size());
1480         // All color attachment
1481         m_colorAttachment       = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat));
1482         m_inputAttachment       = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat));
1483
1484         // FrameBuffer & renderPass
1485         Unique<VkRenderPass>                                            renderPass                              (makeRenderPassWithAttachments(*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderPassType));
1486
1487         vector<VkImageView>                                                     attachments;
1488         attachments.push_back(m_colorAttachment->getImageView());
1489         attachments.push_back(m_inputAttachment->getImageView());
1490         Unique<VkFramebuffer>                                           frameBuffer                             (makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height));
1491
1492         // pipelineLayout
1493         m_descriptorSetLayout   = makeDescriptorSetLayout(*m_device, *m_logicalDevice);
1494         m_pipelineLayout                = makePipelineLayout(*m_device, *m_logicalDevice, m_descriptorSetLayout.get());
1495
1496         // pipelines
1497         map<VkShaderStageFlagBits, ShaderModuleSP>      shaderModule;
1498         vector<PipelineSp>                                                      pipelines(subpassCount);
1499
1500         {
1501                 vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
1502                 madeShaderModule(shaderModule, shaderStageParams);
1503                 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
1504                         pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *m_pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
1505         }
1506
1507         createVertexData();
1508         createVertexBuffer();
1509
1510         createCommandBuffer();
1511         setImageData(m_inputAttachment->getImage());
1512         draw(subpassCount, *renderPass, *frameBuffer, pipelines);
1513
1514         {
1515                 vector<deUint8>                 pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
1516                 tcu::PixelBufferAccess  dst                             (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
1517
1518                 readImage (m_colorAttachment->getImage(), dst);
1519                 if (!checkImage(dst))
1520                         return tcu::TestStatus::fail("Fail");
1521         }
1522
1523         return tcu::TestStatus::pass("Pass");
1524 }
1525
1526 void MultiViewAttachmentsTestInstance::beforeDraw (void)
1527 {
1528         const VkDescriptorPoolSize poolSize =
1529         {
1530                 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1531                 1u
1532         };
1533
1534         const VkDescriptorPoolCreateInfo createInfo =
1535         {
1536                 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1537                 DE_NULL,
1538                 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1539                 1u,
1540                 1u,
1541                 &poolSize
1542         };
1543
1544         m_descriptorPool = createDescriptorPool(*m_device, *m_logicalDevice, &createInfo);
1545
1546         const VkDescriptorSetAllocateInfo       allocateInfo =
1547         {
1548                 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1549                 DE_NULL,
1550                 *m_descriptorPool,
1551                 1u,
1552                 &m_descriptorSetLayout.get()
1553         };
1554
1555         m_descriptorSet = vk::allocateDescriptorSet(*m_device, *m_logicalDevice, &allocateInfo);
1556
1557         const VkDescriptorImageInfo     imageInfo =
1558         {
1559                 (VkSampler)0,
1560                 m_inputAttachment->getImageView(),
1561                 VK_IMAGE_LAYOUT_GENERAL
1562         };
1563
1564         const VkWriteDescriptorSet      write =
1565         {
1566                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, //VkStructureType                               sType;
1567                 DE_NULL,                                                                //const void*                                   pNext;
1568                 *m_descriptorSet,                                               //VkDescriptorSet                               dstSet;
1569                 0u,                                                                             //deUint32                                              dstBinding;
1570                 0u,                                                                             //deUint32                                              dstArrayElement;
1571                 1u,                                                                             //deUint32                                              descriptorCount;
1572                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,    //VkDescriptorType                              descriptorType;
1573                 &imageInfo,                                                             //const VkDescriptorImageInfo*  pImageInfo;
1574                 DE_NULL,                                                                //const VkDescriptorBufferInfo* pBufferInfo;
1575                 DE_NULL,                                                                //const VkBufferView*                   pTexelBufferView;
1576         };
1577
1578         m_device->updateDescriptorSets(*m_logicalDevice, (deUint32)1u, &write, 0u, DE_NULL);
1579
1580         const VkImageSubresourceRange   subresourceRange        =
1581         {
1582                 VK_IMAGE_ASPECT_COLOR_BIT,      //VkImageAspectFlags    aspectMask;
1583                 0u,                                                     //deUint32                              baseMipLevel;
1584                 1u,                                                     //deUint32                              levelCount;
1585                 0u,                                                     //deUint32                              baseArrayLayer;
1586                 m_parameters.extent.depth,      //deUint32                              layerCount;
1587         };
1588         m_device->cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, NULL);
1589
1590         imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
1591                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1592                 0, VK_ACCESS_TRANSFER_WRITE_BIT,
1593                 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1594
1595         const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
1596         m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange);
1597
1598         imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
1599                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1600                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1601                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1602 }
1603
1604 void MultiViewAttachmentsTestInstance::setImageData (VkImage image)
1605 {
1606         const MovePtr<tcu::Texture2DArray>              data            = imageData();
1607         Move<VkBuffer>                                  buffer;
1608         const deUint32                                  bufferSize      = m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * tcu::getPixelSize(mapVkFormat(m_parameters.colorFormat));
1609         MovePtr<Allocation>                             bufferAlloc;
1610
1611         // Create source buffer
1612         {
1613                 const VkBufferCreateInfo                bufferParams                    =
1614                 {
1615                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1616                         DE_NULL,                                                                        // const void*                  pNext;
1617                         0u,                                                                                     // VkBufferCreateFlags  flags;
1618                         bufferSize,                                                                     // VkDeviceSize                 size;
1619                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1620                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1621                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1622                         &m_queueFamilyIndex,                                            // const deUint32*              pQueueFamilyIndices;
1623                 };
1624
1625                 buffer          = createBuffer(*m_device, *m_logicalDevice, &bufferParams);
1626                 bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
1627                 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1628         }
1629
1630         // Barriers for copying buffer to image
1631         const VkBufferMemoryBarrier                             preBufferBarrier                =
1632         {
1633                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType      sType;
1634                 DE_NULL,                                                                                // const void*          pNext;
1635                 VK_ACCESS_HOST_WRITE_BIT,                                               // VkAccessFlags        srcAccessMask;
1636                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags        dstAccessMask;
1637                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     srcQueueFamilyIndex;
1638                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     dstQueueFamilyIndex;
1639                 *buffer,                                                                                // VkBuffer                     buffer;
1640                 0u,                                                                                             // VkDeviceSize         offset;
1641                 bufferSize                                                                              // VkDeviceSize         size;
1642         };
1643
1644         const VkImageAspectFlags                                formatAspect                    = getAspectFlags(mapVkFormat(m_parameters.colorFormat));
1645         VkImageSubresourceRange                                 subresourceRange                =
1646         {                                                                                               // VkImageSubresourceRange      subresourceRange;
1647                 formatAspect,                           // VkImageAspectFlags   aspect;
1648                 0u,                                                     // deUint32                             baseMipLevel;
1649                 1u,                                                     // deUint32                             mipLevels;
1650                 0u,                                                     // deUint32                             baseArraySlice;
1651                 m_parameters.extent.depth,      // deUint32                             arraySize;
1652         };
1653
1654         const VkBufferImageCopy                                 copyRegion                              =
1655         {
1656                 0u,                                                                                                                     // VkDeviceSize                         bufferOffset;
1657                 (deUint32)data->getLevel(0).getWidth(),                                         // deUint32                                     bufferRowLength;
1658                 (deUint32)data->getLevel(0).getHeight(),                                        // deUint32                                     bufferImageHeight;
1659                 {
1660                         VK_IMAGE_ASPECT_COLOR_BIT,                                                              // VkImageAspectFlags           aspect;
1661                         0u,                                                                                                             // deUint32                                     mipLevel;
1662                         0u,                                                                                                             // deUint32                                     baseArrayLayer;
1663                         m_parameters.extent.depth,                                                              // deUint32                                     layerCount;
1664                 },                                                                                                                      // VkImageSubresourceLayers     imageSubresource;
1665                 { 0, 0, 0 },                                                                                            // VkOffset3D                           imageOffset;
1666                 {m_parameters.extent.width, m_parameters.extent.height, 1u}     // VkExtent3D                           imageExtent;
1667         };
1668
1669         // Write buffer data
1670         deMemcpy(bufferAlloc->getHostPtr(), data->getLevel(0).getDataPtr(), bufferSize);
1671         flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
1672
1673         beginCommandBuffer(*m_device, *m_cmdBuffer);
1674
1675         m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1676         imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange,
1677                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1678                 0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1679                 VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1680         m_device->cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
1681         imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange,
1682                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1683                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
1684                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1685         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
1686
1687         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
1688 }
1689
1690 class MultiViewInstancedTestInstance : public MultiViewRenderTestInstance
1691 {
1692 public:
1693                                                 MultiViewInstancedTestInstance  (Context& context, const TestParameters& parameters);
1694 protected:
1695         void                            createVertexData                                (void);
1696         void                            draw                                                    (const deUint32                 subpassCount,
1697                                                                                                                  VkRenderPass                   renderPass,
1698                                                                                                                  VkFramebuffer                  frameBuffer,
1699                                                                                                                  vector<PipelineSp>&    pipelines);
1700 };
1701
1702 MultiViewInstancedTestInstance::MultiViewInstancedTestInstance (Context& context, const TestParameters& parameters)
1703         : MultiViewRenderTestInstance   (context, parameters)
1704 {
1705 }
1706
1707 void MultiViewInstancedTestInstance::createVertexData (void)
1708 {
1709         const tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
1710
1711         appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color);
1712         appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
1713         appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
1714         appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
1715 }
1716
1717 void MultiViewInstancedTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
1718 {
1719         const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
1720         const VkClearValue                              renderPassClearValue    = makeClearValueColor(tcu::Vec4(0.0f));
1721         const VkBuffer                                  vertexBuffers[]                 = { *m_vertexCoordBuffer, *m_vertexColorBuffer };
1722         const VkDeviceSize                              vertexBufferOffsets[]   = {                   0u,                   0u };
1723         const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
1724         const VkRenderPassBeginInfo             renderPassBeginInfo             =
1725         {
1726                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
1727                 DE_NULL,                                                                        // const void*                  pNext;
1728                 renderPass,                                                                     // VkRenderPass                 renderPass;
1729                 frameBuffer,                                                            // VkFramebuffer                framebuffer;
1730                 renderArea,                                                                     // VkRect2D                             renderArea;
1731                 1u,                                                                                     // uint32_t                             clearValueCount;
1732                 &renderPassClearValue,                                          // const VkClearValue*  pClearValues;
1733         };
1734
1735         beginCommandBuffer(*m_device, *m_cmdBuffer);
1736
1737         beforeDraw();
1738
1739         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
1740
1741         m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
1742
1743         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
1744         {
1745                 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
1746
1747                 m_device->cmdDraw(*m_cmdBuffer, 4u, drawCountPerSubpass, 0u, subpassNdx % m_squareCount);
1748
1749                 if (subpassNdx < subpassCount - 1u)
1750                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
1751         }
1752
1753         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
1754
1755         afterDraw();
1756
1757         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
1758         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
1759 }
1760
1761 class MultiViewInputRateInstanceTestInstance : public MultiViewRenderTestInstance
1762 {
1763 public:
1764                                 MultiViewInputRateInstanceTestInstance  (Context& context, const TestParameters& parameters);
1765 protected:
1766         void            createVertexData                                                (void);
1767
1768         void            draw                                                                    (const deUint32                 subpassCount,
1769                                                                                                                  VkRenderPass                   renderPass,
1770                                                                                                                  VkFramebuffer                  frameBuffer,
1771                                                                                                                  vector<PipelineSp>&    pipelines);
1772 };
1773
1774 MultiViewInputRateInstanceTestInstance::MultiViewInputRateInstanceTestInstance (Context& context, const TestParameters& parameters)
1775         : MultiViewRenderTestInstance   (context, parameters)
1776 {
1777 }
1778
1779 void MultiViewInputRateInstanceTestInstance::createVertexData (void)
1780 {
1781         appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f));
1782         appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f));
1783         appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f));
1784         appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f));
1785 }
1786
1787 void MultiViewInputRateInstanceTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
1788 {
1789         const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
1790         const VkClearValue                              renderPassClearValue    = makeClearValueColor(tcu::Vec4(0.0f));
1791         const VkBuffer                                  vertexBuffers[]                 = { *m_vertexCoordBuffer, *m_vertexColorBuffer };
1792         const VkDeviceSize                              vertexBufferOffsets[]   = {                   0u,                   0u };
1793         const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
1794         const VkRenderPassBeginInfo             renderPassBeginInfo             =
1795         {
1796                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
1797                 DE_NULL,                                                                        // const void*                  pNext;
1798                 renderPass,                                                                     // VkRenderPass                 renderPass;
1799                 frameBuffer,                                                            // VkFramebuffer                framebuffer;
1800                 renderArea,                                                                     // VkRect2D                             renderArea;
1801                 1u,                                                                                     // uint32_t                             clearValueCount;
1802                 &renderPassClearValue,                                          // const VkClearValue*  pClearValues;
1803         };
1804
1805         beginCommandBuffer(*m_device, *m_cmdBuffer);
1806
1807         beforeDraw();
1808
1809         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
1810
1811         m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
1812
1813         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
1814         {
1815                 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
1816
1817                 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
1818                         m_device->cmdDraw(*m_cmdBuffer, 4u, 4u, 0u, 0u);
1819
1820                 if (subpassNdx < subpassCount - 1u)
1821                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
1822         }
1823
1824         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
1825
1826         afterDraw();
1827
1828         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
1829         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
1830 }
1831
1832 class MultiViewDrawIndirectTestInstance : public MultiViewRenderTestInstance
1833 {
1834 public:
1835                                 MultiViewDrawIndirectTestInstance       (Context& context, const TestParameters& parameters);
1836 protected:
1837
1838         void            draw                                                            (const deUint32                 subpassCount,
1839                                                                                                          VkRenderPass                   renderPass,
1840                                                                                                          VkFramebuffer                  frameBuffer,
1841                                                                                                          vector<PipelineSp>&    pipelines);
1842 };
1843
1844 MultiViewDrawIndirectTestInstance::MultiViewDrawIndirectTestInstance (Context& context, const TestParameters& parameters)
1845         : MultiViewRenderTestInstance   (context, parameters)
1846 {
1847 }
1848
1849 void MultiViewDrawIndirectTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
1850 {
1851         typedef de::SharedPtr<Unique<VkBuffer> >                BufferSP;
1852         typedef de::SharedPtr<UniquePtr<Allocation> >   AllocationSP;
1853
1854         const size_t                                    nonCoherentAtomSize             = static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize);
1855         const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
1856         const VkClearValue                              renderPassClearValue    = makeClearValueColor(tcu::Vec4(0.0f));
1857         const VkBuffer                                  vertexBuffers[]                 = { *m_vertexCoordBuffer, *m_vertexColorBuffer };
1858         const VkDeviceSize                              vertexBufferOffsets[]   = {                   0u,                   0u };
1859         const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
1860         const deUint32                                  strideInBuffer                  = (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
1861                                                                                                                         ? static_cast<deUint32>(sizeof(vk::VkDrawIndexedIndirectCommand))
1862                                                                                                                         : static_cast<deUint32>(sizeof(vk::VkDrawIndirectCommand));
1863         vector< BufferSP >                              indirectBuffers                 (subpassCount);
1864         vector< AllocationSP >                  indirectAllocations             (subpassCount);
1865
1866         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
1867         {
1868                 vector<VkDrawIndirectCommand>                   drawCommands;
1869                 vector<VkDrawIndexedIndirectCommand>    drawCommandsIndexed;
1870
1871                 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
1872                 {
1873                         if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
1874                         {
1875                                 const VkDrawIndexedIndirectCommand      drawCommandIndexed      =
1876                                 {
1877                                         4u,                                                                                             //  deUint32    indexCount;
1878                                         1u,                                                                                             //  deUint32    instanceCount;
1879                                         (drawNdx + subpassNdx % m_squareCount) * 4u,    //  deUint32    firstIndex;
1880                                         0u,                                                                                             //  deInt32             vertexOffset;
1881                                         0u,                                                                                             //  deUint32    firstInstance;
1882                                 };
1883
1884                                 drawCommandsIndexed.push_back(drawCommandIndexed);
1885                         }
1886                         else
1887                         {
1888                                 const VkDrawIndirectCommand     drawCommand     =
1889                                 {
1890                                         4u,                                                                                             //  deUint32    vertexCount;
1891                                         1u,                                                                                             //  deUint32    instanceCount;
1892                                         (drawNdx + subpassNdx % m_squareCount) * 4u,    //  deUint32    firstVertex;
1893                                         0u                                                                                              //  deUint32    firstInstance;
1894                                 };
1895
1896                                 drawCommands.push_back(drawCommand);
1897                         }
1898                 }
1899
1900                 const size_t                            drawCommandsLength      = (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
1901                                                                                                                 ? drawCommandsIndexed.size()
1902                                                                                                                 : drawCommands.size();
1903                 const void*                                     drawCommandsDataPtr     = (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
1904                                                                                                                 ? (void*)&drawCommandsIndexed[0]
1905                                                                                                                 : (void*)&drawCommands[0];
1906                 const size_t                            dataSize                        = static_cast<size_t>(drawCommandsLength * strideInBuffer);
1907                 const VkDeviceSize                      bufferDataSize          = static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
1908                 const VkBufferCreateInfo        bufferInfo                      = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
1909                 Move<VkBuffer>                          indirectBuffer          = createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
1910                 MovePtr<Allocation>                     allocationBuffer        = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *indirectBuffer),  MemoryRequirement::HostVisible);
1911
1912                 DE_ASSERT(drawCommandsLength != 0);
1913
1914                 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *indirectBuffer, allocationBuffer->getMemory(), allocationBuffer->getOffset()));
1915
1916                 deMemcpy(allocationBuffer->getHostPtr(), drawCommandsDataPtr, static_cast<size_t>(dataSize));
1917
1918                 flushAlloc(*m_device, *m_logicalDevice, *allocationBuffer);
1919                 indirectBuffers[subpassNdx] = (BufferSP(new Unique<VkBuffer>(indirectBuffer)));
1920                 indirectAllocations[subpassNdx] = (AllocationSP(new UniquePtr<Allocation>(allocationBuffer)));
1921         }
1922
1923         const VkRenderPassBeginInfo             renderPassBeginInfo             =
1924         {
1925                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
1926                 DE_NULL,                                                                        // const void*                  pNext;
1927                 renderPass,                                                                     // VkRenderPass                 renderPass;
1928                 frameBuffer,                                                            // VkFramebuffer                framebuffer;
1929                 renderArea,                                                                     // VkRect2D                             renderArea;
1930                 1u,                                                                                     // uint32_t                             clearValueCount;
1931                 &renderPassClearValue,                                          // const VkClearValue*  pClearValues;
1932         };
1933
1934         beginCommandBuffer(*m_device, *m_cmdBuffer);
1935
1936         beforeDraw();
1937
1938         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
1939
1940         m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
1941
1942         if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
1943                 m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32);
1944
1945         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
1946         {
1947                 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
1948
1949                 if (m_hasMultiDrawIndirect)
1950                 {
1951                         if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
1952                                 m_device->cmdDrawIndexedIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer);
1953                         else
1954                                 m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer);
1955                 }
1956                 else
1957                 {
1958                         for (deUint32 drawNdx = 0; drawNdx < drawCountPerSubpass; drawNdx++)
1959                         {
1960                                 if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
1961                                         m_device->cmdDrawIndexedIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer);
1962                                 else
1963                                         m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer);
1964                         }
1965                 }
1966
1967                 if (subpassNdx < subpassCount - 1u)
1968                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
1969         }
1970
1971         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
1972
1973         afterDraw();
1974
1975         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
1976         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
1977 }
1978
1979 class MultiViewClearAttachmentsTestInstance : public MultiViewRenderTestInstance
1980 {
1981 public:
1982                                 MultiViewClearAttachmentsTestInstance   (Context& context, const TestParameters& parameters);
1983 protected:
1984         void            draw                                                                    (const deUint32                 subpassCount,
1985                                                                                                                  VkRenderPass                   renderPass,
1986                                                                                                                  VkFramebuffer                  frameBuffer,
1987                                                                                                                  vector<PipelineSp>&    pipelines);
1988 };
1989
1990 MultiViewClearAttachmentsTestInstance::MultiViewClearAttachmentsTestInstance (Context& context, const TestParameters& parameters)
1991         : MultiViewRenderTestInstance   (context, parameters)
1992 {
1993 }
1994
1995 void MultiViewClearAttachmentsTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
1996 {
1997         const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
1998         const VkClearValue                              renderPassClearValue    = makeClearValueColor(tcu::Vec4(0.0f));
1999         const VkBuffer                                  vertexBuffers[]                 = { *m_vertexCoordBuffer, *m_vertexColorBuffer };
2000         const VkDeviceSize                              vertexBufferOffsets[]   = {                   0u,                   0u };
2001         const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
2002
2003         const VkRenderPassBeginInfo             renderPassBeginInfo             =
2004         {
2005                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
2006                 DE_NULL,                                                                        // const void*                  pNext;
2007                 renderPass,                                                                     // VkRenderPass                 renderPass;
2008                 frameBuffer,                                                            // VkFramebuffer                framebuffer;
2009                 renderArea,                                                                     // VkRect2D                             renderArea;
2010                 1u,                                                                                     // uint32_t                             clearValueCount;
2011                 &renderPassClearValue,                                          // const VkClearValue*  pClearValues;
2012         };
2013
2014         beginCommandBuffer(*m_device, *m_cmdBuffer);
2015
2016         beforeDraw();
2017
2018         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
2019
2020         m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2021
2022         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2023         {
2024                 VkClearAttachment       clearAttachment =
2025                 {
2026                         VK_IMAGE_ASPECT_COLOR_BIT,                                                              // VkImageAspectFlags   aspectMask
2027                         0u,                                                                                                             // deUint32                             colorAttachment
2028                         makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f))  // VkClearValue                 clearValue
2029                 };
2030
2031                 const VkOffset2D        offset[2]               =
2032                 {
2033                         {0, 0},
2034                         {static_cast<deInt32>(static_cast<float>(m_parameters.extent.width) * 0.25f), static_cast<deInt32>(static_cast<float>(m_parameters.extent.height) * 0.25f)}
2035                 };
2036
2037                 const VkExtent2D        extent[2]               =
2038                 {
2039                         {m_parameters.extent.width, m_parameters.extent.height},
2040                         {static_cast<deUint32>(static_cast<float>(m_parameters.extent.width) * 0.5f), static_cast<deUint32>(static_cast<float>(m_parameters.extent.height) * 0.5f)}
2041                 };
2042
2043                 const VkRect2D          rect2D[2]               =
2044                 {
2045                         {offset[0], extent[0]},
2046                         {offset[1], extent[1]}
2047                 };
2048
2049                 VkClearRect                     clearRect               =
2050                 {
2051                         rect2D[0],      // VkRect2D     rect
2052                         0u,                     // deUint32     baseArrayLayer
2053                         1u,                     // deUint32     layerCount
2054                 };
2055
2056                 m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect);
2057                 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2058
2059                 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2060                         m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
2061
2062                 clearRect.rect = rect2D[1];
2063                 clearAttachment.clearValue = makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
2064                 m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect);
2065
2066                 if (subpassNdx < subpassCount - 1u)
2067                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
2068         }
2069
2070         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
2071
2072         afterDraw();
2073
2074         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2075         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2076 }
2077
2078 class MultiViewSecondaryCommandBufferTestInstance : public MultiViewRenderTestInstance
2079 {
2080 public:
2081                                 MultiViewSecondaryCommandBufferTestInstance     (Context& context, const TestParameters& parameters);
2082 protected:
2083         void            draw                                                                            (const deUint32                 subpassCount,
2084                                                                                                                          VkRenderPass                   renderPass,
2085                                                                                                                          VkFramebuffer                  frameBuffer,
2086                                                                                                                          vector<PipelineSp>&    pipelines);
2087 };
2088
2089 MultiViewSecondaryCommandBufferTestInstance::MultiViewSecondaryCommandBufferTestInstance (Context& context, const TestParameters& parameters)
2090         : MultiViewRenderTestInstance   (context, parameters)
2091 {
2092 }
2093
2094 void MultiViewSecondaryCommandBufferTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
2095 {
2096         typedef de::SharedPtr<Unique<VkCommandBuffer> > VkCommandBufferSp;
2097
2098         const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
2099         const VkClearValue                              renderPassClearValue    = makeClearValueColor(tcu::Vec4(0.0f));
2100         const VkBuffer                                  vertexBuffers[]                 = { *m_vertexCoordBuffer, *m_vertexColorBuffer };
2101         const VkDeviceSize                              vertexBufferOffsets[]   = {                   0u,                   0u };
2102         const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
2103         const VkRenderPassBeginInfo             renderPassBeginInfo             =
2104         {
2105                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
2106                 DE_NULL,                                                                        // const void*                  pNext;
2107                 renderPass,                                                                     // VkRenderPass                 renderPass;
2108                 frameBuffer,                                                            // VkFramebuffer                framebuffer;
2109                 renderArea,                                                                     // VkRect2D                             renderArea;
2110                 1u,                                                                                     // uint32_t                             clearValueCount;
2111                 &renderPassClearValue,                                          // const VkClearValue*  pClearValues;
2112         };
2113
2114         beginCommandBuffer(*m_device, *m_cmdBuffer);
2115
2116         beforeDraw();
2117
2118         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, m_parameters.renderPassType);
2119
2120         //Create secondary buffer
2121         const VkCommandBufferAllocateInfo       cmdBufferAllocateInfo   =
2122         {
2123                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
2124                 DE_NULL,                                                                                // const void*                          pNext;
2125                 *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
2126                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                              // VkCommandBufferLevel         level;
2127                 1u,                                                                                             // deUint32                                     bufferCount;
2128         };
2129         vector<VkCommandBufferSp>       cmdBufferSecondary;
2130
2131         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2132         {
2133                 cmdBufferSecondary.push_back(VkCommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo))));
2134
2135                 beginSecondaryCommandBuffer(*m_device, cmdBufferSecondary.back().get()->get(), renderPass, subpassNdx, frameBuffer);
2136                 m_device->cmdBindVertexBuffers(cmdBufferSecondary.back().get()->get(), 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2137                 m_device->cmdBindPipeline(cmdBufferSecondary.back().get()->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2138
2139                 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2140                         m_device->cmdDraw(cmdBufferSecondary.back().get()->get(), 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
2141
2142                 VK_CHECK(m_device->endCommandBuffer(cmdBufferSecondary.back().get()->get()));
2143
2144                 m_device->cmdExecuteCommands(*m_cmdBuffer, 1u, &cmdBufferSecondary.back().get()->get());
2145                 if (subpassNdx < subpassCount - 1u)
2146                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, m_parameters.renderPassType);
2147         }
2148
2149         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
2150
2151         afterDraw();
2152
2153         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2154         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2155 }
2156
2157 class MultiViewPointSizeTestInstance : public MultiViewRenderTestInstance
2158 {
2159 public:
2160                                 MultiViewPointSizeTestInstance  (Context& context, const TestParameters& parameters);
2161 protected:
2162         void            validatePointSize                               (const VkPhysicalDeviceLimits& limits, const deUint32 pointSize);
2163         void            createVertexData                                (void);
2164         void            draw                                                    (const deUint32                 subpassCount,
2165                                                                                                  VkRenderPass                   renderPass,
2166                                                                                                  VkFramebuffer                  frameBuffer,
2167                                                                                                  vector<PipelineSp>&    pipelines);
2168 };
2169
2170 MultiViewPointSizeTestInstance::MultiViewPointSizeTestInstance (Context& context, const TestParameters& parameters)
2171         : MultiViewRenderTestInstance   (context, parameters)
2172 {
2173         const InstanceInterface&                vki                                     = m_context.getInstanceInterface();
2174         const VkPhysicalDevice                  physDevice                      = m_context.getPhysicalDevice();
2175         const VkPhysicalDeviceLimits    limits                          = getPhysicalDeviceProperties(vki, physDevice).limits;
2176
2177         validatePointSize(limits, static_cast<deUint32>(TEST_POINT_SIZE_WIDE));
2178         validatePointSize(limits, static_cast<deUint32>(TEST_POINT_SIZE_SMALL));
2179 }
2180
2181 void MultiViewPointSizeTestInstance::validatePointSize (const VkPhysicalDeviceLimits& limits, const deUint32 pointSize)
2182 {
2183         const float     testPointSizeFloat      = static_cast<float>(pointSize);
2184         float           granuleCount            = 0.0f;
2185
2186         if (!de::inRange(testPointSizeFloat, limits.pointSizeRange[0], limits.pointSizeRange[1]))
2187                 TCU_THROW(NotSupportedError, "Required point size is outside of the the limits range");
2188
2189         granuleCount = static_cast<float>(deCeilFloatToInt32((testPointSizeFloat - limits.pointSizeRange[0]) / limits.pointSizeGranularity));
2190
2191         if (limits.pointSizeRange[0] + granuleCount * limits.pointSizeGranularity != testPointSizeFloat)
2192                 TCU_THROW(NotSupportedError, "Granuliraty does not allow to get required point size");
2193
2194         DE_ASSERT(pointSize + 1 <= m_parameters.extent.width / 2);
2195         DE_ASSERT(pointSize + 1 <= m_parameters.extent.height / 2);
2196 }
2197
2198 void MultiViewPointSizeTestInstance::createVertexData (void)
2199 {
2200         const float             pixelStepX      = 2.0f / static_cast<float>(m_parameters.extent.width);
2201         const float             pixelStepY      = 2.0f / static_cast<float>(m_parameters.extent.height);
2202         const int               pointMargin     = 1 + TEST_POINT_SIZE_WIDE / 2;
2203
2204         appendVertex(tcu::Vec4(-1.0f + pointMargin * pixelStepX,-1.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
2205         appendVertex(tcu::Vec4(-1.0f + pointMargin * pixelStepX, 0.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
2206         appendVertex(tcu::Vec4( 0.0f + pointMargin * pixelStepX,-1.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
2207         appendVertex(tcu::Vec4( 0.0f + pointMargin * pixelStepX, 0.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.5f, 0.3f, 1.0f));
2208 }
2209
2210 void MultiViewPointSizeTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
2211 {
2212         const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
2213         const VkClearValue                              renderPassClearValue    = makeClearValueColor(tcu::Vec4(0.0f));
2214         const VkBuffer                                  vertexBuffers[]                 = { *m_vertexCoordBuffer, *m_vertexColorBuffer };
2215         const VkDeviceSize                              vertexBufferOffsets[]   = {                   0u,                   0u };
2216         const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
2217
2218         const VkRenderPassBeginInfo             renderPassBeginInfo             =
2219         {
2220                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
2221                 DE_NULL,                                                                        // const void*                  pNext;
2222                 renderPass,                                                                     // VkRenderPass                 renderPass;
2223                 frameBuffer,                                                            // VkFramebuffer                framebuffer;
2224                 renderArea,                                                                     // VkRect2D                             renderArea;
2225                 1u,                                                                                     // uint32_t                             clearValueCount;
2226                 &renderPassClearValue,                                          // const VkClearValue*  pClearValues;
2227         };
2228
2229         beginCommandBuffer(*m_device, *m_cmdBuffer);
2230
2231         beforeDraw();
2232
2233         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
2234
2235         m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2236
2237         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2238         {
2239                 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2240
2241                 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2242                         m_device->cmdDraw(*m_cmdBuffer, 1u, 1u, drawNdx + subpassNdx % m_squareCount, 0u);
2243
2244                 if (subpassNdx < subpassCount - 1u)
2245                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
2246         }
2247
2248         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
2249
2250         afterDraw();
2251
2252         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2253         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2254 }
2255
2256 class MultiViewMultsampleTestInstance : public MultiViewRenderTestInstance
2257 {
2258 public:
2259                                         MultiViewMultsampleTestInstance (Context& context, const TestParameters& parameters);
2260 protected:
2261         tcu::TestStatus iterate                                                 (void);
2262         void                    createVertexData                                (void);
2263
2264         void                    draw                                                    (const deUint32                 subpassCount,
2265                                                                                                          VkRenderPass                   renderPass,
2266                                                                                                          VkFramebuffer                  frameBuffer,
2267                                                                                                          vector<PipelineSp>&    pipelines);
2268         void                    afterDraw                                               (void);
2269 private:
2270         de::SharedPtr<ImageAttachment>  m_resolveAttachment;
2271 };
2272
2273 MultiViewMultsampleTestInstance::MultiViewMultsampleTestInstance (Context& context, const TestParameters& parameters)
2274         : MultiViewRenderTestInstance   (context, parameters)
2275 {
2276         // Color attachment
2277         m_resolveAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, VK_SAMPLE_COUNT_1_BIT));
2278 }
2279
2280 tcu::TestStatus MultiViewMultsampleTestInstance::iterate (void)
2281 {
2282         const deUint32                                                          subpassCount                            = static_cast<deUint32>(m_parameters.viewMasks.size());
2283
2284         // FrameBuffer & renderPass
2285         Unique<VkRenderPass>                                            renderPass                                      (makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderPassType, VK_SAMPLE_COUNT_4_BIT));
2286
2287         Unique<VkFramebuffer>                                           frameBuffer                                     (makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height));
2288
2289         // pipelineLayout
2290         Unique<VkPipelineLayout>                                        pipelineLayout                          (makePipelineLayout(*m_device, *m_logicalDevice));
2291
2292         // pipelines
2293         map<VkShaderStageFlagBits, ShaderModuleSP>      shaderModule;
2294         vector<PipelineSp>                                                      pipelines(subpassCount);
2295         const VkVertexInputRate                                         vertexInputRate                         = (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
2296
2297         {
2298                 vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
2299                 madeShaderModule(shaderModule, shaderStageParams);
2300                 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
2301                         pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate))));
2302         }
2303
2304         createCommandBuffer();
2305         createVertexData();
2306         createVertexBuffer();
2307
2308         draw(subpassCount, *renderPass, *frameBuffer, pipelines);
2309
2310         {
2311                 vector<deUint8>                 pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
2312                 tcu::PixelBufferAccess  dst                             (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
2313
2314                 readImage(m_resolveAttachment->getImage(), dst);
2315
2316                 if (!checkImage(dst))
2317                         return tcu::TestStatus::fail("Fail");
2318         }
2319
2320         return tcu::TestStatus::pass("Pass");
2321 }
2322
2323 void MultiViewMultsampleTestInstance::createVertexData (void)
2324 {
2325         tcu::Vec4       color   = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
2326
2327         color   = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2328         appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
2329         appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color);
2330         appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
2331
2332         color   = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2333         appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color);
2334         appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
2335         appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
2336
2337         color   = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2338         appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
2339         appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
2340         appendVertex(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color);
2341
2342         color   = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2343         appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);
2344         appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
2345         appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);
2346 }
2347
2348 void MultiViewMultsampleTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
2349 {
2350         const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
2351         const VkClearValue                              renderPassClearValue    = makeClearValueColor(tcu::Vec4(0.0f));
2352         const VkBuffer                                  vertexBuffers[]                 = { *m_vertexCoordBuffer, *m_vertexColorBuffer };
2353         const VkDeviceSize                              vertexBufferOffsets[]   = {                   0u,                   0u };
2354         const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
2355         const deUint32                                  vertexPerPrimitive              = 3u;
2356         const VkImageSubresourceLayers  subresourceLayer                =
2357         {
2358                 VK_IMAGE_ASPECT_COLOR_BIT,      //  VkImageAspectFlags  aspectMask;
2359                 0u,                                                     //  deUint32                    mipLevel;
2360                 0u,                                                     //  deUint32                    baseArrayLayer;
2361                 m_parameters.extent.depth,      //  deUint32                    layerCount;
2362         };
2363         const VkImageResolve                    imageResolveRegion              =
2364         {
2365                 subresourceLayer,                                                                                                                       //  VkImageSubresourceLayers    srcSubresource;
2366                 makeOffset3D(0, 0, 0),                                                                                                          //  VkOffset3D                                  srcOffset;
2367                 subresourceLayer,                                                                                                                       //  VkImageSubresourceLayers    dstSubresource;
2368                 makeOffset3D(0, 0, 0),                                                                                                          //  VkOffset3D                                  dstOffset;
2369                 makeExtent3D(m_parameters.extent.width, m_parameters.extent.height, 1u),        //  VkExtent3D                                  extent;
2370         };
2371
2372         const VkRenderPassBeginInfo             renderPassBeginInfo             =
2373         {
2374                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
2375                 DE_NULL,                                                                        // const void*                  pNext;
2376                 renderPass,                                                                     // VkRenderPass                 renderPass;
2377                 frameBuffer,                                                            // VkFramebuffer                framebuffer;
2378                 renderArea,                                                                     // VkRect2D                             renderArea;
2379                 1u,                                                                                     // uint32_t                             clearValueCount;
2380                 &renderPassClearValue,                                          // const VkClearValue*  pClearValues;
2381         };
2382
2383         beginCommandBuffer(*m_device, *m_cmdBuffer);
2384
2385         beforeDraw();
2386
2387         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
2388
2389         m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2390
2391         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2392         {
2393                 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2394
2395                 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2396                         m_device->cmdDraw(*m_cmdBuffer, vertexPerPrimitive, 1u, (drawNdx + subpassNdx % m_squareCount) * vertexPerPrimitive, 0u);
2397
2398                 if (subpassNdx < subpassCount - 1u)
2399                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
2400         }
2401
2402         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
2403
2404         afterDraw();
2405
2406         m_device->cmdResolveImage(*m_cmdBuffer, m_colorAttachment->getImage(), VK_IMAGE_LAYOUT_GENERAL, m_resolveAttachment->getImage(), VK_IMAGE_LAYOUT_GENERAL, 1u, &imageResolveRegion);
2407
2408         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2409         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2410 }
2411
2412 void MultiViewMultsampleTestInstance::afterDraw (void)
2413 {
2414         const VkImageSubresourceRange   subresourceRange                =
2415         {
2416                 VK_IMAGE_ASPECT_COLOR_BIT,      //  VkImageAspectFlags  aspectMask;
2417                 0u,                                                     //  deUint32                    baseMipLevel;
2418                 1u,                                                     //  deUint32                    levelCount;
2419                 0u,                                                     //  deUint32                    baseArrayLayer;
2420                 m_parameters.extent.depth,      //  deUint32                    layerCount;
2421         };
2422
2423         imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
2424                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2425                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2426                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2427
2428         imageBarrier(*m_device, *m_cmdBuffer, m_resolveAttachment->getImage(), subresourceRange,
2429                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
2430                 0u, VK_ACCESS_TRANSFER_WRITE_BIT,
2431                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2432 }
2433
2434 class MultiViewQueriesTestInstance : public MultiViewRenderTestInstance
2435 {
2436 public:
2437                                                 MultiViewQueriesTestInstance    (Context& context, const TestParameters& parameters);
2438 protected:
2439         tcu::TestStatus         iterate                                                 (void);
2440         void                            createVertexData                                (void);
2441
2442         void                            draw                                                    (const deUint32                 subpassCount,
2443                                                                                                                  VkRenderPass                   renderPass,
2444                                                                                                                  VkFramebuffer                  frameBuffer,
2445                                                                                                                  vector<PipelineSp>&    pipelines);
2446         deUint32                        getUsedViewsCount                               (const deUint32                 viewMaskIndex);
2447         deUint32                        getQueryCountersNumber                  ();
2448 private:
2449         const deUint32                          m_verticesPerPrimitive;
2450         const VkQueryControlFlags       m_occlusionQueryFlags;
2451         deUint64                                        m_timestampMask;
2452         vector<deUint64>                        m_timestampStartValues;
2453         vector<deUint64>                        m_timestampEndValues;
2454         vector<deBool>                          m_counterSeriesStart;
2455         vector<deBool>                          m_counterSeriesEnd;
2456         vector<deUint64>                        m_occlusionValues;
2457         vector<deUint64>                        m_occlusionExpectedValues;
2458         deUint32                                        m_occlusionObjectsOffset;
2459         vector<deUint64>                        m_occlusionObjectPixelsCount;
2460 };
2461
2462 MultiViewQueriesTestInstance::MultiViewQueriesTestInstance (Context& context, const TestParameters& parameters)
2463         : MultiViewRenderTestInstance   (context, parameters)
2464         , m_verticesPerPrimitive                (4u)
2465         , m_occlusionQueryFlags                 ((parameters.viewIndex == TEST_TYPE_QUERIES) * VK_QUERY_CONTROL_PRECISE_BIT)
2466 {
2467         // Generate the timestamp mask
2468         const std::vector<VkQueueFamilyProperties>      queueProperties = vk::getPhysicalDeviceQueueFamilyProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
2469
2470         if(queueProperties[0].timestampValidBits == 0)
2471                 TCU_THROW(NotSupportedError, "Device does not support timestamp.");
2472
2473         m_timestampMask = 0xFFFFFFFFFFFFFFFFull >> (64 - queueProperties[0].timestampValidBits);
2474 }
2475
2476 tcu::TestStatus MultiViewQueriesTestInstance::iterate (void)
2477 {
2478         const deUint32                                                          subpassCount                    = static_cast<deUint32>(m_parameters.viewMasks.size());
2479         Unique<VkRenderPass>                                            renderPass                              (makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderPassType));
2480         Unique<VkFramebuffer>                                           frameBuffer                             (makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height));
2481         Unique<VkPipelineLayout>                                        pipelineLayout                  (makePipelineLayout(*m_device, *m_logicalDevice));
2482         vector<PipelineSp>                                                      pipelines                               (subpassCount);
2483         deUint64                                                                        occlusionValue                  = 0;
2484         deUint64                                                                        occlusionExpectedValue  = 0;
2485         map<VkShaderStageFlagBits, ShaderModuleSP>      shaderModule;
2486
2487         {
2488                 vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
2489
2490                 madeShaderModule(shaderModule, shaderStageParams);
2491                 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
2492                         pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
2493         }
2494
2495         createCommandBuffer();
2496         createVertexData();
2497         createVertexBuffer();
2498
2499         draw(subpassCount, *renderPass, *frameBuffer, pipelines);
2500
2501         DE_ASSERT(!m_occlusionValues.empty());
2502         DE_ASSERT(m_occlusionValues.size() == m_occlusionExpectedValues.size());
2503         DE_ASSERT(m_occlusionValues.size() == m_counterSeriesEnd.size());
2504         for (size_t ndx = 0; ndx < m_counterSeriesEnd.size(); ++ndx)
2505         {
2506                 occlusionValue                  += m_occlusionValues[ndx];
2507                 occlusionExpectedValue  += m_occlusionExpectedValues[ndx];
2508
2509                 if (m_counterSeriesEnd[ndx])
2510                 {
2511                         if (m_parameters.viewIndex == TEST_TYPE_QUERIES)
2512                         {
2513                                 if (occlusionExpectedValue != occlusionValue)
2514                                         return tcu::TestStatus::fail("occlusion, result:" + de::toString(occlusionValue) + ", expected:" + de::toString(occlusionExpectedValue));
2515                         }
2516                         else // verify non precise occlusion query
2517                         {
2518                                 if (occlusionValue == 0)
2519                                         return tcu::TestStatus::fail("occlusion, result: 0, expected non zero value");
2520                         }
2521                 }
2522         }
2523
2524         DE_ASSERT(!m_timestampStartValues.empty());
2525         DE_ASSERT(m_timestampStartValues.size() == m_timestampEndValues.size());
2526         DE_ASSERT(m_timestampStartValues.size() == m_counterSeriesStart.size());
2527         for (size_t ndx = 0; ndx < m_timestampStartValues.size(); ++ndx)
2528         {
2529                 if (m_counterSeriesStart[ndx])
2530                 {
2531                         if (m_timestampEndValues[ndx] > 0 && m_timestampEndValues[ndx] >= m_timestampStartValues[ndx])
2532                                 continue;
2533                 }
2534                 else
2535                 {
2536                         if (m_timestampEndValues[ndx] > 0 && m_timestampEndValues[ndx] >= m_timestampStartValues[ndx])
2537                                 continue;
2538
2539                         if (m_timestampEndValues[ndx] == 0 && m_timestampStartValues[ndx] == 0)
2540                                 continue;
2541                 }
2542
2543                 return tcu::TestStatus::fail("timestamp");
2544         }
2545
2546         return tcu::TestStatus::pass("Pass");
2547 }
2548
2549 void MultiViewQueriesTestInstance::createVertexData (void)
2550 {
2551         tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
2552
2553         appendVertex(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), color);
2554         appendVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), color);
2555         appendVertex(tcu::Vec4( 0.0f,-1.0f, 0.0f, 1.0f), color);
2556         appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
2557
2558         color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
2559         appendVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), color);
2560         appendVertex(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), color);
2561         appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
2562         appendVertex(tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f), color);
2563
2564         color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
2565         appendVertex(tcu::Vec4( 0.0f,-1.0f, 0.0f, 1.0f), color);
2566         appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
2567         appendVertex(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), color);
2568         appendVertex(tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f), color);
2569
2570         color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
2571         appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
2572         appendVertex(tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f), color);
2573         appendVertex(tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f), color);
2574         appendVertex(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), color);
2575
2576         // Create occluded square objects as zoom out of main
2577         const deUint32  mainObjectsVerticesCount                = static_cast<deUint32>(m_vertexCoord.size());
2578         const deUint32  mainObjectsCount                                = mainObjectsVerticesCount / m_verticesPerPrimitive;
2579         const deUint32  occlusionObjectMultiplierX[]    = { 1, 2, 2, 1 };
2580         const deUint32  occlusionObjectMultiplierY[]    = { 1, 1, 3, 3 };
2581         const deUint32  occlusionObjectDivisor                  = 4u;
2582         const float             occlusionObjectDivisorFloat             = static_cast<float>(occlusionObjectDivisor);
2583
2584         DE_ASSERT(0 == m_parameters.extent.width  % (2 * occlusionObjectDivisor));
2585         DE_ASSERT(0 == m_parameters.extent.height % (2 * occlusionObjectDivisor));
2586         DE_ASSERT(DE_LENGTH_OF_ARRAY(occlusionObjectMultiplierX) == mainObjectsCount);
2587         DE_ASSERT(DE_LENGTH_OF_ARRAY(occlusionObjectMultiplierY) == mainObjectsCount);
2588
2589         for (size_t objectNdx = 0; objectNdx < mainObjectsCount; ++objectNdx)
2590         {
2591                 const size_t    objectStart                     = objectNdx * m_verticesPerPrimitive;
2592                 const float             xRatio                          = static_cast<float>(occlusionObjectMultiplierX[objectNdx]) / occlusionObjectDivisorFloat;
2593                 const float             yRatio                          = static_cast<float>(occlusionObjectMultiplierY[objectNdx]) / occlusionObjectDivisorFloat;
2594                 const double    areaRatio                       = static_cast<double>(xRatio) * static_cast<double>(yRatio);
2595                 const deUint64  occludedPixelsCount     = static_cast<deUint64>(areaRatio * (m_parameters.extent.width / 2) * (m_parameters.extent.height / 2));
2596
2597                 m_occlusionObjectPixelsCount.push_back(occludedPixelsCount);
2598
2599                 for (size_t vertexNdx = 0; vertexNdx < m_verticesPerPrimitive; ++vertexNdx)
2600                 {
2601                         const float             occludedObjectVertexXCoord      = m_vertexCoord[objectStart + vertexNdx][0] * xRatio;
2602                         const float             occludedObjectVertexYCoord      = m_vertexCoord[objectStart + vertexNdx][1] * yRatio;
2603                         const tcu::Vec4 occludedObjectVertexCoord       = tcu::Vec4(occludedObjectVertexXCoord, occludedObjectVertexYCoord, 1.0f, 1.0f);
2604
2605                         appendVertex(occludedObjectVertexCoord, m_vertexColor[objectStart + vertexNdx]);
2606                 }
2607         }
2608
2609         m_occlusionObjectsOffset = mainObjectsVerticesCount;
2610 }
2611
2612 void MultiViewQueriesTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
2613 {
2614         const VkRect2D                          renderArea                                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
2615         const VkClearValue                      renderPassClearValue                    = makeClearValueColor(tcu::Vec4(0.0f));
2616         const VkBuffer                          vertexBuffers[]                                 = { *m_vertexCoordBuffer, *m_vertexColorBuffer };
2617         const VkDeviceSize                      vertexBufferOffsets[]                   = {                   0u,                   0u };
2618         const deUint32                          drawCountPerSubpass                             = (subpassCount == 1) ? m_squareCount : 1u;
2619         const deUint32                          queryCountersNumber                             = (subpassCount == 1) ? m_squareCount * getUsedViewsCount(0) : getQueryCountersNumber();
2620         const VkRenderPassBeginInfo     renderPassBeginInfo                             =
2621         {
2622                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       //  VkStructureType             sType;
2623                 DE_NULL,                                                                        //  const void*                 pNext;
2624                 renderPass,                                                                     //  VkRenderPass                renderPass;
2625                 frameBuffer,                                                            //  VkFramebuffer               framebuffer;
2626                 renderArea,                                                                     //  VkRect2D                    renderArea;
2627                 1u,                                                                                     //  uint32_t                    clearValueCount;
2628                 &renderPassClearValue,                                          //  const VkClearValue* pClearValues;
2629         };
2630         const VkQueryPoolCreateInfo     occlusionQueryPoolCreateInfo    =
2631         {
2632                 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,       //  VkStructureType                                     sType;
2633                 DE_NULL,                                                                        //  const void*                                         pNext;
2634                 (VkQueryPoolCreateFlags)0,                                      //  VkQueryPoolCreateFlags                      flags;
2635                 VK_QUERY_TYPE_OCCLUSION,                                        //  VkQueryType                                         queryType;
2636                 queryCountersNumber,                                            //  deUint32                                            queryCount;
2637                 0u,                                                                                     //  VkQueryPipelineStatisticFlags       pipelineStatistics;
2638         };
2639         const VkQueryPoolCreateInfo     timestampQueryPoolCreateInfo    =
2640         {
2641                 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,       //  VkStructureType                                     sType;
2642                 DE_NULL,                                                                        //  const void*                                         pNext;
2643                 (VkQueryPoolCreateFlags)0,                                      //  VkQueryPoolCreateFlags                      flags;
2644                 VK_QUERY_TYPE_TIMESTAMP,                                        //  VkQueryType                                         queryType;
2645                 queryCountersNumber,                                            //  deUint32                                            queryCount;
2646                 0u,                                                                                     //  VkQueryPipelineStatisticFlags       pipelineStatistics;
2647         };
2648         const Unique<VkQueryPool>       occlusionQueryPool                              (createQueryPool(*m_device, *m_logicalDevice, &occlusionQueryPoolCreateInfo));
2649         const Unique<VkQueryPool>       timestampStartQueryPool                 (createQueryPool(*m_device, *m_logicalDevice, &timestampQueryPoolCreateInfo));
2650         const Unique<VkQueryPool>       timestampEndQueryPool                   (createQueryPool(*m_device, *m_logicalDevice, &timestampQueryPoolCreateInfo));
2651         deUint32                                        queryStartIndex                                 = 0;
2652
2653         beginCommandBuffer(*m_device, *m_cmdBuffer);
2654
2655         beforeDraw();
2656
2657         // Query pools must be reset before use
2658         m_device->cmdResetQueryPool(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex, queryCountersNumber);
2659         m_device->cmdResetQueryPool(*m_cmdBuffer, *timestampStartQueryPool, queryStartIndex, queryCountersNumber);
2660         m_device->cmdResetQueryPool(*m_cmdBuffer, *timestampEndQueryPool, queryStartIndex, queryCountersNumber);
2661
2662         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
2663
2664         m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2665
2666         m_occlusionExpectedValues.reserve(queryCountersNumber);
2667         m_counterSeriesStart.reserve(queryCountersNumber);
2668         m_counterSeriesEnd.reserve(queryCountersNumber);
2669
2670         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2671         {
2672                 deUint32        queryCountersToUse      = getUsedViewsCount(subpassNdx);
2673
2674                 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2675
2676                 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2677                 {
2678                         const deUint32 primitiveNumber  = drawNdx + subpassNdx % m_squareCount;
2679                         const deUint32 firstVertex              = primitiveNumber * m_verticesPerPrimitive;
2680
2681                         m_device->cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, *timestampStartQueryPool, queryStartIndex);
2682                         {
2683                                 m_device->cmdDraw(*m_cmdBuffer, m_verticesPerPrimitive, 1u, firstVertex, 0u);
2684
2685                                 // Render occluded object
2686                                 m_device->cmdBeginQuery(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex, m_occlusionQueryFlags);
2687                                 m_device->cmdDraw(*m_cmdBuffer, m_verticesPerPrimitive, 1u, m_occlusionObjectsOffset + firstVertex, 0u);
2688                                 m_device->cmdEndQuery(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex);
2689
2690                                 for (deUint32 viewMaskNdx = 0; viewMaskNdx < queryCountersToUse; ++viewMaskNdx)
2691                                 {
2692                                         m_occlusionExpectedValues.push_back(m_occlusionObjectPixelsCount[primitiveNumber]);
2693                                         m_counterSeriesStart.push_back(viewMaskNdx == 0);
2694                                         m_counterSeriesEnd.push_back(viewMaskNdx + 1 == queryCountersToUse);
2695                                 }
2696                         }
2697                         m_device->cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, *timestampEndQueryPool, queryStartIndex);
2698
2699                         queryStartIndex += queryCountersToUse;
2700                 }
2701
2702                 if (subpassNdx < subpassCount - 1u)
2703                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
2704         }
2705
2706         DE_ASSERT(queryStartIndex == queryCountersNumber);
2707
2708         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
2709
2710         afterDraw();
2711
2712         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2713         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2714
2715         m_occlusionValues.resize(queryCountersNumber, 0ull);
2716         m_device->getQueryPoolResults(*m_logicalDevice, *occlusionQueryPool, 0u, queryCountersNumber, sizeof(deUint64) * queryCountersNumber, (void*)&m_occlusionValues[0], sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
2717
2718         m_timestampStartValues.resize(queryCountersNumber, 0ull);
2719         m_device->getQueryPoolResults(*m_logicalDevice, *timestampStartQueryPool, 0u, queryCountersNumber, sizeof(deUint64) * queryCountersNumber, (void*)&m_timestampStartValues[0], sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
2720         for (deUint32 ndx = 0; ndx < m_timestampStartValues.size(); ++ndx)
2721                 m_timestampStartValues[ndx] &= m_timestampMask;
2722
2723         m_timestampEndValues.resize(queryCountersNumber, 0ull);
2724         m_device->getQueryPoolResults(*m_logicalDevice, *timestampEndQueryPool, 0u, queryCountersNumber, sizeof(deUint64) * queryCountersNumber, (void*)&m_timestampEndValues[0], sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
2725         for (deUint32 ndx = 0; ndx < m_timestampEndValues.size(); ++ndx)
2726                 m_timestampEndValues[ndx] &= m_timestampMask;
2727 }
2728
2729 deUint32 MultiViewQueriesTestInstance::getUsedViewsCount (const deUint32 viewMaskIndex)
2730 {
2731         deUint32 result = 0;
2732
2733         for (deUint32 viewMask = m_parameters.viewMasks[viewMaskIndex]; viewMask != 0; viewMask >>= 1)
2734                 if ((viewMask & 1) != 0)
2735                         result++;
2736
2737         return result;
2738 }
2739
2740 deUint32 MultiViewQueriesTestInstance::getQueryCountersNumber ()
2741 {
2742         deUint32 result = 0;
2743
2744         for (deUint32 i = 0; i < m_parameters.viewMasks.size(); ++i)
2745                 result += getUsedViewsCount(i);
2746
2747         return result;
2748 }
2749
2750 class MultiViewReadbackTestInstance : public MultiViewRenderTestInstance
2751 {
2752 public:
2753                                                 MultiViewReadbackTestInstance   (Context& context, const TestParameters& parameters);
2754 protected:
2755         tcu::TestStatus         iterate                                                 (void);
2756         void                            drawClears                                              (const deUint32                         subpassCount,
2757                                                                                                                  VkRenderPass                           renderPass,
2758                                                                                                                  VkFramebuffer                          frameBuffer,
2759                                                                                                                  vector<PipelineSp>&            pipelines,
2760                                                                                                                  const bool                                     clearPass);
2761         void                            clear                                                   (const VkCommandBuffer          commandBuffer,
2762                                                                                                                  const VkRect2D&                        clearRect2D,
2763                                                                                                                  const tcu::Vec4&                       clearColor);
2764 private:
2765         vector<VkRect2D>        m_quarters;
2766 };
2767
2768 MultiViewReadbackTestInstance::MultiViewReadbackTestInstance (Context& context, const TestParameters& parameters)
2769         : MultiViewRenderTestInstance   (context, parameters)
2770 {
2771         const deUint32 halfWidth        = m_parameters.extent.width / 2;
2772         const deUint32 halfHeight       = m_parameters.extent.height / 2;
2773
2774         for (deInt32 x = 0; x < 2; ++x)
2775         for (deInt32 y = 0; y < 2; ++y)
2776         {
2777                 const deInt32   offsetX = static_cast<deInt32>(halfWidth) * x;
2778                 const deInt32   offsetY = static_cast<deInt32>(halfHeight) * y;
2779                 const VkRect2D  area    = { { offsetX, offsetY}, {halfWidth, halfHeight} };
2780
2781                 m_quarters.push_back(area);
2782         }
2783 }
2784
2785 tcu::TestStatus MultiViewReadbackTestInstance::iterate (void)
2786 {
2787         const deUint32  subpassCount    = static_cast<deUint32>(m_parameters.viewMasks.size());
2788
2789         createCommandBuffer();
2790
2791         for (deUint32 pass = 0; pass < 2; ++pass)
2792         {
2793                 const bool                                                                      fullClearPass   = (pass == 0);
2794                 const VkAttachmentLoadOp                                        loadOp                  = (!fullClearPass) ? VK_ATTACHMENT_LOAD_OP_LOAD :
2795                                                                                                                                           (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR) ? VK_ATTACHMENT_LOAD_OP_CLEAR :
2796                                                                                                                                           (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR) ? VK_ATTACHMENT_LOAD_OP_DONT_CARE :
2797                                                                                                                                           VK_ATTACHMENT_LOAD_OP_LAST;
2798                 Unique<VkRenderPass>                                            renderPass              (makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderPassType, VK_SAMPLE_COUNT_1_BIT, loadOp));
2799                 Unique<VkFramebuffer>                                           frameBuffer             (makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height));
2800                 Unique<VkPipelineLayout>                                        pipelineLayout  (makePipelineLayout(*m_device, *m_logicalDevice));
2801                 vector<PipelineSp>                                                      pipelines               (subpassCount);
2802                 map<VkShaderStageFlagBits, ShaderModuleSP>      shaderModule;
2803
2804                 {
2805                         vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
2806                         madeShaderModule(shaderModule, shaderStageParams);
2807                         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
2808                                 pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
2809                 }
2810
2811                 drawClears(subpassCount, *renderPass, *frameBuffer, pipelines, fullClearPass);
2812         }
2813
2814         {
2815                 vector<deUint8>                 pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
2816                 tcu::PixelBufferAccess  dst                             (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
2817
2818                 readImage(m_colorAttachment->getImage(), dst);
2819
2820                 if (!checkImage(dst))
2821                         return tcu::TestStatus::fail("Fail");
2822         }
2823
2824         return tcu::TestStatus::pass("Pass");
2825 }
2826
2827 void MultiViewReadbackTestInstance::drawClears (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines, const bool clearPass)
2828 {
2829         const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
2830         const VkClearValue                              renderPassClearValue    = makeClearValueColor(m_colorTable[0]);
2831         const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
2832         const bool                                              withClearColor                  = (clearPass && m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR);
2833         const VkRenderPassBeginInfo             renderPassBeginInfo             =
2834         {
2835                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                       //  VkStructureType             sType;
2836                 DE_NULL,                                                                                        //  const void*                 pNext;
2837                 renderPass,                                                                                     //  VkRenderPass                renderPass;
2838                 frameBuffer,                                                                            //  VkFramebuffer               framebuffer;
2839                 renderArea,                                                                                     //  VkRect2D                    renderArea;
2840                 withClearColor ? 1u : 0u,                                                       //  uint32_t                    clearValueCount;
2841                 withClearColor ? &renderPassClearValue : DE_NULL,       //  const VkClearValue* pClearValues;
2842         };
2843
2844         beginCommandBuffer(*m_device, *m_cmdBuffer);
2845
2846         if (clearPass)
2847                 beforeDraw();
2848
2849         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
2850
2851         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2852         {
2853                 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2854
2855                 if (clearPass)
2856                 {
2857                         if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR)
2858                                 clear(*m_cmdBuffer, renderArea, m_colorTable[subpassNdx % 4]);
2859                 }
2860                 else
2861                 {
2862                         for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2863                         {
2864                                 const deUint32 primitiveNumber  = drawNdx + subpassNdx % m_squareCount;
2865
2866                                 clear(*m_cmdBuffer, m_quarters[primitiveNumber], m_colorTable[4 + primitiveNumber]);
2867                         }
2868                 }
2869
2870                 if (subpassNdx < subpassCount - 1u)
2871                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
2872         }
2873
2874         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
2875
2876         if (!clearPass)
2877                 afterDraw();
2878
2879         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2880         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2881 }
2882
2883 void MultiViewReadbackTestInstance::clear (const VkCommandBuffer commandBuffer, const VkRect2D& clearRect2D, const tcu::Vec4& clearColor)
2884 {
2885         const VkClearRect               clearRect               =
2886         {
2887                 clearRect2D,                                            //  VkRect2D    rect
2888                 0u,                                                                     //  deUint32    baseArrayLayer
2889                 1u,                                                                     //  deUint32    layerCount
2890         };
2891         const VkClearAttachment clearAttachment =
2892         {
2893                 VK_IMAGE_ASPECT_COLOR_BIT,                      //  VkImageAspectFlags  aspectMask
2894                 0u,                                                                     //  deUint32                    colorAttachment
2895                 makeClearValueColor(clearColor)         //  VkClearValue                clearValue
2896         };
2897
2898         m_device->cmdClearAttachments(commandBuffer, 1u, &clearAttachment, 1u, &clearRect);
2899 }
2900
2901 class MultiViewDepthStencilTestInstance : public MultiViewRenderTestInstance
2902 {
2903 public:
2904                                                 MultiViewDepthStencilTestInstance       (Context& context, const TestParameters& parameters);
2905 protected:
2906         tcu::TestStatus         iterate                                                         (void);
2907         void                            createVertexData                                        (void);
2908
2909         void                            draw                                                            (const deUint32                                 subpassCount,
2910                                                                                                                          VkRenderPass                                   renderPass,
2911                                                                                                                          VkFramebuffer                                  frameBuffer,
2912                                                                                                                          vector<PipelineSp>&                    pipelines);
2913         void                            beforeDraw                                                      (void);
2914         void                            afterDraw                                                       (void);
2915         vector<VkImageView>     makeAttachmentsVector                           (void);
2916         void                            readImage                                                       (VkImage                                                image,
2917                                                                                                                          const tcu::PixelBufferAccess&  dst);
2918 private:
2919         VkFormat                                                m_dsFormat;
2920         de::SharedPtr<ImageAttachment>  m_dsAttachment;
2921         bool                                                    m_depthTest;
2922         bool                                                    m_stencilTest;
2923 };
2924
2925 MultiViewDepthStencilTestInstance::MultiViewDepthStencilTestInstance (Context& context, const TestParameters& parameters)
2926         : MultiViewRenderTestInstance   (context, parameters)
2927         , m_dsFormat                                    (VK_FORMAT_UNDEFINED)
2928         , m_depthTest                                   (m_parameters.viewIndex == TEST_TYPE_DEPTH)
2929         , m_stencilTest                                 (m_parameters.viewIndex == TEST_TYPE_STENCIL)
2930 {
2931         const VkFormat formats[] = { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
2932
2933         for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(formats); ++ndx)
2934         {
2935                 const VkFormat                          format                          = formats[ndx];
2936                 const VkFormatProperties        formatProperties        = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
2937
2938                 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
2939                 {
2940                         m_dsFormat = format;
2941
2942                         break;
2943                 }
2944         }
2945
2946         if (m_dsFormat == VK_FORMAT_UNDEFINED)
2947                 TCU_FAIL("Supported depth/stencil format not found, that violates specification");
2948
2949         // Depth/stencil attachment
2950         m_dsAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_dsFormat));
2951 }
2952
2953 vector<VkImageView>     MultiViewDepthStencilTestInstance::makeAttachmentsVector (void)
2954 {
2955         vector<VkImageView> attachments;
2956
2957         attachments.push_back(m_colorAttachment->getImageView());
2958         attachments.push_back(m_dsAttachment->getImageView());
2959
2960         return attachments;
2961 }
2962
2963 void MultiViewDepthStencilTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst)
2964 {
2965         const VkFormat                          bufferFormat    = m_depthTest ? getDepthBufferFormat(m_dsFormat) :
2966                                                                                                   m_stencilTest ? getStencilBufferFormat(m_dsFormat) :
2967                                                                                                   VK_FORMAT_UNDEFINED;
2968         const deUint32                          imagePixelSize  = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(bufferFormat)));
2969         const VkDeviceSize                      pixelDataSize   = dst.getWidth() * dst.getHeight() * dst.getDepth() * imagePixelSize;
2970         const tcu::TextureFormat        tcuBufferFormat = mapVkFormat(bufferFormat);
2971         Move<VkBuffer>                          buffer;
2972         MovePtr<Allocation>                     bufferAlloc;
2973
2974         // Create destination buffer
2975         {
2976                 const VkBufferCreateInfo bufferParams   =
2977                 {
2978                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
2979                         DE_NULL,                                                                // const void*                  pNext;
2980                         0u,                                                                             // VkBufferCreateFlags  flags;
2981                         pixelDataSize,                                                  // VkDeviceSize                 size;
2982                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,               // VkBufferUsageFlags   usage;
2983                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2984                         1u,                                                                             // deUint32                             queueFamilyIndexCount;
2985                         &m_queueFamilyIndex,                                    // const deUint32*              pQueueFamilyIndices;
2986                 };
2987
2988                 buffer          = createBuffer(*m_device, *m_logicalDevice, &bufferParams);
2989                 bufferAlloc     = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
2990                 VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
2991
2992                 deMemset(bufferAlloc->getHostPtr(), 0xCC, static_cast<size_t>(pixelDataSize));
2993                 flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
2994         }
2995
2996         const VkBufferMemoryBarrier     bufferBarrier   =
2997         {
2998                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
2999                 DE_NULL,                                                                        // const void*          pNext;
3000                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
3001                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
3002                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
3003                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
3004                 *buffer,                                                                        // VkBuffer                     buffer;
3005                 0u,                                                                                     // VkDeviceSize         offset;
3006                 pixelDataSize                                                           // VkDeviceSize         size;
3007         };
3008
3009         // Copy image to buffer
3010         const VkImageAspectFlags        aspect                  = m_depthTest ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT) :
3011                                                                                                   m_stencilTest ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_STENCIL_BIT) :
3012                                                                                                   static_cast<VkImageAspectFlags>(0u);
3013         const VkBufferImageCopy         copyRegion              =
3014         {
3015                 0u,                                                                                     // VkDeviceSize                         bufferOffset;
3016                 (deUint32)dst.getWidth(),                                       // deUint32                                     bufferRowLength;
3017                 (deUint32)dst.getHeight(),                                      // deUint32                                     bufferImageHeight;
3018                 {
3019                         aspect,                                                                 // VkImageAspectFlags           aspect;
3020                         0u,                                                                             // deUint32                                     mipLevel;
3021                         0u,                                                                             // deUint32                                     baseArrayLayer;
3022                         m_parameters.extent.depth,                              // deUint32                                     layerCount;
3023                 },                                                                                      // VkImageSubresourceLayers     imageSubresource;
3024                 { 0, 0, 0 },                                                            // VkOffset3D                           imageOffset;
3025                 {                                                                                       // VkExtent3D                           imageExtent;
3026                         m_parameters.extent.width,
3027                         m_parameters.extent.height,
3028                         1u
3029                 }
3030         };
3031
3032         beginCommandBuffer (*m_device, *m_cmdBuffer);
3033         {
3034                 m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
3035                 m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0u, DE_NULL);
3036         }
3037         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
3038         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
3039
3040         // Read buffer data
3041         invalidateAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
3042
3043         if (m_depthTest)
3044         {
3045                 // Translate depth into color space
3046                 tcu::ConstPixelBufferAccess     pixelBuffer     (tcuBufferFormat, dst.getSize(), bufferAlloc->getHostPtr());
3047
3048                 for (int z = 0; z < pixelBuffer.getDepth(); z++)
3049                 for (int y = 0; y < pixelBuffer.getHeight(); y++)
3050                 for (int x = 0; x < pixelBuffer.getWidth(); x++)
3051                 {
3052                         const float             depth   = pixelBuffer.getPixDepth(x, y, z);
3053                         const tcu::Vec4 color   = tcu::Vec4(depth, 0.0f, 0.0f, 1.0f);
3054
3055                         dst.setPixel(color, x, y, z);
3056                 }
3057         }
3058
3059         if (m_stencilTest)
3060         {
3061                 // Translate stencil into color space
3062                 tcu::ConstPixelBufferAccess     pixelBuffer     (tcuBufferFormat, dst.getSize(), bufferAlloc->getHostPtr());
3063                 const tcu::Vec4                         baseColor               = getQuarterRefColor(0u, 0u, 0u, false);
3064                 const tcu::Vec4                         colorStep               = getQuarterRefColor(0u, 0u, 0u, true);
3065                 const tcu::Vec4                         colorMap[4]             =
3066                 {
3067                         baseColor,
3068                         tcu::Vec4(1.0f * colorStep[0], 0.0f, 0.0f, 1.0),
3069                         tcu::Vec4(2.0f * colorStep[0], 0.0f, 0.0f, 1.0),
3070                         tcu::Vec4(3.0f * colorStep[0], 0.0f, 0.0f, 1.0),
3071                 };
3072                 const tcu::Vec4                         invalidColor    = tcu::Vec4(0.0f);
3073
3074                 for (int z = 0; z < pixelBuffer.getDepth(); z++)
3075                 for (int y = 0; y < pixelBuffer.getHeight(); y++)
3076                 for (int x = 0; x < pixelBuffer.getWidth(); x++)
3077                 {
3078                         const int                       stencilInt      = pixelBuffer.getPixStencil(x, y, z);
3079                         const tcu::Vec4&        color           = de::inRange(stencilInt, 0, DE_LENGTH_OF_ARRAY(colorMap)) ? colorMap[stencilInt] : invalidColor;
3080
3081                         dst.setPixel(color, x, y, z);
3082                 }
3083         }
3084
3085 }
3086
3087 tcu::TestStatus MultiViewDepthStencilTestInstance::iterate (void)
3088 {
3089         const deUint32                                                          subpassCount                            = static_cast<deUint32>(m_parameters.viewMasks.size());
3090         Unique<VkRenderPass>                                            renderPass                                      (makeRenderPassWithDepth (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_dsFormat, m_parameters.renderPassType));
3091         vector<VkImageView>                                                     attachments                                     (makeAttachmentsVector());
3092         Unique<VkFramebuffer>                                           frameBuffer                                     (makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height, 1u));
3093         Unique<VkPipelineLayout>                                        pipelineLayout                          (makePipelineLayout(*m_device, *m_logicalDevice));
3094         map<VkShaderStageFlagBits, ShaderModuleSP>      shaderModule;
3095         vector<PipelineSp>                                                      pipelines(subpassCount);
3096
3097         {
3098                 vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
3099                 madeShaderModule(shaderModule, shaderStageParams);
3100                 for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
3101                         pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(),
3102                                 subpassNdx, VK_VERTEX_INPUT_RATE_VERTEX, m_depthTest, m_stencilTest))));
3103         }
3104
3105         createCommandBuffer();
3106         createVertexData();
3107         createVertexBuffer();
3108
3109         draw(subpassCount, *renderPass, *frameBuffer, pipelines);
3110
3111         {
3112                 vector<deUint8>                 pixelAccessData (m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
3113                 tcu::PixelBufferAccess  dst                             (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
3114
3115                 readImage(m_dsAttachment->getImage(), dst);
3116
3117                 if (!checkImage(dst))
3118                         return tcu::TestStatus::fail("Fail");
3119         }
3120
3121         return tcu::TestStatus::pass("Pass");
3122 }
3123
3124 void MultiViewDepthStencilTestInstance::createVertexData (void)
3125 {
3126 /*
3127         partA
3128
3129         ViewMasks
3130         0011
3131         0110
3132         1100
3133         1001
3134
3135         Layer3  Layer2  Layer1  Layer0
3136           ^       ^       ^       ^
3137         00|10   00|10   01|00   01|00
3138         00|10   00|10   01|00   01|00
3139         --+-->  --+-->  --+-->  --+-->
3140         00|10   01|00   01|00   00|10
3141         00|10   01|00   01|00   00|10
3142
3143
3144         partB
3145
3146         ViewMasks
3147         0110
3148         1100
3149         1001
3150         0011
3151
3152         Layer3  Layer2  Layer1  Layer0
3153           ^       ^       ^       ^
3154         00|00   00|00   00|00   00|00
3155         00|22   22|00   22|00   00|22
3156         --+-->  --+-->  --+-->  --+-->
3157         22|00   22|00   00|22   00|22
3158         00|00   00|00   00|00   00|00
3159
3160         Final
3161         Layer3  Layer2  Layer1  Layer0
3162           ^       ^       ^       ^
3163         00|10   00|10   01|00   01|00
3164         00|32   22|10   23|00   01|22
3165         --+-->  --+-->  --+-->  --+-->
3166         22|10   23|00   01|22   00|32
3167         00|10   01|00   01|00   00|10
3168 */
3169         tcu::Vec4       color   (0.0f, 0.0f, 0.0f, 1.0f); // is not essential in this test
3170
3171         const tcu::Vec4 partAReference  = getQuarterRefColor(0u, 0u, 0u, true, 0u);
3172         const tcu::Vec4 partBReference  = getQuarterRefColor(0u, 0u, 0u, true, 4u);
3173         const float             depthA                  = partAReference[0];
3174         const float             depthB                  = partBReference[0];
3175
3176         // part A
3177         appendVertex(tcu::Vec4(-1.0f,-0.5f, depthA, 1.0f), color);
3178         appendVertex(tcu::Vec4(-1.0f, 0.0f, depthA, 1.0f), color);
3179         appendVertex(tcu::Vec4( 0.0f,-0.5f, depthA, 1.0f), color);
3180         appendVertex(tcu::Vec4( 0.0f, 0.0f, depthA, 1.0f), color);
3181
3182         appendVertex(tcu::Vec4(-1.0f, 0.0f, depthA, 1.0f), color);
3183         appendVertex(tcu::Vec4(-1.0f, 0.5f, depthA, 1.0f), color);
3184         appendVertex(tcu::Vec4( 0.0f, 0.0f, depthA, 1.0f), color);
3185         appendVertex(tcu::Vec4( 0.0f, 0.5f, depthA, 1.0f), color);
3186
3187         appendVertex(tcu::Vec4( 0.0f,-0.5f, depthA, 1.0f), color);
3188         appendVertex(tcu::Vec4( 0.0f, 0.0f, depthA, 1.0f), color);
3189         appendVertex(tcu::Vec4( 1.0f,-0.5f, depthA, 1.0f), color);
3190         appendVertex(tcu::Vec4( 1.0f, 0.0f, depthA, 1.0f), color);
3191
3192         appendVertex(tcu::Vec4( 0.0f, 0.0f, depthA, 1.0f), color);
3193         appendVertex(tcu::Vec4( 0.0f, 0.5f, depthA, 1.0f), color);
3194         appendVertex(tcu::Vec4( 1.0f, 0.0f, depthA, 1.0f), color);
3195         appendVertex(tcu::Vec4( 1.0f, 0.5f, depthA, 1.0f), color);
3196
3197         // part B
3198         appendVertex(tcu::Vec4(-0.5f,-1.0f, depthB, 1.0f), color);
3199         appendVertex(tcu::Vec4(-0.5f, 0.0f, depthB, 1.0f), color);
3200         appendVertex(tcu::Vec4( 0.0f,-1.0f, depthB, 1.0f), color);
3201         appendVertex(tcu::Vec4( 0.0f, 0.0f, depthB, 1.0f), color);
3202
3203         appendVertex(tcu::Vec4(-0.5f, 0.0f, depthB, 1.0f), color);
3204         appendVertex(tcu::Vec4(-0.5f, 1.0f, depthB, 1.0f), color);
3205         appendVertex(tcu::Vec4( 0.0f, 0.0f, depthB, 1.0f), color);
3206         appendVertex(tcu::Vec4( 0.0f, 1.0f, depthB, 1.0f), color);
3207
3208         appendVertex(tcu::Vec4( 0.0f,-1.0f, depthB, 1.0f), color);
3209         appendVertex(tcu::Vec4( 0.0f, 0.0f, depthB, 1.0f), color);
3210         appendVertex(tcu::Vec4( 0.5f,-1.0f, depthB, 1.0f), color);
3211         appendVertex(tcu::Vec4( 0.5f, 0.0f, depthB, 1.0f), color);
3212
3213         appendVertex(tcu::Vec4( 0.0f, 0.0f, depthB, 1.0f), color);
3214         appendVertex(tcu::Vec4( 0.0f, 1.0f, depthB, 1.0f), color);
3215         appendVertex(tcu::Vec4( 0.5f, 0.0f, depthB, 1.0f), color);
3216         appendVertex(tcu::Vec4( 0.5f, 1.0f, depthB, 1.0f), color);
3217 }
3218
3219 void MultiViewDepthStencilTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
3220 {
3221         const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
3222         const VkClearValue                              renderPassClearValue    = makeClearValueColor(tcu::Vec4(0.0f));
3223         const VkBuffer                                  vertexBuffers[]                 = { *m_vertexCoordBuffer, *m_vertexColorBuffer };
3224         const VkDeviceSize                              vertexBufferOffsets[]   = {                   0u,                   0u };
3225         const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
3226         const deUint32                                  vertexPerPrimitive              = 4u;
3227         const VkRenderPassBeginInfo             renderPassBeginInfo             =
3228         {
3229                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
3230                 DE_NULL,                                                                        // const void*                  pNext;
3231                 renderPass,                                                                     // VkRenderPass                 renderPass;
3232                 frameBuffer,                                                            // VkFramebuffer                framebuffer;
3233                 renderArea,                                                                     // VkRect2D                             renderArea;
3234                 1u,                                                                                     // uint32_t                             clearValueCount;
3235                 &renderPassClearValue,                                          // const VkClearValue*  pClearValues;
3236         };
3237
3238         beginCommandBuffer(*m_device, *m_cmdBuffer);
3239
3240         beforeDraw();
3241
3242         cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
3243
3244         m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
3245
3246         for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
3247         {
3248                 deUint32 firstVertexOffset = (subpassNdx < 4) ? 0u : m_squareCount * vertexPerPrimitive;
3249
3250                 m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
3251
3252                 for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
3253                         m_device->cmdDraw(*m_cmdBuffer, vertexPerPrimitive, 1u, firstVertexOffset + (drawNdx + subpassNdx % m_squareCount) * vertexPerPrimitive, 0u);
3254
3255                 if (subpassNdx < subpassCount - 1u)
3256                         cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderPassType);
3257         }
3258
3259         cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderPassType);
3260
3261         afterDraw();
3262
3263         VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
3264         submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
3265 }
3266
3267 void MultiViewDepthStencilTestInstance::beforeDraw (void)
3268 {
3269         MultiViewRenderTestInstance::beforeDraw();
3270
3271         const VkImageSubresourceRange   subresourceRange                =
3272         {
3273                 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,        //VkImageAspectFlags    aspectMask;
3274                 0u,                                                                                                                     //deUint32                              baseMipLevel;
3275                 1u,                                                                                                                     //deUint32                              levelCount;
3276                 0u,                                                                                                                     //deUint32                              baseArrayLayer;
3277                 m_parameters.extent.depth,                                                                      //deUint32                              layerCount;
3278         };
3279         imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), subresourceRange,
3280                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3281                 0, 0,
3282                 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
3283
3284         const tcu::Vec4         baseColor       = getQuarterRefColor(0u, 0u, 0u, false);
3285         const float                     clearDepth      = baseColor[0];
3286         const VkClearValue      clearValue      = makeClearValueDepthStencil(clearDepth, 0);
3287
3288         m_device->cmdClearDepthStencilImage(*m_cmdBuffer, m_dsAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &subresourceRange);
3289
3290         imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), subresourceRange,
3291                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3292                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
3293                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
3294 }
3295
3296 void MultiViewDepthStencilTestInstance::afterDraw (void)
3297 {
3298         MultiViewRenderTestInstance::afterDraw();
3299
3300         const VkImageSubresourceRange   dsSubresourceRange              =
3301         {
3302                 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,        //  VkImageAspectFlags  aspectMask;
3303                 0u,                                                                                                                     //  deUint32                    baseMipLevel;
3304                 1u,                                                                                                                     //  deUint32                    levelCount;
3305                 0u,                                                                                                                     //  deUint32                    baseArrayLayer;
3306                 m_parameters.extent.depth,                                                                      //  deUint32                    layerCount;
3307         };
3308
3309         imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), dsSubresourceRange,
3310                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3311                 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3312                 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3313 }
3314
3315 class MultiViewRenderTestsCase : public vkt::TestCase
3316 {
3317 public:
3318         MultiViewRenderTestsCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
3319                 : TestCase                      (context, name, description)
3320                 , m_parameters          (parameters)
3321         {
3322                 DE_ASSERT(m_parameters.extent.width == m_parameters.extent.height);
3323         }
3324 private:
3325         const TestParameters    m_parameters;
3326
3327         vkt::TestInstance*      createInstance          (vkt::Context& context) const
3328         {
3329                 if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex ||
3330                         TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY == m_parameters.viewIndex)
3331                         return new MultiViewAttachmentsTestInstance(context, m_parameters);
3332
3333                 if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex)
3334                         return new MultiViewInstancedTestInstance(context, m_parameters);
3335
3336                 if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
3337                         return new MultiViewInputRateInstanceTestInstance(context, m_parameters);
3338
3339                 if (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex ||
3340                         TEST_TYPE_DRAW_INDIRECT_INDEXED == m_parameters.viewIndex)
3341                         return new MultiViewDrawIndirectTestInstance(context, m_parameters);
3342
3343                 if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
3344                         return new MultiViewClearAttachmentsTestInstance(context, m_parameters);
3345
3346                 if (TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex ||
3347                         TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == m_parameters.viewIndex)
3348                         return new MultiViewSecondaryCommandBufferTestInstance(context, m_parameters);
3349
3350                 if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
3351                         return new MultiViewPointSizeTestInstance(context, m_parameters);
3352
3353                 if (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex)
3354                         return new MultiViewMultsampleTestInstance(context, m_parameters);
3355
3356                 if (TEST_TYPE_QUERIES == m_parameters.viewIndex ||
3357                         TEST_TYPE_NON_PRECISE_QUERIES == m_parameters.viewIndex)
3358                         return new MultiViewQueriesTestInstance(context, m_parameters);
3359
3360                 if (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex ||
3361                         TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex ||
3362                         TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex ||
3363                         TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex ||
3364                         TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex ||
3365                         TEST_TYPE_DRAW_INDEXED == m_parameters.viewIndex)
3366                         return new MultiViewRenderTestInstance(context, m_parameters);
3367
3368                 if (TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR == m_parameters.viewIndex ||
3369                         TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR == m_parameters.viewIndex)
3370                         return new MultiViewReadbackTestInstance(context, m_parameters);
3371
3372                 if (TEST_TYPE_DEPTH == m_parameters.viewIndex ||
3373                         TEST_TYPE_STENCIL == m_parameters.viewIndex)
3374                         return new MultiViewDepthStencilTestInstance(context, m_parameters);
3375
3376                 TCU_THROW(InternalError, "Unknown test type");
3377         }
3378
3379         virtual void            checkSupport            (Context& context) const
3380         {
3381                 context.requireDeviceFunctionality("VK_KHR_multiview");
3382         }
3383
3384         void                            initPrograms            (SourceCollections& programCollection) const
3385         {
3386                 // Create vertex shader
3387                 if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex)
3388                 {
3389                         std::ostringstream source;
3390                         source  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3391                                         << "#extension GL_EXT_multiview : enable\n"
3392                                         << "layout(location = 0) in highp vec4 in_position;\n"
3393                                         << "layout(location = 1) in vec4 in_color;\n"
3394                                         << "layout(location = 0) out vec4 out_color;\n"
3395                                         << "void main (void)\n"
3396                                         << "{\n"
3397                                         << "    int modInstance = gl_InstanceIndex % 4;\n"
3398                                         << "    int instance    = gl_InstanceIndex + 1;\n"
3399                                         << "    gl_Position = in_position;\n"
3400                                         << "    if (modInstance == 1)\n"
3401                                         << "            gl_Position = in_position + vec4(0.0f, 1.0f, 0.0f, 0.0f);\n"
3402                                         << "    if (modInstance == 2)\n"
3403                                         << "            gl_Position = in_position + vec4(1.0f, 0.0f, 0.0f, 0.0f);\n"
3404                                         << "    if (modInstance == 3)\n"
3405                                         << "            gl_Position =  in_position + vec4(1.0f, 1.0f, 0.0f, 0.0f);\n"
3406                                         << "    out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n"
3407                                         << "}\n";
3408                         programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
3409                 }
3410                 else if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
3411                 {
3412                         std::ostringstream source;
3413                         source  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3414                                         << "#extension GL_EXT_multiview : enable\n"
3415                                         << "layout(location = 0) in highp vec4 in_position;\n"
3416                                         << "layout(location = 1) in vec4 in_color;\n"
3417                                         << "layout(location = 0) out vec4 out_color;\n"
3418                                         << "void main (void)\n"
3419                                         << "{\n"
3420                                         << "    int instance = gl_InstanceIndex + 1;\n"
3421                                         << "    gl_Position = in_position;\n"
3422                                         << "    if (gl_VertexIndex == 1)\n"
3423                                         << "            gl_Position.y += 1.0f;\n"
3424                                         << "    else if (gl_VertexIndex == 2)\n"
3425                                         << "            gl_Position.x += 1.0f;\n"
3426                                         << "    else if (gl_VertexIndex == 3)\n"
3427                                         << "    {\n"
3428                                         << "            gl_Position.x += 1.0f;\n"
3429                                         << "            gl_Position.y += 1.0f;\n"
3430                                         << "    }\n"
3431                                         << "    out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n"
3432                                         << "}\n";
3433                         programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
3434                 }
3435                 else if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
3436                 {
3437                         std::ostringstream source;
3438                         source  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3439                                         << "#extension GL_EXT_multiview : enable\n"
3440                                         << "layout(location = 0) in highp vec4 in_position;\n"
3441                                         << "layout(location = 1) in highp vec4 in_color;\n"
3442                                         << "layout(location = 0) out vec4 out_color;\n"
3443                                         << "void main (void)\n"
3444                                         << "{\n"
3445                                         << "    gl_Position = in_position;\n"
3446                                         << "    if (gl_ViewIndex == 0)\n"
3447                                         << "            gl_PointSize = " << de::floatToString(static_cast<float>(TEST_POINT_SIZE_WIDE), 1) << "f;\n"
3448                                         << "    else\n"
3449                                         << "            gl_PointSize = " << de::floatToString(static_cast<float>(TEST_POINT_SIZE_SMALL), 1) << "f;\n"
3450                                         << "    out_color = in_color;\n"
3451                                         << "}\n";
3452                         programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
3453                 }
3454                 else
3455                 {
3456                         const bool generateColor        =  (TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex)
3457                                                                                 || (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex)
3458                                                                                 || (TEST_TYPE_DRAW_INDIRECT_INDEXED == m_parameters.viewIndex)
3459                                                                                 || (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex);
3460                         std::ostringstream source;
3461                         source  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3462                                         << "#extension GL_EXT_multiview : enable\n"
3463                                         << "layout(location = 0) in highp vec4 in_position;\n"
3464                                         << "layout(location = 1) in vec4 in_color;\n"
3465                                         << "layout(location = 0) out vec4 out_color;\n"
3466                                         << "void main (void)\n"
3467                                         << "{\n"
3468                                         << "    gl_Position = in_position;\n";
3469                                 if (generateColor)
3470                                         source << "     out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
3471                                 else
3472                                         source << "     out_color = in_color;\n";
3473                         source  << "}\n";
3474                         programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
3475                 }
3476
3477                 if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)
3478                 {// Tessellation control & evaluation
3479                         std::ostringstream source_tc;
3480                         source_tc       << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
3481                                                 << "#extension GL_EXT_multiview : enable\n"
3482                                                 << "#extension GL_EXT_tessellation_shader : require\n"
3483                                                 << "layout(vertices = 4) out;\n"
3484                                                 << "layout(location = 0) in vec4 in_color[];\n"
3485                                                 << "layout(location = 0) out vec4 out_color[];\n"
3486                                                 << "\n"
3487                                                 << "void main (void)\n"
3488                                                 << "{\n"
3489                                                 << "    if ( gl_InvocationID == 0 )\n"
3490                                                 << "    {\n"
3491                                                 << "            gl_TessLevelInner[0] = 4.0f;\n"
3492                                                 << "            gl_TessLevelInner[1] = 4.0f;\n"
3493                                                 << "            gl_TessLevelOuter[0] = 4.0f;\n"
3494                                                 << "            gl_TessLevelOuter[1] = 4.0f;\n"
3495                                                 << "            gl_TessLevelOuter[2] = 4.0f;\n"
3496                                                 << "            gl_TessLevelOuter[3] = 4.0f;\n"
3497                                                 << "    }\n"
3498                                                 << "    out_color[gl_InvocationID] = in_color[gl_InvocationID];\n"
3499                                                 << "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
3500                                                 << "}\n";
3501                         programCollection.glslSources.add("tessellation_control") << glu::TessellationControlSource(source_tc.str());
3502
3503                         std::ostringstream source_te;
3504                         source_te       << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
3505                                                 << "#extension GL_EXT_multiview : enable\n"
3506                                                 << "#extension GL_EXT_tessellation_shader : require\n"
3507                                                 << "layout( quads, equal_spacing, ccw ) in;\n"
3508                                                 << "layout(location = 0) in vec4 in_color[];\n"
3509                                                 << "layout(location = 0) out vec4 out_color;\n"
3510                                                 << "void main (void)\n"
3511                                                 << "{\n"
3512                                                 << "    const float u = gl_TessCoord.x;\n"
3513                                                 << "    const float v = gl_TessCoord.y;\n"
3514                                                 << "    const float w = gl_TessCoord.z;\n"
3515                                                 << "    gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;\n"
3516                                                 << "    out_color = in_color[0]+ vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
3517                                                 << "}\n";
3518                         programCollection.glslSources.add("tessellation_evaluation") << glu::TessellationEvaluationSource(source_te.str());
3519                 }
3520
3521                 if (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY            == m_parameters.viewIndex ||
3522                         TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY    == m_parameters.viewIndex ||
3523                         TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == m_parameters.viewIndex)
3524                 {// Geometry Shader
3525                         std::ostringstream      source;
3526                         source  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3527                                         << "#extension GL_EXT_multiview : enable\n"
3528                                         << "layout(triangles) in;\n"
3529                                         << "layout(triangle_strip, max_vertices = 16) out;\n"
3530                                         << "layout(location = 0) in vec4 in_color[];\n"
3531                                         << "layout(location = 0) out vec4 out_color;\n"
3532                                         << "void main (void)\n"
3533                                         << "{\n"
3534                                         << "    out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
3535                                         << "    gl_Position = gl_in[0].gl_Position;\n"
3536                                         << "    EmitVertex();\n"
3537                                         << "    out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
3538                                         << "    gl_Position = gl_in[1].gl_Position;\n"
3539                                         << "    EmitVertex();\n"
3540                                         << "    out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
3541                                         << "    gl_Position = gl_in[2].gl_Position;\n"
3542                                         << "    EmitVertex();\n"
3543                                         << "    out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
3544                                         << "    gl_Position = vec4(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y, 1.0, 1.0);\n"
3545                                         << "    EmitVertex();\n"
3546                                         << "    EndPrimitive();\n"
3547                                         << "}\n";
3548                         programCollection.glslSources.add("geometry") << glu::GeometrySource(source.str());
3549                 }
3550
3551                 if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex)
3552                 {// Create fragment shader read/write attachment
3553                         std::ostringstream source;
3554                         source  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3555                                         << "#extension GL_EXT_multiview : enable\n"
3556                                         << "layout(location = 0) in vec4 in_color;\n"
3557                                         << "layout(location = 0) out vec4 out_color;\n"
3558                                         << "layout(input_attachment_index = 0, set=0, binding=0) uniform highp subpassInput in_color_attachment;\n"
3559                                         << "void main()\n"
3560                                         <<"{\n"
3561                                         << "    out_color = vec4(subpassLoad(in_color_attachment));\n"
3562                                         << "}\n";
3563                         programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
3564                 }
3565                 else
3566                 {// Create fragment shader
3567                         std::ostringstream source;
3568                         source  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3569                                         << "#extension GL_EXT_multiview : enable\n"
3570                                         << "layout(location = 0) in vec4 in_color;\n"
3571                                         << "layout(location = 0) out vec4 out_color;\n"
3572                                         << "void main()\n"
3573                                         <<"{\n";
3574                                 if (TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex ||
3575                                         TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex)
3576                                         source << "     out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
3577                                 else
3578                                         source << "     out_color = in_color;\n";
3579                         source  << "}\n";
3580                         programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
3581                 }
3582         }
3583 };
3584 } //anonymous
3585
3586 static std::string createViewMasksName(const std::vector<deUint32>& viewMasks)
3587 {
3588         std::ostringstream              masks;
3589
3590         for (size_t ndx = 0u; ndx < viewMasks.size(); ++ndx)
3591         {
3592                 masks << viewMasks[ndx];
3593                 if (viewMasks.size() - 1 != ndx)
3594                         masks << "_";
3595         }
3596
3597         return masks.str();
3598 }
3599
3600 static std::vector<deUint32> tripleDepthStencilMasks(std::vector<deUint32>& baseMasks)
3601 {
3602         std::vector<deUint32> tripledMasks(baseMasks);
3603         std::vector<deUint32> partBMasks;
3604
3605         // a,b,c,d  =>  b,c,d,a
3606         partBMasks.insert(partBMasks.end(), baseMasks.begin() + 1, baseMasks.end());
3607         partBMasks.push_back(baseMasks[0]);
3608
3609         tripledMasks.insert(tripledMasks.end(), partBMasks.begin(), partBMasks.end());
3610         tripledMasks.insert(tripledMasks.end(), partBMasks.begin(), partBMasks.end());
3611
3612         return tripledMasks;
3613 }
3614
3615 void multiViewRenderCreateTests (tcu::TestCaseGroup* group)
3616 {
3617         const deUint32                          testCaseCount                           = 7u;
3618         const string                            shaderName[TEST_TYPE_LAST]      =
3619         {
3620                 "masks",
3621                 "vertex_shader",
3622                 "fragment_shader",
3623                 "geometry_shader",
3624                 "tessellation_shader",
3625                 "input_attachments",
3626                 "input_attachments_geometry",
3627                 "instanced",
3628                 "input_instance",
3629                 "draw_indirect",
3630                 "draw_indirect_indexed",
3631                 "draw_indexed",
3632                 "clear_attachments",
3633                 "secondary_cmd_buffer",
3634                 "secondary_cmd_buffer_geometry",
3635                 "point_size",
3636                 "multisample",
3637                 "queries",
3638                 "non_precise_queries",
3639                 "readback_implicit_clear",
3640                 "readback_explicit_clear",
3641                 "depth",
3642                 "stencil",
3643         };
3644         const VkExtent3D                        extent3D[testCaseCount]         =
3645         {
3646                 {16u,   16u,    4u},
3647                 {64u,   64u,    8u},
3648                 {128u,  128u,   4u},
3649                 {32u,   32u,    5u},
3650                 {64u,   64u,    6u},
3651                 {32u,   32u,    4u},
3652                 {16u,   16u,    10u},
3653         };
3654         vector<deUint32>                        viewMasks[testCaseCount];
3655
3656         viewMasks[0].push_back(15u);    //1111
3657
3658         viewMasks[1].push_back(8u);             //1000
3659
3660         viewMasks[2].push_back(1u);             //0001
3661         viewMasks[2].push_back(2u);             //0010
3662         viewMasks[2].push_back(4u);             //0100
3663         viewMasks[2].push_back(8u);             //1000
3664
3665         viewMasks[3].push_back(15u);    //1111
3666         viewMasks[3].push_back(15u);    //1111
3667         viewMasks[3].push_back(15u);    //1111
3668         viewMasks[3].push_back(15u);    //1111
3669
3670         viewMasks[4].push_back(8u);             //1000
3671         viewMasks[4].push_back(1u);             //0001
3672         viewMasks[4].push_back(1u);             //0001
3673         viewMasks[4].push_back(8u);             //1000
3674
3675         viewMasks[5].push_back(5u);             //0101
3676         viewMasks[5].push_back(10u);    //1010
3677         viewMasks[5].push_back(5u);             //0101
3678         viewMasks[5].push_back(10u);    //1010
3679
3680         const deUint32 minSupportedMultiviewViewCount   = 6u;
3681         const deUint32 maxViewMask                                              = (1u << minSupportedMultiviewViewCount) - 1u;
3682
3683         for (deUint32 mask = 1u; mask <= maxViewMask; mask = mask << 1u)
3684                 viewMasks[testCaseCount - 1].push_back(mask);
3685
3686         vector<deUint32>                        depthStencilMasks;
3687
3688         depthStencilMasks.push_back(3u);        // 0011
3689         depthStencilMasks.push_back(6u);        // 0110
3690         depthStencilMasks.push_back(12u);       // 1100
3691         depthStencilMasks.push_back(9u);        // 1001
3692
3693         for (int renderPassTypeNdx = 0; renderPassTypeNdx < 2; ++renderPassTypeNdx)
3694         {
3695                 RenderPassType                          renderPassType          ((renderPassTypeNdx == 0) ? RENDERPASS_TYPE_LEGACY : RENDERPASS_TYPE_RENDERPASS2);
3696                 MovePtr<tcu::TestCaseGroup>     groupRenderPass2        ((renderPassTypeNdx == 0) ? DE_NULL : new tcu::TestCaseGroup(group->getTestContext(), "renderpass2", "RenderPass2 index tests"));
3697                 tcu::TestCaseGroup*                     targetGroup                     ((renderPassTypeNdx == 0) ? group : groupRenderPass2.get());
3698                 tcu::TestContext&                       testCtx                         (targetGroup->getTestContext());
3699                 MovePtr<tcu::TestCaseGroup>     groupViewIndex          (new tcu::TestCaseGroup(testCtx, "index", "ViewIndex rendering tests."));
3700
3701                 for (int testTypeNdx = TEST_TYPE_VIEW_MASK; testTypeNdx < TEST_TYPE_LAST; ++testTypeNdx)
3702                 {
3703                         MovePtr<tcu::TestCaseGroup>     groupShader                     (new tcu::TestCaseGroup(testCtx, shaderName[testTypeNdx].c_str(), ""));
3704                         const TestType                          testType                        = static_cast<TestType>(testTypeNdx);
3705                         const VkSampleCountFlagBits     sampleCountFlags        = (testType == TEST_TYPE_MULTISAMPLE) ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT;
3706                         const VkFormat                          colorFormat                     = (testType == TEST_TYPE_MULTISAMPLE) ? VK_FORMAT_R32G32B32A32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM;
3707
3708                         if (testTypeNdx == TEST_TYPE_DEPTH || testTypeNdx == TEST_TYPE_STENCIL)
3709                         {
3710                                 const VkExtent3D                dsTestExtent3D  = { 64u, 64u, 4u };
3711                                 const TestParameters    parameters              = { dsTestExtent3D, tripleDepthStencilMasks(depthStencilMasks), testType, sampleCountFlags, colorFormat, renderPassType };
3712                                 const std::string               testName                = createViewMasksName(parameters.viewMasks);
3713
3714                                 groupShader->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), "", parameters));
3715                         }
3716                         else
3717                         {
3718                                 for (deUint32 testCaseNdx = 0u; testCaseNdx < testCaseCount; ++testCaseNdx)
3719                                 {
3720                                         const TestParameters    parameters      =       { extent3D[testCaseNdx], viewMasks[testCaseNdx], testType, sampleCountFlags, colorFormat, renderPassType };
3721                                         const std::string               testName        =       createViewMasksName(parameters.viewMasks);
3722
3723                                         groupShader->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), "", parameters));
3724                                 }
3725
3726                                 // maxMultiviewViewCount case
3727                                 {
3728                                         const VkExtent3D                incompleteExtent3D      = { 16u, 16u, 0u };
3729                                         const vector<deUint32>  unusedMasks;
3730                                         const TestParameters    parameters                      = { incompleteExtent3D, unusedMasks, testType, sampleCountFlags, colorFormat, renderPassType };
3731
3732                                         groupShader->addChild(new MultiViewRenderTestsCase(testCtx, "max_multi_view_view_count", "", parameters));
3733                                 }
3734                         }
3735
3736                         switch (testType)
3737                         {
3738                                 case TEST_TYPE_VIEW_MASK:
3739                                 case TEST_TYPE_INPUT_ATTACHMENTS:
3740                                 case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY:
3741                                 case TEST_TYPE_INSTANCED_RENDERING:
3742                                 case TEST_TYPE_INPUT_RATE_INSTANCE:
3743                                 case TEST_TYPE_DRAW_INDIRECT:
3744                                 case TEST_TYPE_DRAW_INDIRECT_INDEXED:
3745                                 case TEST_TYPE_DRAW_INDEXED:
3746                                 case TEST_TYPE_CLEAR_ATTACHMENTS:
3747                                 case TEST_TYPE_SECONDARY_CMD_BUFFER:
3748                                 case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY:
3749                                 case TEST_TYPE_POINT_SIZE:
3750                                 case TEST_TYPE_MULTISAMPLE:
3751                                 case TEST_TYPE_QUERIES:
3752                                 case TEST_TYPE_NON_PRECISE_QUERIES:
3753                                 case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR:
3754                                 case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR:
3755                                 case TEST_TYPE_DEPTH:
3756                                 case TEST_TYPE_STENCIL:
3757                                         targetGroup->addChild(groupShader.release());
3758                                         break;
3759                                 case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
3760                                 case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
3761                                 case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
3762                                 case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
3763                                         groupViewIndex->addChild(groupShader.release());
3764                                         break;
3765                                 default:
3766                                         DE_ASSERT(0);
3767                                         break;
3768                         };
3769                 }
3770
3771                 targetGroup->addChild(groupViewIndex.release());
3772
3773                 if (renderPassTypeNdx == 1)
3774                         group->addChild(groupRenderPass2.release());
3775         }
3776 }
3777
3778 } //MultiView
3779 } //vkt
3780