VK_KHR_dedicated_allocation: Extend pipeline.image
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineRenderToImageTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 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 #include "tcuTestLog.hpp"
42
43 #include "deUniquePtr.hpp"
44 #include "deSharedPtr.hpp"
45
46 #include <string>
47 #include <vector>
48
49 namespace vkt
50 {
51 namespace pipeline
52 {
53 namespace
54 {
55 using namespace vk;
56 using de::UniquePtr;
57 using de::MovePtr;
58 using de::SharedPtr;
59 using tcu::IVec3;
60 using tcu::Vec4;
61 using tcu::UVec4;
62 using tcu::IVec4;
63 using std::vector;
64
65 typedef SharedPtr<Unique<VkImageView> > SharedPtrVkImageView;
66 typedef SharedPtr<Unique<VkPipeline> >  SharedPtrVkPipeline;
67
68 enum Constants
69 {
70         REFERENCE_COLOR_VALUE = 125
71 };
72
73 struct CaseDef
74 {
75         VkImageViewType imageType;
76         IVec3                   renderSize;
77         int                             numLayers;
78         VkFormat                colorFormat;
79 };
80
81 template<typename T>
82 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
83 {
84         return SharedPtr<Unique<T> >(new Unique<T>(move));
85 }
86
87 template<typename T>
88 inline VkDeviceSize sizeInBytes (const vector<T>& vec)
89 {
90         return vec.size() * sizeof(vec[0]);
91 }
92
93 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&           vk,
94                                                                            const VkDevice                               device,
95                                                                            const VkPipelineLayout               pipelineLayout,
96                                                                            const VkRenderPass                   renderPass,
97                                                                            const VkShaderModule                 vertexModule,
98                                                                            const VkShaderModule                 fragmentModule,
99                                                                            const IVec3                                  renderSize,
100                                                                            const VkPrimitiveTopology    topology,
101                                                                            const deUint32                               subpass)
102 {
103         const VkVertexInputBindingDescription vertexInputBindingDescription =
104         {
105                 0u,                                                             // uint32_t                             binding;
106                 sizeof(Vertex4RGBA),                    // uint32_t                             stride;
107                 VK_VERTEX_INPUT_RATE_VERTEX,    // VkVertexInputRate    inputRate;
108         };
109
110         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
111         {
112                 {
113                         0u,                                                             // uint32_t                     location;
114                         0u,                                                             // uint32_t                     binding;
115                         VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat                     format;
116                         0u,                                                             // uint32_t                     offset;
117                 },
118                 {
119                         1u,                                                             // uint32_t                     location;
120                         0u,                                                             // uint32_t                     binding;
121                         VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat                     format;
122                         sizeof(Vec4),                                   // uint32_t                     offset;
123                 }
124         };
125
126         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
127         {
128                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
129                 DE_NULL,                                                                                                        // const void*                                                          pNext;
130                 (VkPipelineVertexInputStateCreateFlags)0,                                       // VkPipelineVertexInputStateCreateFlags        flags;
131                 1u,                                                                                                                     // uint32_t                                                                     vertexBindingDescriptionCount;
132                 &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
133                 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),           // uint32_t                                                                     vertexAttributeDescriptionCount;
134                 vertexInputAttributeDescriptions,                                                       // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
135         };
136
137         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
138         {
139                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
140                 DE_NULL,                                                                                                                // const void*                                                          pNext;
141                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
142                 topology,                                                                                                               // VkPrimitiveTopology                                          topology;
143                 VK_FALSE,                                                                                                               // VkBool32                                                                     primitiveRestartEnable;
144         };
145
146         const VkViewport viewport = makeViewport(
147                 0.0f, 0.0f,
148                 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
149                 0.0f, 1.0f);
150
151         const VkRect2D scissor =
152         {
153                 makeOffset2D(0, 0),
154                 makeExtent2D(renderSize.x(), renderSize.y()),
155         };
156
157         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
158         {
159                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                              sType;
160                 DE_NULL,                                                                                                // const void*                                                  pNext;
161                 (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags   flags;
162                 1u,                                                                                                             // uint32_t                                                             viewportCount;
163                 &viewport,                                                                                              // const VkViewport*                                    pViewports;
164                 1u,                                                                                                             // uint32_t                                                             scissorCount;
165                 &scissor,                                                                                               // const VkRect2D*                                              pScissors;
166         };
167
168         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
169         {
170                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
171                 DE_NULL,                                                                                                        // const void*                                                          pNext;
172                 (VkPipelineRasterizationStateCreateFlags)0,                                     // VkPipelineRasterizationStateCreateFlags      flags;
173                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthClampEnable;
174                 VK_FALSE,                                                                                                       // VkBool32                                                                     rasterizerDiscardEnable;
175                 VK_POLYGON_MODE_FILL,                                                                           // VkPolygonMode                                                        polygonMode;
176                 VK_CULL_MODE_NONE,                                                                                      // VkCullModeFlags                                                      cullMode;
177                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                        // VkFrontFace                                                          frontFace;
178                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBiasEnable;
179                 0.0f,                                                                                                           // float                                                                        depthBiasConstantFactor;
180                 0.0f,                                                                                                           // float                                                                        depthBiasClamp;
181                 0.0f,                                                                                                           // float                                                                        depthBiasSlopeFactor;
182                 1.0f,                                                                                                           // float                                                                        lineWidth;
183         };
184
185         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
186         {
187                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
188                 DE_NULL,                                                                                                        // const void*                                                          pNext;
189                 (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
190                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
191                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
192                 0.0f,                                                                                                           // float                                                                        minSampleShading;
193                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
194                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
195                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
196         };
197
198         const VkStencilOpState stencilOpState = makeStencilOpState(
199                 VK_STENCIL_OP_KEEP,             // stencil fail
200                 VK_STENCIL_OP_KEEP,             // depth & stencil pass
201                 VK_STENCIL_OP_KEEP,             // depth only fail
202                 VK_COMPARE_OP_ALWAYS,   // compare op
203                 0u,                                             // compare mask
204                 0u,                                             // write mask
205                 0u);                                    // reference
206
207         VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
208         {
209                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
210                 DE_NULL,                                                                                                        // const void*                                                          pNext;
211                 (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
212                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthTestEnable;
213                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthWriteEnable;
214                 VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
215                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
216                 VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
217                 stencilOpState,                                                                                         // VkStencilOpState                                                     front;
218                 stencilOpState,                                                                                         // VkStencilOpState                                                     back;
219                 0.0f,                                                                                                           // float                                                                        minDepthBounds;
220                 1.0f,                                                                                                           // float                                                                        maxDepthBounds;
221         };
222
223         const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
224         // Number of blend attachments must equal the number of color attachments during any subpass.
225         const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
226         {
227                 VK_FALSE,                               // VkBool32                                     blendEnable;
228                 VK_BLEND_FACTOR_ONE,    // VkBlendFactor                        srcColorBlendFactor;
229                 VK_BLEND_FACTOR_ZERO,   // VkBlendFactor                        dstColorBlendFactor;
230                 VK_BLEND_OP_ADD,                // VkBlendOp                            colorBlendOp;
231                 VK_BLEND_FACTOR_ONE,    // VkBlendFactor                        srcAlphaBlendFactor;
232                 VK_BLEND_FACTOR_ZERO,   // VkBlendFactor                        dstAlphaBlendFactor;
233                 VK_BLEND_OP_ADD,                // VkBlendOp                            alphaBlendOp;
234                 colorComponentsAll,             // VkColorComponentFlags        colorWriteMask;
235         };
236
237         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
238         {
239                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
240                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
241                 (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
242                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
243                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
244                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
245                 &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
246                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
247         };
248
249         const VkPipelineShaderStageCreateInfo pShaderStages[] =
250         {
251                 {
252                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
253                         DE_NULL,                                                                                                // const void*                                                  pNext;
254                         (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
255                         VK_SHADER_STAGE_VERTEX_BIT,                                                             // VkShaderStageFlagBits                                stage;
256                         vertexModule,                                                                                   // VkShaderModule                                               module;
257                         "main",                                                                                                 // const char*                                                  pName;
258                         DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
259                 },
260                 {
261                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
262                         DE_NULL,                                                                                                // const void*                                                  pNext;
263                         (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
264                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                   // VkShaderStageFlagBits                                stage;
265                         fragmentModule,                                                                                 // VkShaderModule                                               module;
266                         "main",                                                                                                 // const char*                                                  pName;
267                         DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
268                 }
269         };
270
271         const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
272         {
273                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
274                 DE_NULL,                                                                                        // const void*                                                                          pNext;
275                 (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                                                        flags;
276                 DE_LENGTH_OF_ARRAY(pShaderStages),                                      // deUint32                                                                                     stageCount;
277                 pShaderStages,                                                                          // const VkPipelineShaderStageCreateInfo*                       pStages;
278                 &vertexInputStateInfo,                                                          // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
279                 &pipelineInputAssemblyStateInfo,                                        // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
280                 DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
281                 &pipelineViewportStateInfo,                                                     // const VkPipelineViewportStateCreateInfo*                     pViewportState;
282                 &pipelineRasterizationStateInfo,                                        // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
283                 &pipelineMultisampleStateInfo,                                          // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
284                 &pipelineDepthStencilStateInfo,                                         // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
285                 &pipelineColorBlendStateInfo,                                           // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
286                 DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
287                 pipelineLayout,                                                                         // VkPipelineLayout                                                                     layout;
288                 renderPass,                                                                                     // VkRenderPass                                                                         renderPass;
289                 subpass,                                                                                        // deUint32                                                                                     subpass;
290                 DE_NULL,                                                                                        // VkPipeline                                                                           basePipelineHandle;
291                 0,                                                                                                      // deInt32                                                                                      basePipelineIndex;
292         };
293
294         return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
295 }
296
297 //! Make a render pass with one subpass per color attachment and one attachment per image layer.
298 Move<VkRenderPass> makeRenderPass (const DeviceInterface&               vk,
299                                                                    const VkDevice                               device,
300                                                                    const VkFormat                               colorFormat,
301                                                                    const deUint32                               numLayers)
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                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // 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         const Unique<VkPipelineLayout>  pipelineLayout          (makePipelineLayout                     (vk, device));
580         vector<SharedPtrVkPipeline>             pipeline;
581         const Unique<VkCommandPool>             cmdPool                         (createCommandPool  (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
582         const Unique<VkCommandBuffer>   cmdBuffer                       (makeCommandBuffer(vk, device, *cmdPool));
583
584         vector<SharedPtrVkImageView>    colorAttachments;
585         vector<VkImageView>                             attachmentHandles;
586         Move<VkBuffer>                                  vertexBuffer;
587         MovePtr<Allocation>                             vertexBufferAlloc;
588         Move<VkFramebuffer>                             framebuffer;
589
590         //create colorImage
591         {
592                 const VkImageViewCreateFlags    flags                   = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? (VkImageViewCreateFlags)VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : (VkImageViewCreateFlags)0);
593                 const VkImageUsageFlags                 colorImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
594                 colorImage = makeImage(vk, device, flags, getImageType(caseDef.imageType), caseDef.colorFormat, caseDef.renderSize, caseDef.numLayers, colorImageUsage);
595                 colorImageAlloc = bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any);
596         }
597
598         //create vertexBuffer
599         {
600                 const vector<Vertex4RGBA>       vertices                        = genFullQuadVertices(numLayers, vector<Vec4>(color, color + DE_LENGTH_OF_ARRAY(color)));
601                 const VkDeviceSize                      vertexBufferSize        = sizeInBytes(vertices);
602
603                 vertexBuffer            = makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
604                 vertexBufferAlloc       = bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible);
605                 deMemcpy(vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
606                 flushMappedMemoryRange(vk, device, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferSize);
607         }
608
609         //create attachmentHandles and pipelines
610         for (int layerNdx = 0; layerNdx < numLayers; ++layerNdx)
611         {
612                 const VkImageViewType   imageType = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY :
613                                                                                         (VK_IMAGE_VIEW_TYPE_CUBE == caseDef.imageType || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == caseDef.imageType ? VK_IMAGE_VIEW_TYPE_2D :
614                                                                                         caseDef.imageType));
615
616                 colorAttachments.push_back(makeSharedPtr(makeImageView(vk, device, *colorImage, imageType, caseDef.colorFormat, makeColorSubresourceRange(layerNdx, 1))));
617                 attachmentHandles.push_back(**colorAttachments.back());
618
619                 pipeline.push_back(makeSharedPtr(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule,
620                                                                                                                           caseDef.renderSize, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, static_cast<deUint32>(layerNdx))));
621         }
622
623         framebuffer = makeFramebuffer(vk, device, *renderPass, numLayers, &attachmentHandles[0], static_cast<deUint32>(caseDef.renderSize.x()), static_cast<deUint32>(caseDef.renderSize.y()));
624
625         beginCommandBuffer(vk, *cmdBuffer);
626         {
627                 const vector<VkClearValue>      clearValues                     (numLayers, getClearValue(caseDef.colorFormat));
628                 const VkRect2D                          renderArea                      =
629                 {
630                         makeOffset2D(0, 0),
631                         makeExtent2D(caseDef.renderSize.x(), caseDef.renderSize.y()),
632                 };
633                 const VkRenderPassBeginInfo     renderPassBeginInfo     =
634                 {
635                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType         sType;
636                         DE_NULL,                                                                        // const void*             pNext;
637                         *renderPass,                                                            // VkRenderPass            renderPass;
638                         *framebuffer,                                                           // VkFramebuffer           framebuffer;
639                         renderArea,                                                                     // VkRect2D                renderArea;
640                         static_cast<deUint32>(clearValues.size()),      // uint32_t                clearValueCount;
641                         &clearValues[0],                                                        // const VkClearValue*     pClearValues;
642                 };
643                 const VkDeviceSize                      vertexBufferOffset      = 0ull;
644
645                 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
646                 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
647         }
648
649         //cmdDraw
650         for (deUint32 layerNdx = 0; layerNdx < static_cast<deUint32>(numLayers); ++layerNdx)
651         {
652                 if (layerNdx != 0)
653                         vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
654
655                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipeline[layerNdx]);
656                 vk.cmdDraw(*cmdBuffer, 4u, 1u, layerNdx*4u, 0u);
657         }
658
659         vk.cmdEndRenderPass(*cmdBuffer);
660
661         // copy colorImage -> host visible colorBuffer
662         {
663                 const VkImageMemoryBarrier      imageBarriers[] =
664                 {
665                         {
666                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
667                                 DE_NULL,                                                                                // const void*                          pNext;
668                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags                        outputMask;
669                                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags                        inputMask;
670                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               // VkImageLayout                        oldLayout;
671                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                   // VkImageLayout                        newLayout;
672                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
673                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
674                                 *colorImage,                                                                    // VkImage                                      image;
675                                 makeColorSubresourceRange(0, caseDef.numLayers) // VkImageSubresourceRange      subresourceRange;
676                         }
677                 };
678
679                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
680                                                           0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
681
682                 const VkBufferImageCopy         region                  =
683                 {
684                         0ull,                                                                                                                                                           // VkDeviceSize                bufferOffset;
685                         0u,                                                                                                                                                                     // uint32_t                    bufferRowLength;
686                         0u,                                                                                                                                                                     // uint32_t                    bufferImageHeight;
687                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, caseDef.numLayers),       // VkImageSubresourceLayers    imageSubresource;
688                         makeOffset3D(0, 0, 0),                                                                                                                          // VkOffset3D                  imageOffset;
689                         makeExtent3D(caseDef.renderSize),                                                                                                       // VkExtent3D                  imageExtent;
690                 };
691
692                 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
693
694                 const VkBufferMemoryBarrier     bufferBarriers[] =
695                 {
696                         {
697                                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType    sType;
698                                 DE_NULL,                                                                        // const void*        pNext;
699                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags      srcAccessMask;
700                                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags      dstAccessMask;
701                                 VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t           srcQueueFamilyIndex;
702                                 VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t           dstQueueFamilyIndex;
703                                 *colorBuffer,                                                           // VkBuffer           buffer;
704                                 0ull,                                                                           // VkDeviceSize       offset;
705                                 VK_WHOLE_SIZE,                                                          // VkDeviceSize       size;
706                         },
707                 };
708
709                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
710                                                           0u, DE_NULL, DE_LENGTH_OF_ARRAY(bufferBarriers), bufferBarriers, 0u, DE_NULL);
711         }
712
713         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
714         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
715
716         // Verify results
717         {
718                 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
719
720                 const tcu::TextureFormat                        format                  = mapVkFormat(caseDef.colorFormat);
721                 const int                                                       depth                   = deMax32(caseDef.renderSize.z(), caseDef.numLayers);
722                 tcu::TextureLevel                                       textureLevel    (format, caseDef.renderSize.x(), caseDef.renderSize.y(), depth);
723                 const tcu::PixelBufferAccess            expectedImage   = getExpectedData (textureLevel, caseDef, color, DE_LENGTH_OF_ARRAY(color));
724                 const tcu::ConstPixelBufferAccess       resultImage             (format, caseDef.renderSize.x(), caseDef.renderSize.y(), depth, colorBufferAlloc->getHostPtr());
725
726                 if (!tcu::intThresholdCompare(context.getTestContext().getLog(), "Image Comparison", "", expectedImage, resultImage, tcu::UVec4(2), tcu::COMPARE_LOG_RESULT))
727                         return tcu::TestStatus::fail("Fail");
728         }
729         return tcu::TestStatus::pass("Pass");
730 }
731
732 std::string getSizeString (const IVec3& size, const int numLayer)
733 {
734         std::ostringstream str;
735                                                         str <<            size.x();
736         if (size.y() > 1)               str << "x" << size.y();
737         if (size.z() > 1)               str << "x" << size.z();
738         if (numLayer > 1)               str << "_" << numLayer;
739
740         return str.str();
741 }
742
743 std::string getFormatString (const VkFormat format)
744 {
745         std::string name(getFormatName(format));
746         return de::toLower(name.substr(10));
747 }
748
749 std::string getShortImageViewTypeName (const VkImageViewType imageViewType)
750 {
751         std::string s(getImageViewTypeName(imageViewType));
752         return de::toLower(s.substr(19));
753 }
754
755 CaseDef caseDefWithFormat (CaseDef caseDef, const VkFormat format)
756 {
757         caseDef.colorFormat = format;
758         return caseDef;
759 }
760
761 void addTestCasesWithFunctions (tcu::TestCaseGroup* group)
762 {
763         const CaseDef caseDef[] =
764         {
765                 { VK_IMAGE_VIEW_TYPE_1D,                        IVec3(54,  1, 1),       1,              VK_FORMAT_UNDEFINED},
766                 { VK_IMAGE_VIEW_TYPE_1D_ARRAY,          IVec3(54,  1, 1),       4,              VK_FORMAT_UNDEFINED},
767                 { VK_IMAGE_VIEW_TYPE_2D,                        IVec3(22, 64, 1),       1,              VK_FORMAT_UNDEFINED},
768                 { VK_IMAGE_VIEW_TYPE_2D_ARRAY,          IVec3(22, 64, 1),       4,              VK_FORMAT_UNDEFINED},
769                 { VK_IMAGE_VIEW_TYPE_3D,                        IVec3(22, 64, 7),       1,              VK_FORMAT_UNDEFINED},
770                 { VK_IMAGE_VIEW_TYPE_CUBE,                      IVec3(35, 35, 1),       6,              VK_FORMAT_UNDEFINED},
771                 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,        IVec3(35, 35, 1),       2*6,    VK_FORMAT_UNDEFINED},
772         };
773
774         const VkFormat format[] =
775         {
776                 VK_FORMAT_R8G8B8A8_UNORM,
777                 VK_FORMAT_R32_UINT,
778                 VK_FORMAT_R16G16_SINT,
779                 VK_FORMAT_R32G32B32A32_SFLOAT,
780         };
781
782         for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(caseDef); ++sizeNdx)
783         {
784                 MovePtr<tcu::TestCaseGroup>     imageGroup(new tcu::TestCaseGroup(group->getTestContext(), getShortImageViewTypeName(caseDef[sizeNdx].imageType).c_str(), ""));
785                 {
786                         MovePtr<tcu::TestCaseGroup>     sizeGroup(new tcu::TestCaseGroup(group->getTestContext(), getSizeString(caseDef[sizeNdx].renderSize, caseDef[sizeNdx].numLayers).c_str(), ""));
787
788                         for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(format); ++formatNdx)
789                                 addFunctionCaseWithPrograms(sizeGroup.get(), getFormatString(format[formatNdx]).c_str(), "", initPrograms, test, caseDefWithFormat(caseDef[sizeNdx], format[formatNdx]));
790
791                         imageGroup->addChild(sizeGroup.release());
792                 }
793                 group->addChild(imageGroup.release());
794         }
795 }
796
797 } // anonymous ns
798
799 tcu::TestCaseGroup* createRenderToImageTests (tcu::TestContext& testCtx)
800 {
801         return createTestGroup(testCtx, "render_to_image", "Render to image tests", addTestCasesWithFunctions);
802 }
803
804 } // pipeline
805 } // vkt