1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Input Assembly Tests
23 *//*--------------------------------------------------------------------*/
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"
36 #include "vkRefUtil.hpp"
37 #include "tcuImageCompare.hpp"
40 #include "deRandom.hpp"
41 #include "deStringUtil.hpp"
42 #include "deUniquePtr.hpp"
58 class InputAssemblyTest : public vkt::TestCase
61 const static VkPrimitiveTopology s_primitiveTopologies[];
62 const static deUint32 s_restartIndex32;
63 const static deUint16 s_restartIndex16;
65 InputAssemblyTest (tcu::TestContext& testContext,
66 const std::string& name,
67 const std::string& description,
68 VkPrimitiveTopology primitiveTopology,
70 bool testPrimitiveRestart,
71 VkIndexType indexType);
72 virtual ~InputAssemblyTest (void) {}
73 virtual void initPrograms (SourceCollections& sourceCollections) const;
74 virtual TestInstance* createInstance (Context& context) const;
75 static bool isRestartIndex (VkIndexType indexType, deUint32 indexValue);
76 static deUint32 getRestartIndex (VkIndexType indexType);
79 virtual void createBufferData (VkPrimitiveTopology topology,
81 VkIndexType indexType,
82 std::vector<deUint32>& indexData,
83 std::vector<Vertex4RGBA>& vertexData) const = 0;
86 VkPrimitiveTopology m_primitiveTopology;
87 const int m_primitiveCount;
88 bool m_testPrimitiveRestart;
89 VkIndexType m_indexType;
92 class PrimitiveTopologyTest : public InputAssemblyTest
95 PrimitiveTopologyTest (tcu::TestContext& testContext,
96 const std::string& name,
97 const std::string& description,
98 VkPrimitiveTopology primitiveTopology);
99 virtual ~PrimitiveTopologyTest (void) {}
102 virtual void createBufferData (VkPrimitiveTopology topology,
104 VkIndexType indexType,
105 std::vector<deUint32>& indexData,
106 std::vector<Vertex4RGBA>& vertexData) const;
111 class PrimitiveRestartTest : public InputAssemblyTest
114 PrimitiveRestartTest (tcu::TestContext& testContext,
115 const std::string& name,
116 const std::string& description,
117 VkPrimitiveTopology primitiveTopology,
118 VkIndexType indexType);
119 virtual ~PrimitiveRestartTest (void) {}
122 virtual void createBufferData (VkPrimitiveTopology topology,
124 VkIndexType indexType,
125 std::vector<deUint32>& indexData,
126 std::vector<Vertex4RGBA>& vertexData) const;
129 bool isRestartPrimitive (int primitiveIndex) const;
131 std::vector<deUint32> m_restartPrimitives;
134 class InputAssemblyInstance : public vkt::TestInstance
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);
147 tcu::TestStatus verifyImage (void);
148 void uploadIndexBufferData16 (deUint16* destPtr, const std::vector<deUint32>& indexBufferData);
150 VkPrimitiveTopology m_primitiveTopology;
151 bool m_primitiveRestartEnable;
152 VkIndexType m_indexType;
154 Move<VkBuffer> m_vertexBuffer;
155 std::vector<Vertex4RGBA> m_vertices;
156 de::MovePtr<Allocation> m_vertexBufferAlloc;
158 Move<VkBuffer> m_indexBuffer;
159 std::vector<deUint32> m_indices;
160 de::MovePtr<Allocation> m_indexBufferAlloc;
162 const tcu::UVec2 m_renderSize;
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;
172 Move<VkShaderModule> m_vertexShaderModule;
173 Move<VkShaderModule> m_fragmentShaderModule;
175 Move<VkPipelineLayout> m_pipelineLayout;
176 Move<VkPipeline> m_graphicsPipeline;
178 Move<VkCommandPool> m_cmdPool;
179 Move<VkCommandBuffer> m_cmdBuffer;
181 Move<VkFence> m_fence;
187 const VkPrimitiveTopology InputAssemblyTest::s_primitiveTopologies[] =
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
201 const deUint32 InputAssemblyTest::s_restartIndex32 = ~((deUint32)0u);
202 const deUint16 InputAssemblyTest::s_restartIndex16 = ~((deUint16)0u);
204 InputAssemblyTest::InputAssemblyTest (tcu::TestContext& testContext,
205 const std::string& name,
206 const std::string& description,
207 VkPrimitiveTopology primitiveTopology,
209 bool testPrimitiveRestart,
210 VkIndexType indexType)
212 : vkt::TestCase (testContext, name, description)
213 , m_primitiveTopology (primitiveTopology)
214 , m_primitiveCount (primitiveCount)
215 , m_testPrimitiveRestart (testPrimitiveRestart)
216 , m_indexType (indexType)
220 TestInstance* InputAssemblyTest::createInstance (Context& context) const
222 std::vector<deUint32> indexBufferData;
223 std::vector<Vertex4RGBA> vertexBufferData;
225 createBufferData(m_primitiveTopology, m_primitiveCount, m_indexType, indexBufferData, vertexBufferData);
227 return new InputAssemblyInstance(context, m_primitiveTopology, m_testPrimitiveRestart, m_indexType, indexBufferData, vertexBufferData);
230 void InputAssemblyTest::initPrograms (SourceCollections& sourceCollections) const
232 std::ostringstream vertexSource;
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"
241 " gl_Position = position;\n"
242 << (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST ? " gl_PointSize = 3.0;\n"
244 << " vtxColor = color;\n"
247 sourceCollections.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
249 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
251 "layout(location = 0) in highp vec4 vtxColor;\n"
252 "layout(location = 0) out highp vec4 fragColor;\n"
255 " fragColor = vtxColor;\n"
259 bool InputAssemblyTest::isRestartIndex (VkIndexType indexType, deUint32 indexValue)
261 if (indexType == VK_INDEX_TYPE_UINT32)
262 return indexValue == s_restartIndex32;
264 return indexValue == s_restartIndex16;
267 deUint32 InputAssemblyTest::getRestartIndex (VkIndexType indexType)
269 if (indexType == VK_INDEX_TYPE_UINT16)
270 return InputAssemblyTest::s_restartIndex16;
272 return InputAssemblyTest::s_restartIndex32;
276 // PrimitiveTopologyTest
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)
286 void PrimitiveTopologyTest::createBufferData (VkPrimitiveTopology topology, int primitiveCount, VkIndexType indexType, std::vector<deUint32>& indexData, std::vector<Vertex4RGBA>& vertexData) const
288 DE_ASSERT(primitiveCount > 0);
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;
303 // Calculate primitive size
306 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
307 primitiveSizeX = (2.0f - 2.0f * border) / float(primitiveCount / 2 + primitiveCount % 2 - 1);
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);
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);
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);
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);
330 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
331 primitiveSizeX = 1.0f - border;
332 primitiveSizeY = 1.0f - border;
336 primitiveSizeX = 0.0f; // Garbage
342 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
343 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
345 const Vertex4RGBA vertex =
347 tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
351 vertices.push_back(vertex);
352 indices.push_back(primitiveNdx);
356 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
357 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
359 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
361 const Vertex4RGBA vertex =
363 tcu::Vec4(originX + float((primitiveNdx * 2 + vertexNdx) / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
367 vertices.push_back(vertex);
368 indices.push_back((primitiveNdx * 2 + vertexNdx));
373 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
374 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
376 if (primitiveNdx == 0)
380 tcu::Vec4(originX, originY, 0.0f, 1.0f),
384 vertices.push_back(vertex);
385 indices.push_back(0);
387 vertex.position = tcu::Vec4(originX, originY + primitiveSizeY, 0.0f, 1.0f);
388 vertices.push_back(vertex);
389 indices.push_back(1);
393 const Vertex4RGBA vertex =
395 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
399 vertices.push_back(vertex);
400 indices.push_back(primitiveNdx + 1);
405 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
406 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
408 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
410 const Vertex4RGBA vertex =
412 tcu::Vec4(originX + float((primitiveNdx * 3 + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx * 3 + vertexNdx)% 2) * primitiveSizeY, 0.0f, 1.0f),
416 vertices.push_back(vertex);
417 indices.push_back(primitiveNdx * 3 + vertexNdx);
422 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
423 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
425 if (primitiveNdx == 0)
427 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
429 const Vertex4RGBA vertex =
431 tcu::Vec4(originX + float(vertexNdx / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
435 vertices.push_back(vertex);
436 indices.push_back(vertexNdx);
441 const Vertex4RGBA vertex =
443 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
447 vertices.push_back(vertex);
448 indices.push_back(primitiveNdx + 2);
453 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
455 const float stepAngle = de::min(DE_PI * 0.5f, (2 * DE_PI) / float(primitiveCount));
457 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
459 if (primitiveNdx == 0)
463 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
467 vertices.push_back(vertex);
468 indices.push_back(0);
470 vertex.position = tcu::Vec4(primitiveSizeX, 0.0f, 0.0f, 1.0f);
471 vertices.push_back(vertex);
472 indices.push_back(1);
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);
480 const Vertex4RGBA vertex =
482 tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx + 1)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx + 1)), 0.0f, 1.0f),
486 vertices.push_back(vertex);
487 indices.push_back(primitiveNdx + 2);
493 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
494 vertices.push_back(defaultVertex);
496 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
498 indices.push_back(0);
500 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
502 const Vertex4RGBA vertex =
504 tcu::Vec4(originX + float((primitiveNdx * 2 + vertexNdx) / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
508 vertices.push_back(vertex);
509 indices.push_back(primitiveNdx * 2 + vertexNdx + 1);
512 indices.push_back(0);
517 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
518 vertices.push_back(defaultVertex);
519 indices.push_back(0);
521 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
523 if (primitiveNdx == 0)
527 tcu::Vec4(originX, originY, 0.0f, 1.0f),
531 vertices.push_back(vertex);
532 indices.push_back(1);
534 vertex.position = tcu::Vec4(originX, originY + primitiveSizeY, 0.0f, 1.0f);
535 vertices.push_back(vertex);
536 indices.push_back(2);
540 const Vertex4RGBA vertex =
542 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
546 vertices.push_back(vertex);
547 indices.push_back(primitiveNdx + 2);
551 indices.push_back(0);
554 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
555 vertices.push_back(defaultVertex);
557 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
559 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
561 const Vertex4RGBA vertex =
563 tcu::Vec4(originX + float((primitiveNdx * 3 + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx * 3 + vertexNdx)% 2) * primitiveSizeY, 0.0f, 1.0f),
567 vertices.push_back(vertex);
568 indices.push_back(primitiveNdx * 3 + vertexNdx + 1);
569 indices.push_back(0);
574 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
575 vertices.push_back(defaultVertex);
577 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
579 if (primitiveNdx == 0)
581 for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
583 const Vertex4RGBA vertex =
585 tcu::Vec4(originX + float(vertexNdx / 2) * primitiveSizeX, originY + float(vertexNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
589 vertices.push_back(vertex);
590 indices.push_back(vertexNdx + 1);
591 indices.push_back(0);
596 const Vertex4RGBA vertex =
598 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
602 vertices.push_back(vertex);
603 indices.push_back(primitiveNdx + 2 + 1);
604 indices.push_back(0);
614 vertexData = vertices;
619 // PrimitiveRestartTest
621 PrimitiveRestartTest::PrimitiveRestartTest (tcu::TestContext& testContext,
622 const std::string& name,
623 const std::string& description,
624 VkPrimitiveTopology primitiveTopology,
625 VkIndexType indexType)
627 : InputAssemblyTest (testContext, name, description, primitiveTopology, 10, true, indexType)
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);
635 deUint32 restartPrimitives[] = { 1, 5 };
637 m_restartPrimitives = std::vector<deUint32>(restartPrimitives, restartPrimitives + sizeof(restartPrimitives) / sizeof(deUint32));
640 void PrimitiveRestartTest::createBufferData (VkPrimitiveTopology topology, int primitiveCount, VkIndexType indexType, std::vector<deUint32>& indexData, std::vector<Vertex4RGBA>& vertexData) const
642 DE_ASSERT(primitiveCount > 0);
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;
658 // Calculate primitive size
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);
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);
671 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
672 primitiveSizeX = 1.0f - border;
673 primitiveSizeY = 1.0f - border;
677 primitiveSizeX = 0.0f; // Garbage
683 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
684 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
686 if (isRestartPrimitive(primitiveNdx))
688 indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
689 primitiveStart = true;
695 const Vertex4RGBA vertex =
697 tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
701 vertices.push_back(vertex);
702 indices.push_back((deUint32)vertices.size() - 1);
704 primitiveStart = false;
707 const Vertex4RGBA vertex =
709 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
713 vertices.push_back(vertex);
714 indices.push_back((deUint32)vertices.size() - 1);
719 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
721 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
723 if (isRestartPrimitive(primitiveNdx))
725 indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
726 primitiveStart = true;
732 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
734 const Vertex4RGBA vertex =
736 tcu::Vec4(originX + float((primitiveNdx + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx + vertexNdx) % 2) * primitiveSizeY, 0.0f, 1.0f),
740 vertices.push_back(vertex);
741 indices.push_back((deUint32)vertices.size() - 1);
744 primitiveStart = false;
746 const Vertex4RGBA vertex =
748 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
752 vertices.push_back(vertex);
753 indices.push_back((deUint32)vertices.size() - 1);
759 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
761 const float stepAngle = de::min(DE_PI * 0.5f, (2 * DE_PI) / float(primitiveCount));
763 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
765 if (isRestartPrimitive(primitiveNdx))
767 indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
768 primitiveStart = true;
776 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
780 vertices.push_back(vertex);
781 indices.push_back((deUint32)vertices.size() - 1);
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);
787 primitiveStart = false;
790 const Vertex4RGBA vertex =
792 tcu::Vec4(primitiveSizeX * deFloatCos(stepAngle * float(primitiveNdx + 1)), primitiveSizeY * deFloatSin(stepAngle * float(primitiveNdx + 1)), 0.0f, 1.0f),
796 vertices.push_back(vertex);
797 indices.push_back((deUint32)vertices.size() - 1);
803 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
804 vertices.push_back(defaultVertex);
806 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
808 if (isRestartPrimitive(primitiveNdx))
810 indices.push_back(0);
811 indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
812 primitiveStart = true;
818 indices.push_back(0);
820 const Vertex4RGBA vertex =
822 tcu::Vec4(originX + float(primitiveNdx / 2) * primitiveSizeX, originY + float(primitiveNdx % 2) * primitiveSizeY, 0.0f, 1.0f),
826 vertices.push_back(vertex);
827 indices.push_back((deUint32)vertices.size() - 1);
829 primitiveStart = false;
832 const Vertex4RGBA vertex =
834 tcu::Vec4(originX + float((primitiveNdx + 1) / 2) * primitiveSizeX, originY + float((primitiveNdx + 1) % 2) * primitiveSizeY, 0.0f, 1.0f),
838 vertices.push_back(vertex);
839 indices.push_back((deUint32)vertices.size() - 1);
843 indices.push_back(0);
846 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
847 vertices.push_back(defaultVertex);
849 for (int primitiveNdx = 0; primitiveNdx < primitiveCount; primitiveNdx++)
851 if (isRestartPrimitive(primitiveNdx))
853 indices.push_back(InputAssemblyTest::getRestartIndex(indexType));
854 primitiveStart = true;
860 for (int vertexNdx = 0; vertexNdx < 2; vertexNdx++)
862 const Vertex4RGBA vertex =
864 tcu::Vec4(originX + float((primitiveNdx + vertexNdx) / 2) * primitiveSizeX, originY + float((primitiveNdx + vertexNdx) % 2) * primitiveSizeY, 0.0f, 1.0f),
868 vertices.push_back(vertex);
869 indices.push_back((deUint32)vertices.size() - 1);
870 indices.push_back(0);
873 primitiveStart = false;
876 const Vertex4RGBA vertex =
878 tcu::Vec4(originX + float((primitiveNdx + 2) / 2) * primitiveSizeX, originY + float((primitiveNdx + 2) % 2) * primitiveSizeY, 0.0f, 1.0f),
882 vertices.push_back(vertex);
883 indices.push_back((deUint32)vertices.size() - 1);
884 indices.push_back(0);
894 vertexData = vertices;
898 bool PrimitiveRestartTest::isRestartPrimitive (int primitiveIndex) const
900 return std::find(m_restartPrimitives.begin(), m_restartPrimitives.end(), primitiveIndex) != m_restartPrimitives.end();
904 // InputAssemblyInstance
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)
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)
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 };
928 switch (m_primitiveTopology)
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");
938 case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
939 if (!context.getDeviceFeatures().tessellationShader)
940 throw tcu::NotSupportedError("Tessellation shaders are not supported");
947 // Create color image
949 const VkImageCreateInfo colorImageParams =
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;
968 m_colorImageCreateInfo = colorImageParams;
969 m_colorImage = createImage(vk, vkDevice, &m_colorImageCreateInfo);
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()));
976 // Create color attachment view
978 const VkImageViewCreateInfo colorAttachmentViewParams =
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;
990 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
993 // Create render pass
995 const VkAttachmentDescription colorAttachmentDescription =
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;
1008 const VkAttachmentReference colorAttachmentReference =
1010 0u, // deUint32 attachment;
1011 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
1014 const VkSubpassDescription subpassDescription =
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;
1028 const VkRenderPassCreateInfo renderPassParams =
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;
1041 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1044 // Create framebuffer
1046 const VkFramebufferCreateInfo framebufferParams =
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;
1059 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1062 // Create pipeline layout
1064 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
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;
1075 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
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);
1083 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
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;
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;
1105 const VkVertexInputBindingDescription vertexInputBindingDescription =
1107 0u, // deUint32 binding;
1108 sizeof(Vertex4RGBA), // deUint32 stride;
1109 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
1112 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1115 0u, // deUint32 location;
1116 0u, // deUint32 binding;
1117 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1118 0u // deUint32 offset;
1121 1u, // deUint32 location;
1122 0u, // deUint32 binding;
1123 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1124 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset;
1128 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
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;
1139 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
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;
1148 const VkViewport viewport =
1152 (float)m_renderSize.x(), // float width;
1153 (float)m_renderSize.y(), // float height;
1154 0.0f, // float minDepth;
1155 1.0f // float maxDepth;
1158 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } };
1160 const VkPipelineViewportStateCreateInfo viewportStateParams =
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;
1171 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
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;
1188 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
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
1201 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
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];
1213 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
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;
1226 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
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;
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;
1246 // VkStencilOpState back;
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;
1256 0.0f, // float minDepthBounds;
1257 1.0f // float maxDepthBounds;
1260 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
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;
1283 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1286 // Create vertex and index buffer
1288 const VkBufferCreateInfo indexBufferParams =
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;
1300 const VkBufferCreateInfo vertexBufferParams =
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;
1312 m_indexBuffer = createBuffer(vk, vkDevice, &indexBufferParams);
1313 m_indexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indexBuffer), MemoryRequirement::HostVisible);
1315 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indexBuffer, m_indexBufferAlloc->getMemory(), m_indexBufferAlloc->getOffset()));
1317 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
1318 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
1320 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
1322 // Load vertices into index buffer
1323 if (m_indexType == VK_INDEX_TYPE_UINT32)
1325 deMemcpy(m_indexBufferAlloc->getHostPtr(), m_indices.data(), m_indices.size() * sizeof(deUint32));
1327 else // m_indexType == VK_INDEX_TYPE_UINT16
1329 uploadIndexBufferData16((deUint16*)m_indexBufferAlloc->getHostPtr(), m_indices);
1332 // Load vertices into vertex buffer
1333 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
1336 const VkMappedMemoryRange flushMemoryRanges[] =
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;
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;
1354 vk.flushMappedMemoryRanges(vkDevice, 2, flushMemoryRanges);
1357 // Create command pool
1358 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1360 // Create command buffer
1362 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1364 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1365 DE_NULL, // const void* pNext;
1366 0u, // VkCommandBufferUsageFlags flags;
1367 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1370 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
1372 const VkRenderPassBeginInfo renderPassBeginInfo =
1374 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1375 DE_NULL, // const void* pNext;
1376 *m_renderPass, // VkRenderPass renderPass;
1377 *m_framebuffer, // VkFramebuffer framebuffer;
1378 { { 0, 0 } , { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea;
1379 1u, // deUint32 clearValueCount;
1380 &attachmentClearValue // const VkClearValue* pClearValues;
1383 const VkImageMemoryBarrier attachmentLayoutBarrier =
1385 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1386 DE_NULL, // const void* pNext;
1387 0u, // VkAccessFlags srcAccessMask;
1388 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
1389 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1390 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
1391 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1392 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1393 *m_colorImage, // VkImage image;
1394 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
1397 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1399 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1401 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
1402 0u, DE_NULL, 0u, DE_NULL, 1u, &attachmentLayoutBarrier);
1404 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1406 const VkDeviceSize vertexBufferOffset = 0;
1408 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1409 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1410 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indexBuffer, 0, m_indexType);
1411 vk.cmdDrawIndexed(*m_cmdBuffer, (deUint32)m_indices.size(), 1, 0, 0, 0);
1413 vk.cmdEndRenderPass(*m_cmdBuffer);
1414 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1418 m_fence = createFence(vk, vkDevice);
1421 InputAssemblyInstance::~InputAssemblyInstance (void)
1425 tcu::TestStatus InputAssemblyInstance::iterate (void)
1427 const DeviceInterface& vk = m_context.getDeviceInterface();
1428 const VkDevice vkDevice = m_context.getDevice();
1429 const VkQueue queue = m_context.getUniversalQueue();
1430 const VkSubmitInfo submitInfo =
1432 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1433 DE_NULL, // const void* pNext;
1434 0u, // deUint32 waitSemaphoreCount;
1435 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1436 (const VkPipelineStageFlags*)DE_NULL,
1437 1u, // deUint32 commandBufferCount;
1438 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1439 0u, // deUint32 signalSemaphoreCount;
1440 DE_NULL // const VkSemaphore* pSignalSemaphores;
1443 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1444 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1445 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1447 return verifyImage();
1450 tcu::TestStatus InputAssemblyInstance::verifyImage (void)
1452 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
1453 const tcu::TextureFormat tcuStencilFormat = tcu::TextureFormat();
1454 const ColorVertexShader vertexShader;
1455 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuStencilFormat);
1456 const rr::Program program (&vertexShader, &fragmentShader);
1457 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuStencilFormat, &program);
1458 bool compareOk = false;
1460 // Render reference image
1462 const rr::PrimitiveType topology = mapVkPrimitiveTopology(m_primitiveTopology);
1463 rr::RenderState renderState (refRenderer.getViewportState());
1465 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
1466 renderState.point.pointSize = 3.0f;
1468 if (m_primitiveRestartEnable)
1470 std::vector<deUint32> indicesRange;
1472 for (size_t indexNdx = 0; indexNdx < m_indices.size(); indexNdx++)
1474 const bool isRestart = InputAssemblyTest::isRestartIndex(m_indexType, m_indices[indexNdx]);
1477 indicesRange.push_back(m_indices[indexNdx]);
1479 if (isRestart || indexNdx == (m_indices.size() - 1))
1481 // Draw the range of indices found so far
1483 std::vector<Vertex4RGBA> nonIndexedVertices;
1484 for (size_t i = 0; i < indicesRange.size(); i++)
1485 nonIndexedVertices.push_back(m_vertices[indicesRange[i]]);
1487 refRenderer.draw(renderState, topology, nonIndexedVertices);
1488 indicesRange.clear();
1494 std::vector<Vertex4RGBA> nonIndexedVertices;
1495 for (size_t i = 0; i < m_indices.size(); i++)
1496 nonIndexedVertices.push_back(m_vertices[m_indices[i]]);
1498 refRenderer.draw(renderState, topology, nonIndexedVertices);
1502 // Compare result with reference image
1504 const DeviceInterface& vk = m_context.getDeviceInterface();
1505 const VkDevice vkDevice = m_context.getDevice();
1506 const VkQueue queue = m_context.getUniversalQueue();
1507 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1508 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1509 de::UniquePtr<tcu::TextureLevel> result (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
1511 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1514 refRenderer.getAccess(),
1515 result->getAccess(),
1516 tcu::UVec4(2, 2, 2, 2),
1517 tcu::IVec3(1, 1, 0),
1519 tcu::COMPARE_LOG_RESULT);
1523 return tcu::TestStatus::pass("Result image matches reference");
1525 return tcu::TestStatus::fail("Image mismatch");
1528 void InputAssemblyInstance::uploadIndexBufferData16 (deUint16* destPtr, const std::vector<deUint32>& indexBufferData)
1530 for (size_t i = 0; i < indexBufferData.size(); i++)
1532 DE_ASSERT(indexBufferData[i] <= 0xFFFF);
1533 destPtr[i] = (deUint16)indexBufferData[i];
1538 // Utilities for test names
1540 std::string getPrimitiveTopologyCaseName (VkPrimitiveTopology topology)
1542 const std::string fullName = getPrimitiveTopologyName(topology);
1544 DE_ASSERT(de::beginsWith(fullName, "VK_PRIMITIVE_TOPOLOGY_"));
1546 return de::toLower(fullName.substr(22));
1549 de::MovePtr<tcu::TestCaseGroup> createPrimitiveTopologyTests (tcu::TestContext& testCtx)
1551 de::MovePtr<tcu::TestCaseGroup> primitiveTopologyTests (new tcu::TestCaseGroup(testCtx, "primitive_topology", ""));
1553 for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(InputAssemblyTest::s_primitiveTopologies); topologyNdx++)
1555 const VkPrimitiveTopology topology = InputAssemblyTest::s_primitiveTopologies[topologyNdx];
1557 primitiveTopologyTests->addChild(new PrimitiveTopologyTest(testCtx,
1558 getPrimitiveTopologyCaseName(topology),
1563 return primitiveTopologyTests;
1566 de::MovePtr<tcu::TestCaseGroup> createPrimitiveRestartTests (tcu::TestContext& testCtx)
1568 const VkPrimitiveTopology primitiveRestartTopologies[] =
1570 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
1571 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
1572 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
1573 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
1574 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY
1577 de::MovePtr<tcu::TestCaseGroup> primitiveRestartTests (new tcu::TestCaseGroup(testCtx, "primitive_restart", "Restarts indices of "));
1579 de::MovePtr<tcu::TestCaseGroup> indexUint16Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint16", ""));
1580 de::MovePtr<tcu::TestCaseGroup> indexUint32Tests (new tcu::TestCaseGroup(testCtx, "index_type_uint32", ""));
1582 for (int topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(primitiveRestartTopologies); topologyNdx++)
1584 const VkPrimitiveTopology topology = primitiveRestartTopologies[topologyNdx];
1586 indexUint16Tests->addChild(new PrimitiveRestartTest(testCtx,
1587 getPrimitiveTopologyCaseName(topology),
1590 VK_INDEX_TYPE_UINT16));
1592 indexUint32Tests->addChild(new PrimitiveRestartTest(testCtx,
1593 getPrimitiveTopologyCaseName(topology),
1596 VK_INDEX_TYPE_UINT32));
1599 primitiveRestartTests->addChild(indexUint16Tests.release());
1600 primitiveRestartTests->addChild(indexUint32Tests.release());
1602 return primitiveRestartTests;
1607 tcu::TestCaseGroup* createInputAssemblyTests (tcu::TestContext& testCtx)
1609 de::MovePtr<tcu::TestCaseGroup> inputAssemblyTests (new tcu::TestCaseGroup(testCtx, "input_assembly", "Input assembly tests"));
1611 inputAssemblyTests->addChild(createPrimitiveTopologyTests(testCtx).release());
1612 inputAssemblyTests->addChild(createPrimitiveRestartTests(testCtx).release());
1614 return inputAssemblyTests.release();