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