dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineInputAssemblyTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * The Materials are Confidential Information as defined by the
20  * Khronos Membership Agreement until designated non-confidential by Khronos,
21  * at which point this condition clause shall be removed.
22  *
23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30  *
31  *//*!
32  * \file
33  * \brief Input Assembly Tests
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktPipelineInputAssemblyTests.hpp"
37 #include "vktPipelineClearUtil.hpp"
38 #include "vktPipelineImageUtil.hpp"
39 #include "vktPipelineVertexUtil.hpp"
40 #include "vktPipelineReferenceRenderer.hpp"
41 #include "vktTestCase.hpp"
42 #include "vkImageUtil.hpp"
43 #include "vkMemUtil.hpp"
44 #include "vkPrograms.hpp"
45 #include "vkQueryUtil.hpp"
46 #include "vkRef.hpp"
47 #include "vkRefUtil.hpp"
48 #include "tcuImageCompare.hpp"
49 #include "deMath.h"
50 #include "deMemory.h"
51 #include "deRandom.hpp"
52 #include "deStringUtil.hpp"
53 #include "deUniquePtr.hpp"
54
55 #include <algorithm>
56 #include <sstream>
57 #include <vector>
58
59 namespace vkt
60 {
61 namespace pipeline
62 {
63
64 using namespace vk;
65
66 namespace
67 {
68
69 class InputAssemblyTest : public vkt::TestCase
70 {
71 public:
72         const static VkPrimitiveTopology        s_primitiveTopologies[];
73         const static deUint32                           s_restartIndex32;
74         const static deUint16                           s_restartIndex16;
75
76                                                                                 InputAssemblyTest               (tcu::TestContext&              testContext,
77                                                                                                                                  const std::string&             name,
78                                                                                                                                  const std::string&             description,
79                                                                                                                                  VkPrimitiveTopology    primitiveTopology,
80                                                                                                                                  int                                    primitiveCount,
81                                                                                                                                  bool                                   testPrimitiveRestart,
82                                                                                                                                  VkIndexType                    indexType);
83         virtual                                                         ~InputAssemblyTest              (void) {}
84         virtual void                                            initPrograms                    (SourceCollections& sourceCollections) const;
85         virtual TestInstance*                           createInstance                  (Context& context) const;
86         static bool                                                     isRestartIndex                  (VkIndexType indexType, deUint32 indexValue);
87         static deUint32                                         getRestartIndex                 (VkIndexType indexType);
88
89 protected:
90         virtual void                                            createBufferData                (VkPrimitiveTopology            topology,
91                                                                                                                                  int                                            primitiveCount,
92                                                                                                                                  VkIndexType                            indexType,
93                                                                                                                                  std::vector<deUint32>&         indexData,
94                                                                                                                                  std::vector<Vertex4RGBA>&      vertexData) const = 0;
95
96 private:
97         VkPrimitiveTopology                                     m_primitiveTopology;
98         const int                                                       m_primitiveCount;
99         bool                                                            m_testPrimitiveRestart;
100         VkIndexType                                                     m_indexType;
101 };
102
103 class PrimitiveTopologyTest : public InputAssemblyTest
104 {
105 public:
106                                                                                 PrimitiveTopologyTest   (tcu::TestContext&              testContext,
107                                                                                                                                  const std::string&             name,
108                                                                                                                                  const std::string&             description,
109                                                                                                                                  VkPrimitiveTopology    primitiveTopology);
110         virtual                                                         ~PrimitiveTopologyTest  (void) {}
111
112 protected:
113         virtual void                                            createBufferData                (VkPrimitiveTopology            topology,
114                                                                                                                                  int                                            primitiveCount,
115                                                                                                                                  VkIndexType                            indexType,
116                                                                                                                                  std::vector<deUint32>&         indexData,
117                                                                                                                                  std::vector<Vertex4RGBA>&      vertexData) const;
118
119 private:
120 };
121
122 class PrimitiveRestartTest : public InputAssemblyTest
123 {
124 public:
125                                                                                 PrimitiveRestartTest    (tcu::TestContext&              testContext,
126                                                                                                                                  const std::string&             name,
127                                                                                                                                  const std::string&             description,
128                                                                                                                                  VkPrimitiveTopology    primitiveTopology,
129                                                                                                                                  VkIndexType                    indexType);
130         virtual                                                         ~PrimitiveRestartTest   (void) {}
131
132 protected:
133         virtual void                                            createBufferData                (VkPrimitiveTopology            topology,
134                                                                                                                                  int                                            primitiveCount,
135                                                                                                                                  VkIndexType                            indexType,
136                                                                                                                                  std::vector<deUint32>&         indexData,
137                                                                                                                                  std::vector<Vertex4RGBA>&      vertexData) const;
138
139 private:
140         bool                                                            isRestartPrimitive              (int primitiveIndex) const;
141
142         std::vector<deUint32>                           m_restartPrimitives;
143 };
144
145 class InputAssemblyInstance : public vkt::TestInstance
146 {
147 public:
148                                                                                 InputAssemblyInstance   (Context&                                                       context,
149                                                                                                                                  VkPrimitiveTopology                            primitiveTopology,
150                                                                                                                                  bool                                                           testPrimitiveRestart,
151                                                                                                                                  VkIndexType                                            indexType,
152                                                                                                                                  const std::vector<deUint32>&           indexBufferData,
153                                                                                                                                  const std::vector<Vertex4RGBA>&        vertexBufferData);
154         virtual                                                         ~InputAssemblyInstance  (void);
155         virtual tcu::TestStatus                         iterate                                 (void);
156
157 private:
158         tcu::TestStatus                                         verifyImage                             (void);
159         void                                                            uploadIndexBufferData16 (deUint16* destPtr, const std::vector<deUint32>& indexBufferData);
160
161         VkPrimitiveTopology                                     m_primitiveTopology;
162         bool                                                            m_primitiveRestartEnable;
163         VkIndexType                                                     m_indexType;
164
165         Move<VkBuffer>                                          m_vertexBuffer;
166         std::vector<Vertex4RGBA>                        m_vertices;
167         de::MovePtr<Allocation>                         m_vertexBufferAlloc;
168
169         Move<VkBuffer>                                          m_indexBuffer;
170         std::vector<deUint32>                           m_indices;
171         de::MovePtr<Allocation>                         m_indexBufferAlloc;
172
173         const tcu::IVec2                                        m_renderSize;
174
175         const VkFormat                                          m_colorFormat;
176         VkImageCreateInfo                                       m_colorImageCreateInfo;
177         Move<VkImage>                                           m_colorImage;
178         de::MovePtr<Allocation>                         m_colorImageAlloc;
179         Move<VkImageView>                                       m_colorAttachmentView;
180         Move<VkRenderPass>                                      m_renderPass;
181         Move<VkFramebuffer>                                     m_framebuffer;
182
183         Move<VkShaderModule>                            m_vertexShaderModule;
184         Move<VkShaderModule>                            m_fragmentShaderModule;
185
186         Move<VkPipelineLayout>                          m_pipelineLayout;
187         Move<VkPipeline>                                        m_graphicsPipeline;
188
189         Move<VkCommandPool>                                     m_cmdPool;
190         Move<VkCommandBuffer>                           m_cmdBuffer;
191
192         Move<VkFence>                                           m_fence;
193 };
194
195
196 // InputAssemblyTest
197
198 const VkPrimitiveTopology InputAssemblyTest::s_primitiveTopologies[] =
199 {
200         VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
201         VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
202         VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
203         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
204         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
205         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
206         VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
207         VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
208         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
209         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY
210 };
211
212 const deUint32 InputAssemblyTest::s_restartIndex32      = ~((deUint32)0u);
213 const deUint16 InputAssemblyTest::s_restartIndex16      = ~((deUint16)0u);
214
215 InputAssemblyTest::InputAssemblyTest (tcu::TestContext&         testContext,
216                                                                           const std::string&    name,
217                                                                           const std::string&    description,
218                                                                           VkPrimitiveTopology   primitiveTopology,
219                                                                           int                                   primitiveCount,
220                                                                           bool                                  testPrimitiveRestart,
221                                                                           VkIndexType                   indexType)
222
223         : vkt::TestCase                         (testContext, name, description)
224         , m_primitiveTopology           (primitiveTopology)
225         , m_primitiveCount                      (primitiveCount)
226         , m_testPrimitiveRestart        (testPrimitiveRestart)
227         , m_indexType                           (indexType)
228 {
229 }
230
231 TestInstance* InputAssemblyTest::createInstance (Context& context) const
232 {
233         std::vector<deUint32>           indexBufferData;
234         std::vector<Vertex4RGBA>        vertexBufferData;
235
236         createBufferData(m_primitiveTopology, m_primitiveCount, m_indexType, indexBufferData, vertexBufferData);
237
238         return new InputAssemblyInstance(context, m_primitiveTopology, m_testPrimitiveRestart, m_indexType, indexBufferData, vertexBufferData);
239 }
240
241 void InputAssemblyTest::initPrograms (SourceCollections& sourceCollections) const
242 {
243         std::ostringstream vertexSource;
244
245         vertexSource <<
246                 "#version 310 es\n"
247                 "layout(location = 0) in vec4 position;\n"
248                 "layout(location = 1) in vec4 color;\n"
249                 "layout(location = 0) out highp vec4 vtxColor;\n"
250                 "void main (void)\n"
251                 "{\n"
252                 "       gl_Position = position;\n"
253                 << (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST ? " gl_PointSize = 3.0;\n"
254                                                                                                                                         : "" )
255                 << "    vtxColor = color;\n"
256                 "}\n";
257
258         sourceCollections.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
259
260         sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
261                 "#version 310 es\n"
262                 "layout(location = 0) in highp vec4 vtxColor;\n"
263                 "layout(location = 0) out highp vec4 fragColor;\n"
264                 "void main (void)\n"
265                 "{\n"
266                 "       fragColor = vtxColor;\n"
267                 "}\n");
268 }
269
270 bool InputAssemblyTest::isRestartIndex (VkIndexType indexType, deUint32 indexValue)
271 {
272         if (indexType == VK_INDEX_TYPE_UINT32)
273                 return indexValue == s_restartIndex32;
274         else
275                 return indexValue == s_restartIndex16;
276 }
277
278 deUint32 InputAssemblyTest::getRestartIndex (VkIndexType indexType)
279 {
280         if (indexType == VK_INDEX_TYPE_UINT16)
281                 return InputAssemblyTest::s_restartIndex16;
282         else
283                 return InputAssemblyTest::s_restartIndex32;
284 }
285
286
287 // PrimitiveTopologyTest
288
289 PrimitiveTopologyTest::PrimitiveTopologyTest (tcu::TestContext&         testContext,
290                                                                                           const std::string&    name,
291                                                                                           const std::string&    description,
292                                                                                           VkPrimitiveTopology   primitiveTopology)
293         : InputAssemblyTest     (testContext, name, description, primitiveTopology, 10, false, VK_INDEX_TYPE_UINT32)
294 {
295 }
296
297 void PrimitiveTopologyTest::createBufferData (VkPrimitiveTopology topology, int primitiveCount, VkIndexType indexType, std::vector<deUint32>& indexData, std::vector<Vertex4RGBA>& vertexData) const
298 {
299         DE_ASSERT(primitiveCount > 0);
300         DE_UNREF(indexType);
301
302         const tcu::Vec4                         red                                             (1.0f, 0.0f, 0.0f, 1.0f);
303         const tcu::Vec4                         green                                   (0.0f, 1.0f, 0.0f, 1.0f);
304         const float                                     border                                  = 0.2f;
305         const float                                     originX                                 = -1.0f + border;
306         const float                                     originY                                 = -1.0f + border;
307         const Vertex4RGBA                       defaultVertex                   = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), green };
308         float                                           primitiveSizeY                  = (2.0f - 2.0f * border);
309         float                                           primitiveSizeX;
310         std::vector<deUint32>           indices;
311         std::vector<Vertex4RGBA>        vertices;
312
313
314         // Calculate primitive size
315         switch (topology)
316         {
317                 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
318                         primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2 + primitiveCount % 2 - 1);
319                         break;
320
321                 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
322                 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
323                         primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount - 1);
324                         break;
325
326                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
327                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
328                         primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2);
329                         break;
330
331                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
332                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
333                         primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount + primitiveCount / 2 + primitiveCount % 2 - 1);
334                         break;
335
336                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
337                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
338                         primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2 + primitiveCount % 2);
339                         break;
340
341                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
342                         primitiveSizeX = 1.0f - border;
343                         primitiveSizeY = 1.0f - border;
344                         break;
345
346                 default:
347                         primitiveSizeX = 0.0f; // Garbage
348                         DE_ASSERT(false);
349         }
350
351         switch (topology)
352         {
353                 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
354                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
355                         {
356                                 const Vertex4RGBA vertex =
357                                 {
358                                         tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
359                                         red
360                                 };
361
362                                 vertices.push_back(vertex);
363                                 indices.push_back(primitiveNdx);
364                         }
365                         break;
366
367                 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
368                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
369                         {
370                                 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
371                                 {
372                                         const Vertex4RGBA vertex =
373                                         {
374                                                 tcu::Vec4(originX + float((primitiveNdx * 2 + vertexNdx) / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
375                                                 red
376                                         };
377
378                                         vertices.push_back(vertex);
379                                         indices.push_back((primitiveNdx * 2 + vertexNdx));
380                                 }
381                         }
382                         break;
383
384                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
385                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
386                         {
387                                 if (primitiveNdx == 0)
388                                 {
389                                         Vertex4RGBA vertex =
390                                         {
391                                                 tcu::Vec4(originX, originY, 0.0f, 1.0f),
392                                                 red
393                                         };
394
395                                         vertices.push_back(vertex);
396                                         indices.push_back(0);
397
398                                         vertex.position = tcu::Vec4(originX, originY + primitiveSizeY, 0.0f, 1.0f);
399                                         vertices.push_back(vertex);
400                                         indices.push_back(1);
401                                 }
402                                 else
403                                 {
404                                         const Vertex4RGBA vertex =
405                                         {
406                                                 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
407                                                 red
408                                         };
409
410                                         vertices.push_back(vertex);
411                                         indices.push_back(primitiveNdx + 1);
412                                 }
413                         }
414                         break;
415
416                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
417                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
418                         {
419                                 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
420                                 {
421                                         const Vertex4RGBA vertex =
422                                         {
423                                                 tcu::Vec4(originX + float((primitiveNdx * 3 + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx * 3 + vertexNdx)% 2) * primitiveSizeY, 0.0f, 1.0f),
424                                                 red
425                                         };
426
427                                         vertices.push_back(vertex);
428                                         indices.push_back(primitiveNdx * 3 + vertexNdx);
429                                 }
430                         }
431                         break;
432
433                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
434                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
435                         {
436                                 if (primitiveNdx == 0)
437                                 {
438                                         for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
439                                         {
440                                                 const Vertex4RGBA vertex =
441                                                 {
442                                                         tcu::Vec4(originX + float(vertexNdx / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
443                                                         red
444                                                 };
445
446                                                 vertices.push_back(vertex);
447                                                 indices.push_back(vertexNdx);
448                                         }
449                                 }
450                                 else
451                                 {
452                                         const Vertex4RGBA vertex =
453                                         {
454                                                 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
455                                                 red
456                                         };
457
458                                         vertices.push_back(vertex);
459                                         indices.push_back(primitiveNdx + 2);
460                                 }
461                         }
462                         break;
463
464                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
465                 {
466                         const float stepAngle = de::min(DE_PI * 0.5f, (2 * DE_PI) / float(primitiveCount));
467
468                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
469                         {
470                                 if (primitiveNdx == 0)
471                                 {
472                                         Vertex4RGBA vertex =
473                                         {
474                                                 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
475                                                 red
476                                         };
477
478                                         vertices.push_back(vertex);
479                                         indices.push_back(0);
480
481                                         vertex.position = tcu::Vec4(primitiveSizeX, 0.0f, 0.0f, 1.0f);
482                                         vertices.push_back(vertex);
483                                         indices.push_back(1);
484
485                                         vertex.position = tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle), primitiveSizeY * deFloatSin(stepAngle), 0.0f, 1.0f);
486                                         vertices.push_back(vertex);
487                                         indices.push_back(2);
488                                 }
489                                 else
490                                 {
491                                         const Vertex4RGBA vertex =
492                                         {
493                                                 tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx + 1)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx + 1)), 0.0f, 1.0f),
494                                                 red
495                                         };
496
497                                         vertices.push_back(vertex);
498                                         indices.push_back(primitiveNdx + 2);
499                                 }
500                         }
501                         break;
502                 }
503
504                 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
505                         vertices.push_back(defaultVertex);
506
507                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
508                         {
509                                 indices.push_back(0);
510
511                                 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
512                                 {
513                                         const Vertex4RGBA vertex =
514                                         {
515                                                 tcu::Vec4(originX + float((primitiveNdx * 2 + vertexNdx) / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
516                                                 red
517                                         };
518
519                                         vertices.push_back(vertex);
520                                         indices.push_back(primitiveNdx * 2 + vertexNdx + 1);
521                                 }
522
523                                 indices.push_back(0);
524                         }
525                         break;
526
527
528                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
529                         vertices.push_back(defaultVertex);
530                         indices.push_back(0);
531
532                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
533                         {
534                                 if (primitiveNdx == 0)
535                                 {
536                                         Vertex4RGBA vertex =
537                                         {
538                                                 tcu::Vec4(originX, originY, 0.0f, 1.0f),
539                                                 red
540                                         };
541
542                                         vertices.push_back(vertex);
543                                         indices.push_back(1);
544
545                                         vertex.position = tcu::Vec4(originX, originY + primitiveSizeY, 0.0f, 1.0f);
546                                         vertices.push_back(vertex);
547                                         indices.push_back(2);
548                                 }
549                                 else
550                                 {
551                                         const Vertex4RGBA vertex =
552                                         {
553                                                 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
554                                                 red
555                                         };
556
557                                         vertices.push_back(vertex);
558                                         indices.push_back(primitiveNdx + 2);
559                                 }
560                         }
561
562                         indices.push_back(0);
563                         break;
564
565                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
566                         vertices.push_back(defaultVertex);
567
568                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
569                         {
570                                 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
571                                 {
572                                         const Vertex4RGBA vertex =
573                                         {
574                                                 tcu::Vec4(originX + float((primitiveNdx * 3 + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx * 3 + vertexNdx)% 2) * primitiveSizeY, 0.0f, 1.0f),
575                                                 red
576                                         };
577
578                                         vertices.push_back(vertex);
579                                         indices.push_back(primitiveNdx * 3 + vertexNdx + 1);
580                                         indices.push_back(0);
581                                 }
582                         }
583                         break;
584
585                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
586                         vertices.push_back(defaultVertex);
587
588                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
589                         {
590                                 if (primitiveNdx == 0)
591                                 {
592                                         for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
593                                         {
594                                                 const Vertex4RGBA vertex =
595                                                 {
596                                                         tcu::Vec4(originX + float(vertexNdx / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
597                                                         red
598                                                 };
599
600                                                 vertices.push_back(vertex);
601                                                 indices.push_back(vertexNdx + 1);
602                                                 indices.push_back(0);
603                                         }
604                                 }
605                                 else
606                                 {
607                                         const Vertex4RGBA vertex =
608                                         {
609                                                 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
610                                                 red
611                                         };
612
613                                         vertices.push_back(vertex);
614                                         indices.push_back(primitiveNdx + 2 + 1);
615                                         indices.push_back(0);
616                                 }
617                         }
618                         break;
619
620                 default:
621                         DE_ASSERT(false);
622                         break;
623         }
624
625         vertexData      = vertices;
626         indexData       = indices;
627 }
628
629
630 // PrimitiveRestartTest
631
632 PrimitiveRestartTest::PrimitiveRestartTest (tcu::TestContext&           testContext,
633                                                                                         const std::string&              name,
634                                                                                         const std::string&              description,
635                                                                                         VkPrimitiveTopology             primitiveTopology,
636                                                                                         VkIndexType                             indexType)
637
638         : InputAssemblyTest     (testContext, name, description, primitiveTopology, 10, true, indexType)
639 {
640         DE_ASSERT(primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP ||
641                           primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ||
642                           primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN ||
643                           primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ||
644                           primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY);
645
646         deUint32 restartPrimitives[] = { 1, 5 };
647
648         m_restartPrimitives = std::vector<deUint32>(restartPrimitives, restartPrimitives + sizeof(restartPrimitives) / sizeof(deUint32));
649 }
650
651 void PrimitiveRestartTest::createBufferData (VkPrimitiveTopology topology, int primitiveCount, VkIndexType indexType, std::vector<deUint32>& indexData, std::vector<Vertex4RGBA>& vertexData) const
652 {
653         DE_ASSERT(primitiveCount > 0);
654         DE_UNREF(indexType);
655
656         const tcu::Vec4                         red                                             (1.0f, 0.0f, 0.0f, 1.0f);
657         const tcu::Vec4                         green                                   (0.0f, 1.0f, 0.0f, 1.0f);
658         const float                                     border                                  = 0.2f;
659         const float                                     originX                                 = -1.0f + border;
660         const float                                     originY                                 = -1.0f + border;
661         const Vertex4RGBA                       defaultVertex                   = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), green };
662         float                                           primitiveSizeY                  = (2.0f - 2.0f * border);
663         float                                           primitiveSizeX;
664         bool                                            primitiveStart                  = true;
665         std::vector<deUint32>           indices;
666         std::vector<Vertex4RGBA>        vertices;
667
668
669         // Calculate primitive size
670         switch (topology)
671         {
672                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
673                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
674                         primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2);
675                         break;
676
677                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
678                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
679                         primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2 + primitiveCount % 2);
680                         break;
681
682                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
683                         primitiveSizeX = 1.0f - border;
684                         primitiveSizeY = 1.0f - border;
685                         break;
686
687                 default:
688                         primitiveSizeX = 0.0f; // Garbage
689                         DE_ASSERT(false);
690         }
691
692         switch (topology)
693         {
694                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
695                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
696                         {
697                                 if (isRestartPrimitive(primitiveNdx))
698                                 {
699                                         indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
700                                         primitiveStart = true;
701                                 }
702                                 else
703                                 {
704                                         if (primitiveStart)
705                                         {
706                                                 const Vertex4RGBA vertex =
707                                                 {
708                                                         tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
709                                                         red
710                                                 };
711
712                                                 vertices.push_back(vertex);
713                                                 indices.push_back((deUint32)vertices.size() - 1);
714
715                                                 primitiveStart = false;
716                                         }
717
718                                         const Vertex4RGBA vertex =
719                                         {
720                                                 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
721                                                 red
722                                         };
723
724                                         vertices.push_back(vertex);
725                                         indices.push_back((deUint32)vertices.size() - 1);
726                                 }
727                         }
728                         break;
729
730                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
731                 {
732                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
733                         {
734                                 if (isRestartPrimitive(primitiveNdx))
735                                 {
736                                         indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
737                                         primitiveStart = true;
738                                 }
739                                 else
740                                 {
741                                         if (primitiveStart)
742                                         {
743                                                 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
744                                                 {
745                                                         const Vertex4RGBA vertex =
746                                                         {
747                                                                 tcu::Vec4(originX + float((primitiveNdx + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx + vertexNdx) % 2) * primitiveSizeY, 0.0f, 1.0f),
748                                                                 red
749                                                         };
750
751                                                         vertices.push_back(vertex);
752                                                         indices.push_back((deUint32)vertices.size() - 1);
753                                                 }
754
755                                                 primitiveStart = false;
756                                         }
757                                         const Vertex4RGBA vertex =
758                                         {
759                                                 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
760                                                 red
761                                         };
762
763                                         vertices.push_back(vertex);
764                                         indices.push_back((deUint32)vertices.size() - 1);
765                                 }
766                         }
767                         break;
768                 }
769
770                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
771                 {
772                         const float stepAngle = de::min(DE_PI * 0.5f, (2 * DE_PI) / float(primitiveCount));
773
774                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
775                         {
776                                 if (isRestartPrimitive(primitiveNdx))
777                                 {
778                                         indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
779                                         primitiveStart = true;
780                                 }
781                                 else
782                                 {
783                                         if (primitiveStart)
784                                         {
785                                                 Vertex4RGBA vertex =
786                                                 {
787                                                         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
788                                                         red
789                                                 };
790
791                                                 vertices.push_back(vertex);
792                                                 indices.push_back((deUint32)vertices.size() - 1);
793
794                                                 vertex.position = tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx)), 0.0f, 1.0f),
795                                                 vertices.push_back(vertex);
796                                                 indices.push_back((deUint32)vertices.size() - 1);
797
798                                                 primitiveStart = false;
799                                         }
800
801                                         const Vertex4RGBA vertex =
802                                         {
803                                                 tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx + 1)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx + 1)), 0.0f, 1.0f),
804                                                 red
805                                         };
806
807                                         vertices.push_back(vertex);
808                                         indices.push_back((deUint32)vertices.size() - 1);
809                                 }
810                         }
811                         break;
812                 }
813
814                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
815                         vertices.push_back(defaultVertex);
816
817                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
818                         {
819                                 if (isRestartPrimitive(primitiveNdx))
820                                 {
821                                         indices.push_back(0);
822                                         indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
823                                         primitiveStart = true;
824                                 }
825                                 else
826                                 {
827                                         if (primitiveStart)
828                                         {
829                                                 indices.push_back(0);
830
831                                                 const Vertex4RGBA vertex =
832                                                 {
833                                                         tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
834                                                         red
835                                                 };
836
837                                                 vertices.push_back(vertex);
838                                                 indices.push_back((deUint32)vertices.size() - 1);
839
840                                                 primitiveStart = false;
841                                         }
842
843                                         const Vertex4RGBA vertex =
844                                         {
845                                                 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
846                                                 red
847                                         };
848
849                                         vertices.push_back(vertex);
850                                         indices.push_back((deUint32)vertices.size() - 1);
851                                 }
852                         }
853
854                         indices.push_back(0);
855                         break;
856
857                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
858                         vertices.push_back(defaultVertex);
859
860                         for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
861                         {
862                                 if (isRestartPrimitive(primitiveNdx))
863                                 {
864                                         indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
865                                         primitiveStart = true;
866                                 }
867                                 else
868                                 {
869                                         if (primitiveStart)
870                                         {
871                                                 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
872                                                 {
873                                                         const Vertex4RGBA vertex =
874                                                         {
875                                                                 tcu::Vec4(originX + float((primitiveNdx + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx + vertexNdx) % 2) * primitiveSizeY, 0.0f, 1.0f),
876                                                                 red
877                                                         };
878
879                                                         vertices.push_back(vertex);
880                                                         indices.push_back((deUint32)vertices.size() - 1);
881                                                         indices.push_back(0);
882                                                 }
883
884                                                 primitiveStart = false;
885                                         }
886
887                                         const Vertex4RGBA vertex =
888                                         {
889                                                 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
890                                                 red
891                                         };
892
893                                         vertices.push_back(vertex);
894                                         indices.push_back((deUint32)vertices.size() - 1);
895                                         indices.push_back(0);
896                                 }
897                         }
898                         break;
899
900                 default:
901                         DE_ASSERT(false);
902                         break;
903         }
904
905         vertexData      = vertices;
906         indexData       = indices;
907 }
908
909 bool PrimitiveRestartTest::isRestartPrimitive (int primitiveIndex) const
910 {
911         return std::find(m_restartPrimitives.begin(), m_restartPrimitives.end(), primitiveIndex) != m_restartPrimitives.end();
912 }
913
914
915 // InputAssemblyInstance
916
917 InputAssemblyInstance::InputAssemblyInstance (Context&                                                  context,
918                                                                                           VkPrimitiveTopology                           primitiveTopology,
919                                                                                           bool                                                          testPrimitiveRestart,
920                                                                                           VkIndexType                                           indexType,
921                                                                                           const std::vector<deUint32>&          indexBufferData,
922                                                                                           const std::vector<Vertex4RGBA>&       vertexBufferData)
923
924         : vkt::TestInstance                     (context)
925         , m_primitiveTopology           (primitiveTopology)
926         , m_primitiveRestartEnable      (testPrimitiveRestart)
927         , m_indexType                           (indexType)
928         , m_vertices                            (vertexBufferData)
929         , m_indices                                     (indexBufferData)
930         , m_renderSize                          ((primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) ? tcu::IVec2(32, 32) : tcu::IVec2(64, 16))
931         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
932 {
933         const DeviceInterface&                  vk                                              = context.getDeviceInterface();
934         const VkDevice                                  vkDevice                                = context.getDevice();
935         const deUint32                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
936         SimpleAllocator                                 memAlloc                                (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
937         const VkComponentMapping                componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
938
939         // Create color image
940         {
941                 const VkImageCreateInfo colorImageParams =
942                 {
943                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
944                         DE_NULL,                                                                                                                                        // const void*                          pNext;
945                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
946                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
947                         m_colorFormat,                                                                                                                          // VkFormat                                     format;
948                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                           extent;
949                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
950                         1u,                                                                                                                                                     // deUint32                                     arrayLayers;
951                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
952                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
953                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags            usage;
954                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
955                         1u,                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
956                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
957                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                       // VkImageLayout                        initialLayout;
958                 };
959
960                 m_colorImageCreateInfo  = colorImageParams;
961                 m_colorImage                    = createImage(vk, vkDevice, &m_colorImageCreateInfo);
962
963                 // Allocate and bind color image memory
964                 m_colorImageAlloc               = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
965                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
966         }
967
968         // Create color attachment view
969         {
970                 const VkImageViewCreateInfo colorAttachmentViewParams =
971                 {
972                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
973                         DE_NULL,                                                                                        // const void*                          pNext;
974                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
975                         *m_colorImage,                                                                          // VkImage                                      image;
976                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
977                         m_colorFormat,                                                                          // VkFormat                                     format;
978                         componentMappingRGBA,                                                           // VkComponentMapping           components;
979                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },          // VkImageSubresourceRange      subresourceRange;
980                 };
981
982                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
983         }
984
985         // Create render pass
986         {
987                 const VkAttachmentDescription colorAttachmentDescription =
988                 {
989                         0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
990                         m_colorFormat,                                                                          // VkFormat                                                     format;
991                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
992                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
993                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
994                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
995                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
996                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
997                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
998                 };
999
1000                 const VkAttachmentReference colorAttachmentReference =
1001                 {
1002                         0u,                                                                                                     // deUint32                     attachment;
1003                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
1004                 };
1005
1006                 const VkSubpassDescription subpassDescription =
1007                 {
1008                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
1009                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
1010                         0u,                                                                                                     // deUint32                                             inputAttachmentCount;
1011                         DE_NULL,                                                                                        // const VkAttachmentReference* pInputAttachments;
1012                         1u,                                                                                                     // deUint32                                             colorAttachmentCount;
1013                         &colorAttachmentReference,                                                      // const VkAttachmentReference* pColorAttachments;
1014                         DE_NULL,                                                                                        // const VkAttachmentReference* pResolveAttachments;
1015                         DE_NULL,                                                                                        // const VkAttachmentReference* pDepthStencilAttachment;
1016                         0u,                                                                                                     // deUint32                                             preserveAttachmentCount;
1017                         DE_NULL                                                                                         // const VkAttachmentReference* pPreserveAttachments;
1018                 };
1019
1020                 const VkRenderPassCreateInfo renderPassParams =
1021                 {
1022                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
1023                         DE_NULL,                                                                                        // const void*                                          pNext;
1024                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
1025                         1u,                                                                                                     // deUint32                                                     attachmentCount;
1026                         &colorAttachmentDescription,                                            // const VkAttachmentDescription*       pAttachments;
1027                         1u,                                                                                                     // deUint32                                                     subpassCount;
1028                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
1029                         0u,                                                                                                     // deUint32                                                     dependencyCount;
1030                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
1031                 };
1032
1033                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1034         }
1035
1036         // Create framebuffer
1037         {
1038                 const VkFramebufferCreateInfo framebufferParams =
1039                 {
1040                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                      sType;
1041                         DE_NULL,                                                                                        // const void*                          pNext;
1042                         0u,                                                                                                     // VkFramebufferCreateFlags     flags;
1043                         *m_renderPass,                                                                          // VkRenderPass                         renderPass;
1044                         1u,                                                                                                     // deUint32                                     attachmentCount;
1045                         &m_colorAttachmentView.get(),                                           // const VkImageView*           pAttachments;
1046                         (deUint32)m_renderSize.x(),                                                     // deUint32                                     width;
1047                         (deUint32)m_renderSize.y(),                                                     // deUint32                                     height;
1048                         1u                                                                                                      // deUint32                                     layers;
1049                 };
1050
1051                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1052         }
1053
1054         // Create pipeline layout
1055         {
1056                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1057                 {
1058                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
1059                         DE_NULL,                                                                                        // const void*                                          pNext;
1060                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
1061                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
1062                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
1063                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
1064                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
1065                 };
1066
1067                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1068         }
1069
1070         m_vertexShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
1071         m_fragmentShaderModule  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
1072
1073         // Create pipeline
1074         {
1075                 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1076                 {
1077                         {
1078                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
1079                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
1080                                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
1081                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
1082                                 *m_vertexShaderModule,                                                                          // VkShaderModule                                               module;
1083                                 "main",                                                                                                         // const char*                                                  pName;
1084                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
1085                         },
1086                         {
1087                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
1088                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
1089                                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
1090                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
1091                                 *m_fragmentShaderModule,                                                                        // VkShaderModule                                               module;
1092                                 "main",                                                                                                         // const char*                                                  pName;
1093                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
1094                         }
1095                 };
1096
1097                 const VkVertexInputBindingDescription vertexInputBindingDescription =
1098                 {
1099                         0u,                                                             // deUint32                                     binding;
1100                         sizeof(Vertex4RGBA),                    // deUint32                                     stride;
1101                         VK_VERTEX_INPUT_RATE_VERTEX             // VkVertexInputRate            inputRate;
1102                 };
1103
1104                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1105                 {
1106                         {
1107                                 0u,                                                                     // deUint32     location;
1108                                 0u,                                                                     // deUint32     binding;
1109                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
1110                                 0u                                                                      // deUint32     offset;
1111                         },
1112                         {
1113                                 1u,                                                                     // deUint32     location;
1114                                 0u,                                                                     // deUint32     binding;
1115                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
1116                                 DE_OFFSET_OF(Vertex4RGBA, color),       // deUint32     offset;
1117                         }
1118                 };
1119
1120                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1121                 {
1122                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                              sType;
1123                         DE_NULL,                                                                                                                // const void*                                                                  pNext;
1124                         0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags                flags;
1125                         1u,                                                                                                                             // deUint32                                                                             vertexBindingDescriptionCount;
1126                         &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*               pVertexBindingDescriptions;
1127                         2u,                                                                                                                             // deUint32                                                                             vertexAttributeDescriptionCount;
1128                         vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*             pVertexAttributeDescriptions;
1129                 };
1130
1131                 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1132                 {
1133                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
1134                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1135                         0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
1136                         m_primitiveTopology,                                                                                    // VkPrimitiveTopology                                          topology;
1137                         m_primitiveRestartEnable                                                                                // VkBool32                                                                     primitiveRestartEnable;
1138                 };
1139
1140                 const VkViewport viewport =
1141                 {
1142                         0.0f,                                           // float        x;
1143                         0.0f,                                           // float        y;
1144                         (float)m_renderSize.x(),        // float        width;
1145                         (float)m_renderSize.y(),        // float        height;
1146                         0.0f,                                           // float        minDepth;
1147                         1.0f                                            // float        maxDepth;
1148                 };
1149
1150                 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } };
1151
1152                 const VkPipelineViewportStateCreateInfo viewportStateParams =
1153                 {
1154                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
1155                         DE_NULL,                                                                                                                // const void*                                                  pNext;
1156                         0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
1157                         1u,                                                                                                                             // deUint32                                                             viewportCount;
1158                         &viewport,                                                                                                              // const VkViewport*                                    pViewports;
1159                         1u,                                                                                                                             // deUint32                                                             scissorCount;
1160                         &scissor,                                                                                                               // const VkRect2D*                                              pScissors;
1161                 };
1162
1163                 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1164                 {
1165                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
1166                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1167                         0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags      flags;
1168                         false,                                                                                                                  // VkBool32                                                                     depthClampEnable;
1169                         false,                                                                                                                  // VkBool32                                                                     rasterizerDiscardEnable;
1170                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
1171                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
1172                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
1173                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
1174                         0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
1175                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
1176                         0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
1177                         1.0f                                                                                                                    // float                                                                        lineWidth;
1178                 };
1179
1180                 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1181                 {
1182                         false,                                                                                                                  // VkBool32                                     blendEnable;
1183                         VK_BLEND_FACTOR_ONE,                                                                                    // VkBlendFactor                        srcColorBlendFactor;
1184                         VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlendFactor                        dstColorBlendFactor;
1185                         VK_BLEND_OP_ADD,                                                                                                // VkBlendOp                            colorBlendOp;
1186                         VK_BLEND_FACTOR_ONE,                                                                                    // VkBlendFactor                        srcAlphaBlendFactor;
1187                         VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlendFactor                        dstAlphaBlendFactor;
1188                         VK_BLEND_OP_ADD,                                                                                                // VkBlendOp                            alphaBlendOp;
1189                         VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |                   // VkColorComponentFlags        colorWriteMask;
1190                                 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
1191                 };
1192
1193                 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1194                 {
1195                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
1196                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
1197                         0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
1198                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
1199                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
1200                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
1201                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
1202                         { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
1203                 };
1204
1205                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1206                 {
1207                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
1208                         DE_NULL,                                                                                                        // const void*                                                          pNext;
1209                         0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
1210                         VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
1211                         false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
1212                         0.0f,                                                                                                           // float                                                                        minSampleShading;
1213                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
1214                         false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
1215                         false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
1216                 };
1217
1218                 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
1219                 {
1220                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
1221                         DE_NULL,                                                                                                        // const void*                                                          pNext;
1222                         0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
1223                         false,                                                                                                          // VkBool32                                                                     depthTestEnable;
1224                         false,                                                                                                          // VkBool32                                                                     depthWriteEnable;
1225                         VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
1226                         false,                                                                                                          // VkBool32                                                                     depthBoundsTestEnable;
1227                         false,                                                                                                          // VkBool32                                                                     stencilTestEnable;
1228                         // VkStencilOpState     front;
1229                         {
1230                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp;
1231                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  passOp;
1232                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp;
1233                                 VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
1234                                 0u,                                             // deUint32             compareMask;
1235                                 0u,                                             // deUint32             writeMask;
1236                                 0u,                                             // deUint32             reference;
1237                         },
1238                         // VkStencilOpState     back;
1239                         {
1240                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp;
1241                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  passOp;
1242                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp;
1243                                 VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
1244                                 0u,                                             // deUint32             compareMask;
1245                                 0u,                                             // deUint32             writeMask;
1246                                 0u,                                             // deUint32             reference;
1247                         },
1248                         -1.0f,                                                                                                          // float                        minDepthBounds;
1249                         +1.0f                                                                                                           // float                        maxDepthBounds;
1250                 };
1251
1252                 const VkPipelineDynamicStateCreateInfo dynamicStateParams =
1253                 {
1254                         VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,           // VkStructureType                                              sType;
1255                         DE_NULL,                                                                                                        // const void*                                                  pNext;
1256                         0u,                                                                                                                     // VkPipelineDynamicStateCreateFlags    flags;
1257                         0u,                                                                                                                     // deUint32                                                             dynamicStateCount;
1258                         DE_NULL                                                                                                         // const VkDynamicState*                                pDynamicStates;
1259                 };
1260
1261                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1262                 {
1263                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
1264                         DE_NULL,                                                                                        // const void*                                                                          pNext;
1265                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
1266                         2u,                                                                                                     // deUint32                                                                                     stageCount;
1267                         shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
1268                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
1269                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
1270                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
1271                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
1272                         &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
1273                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
1274                         &depthStencilStateParams,                                                       // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
1275                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
1276                         &dynamicStateParams,                                                            // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
1277                         *m_pipelineLayout,                                                                      // VkPipelineLayout                                                                     layout;
1278                         *m_renderPass,                                                                          // VkRenderPass                                                                         renderPass;
1279                         0u,                                                                                                     // deUint32                                                                                     subpass;
1280                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
1281                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
1282                 };
1283
1284                 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1285         }
1286
1287         // Create vertex and index buffer
1288         {
1289                 const VkBufferCreateInfo indexBufferParams =
1290                 {
1291                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1292                         DE_NULL,                                                                        // const void*                  pNext;
1293                         0u,                                                                                     // VkBufferCreateFlags  flags;
1294                         m_indices.size() * sizeof(deUint32),            // VkDeviceSize                 size;
1295                         VK_BUFFER_USAGE_INDEX_BUFFER_BIT,                       // VkBufferUsageFlags   usage;
1296                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1297                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1298                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1299                 };
1300
1301                 const VkBufferCreateInfo vertexBufferParams =
1302                 {
1303                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1304                         DE_NULL,                                                                        // const void*                  pNext;
1305                         0u,                                                                                     // VkBufferCreateFlags  flags;
1306                         m_vertices.size() * sizeof(Vertex4RGBA),        // VkDeviceSize                 size;
1307                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
1308                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1309                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1310                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1311                 };
1312
1313                 m_indexBuffer           = createBuffer(vk, vkDevice, &indexBufferParams);
1314                 m_indexBufferAlloc      = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indexBuffer), MemoryRequirement::HostVisible);
1315
1316                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indexBuffer, m_indexBufferAlloc->getMemory(), m_indexBufferAlloc->getOffset()));
1317
1318                 m_vertexBuffer          = createBuffer(vk, vkDevice, &vertexBufferParams);
1319                 m_vertexBufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
1320
1321                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
1322
1323                 // Load vertices into index buffer
1324                 if (m_indexType == VK_INDEX_TYPE_UINT32)
1325                 {
1326                         deMemcpy(m_indexBufferAlloc->getHostPtr(), m_indices.data(), m_indices.size() * sizeof(deUint32));
1327                 }
1328                 else // m_indexType == VK_INDEX_TYPE_UINT16
1329                 {
1330                         uploadIndexBufferData16((deUint16*)m_indexBufferAlloc->getHostPtr(), m_indices);
1331                 }
1332
1333                 // Load vertices into vertex buffer
1334                 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
1335
1336                 // Flush memory
1337                 const VkMappedMemoryRange flushMemoryRanges[] =
1338                 {
1339                         {
1340                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  // VkStructureType      sType;
1341                                 DE_NULL,                                                                // const void*          pNext;
1342                                 m_indexBufferAlloc->getMemory(),                // VkDeviceMemory       memory;
1343                                 m_indexBufferAlloc->getOffset(),                // VkDeviceSize         offset;
1344                                 indexBufferParams.size                                  // VkDeviceSize         size;
1345                         },
1346                         {
1347                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  // VkStructureType      sType;
1348                                 DE_NULL,                                                                // const void*          pNext;
1349                                 m_vertexBufferAlloc->getMemory(),               // VkDeviceMemory       memory;
1350                                 m_vertexBufferAlloc->getOffset(),               // VkDeviceSize         offset;
1351                                 vertexBufferParams.size                                 // VkDeviceSize         size;
1352                         },
1353                 };
1354
1355                 vk.flushMappedMemoryRanges(vkDevice, 2, flushMemoryRanges);
1356         }
1357
1358         // Create command pool
1359         {
1360                 const VkCommandPoolCreateInfo cmdPoolParams =
1361                 {
1362                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType                              sType;
1363                         DE_NULL,                                                                                // const void*                                  pNext;
1364                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags             flags;
1365                         queueFamilyIndex                                                                // deUint32                                             queueFamilyIndex;
1366                 };
1367
1368                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1369         }
1370
1371         // Create command buffer
1372         {
1373                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
1374                 {
1375                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
1376                         DE_NULL,                                                                                // const void*                          pNext;
1377                         *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
1378                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
1379                         1u                                                                                              // deUint32                                     bufferCount;
1380                 };
1381
1382                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1383                 {
1384                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
1385                         DE_NULL,                                                                                // const void*                                          pNext;
1386                         0u,                                                                                             // VkCommandBufferUsageFlags            flags;
1387                         DE_NULL,                                                                                // VkRenderPass                                         renderPass;
1388                         0u,                                                                                             // deUint32                                                     subpass;
1389                         DE_NULL,                                                                                // VkFramebuffer                                        framebuffer;
1390                         false,                                                                                  // VkBool32                                                     occlusionQueryEnable;
1391                         0u,                                                                                             // VkQueryControlFlags                          queryFlags;
1392                         0u                                                                                              // VkQueryPipelineStatisticFlags        pipelineStatistics;
1393                 };
1394
1395                 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
1396
1397                 const VkRenderPassBeginInfo renderPassBeginInfo =
1398                 {
1399                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
1400                         DE_NULL,                                                                                                // const void*                  pNext;
1401                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
1402                         *m_framebuffer,                                                                                 // VkFramebuffer                framebuffer;
1403                         { { 0, 0 } , { m_renderSize.x(), m_renderSize.y() } },  // VkRect2D                             renderArea;
1404                         1u,                                                                                                             // deUint32                             clearValueCount;
1405                         &attachmentClearValue                                                                   // const VkClearValue*  pClearValues;
1406                 };
1407
1408                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
1409
1410                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1411                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1412
1413                 const VkDeviceSize vertexBufferOffset = 0;
1414
1415                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1416                 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1417                 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indexBuffer, 0, m_indexType);
1418                 vk.cmdDrawIndexed(*m_cmdBuffer, (deUint32)m_indices.size(), 1, 0, 0, 0);
1419
1420                 vk.cmdEndRenderPass(*m_cmdBuffer);
1421                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1422         }
1423
1424         // Create fence
1425         {
1426                 const VkFenceCreateInfo fenceParams =
1427                 {
1428                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
1429                         DE_NULL,                                                                // const void*                  pNext;
1430                         0u                                                                              // VkFenceCreateFlags   flags;
1431                 };
1432
1433                 m_fence = createFence(vk, vkDevice, &fenceParams);
1434         }
1435 }
1436
1437 InputAssemblyInstance::~InputAssemblyInstance (void)
1438 {
1439 }
1440
1441 tcu::TestStatus InputAssemblyInstance::iterate (void)
1442 {
1443         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1444         const VkDevice                          vkDevice        = m_context.getDevice();
1445         const VkQueue                           queue           = m_context.getUniversalQueue();
1446         const VkSubmitInfo                      submitInfo      =
1447         {
1448                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
1449                 DE_NULL,                                                // const void*                          pNext;
1450                 0u,                                                             // deUint32                                     waitSemaphoreCount;
1451                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
1452                 1u,                                                             // deUint32                                     commandBufferCount;
1453                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
1454                 0u,                                                             // deUint32                                     signalSemaphoreCount;
1455                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
1456         };
1457
1458         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1459         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1460         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1461
1462         return verifyImage();
1463 }
1464
1465 tcu::TestStatus InputAssemblyInstance::verifyImage (void)
1466 {
1467         const tcu::TextureFormat        tcuColorFormat          = mapVkFormat(m_colorFormat);
1468         const tcu::TextureFormat        tcuStencilFormat        = tcu::TextureFormat();
1469         const ColorVertexShader         vertexShader;
1470         const ColorFragmentShader       fragmentShader          (tcuColorFormat, tcuStencilFormat);
1471         const rr::Program                       program                         (&vertexShader, &fragmentShader);
1472         ReferenceRenderer                       refRenderer                     (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuStencilFormat, &program);
1473         bool                                            compareOk                       = false;
1474
1475         // Render reference image
1476         {
1477                 const rr::PrimitiveType         topology        = mapVkPrimitiveTopology(m_primitiveTopology);
1478                 rr::RenderState                         renderState     (refRenderer.getViewportState());
1479
1480                 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
1481                         renderState.point.pointSize = 3.0f;
1482
1483                 if (m_primitiveRestartEnable)
1484                 {
1485                         std::vector<deUint32> indicesRange;
1486
1487                         for (size_t indexNdx = 0; indexNdx < m_indices.size(); indexNdx++)
1488                         {
1489                                 const bool isRestart = InputAssemblyTest::isRestartIndex(m_indexType, m_indices[indexNdx]);
1490
1491                                 if (!isRestart)
1492                                         indicesRange.push_back(m_indices[indexNdx]);
1493
1494                                 if (isRestart || indexNdx == (m_indices.size() - 1))
1495                                 {
1496                                         // Draw the range of indices found so far
1497
1498                                         std::vector<Vertex4RGBA> nonIndexedVertices;
1499                                         for (size_t i = 0; i < indicesRange.size(); i++)
1500                                                 nonIndexedVertices.push_back(m_vertices[indicesRange[i]]);
1501
1502                                         refRenderer.draw(renderState, topology, nonIndexedVertices);
1503                                         indicesRange.clear();
1504                                 }
1505                         }
1506                 }
1507                 else
1508                 {
1509                         std::vector<Vertex4RGBA> nonIndexedVertices;
1510                         for (size_t i = 0; i < m_indices.size(); i++)
1511                                 nonIndexedVertices.push_back(m_vertices[m_indices[i]]);
1512
1513                         refRenderer.draw(renderState, topology, nonIndexedVertices);
1514                 }
1515         }
1516
1517         // Compare result with reference image
1518         {
1519                 const DeviceInterface&                          vk                                      = m_context.getDeviceInterface();
1520                 const VkDevice                                          vkDevice                        = m_context.getDevice();
1521                 const VkQueue                                           queue                           = m_context.getUniversalQueue();
1522                 const deUint32                                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
1523                 SimpleAllocator                                         allocator                       (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1524                 de::UniquePtr<tcu::TextureLevel>        result                          (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
1525
1526                 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1527                                                                                                                           "IntImageCompare",
1528                                                                                                                           "Image comparison",
1529                                                                                                                           refRenderer.getAccess(),
1530                                                                                                                           result->getAccess(),
1531                                                                                                                           tcu::UVec4(2, 2, 2, 2),
1532                                                                                                                           tcu::IVec3(1, 1, 0),
1533                                                                                                                           true,
1534                                                                                                                           tcu::COMPARE_LOG_RESULT);
1535         }
1536
1537         if (compareOk)
1538                 return tcu::TestStatus::pass("Result image matches reference");
1539         else
1540                 return tcu::TestStatus::fail("Image mismatch");
1541 }
1542
1543 void InputAssemblyInstance::uploadIndexBufferData16     (deUint16* destPtr, const std::vector<deUint32>& indexBufferData)
1544 {
1545         for (size_t i = 0; i < indexBufferData.size(); i++)
1546         {
1547                 DE_ASSERT(indexBufferData[i] <= 0xFFFF);
1548                 destPtr[i] = (deUint16)indexBufferData[i];
1549         }
1550 }
1551
1552
1553 // Utilities for test names
1554
1555 std::string getPrimitiveTopologyCaseName (VkPrimitiveTopology topology)
1556 {
1557         const std::string  fullName = getPrimitiveTopologyName(topology);
1558
1559         DE_ASSERT(de::beginsWith(fullName, "VK_PRIMITIVE_TOPOLOGY_"));
1560
1561         return de::toLower(fullName.substr(22));
1562 }
1563
1564 de::MovePtr<tcu::TestCaseGroup> createPrimitiveTopologyTests (tcu::TestContext& testCtx)
1565 {
1566         de::MovePtr<tcu::TestCaseGroup> primitiveTopologyTests (new tcu::TestCaseGroup(testCtx, "primitive_topology", ""));
1567
1568         for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(InputAssemblyTest::s_primitiveTopologies); topologyNdx++)
1569         {
1570                 const VkPrimitiveTopology topology = InputAssemblyTest::s_primitiveTopologies[topologyNdx];
1571
1572                 primitiveTopologyTests->addChild(new PrimitiveTopologyTest(testCtx,
1573                                                                                                                                    getPrimitiveTopologyCaseName(topology),
1574                                                                                                                                    "",
1575                                                                                                                                    topology));
1576         }
1577
1578         return primitiveTopologyTests;
1579 }
1580
1581 de::MovePtr<tcu::TestCaseGroup> createPrimitiveRestartTests (tcu::TestContext& testCtx)
1582 {
1583         const VkPrimitiveTopology primitiveRestartTopologies[] =
1584         {
1585                 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
1586                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
1587                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
1588                 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
1589                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY
1590         };
1591
1592         de::MovePtr<tcu::TestCaseGroup> primitiveRestartTests (new tcu::TestCaseGroup(testCtx, "primitive_restart", "Restarts indices of "));
1593
1594         de::MovePtr<tcu::TestCaseGroup> indexUint16Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint16", ""));
1595         de::MovePtr<tcu::TestCaseGroup> indexUint32Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint32", ""));
1596
1597         for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(primitiveRestartTopologies); topologyNdx++)
1598         {
1599                 const VkPrimitiveTopology topology = primitiveRestartTopologies[topologyNdx];
1600
1601                 indexUint16Tests->addChild(new PrimitiveRestartTest(testCtx,
1602                                                                                                                         getPrimitiveTopologyCaseName(topology),
1603                                                                                                                         "",
1604                                                                                                                         topology,
1605                                                                                                                         VK_INDEX_TYPE_UINT16));
1606
1607                 indexUint32Tests->addChild(new PrimitiveRestartTest(testCtx,
1608                                                                                                                         getPrimitiveTopologyCaseName(topology),
1609                                                                                                                         "",
1610                                                                                                                         topology,
1611                                                                                                                         VK_INDEX_TYPE_UINT32));
1612         }
1613
1614         primitiveRestartTests->addChild(indexUint16Tests.release());
1615         primitiveRestartTests->addChild(indexUint32Tests.release());
1616
1617         return primitiveRestartTests;
1618 }
1619
1620 } // anonymous
1621
1622 tcu::TestCaseGroup* createInputAssemblyTests (tcu::TestContext& testCtx)
1623 {
1624         de::MovePtr<tcu::TestCaseGroup>         inputAssemblyTests (new tcu::TestCaseGroup(testCtx, "input_assembly", "Input assembly tests"));
1625
1626         inputAssemblyTests->addChild(createPrimitiveTopologyTests(testCtx).release());
1627         inputAssemblyTests->addChild(createPrimitiveRestartTests(testCtx).release());
1628
1629         return inputAssemblyTests.release();
1630 }
1631
1632 } // pipeline
1633 } // vkt