Remove individual 3D slice layout transitions
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineRenderToImageTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file vktPipelineRenderToImageTests.cpp
21  * \brief Render to image tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktPipelineRenderToImageTests.hpp"
25 #include "vktPipelineMakeUtil.hpp"
26 #include "vktTestCase.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktTestGroupUtil.hpp"
30
31 #include "vkMemUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkImageUtil.hpp"
38
39 #include "tcuTextureUtil.hpp"
40 #include "tcuImageCompare.hpp"
41
42 #include "deUniquePtr.hpp"
43 #include "deSharedPtr.hpp"
44
45 #include <string>
46 #include <vector>
47
48 namespace vkt
49 {
50 namespace pipeline
51 {
52 namespace
53 {
54 using namespace vk;
55 using de::UniquePtr;
56 using de::MovePtr;
57 using de::SharedPtr;
58 using tcu::IVec3;
59 using tcu::Vec4;
60 using tcu::UVec4;
61 using tcu::IVec4;
62 using std::vector;
63
64 typedef SharedPtr<Unique<VkImageView> > SharedPtrVkImageView;
65 typedef SharedPtr<Unique<VkPipeline> >  SharedPtrVkPipeline;
66
67 enum Constants
68 {
69         REFERENCE_COLOR_VALUE = 125
70 };
71
72 struct CaseDef
73 {
74         VkImageViewType imageType;
75         IVec3                   renderSize;
76         int                             numLayers;
77         VkFormat                colorFormat;
78 };
79
80 template<typename T>
81 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
82 {
83         return SharedPtr<Unique<T> >(new Unique<T>(move));
84 }
85
86 template<typename T>
87 inline VkDeviceSize sizeInBytes (const vector<T>& vec)
88 {
89         return vec.size() * sizeof(vec[0]);
90 }
91
92 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&           vk,
93                                                                            const VkDevice                               device,
94                                                                            const VkPipelineLayout               pipelineLayout,
95                                                                            const VkRenderPass                   renderPass,
96                                                                            const VkShaderModule                 vertexModule,
97                                                                            const VkShaderModule                 fragmentModule,
98                                                                            const IVec3                                  renderSize,
99                                                                            const VkPrimitiveTopology    topology,
100                                                                            const deUint32                               subpass)
101 {
102         const VkVertexInputBindingDescription vertexInputBindingDescription =
103         {
104                 0u,                                                             // uint32_t                             binding;
105                 sizeof(Vertex4RGBA),                    // uint32_t                             stride;
106                 VK_VERTEX_INPUT_RATE_VERTEX,    // VkVertexInputRate    inputRate;
107         };
108
109         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
110         {
111                 {
112                         0u,                                                             // uint32_t                     location;
113                         0u,                                                             // uint32_t                     binding;
114                         VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat                     format;
115                         0u,                                                             // uint32_t                     offset;
116                 },
117                 {
118                         1u,                                                             // uint32_t                     location;
119                         0u,                                                             // uint32_t                     binding;
120                         VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat                     format;
121                         sizeof(Vec4),                                   // uint32_t                     offset;
122                 }
123         };
124
125         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
126         {
127                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
128                 DE_NULL,                                                                                                        // const void*                                                          pNext;
129                 (VkPipelineVertexInputStateCreateFlags)0,                                       // VkPipelineVertexInputStateCreateFlags        flags;
130                 1u,                                                                                                                     // uint32_t                                                                     vertexBindingDescriptionCount;
131                 &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
132                 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),           // uint32_t                                                                     vertexAttributeDescriptionCount;
133                 vertexInputAttributeDescriptions,                                                       // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
134         };
135
136         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
137         {
138                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
139                 DE_NULL,                                                                                                                // const void*                                                          pNext;
140                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
141                 topology,                                                                                                               // VkPrimitiveTopology                                          topology;
142                 VK_FALSE,                                                                                                               // VkBool32                                                                     primitiveRestartEnable;
143         };
144
145         const VkViewport viewport = makeViewport(
146                 0.0f, 0.0f,
147                 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
148                 0.0f, 1.0f);
149
150         const VkRect2D scissor =
151         {
152                 makeOffset2D(0, 0),
153                 makeExtent2D(renderSize.x(), renderSize.y()),
154         };
155
156         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
157         {
158                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                              sType;
159                 DE_NULL,                                                                                                // const void*                                                  pNext;
160                 (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags   flags;
161                 1u,                                                                                                             // uint32_t                                                             viewportCount;
162                 &viewport,                                                                                              // const VkViewport*                                    pViewports;
163                 1u,                                                                                                             // uint32_t                                                             scissorCount;
164                 &scissor,                                                                                               // const VkRect2D*                                              pScissors;
165         };
166
167         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
168         {
169                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
170                 DE_NULL,                                                                                                        // const void*                                                          pNext;
171                 (VkPipelineRasterizationStateCreateFlags)0,                                     // VkPipelineRasterizationStateCreateFlags      flags;
172                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthClampEnable;
173                 VK_FALSE,                                                                                                       // VkBool32                                                                     rasterizerDiscardEnable;
174                 VK_POLYGON_MODE_FILL,                                                                           // VkPolygonMode                                                        polygonMode;
175                 VK_CULL_MODE_NONE,                                                                                      // VkCullModeFlags                                                      cullMode;
176                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                        // VkFrontFace                                                          frontFace;
177                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBiasEnable;
178                 0.0f,                                                                                                           // float                                                                        depthBiasConstantFactor;
179                 0.0f,                                                                                                           // float                                                                        depthBiasClamp;
180                 0.0f,                                                                                                           // float                                                                        depthBiasSlopeFactor;
181                 1.0f,                                                                                                           // float                                                                        lineWidth;
182         };
183
184         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
185         {
186                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
187                 DE_NULL,                                                                                                        // const void*                                                          pNext;
188                 (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
189                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
190                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
191                 0.0f,                                                                                                           // float                                                                        minSampleShading;
192                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
193                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
194                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
195         };
196
197         const VkStencilOpState stencilOpState = makeStencilOpState(
198                 VK_STENCIL_OP_KEEP,             // stencil fail
199                 VK_STENCIL_OP_KEEP,             // depth & stencil pass
200                 VK_STENCIL_OP_KEEP,             // depth only fail
201                 VK_COMPARE_OP_ALWAYS,   // compare op
202                 0u,                                             // compare mask
203                 0u,                                             // write mask
204                 0u);                                    // reference
205
206         VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
207         {
208                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
209                 DE_NULL,                                                                                                        // const void*                                                          pNext;
210                 (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
211                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthTestEnable;
212                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthWriteEnable;
213                 VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
214                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
215                 VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
216                 stencilOpState,                                                                                         // VkStencilOpState                                                     front;
217                 stencilOpState,                                                                                         // VkStencilOpState                                                     back;
218                 0.0f,                                                                                                           // float                                                                        minDepthBounds;
219                 1.0f,                                                                                                           // float                                                                        maxDepthBounds;
220         };
221
222         const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
223         // Number of blend attachments must equal the number of color attachments during any subpass.
224         const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
225         {
226                 VK_FALSE,                               // VkBool32                                     blendEnable;
227                 VK_BLEND_FACTOR_ONE,    // VkBlendFactor                        srcColorBlendFactor;
228                 VK_BLEND_FACTOR_ZERO,   // VkBlendFactor                        dstColorBlendFactor;
229                 VK_BLEND_OP_ADD,                // VkBlendOp                            colorBlendOp;
230                 VK_BLEND_FACTOR_ONE,    // VkBlendFactor                        srcAlphaBlendFactor;
231                 VK_BLEND_FACTOR_ZERO,   // VkBlendFactor                        dstAlphaBlendFactor;
232                 VK_BLEND_OP_ADD,                // VkBlendOp                            alphaBlendOp;
233                 colorComponentsAll,             // VkColorComponentFlags        colorWriteMask;
234         };
235
236         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
237         {
238                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
239                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
240                 (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
241                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
242                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
243                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
244                 &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
245                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
246         };
247
248         const VkPipelineShaderStageCreateInfo pShaderStages[] =
249         {
250                 {
251                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
252                         DE_NULL,                                                                                                // const void*                                                  pNext;
253                         (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
254                         VK_SHADER_STAGE_VERTEX_BIT,                                                             // VkShaderStageFlagBits                                stage;
255                         vertexModule,                                                                                   // VkShaderModule                                               module;
256                         "main",                                                                                                 // const char*                                                  pName;
257                         DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
258                 },
259                 {
260                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
261                         DE_NULL,                                                                                                // const void*                                                  pNext;
262                         (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
263                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                   // VkShaderStageFlagBits                                stage;
264                         fragmentModule,                                                                                 // VkShaderModule                                               module;
265                         "main",                                                                                                 // const char*                                                  pName;
266                         DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
267                 }
268         };
269
270         const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
271         {
272                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
273                 DE_NULL,                                                                                        // const void*                                                                          pNext;
274                 (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                                                        flags;
275                 DE_LENGTH_OF_ARRAY(pShaderStages),                                      // deUint32                                                                                     stageCount;
276                 pShaderStages,                                                                          // const VkPipelineShaderStageCreateInfo*                       pStages;
277                 &vertexInputStateInfo,                                                          // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
278                 &pipelineInputAssemblyStateInfo,                                        // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
279                 DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
280                 &pipelineViewportStateInfo,                                                     // const VkPipelineViewportStateCreateInfo*                     pViewportState;
281                 &pipelineRasterizationStateInfo,                                        // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
282                 &pipelineMultisampleStateInfo,                                          // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
283                 &pipelineDepthStencilStateInfo,                                         // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
284                 &pipelineColorBlendStateInfo,                                           // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
285                 DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
286                 pipelineLayout,                                                                         // VkPipelineLayout                                                                     layout;
287                 renderPass,                                                                                     // VkRenderPass                                                                         renderPass;
288                 subpass,                                                                                        // deUint32                                                                                     subpass;
289                 DE_NULL,                                                                                        // VkPipeline                                                                           basePipelineHandle;
290                 0,                                                                                                      // deInt32                                                                                      basePipelineIndex;
291         };
292
293         return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
294 }
295
296 //! Make a render pass with one subpass per color attachment and one attachment per image layer.
297 Move<VkRenderPass> makeRenderPass (const DeviceInterface&               vk,
298                                                                    const VkDevice                               device,
299                                                                    const VkFormat                               colorFormat,
300                                                                    const deUint32                               numLayers,
301                                                                    const VkImageLayout                  initialColorImageLayout                 = VK_IMAGE_LAYOUT_UNDEFINED)
302 {
303         const VkAttachmentDescription colorAttachmentDescription =
304         {
305                 (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags         flags;
306                 colorFormat,                                                            // VkFormat                                                     format;
307                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                        samples;
308                 VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
309                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
310                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
311                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
312                 initialColorImageLayout,                                        // VkImageLayout                                        initialLayout;
313                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        finalLayout;
314         };
315         const vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);
316
317         // Create a subpass for each attachment (each attachement is a layer of an arrayed image).
318         vector<VkAttachmentReference>   colorAttachmentReferences(numLayers);
319         vector<VkSubpassDescription>    subpasses;
320
321         for (deUint32 i = 0; i < numLayers; ++i)
322         {
323                 const VkAttachmentReference attachmentRef =
324                 {
325                         i,                                                                                              // deUint32                     attachment;
326                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                // VkImageLayout        layout;
327                 };
328                 colorAttachmentReferences[i] = attachmentRef;
329
330                 const VkSubpassDescription subpassDescription =
331                 {
332                         (VkSubpassDescriptionFlags)0,           // VkSubpassDescriptionFlags            flags;
333                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                          pipelineBindPoint;
334                         0u,                                                                     // deUint32                                                     inputAttachmentCount;
335                         DE_NULL,                                                        // const VkAttachmentReference*         pInputAttachments;
336                         1u,                                                                     // deUint32                                                     colorAttachmentCount;
337                         &colorAttachmentReferences[i],          // const VkAttachmentReference*         pColorAttachments;
338                         DE_NULL,                                                        // const VkAttachmentReference*         pResolveAttachments;
339                         DE_NULL,                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
340                         0u,                                                                     // deUint32                                                     preserveAttachmentCount;
341                         DE_NULL                                                         // const deUint32*                                      pPreserveAttachments;
342                 };
343                 subpasses.push_back(subpassDescription);
344         }
345
346         const VkRenderPassCreateInfo renderPassInfo =
347         {
348                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                              // VkStructureType                                      sType;
349                 DE_NULL,                                                                                                // const void*                                          pNext;
350                 (VkRenderPassCreateFlags)0,                                                             // VkRenderPassCreateFlags                      flags;
351                 static_cast<deUint32>(attachmentDescriptions.size()),   // deUint32                                                     attachmentCount;
352                 &attachmentDescriptions[0],                                                             // const VkAttachmentDescription*       pAttachments;
353                 static_cast<deUint32>(subpasses.size()),                                // deUint32                                                     subpassCount;
354                 &subpasses[0],                                                                                  // const VkSubpassDescription*          pSubpasses;
355                 0u,                                                                                                             // deUint32                                                     dependencyCount;
356                 DE_NULL                                                                                                 // const VkSubpassDependency*           pDependencies;
357         };
358
359         return createRenderPass(vk, device, &renderPassInfo);
360 }
361
362 Move<VkImage> makeImage (const DeviceInterface&         vk,
363                                                  const VkDevice                         device,
364                                                  VkImageCreateFlags                     flags,
365                                                  VkImageType                            imageType,
366                                                  const VkFormat                         format,
367                                                  const IVec3&                           size,
368                                                  const deUint32                         numLayers,
369                                                  const VkImageUsageFlags        usage)
370 {
371         const VkImageCreateInfo imageParams =
372         {
373                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType                      sType;
374                 DE_NULL,                                                                // const void*                          pNext;
375                 flags,                                                                  // VkImageCreateFlags           flags;
376                 imageType,                                                              // VkImageType                          imageType;
377                 format,                                                                 // VkFormat                                     format;
378                 makeExtent3D(size),                                             // VkExtent3D                           extent;
379                 1u,                                                                             // deUint32                                     mipLevels;
380                 numLayers,                                                              // deUint32                                     arrayLayers;
381                 VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits        samples;
382                 VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                        tiling;
383                 usage,                                                                  // VkImageUsageFlags            usage;
384                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                        sharingMode;
385                 0u,                                                                             // deUint32                                     queueFamilyIndexCount;
386                 DE_NULL,                                                                // const deUint32*                      pQueueFamilyIndices;
387                 VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                        initialLayout;
388         };
389         return createImage(vk, device, &imageParams);
390 }
391
392 inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
393 {
394         const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
395         return createBuffer(vk, device, &bufferCreateInfo);
396 }
397
398 inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
399 {
400         return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
401 }
402
403 //! Get a reference clear value based on color format.
404 VkClearValue getClearValue (const VkFormat format)
405 {
406         if (isUintFormat(format) || isIntFormat(format))
407                 return makeClearValueColorU32(REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE);
408         else
409                 return makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f);
410 }
411
412 std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
413 {
414         std::ostringstream str;
415         if (numComponents == 1)
416                 str << (isUint ? "uint" : isSint ? "int" : "float");
417         else
418                 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;
419
420         return str.str();
421 }
422
423 //! A half-viewport quad. Use with TRIANGLE_STRIP topology.
424 vector<Vertex4RGBA> genFullQuadVertices (const int subpassCount, const vector<Vec4>& color)
425 {
426         vector<Vertex4RGBA>     vectorData;
427         for (int subpassNdx = 0; subpassNdx < subpassCount; ++subpassNdx)
428         {
429                 Vertex4RGBA data =
430                 {
431                         Vec4(0.0f, -1.0f, 0.0f, 1.0f),
432                         color[subpassNdx % color.size()],
433                 };
434                 vectorData.push_back(data);
435                 data.position   = Vec4(0.0f,  1.0f, 0.0f, 1.0f);
436                 vectorData.push_back(data);
437                 data.position   = Vec4(1.0f, -1.0f, 0.0f, 1.0f);
438                 vectorData.push_back(data);
439                 data.position   = Vec4(1.0f,  1.0f, 0.0f, 1.0f);
440                 vectorData.push_back(data);
441         }
442         return vectorData;
443 }
444
445 VkImageType getImageType (const VkImageViewType viewType)
446 {
447         switch (viewType)
448         {
449         case VK_IMAGE_VIEW_TYPE_1D:
450         case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
451                 return VK_IMAGE_TYPE_1D;
452
453         case VK_IMAGE_VIEW_TYPE_2D:
454         case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
455         case VK_IMAGE_VIEW_TYPE_CUBE:
456         case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
457                 return VK_IMAGE_TYPE_2D;
458
459         case VK_IMAGE_VIEW_TYPE_3D:
460                 return VK_IMAGE_TYPE_3D;
461
462         default:
463                 DE_ASSERT(0);
464                 return VK_IMAGE_TYPE_LAST;
465         }
466 }
467
468 void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
469 {
470         const int       numComponents   = getNumUsedChannels(mapVkFormat(caseDef.colorFormat).order);
471         const bool      isUint                  = isUintFormat(caseDef.colorFormat);
472         const bool      isSint                  = isIntFormat(caseDef.colorFormat);
473
474         // Vertex shader
475         {
476                 std::ostringstream src;
477                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
478                         << "\n"
479                         << "layout(location = 0) in  vec4 in_position;\n"
480                         << "layout(location = 1) in  vec4 in_color;\n"
481                         << "layout(location = 0) out vec4 out_color;\n"
482                         << "\n"
483                         << "out gl_PerVertex {\n"
484                         << "    vec4 gl_Position;\n"
485                         << "};\n"
486                         << "\n"
487                         << "void main(void)\n"
488                         << "{\n"
489                         << "    gl_Position     = in_position;\n"
490                         << "    out_color       = in_color;\n"
491                         << "}\n";
492
493                 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
494         }
495
496         // Fragment shader
497         {
498                 std::ostringstream colorValue;
499                 colorValue << REFERENCE_COLOR_VALUE;
500                 const std::string colorFormat   = getColorFormatStr(numComponents, isUint, isSint);
501                 const std::string colorInteger  = (isUint || isSint ? " * "+colorFormat+"("+colorValue.str()+")" :"");
502
503                 std::ostringstream src;
504                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
505                         << "\n"
506                         << "layout(location = 0) in  vec4 in_color;\n"
507                         << "layout(location = 0) out " << colorFormat << " o_color;\n"
508                         << "\n"
509                         << "void main(void)\n"
510                         << "{\n"
511                         << "    o_color = " << colorFormat << "("
512                         << (numComponents == 1 ? "in_color.r"   :
513                                 numComponents == 2 ? "in_color.rg"  :
514                                 numComponents == 3 ? "in_color.rgb" : "in_color")
515                         << colorInteger
516                         << ");\n"
517                         << "}\n";
518
519                 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
520         }
521 }
522
523 tcu::PixelBufferAccess getExpectedData (tcu::TextureLevel& textureLevel, const CaseDef& caseDef, const Vec4* color, const int sizeColor)
524 {
525         const bool                                              isInt                   = isUintFormat(caseDef.colorFormat) || isIntFormat(caseDef.colorFormat);
526         const tcu::PixelBufferAccess    expectedImage   (textureLevel);
527
528         if (isInt)
529                 tcu::clear(expectedImage, tcu::IVec4(REFERENCE_COLOR_VALUE));
530         else
531                 tcu::clear(expectedImage, tcu::Vec4(1.0));
532
533         for (int z = 0; z < expectedImage.getDepth(); ++z)
534         {
535                 const Vec4& setColor    = color[z % sizeColor];
536                 const IVec4 setColorInt = (static_cast<float>(REFERENCE_COLOR_VALUE) * setColor).cast<deInt32>();
537
538                 for (int y = 0;                                                 y < caseDef.renderSize.y(); ++y)
539                 for (int x = caseDef.renderSize.x()/2;  x < caseDef.renderSize.x(); ++x)
540                 {
541                         if (isInt)
542                                 expectedImage.setPixel(setColorInt, x, y, z);
543                         else
544                                 expectedImage.setPixel(setColor, x, y, z);
545                 }
546         }
547         return expectedImage;
548 }
549
550 tcu::TestStatus test (Context& context, const CaseDef caseDef)
551 {
552         if (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType &&
553                 (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1")))
554                 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
555
556         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
557         const VkDevice                                  device                          = context.getDevice();
558         const VkQueue                                   queue                           = context.getUniversalQueue();
559         const deUint32                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
560         Allocator&                                              allocator                       = context.getDefaultAllocator();
561         Move<VkImage>                                   colorImage;
562         MovePtr<Allocation>                             colorImageAlloc;
563         const Vec4                                              color[]                         =
564         {
565                 Vec4(0.9f, 0.0f, 0.0f, 1.0f),
566                 Vec4(0.6f, 1.0f, 0.0f, 1.0f),
567                 Vec4(0.3f, 0.0f, 1.0f, 1.0f),
568                 Vec4(0.1f, 0.0f, 1.0f, 1.0f)
569         };
570
571         const int                                               numLayers                       = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? caseDef.renderSize.z() : caseDef.numLayers);
572         const VkDeviceSize                              colorBufferSize         = caseDef.renderSize.x() * caseDef.renderSize.y() * caseDef.renderSize.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.colorFormat));
573         const Unique<VkBuffer>                  colorBuffer                     (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
574         const UniquePtr<Allocation>             colorBufferAlloc        (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
575
576         const Unique<VkShaderModule>    vertexModule            (createShaderModule                     (vk, device, context.getBinaryCollection().get("vert"), 0u));
577         const Unique<VkShaderModule>    fragmentModule          (createShaderModule                     (vk, device, context.getBinaryCollection().get("frag"), 0u));
578         const Unique<VkRenderPass>              renderPass                      (makeRenderPass                         (vk, device, caseDef.colorFormat, static_cast<deUint32>(numLayers),
579                                                                                                                                                                          (caseDef.imageType == VK_IMAGE_VIEW_TYPE_3D) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
580                                                                                                                                                                                                                                                                   : VK_IMAGE_LAYOUT_UNDEFINED));
581         const Unique<VkPipelineLayout>  pipelineLayout          (makePipelineLayout                     (vk, device));
582         vector<SharedPtrVkPipeline>             pipeline;
583         const Unique<VkCommandPool>             cmdPool                         (makeCommandPool  (vk, device, queueFamilyIndex));
584         const Unique<VkCommandBuffer>   cmdBuffer                       (makeCommandBuffer(vk, device, *cmdPool));
585
586         vector<SharedPtrVkImageView>    colorAttachments;
587         vector<VkImageView>                             attachmentHandles;
588         Move<VkBuffer>                                  vertexBuffer;
589         MovePtr<Allocation>                             vertexBufferAlloc;
590         Move<VkFramebuffer>                             framebuffer;
591
592         //create colorImage
593         {
594                 const VkImageViewCreateFlags    flags                   = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? (VkImageViewCreateFlags)VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : (VkImageViewCreateFlags)0);
595                 const VkImageUsageFlags                 colorImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
596                 colorImage = makeImage(vk, device, flags, getImageType(caseDef.imageType), caseDef.colorFormat, caseDef.renderSize, caseDef.numLayers, colorImageUsage);
597                 colorImageAlloc = bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any);
598         }
599
600         //create vertexBuffer
601         {
602                 const vector<Vertex4RGBA>       vertices                        = genFullQuadVertices(numLayers, vector<Vec4>(color, color + DE_LENGTH_OF_ARRAY(color)));
603                 const VkDeviceSize                      vertexBufferSize        = sizeInBytes(vertices);
604
605                 vertexBuffer            = makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
606                 vertexBufferAlloc       = bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible);
607                 deMemcpy(vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
608                 flushMappedMemoryRange(vk, device, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferSize);
609         }
610
611         //create attachmentHandles and pipelines
612         for (int layerNdx = 0; layerNdx < numLayers; ++layerNdx)
613         {
614                 const VkImageViewType   imageType = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY :
615                                                                                         (VK_IMAGE_VIEW_TYPE_CUBE == caseDef.imageType || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == caseDef.imageType ? VK_IMAGE_VIEW_TYPE_2D :
616                                                                                         caseDef.imageType));
617
618                 colorAttachments.push_back(makeSharedPtr(makeImageView(vk, device, *colorImage, imageType, caseDef.colorFormat, makeColorSubresourceRange(layerNdx, 1))));
619                 attachmentHandles.push_back(**colorAttachments.back());
620
621                 pipeline.push_back(makeSharedPtr(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule,
622                                                                                                                           caseDef.renderSize, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, static_cast<deUint32>(layerNdx))));
623         }
624
625         framebuffer = makeFramebuffer(vk, device, *renderPass, numLayers, &attachmentHandles[0], static_cast<deUint32>(caseDef.renderSize.x()), static_cast<deUint32>(caseDef.renderSize.y()));
626
627         beginCommandBuffer(vk, *cmdBuffer);
628
629         // Prepare color image upfront for rendering to individual slices.  3D slices aren't separate subresources, so they shouldn't be transitioned
630         // during each subpass like array layers.
631         if (caseDef.imageType == VK_IMAGE_VIEW_TYPE_3D)
632         {
633                 const VkImageMemoryBarrier      imageBarrier    =
634                 {
635                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType            sType;
636                         DE_NULL,                                                                                        // const void*                pNext;
637                         (VkAccessFlags)0,                                                                       // VkAccessFlags              srcAccessMask;
638                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                           // VkAccessFlags              dstAccessMask;
639                         VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout              oldLayout;
640                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout              newLayout;
641                         VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                   srcQueueFamilyIndex;
642                         VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                   dstQueueFamilyIndex;
643                         *colorImage,                                                                            // VkImage                    image;
644                         makeColorSubresourceRange(0, caseDef.numLayers)         // VkImageSubresourceRange    subresourceRange;
645                 };
646
647                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u,
648                                                                 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
649         }
650
651         {
652                 const vector<VkClearValue>      clearValues                     (numLayers, getClearValue(caseDef.colorFormat));
653                 const VkRect2D                          renderArea                      =
654                 {
655                         makeOffset2D(0, 0),
656                         makeExtent2D(caseDef.renderSize.x(), caseDef.renderSize.y()),
657                 };
658                 const VkRenderPassBeginInfo     renderPassBeginInfo     =
659                 {
660                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType         sType;
661                         DE_NULL,                                                                        // const void*             pNext;
662                         *renderPass,                                                            // VkRenderPass            renderPass;
663                         *framebuffer,                                                           // VkFramebuffer           framebuffer;
664                         renderArea,                                                                     // VkRect2D                renderArea;
665                         static_cast<deUint32>(clearValues.size()),      // uint32_t                clearValueCount;
666                         &clearValues[0],                                                        // const VkClearValue*     pClearValues;
667                 };
668                 const VkDeviceSize                      vertexBufferOffset      = 0ull;
669
670                 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
671                 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
672         }
673
674         //cmdDraw
675         for (deUint32 layerNdx = 0; layerNdx < static_cast<deUint32>(numLayers); ++layerNdx)
676         {
677                 if (layerNdx != 0)
678                         vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
679
680                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipeline[layerNdx]);
681                 vk.cmdDraw(*cmdBuffer, 4u, 1u, layerNdx*4u, 0u);
682         }
683
684         vk.cmdEndRenderPass(*cmdBuffer);
685
686         // copy colorImage -> host visible colorBuffer
687         {
688                 const VkImageMemoryBarrier      imageBarriers[] =
689                 {
690                         {
691                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
692                                 DE_NULL,                                                                                // const void*                          pNext;
693                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags                        outputMask;
694                                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags                        inputMask;
695                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               // VkImageLayout                        oldLayout;
696                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                   // VkImageLayout                        newLayout;
697                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
698                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
699                                 *colorImage,                                                                    // VkImage                                      image;
700                                 makeColorSubresourceRange(0, caseDef.numLayers) // VkImageSubresourceRange      subresourceRange;
701                         }
702                 };
703
704                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
705                                                           0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
706
707                 const VkBufferImageCopy         region                  =
708                 {
709                         0ull,                                                                                                                                                           // VkDeviceSize                bufferOffset;
710                         0u,                                                                                                                                                                     // uint32_t                    bufferRowLength;
711                         0u,                                                                                                                                                                     // uint32_t                    bufferImageHeight;
712                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, caseDef.numLayers),       // VkImageSubresourceLayers    imageSubresource;
713                         makeOffset3D(0, 0, 0),                                                                                                                          // VkOffset3D                  imageOffset;
714                         makeExtent3D(caseDef.renderSize),                                                                                                       // VkExtent3D                  imageExtent;
715                 };
716
717                 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
718
719                 const VkBufferMemoryBarrier     bufferBarriers[] =
720                 {
721                         {
722                                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType    sType;
723                                 DE_NULL,                                                                        // const void*        pNext;
724                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags      srcAccessMask;
725                                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags      dstAccessMask;
726                                 VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t           srcQueueFamilyIndex;
727                                 VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t           dstQueueFamilyIndex;
728                                 *colorBuffer,                                                           // VkBuffer           buffer;
729                                 0ull,                                                                           // VkDeviceSize       offset;
730                                 VK_WHOLE_SIZE,                                                          // VkDeviceSize       size;
731                         },
732                 };
733
734                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
735                                                           0u, DE_NULL, DE_LENGTH_OF_ARRAY(bufferBarriers), bufferBarriers, 0u, DE_NULL);
736         }
737
738         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
739         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
740
741         // Verify results
742         {
743                 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
744
745                 const tcu::TextureFormat                        format                  = mapVkFormat(caseDef.colorFormat);
746                 const int                                                       depth                   = deMax32(caseDef.renderSize.z(), caseDef.numLayers);
747                 tcu::TextureLevel                                       textureLevel    (format, caseDef.renderSize.x(), caseDef.renderSize.y(), depth);
748                 const tcu::PixelBufferAccess            expectedImage   = getExpectedData (textureLevel, caseDef, color, DE_LENGTH_OF_ARRAY(color));
749                 const tcu::ConstPixelBufferAccess       resultImage             (format, caseDef.renderSize.x(), caseDef.renderSize.y(), depth, colorBufferAlloc->getHostPtr());
750
751                 if (!tcu::intThresholdCompare(context.getTestContext().getLog(), "Image Comparison", "", expectedImage, resultImage, tcu::UVec4(2), tcu::COMPARE_LOG_RESULT))
752                         return tcu::TestStatus::fail("Fail");
753         }
754         return tcu::TestStatus::pass("Pass");
755 }
756
757 std::string getSizeString (const IVec3& size, const int numLayer)
758 {
759         std::ostringstream str;
760                                                         str <<            size.x();
761         if (size.y() > 1)               str << "x" << size.y();
762         if (size.z() > 1)               str << "x" << size.z();
763         if (numLayer > 1)               str << "_" << numLayer;
764
765         return str.str();
766 }
767
768 std::string getFormatString (const VkFormat format)
769 {
770         std::string name(getFormatName(format));
771         return de::toLower(name.substr(10));
772 }
773
774 std::string getShortImageViewTypeName (const VkImageViewType imageViewType)
775 {
776         std::string s(getImageViewTypeName(imageViewType));
777         return de::toLower(s.substr(19));
778 }
779
780 CaseDef caseDefWithFormat (CaseDef caseDef, const VkFormat format)
781 {
782         caseDef.colorFormat = format;
783         return caseDef;
784 }
785
786 void addTestCasesWithFunctions (tcu::TestCaseGroup* group)
787 {
788         const CaseDef caseDef[] =
789         {
790                 { VK_IMAGE_VIEW_TYPE_1D,                        IVec3(54,  1, 1),       1,              VK_FORMAT_UNDEFINED},
791                 { VK_IMAGE_VIEW_TYPE_1D_ARRAY,          IVec3(54,  1, 1),       4,              VK_FORMAT_UNDEFINED},
792                 { VK_IMAGE_VIEW_TYPE_2D,                        IVec3(22, 64, 1),       1,              VK_FORMAT_UNDEFINED},
793                 { VK_IMAGE_VIEW_TYPE_2D_ARRAY,          IVec3(22, 64, 1),       4,              VK_FORMAT_UNDEFINED},
794                 { VK_IMAGE_VIEW_TYPE_3D,                        IVec3(22, 64, 7),       1,              VK_FORMAT_UNDEFINED},
795                 { VK_IMAGE_VIEW_TYPE_CUBE,                      IVec3(35, 35, 1),       6,              VK_FORMAT_UNDEFINED},
796                 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,        IVec3(35, 35, 1),       2*6,    VK_FORMAT_UNDEFINED},
797         };
798
799         const VkFormat format[] =
800         {
801                 VK_FORMAT_R8G8B8A8_UNORM,
802                 VK_FORMAT_R32_UINT,
803                 VK_FORMAT_R16G16_SINT,
804                 VK_FORMAT_R32G32B32A32_SFLOAT,
805         };
806
807         for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(caseDef); ++sizeNdx)
808         {
809                 MovePtr<tcu::TestCaseGroup>     imageGroup(new tcu::TestCaseGroup(group->getTestContext(), getShortImageViewTypeName(caseDef[sizeNdx].imageType).c_str(), ""));
810                 {
811                         MovePtr<tcu::TestCaseGroup>     sizeGroup(new tcu::TestCaseGroup(group->getTestContext(), getSizeString(caseDef[sizeNdx].renderSize, caseDef[sizeNdx].numLayers).c_str(), ""));
812
813                         for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(format); ++formatNdx)
814                                 addFunctionCaseWithPrograms(sizeGroup.get(), getFormatString(format[formatNdx]).c_str(), "", initPrograms, test, caseDefWithFormat(caseDef[sizeNdx], format[formatNdx]));
815
816                         imageGroup->addChild(sizeGroup.release());
817                 }
818                 group->addChild(imageGroup.release());
819         }
820 }
821
822 } // anonymous ns
823
824 tcu::TestCaseGroup* createRenderToImageTests (tcu::TestContext& testCtx)
825 {
826         return createTestGroup(testCtx, "render_to_image", "Render to image tests", addTestCasesWithFunctions);
827 }
828
829 } // pipeline
830 } // vkt