1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
33 * \brief Input Assembly Tests
34 *//*--------------------------------------------------------------------*/
36 #include "vktPipelineInputAssemblyTests.hpp"
37 #include "vktPipelineClearUtil.hpp"
38 #include "vktPipelineImageUtil.hpp"
39 #include "vktPipelineVertexUtil.hpp"
40 #include "vktPipelineReferenceRenderer.hpp"
41 #include "vktTestCase.hpp"
42 #include "vkImageUtil.hpp"
43 #include "vkMemUtil.hpp"
44 #include "vkPrograms.hpp"
45 #include "vkQueryUtil.hpp"
47 #include "vkRefUtil.hpp"
48 #include "tcuImageCompare.hpp"
51 #include "deRandom.hpp"
52 #include "deStringUtil.hpp"
53 #include "deUniquePtr.hpp"
69 class InputAssemblyTest : public vkt::TestCase
72 const static VkPrimitiveTopology s_primitiveTopologies[];
73 const static deUint32 s_restartIndex32;
74 const static deUint16 s_restartIndex16;
76 InputAssemblyTest (tcu::TestContext& testContext,
77 const std::string& name,
78 const std::string& description,
79 VkPrimitiveTopology primitiveTopology,
81 bool testPrimitiveRestart,
82 VkIndexType indexType);
83 virtual ~InputAssemblyTest (void) {}
84 virtual void initPrograms (SourceCollections& sourceCollections) const;
85 virtual TestInstance* createInstance (Context& context) const;
86 static bool isRestartIndex (VkIndexType indexType, deUint32 indexValue);
87 static deUint32 getRestartIndex (VkIndexType indexType);
90 virtual void createBufferData (VkPrimitiveTopology topology,
92 VkIndexType indexType,
93 std::vector<deUint32>& indexData,
94 std::vector<Vertex4RGBA>& vertexData) const = 0;
97 VkPrimitiveTopology m_primitiveTopology;
98 const int m_primitiveCount;
99 bool m_testPrimitiveRestart;
100 VkIndexType m_indexType;
103 class PrimitiveTopologyTest : public InputAssemblyTest
106 PrimitiveTopologyTest (tcu::TestContext& testContext,
107 const std::string& name,
108 const std::string& description,
109 VkPrimitiveTopology primitiveTopology);
110 virtual ~PrimitiveTopologyTest (void) {}
113 virtual void createBufferData (VkPrimitiveTopology topology,
115 VkIndexType indexType,
116 std::vector<deUint32>& indexData,
117 std::vector<Vertex4RGBA>& vertexData) const;
122 class PrimitiveRestartTest : public InputAssemblyTest
125 PrimitiveRestartTest (tcu::TestContext& testContext,
126 const std::string& name,
127 const std::string& description,
128 VkPrimitiveTopology primitiveTopology,
129 VkIndexType indexType);
130 virtual ~PrimitiveRestartTest (void) {}
133 virtual void createBufferData (VkPrimitiveTopology topology,
135 VkIndexType indexType,
136 std::vector<deUint32>& indexData,
137 std::vector<Vertex4RGBA>& vertexData) const;
140 bool isRestartPrimitive (int primitiveIndex) const;
142 std::vector<deUint32> m_restartPrimitives;
145 class InputAssemblyInstance : public vkt::TestInstance
148 InputAssemblyInstance (Context& context,
149 VkPrimitiveTopology primitiveTopology,
150 bool testPrimitiveRestart,
151 VkIndexType indexType,
152 const std::vector<deUint32>& indexBufferData,
153 const std::vector<Vertex4RGBA>& vertexBufferData);
154 virtual ~InputAssemblyInstance (void);
155 virtual tcu::TestStatus iterate (void);
158 tcu::TestStatus verifyImage (void);
159 void uploadIndexBufferData16 (deUint16* destPtr, const std::vector<deUint32>& indexBufferData);
161 VkPrimitiveTopology m_primitiveTopology;
162 bool m_primitiveRestartEnable;
163 VkIndexType m_indexType;
165 Move<VkBuffer> m_vertexBuffer;
166 std::vector<Vertex4RGBA> m_vertices;
167 de::MovePtr<Allocation> m_vertexBufferAlloc;
169 Move<VkBuffer> m_indexBuffer;
170 std::vector<deUint32> m_indices;
171 de::MovePtr<Allocation> m_indexBufferAlloc;
173 const tcu::IVec2 m_renderSize;
175 const VkFormat m_colorFormat;
176 VkImageCreateInfo m_colorImageCreateInfo;
177 Move<VkImage> m_colorImage;
178 de::MovePtr<Allocation> m_colorImageAlloc;
179 Move<VkImageView> m_colorAttachmentView;
180 Move<VkRenderPass> m_renderPass;
181 Move<VkFramebuffer> m_framebuffer;
183 Move<VkShaderModule> m_vertexShaderModule;
184 Move<VkShaderModule> m_fragmentShaderModule;
186 Move<VkPipelineLayout> m_pipelineLayout;
187 Move<VkPipeline> m_graphicsPipeline;
189 Move<VkCommandPool> m_cmdPool;
190 Move<VkCommandBuffer> m_cmdBuffer;
192 Move<VkFence> m_fence;
198 const VkPrimitiveTopology InputAssemblyTest::s_primitiveTopologies[] =
200 VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
201 VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
202 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
203 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
204 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
205 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
206 VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
207 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
208 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
209 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY
212 const deUint32 InputAssemblyTest::s_restartIndex32 = ~((deUint32)0u);
213 const deUint16 InputAssemblyTest::s_restartIndex16 = ~((deUint16)0u);
215 InputAssemblyTest::InputAssemblyTest (tcu::TestContext& testContext,
216 const std::string& name,
217 const std::string& description,
218 VkPrimitiveTopology primitiveTopology,
220 bool testPrimitiveRestart,
221 VkIndexType indexType)
223 : vkt::TestCase (testContext, name, description)
224 , m_primitiveTopology (primitiveTopology)
225 , m_primitiveCount (primitiveCount)
226 , m_testPrimitiveRestart (testPrimitiveRestart)
227 , m_indexType (indexType)
231 TestInstance* InputAssemblyTest::createInstance (Context& context) const
233 std::vector<deUint32> indexBufferData;
234 std::vector<Vertex4RGBA> vertexBufferData;
236 createBufferData(m_primitiveTopology, m_primitiveCount, m_indexType, indexBufferData, vertexBufferData);
238 return new InputAssemblyInstance(context, m_primitiveTopology, m_testPrimitiveRestart, m_indexType, indexBufferData, vertexBufferData);
241 void InputAssemblyTest::initPrograms (SourceCollections& sourceCollections) const
243 std::ostringstream vertexSource;
247 "layout(location = 0) in vec4 position;\n"
248 "layout(location = 1) in vec4 color;\n"
249 "layout(location = 0) out highp vec4 vtxColor;\n"
252 " gl_Position = position;\n"
253 << (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST ? " gl_PointSize = 3.0;\n"
255 << " vtxColor = color;\n"
258 sourceCollections.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
260 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
262 "layout(location = 0) in highp vec4 vtxColor;\n"
263 "layout(location = 0) out highp vec4 fragColor;\n"
266 " fragColor = vtxColor;\n"
270 bool InputAssemblyTest::isRestartIndex (VkIndexType indexType, deUint32 indexValue)
272 if (indexType == VK_INDEX_TYPE_UINT32)
273 return indexValue == s_restartIndex32;
275 return indexValue == s_restartIndex16;
278 deUint32 InputAssemblyTest::getRestartIndex (VkIndexType indexType)
280 if (indexType == VK_INDEX_TYPE_UINT16)
281 return InputAssemblyTest::s_restartIndex16;
283 return InputAssemblyTest::s_restartIndex32;
287 // PrimitiveTopologyTest
289 PrimitiveTopologyTest::PrimitiveTopologyTest (tcu::TestContext& testContext,
290 const std::string& name,
291 const std::string& description,
292 VkPrimitiveTopology primitiveTopology)
293 : InputAssemblyTest (testContext, name, description, primitiveTopology, 10, false, VK_INDEX_TYPE_UINT32)
297 void PrimitiveTopologyTest::createBufferData (VkPrimitiveTopology topology, int primitiveCount, VkIndexType indexType, std::vector<deUint32>& indexData, std::vector<Vertex4RGBA>& vertexData) const
299 DE_ASSERT(primitiveCount > 0);
302 const tcu::Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
303 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
304 const float border = 0.2f;
305 const float originX = -1.0f + border;
306 const float originY = -1.0f + border;
307 const Vertex4RGBA defaultVertex = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), green };
308 float primitiveSizeY = (2.0f - 2.0f * border);
309 float primitiveSizeX;
310 std::vector<deUint32> indices;
311 std::vector<Vertex4RGBA> vertices;
314 // Calculate primitive size
317 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
318 primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2 + primitiveCount % 2 - 1);
321 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
322 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
323 primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount - 1);
326 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
327 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
328 primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2);
331 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
332 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
333 primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount + primitiveCount / 2 + primitiveCount % 2 - 1);
336 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
337 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
338 primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2 + primitiveCount % 2);
341 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
342 primitiveSizeX = 1.0f - border;
343 primitiveSizeY = 1.0f - border;
347 primitiveSizeX = 0.0f; // Garbage
353 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
354 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
356 const Vertex4RGBA vertex =
358 tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
362 vertices.push_back(vertex);
363 indices.push_back(primitiveNdx);
367 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
368 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
370 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
372 const Vertex4RGBA vertex =
374 tcu::Vec4(originX + float((primitiveNdx * 2 + vertexNdx) / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
378 vertices.push_back(vertex);
379 indices.push_back((primitiveNdx * 2 + vertexNdx));
384 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
385 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
387 if (primitiveNdx == 0)
391 tcu::Vec4(originX, originY, 0.0f, 1.0f),
395 vertices.push_back(vertex);
396 indices.push_back(0);
398 vertex.position = tcu::Vec4(originX, originY + primitiveSizeY, 0.0f, 1.0f);
399 vertices.push_back(vertex);
400 indices.push_back(1);
404 const Vertex4RGBA vertex =
406 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
410 vertices.push_back(vertex);
411 indices.push_back(primitiveNdx + 1);
416 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
417 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
419 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
421 const Vertex4RGBA vertex =
423 tcu::Vec4(originX + float((primitiveNdx * 3 + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx * 3 + vertexNdx)% 2) * primitiveSizeY, 0.0f, 1.0f),
427 vertices.push_back(vertex);
428 indices.push_back(primitiveNdx * 3 + vertexNdx);
433 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
434 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
436 if (primitiveNdx == 0)
438 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
440 const Vertex4RGBA vertex =
442 tcu::Vec4(originX + float(vertexNdx / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
446 vertices.push_back(vertex);
447 indices.push_back(vertexNdx);
452 const Vertex4RGBA vertex =
454 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
458 vertices.push_back(vertex);
459 indices.push_back(primitiveNdx + 2);
464 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
466 const float stepAngle = de::min(DE_PI * 0.5f, (2 * DE_PI) / float(primitiveCount));
468 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
470 if (primitiveNdx == 0)
474 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
478 vertices.push_back(vertex);
479 indices.push_back(0);
481 vertex.position = tcu::Vec4(primitiveSizeX, 0.0f, 0.0f, 1.0f);
482 vertices.push_back(vertex);
483 indices.push_back(1);
485 vertex.position = tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle), primitiveSizeY * deFloatSin(stepAngle), 0.0f, 1.0f);
486 vertices.push_back(vertex);
487 indices.push_back(2);
491 const Vertex4RGBA vertex =
493 tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx + 1)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx + 1)), 0.0f, 1.0f),
497 vertices.push_back(vertex);
498 indices.push_back(primitiveNdx + 2);
504 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
505 vertices.push_back(defaultVertex);
507 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
509 indices.push_back(0);
511 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
513 const Vertex4RGBA vertex =
515 tcu::Vec4(originX + float((primitiveNdx * 2 + vertexNdx) / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
519 vertices.push_back(vertex);
520 indices.push_back(primitiveNdx * 2 + vertexNdx + 1);
523 indices.push_back(0);
528 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
529 vertices.push_back(defaultVertex);
530 indices.push_back(0);
532 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
534 if (primitiveNdx == 0)
538 tcu::Vec4(originX, originY, 0.0f, 1.0f),
542 vertices.push_back(vertex);
543 indices.push_back(1);
545 vertex.position = tcu::Vec4(originX, originY + primitiveSizeY, 0.0f, 1.0f);
546 vertices.push_back(vertex);
547 indices.push_back(2);
551 const Vertex4RGBA vertex =
553 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
557 vertices.push_back(vertex);
558 indices.push_back(primitiveNdx + 2);
562 indices.push_back(0);
565 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
566 vertices.push_back(defaultVertex);
568 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
570 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
572 const Vertex4RGBA vertex =
574 tcu::Vec4(originX + float((primitiveNdx * 3 + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx * 3 + vertexNdx)% 2) * primitiveSizeY, 0.0f, 1.0f),
578 vertices.push_back(vertex);
579 indices.push_back(primitiveNdx * 3 + vertexNdx + 1);
580 indices.push_back(0);
585 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
586 vertices.push_back(defaultVertex);
588 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
590 if (primitiveNdx == 0)
592 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
594 const Vertex4RGBA vertex =
596 tcu::Vec4(originX + float(vertexNdx / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
600 vertices.push_back(vertex);
601 indices.push_back(vertexNdx + 1);
602 indices.push_back(0);
607 const Vertex4RGBA vertex =
609 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
613 vertices.push_back(vertex);
614 indices.push_back(primitiveNdx + 2 + 1);
615 indices.push_back(0);
625 vertexData = vertices;
630 // PrimitiveRestartTest
632 PrimitiveRestartTest::PrimitiveRestartTest (tcu::TestContext& testContext,
633 const std::string& name,
634 const std::string& description,
635 VkPrimitiveTopology primitiveTopology,
636 VkIndexType indexType)
638 : InputAssemblyTest (testContext, name, description, primitiveTopology, 10, true, indexType)
640 DE_ASSERT(primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP ||
641 primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ||
642 primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN ||
643 primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ||
644 primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY);
646 deUint32 restartPrimitives[] = { 1, 5 };
648 m_restartPrimitives = std::vector<deUint32>(restartPrimitives, restartPrimitives + sizeof(restartPrimitives) / sizeof(deUint32));
651 void PrimitiveRestartTest::createBufferData (VkPrimitiveTopology topology, int primitiveCount, VkIndexType indexType, std::vector<deUint32>& indexData, std::vector<Vertex4RGBA>& vertexData) const
653 DE_ASSERT(primitiveCount > 0);
656 const tcu::Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
657 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
658 const float border = 0.2f;
659 const float originX = -1.0f + border;
660 const float originY = -1.0f + border;
661 const Vertex4RGBA defaultVertex = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), green };
662 float primitiveSizeY = (2.0f - 2.0f * border);
663 float primitiveSizeX;
664 bool primitiveStart = true;
665 std::vector<deUint32> indices;
666 std::vector<Vertex4RGBA> vertices;
669 // Calculate primitive size
672 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
673 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
674 primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2);
677 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
678 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
679 primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2 + primitiveCount % 2);
682 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
683 primitiveSizeX = 1.0f - border;
684 primitiveSizeY = 1.0f - border;
688 primitiveSizeX = 0.0f; // Garbage
694 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
695 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
697 if (isRestartPrimitive(primitiveNdx))
699 indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
700 primitiveStart = true;
706 const Vertex4RGBA vertex =
708 tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
712 vertices.push_back(vertex);
713 indices.push_back((deUint32)vertices.size() - 1);
715 primitiveStart = false;
718 const Vertex4RGBA vertex =
720 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
724 vertices.push_back(vertex);
725 indices.push_back((deUint32)vertices.size() - 1);
730 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
732 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
734 if (isRestartPrimitive(primitiveNdx))
736 indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
737 primitiveStart = true;
743 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
745 const Vertex4RGBA vertex =
747 tcu::Vec4(originX + float((primitiveNdx + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx + vertexNdx) % 2) * primitiveSizeY, 0.0f, 1.0f),
751 vertices.push_back(vertex);
752 indices.push_back((deUint32)vertices.size() - 1);
755 primitiveStart = false;
757 const Vertex4RGBA vertex =
759 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
763 vertices.push_back(vertex);
764 indices.push_back((deUint32)vertices.size() - 1);
770 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
772 const float stepAngle = de::min(DE_PI * 0.5f, (2 * DE_PI) / float(primitiveCount));
774 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
776 if (isRestartPrimitive(primitiveNdx))
778 indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
779 primitiveStart = true;
787 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
791 vertices.push_back(vertex);
792 indices.push_back((deUint32)vertices.size() - 1);
794 vertex.position = tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx)), 0.0f, 1.0f),
795 vertices.push_back(vertex);
796 indices.push_back((deUint32)vertices.size() - 1);
798 primitiveStart = false;
801 const Vertex4RGBA vertex =
803 tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx + 1)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx + 1)), 0.0f, 1.0f),
807 vertices.push_back(vertex);
808 indices.push_back((deUint32)vertices.size() - 1);
814 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
815 vertices.push_back(defaultVertex);
817 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
819 if (isRestartPrimitive(primitiveNdx))
821 indices.push_back(0);
822 indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
823 primitiveStart = true;
829 indices.push_back(0);
831 const Vertex4RGBA vertex =
833 tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
837 vertices.push_back(vertex);
838 indices.push_back((deUint32)vertices.size() - 1);
840 primitiveStart = false;
843 const Vertex4RGBA vertex =
845 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
849 vertices.push_back(vertex);
850 indices.push_back((deUint32)vertices.size() - 1);
854 indices.push_back(0);
857 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
858 vertices.push_back(defaultVertex);
860 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
862 if (isRestartPrimitive(primitiveNdx))
864 indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
865 primitiveStart = true;
871 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
873 const Vertex4RGBA vertex =
875 tcu::Vec4(originX + float((primitiveNdx + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx + vertexNdx) % 2) * primitiveSizeY, 0.0f, 1.0f),
879 vertices.push_back(vertex);
880 indices.push_back((deUint32)vertices.size() - 1);
881 indices.push_back(0);
884 primitiveStart = false;
887 const Vertex4RGBA vertex =
889 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
893 vertices.push_back(vertex);
894 indices.push_back((deUint32)vertices.size() - 1);
895 indices.push_back(0);
905 vertexData = vertices;
909 bool PrimitiveRestartTest::isRestartPrimitive (int primitiveIndex) const
911 return std::find(m_restartPrimitives.begin(), m_restartPrimitives.end(), primitiveIndex) != m_restartPrimitives.end();
915 // InputAssemblyInstance
917 InputAssemblyInstance::InputAssemblyInstance (Context& context,
918 VkPrimitiveTopology primitiveTopology,
919 bool testPrimitiveRestart,
920 VkIndexType indexType,
921 const std::vector<deUint32>& indexBufferData,
922 const std::vector<Vertex4RGBA>& vertexBufferData)
924 : vkt::TestInstance (context)
925 , m_primitiveTopology (primitiveTopology)
926 , m_primitiveRestartEnable (testPrimitiveRestart)
927 , m_indexType (indexType)
928 , m_vertices (vertexBufferData)
929 , m_indices (indexBufferData)
930 , m_renderSize ((primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) ? tcu::IVec2(32, 32) : tcu::IVec2(64, 16))
931 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
933 const DeviceInterface& vk = context.getDeviceInterface();
934 const VkDevice vkDevice = context.getDevice();
935 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
936 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
937 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
939 // Create color image
941 const VkImageCreateInfo colorImageParams =
943 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
944 DE_NULL, // const void* pNext;
945 0u, // VkImageCreateFlags flags;
946 VK_IMAGE_TYPE_2D, // VkImageType imageType;
947 m_colorFormat, // VkFormat format;
948 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
949 1u, // deUint32 mipLevels;
950 1u, // deUint32 arrayLayers;
951 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
952 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
953 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
954 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
955 1u, // deUint32 queueFamilyIndexCount;
956 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
957 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
960 m_colorImageCreateInfo = colorImageParams;
961 m_colorImage = createImage(vk, vkDevice, &m_colorImageCreateInfo);
963 // Allocate and bind color image memory
964 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
965 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
968 // Create color attachment view
970 const VkImageViewCreateInfo colorAttachmentViewParams =
972 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
973 DE_NULL, // const void* pNext;
974 0u, // VkImageViewCreateFlags flags;
975 *m_colorImage, // VkImage image;
976 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
977 m_colorFormat, // VkFormat format;
978 componentMappingRGBA, // VkComponentMapping components;
979 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
982 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
985 // Create render pass
987 const VkAttachmentDescription colorAttachmentDescription =
989 0u, // VkAttachmentDescriptionFlags flags;
990 m_colorFormat, // VkFormat format;
991 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
992 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
993 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
994 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
995 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
996 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
997 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
1000 const VkAttachmentReference colorAttachmentReference =
1002 0u, // deUint32 attachment;
1003 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
1006 const VkSubpassDescription subpassDescription =
1008 0u, // VkSubpassDescriptionFlags flags;
1009 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1010 0u, // deUint32 inputAttachmentCount;
1011 DE_NULL, // const VkAttachmentReference* pInputAttachments;
1012 1u, // deUint32 colorAttachmentCount;
1013 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
1014 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
1015 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
1016 0u, // deUint32 preserveAttachmentCount;
1017 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
1020 const VkRenderPassCreateInfo renderPassParams =
1022 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1023 DE_NULL, // const void* pNext;
1024 0u, // VkRenderPassCreateFlags flags;
1025 1u, // deUint32 attachmentCount;
1026 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
1027 1u, // deUint32 subpassCount;
1028 &subpassDescription, // const VkSubpassDescription* pSubpasses;
1029 0u, // deUint32 dependencyCount;
1030 DE_NULL // const VkSubpassDependency* pDependencies;
1033 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1036 // Create framebuffer
1038 const VkFramebufferCreateInfo framebufferParams =
1040 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1041 DE_NULL, // const void* pNext;
1042 0u, // VkFramebufferCreateFlags flags;
1043 *m_renderPass, // VkRenderPass renderPass;
1044 1u, // deUint32 attachmentCount;
1045 &m_colorAttachmentView.get(), // const VkImageView* pAttachments;
1046 (deUint32)m_renderSize.x(), // deUint32 width;
1047 (deUint32)m_renderSize.y(), // deUint32 height;
1048 1u // deUint32 layers;
1051 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1054 // Create pipeline layout
1056 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1058 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1059 DE_NULL, // const void* pNext;
1060 0u, // VkPipelineLayoutCreateFlags flags;
1061 0u, // deUint32 setLayoutCount;
1062 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
1063 0u, // deUint32 pushConstantRangeCount;
1064 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1067 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1070 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
1071 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
1075 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1078 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1079 DE_NULL, // const void* pNext;
1080 0u, // VkPipelineShaderStageCreateFlags flags;
1081 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
1082 *m_vertexShaderModule, // VkShaderModule module;
1083 "main", // const char* pName;
1084 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1087 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1088 DE_NULL, // const void* pNext;
1089 0u, // VkPipelineShaderStageCreateFlags flags;
1090 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
1091 *m_fragmentShaderModule, // VkShaderModule module;
1092 "main", // const char* pName;
1093 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1097 const VkVertexInputBindingDescription vertexInputBindingDescription =
1099 0u, // deUint32 binding;
1100 sizeof(Vertex4RGBA), // deUint32 stride;
1101 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
1104 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1107 0u, // deUint32 location;
1108 0u, // deUint32 binding;
1109 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1110 0u // deUint32 offset;
1113 1u, // deUint32 location;
1114 0u, // deUint32 binding;
1115 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1116 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset;
1120 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1122 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1123 DE_NULL, // const void* pNext;
1124 0u, // VkPipelineVertexInputStateCreateFlags flags;
1125 1u, // deUint32 vertexBindingDescriptionCount;
1126 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1127 2u, // deUint32 vertexAttributeDescriptionCount;
1128 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1131 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1133 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1134 DE_NULL, // const void* pNext;
1135 0u, // VkPipelineInputAssemblyStateCreateFlags flags;
1136 m_primitiveTopology, // VkPrimitiveTopology topology;
1137 m_primitiveRestartEnable // VkBool32 primitiveRestartEnable;
1140 const VkViewport viewport =
1144 (float)m_renderSize.x(), // float width;
1145 (float)m_renderSize.y(), // float height;
1146 0.0f, // float minDepth;
1147 1.0f // float maxDepth;
1150 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } };
1152 const VkPipelineViewportStateCreateInfo viewportStateParams =
1154 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1155 DE_NULL, // const void* pNext;
1156 0u, // VkPipelineViewportStateCreateFlags flags;
1157 1u, // deUint32 viewportCount;
1158 &viewport, // const VkViewport* pViewports;
1159 1u, // deUint32 scissorCount;
1160 &scissor, // const VkRect2D* pScissors;
1163 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1165 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1166 DE_NULL, // const void* pNext;
1167 0u, // VkPipelineRasterizationStateCreateFlags flags;
1168 false, // VkBool32 depthClampEnable;
1169 false, // VkBool32 rasterizerDiscardEnable;
1170 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1171 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1172 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1173 VK_FALSE, // VkBool32 depthBiasEnable;
1174 0.0f, // float depthBiasConstantFactor;
1175 0.0f, // float depthBiasClamp;
1176 0.0f, // float depthBiasSlopeFactor;
1177 1.0f // float lineWidth;
1180 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1182 false, // VkBool32 blendEnable;
1183 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
1184 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
1185 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
1186 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
1187 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
1188 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
1189 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask;
1190 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
1193 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1195 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1196 DE_NULL, // const void* pNext;
1197 0u, // VkPipelineColorBlendStateCreateFlags flags;
1198 false, // VkBool32 logicOpEnable;
1199 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1200 1u, // deUint32 attachmentCount;
1201 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1202 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
1205 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1207 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1208 DE_NULL, // const void* pNext;
1209 0u, // VkPipelineMultisampleStateCreateFlags flags;
1210 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1211 false, // VkBool32 sampleShadingEnable;
1212 0.0f, // float minSampleShading;
1213 DE_NULL, // const VkSampleMask* pSampleMask;
1214 false, // VkBool32 alphaToCoverageEnable;
1215 false // VkBool32 alphaToOneEnable;
1218 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
1220 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
1221 DE_NULL, // const void* pNext;
1222 0u, // VkPipelineDepthStencilStateCreateFlags flags;
1223 false, // VkBool32 depthTestEnable;
1224 false, // VkBool32 depthWriteEnable;
1225 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
1226 false, // VkBool32 depthBoundsTestEnable;
1227 false, // VkBool32 stencilTestEnable;
1228 // VkStencilOpState front;
1230 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
1231 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
1232 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
1233 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
1234 0u, // deUint32 compareMask;
1235 0u, // deUint32 writeMask;
1236 0u, // deUint32 reference;
1238 // VkStencilOpState back;
1240 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
1241 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
1242 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
1243 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
1244 0u, // deUint32 compareMask;
1245 0u, // deUint32 writeMask;
1246 0u, // deUint32 reference;
1248 -1.0f, // float minDepthBounds;
1249 +1.0f // float maxDepthBounds;
1252 const VkPipelineDynamicStateCreateInfo dynamicStateParams =
1254 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1255 DE_NULL, // const void* pNext;
1256 0u, // VkPipelineDynamicStateCreateFlags flags;
1257 0u, // deUint32 dynamicStateCount;
1258 DE_NULL // const VkDynamicState* pDynamicStates;
1261 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1263 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1264 DE_NULL, // const void* pNext;
1265 0u, // VkPipelineCreateFlags flags;
1266 2u, // deUint32 stageCount;
1267 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
1268 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1269 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1270 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1271 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1272 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
1273 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1274 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1275 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1276 &dynamicStateParams, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1277 *m_pipelineLayout, // VkPipelineLayout layout;
1278 *m_renderPass, // VkRenderPass renderPass;
1279 0u, // deUint32 subpass;
1280 0u, // VkPipeline basePipelineHandle;
1281 0u // deInt32 basePipelineIndex;
1284 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1287 // Create vertex and index buffer
1289 const VkBufferCreateInfo indexBufferParams =
1291 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1292 DE_NULL, // const void* pNext;
1293 0u, // VkBufferCreateFlags flags;
1294 m_indices.size() * sizeof(deUint32), // VkDeviceSize size;
1295 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1296 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1297 1u, // deUint32 queueFamilyIndexCount;
1298 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1301 const VkBufferCreateInfo vertexBufferParams =
1303 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1304 DE_NULL, // const void* pNext;
1305 0u, // VkBufferCreateFlags flags;
1306 m_vertices.size() * sizeof(Vertex4RGBA), // VkDeviceSize size;
1307 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1308 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1309 1u, // deUint32 queueFamilyIndexCount;
1310 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1313 m_indexBuffer = createBuffer(vk, vkDevice, &indexBufferParams);
1314 m_indexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indexBuffer), MemoryRequirement::HostVisible);
1316 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indexBuffer, m_indexBufferAlloc->getMemory(), m_indexBufferAlloc->getOffset()));
1318 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
1319 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
1321 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
1323 // Load vertices into index buffer
1324 if (m_indexType == VK_INDEX_TYPE_UINT32)
1326 deMemcpy(m_indexBufferAlloc->getHostPtr(), m_indices.data(), m_indices.size() * sizeof(deUint32));
1328 else // m_indexType == VK_INDEX_TYPE_UINT16
1330 uploadIndexBufferData16((deUint16*)m_indexBufferAlloc->getHostPtr(), m_indices);
1333 // Load vertices into vertex buffer
1334 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
1337 const VkMappedMemoryRange flushMemoryRanges[] =
1340 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1341 DE_NULL, // const void* pNext;
1342 m_indexBufferAlloc->getMemory(), // VkDeviceMemory memory;
1343 m_indexBufferAlloc->getOffset(), // VkDeviceSize offset;
1344 indexBufferParams.size // VkDeviceSize size;
1347 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1348 DE_NULL, // const void* pNext;
1349 m_vertexBufferAlloc->getMemory(), // VkDeviceMemory memory;
1350 m_vertexBufferAlloc->getOffset(), // VkDeviceSize offset;
1351 vertexBufferParams.size // VkDeviceSize size;
1355 vk.flushMappedMemoryRanges(vkDevice, 2, flushMemoryRanges);
1358 // Create command pool
1360 const VkCommandPoolCreateInfo cmdPoolParams =
1362 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1363 DE_NULL, // const void* pNext;
1364 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
1365 queueFamilyIndex // deUint32 queueFamilyIndex;
1368 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1371 // Create command buffer
1373 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
1375 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1376 DE_NULL, // const void* pNext;
1377 *m_cmdPool, // VkCommandPool commandPool;
1378 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
1379 1u // deUint32 bufferCount;
1382 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1384 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1385 DE_NULL, // const void* pNext;
1386 0u, // VkCommandBufferUsageFlags flags;
1387 DE_NULL, // VkRenderPass renderPass;
1388 0u, // deUint32 subpass;
1389 DE_NULL, // VkFramebuffer framebuffer;
1390 false, // VkBool32 occlusionQueryEnable;
1391 0u, // VkQueryControlFlags queryFlags;
1392 0u // VkQueryPipelineStatisticFlags pipelineStatistics;
1395 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
1397 const VkRenderPassBeginInfo renderPassBeginInfo =
1399 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1400 DE_NULL, // const void* pNext;
1401 *m_renderPass, // VkRenderPass renderPass;
1402 *m_framebuffer, // VkFramebuffer framebuffer;
1403 { { 0, 0 } , { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea;
1404 1u, // deUint32 clearValueCount;
1405 &attachmentClearValue // const VkClearValue* pClearValues;
1408 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
1410 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1411 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1413 const VkDeviceSize vertexBufferOffset = 0;
1415 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1416 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1417 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indexBuffer, 0, m_indexType);
1418 vk.cmdDrawIndexed(*m_cmdBuffer, (deUint32)m_indices.size(), 1, 0, 0, 0);
1420 vk.cmdEndRenderPass(*m_cmdBuffer);
1421 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1426 const VkFenceCreateInfo fenceParams =
1428 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1429 DE_NULL, // const void* pNext;
1430 0u // VkFenceCreateFlags flags;
1433 m_fence = createFence(vk, vkDevice, &fenceParams);
1437 InputAssemblyInstance::~InputAssemblyInstance (void)
1441 tcu::TestStatus InputAssemblyInstance::iterate (void)
1443 const DeviceInterface& vk = m_context.getDeviceInterface();
1444 const VkDevice vkDevice = m_context.getDevice();
1445 const VkQueue queue = m_context.getUniversalQueue();
1446 const VkSubmitInfo submitInfo =
1448 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1449 DE_NULL, // const void* pNext;
1450 0u, // deUint32 waitSemaphoreCount;
1451 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1452 1u, // deUint32 commandBufferCount;
1453 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1454 0u, // deUint32 signalSemaphoreCount;
1455 DE_NULL // const VkSemaphore* pSignalSemaphores;
1458 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1459 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1460 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1462 return verifyImage();
1465 tcu::TestStatus InputAssemblyInstance::verifyImage (void)
1467 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
1468 const tcu::TextureFormat tcuStencilFormat = tcu::TextureFormat();
1469 const ColorVertexShader vertexShader;
1470 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuStencilFormat);
1471 const rr::Program program (&vertexShader, &fragmentShader);
1472 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuStencilFormat, &program);
1473 bool compareOk = false;
1475 // Render reference image
1477 const rr::PrimitiveType topology = mapVkPrimitiveTopology(m_primitiveTopology);
1478 rr::RenderState renderState (refRenderer.getViewportState());
1480 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
1481 renderState.point.pointSize = 3.0f;
1483 if (m_primitiveRestartEnable)
1485 std::vector<deUint32> indicesRange;
1487 for (size_t indexNdx = 0; indexNdx < m_indices.size(); indexNdx++)
1489 const bool isRestart = InputAssemblyTest::isRestartIndex(m_indexType, m_indices[indexNdx]);
1492 indicesRange.push_back(m_indices[indexNdx]);
1494 if (isRestart || indexNdx == (m_indices.size() - 1))
1496 // Draw the range of indices found so far
1498 std::vector<Vertex4RGBA> nonIndexedVertices;
1499 for (size_t i = 0; i < indicesRange.size(); i++)
1500 nonIndexedVertices.push_back(m_vertices[indicesRange[i]]);
1502 refRenderer.draw(renderState, topology, nonIndexedVertices);
1503 indicesRange.clear();
1509 std::vector<Vertex4RGBA> nonIndexedVertices;
1510 for (size_t i = 0; i < m_indices.size(); i++)
1511 nonIndexedVertices.push_back(m_vertices[m_indices[i]]);
1513 refRenderer.draw(renderState, topology, nonIndexedVertices);
1517 // Compare result with reference image
1519 const DeviceInterface& vk = m_context.getDeviceInterface();
1520 const VkDevice vkDevice = m_context.getDevice();
1521 const VkQueue queue = m_context.getUniversalQueue();
1522 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1523 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1524 de::UniquePtr<tcu::TextureLevel> result (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
1526 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1529 refRenderer.getAccess(),
1530 result->getAccess(),
1531 tcu::UVec4(2, 2, 2, 2),
1532 tcu::IVec3(1, 1, 0),
1534 tcu::COMPARE_LOG_RESULT);
1538 return tcu::TestStatus::pass("Result image matches reference");
1540 return tcu::TestStatus::fail("Image mismatch");
1543 void InputAssemblyInstance::uploadIndexBufferData16 (deUint16* destPtr, const std::vector<deUint32>& indexBufferData)
1545 for (size_t i = 0; i < indexBufferData.size(); i++)
1547 DE_ASSERT(indexBufferData[i] <= 0xFFFF);
1548 destPtr[i] = (deUint16)indexBufferData[i];
1553 // Utilities for test names
1555 std::string getPrimitiveTopologyCaseName (VkPrimitiveTopology topology)
1557 const std::string fullName = getPrimitiveTopologyName(topology);
1559 DE_ASSERT(de::beginsWith(fullName, "VK_PRIMITIVE_TOPOLOGY_"));
1561 return de::toLower(fullName.substr(22));
1564 de::MovePtr<tcu::TestCaseGroup> createPrimitiveTopologyTests (tcu::TestContext& testCtx)
1566 de::MovePtr<tcu::TestCaseGroup> primitiveTopologyTests (new tcu::TestCaseGroup(testCtx, "primitive_topology", ""));
1568 for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(InputAssemblyTest::s_primitiveTopologies); topologyNdx++)
1570 const VkPrimitiveTopology topology = InputAssemblyTest::s_primitiveTopologies[topologyNdx];
1572 primitiveTopologyTests->addChild(new PrimitiveTopologyTest(testCtx,
1573 getPrimitiveTopologyCaseName(topology),
1578 return primitiveTopologyTests;
1581 de::MovePtr<tcu::TestCaseGroup> createPrimitiveRestartTests (tcu::TestContext& testCtx)
1583 const VkPrimitiveTopology primitiveRestartTopologies[] =
1585 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
1586 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
1587 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
1588 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
1589 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY
1592 de::MovePtr<tcu::TestCaseGroup> primitiveRestartTests (new tcu::TestCaseGroup(testCtx, "primitive_restart", "Restarts indices of "));
1594 de::MovePtr<tcu::TestCaseGroup> indexUint16Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint16", ""));
1595 de::MovePtr<tcu::TestCaseGroup> indexUint32Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint32", ""));
1597 for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(primitiveRestartTopologies); topologyNdx++)
1599 const VkPrimitiveTopology topology = primitiveRestartTopologies[topologyNdx];
1601 indexUint16Tests->addChild(new PrimitiveRestartTest(testCtx,
1602 getPrimitiveTopologyCaseName(topology),
1605 VK_INDEX_TYPE_UINT16));
1607 indexUint32Tests->addChild(new PrimitiveRestartTest(testCtx,
1608 getPrimitiveTopologyCaseName(topology),
1611 VK_INDEX_TYPE_UINT32));
1614 primitiveRestartTests->addChild(indexUint16Tests.release());
1615 primitiveRestartTests->addChild(indexUint32Tests.release());
1617 return primitiveRestartTests;
1622 tcu::TestCaseGroup* createInputAssemblyTests (tcu::TestContext& testCtx)
1624 de::MovePtr<tcu::TestCaseGroup> inputAssemblyTests (new tcu::TestCaseGroup(testCtx, "input_assembly", "Input assembly tests"));
1626 inputAssemblyTests->addChild(createPrimitiveTopologyTests(testCtx).release());
1627 inputAssemblyTests->addChild(createPrimitiveRestartTests(testCtx).release());
1629 return inputAssemblyTests.release();