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