Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / draw / vktDrawShaderLayerTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 The Khronos Group Inc.
6  * Copyright (c) 2018 The Android Open Source Project
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Use of gl_Layer in Vertex and Tessellation Shaders
23  *        (part of VK_EXT_ShaderViewportIndexLayer)
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktDrawShaderLayerTests.hpp"
27
28 #include "vktDrawBaseClass.hpp"
29 #include "vktTestCaseUtil.hpp"
30
31 #include "vkDefs.hpp"
32 #include "vkRef.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41
42 #include "tcuTestLog.hpp"
43 #include "tcuVector.hpp"
44 #include "tcuImageCompare.hpp"
45 #include "tcuTextureUtil.hpp"
46
47 #include "deUniquePtr.hpp"
48 #include "deMath.h"
49
50 #include <vector>
51
52 namespace vkt
53 {
54 namespace Draw
55 {
56 using namespace vk;
57 using de::UniquePtr;
58 using de::MovePtr;
59 using de::SharedPtr;
60 using tcu::Vec4;
61 using tcu::Vec2;
62 using tcu::UVec2;
63 using tcu::UVec4;
64
65 namespace
66 {
67
68 enum Constants
69 {
70         MIN_MAX_FRAMEBUFFER_LAYERS = 256,       //!< Minimum number of framebuffer layers.
71         MIN_MAX_VIEWPORTS = 16,                         //!< Minimum number of viewports for an implementation supporting multiViewport.
72 };
73
74 struct TestParams
75 {
76         int                                             numLayers;
77         const SharedGroupParams groupParams;
78 };
79
80 template<typename T>
81 inline VkDeviceSize sizeInBytes(const std::vector<T>& vec)
82 {
83         return vec.size() * sizeof(vec[0]);
84 }
85
86 VkImageCreateInfo makeImageCreateInfo (const VkFormat format, const UVec2& size, const deUint32 numLayers, VkImageUsageFlags usage)
87 {
88         const VkImageCreateInfo imageParams =
89         {
90                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType;
91                 DE_NULL,                                                                                // const void*                          pNext;
92                 (VkImageCreateFlags)0,                                                  // VkImageCreateFlags           flags;
93                 VK_IMAGE_TYPE_2D,                                                               // VkImageType                          imageType;
94                 format,                                                                                 // VkFormat                                     format;
95                 makeExtent3D(size.x(), size.y(), 1),                    // VkExtent3D                           extent;
96                 1u,                                                                                             // deUint32                                     mipLevels;
97                 numLayers,                                                                              // deUint32                                     arrayLayers;
98                 VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits        samples;
99                 VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling;
100                 usage,                                                                                  // VkImageUsageFlags            usage;
101                 VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode;
102                 0u,                                                                                             // deUint32                                     queueFamilyIndexCount;
103                 DE_NULL,                                                                                // const deUint32*                      pQueueFamilyIndices;
104                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        initialLayout;
105         };
106         return imageParams;
107 }
108
109 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&           vk,
110                                                                            const VkDevice                               device,
111                                                                            const VkPipelineLayout               pipelineLayout,
112                                                                            const VkRenderPass                   renderPass,
113                                                                            const VkShaderModule                 vertexModule,
114                                                                            const VkShaderModule                 tessellationControlModule,
115                                                                            const VkShaderModule                 tessellationEvaluationModule,
116                                                                            const VkShaderModule                 fragmentModule,
117                                                                            const UVec2                                  renderSize)
118 {
119         const VkVertexInputBindingDescription vertexInputBindingDescription =
120         {
121                 0u,                                                             // uint32_t                             binding;
122                 sizeof(PositionColorVertex),    // uint32_t                             stride;
123                 VK_VERTEX_INPUT_RATE_VERTEX,    // VkVertexInputRate    inputRate;
124         };
125
126         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
127         {
128                 {
129                         0u,                                                                     // uint32_t                     location;
130                         0u,                                                                     // uint32_t                     binding;
131                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat                     format;
132                         0u,                                                                     // uint32_t                     offset;
133                 },
134                 {
135                         1u,                                                                     // uint32_t                     location;
136                         0u,                                                                     // uint32_t                     binding;
137                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat                     format;
138                         sizeof(Vec4),                                           // uint32_t                     offset;
139                 },
140         };
141
142         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
143         {
144                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                             sType;
145                 DE_NULL,                                                                                                                // const void*                                 pNext;
146                 (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags       flags;
147                 1u,                                                                                                                             // uint32_t                                    vertexBindingDescriptionCount;
148                 &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
149                 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),                   // uint32_t                                    vertexAttributeDescriptionCount;
150                 vertexInputAttributeDescriptions,                                                               // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
151         };
152
153         const bool useTessellationShaders = (tessellationControlModule != DE_NULL) && (tessellationEvaluationModule != DE_NULL);
154
155         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
156         {
157                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,                                                                            // VkStructureType                             sType;
158                 DE_NULL,                                                                                                                                                                                        // const void*                                 pNext;
159                 (VkPipelineInputAssemblyStateCreateFlags)0,                                                                                                                     // VkPipelineInputAssemblyStateCreateFlags     flags;
160                 useTessellationShaders ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,        // VkPrimitiveTopology                         topology;
161                 VK_FALSE,                                                                                                                                                                                       // VkBool32                                    primitiveRestartEnable;
162         };
163
164
165         VkViewport viewport = makeViewport(0.0f, 0.0f, static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()), 0.0f, 1.0f);
166         VkRect2D rectScissor = { { 0, 0 }, { renderSize.x(), renderSize.y() } };
167
168         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
169         {
170                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                             sType;
171                 DE_NULL,                                                                                                                // const void*                                 pNext;
172                 (VkPipelineViewportStateCreateFlags)0,                                                  // VkPipelineViewportStateCreateFlags          flags;
173                 1u,                                                                                                                             // uint32_t                                    viewportCount;
174                 &viewport,                                                                                                              // const VkViewport*                           pViewports;
175                 1u,                                                                                                                             // uint32_t                                    scissorCount;
176                 &rectScissor,                                                                                                   // const VkRect2D*                             pScissors;
177         };
178
179         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
180         {
181                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
182                 DE_NULL,                                                                                                                // const void*                              pNext;
183                 (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags  flags;
184                 VK_FALSE,                                                                                                               // VkBool32                                 depthClampEnable;
185                 VK_FALSE,                                                                                                               // VkBool32                                 rasterizerDiscardEnable;
186                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
187                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
188                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
189                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
190                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
191                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
192                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
193                 1.0f,                                                                                                                   // float                                                                        lineWidth;
194         };
195
196         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
197         {
198                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
199                 DE_NULL,                                                                                                                // const void*                                                          pNext;
200                 (VkPipelineMultisampleStateCreateFlags)0,                                               // VkPipelineMultisampleStateCreateFlags        flags;
201                 VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
202                 VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
203                 0.0f,                                                                                                                   // float                                                                        minSampleShading;
204                 DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
205                 VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
206                 VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
207         };
208
209         const VkStencilOpState stencilOpState = makeStencilOpState(
210                 VK_STENCIL_OP_KEEP,                             // stencil fail
211                 VK_STENCIL_OP_KEEP,                             // depth & stencil pass
212                 VK_STENCIL_OP_KEEP,                             // depth only fail
213                 VK_COMPARE_OP_ALWAYS,                   // compare op
214                 0u,                                                             // compare mask
215                 0u,                                                             // write mask
216                 0u);                                                    // reference
217
218         VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
219         {
220                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
221                 DE_NULL,                                                                                                                // const void*                                                          pNext;
222                 (VkPipelineDepthStencilStateCreateFlags)0,                                              // VkPipelineDepthStencilStateCreateFlags       flags;
223                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthTestEnable;
224                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthWriteEnable;
225                 VK_COMPARE_OP_LESS,                                                                                             // VkCompareOp                                                          depthCompareOp;
226                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBoundsTestEnable;
227                 VK_FALSE,                                                                                                               // VkBool32                                                                     stencilTestEnable;
228                 stencilOpState,                                                                                                 // VkStencilOpState                                                     front;
229                 stencilOpState,                                                                                                 // VkStencilOpState                                                     back;
230                 0.0f,                                                                                                                   // float                                                                        minDepthBounds;
231                 1.0f,                                                                                                                   // float                                                                        maxDepthBounds;
232         };
233
234         const VkColorComponentFlags                                     colorComponentsAll                                      = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
235         const VkPipelineColorBlendAttachmentState       pipelineColorBlendAttachmentState       =
236         {
237                 VK_FALSE,                                               // VkBool32                                     blendEnable;
238                 VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcColorBlendFactor;
239                 VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        dstColorBlendFactor;
240                 VK_BLEND_OP_ADD,                                // VkBlendOp                            colorBlendOp;
241                 VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcAlphaBlendFactor;
242                 VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        dstAlphaBlendFactor;
243                 VK_BLEND_OP_ADD,                                // VkBlendOp                            alphaBlendOp;
244                 colorComponentsAll,                             // VkColorComponentFlags        colorWriteMask;
245         };
246
247         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
248         {
249                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,               // VkStructureType                                                              sType;
250                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
251                 (VkPipelineColorBlendStateCreateFlags)0,                                                // VkPipelineColorBlendStateCreateFlags                 flags;
252                 VK_FALSE,                                                                                                               // VkBool32                                                                             logicOpEnable;
253                 VK_LOGIC_OP_COPY,                                                                                               // VkLogicOp                                                                    logicOp;
254                 1u,                                                                                                                             // deUint32                                                                             attachmentCount;
255                 &pipelineColorBlendAttachmentState,                                                             // const VkPipelineColorBlendAttachmentState*   pAttachments;
256                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                             // float                                                                                blendConstants[4];
257         };
258
259         const VkPipelineShaderStageCreateInfo pShaderStages[] =
260         {
261                 {
262                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
263                         DE_NULL,                                                                                                        // const void*                                                  pNext;
264                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
265                         VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
266                         vertexModule,                                                                                           // VkShaderModule                                               module;
267                         "main",                                                                                                         // const char*                                                  pName;
268                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                  pSpecializationInfo;
269                 },
270                 {
271                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
272                         DE_NULL,                                                                                                        // const void*                                                  pNext;
273                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
274                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
275                         fragmentModule,                                                                                         // VkShaderModule                                               module;
276                         "main",                                                                                                         // const char*                                                  pName;
277                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                  pSpecializationInfo;
278                 },
279                 {
280                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
281                         DE_NULL,                                                                                                        // const void*                                                  pNext;
282                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
283                         VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,                                       // VkShaderStageFlagBits                                stage;
284                         tessellationControlModule,                                                                      // VkShaderModule                                               module;
285                         "main",                                                                                                         // const char*                                                  pName;
286                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                  pSpecializationInfo;
287                 },
288                 {
289                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
290                         DE_NULL,                                                                                                        // const void*                                                  pNext;
291                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
292                         VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,                            // VkShaderStageFlagBits                                stage;
293                         tessellationEvaluationModule,                                                           // VkShaderModule                                               module;
294                         "main",                                                                                                         // const char*                                                  pName;
295                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                  pSpecializationInfo;
296                 },
297         };
298
299         const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
300         {
301                 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
302                 DE_NULL,                                                                                                                // const void*                                                          pNext;
303                 (VkPipelineTessellationStateCreateFlags)0,                                              // VkPipelineTessellationStateCreateFlags       flags;
304                 3,                                                                                                                              // uint32_t                                                                     patchControlPoints;
305         };
306
307         VkGraphicsPipelineCreateInfo graphicsPipelineInfo
308         {
309                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                        // VkStructureType                                                                      sType;
310                 DE_NULL,                                                                                                                        // const void*                                                                          pNext;
311                 (VkPipelineCreateFlags)0,                                                                                       // VkPipelineCreateFlags                                                        flags;
312                 useTessellationShaders ? deUint32(4) : deUint32(2),                                     // deUint32                                                                                     stageCount;
313                 pShaderStages,                                                                                                          // const VkPipelineShaderStageCreateInfo*                       pStages;
314                 &vertexInputStateInfo,                                                                                          // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
315                 &pipelineInputAssemblyStateInfo,                                                                        // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
316                 useTessellationShaders ? &pipelineTessellationStateInfo : DE_NULL,      // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
317                 &pipelineViewportStateInfo,                                                                                     // const VkPipelineViewportStateCreateInfo*                     pViewportState;
318                 &pipelineRasterizationStateInfo,                                                                        // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
319                 &pipelineMultisampleStateInfo,                                                                          // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
320                 &pipelineDepthStencilStateInfo,                                                                         // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
321                 &pipelineColorBlendStateInfo,                                                                           // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
322                 DE_NULL,                                                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
323                 pipelineLayout,                                                                                                         // VkPipelineLayout                                                                     layout;
324                 renderPass,                                                                                                                     // VkRenderPass                                                                         renderPass;
325                 0u,                                                                                                                                     // deUint32                                                                                     subpass;
326                 DE_NULL,                                                                                                                        // VkPipeline                                                                           basePipelineHandle;
327                 0,                                                                                                                                      // deInt32                                                                                      basePipelineIndex;
328         };
329
330 #ifndef CTS_USES_VULKANSC
331         VkFormat colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM;
332         VkPipelineRenderingCreateInfoKHR renderingCreateInfo
333         {
334                 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
335                 DE_NULL,
336                 0u,
337                 1u,
338                 &colorAttachmentFormat,
339                 VK_FORMAT_UNDEFINED,
340                 VK_FORMAT_UNDEFINED
341         };
342
343         // when pipeline is created without render pass we are using dynamic rendering
344         if (renderPass == DE_NULL)
345                 graphicsPipelineInfo.pNext = &renderingCreateInfo;
346 #endif // CTS_USES_VULKANSC
347
348         return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
349 }
350
351 //! Renders a colorful grid of rectangles.
352 tcu::TextureLevel generateReferenceImage (const tcu::TextureFormat      format,
353                                                                                   const UVec2&                          renderSize,
354                                                                                   const Vec4&                           clearColor,
355                                                                                   const UVec4&                          cell,
356                                                                                   const Vec4&                           cellColor)
357 {
358         tcu::TextureLevel image(format, renderSize.x(), renderSize.y());
359         tcu::clear(image.getAccess(), clearColor);
360
361         tcu::clear(tcu::getSubregion(image.getAccess(), cell.x(), cell.y(), cell.z(), cell.w()),
362                            cellColor);
363
364         return image;
365 }
366
367 void initVertexTestPrograms (SourceCollections& programCollection, const TestParams params)
368 {
369         DE_UNREF(params.numLayers);
370
371         // Vertex shader
372         {
373                 std::ostringstream src;
374                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
375                         << "#extension GL_ARB_shader_viewport_layer_array : require\n"
376                         << "\n"
377                         << "layout(location = 0) in  vec4 in_position;\n"
378                         << "layout(location = 1) in  vec4 in_color;\n"
379                         << "layout(location = 0) out vec4 out_color;\n"
380                         << "\n"
381                         << "void main(void)\n"
382                         << "{\n"
383                         << "    gl_Layer = gl_VertexIndex / 6;\n"
384                         << "    gl_Position = in_position;\n"
385                         << "    out_color = in_color;\n"
386                         << "}\n";
387
388                 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
389         }
390
391         // Fragment shader
392         {
393                 std::ostringstream src;
394                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
395                         << "\n"
396                         << "layout(location = 0) in  vec4 in_color;\n"
397                         << "layout(location = 0) out vec4 out_color;\n"
398                         << "\n"
399                         << "void main(void)\n"
400                         << "{\n"
401                         << "    out_color = in_color;\n"
402                         << "}\n";
403
404                 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
405         }
406 }
407
408 void initTessellationTestPrograms (SourceCollections& programCollection, const TestParams params)
409 {
410         DE_UNREF(params.numLayers);
411
412         // Vertex shader
413         {
414                 std::ostringstream src;
415                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
416                         << "\n"
417                         << "layout(location = 0) in  vec4 in_position;\n"
418                         << "layout(location = 1) in  vec4 in_color;\n"
419                         << "layout(location = 0) out vec4 out_color;\n"
420                         << "\n"
421                         << "void main(void)\n"
422                         << "{\n"
423                         << "    gl_Position = in_position;\n"
424                         << "    out_color = in_color;\n"
425                         << "}\n";
426
427                 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
428         }
429
430         // Tessellation control shader
431         {
432                 std::ostringstream src;
433                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
434                         << "\n"
435                         << "layout(vertices = 3) out;\n"
436                         << "\n"
437                         << "layout(location = 0) in  vec4 in_color[];\n"
438                         << "layout(location = 0) out vec4 out_color[];\n"
439                         << "\n"
440                         << "void main(void)\n"
441                         << "{\n"
442                         << "    if (gl_InvocationID == 0) {\n"
443                         << "        gl_TessLevelInner[0] = 1.0;\n"
444                         << "        gl_TessLevelInner[1] = 1.0;\n"
445                         << "        gl_TessLevelOuter[0] = 1.0;\n"
446                         << "        gl_TessLevelOuter[1] = 1.0;\n"
447                         << "        gl_TessLevelOuter[2] = 1.0;\n"
448                         << "        gl_TessLevelOuter[3] = 1.0;\n"
449                         << "    }\n"
450                         << "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
451                         << "    out_color[gl_InvocationID] = in_color[gl_InvocationID];\n"
452                         << "}\n";
453
454                 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
455         }
456
457         // Tessellation evaluation shader
458         {
459                 std::ostringstream src;
460                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
461                         << "#extension GL_ARB_shader_viewport_layer_array : require\n"
462                         << "\n"
463                         << "layout(triangles, equal_spacing, cw) in;\n"
464                         << "\n"
465                         << "layout(location = 0) in  vec4 in_color[];\n"
466                         << "layout(location = 0) out vec4 out_color;\n"
467                         << "\n"
468                         << "void main(void)\n"
469                         << "{\n"
470                         << "    gl_Layer = gl_PrimitiveID / 2;\n"
471                         << "    gl_Position = gl_in[0].gl_Position * gl_TessCoord.x +\n"
472                         << "                  gl_in[1].gl_Position * gl_TessCoord.y +\n"
473                         << "                  gl_in[2].gl_Position * gl_TessCoord.z;\n"
474                         << "\n"
475                         << "    out_color = in_color[0] * gl_TessCoord.x +\n"
476                         << "                in_color[1] * gl_TessCoord.y +\n"
477                         << "                in_color[2] * gl_TessCoord.z;\n"
478                         << "}\n";
479
480                 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
481         }
482
483         // Fragment shader
484         {
485                 std::ostringstream src;
486                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
487                         << "\n"
488                         << "layout(location = 0) in  vec4 in_color;\n"
489                         << "layout(location = 0) out vec4 out_color;\n"
490                         << "\n"
491                         << "void main(void)\n"
492                         << "{\n"
493                         << "    out_color = in_color;\n"
494                         << "}\n";
495
496                 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
497         }
498 }
499
500 std::vector<UVec4> generateGrid (const int numCells, const UVec2& renderSize)
501 {
502         const int numCols               = deCeilFloatToInt32(deFloatSqrt(static_cast<float>(numCells)));
503         const int numRows               = deCeilFloatToInt32(static_cast<float>(numCells) / static_cast<float>(numCols));
504         const int rectWidth             = renderSize.x() / numCols;
505         const int rectHeight    = renderSize.y() / numRows;
506
507         std::vector<UVec4> cells;
508         cells.reserve(numCells);
509
510         int x = 0;
511         int y = 0;
512
513         for (int cellNdx = 0; cellNdx < numCells; ++cellNdx)
514         {
515                 const bool nextRow = (cellNdx != 0) && (cellNdx % numCols == 0);
516                 if (nextRow)
517                 {
518                         x  = 0;
519                         y += rectHeight;
520                 }
521
522                 cells.push_back(UVec4(x, y, rectWidth, rectHeight));
523
524                 x += rectWidth;
525         }
526
527         return cells;
528 }
529
530 std::vector<Vec4> generateColors (int numColors)
531 {
532         const Vec4 colors[] =
533         {
534                 Vec4(0.18f, 0.42f, 0.17f, 1.0f),
535                 Vec4(0.29f, 0.62f, 0.28f, 1.0f),
536                 Vec4(0.59f, 0.84f, 0.44f, 1.0f),
537                 Vec4(0.96f, 0.95f, 0.72f, 1.0f),
538                 Vec4(0.94f, 0.55f, 0.39f, 1.0f),
539                 Vec4(0.82f, 0.19f, 0.12f, 1.0f),
540                 Vec4(0.46f, 0.15f, 0.26f, 1.0f),
541                 Vec4(0.24f, 0.14f, 0.24f, 1.0f),
542                 Vec4(0.49f, 0.31f, 0.26f, 1.0f),
543                 Vec4(0.78f, 0.52f, 0.33f, 1.0f),
544                 Vec4(0.94f, 0.82f, 0.31f, 1.0f),
545                 Vec4(0.98f, 0.65f, 0.30f, 1.0f),
546                 Vec4(0.22f, 0.65f, 0.53f, 1.0f),
547                 Vec4(0.67f, 0.81f, 0.91f, 1.0f),
548                 Vec4(0.43f, 0.44f, 0.75f, 1.0f),
549                 Vec4(0.26f, 0.24f, 0.48f, 1.0f),
550         };
551
552         std::vector<Vec4> result;
553         result.reserve(numColors);
554
555         for (int i = 0; i < numColors; ++i)
556         {
557                 result.push_back(colors[i % DE_LENGTH_OF_ARRAY(colors)]);
558         }
559
560         return result;
561 }
562
563 std::vector<PositionColorVertex> generateVertices (const std::vector<UVec4>& grid, const std::vector<Vec4>& colors, const UVec2& renderSize)
564 {
565         DE_ASSERT(colors.size() == grid.size());
566
567         // Two triangles for each cell. Each cell correspond to a layer.
568         std::size_t total = grid.size() * 6;
569
570         std::vector<PositionColorVertex> result;
571         result.reserve(total);
572
573         for (std::size_t i = 0; i < total; ++i)
574         {
575                 Vec4 pos;
576                 pos.z() = 0.0;
577                 pos.w() = 1.0;
578
579                 Vec4 cell = grid[i/6].asFloat() * 2.0f;
580                 float x                 = cell.x() / float(renderSize.x()) - 1.0f;
581                 float y                 = cell.y() / float(renderSize.y()) - 1.0f;
582                 float width             = cell.z() / float(renderSize.x());
583                 float height    = cell.w() / float(renderSize.y());
584
585                 switch (i % 6)
586                 {
587                 case 0: pos.xy() = Vec2(x,                      y + height);    break;
588                 case 1: pos.xy() = Vec2(x + width,      y + height);    break;
589                 case 2: pos.xy() = Vec2(x,                      y);                             break;
590                 case 3: pos.xy() = Vec2(x + width,      y);                             break;
591                 case 4: pos.xy() = Vec2(x + width,      y + height);    break;
592                 case 5: pos.xy() = Vec2(x,                      y);                             break;
593                 }
594
595                 result.push_back(PositionColorVertex(pos, colors[i/6]));
596         }
597
598         return result;
599 }
600
601 // Renderer generates two triangles per layer, each pair using a different
602 // color and a different position.
603 class Renderer
604 {
605 public:
606         enum Shader
607         {
608                 VERTEX,
609                 TESSELLATION,
610         };
611
612         Renderer (Context&                                                                      context,
613                           const SharedGroupParams                                       groupParams,
614                           const UVec2&                                                          renderSize,
615                           const int                                                                     numLayers,
616                           const VkFormat                                                        colorFormat,
617                           const Vec4&                                                           clearColor,
618                           const std::vector<PositionColorVertex>&       vertices,
619                           const Shader                                                          shader)
620                 : m_groupParams                         (groupParams)
621                 , m_renderSize                          (renderSize)
622                 , m_colorFormat                         (colorFormat)
623                 , m_colorSubresourceRange       (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers))
624                 , m_clearColor                          (clearColor)
625                 , m_numLayers                           (numLayers)
626                 , m_vertices                            (vertices)
627         {
628                 const DeviceInterface&          vk                                      = context.getDeviceInterface();
629                 const VkDevice                          device                          = context.getDevice();
630                 const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
631                 Allocator&                                      allocator                       = context.getDefaultAllocator();
632                 const VkDeviceSize                      vertexBufferSize        = sizeInBytes(m_vertices);
633
634                 m_colorImage            = makeImage                                     (vk, device, makeImageCreateInfo(m_colorFormat, m_renderSize, m_numLayers, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT));
635                 m_colorImageAlloc       = bindImage                                     (vk, device, allocator, *m_colorImage, MemoryRequirement::Any);
636                 m_colorAttachment       = makeImageView                         (vk, device, *m_colorImage, VK_IMAGE_VIEW_TYPE_2D_ARRAY, m_colorFormat, m_colorSubresourceRange);
637
638                 m_vertexBuffer          = Buffer::createAndAlloc        (vk, device, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), allocator, MemoryRequirement::HostVisible);
639
640                 deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), &m_vertices[0], static_cast<std::size_t>(vertexBufferSize));
641                 flushAlloc(vk, device, m_vertexBuffer->getBoundMemory());
642
643                 if (shader == TESSELLATION)
644                 {
645                         m_tessellationControlModule             = createShaderModule    (vk, device, context.getBinaryCollection().get("tesc"), 0u);
646                         m_tessellationEvaluationModule  = createShaderModule    (vk, device, context.getBinaryCollection().get("tese"), 0u);
647                 }
648
649                 m_vertexModule          = createShaderModule    (vk, device, context.getBinaryCollection().get("vert"), 0u);
650                 m_fragmentModule        = createShaderModule    (vk, device, context.getBinaryCollection().get("frag"), 0u);
651
652                 if (!m_groupParams->useDynamicRendering)
653                 {
654                         m_renderPass    = makeRenderPass                (vk, device, m_colorFormat);
655
656                         m_framebuffer   = makeFramebuffer               (vk, device, *m_renderPass, m_colorAttachment.get(),
657                                                                                                          static_cast<deUint32>(m_renderSize.x()),
658                                                                                                          static_cast<deUint32>(m_renderSize.y()),
659                                                                                                          numLayers);
660                 }
661
662                 m_pipelineLayout        = makePipelineLayout    (vk, device);
663                 m_pipeline                      = makeGraphicsPipeline  (vk, device, *m_pipelineLayout, *m_renderPass, *m_vertexModule, *m_tessellationControlModule,
664                                                                                                          *m_tessellationEvaluationModule, *m_fragmentModule, m_renderSize);
665                 m_cmdPool                       = createCommandPool             (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
666                 m_cmdBuffer                     = allocateCommandBuffer (vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
667                 m_secCmdBuffer          = allocateCommandBuffer (vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
668         }
669
670         void draw (Context& context, const VkBuffer colorBuffer) const
671         {
672                 const DeviceInterface&  vk                      = context.getDeviceInterface();
673                 const VkDevice                  device          = context.getDevice();
674                 const VkQueue                   queue           = context.getUniversalQueue();
675                 const VkClearValue              clearValue      = makeClearValueColor(m_clearColor);
676                 const VkRect2D                  renderArea
677                 {
678                         makeOffset2D(0, 0),
679                         makeExtent2D(m_renderSize.x(), m_renderSize.y()),
680                 };
681
682 #ifndef CTS_USES_VULKANSC
683                 if (m_groupParams->useSecondaryCmdBuffer)
684                 {
685                         // record secondary command buffer
686                         if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
687                         {
688                                 beginSecondaryCmdBuffer(context, *m_secCmdBuffer, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
689                                 beginRendering(vk, *m_secCmdBuffer, *m_colorAttachment, renderArea, clearValue,
690                                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_CLEAR, 0u, m_numLayers);
691                         }
692                         else
693                                 beginSecondaryCmdBuffer(context, *m_secCmdBuffer);
694
695                         drawCommands(context, *m_secCmdBuffer);
696
697                         if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
698                                 endRendering(vk, *m_secCmdBuffer);
699
700                         endCommandBuffer(vk, *m_secCmdBuffer);
701
702                         // record primary command buffer
703                         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
704
705                         preRenderCommands(context, *m_cmdBuffer);
706
707                         if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
708                                 beginRendering(vk, *m_cmdBuffer, *m_colorAttachment, renderArea, clearValue, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
709                                                            VK_ATTACHMENT_LOAD_OP_CLEAR, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, m_numLayers);
710
711                         vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
712
713                         if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
714                                 endRendering(vk, *m_cmdBuffer);
715
716                         postRenderCommands(context, colorBuffer);
717                         endCommandBuffer(vk, *m_cmdBuffer);
718                 }
719                 else if (m_groupParams->useDynamicRendering)
720                 {
721                         beginCommandBuffer(vk, *m_cmdBuffer);
722
723                         preRenderCommands(context, *m_cmdBuffer);
724                         beginRendering(vk, *m_cmdBuffer, *m_colorAttachment, renderArea, clearValue,
725                                                    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_CLEAR, 0u, m_numLayers);
726                         drawCommands(context, *m_cmdBuffer);
727                         endRendering(vk, *m_cmdBuffer);
728                         postRenderCommands(context, colorBuffer);
729
730                         endCommandBuffer(vk, *m_cmdBuffer);
731                 }
732 #endif // CTS_USES_VULKANSC
733
734                 if (!m_groupParams->useDynamicRendering)
735                 {
736                         beginCommandBuffer(vk, *m_cmdBuffer);
737
738                         preRenderCommands(context, *m_cmdBuffer);
739                         beginRenderPass(context, *m_cmdBuffer, renderArea, clearValue);
740                         drawCommands(context, *m_cmdBuffer);
741                         vk.cmdEndRenderPass(*m_cmdBuffer);
742                         postRenderCommands(context, colorBuffer);
743
744                         endCommandBuffer(vk, *m_cmdBuffer);
745                 }
746
747                 submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
748         }
749
750 protected:
751
752         void preRenderCommands(Context& context, VkCommandBuffer cmdBuffer) const
753         {
754                 if (m_groupParams->useDynamicRendering)
755                 {
756                         const DeviceInterface& vk = context.getDeviceInterface();
757                         initialTransitionColor2DImage(vk, cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
758                                                                                   VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, m_colorSubresourceRange.layerCount);
759                 }
760         }
761
762         void postRenderCommands(Context& context, VkBuffer colorBuffer) const
763         {
764                 const DeviceInterface& vk = context.getDeviceInterface();
765                 copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, colorBuffer, tcu::IVec2(m_renderSize.x(), m_renderSize.y()), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, m_colorSubresourceRange.layerCount);
766         }
767
768         void beginRenderPass(Context& context, VkCommandBuffer cmdBuffer, const VkRect2D& renderArea, const VkClearValue& clearValue) const
769         {
770                 const DeviceInterface& vk = context.getDeviceInterface();
771                 const VkRenderPassBeginInfo renderPassBeginInfo
772                 {
773                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType                      sType;
774                         DE_NULL,                                                                                // const void*                          pNext;
775                         *m_renderPass,                                                                  // VkRenderPass                         renderPass;
776                         *m_framebuffer,                                                                 // VkFramebuffer                        framebuffer;
777                         renderArea,                                                                             // VkRect2D                                     renderArea;
778                         1u,                                                                                             // uint32_t                                     clearValueCount;
779                         &clearValue,                                                                    // const VkClearValue*          pClearValues;
780                 };
781                 vk.cmdBeginRenderPass(cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
782         }
783
784         void drawCommands (Context& context, VkCommandBuffer cmdBuffer) const
785         {
786                 const DeviceInterface&  vk                                      = context.getDeviceInterface();
787                 const VkBuffer                  vertexBuffer            = m_vertexBuffer->object();
788                 const VkDeviceSize              vertexBufferOffset      = 0ull;
789
790                 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
791                 vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
792                 vk.cmdDraw(cmdBuffer, static_cast<deUint32>(m_numLayers * 6), 1u, 0u, 0u);      // two triangles per layer
793         }
794
795 #ifndef CTS_USES_VULKANSC
796         void beginSecondaryCmdBuffer(Context& context, VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags = 0u) const
797         {
798                 VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
799                 {
800                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,                // VkStructureType                                      sType;
801                         DE_NULL,                                                                                                                                // const void*                                          pNext;
802                         renderingFlags,                                                                                                                 // VkRenderingFlagsKHR                          flags;
803                         0u,                                                                                                                                             // uint32_t                                                     viewMask;
804                         1u,                                                                                                                                             // uint32_t                                                     colorAttachmentCount;
805                         &m_colorFormat,                                                                                                                 // const VkFormat*                                      pColorAttachmentFormats;
806                         VK_FORMAT_UNDEFINED,                                                                                                    // VkFormat                                                     depthAttachmentFormat;
807                         VK_FORMAT_UNDEFINED,                                                                                                    // VkFormat                                                     stencilAttachmentFormat;
808                         VK_SAMPLE_COUNT_1_BIT,                                                                                                  // VkSampleCountFlagBits                        rasterizationSamples;
809                 };
810                 const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
811
812                 VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
813                 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
814                         usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
815
816                 const VkCommandBufferBeginInfo commandBufBeginParams
817                 {
818                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                                                    // VkStructureType                                      sType;
819                         DE_NULL,                                                                                                                                // const void*                                          pNext;
820                         usageFlags,                                                                                                                             // VkCommandBufferUsageFlags            flags;
821                         &bufferInheritanceInfo
822                 };
823
824                 const DeviceInterface& vk = context.getDeviceInterface();
825                 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
826         }
827 #endif // CTS_USES_VULKANSC
828
829 private:
830         const SharedGroupParams                                 m_groupParams;
831         const UVec2                                                             m_renderSize;
832         const VkFormat                                                  m_colorFormat;
833         const VkImageSubresourceRange                   m_colorSubresourceRange;
834         const Vec4                                                              m_clearColor;
835         const int                                                               m_numLayers;
836         const std::vector<PositionColorVertex>  m_vertices;
837
838         Move<VkImage>                                                   m_colorImage;
839         MovePtr<Allocation>                                             m_colorImageAlloc;
840         Move<VkImageView>                                               m_colorAttachment;
841         SharedPtr<Buffer>                                               m_vertexBuffer;
842         Move<VkShaderModule>                                    m_vertexModule;
843         Move<VkShaderModule>                                    m_tessellationControlModule;
844         Move<VkShaderModule>                                    m_tessellationEvaluationModule;
845         Move<VkShaderModule>                                    m_fragmentModule;
846         Move<VkRenderPass>                                              m_renderPass;
847         Move<VkFramebuffer>                                             m_framebuffer;
848         Move<VkPipelineLayout>                                  m_pipelineLayout;
849         Move<VkPipeline>                                                m_pipeline;
850         Move<VkCommandPool>                                             m_cmdPool;
851         Move<VkCommandBuffer>                                   m_cmdBuffer;
852         Move<VkCommandBuffer>                                   m_secCmdBuffer;
853
854         // "deleted"
855                                 Renderer        (const Renderer&);
856         Renderer&       operator=       (const Renderer&);
857 };
858
859 void checkRequirements (Context& context, const TestParams params)
860 {
861         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_MULTI_VIEWPORT);
862         context.requireDeviceFunctionality("VK_EXT_shader_viewport_index_layer");
863
864         if (params.groupParams->useDynamicRendering)
865                 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
866
867         const VkPhysicalDeviceLimits    limits  = context.getDeviceProperties().limits;
868
869         if (limits.maxFramebufferLayers < MIN_MAX_FRAMEBUFFER_LAYERS)
870                 TCU_FAIL("maxFramebuffersLayers is less than the minimum required");
871
872         if (limits.maxViewports < MIN_MAX_VIEWPORTS)
873                 TCU_FAIL("multiViewport supported but maxViewports is less than the minimum required");
874 }
875
876 tcu::TestStatus testVertexShader (Context& context, const TestParams params)
877 {
878         const DeviceInterface&                                  vk                                      = context.getDeviceInterface();
879         const VkDevice                                                  device                          = context.getDevice();
880         Allocator&                                                              allocator                       = context.getDefaultAllocator();
881
882         const UVec2                                                             renderSize                      (256, 256);
883         const VkFormat                                                  colorFormat                     = VK_FORMAT_R8G8B8A8_UNORM;
884         const Vec4                                                              clearColor                      (0.5f, 0.5f, 0.5f, 1.0f);
885         const std::vector<UVec4>                                grid                            = generateGrid(params.numLayers, renderSize);
886         const std::vector<Vec4>                                 colors                          = generateColors(params.numLayers);
887         const std::vector<PositionColorVertex>  vertices                        = generateVertices(grid, colors, renderSize);
888
889         const VkDeviceSize                                              colorBufferSize         = renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat)) * params.numLayers;
890
891         const SharedPtr<Buffer>                                 colorBuffer                     = Buffer::createAndAlloc(vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), allocator, MemoryRequirement::HostVisible);
892
893         // Zero buffer.
894         {
895                 const Allocation alloc = colorBuffer->getBoundMemory();
896                 deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
897                 flushAlloc(vk, device, alloc);
898         }
899
900         {
901                 context.getTestContext().getLog()
902                         << tcu::TestLog::Message << "Rendering a rectangle in each of the " << params.numLayers << " layer(s)." << tcu::TestLog::EndMessage
903                         << tcu::TestLog::Message << "Not covered area will be filled with a gray color." << tcu::TestLog::EndMessage;
904         }
905
906         // Draw.
907         {
908                 const Renderer renderer (context, params.groupParams, renderSize, params.numLayers, colorFormat, clearColor, vertices, Renderer::VERTEX);
909                 renderer.draw(context, colorBuffer->object());
910         }
911
912         // Verify layers.
913         {
914                 const Allocation alloc = colorBuffer->getBoundMemory();
915                 invalidateAlloc(vk, device, alloc);
916
917                 deUint8* resultMem = reinterpret_cast<deUint8*>(alloc.getHostPtr());
918                 for (int i = 0; i < params.numLayers; i++)
919                 {
920                         const tcu::ConstPixelBufferAccess       resultImage             (mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1u, resultMem + ((colorBufferSize / params.numLayers) * i));
921                         const tcu::TextureLevel                         referenceImage  = generateReferenceImage(mapVkFormat(colorFormat), renderSize, clearColor, grid[i], colors[i]);
922                         std::string imageSetName = "layer_" + de::toString(i);
923                         std::string imageSetDesc = "Image compare for layer " + de::toString(i);
924                         if (!tcu::floatThresholdCompare(context.getTestContext().getLog(), imageSetName.c_str(), imageSetDesc.c_str(), referenceImage.getAccess(), resultImage, Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
925                                 TCU_FAIL("Rendered image is not correct");
926                 }
927         }
928
929         return tcu::TestStatus::pass("OK");
930 }
931
932 tcu::TestStatus testTessellationShader (Context& context, const TestParams params)
933 {
934         const VkPhysicalDeviceFeatures&                 features                        = context.getDeviceFeatures();
935         if (!features.tessellationShader)
936                 TCU_THROW(NotSupportedError, "Required feature is not supported: tessellationShader");
937
938         const DeviceInterface&                                  vk                                      = context.getDeviceInterface();
939         const VkDevice                                                  device                          = context.getDevice();
940         Allocator&                                                              allocator                       = context.getDefaultAllocator();
941
942         const UVec2                                                             renderSize                      (256, 256);
943         const VkFormat                                                  colorFormat                     = VK_FORMAT_R8G8B8A8_UNORM;
944         const Vec4                                                              clearColor                      (0.5f, 0.5f, 0.5f, 1.0f);
945         const std::vector<UVec4>                                grid                            = generateGrid(params.numLayers, renderSize);
946         const std::vector<Vec4>                                 colors                          = generateColors(params.numLayers);
947         const std::vector<PositionColorVertex>  vertices                        = generateVertices(grid, colors, renderSize);
948
949         const VkDeviceSize                                              colorBufferSize         = renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat)) * params.numLayers;
950
951         const SharedPtr<Buffer>                                 colorBuffer                     = Buffer::createAndAlloc(vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), allocator, MemoryRequirement::HostVisible);
952
953         // Zero buffer.
954         {
955                 const Allocation alloc = colorBuffer->getBoundMemory();
956                 deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
957                 flushAlloc(vk, device, alloc);
958         }
959
960         {
961                 context.getTestContext().getLog()
962                         << tcu::TestLog::Message << "Rendering a rectangle in each of the " << params.numLayers << " layer(s)." << tcu::TestLog::EndMessage
963                         << tcu::TestLog::Message << "Not covered area will be filled with a gray color." << tcu::TestLog::EndMessage;
964         }
965
966         // Draw.
967         {
968                 const Renderer renderer (context, params.groupParams, renderSize, params.numLayers, colorFormat, clearColor, vertices, Renderer::TESSELLATION);
969                 renderer.draw(context, colorBuffer->object());
970         }
971
972         // Verify layers.
973         {
974                 const Allocation alloc = colorBuffer->getBoundMemory();
975                 invalidateAlloc(vk, device, alloc);
976
977                 deUint8* resultMem = reinterpret_cast<deUint8*>(alloc.getHostPtr());
978                 for (int i = 0; i < params.numLayers; i++) {
979                         const tcu::ConstPixelBufferAccess       resultImage             (mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1u, resultMem + ((colorBufferSize / params.numLayers) * i));
980                         const tcu::TextureLevel                         referenceImage  = generateReferenceImage(mapVkFormat(colorFormat), renderSize, clearColor, grid[i], colors[i]);
981                         std::string imageSetName = "layer_" + de::toString(i);
982                         std::string imageSetDesc = "Image compare for layer " + de::toString(i);
983                         if (!tcu::floatThresholdCompare(context.getTestContext().getLog(), imageSetName.c_str(), imageSetDesc.c_str(), referenceImage.getAccess(), resultImage, Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
984                                 TCU_FAIL("Rendered image is not correct");
985                 }
986         }
987
988         return tcu::TestStatus::pass("OK");
989 }
990
991 } // anonymous
992
993 tcu::TestCaseGroup* createShaderLayerTests      (tcu::TestContext& testCtx, const SharedGroupParams groupParams)
994 {
995         MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "shader_layer", ""));
996
997         int numLayersToTest[] =
998         {
999                 1,
1000                 2,
1001                 3,
1002                 4,
1003                 5,
1004                 6,
1005                 7,
1006                 8,
1007                 MIN_MAX_FRAMEBUFFER_LAYERS,
1008         };
1009
1010         TestParams parmas
1011         {
1012                 1,
1013                 groupParams
1014         };
1015
1016         for (int i = 0; i < DE_LENGTH_OF_ARRAY(numLayersToTest); ++i)
1017         {
1018                 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
1019                 if (groupParams->useSecondaryCmdBuffer && (i % 2))
1020                         continue;
1021
1022                 parmas.numLayers = numLayersToTest[i];
1023                 addFunctionCaseWithPrograms<TestParams>(group.get(), "vertex_shader_" + de::toString(parmas.numLayers), "", checkRequirements, initVertexTestPrograms, testVertexShader, parmas);
1024         }
1025
1026         for (int i = 0; i < DE_LENGTH_OF_ARRAY(numLayersToTest); ++i)
1027         {
1028                 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
1029                 if (groupParams->useSecondaryCmdBuffer && (i % 2))
1030                         continue;
1031
1032                 parmas.numLayers = numLayersToTest[i];
1033                 addFunctionCaseWithPrograms<TestParams>(group.get(), "tessellation_shader_" + de::toString(parmas.numLayers), "", checkRequirements, initTessellationTestPrograms, testTessellationShader, parmas);
1034         }
1035
1036         return group.release();
1037 }
1038
1039 } // Draw
1040 } // vkt