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);
~InputAssemblyTest(void)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);
~PrimitiveTopologyTest(void)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);
~PrimitiveRestartTest(void)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
InputAssemblyTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkPrimitiveTopology primitiveTopology,int primitiveCount,bool testPrimitiveRestart,VkIndexType indexType)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
createInstance(Context & context) const220 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
initPrograms(SourceCollections & sourceCollections) const230 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
isRestartIndex(VkIndexType indexType,deUint32 indexValue)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
getRestartIndex(VkIndexType indexType)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
PrimitiveTopologyTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkPrimitiveTopology primitiveTopology)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
createBufferData(VkPrimitiveTopology topology,int primitiveCount,VkIndexType indexType,std::vector<deUint32> & indexData,std::vector<Vertex4RGBA> & vertexData) const286 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
PrimitiveRestartTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkPrimitiveTopology primitiveTopology,VkIndexType indexType)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
createBufferData(VkPrimitiveTopology topology,int primitiveCount,VkIndexType indexType,std::vector<deUint32> & indexData,std::vector<Vertex4RGBA> & vertexData) const640 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
isRestartPrimitive(int primitiveIndex) const898 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
InputAssemblyInstance(Context & context,VkPrimitiveTopology primitiveTopology,bool testPrimitiveRestart,VkIndexType indexType,const std::vector<deUint32> & indexBufferData,const std::vector<Vertex4RGBA> & vertexBufferData)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 {
1359 const VkCommandPoolCreateInfo cmdPoolParams =
1360 {
1361 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1362 DE_NULL, // const void* pNext;
1363 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
1364 queueFamilyIndex // deUint32 queueFamilyIndex;
1365 };
1366
1367 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1368 }
1369
1370 // Create command buffer
1371 {
1372 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
1373 {
1374 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1375 DE_NULL, // const void* pNext;
1376 *m_cmdPool, // VkCommandPool commandPool;
1377 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
1378 1u // deUint32 bufferCount;
1379 };
1380
1381 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1382 {
1383 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1384 DE_NULL, // const void* pNext;
1385 0u, // VkCommandBufferUsageFlags flags;
1386 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1387 };
1388
1389 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
1390
1391 const VkRenderPassBeginInfo renderPassBeginInfo =
1392 {
1393 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1394 DE_NULL, // const void* pNext;
1395 *m_renderPass, // VkRenderPass renderPass;
1396 *m_framebuffer, // VkFramebuffer framebuffer;
1397 { { 0, 0 } , { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea;
1398 1u, // deUint32 clearValueCount;
1399 &attachmentClearValue // const VkClearValue* pClearValues;
1400 };
1401
1402 const VkImageMemoryBarrier attachmentLayoutBarrier =
1403 {
1404 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1405 DE_NULL, // const void* pNext;
1406 0u, // VkAccessFlags srcAccessMask;
1407 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
1408 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1409 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
1410 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1411 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1412 *m_colorImage, // VkImage image;
1413 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
1414 };
1415
1416 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
1417
1418 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1419
1420 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
1421 0u, DE_NULL, 0u, DE_NULL, 1u, &attachmentLayoutBarrier);
1422
1423 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1424
1425 const VkDeviceSize vertexBufferOffset = 0;
1426
1427 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1428 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1429 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indexBuffer, 0, m_indexType);
1430 vk.cmdDrawIndexed(*m_cmdBuffer, (deUint32)m_indices.size(), 1, 0, 0, 0);
1431
1432 vk.cmdEndRenderPass(*m_cmdBuffer);
1433 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1434 }
1435
1436 // Create fence
1437 {
1438 const VkFenceCreateInfo fenceParams =
1439 {
1440 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1441 DE_NULL, // const void* pNext;
1442 0u // VkFenceCreateFlags flags;
1443 };
1444
1445 m_fence = createFence(vk, vkDevice, &fenceParams);
1446 }
1447 }
1448
~InputAssemblyInstance(void)1449 InputAssemblyInstance::~InputAssemblyInstance (void)
1450 {
1451 }
1452
iterate(void)1453 tcu::TestStatus InputAssemblyInstance::iterate (void)
1454 {
1455 const DeviceInterface& vk = m_context.getDeviceInterface();
1456 const VkDevice vkDevice = m_context.getDevice();
1457 const VkQueue queue = m_context.getUniversalQueue();
1458 const VkSubmitInfo submitInfo =
1459 {
1460 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1461 DE_NULL, // const void* pNext;
1462 0u, // deUint32 waitSemaphoreCount;
1463 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1464 (const VkPipelineStageFlags*)DE_NULL,
1465 1u, // deUint32 commandBufferCount;
1466 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1467 0u, // deUint32 signalSemaphoreCount;
1468 DE_NULL // const VkSemaphore* pSignalSemaphores;
1469 };
1470
1471 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1472 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1473 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1474
1475 return verifyImage();
1476 }
1477
verifyImage(void)1478 tcu::TestStatus InputAssemblyInstance::verifyImage (void)
1479 {
1480 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
1481 const tcu::TextureFormat tcuStencilFormat = tcu::TextureFormat();
1482 const ColorVertexShader vertexShader;
1483 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuStencilFormat);
1484 const rr::Program program (&vertexShader, &fragmentShader);
1485 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuStencilFormat, &program);
1486 bool compareOk = false;
1487
1488 // Render reference image
1489 {
1490 const rr::PrimitiveType topology = mapVkPrimitiveTopology(m_primitiveTopology);
1491 rr::RenderState renderState (refRenderer.getViewportState());
1492
1493 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
1494 renderState.point.pointSize = 3.0f;
1495
1496 if (m_primitiveRestartEnable)
1497 {
1498 std::vector<deUint32> indicesRange;
1499
1500 for (size_t indexNdx = 0; indexNdx < m_indices.size(); indexNdx++)
1501 {
1502 const bool isRestart = InputAssemblyTest::isRestartIndex(m_indexType, m_indices[indexNdx]);
1503
1504 if (!isRestart)
1505 indicesRange.push_back(m_indices[indexNdx]);
1506
1507 if (isRestart || indexNdx == (m_indices.size() - 1))
1508 {
1509 // Draw the range of indices found so far
1510
1511 std::vector<Vertex4RGBA> nonIndexedVertices;
1512 for (size_t i = 0; i < indicesRange.size(); i++)
1513 nonIndexedVertices.push_back(m_vertices[indicesRange[i]]);
1514
1515 refRenderer.draw(renderState, topology, nonIndexedVertices);
1516 indicesRange.clear();
1517 }
1518 }
1519 }
1520 else
1521 {
1522 std::vector<Vertex4RGBA> nonIndexedVertices;
1523 for (size_t i = 0; i < m_indices.size(); i++)
1524 nonIndexedVertices.push_back(m_vertices[m_indices[i]]);
1525
1526 refRenderer.draw(renderState, topology, nonIndexedVertices);
1527 }
1528 }
1529
1530 // Compare result with reference image
1531 {
1532 const DeviceInterface& vk = m_context.getDeviceInterface();
1533 const VkDevice vkDevice = m_context.getDevice();
1534 const VkQueue queue = m_context.getUniversalQueue();
1535 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1536 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1537 de::UniquePtr<tcu::TextureLevel> result (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
1538
1539 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1540 "IntImageCompare",
1541 "Image comparison",
1542 refRenderer.getAccess(),
1543 result->getAccess(),
1544 tcu::UVec4(2, 2, 2, 2),
1545 tcu::IVec3(1, 1, 0),
1546 true,
1547 tcu::COMPARE_LOG_RESULT);
1548 }
1549
1550 if (compareOk)
1551 return tcu::TestStatus::pass("Result image matches reference");
1552 else
1553 return tcu::TestStatus::fail("Image mismatch");
1554 }
1555
uploadIndexBufferData16(deUint16 * destPtr,const std::vector<deUint32> & indexBufferData)1556 void InputAssemblyInstance::uploadIndexBufferData16 (deUint16* destPtr, const std::vector<deUint32>& indexBufferData)
1557 {
1558 for (size_t i = 0; i < indexBufferData.size(); i++)
1559 {
1560 DE_ASSERT(indexBufferData[i] <= 0xFFFF);
1561 destPtr[i] = (deUint16)indexBufferData[i];
1562 }
1563 }
1564
1565
1566 // Utilities for test names
1567
getPrimitiveTopologyCaseName(VkPrimitiveTopology topology)1568 std::string getPrimitiveTopologyCaseName (VkPrimitiveTopology topology)
1569 {
1570 const std::string fullName = getPrimitiveTopologyName(topology);
1571
1572 DE_ASSERT(de::beginsWith(fullName, "VK_PRIMITIVE_TOPOLOGY_"));
1573
1574 return de::toLower(fullName.substr(22));
1575 }
1576
createPrimitiveTopologyTests(tcu::TestContext & testCtx)1577 de::MovePtr<tcu::TestCaseGroup> createPrimitiveTopologyTests (tcu::TestContext& testCtx)
1578 {
1579 de::MovePtr<tcu::TestCaseGroup> primitiveTopologyTests (new tcu::TestCaseGroup(testCtx, "primitive_topology", ""));
1580
1581 for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(InputAssemblyTest::s_primitiveTopologies); topologyNdx++)
1582 {
1583 const VkPrimitiveTopology topology = InputAssemblyTest::s_primitiveTopologies[topologyNdx];
1584
1585 primitiveTopologyTests->addChild(new PrimitiveTopologyTest(testCtx,
1586 getPrimitiveTopologyCaseName(topology),
1587 "",
1588 topology));
1589 }
1590
1591 return primitiveTopologyTests;
1592 }
1593
createPrimitiveRestartTests(tcu::TestContext & testCtx)1594 de::MovePtr<tcu::TestCaseGroup> createPrimitiveRestartTests (tcu::TestContext& testCtx)
1595 {
1596 const VkPrimitiveTopology primitiveRestartTopologies[] =
1597 {
1598 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
1599 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
1600 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
1601 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
1602 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY
1603 };
1604
1605 de::MovePtr<tcu::TestCaseGroup> primitiveRestartTests (new tcu::TestCaseGroup(testCtx, "primitive_restart", "Restarts indices of "));
1606
1607 de::MovePtr<tcu::TestCaseGroup> indexUint16Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint16", ""));
1608 de::MovePtr<tcu::TestCaseGroup> indexUint32Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint32", ""));
1609
1610 for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(primitiveRestartTopologies); topologyNdx++)
1611 {
1612 const VkPrimitiveTopology topology = primitiveRestartTopologies[topologyNdx];
1613
1614 indexUint16Tests->addChild(new PrimitiveRestartTest(testCtx,
1615 getPrimitiveTopologyCaseName(topology),
1616 "",
1617 topology,
1618 VK_INDEX_TYPE_UINT16));
1619
1620 indexUint32Tests->addChild(new PrimitiveRestartTest(testCtx,
1621 getPrimitiveTopologyCaseName(topology),
1622 "",
1623 topology,
1624 VK_INDEX_TYPE_UINT32));
1625 }
1626
1627 primitiveRestartTests->addChild(indexUint16Tests.release());
1628 primitiveRestartTests->addChild(indexUint32Tests.release());
1629
1630 return primitiveRestartTests;
1631 }
1632
1633 } // anonymous
1634
createInputAssemblyTests(tcu::TestContext & testCtx)1635 tcu::TestCaseGroup* createInputAssemblyTests (tcu::TestContext& testCtx)
1636 {
1637 de::MovePtr<tcu::TestCaseGroup> inputAssemblyTests (new tcu::TestCaseGroup(testCtx, "input_assembly", "Input assembly tests"));
1638
1639 inputAssemblyTests->addChild(createPrimitiveTopologyTests(testCtx).release());
1640 inputAssemblyTests->addChild(createPrimitiveRestartTests(testCtx).release());
1641
1642 return inputAssemblyTests.release();
1643 }
1644
1645 } // pipeline
1646 } // vkt
1647