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