Merge gerrit/vulkan-cts-1.0.1 into gerrit/vulkan-cts-1.0.2
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / geometry / vktGeometryLayeredRenderingTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2014 The Android Open Source Project
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Geometry shader layered rendering tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktGeometryLayeredRenderingTests.hpp"
26 #include "vktTestCase.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktGeometryTestsUtil.hpp"
29
30 #include "vkPrograms.hpp"
31 #include "vkStrUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkImageUtil.hpp"
37
38 #include "deStringUtil.hpp"
39 #include "deUniquePtr.hpp"
40
41 #include "tcuTextureUtil.hpp"
42 #include "tcuVectorUtil.hpp"
43
44 namespace vkt
45 {
46 namespace geometry
47 {
48 namespace
49 {
50 using namespace vk;
51 using de::MovePtr;
52 using de::UniquePtr;
53 using tcu::Vec4;
54 using tcu::IVec3;
55
56 enum TestType
57 {
58         TEST_TYPE_DEFAULT_LAYER,                                        // !< draw to default layer
59         TEST_TYPE_SINGLE_LAYER,                                         // !< draw to single layer
60         TEST_TYPE_ALL_LAYERS,                                           // !< draw all layers
61         TEST_TYPE_DIFFERENT_CONTENT,                            // !< draw different content to different layers
62         TEST_TYPE_LAYER_ID,                                                     // !< draw to all layers, verify gl_Layer fragment input
63         TEST_TYPE_INVOCATION_PER_LAYER,                         // !< draw to all layers, one invocation per layer
64         TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION,       // !< draw to all layers, multiple invocations write to multiple layers
65 };
66
67 struct ImageParams
68 {
69         VkImageViewType         viewType;
70         VkExtent3D                      size;
71         deUint32                        numLayers;
72 };
73
74 struct TestParams
75 {
76         TestType                        testType;
77         ImageParams                     image;
78 };
79
80 static const float s_colors[][4] =
81 {
82         { 1.0f, 1.0f, 1.0f, 1.0f },             // white
83         { 1.0f, 0.0f, 0.0f, 1.0f },             // red
84         { 0.0f, 1.0f, 0.0f, 1.0f },             // green
85         { 0.0f, 0.0f, 1.0f, 1.0f },             // blue
86         { 1.0f, 1.0f, 0.0f, 1.0f },             // yellow
87         { 1.0f, 0.0f, 1.0f, 1.0f },             // magenta
88 };
89
90 deUint32 getTargetLayer (const ImageParams& imageParams)
91 {
92         if (imageParams.viewType == VK_IMAGE_VIEW_TYPE_3D)
93                 return imageParams.size.depth / 2;
94         else
95                 return imageParams.numLayers / 2;
96 }
97
98 std::string getShortImageViewTypeName (const VkImageViewType imageViewType)
99 {
100         std::string s(getImageViewTypeName(imageViewType));
101         return de::toLower(s.substr(19));
102 }
103
104 VkImageType getImageType (const VkImageViewType viewType)
105 {
106         switch (viewType)
107         {
108                 case VK_IMAGE_VIEW_TYPE_1D:
109                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
110                         return VK_IMAGE_TYPE_1D;
111
112                 case VK_IMAGE_VIEW_TYPE_2D:
113                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
114                 case VK_IMAGE_VIEW_TYPE_CUBE:
115                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
116                         return VK_IMAGE_TYPE_2D;
117
118                 case VK_IMAGE_VIEW_TYPE_3D:
119                         return VK_IMAGE_TYPE_3D;
120
121                 default:
122                         DE_ASSERT(0);
123                         return VK_IMAGE_TYPE_LAST;
124         }
125 }
126
127 inline bool isCubeImageViewType (const VkImageViewType viewType)
128 {
129         return viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
130 }
131
132 VkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const VkImageUsageFlags usage)
133 {
134         const VkImageCreateInfo imageParams =
135         {
136                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType;
137                 DE_NULL,                                                                                // const void*                          pNext;
138                 flags,                                                                                  // VkImageCreateFlags           flags;
139                 type,                                                                                   // VkImageType                          imageType;
140                 format,                                                                                 // VkFormat                                     format;
141                 size,                                                                                   // VkExtent3D                           extent;
142                 1u,                                                                                             // deUint32                                     mipLevels;
143                 numLayers,                                                                              // deUint32                                     arrayLayers;
144                 VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits        samples;
145                 VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling;
146                 usage,                                                                                  // VkImageUsageFlags            usage;
147                 VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode;
148                 0u,                                                                                             // deUint32                                     queueFamilyIndexCount;
149                 DE_NULL,                                                                                // const deUint32*                      pQueueFamilyIndices;
150                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        initialLayout;
151         };
152         return imageParams;
153 }
154
155 Move<VkRenderPass> makeRenderPass (const DeviceInterface&       vk,
156                                                                    const VkDevice                       device,
157                                                                    const VkFormat                       colorFormat)
158 {
159         const VkAttachmentDescription colorAttachmentDescription =
160         {
161                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
162                 colorFormat,                                                                            // VkFormat                                                     format;
163                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
164                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
165                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
166                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
167                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
168                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout;
169                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
170         };
171
172         const VkAttachmentReference colorAttachmentRef =
173         {
174                 0u,                                                                                                     // deUint32                     attachment;
175                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
176         };
177
178         const VkSubpassDescription subpassDescription =
179         {
180                 (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
181                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
182                 0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
183                 DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
184                 1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
185                 &colorAttachmentRef,                                                            // const VkAttachmentReference*         pColorAttachments;
186                 DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
187                 DE_NULL,                                                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
188                 0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
189                 DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
190         };
191
192         const VkRenderPassCreateInfo renderPassInfo =
193         {
194                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
195                 DE_NULL,                                                                                        // const void*                                          pNext;
196                 (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
197                 1u,                                                                                                     // deUint32                                                     attachmentCount;
198                 &colorAttachmentDescription,                                            // const VkAttachmentDescription*       pAttachments;
199                 1u,                                                                                                     // deUint32                                                     subpassCount;
200                 &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
201                 0u,                                                                                                     // deUint32                                                     dependencyCount;
202                 DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
203         };
204
205         return createRenderPass(vk, device, &renderPassInfo);
206 }
207
208 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&           vk,
209                                                                            const VkDevice                               device,
210                                                                            const VkPipelineLayout               pipelineLayout,
211                                                                            const VkRenderPass                   renderPass,
212                                                                            const VkShaderModule                 vertexModule,
213                                                                            const VkShaderModule                 geometryModule,
214                                                                            const VkShaderModule                 fragmentModule,
215                                                                            const VkExtent2D                             renderSize)
216 {
217         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
218         {
219                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                             sType;
220                 DE_NULL,                                                                                                                // const void*                                 pNext;
221                 (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags       flags;
222                 0u,                                                                                                                             // uint32_t                                    vertexBindingDescriptionCount;
223                 DE_NULL,                                                                                                                // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
224                 0u,                                                                                                                             // uint32_t                                    vertexAttributeDescriptionCount;
225                 DE_NULL,                                                                                                                // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
226         };
227
228         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
229         {
230                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
231                 DE_NULL,                                                                                                                // const void*                                 pNext;
232                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags     flags;
233                 VK_PRIMITIVE_TOPOLOGY_POINT_LIST,                                                               // VkPrimitiveTopology                         topology;
234                 VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
235         };
236
237         const VkViewport viewport = makeViewport(
238                 0.0f, 0.0f,
239                 static_cast<float>(renderSize.width), static_cast<float>(renderSize.height),
240                 0.0f, 1.0f);
241         const VkRect2D scissor =
242         {
243                 makeOffset2D(0, 0),
244                 makeExtent2D(renderSize.width, renderSize.height),
245         };
246
247         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
248         {
249                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                             sType;
250                 DE_NULL,                                                                                                                // const void*                                 pNext;
251                 (VkPipelineViewportStateCreateFlags)0,                                                  // VkPipelineViewportStateCreateFlags          flags;
252                 1u,                                                                                                                             // uint32_t                                    viewportCount;
253                 &viewport,                                                                                                              // const VkViewport*                           pViewports;
254                 1u,                                                                                                                             // uint32_t                                    scissorCount;
255                 &scissor,                                                                                                               // const VkRect2D*                             pScissors;
256         };
257
258         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
259         {
260                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
261                 DE_NULL,                                                                                                                // const void*                              pNext;
262                 (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags  flags;
263                 VK_FALSE,                                                                                                               // VkBool32                                 depthClampEnable;
264                 VK_FALSE,                                                                                                               // VkBool32                                 rasterizerDiscardEnable;
265                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
266                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
267                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
268                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
269                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
270                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
271                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
272                 1.0f,                                                                                                                   // float                                                                        lineWidth;
273         };
274
275         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
276         {
277                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
278                 DE_NULL,                                                                                                                // const void*                                                          pNext;
279                 (VkPipelineMultisampleStateCreateFlags)0,                                               // VkPipelineMultisampleStateCreateFlags        flags;
280                 VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
281                 VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
282                 0.0f,                                                                                                                   // float                                                                        minSampleShading;
283                 DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
284                 VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
285                 VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
286         };
287
288         const VkStencilOpState stencilOpState = makeStencilOpState(
289                 VK_STENCIL_OP_KEEP,                             // stencil fail
290                 VK_STENCIL_OP_KEEP,                             // depth & stencil pass
291                 VK_STENCIL_OP_KEEP,                             // depth only fail
292                 VK_COMPARE_OP_ALWAYS,                   // compare op
293                 0u,                                                             // compare mask
294                 0u,                                                             // write mask
295                 0u);                                                    // reference
296
297         VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
298         {
299                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
300                 DE_NULL,                                                                                                                // const void*                                                          pNext;
301                 (VkPipelineDepthStencilStateCreateFlags)0,                                              // VkPipelineDepthStencilStateCreateFlags       flags;
302                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthTestEnable;
303                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthWriteEnable;
304                 VK_COMPARE_OP_LESS,                                                                                             // VkCompareOp                                                          depthCompareOp;
305                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBoundsTestEnable;
306                 VK_FALSE,                                                                                                               // VkBool32                                                                     stencilTestEnable;
307                 stencilOpState,                                                                                                 // VkStencilOpState                                                     front;
308                 stencilOpState,                                                                                                 // VkStencilOpState                                                     back;
309                 0.0f,                                                                                                                   // float                                                                        minDepthBounds;
310                 1.0f,                                                                                                                   // float                                                                        maxDepthBounds;
311         };
312
313         const VkColorComponentFlags                                     colorComponentsAll                                      = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
314         const VkPipelineColorBlendAttachmentState       pipelineColorBlendAttachmentState       =
315         {
316                 VK_FALSE,                                               // VkBool32                                     blendEnable;
317                 VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcColorBlendFactor;
318                 VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        dstColorBlendFactor;
319                 VK_BLEND_OP_ADD,                                // VkBlendOp                            colorBlendOp;
320                 VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcAlphaBlendFactor;
321                 VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        dstAlphaBlendFactor;
322                 VK_BLEND_OP_ADD,                                // VkBlendOp                            alphaBlendOp;
323                 colorComponentsAll,                             // VkColorComponentFlags        colorWriteMask;
324         };
325
326         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
327         {
328                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,               // VkStructureType                                                              sType;
329                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
330                 (VkPipelineColorBlendStateCreateFlags)0,                                                // VkPipelineColorBlendStateCreateFlags                 flags;
331                 VK_FALSE,                                                                                                               // VkBool32                                                                             logicOpEnable;
332                 VK_LOGIC_OP_COPY,                                                                                               // VkLogicOp                                                                    logicOp;
333                 1u,                                                                                                                             // deUint32                                                                             attachmentCount;
334                 &pipelineColorBlendAttachmentState,                                                             // const VkPipelineColorBlendAttachmentState*   pAttachments;
335                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                             // float                                                                                blendConstants[4];
336         };
337
338         const VkPipelineShaderStageCreateInfo pShaderStages[] =
339         {
340                 {
341                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
342                         DE_NULL,                                                                                                        // const void*                                                  pNext;
343                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
344                         VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
345                         vertexModule,                                                                                           // VkShaderModule                                               module;
346                         "main",                                                                                                         // const char*                                                  pName;
347                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                  pSpecializationInfo;
348                 },
349                 {
350                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
351                         DE_NULL,                                                                                                        // const void*                                                  pNext;
352                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
353                         VK_SHADER_STAGE_GEOMETRY_BIT,                                                           // VkShaderStageFlagBits                                stage;
354                         geometryModule,                                                                                         // VkShaderModule                                               module;
355                         "main",                                                                                                         // const char*                                                  pName;
356                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                  pSpecializationInfo;
357                 },
358                 {
359                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
360                         DE_NULL,                                                                                                        // const void*                                                  pNext;
361                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
362                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
363                         fragmentModule,                                                                                         // VkShaderModule                                               module;
364                         "main",                                                                                                         // const char*                                                  pName;
365                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                  pSpecializationInfo;
366                 },
367         };
368
369         const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
370         {
371                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
372                 DE_NULL,                                                                                        // const void*                                                                          pNext;
373                 (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                                                        flags;
374                 DE_LENGTH_OF_ARRAY(pShaderStages),                                      // deUint32                                                                                     stageCount;
375                 pShaderStages,                                                                          // const VkPipelineShaderStageCreateInfo*                       pStages;
376                 &vertexInputStateInfo,                                                          // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
377                 &pipelineInputAssemblyStateInfo,                                        // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
378                 DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
379                 &pipelineViewportStateInfo,                                                     // const VkPipelineViewportStateCreateInfo*                     pViewportState;
380                 &pipelineRasterizationStateInfo,                                        // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
381                 &pipelineMultisampleStateInfo,                                          // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
382                 &pipelineDepthStencilStateInfo,                                         // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
383                 &pipelineColorBlendStateInfo,                                           // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
384                 DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
385                 pipelineLayout,                                                                         // VkPipelineLayout                                                                     layout;
386                 renderPass,                                                                                     // VkRenderPass                                                                         renderPass;
387                 0u,                                                                                                     // deUint32                                                                                     subpass;
388                 DE_NULL,                                                                                        // VkPipeline                                                                           basePipelineHandle;
389                 0,                                                                                                      // deInt32                                                                                      basePipelineIndex;
390         };
391
392         return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
393 }
394
395 //! Convenience wrapper to access 1D, 2D, and 3D image layers/slices in a uniform way.
396 class LayeredImageAccess
397 {
398 public:
399         static LayeredImageAccess create (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData)
400         {
401                 if (type == VK_IMAGE_TYPE_1D)
402                         return LayeredImageAccess(format, size.width, numLayers, pData);
403                 else
404                         return LayeredImageAccess(type, format, size, numLayers, pData);
405         }
406
407         inline tcu::ConstPixelBufferAccess getLayer (const int layer) const
408         {
409                 return tcu::getSubregion(m_wholeImage, 0, (m_1dModifier * layer), ((~m_1dModifier & 1) * layer), m_width, m_height, 1);
410         }
411
412         inline int getNumLayersOrSlices (void) const
413         {
414                 return m_layers;
415         }
416
417 private:
418         // Specialized for 1D images.
419         LayeredImageAccess (const VkFormat format, const deUint32 width, const deUint32 numLayers, const void* pData)
420                 : m_width               (static_cast<int>(width))
421                 , m_height              (1)
422                 , m_1dModifier  (1)
423                 , m_layers              (numLayers)
424                 , m_wholeImage  (tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_layers, 1, pData))
425         {
426         }
427
428         LayeredImageAccess (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData)
429                 : m_width               (static_cast<int>(size.width))
430                 , m_height              (static_cast<int>(size.height))
431                 , m_1dModifier  (0)
432                 , m_layers              (static_cast<int>(type == VK_IMAGE_TYPE_3D ? size.depth : numLayers))
433                 , m_wholeImage  (tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_height, m_layers, pData))
434         {
435         }
436
437         const int                                                       m_width;
438         const int                                                       m_height;
439         const int                                                       m_1dModifier;
440         const int                                                       m_layers;
441         const tcu::ConstPixelBufferAccess       m_wholeImage;
442 };
443
444 inline bool compareColors (const Vec4& colorA, const Vec4& colorB, const Vec4& threshold)
445 {
446         return tcu::allEqual(
447                                 tcu::lessThan(tcu::abs(colorA - colorB), threshold),
448                                 tcu::BVec4(true, true, true, true));
449 }
450
451 bool verifyImageSingleColoredRow (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image, const float rowWidthRatio, const tcu::Vec4& barColor)
452 {
453         DE_ASSERT(rowWidthRatio > 0.0f);
454
455         const Vec4                              black                           (0.0f, 0.0f, 0.0f, 1.0f);
456         const Vec4                              green                           (0.0f, 1.0f, 0.0f, 1.0f);
457         const Vec4                              red                                     (1.0f, 0.0f, 0.0f, 1.0f);
458         const Vec4                              threshold                       (0.02f);
459         const int                               barLength                       = static_cast<int>(rowWidthRatio * static_cast<float>(image.getWidth()));
460         const int                               barLengthThreshold      = 1;
461         tcu::TextureLevel               errorMask                       (image.getFormat(), image.getWidth(), image.getHeight());
462         tcu::PixelBufferAccess  errorMaskAccess         = errorMask.getAccess();
463
464         tcu::clear(errorMask.getAccess(), green);
465
466         log << tcu::TestLog::Message
467                 << "Expecting all pixels with distance less or equal to (about) " << barLength
468                 << " pixels from left border to be of color " << barColor.swizzle(0, 1, 2) << "."
469                 << tcu::TestLog::EndMessage;
470
471         bool allPixelsOk = true;
472
473         for (int y = 0; y < image.getHeight(); ++y)
474         for (int x = 0; x < image.getWidth();  ++x)
475         {
476                 const Vec4      color           = image.getPixel(x, y);
477                 const bool      isBlack         = compareColors(color, black, threshold);
478                 const bool      isColor         = compareColors(color, barColor, threshold);
479
480                 bool isOk;
481
482                 if (x <= barLength - barLengthThreshold)
483                         isOk = isColor;
484                 else if (x >= barLength + barLengthThreshold)
485                         isOk = isBlack;
486                 else
487                         isOk = isColor || isBlack;
488
489                 allPixelsOk &= isOk;
490
491                 if (!isOk)
492                         errorMaskAccess.setPixel(red, x, y);
493         }
494
495         if (allPixelsOk)
496         {
497                 log << tcu::TestLog::Message << "Image is valid." << tcu::TestLog::EndMessage
498                         << tcu::TestLog::ImageSet("LayerContent", "Layer content")
499                         << tcu::TestLog::Image("Layer", "Layer", image)
500                         << tcu::TestLog::EndImageSet;
501                 return true;
502         }
503         else
504         {
505                 log << tcu::TestLog::Message << "Image verification failed. Got unexpected pixels." << tcu::TestLog::EndMessage
506                         << tcu::TestLog::ImageSet("LayerContent", "Layer content")
507                         << tcu::TestLog::Image("Layer",         "Layer",        image)
508                         << tcu::TestLog::Image("ErrorMask",     "Errors",       errorMask)
509                         << tcu::TestLog::EndImageSet;
510                 return false;
511         }
512
513         log << tcu::TestLog::Image("LayerContent", "Layer content", image);
514
515         return allPixelsOk;
516 }
517
518 bool verifyEmptyImage (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image)
519 {
520         log << tcu::TestLog::Message << "Expecting empty image" << tcu::TestLog::EndMessage;
521
522         const Vec4      black           (0.0f, 0.0f, 0.0f, 1.0f);
523         const Vec4      threshold       (0.02f);
524
525         for (int y = 0; y < image.getHeight(); ++y)
526         for (int x = 0; x < image.getWidth();  ++x)
527         {
528                 const Vec4 color = image.getPixel(x, y);
529
530                 if (!compareColors(color, black, threshold))
531                 {
532                         log     << tcu::TestLog::Message
533                                 << "Found (at least) one bad pixel at " << x << "," << y << ". Pixel color is not background color."
534                                 << tcu::TestLog::EndMessage
535                                 << tcu::TestLog::ImageSet("LayerContent", "Layer content")
536                                 << tcu::TestLog::Image("Layer", "Layer", image)
537                                 << tcu::TestLog::EndImageSet;
538                         return false;
539                 }
540         }
541
542         log << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage;
543
544         return true;
545 }
546
547 bool verifyLayerContent (tcu::TestLog& log, const TestType testType, const tcu::ConstPixelBufferAccess image, const int layerNdx, const int numLayers)
548 {
549         const Vec4      white                           (1.0f, 1.0f, 1.0f, 1.0f);
550         const int       targetLayer                     = numLayers / 2;
551         const float     variableBarRatio        = static_cast<float>(layerNdx) / static_cast<float>(numLayers);
552
553         switch (testType)
554         {
555                 case TEST_TYPE_DEFAULT_LAYER:
556                         if (layerNdx == 0)
557                                 return verifyImageSingleColoredRow(log, image, 0.5f, white);
558                         else
559                                 return verifyEmptyImage(log, image);
560
561                 case TEST_TYPE_SINGLE_LAYER:
562                         if (layerNdx == targetLayer)
563                                 return verifyImageSingleColoredRow(log, image, 0.5f, white);
564                         else
565                                 return verifyEmptyImage(log, image);
566
567                 case TEST_TYPE_ALL_LAYERS:
568                 case TEST_TYPE_INVOCATION_PER_LAYER:
569                         return verifyImageSingleColoredRow(log, image, 0.5f, s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)]);
570
571                 case TEST_TYPE_DIFFERENT_CONTENT:
572                 case TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION:
573                         if (layerNdx == 0)
574                                 return verifyEmptyImage(log, image);
575                         else
576                                 return verifyImageSingleColoredRow(log, image, variableBarRatio, white);
577
578                 case TEST_TYPE_LAYER_ID:
579                 {
580                         // This code must be in sync with the fragment shader.
581                         const tcu::Vec4 layerColor( (layerNdx    % 2) == 1 ? 1.0f : 0.5f,
582                                                                            ((layerNdx/2) % 2) == 1 ? 1.0f : 0.5f,
583                                                                              layerNdx         == 0 ? 1.0f : 0.0f,
584                                                                                                                                  1.0f);
585                         return verifyImageSingleColoredRow(log, image, 0.5f, layerColor);
586                 }
587
588                 default:
589                         DE_ASSERT(0);
590                         return false;
591         };
592 }
593
594 std::string getLayerDescription (const VkImageViewType viewType, const int layer)
595 {
596         std::ostringstream str;
597         const int numCubeFaces = 6;
598
599         if (isCubeImageViewType(viewType))
600                 str << "cube " << (layer / numCubeFaces) << ", face " << (layer % numCubeFaces);
601         else if (viewType == VK_IMAGE_VIEW_TYPE_3D)
602                 str << "slice z = " << layer;
603         else
604                 str << "layer " << layer;
605
606         return str.str();
607 }
608
609 bool verifyResults (tcu::TestLog& log, const TestParams& params, const VkFormat colorFormat, const void* resultData)
610 {
611         const LayeredImageAccess image = LayeredImageAccess::create(getImageType(params.image.viewType), colorFormat, params.image.size, params.image.numLayers, resultData);
612
613         int numGoodLayers = 0;
614
615         for (int layerNdx = 0; layerNdx < image.getNumLayersOrSlices(); ++layerNdx)
616         {
617                 const tcu::ConstPixelBufferAccess layerImage = image.getLayer(layerNdx);
618
619                 log << tcu::TestLog::Message << "Verifying " << getLayerDescription(params.image.viewType, layerNdx) << tcu::TestLog::EndMessage;
620
621                 if (verifyLayerContent(log, params.testType, layerImage, layerNdx, image.getNumLayersOrSlices()))
622                         ++numGoodLayers;
623         }
624
625         return numGoodLayers == image.getNumLayersOrSlices();
626 }
627
628 std::string toGlsl (const Vec4& v)
629 {
630         std::ostringstream str;
631         str << "vec4(";
632         for (int i = 0; i < 4; ++i)
633                 str << (i != 0 ? ", " : "") << de::floatToString(v[i], 1);
634         str << ")";
635         return str.str();
636 }
637
638 void initPrograms (SourceCollections& programCollection, const TestParams params)
639 {
640         const bool geomOutputColor = (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_INVOCATION_PER_LAYER);
641
642         // Vertex shader
643         {
644                 std::ostringstream src;
645                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
646                         << "\n"
647                         << "void main(void)\n"
648                         << "{\n"
649                         << "}\n";
650
651                 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
652         }
653
654         // Geometry shader
655         {
656                 const int maxVertices = (params.testType == TEST_TYPE_DIFFERENT_CONTENT)                                                                        ? (params.image.numLayers + 1) * params.image.numLayers :
657                                                                 (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_LAYER_ID)      ? params.image.numLayers * 4 :
658                                                                 (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION)                                           ? 6 : 4;
659
660                 std::ostringstream src;
661                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
662                         << "\n";
663
664                 if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER || params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION)
665                         src << "layout(points, invocations = " << params.image.numLayers << ") in;\n";
666                 else
667                         src << "layout(points) in;\n";
668
669                 src << "layout(triangle_strip, max_vertices = " << maxVertices << ") out;\n"
670                         << "\n"
671                         << (geomOutputColor ? "layout(location = 0) out vec4 vert_color;\n\n" : "")
672                         << "out gl_PerVertex {\n"
673                         << "    vec4 gl_Position;\n"
674                         << "};\n"
675                         << "\n"
676                         << "void main(void)\n"
677                         << "{\n";
678
679                 std::ostringstream colorTable;
680                 {
681                         const int numColors = DE_LENGTH_OF_ARRAY(s_colors);
682
683                         colorTable << "    const vec4 colors[" << numColors << "] = vec4[" << numColors << "](";
684
685                         const std::string padding(colorTable.str().length(), ' ');
686
687                         for (int i = 0; i < numColors; ++i)
688                                 colorTable << (i != 0 ? ",\n" + padding : "") << toGlsl(s_colors[i]);
689
690                         colorTable << ");\n";
691                 }
692
693                 if (params.testType == TEST_TYPE_DEFAULT_LAYER)
694                 {
695                         src << "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
696                                 << "    EmitVertex();\n"
697                                 << "\n"
698                                 << "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
699                                 << "    EmitVertex();\n"
700                                 << "\n"
701                                 << "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
702                                 << "    EmitVertex();\n"
703                                 << "\n"
704                                 << "    gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
705                                 << "    EmitVertex();\n";
706                 }
707                 else if (params.testType == TEST_TYPE_SINGLE_LAYER)
708                 {
709                         const deUint32 targetLayer = getTargetLayer(params.image);
710
711                         src << "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
712                                 << "    gl_Layer    = " << targetLayer << ";\n"
713                                 << "    EmitVertex();\n"
714                                 << "\n"
715                                 << "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
716                                 << "    gl_Layer    = " << targetLayer << ";\n"
717                                 << "    EmitVertex();\n"
718                                 << "\n"
719                                 << "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
720                                 << "    gl_Layer    = " << targetLayer << ";\n"
721                                 << "    EmitVertex();\n"
722                                 << "\n"
723                                 << "    gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
724                                 << "    gl_Layer    = " << targetLayer << ";\n"
725                                 << "    EmitVertex();\n";
726                 }
727                 else if (params.testType == TEST_TYPE_ALL_LAYERS)
728                 {
729                         src << colorTable.str()
730                                 << "\n"
731                                 << "    for (int layerNdx = 0; layerNdx < " << params.image.numLayers << "; ++layerNdx) {\n"
732                                 << "        const int colorNdx = layerNdx % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n"
733                                 << "\n"
734                                 << "        gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
735                                 << "        gl_Layer    = layerNdx;\n"
736                                 << "        vert_color  = colors[colorNdx];\n"
737                                 << "        EmitVertex();\n"
738                                 << "\n"
739                                 << "        gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
740                                 << "        gl_Layer    = layerNdx;\n"
741                                 << "        vert_color  = colors[colorNdx];\n"
742                                 << "        EmitVertex();\n"
743                                 << "\n"
744                                 << "        gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
745                                 << "        gl_Layer    = layerNdx;\n"
746                                 << "        vert_color  = colors[colorNdx];\n"
747                                 << "        EmitVertex();\n"
748                                 << "\n"
749                                 << "        gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
750                                 << "        gl_Layer    = layerNdx;\n"
751                                 << "        vert_color  = colors[colorNdx];\n"
752                                 << "        EmitVertex();\n"
753                                 << "        EndPrimitive();\n"
754                                 << "    };\n";
755                 }
756                 else if (params.testType == TEST_TYPE_LAYER_ID)
757                 {
758                         src << "    for (int layerNdx = 0; layerNdx < " << params.image.numLayers << "; ++layerNdx) {\n"
759                                 << "        gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
760                                 << "        gl_Layer    = layerNdx;\n"
761                                 << "        EmitVertex();\n"
762                                 << "\n"
763                                 << "        gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
764                                 << "        gl_Layer    = layerNdx;\n"
765                                 << "        EmitVertex();\n"
766                                 << "\n"
767                                 << "        gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
768                                 << "        gl_Layer    = layerNdx;\n"
769                                 << "        EmitVertex();\n"
770                                 << "\n"
771                                 << "        gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
772                                 << "        gl_Layer    = layerNdx;\n"
773                                 << "        EmitVertex();\n"
774                                 << "        EndPrimitive();\n"
775                                 << "    };\n";
776                 }
777                 else if (params.testType == TEST_TYPE_DIFFERENT_CONTENT)
778                 {
779                         src << "    for (int layerNdx = 0; layerNdx < " << params.image.numLayers << "; ++layerNdx) {\n"
780                                 << "        for (int colNdx = 0; colNdx <= layerNdx; ++colNdx) {\n"
781                                 << "            const float posX = float(colNdx) / float(" << params.image.numLayers << ") * 2.0 - 1.0;\n"
782                                 << "\n"
783                                 << "            gl_Position = vec4(posX,  1.0, 0.0, 1.0);\n"
784                                 << "            gl_Layer    = layerNdx;\n"
785                                 << "            EmitVertex();\n"
786                                 << "\n"
787                                 << "            gl_Position = vec4(posX, -1.0, 0.0, 1.0);\n"
788                                 << "            gl_Layer    = layerNdx;\n"
789                                 << "            EmitVertex();\n"
790                                 << "        }\n"
791                                 << "        EndPrimitive();\n"
792                                 << "    }\n";
793                 }
794                 else if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER)
795                 {
796                         src << colorTable.str()
797                                 << "    const int colorNdx = gl_InvocationID % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n"
798                                 << "\n"
799                                 << "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
800                                 << "    gl_Layer    = gl_InvocationID;\n"
801                                 << "    vert_color  = colors[colorNdx];\n"
802                                 << "    EmitVertex();\n"
803                                 << "\n"
804                                 << "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
805                                 << "    gl_Layer    = gl_InvocationID;\n"
806                                 << "    vert_color  = colors[colorNdx];\n"
807                                 << "    EmitVertex();\n"
808                                 << "\n"
809                                 << "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
810                                 << "    gl_Layer    = gl_InvocationID;\n"
811                                 << "    vert_color  = colors[colorNdx];\n"
812                                 << "    EmitVertex();\n"
813                                 << "\n"
814                                 << "    gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
815                                 << "    gl_Layer    = gl_InvocationID;\n"
816                                 << "    vert_color  = colors[colorNdx];\n"
817                                 << "    EmitVertex();\n"
818                                 << "    EndPrimitive();\n";
819                 }
820                 else if (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION)
821                 {
822                         src << "    const int   layerA = gl_InvocationID;\n"
823                                 << "    const int   layerB = (gl_InvocationID + 1) % " << params.image.numLayers << ";\n"
824                                 << "    const float aEnd   = float(layerA) / float(" << params.image.numLayers << ") * 2.0 - 1.0;\n"
825                                 << "    const float bEnd   = float(layerB) / float(" << params.image.numLayers << ") * 2.0 - 1.0;\n"
826                                 << "\n"
827                                 << "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
828                                 << "    gl_Layer    = layerA;\n"
829                                 << "    EmitVertex();\n"
830                                 << "\n"
831                                 << "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
832                                 << "    gl_Layer    = layerA;\n"
833                                 << "    EmitVertex();\n"
834                                 << "\n"
835                                 << "    gl_Position = vec4(aEnd, -1.0, 0.0, 1.0);\n"
836                                 << "    gl_Layer    = layerA;\n"
837                                 << "    EmitVertex();\n"
838                                 << "    EndPrimitive();\n"
839                                 << "\n"
840                                 << "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
841                                 << "    gl_Layer    = layerB;\n"
842                                 << "    EmitVertex();\n"
843                                 << "\n"
844                                 << "    gl_Position = vec4(bEnd,  1.0, 0.0, 1.0);\n"
845                                 << "    gl_Layer    = layerB;\n"
846                                 << "    EmitVertex();\n"
847                                 << "\n"
848                                 << "    gl_Position = vec4(bEnd, -1.0, 0.0, 1.0);\n"
849                                 << "    gl_Layer    = layerB;\n"
850                                 << "    EmitVertex();\n"
851                                 << "    EndPrimitive();\n";
852                 }
853                 else
854                         DE_ASSERT(0);
855
856                 src <<  "}\n";  // end main
857
858                 programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
859         }
860
861         // Fragment shader
862         {
863                 std::ostringstream src;
864                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
865                         << "\n"
866                         << "layout(location = 0) out vec4 o_color;\n"
867                         << (geomOutputColor ? "layout(location = 0) in  vec4 vert_color;\n" : "")
868                         << "\n"
869                         << "void main(void)\n"
870                         << "{\n";
871
872                 if (params.testType == TEST_TYPE_LAYER_ID)
873                 {
874                         // This code must be in sync with verifyLayerContent()
875                         src << "    o_color = vec4( (gl_Layer    % 2) == 1 ? 1.0 : 0.5,\n"
876                                 << "                   ((gl_Layer/2) % 2) == 1 ? 1.0 : 0.5,\n"
877                                 << "                     gl_Layer         == 0 ? 1.0 : 0.0,\n"
878                                 << "                                             1.0);\n";
879                 }
880                 else if (geomOutputColor)
881                         src << "    o_color = vert_color;\n";
882                 else
883                         src << "    o_color = vec4(1.0);\n";
884
885                 src << "}\n";
886
887                 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
888         }
889 }
890
891 tcu::TestStatus test (Context& context, const TestParams params)
892 {
893         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
894         const InstanceInterface&                vki                                     = context.getInstanceInterface();
895         const VkDevice                                  device                          = context.getDevice();
896         const VkPhysicalDevice                  physDevice                      = context.getPhysicalDevice();
897         const deUint32                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
898         const VkQueue                                   queue                           = context.getUniversalQueue();
899         Allocator&                                              allocator                       = context.getDefaultAllocator();
900
901         checkGeometryShaderSupport(vki, physDevice);
902
903         const VkFormat                                  colorFormat                             = VK_FORMAT_R8G8B8A8_UNORM;
904         const VkImageSubresourceRange   colorSubresourceRange   = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.image.numLayers);
905         const Vec4                                              clearColor                              = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
906         const VkDeviceSize                              colorBufferSize                 = params.image.size.width * params.image.size.height * params.image.size.depth * params.image.numLayers * tcu::getPixelSize(mapVkFormat(colorFormat));
907         const VkImageCreateFlags                imageCreateFlags                = (isCubeImageViewType(params.image.viewType) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlagBits)0);
908
909         const Unique<VkImage>                   colorImage                      (makeImage                              (vk, device, makeImageCreateInfo(imageCreateFlags, getImageType(params.image.viewType), colorFormat, params.image.size,
910                                                                                                                                                                  params.image.numLayers, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
911         const UniquePtr<Allocation>             colorImageAlloc         (bindImage                              (vk, device, allocator, *colorImage, MemoryRequirement::Any));
912         const Unique<VkImageView>               colorAttachment         (makeImageView                  (vk, device, *colorImage, params.image.viewType, colorFormat, colorSubresourceRange));
913         const Unique<VkBuffer>                  colorBuffer                     (makeBuffer                             (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
914         const UniquePtr<Allocation>             colorBufferAlloc        (bindBuffer                             (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
915
916         const Unique<VkShaderModule>    vertexModule            (createShaderModule             (vk, device, context.getBinaryCollection().get("vert"), 0u));
917         const Unique<VkShaderModule>    geometryModule          (createShaderModule             (vk, device, context.getBinaryCollection().get("geom"), 0u));
918         const Unique<VkShaderModule>    fragmentModule          (createShaderModule             (vk, device, context.getBinaryCollection().get("frag"), 0u));
919
920         const Unique<VkRenderPass>              renderPass                      (makeRenderPass                 (vk, device, colorFormat));
921         const Unique<VkFramebuffer>             framebuffer                     (makeFramebuffer                (vk, device, *renderPass, *colorAttachment, params.image.size.width,  params.image.size.height, params.image.numLayers));
922         const Unique<VkPipelineLayout>  pipelineLayout          (makePipelineLayout             (vk, device));
923         const Unique<VkPipeline>                pipeline                        (makeGraphicsPipeline   (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geometryModule, *fragmentModule,
924                                                                                                                                                                  makeExtent2D(params.image.size.width, params.image.size.height)));
925         const Unique<VkCommandPool>             cmdPool                         (makeCommandPool                (vk, device, queueFamilyIndex));
926         const Unique<VkCommandBuffer>   cmdBuffer                       (makeCommandBuffer              (vk, device, *cmdPool));
927
928         zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize);
929
930         beginCommandBuffer(vk, *cmdBuffer);
931
932         const VkClearValue                      clearValue      = makeClearValueColor(clearColor);
933         const VkRect2D                          renderArea      =
934         {
935                 makeOffset2D(0, 0),
936                 makeExtent2D(params.image.size.width, params.image.size.height),
937         };
938         const VkRenderPassBeginInfo renderPassBeginInfo =
939         {
940                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType         sType;
941                 DE_NULL,                                                                                // const void*             pNext;
942                 *renderPass,                                                                    // VkRenderPass            renderPass;
943                 *framebuffer,                                                                   // VkFramebuffer           framebuffer;
944                 renderArea,                                                                             // VkRect2D                renderArea;
945                 1u,                                                                                             // uint32_t                clearValueCount;
946                 &clearValue,                                                                    // const VkClearValue*     pClearValues;
947         };
948         vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
949
950         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
951         vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u);
952         vk.cmdEndRenderPass(*cmdBuffer);
953
954         // Prepare color image for copy
955         {
956                 const VkImageMemoryBarrier barriers[] =
957                 {
958                         {
959                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
960                                 DE_NULL,                                                                                // const void*                          pNext;
961                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags                        outputMask;
962                                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags                        inputMask;
963                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               // VkImageLayout                        oldLayout;
964                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                   // VkImageLayout                        newLayout;
965                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
966                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
967                                 *colorImage,                                                                    // VkImage                                      image;
968                                 colorSubresourceRange,                                                  // VkImageSubresourceRange      subresourceRange;
969                         },
970                 };
971
972                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
973                         0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
974         }
975         // Color image -> host buffer
976         {
977                 const VkBufferImageCopy region =
978                 {
979                         0ull,                                                                                                                                                                           // VkDeviceSize                bufferOffset;
980                         0u,                                                                                                                                                                                     // uint32_t                    bufferRowLength;
981                         0u,                                                                                                                                                                                     // uint32_t                    bufferImageHeight;
982                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, params.image.numLayers),          // VkImageSubresourceLayers    imageSubresource;
983                         makeOffset3D(0, 0, 0),                                                                                                                                          // VkOffset3D                  imageOffset;
984                         params.image.size,                                                                                                                                                      // VkExtent3D                  imageExtent;
985                 };
986
987                 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
988         }
989         // Buffer write barrier
990         {
991                 const VkBufferMemoryBarrier barriers[] =
992                 {
993                         {
994                                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType    sType;
995                                 DE_NULL,                                                                                // const void*        pNext;
996                                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags      srcAccessMask;
997                                 VK_ACCESS_HOST_READ_BIT,                                                // VkAccessFlags      dstAccessMask;
998                                 VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t           srcQueueFamilyIndex;
999                                 VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t           dstQueueFamilyIndex;
1000                                 *colorBuffer,                                                                   // VkBuffer           buffer;
1001                                 0ull,                                                                                   // VkDeviceSize       offset;
1002                                 VK_WHOLE_SIZE,                                                                  // VkDeviceSize       size;
1003                         },
1004                 };
1005
1006                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1007                         0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers, DE_NULL, 0u);
1008         }
1009
1010         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1011         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1012
1013         invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), colorBufferSize);
1014
1015         if (!verifyResults(context.getTestContext().getLog(), params, colorFormat, colorBufferAlloc->getHostPtr()))
1016                 return tcu::TestStatus::fail("Rendered images are incorrect");
1017         else
1018                 return tcu::TestStatus::pass("OK");
1019 }
1020
1021 } // anonymous
1022
1023 tcu::TestCaseGroup* createLayeredRenderingTests (tcu::TestContext& testCtx)
1024 {
1025         MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "layered", "Layered rendering tests."));
1026
1027         const struct
1028         {
1029                 TestType                test;
1030                 const char*             name;
1031                 const char*             description;
1032         } testTypes[] =
1033         {
1034                 { TEST_TYPE_DEFAULT_LAYER,                                      "render_to_default_layer",                      "Render to the default layer"                                                                                                                   },
1035                 { TEST_TYPE_SINGLE_LAYER,                                       "render_to_one",                                        "Render to one layer"                                                                                                                                   },
1036                 { TEST_TYPE_ALL_LAYERS,                                         "render_to_all",                                        "Render to all layers"                                                                                                                                  },
1037                 { TEST_TYPE_DIFFERENT_CONTENT,                          "render_different_content",                     "Render different data to different layers"                                                                                             },
1038                 { TEST_TYPE_LAYER_ID,                                           "fragment_layer",                                       "Read gl_Layer in fragment shader"                                                                                                              },
1039                 { TEST_TYPE_INVOCATION_PER_LAYER,                       "invocation_per_layer",                         "Render to multiple layers with multiple invocations, one invocation per layer"                 },
1040                 { TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION,     "multiple_layers_per_invocation",       "Render to multiple layers with multiple invocations, multiple layers per invocation",  },
1041         };
1042
1043         const ImageParams imageParams[] =
1044         {
1045                 { VK_IMAGE_VIEW_TYPE_1D_ARRAY,          { 64,  1,  1 },         4       },
1046                 { VK_IMAGE_VIEW_TYPE_2D_ARRAY,          { 64, 64,  1 },         4       },
1047                 { VK_IMAGE_VIEW_TYPE_CUBE,                      { 64, 64,  1 },         6       },
1048                 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,        { 64, 64,  1 },         2*6     },
1049                 // No support for rendering to 3d image slices in Vulkan 1.0
1050         };
1051
1052         for (int imageParamNdx = 0; imageParamNdx < DE_LENGTH_OF_ARRAY(imageParams); ++imageParamNdx)
1053         {
1054                 MovePtr<tcu::TestCaseGroup> viewTypeGroup(new tcu::TestCaseGroup(testCtx, getShortImageViewTypeName(imageParams[imageParamNdx].viewType).c_str(), ""));
1055
1056                 for (int testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
1057                 {
1058                         const TestParams params =
1059                         {
1060                                 testTypes[testTypeNdx].test,
1061                                 imageParams[imageParamNdx],
1062                         };
1063                         addFunctionCaseWithPrograms(viewTypeGroup.get(), testTypes[testTypeNdx].name, testTypes[testTypeNdx].description, initPrograms, test, params);
1064                 }
1065
1066                 group->addChild(viewTypeGroup.release());
1067         }
1068
1069         return group.release();
1070 }
1071
1072 } // geometry
1073 } // vkt