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 Vertex Input Tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktPipelineVertexInputTests.hpp" 26 #include "vktPipelineCombinationsIterator.hpp" 27 #include "vktPipelineClearUtil.hpp" 28 #include "vktPipelineImageUtil.hpp" 29 #include "vktPipelineVertexUtil.hpp" 30 #include "vktPipelineReferenceRenderer.hpp" 31 #include "vktTestCase.hpp" 32 #include "vktTestCaseUtil.hpp" 33 #include "vkImageUtil.hpp" 34 #include "vkMemUtil.hpp" 35 #include "vkPrograms.hpp" 36 #include "vkQueryUtil.hpp" 37 #include "vkRef.hpp" 38 #include "vkRefUtil.hpp" 39 #include "tcuFloat.hpp" 40 #include "tcuImageCompare.hpp" 41 #include "deFloat16.h" 42 #include "deMemory.h" 43 #include "deStringUtil.hpp" 44 #include "deUniquePtr.hpp" 45 46 #include <sstream> 47 #include <vector> 48 49 namespace vkt 50 { 51 namespace pipeline 52 { 53 54 using namespace vk; 55 56 namespace 57 { 58 59 bool isSupportedVertexFormat (Context& context, VkFormat format) 60 { 61 if (isVertexFormatDouble(format) && !context.getDeviceFeatures().shaderFloat64) 62 return false; 63 64 VkFormatProperties formatProps; 65 deMemset(&formatProps, 0, sizeof(VkFormatProperties)); 66 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), format, &formatProps); 67 68 return (formatProps.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) != 0u; 69 } 70 71 float getRepresentableDifferenceUnorm (VkFormat format) 72 { 73 DE_ASSERT(isVertexFormatUnorm(format) || isVertexFormatSRGB(format)); 74 75 return 1.0f / float((1 << (getVertexFormatComponentSize(format) * 8)) - 1); 76 } 77 78 float getRepresentableDifferenceSnorm (VkFormat format) 79 { 80 DE_ASSERT(isVertexFormatSnorm(format)); 81 82 return 1.0f / float((1 << (getVertexFormatComponentSize(format) * 8 - 1)) - 1); 83 } 84 85 deUint32 getNextMultipleOffset (deUint32 divisor, deUint32 value) 86 { 87 if (value % divisor == 0) 88 return 0; 89 else 90 return divisor - (value % divisor); 91 } 92 93 class VertexInputTest : public vkt::TestCase 94 { 95 public: 96 enum GlslType 97 { 98 GLSL_TYPE_INT, 99 GLSL_TYPE_IVEC2, 100 GLSL_TYPE_IVEC3, 101 GLSL_TYPE_IVEC4, 102 103 GLSL_TYPE_UINT, 104 GLSL_TYPE_UVEC2, 105 GLSL_TYPE_UVEC3, 106 GLSL_TYPE_UVEC4, 107 108 GLSL_TYPE_FLOAT, 109 GLSL_TYPE_VEC2, 110 GLSL_TYPE_VEC3, 111 GLSL_TYPE_VEC4, 112 GLSL_TYPE_MAT2, 113 GLSL_TYPE_MAT3, 114 GLSL_TYPE_MAT4, 115 116 GLSL_TYPE_DOUBLE, 117 GLSL_TYPE_DVEC2, 118 GLSL_TYPE_DVEC3, 119 GLSL_TYPE_DVEC4, 120 GLSL_TYPE_DMAT2, 121 GLSL_TYPE_DMAT3, 122 GLSL_TYPE_DMAT4, 123 124 GLSL_TYPE_COUNT 125 }; 126 127 enum GlslBasicType 128 { 129 GLSL_BASIC_TYPE_INT, 130 GLSL_BASIC_TYPE_UINT, 131 GLSL_BASIC_TYPE_FLOAT, 132 GLSL_BASIC_TYPE_DOUBLE 133 }; 134 135 enum BindingMapping 136 { 137 BINDING_MAPPING_ONE_TO_ONE, // Vertex input bindings will not contain data for more than one attribute. 138 BINDING_MAPPING_ONE_TO_MANY // Vertex input bindings can contain data for more than one attribute. 139 }; 140 141 struct AttributeInfo 142 { 143 GlslType glslType; 144 VkFormat vkType; 145 VkVertexInputRate inputRate; 146 }; 147 148 struct GlslTypeDescription 149 { 150 const char* name; 151 int vertexInputComponentCount; 152 int vertexInputCount; 153 GlslBasicType basicType; 154 }; 155 156 static const GlslTypeDescription s_glslTypeDescriptions[GLSL_TYPE_COUNT]; 157 158 VertexInputTest (tcu::TestContext& testContext, 159 const std::string& name, 160 const std::string& description, 161 const std::vector<AttributeInfo>& attributeInfos, 162 BindingMapping bindingMapping); 163 164 virtual ~VertexInputTest (void) {} 165 virtual void initPrograms (SourceCollections& programCollection) const; 166 virtual TestInstance* createInstance (Context& context) const; 167 static bool isCompatibleType (VkFormat format, GlslType glslType); 168 169 private: 170 std::string getGlslInputDeclarations (void) const; 171 std::string getGlslVertexCheck (void) const; 172 std::string getGlslAttributeConditions (const AttributeInfo& attributeInfo, deUint32 attributeIndex) const; 173 static tcu::Vec4 getFormatThreshold (VkFormat format); 174 175 const std::vector<AttributeInfo> m_attributeInfos; 176 const BindingMapping m_bindingMapping; 177 bool m_usesDoubleType; 178 }; 179 180 class GlslTypeCombinationsIterator : public CombinationsIterator< std::vector<VertexInputTest::GlslType> > 181 { 182 public: 183 GlslTypeCombinationsIterator (deUint32 numValues, deUint32 combinationSize); 184 virtual ~GlslTypeCombinationsIterator (void) {} 185 186 protected: 187 virtual std::vector<VertexInputTest::GlslType> getCombinationValue (const std::vector<deUint32>& combination); 188 189 private: 190 std::vector<VertexInputTest::GlslType> m_combinationValue; 191 }; 192 193 class VertexInputInstance : public vkt::TestInstance 194 { 195 public: 196 struct VertexInputAttributeDescription 197 { 198 VertexInputTest::GlslType glslType; 199 int vertexInputIndex; 200 VkVertexInputAttributeDescription vkDescription; 201 }; 202 203 typedef std::vector<VertexInputAttributeDescription> AttributeDescriptionList; 204 205 VertexInputInstance (Context& context, 206 const AttributeDescriptionList& attributeDescriptions, 207 const std::vector<VkVertexInputBindingDescription>& bindingDescriptions, 208 const std::vector<VkDeviceSize>& bindingOffsets); 209 210 virtual ~VertexInputInstance (void); 211 virtual tcu::TestStatus iterate (void); 212 213 214 static void writeVertexInputData (deUint8* destPtr, const VkVertexInputBindingDescription& bindingDescription, const VkDeviceSize bindingOffset, const AttributeDescriptionList& attributes); 215 static void writeVertexInputValue (deUint8* destPtr, const VertexInputAttributeDescription& attributes, int indexId); 216 217 private: 218 tcu::TestStatus verifyImage (void); 219 220 private: 221 std::vector<VkBuffer> m_vertexBuffers; 222 std::vector<Allocation*> m_vertexBufferAllocs; 223 224 const tcu::UVec2 m_renderSize; 225 const VkFormat m_colorFormat; 226 227 Move<VkImage> m_colorImage; 228 de::MovePtr<Allocation> m_colorImageAlloc; 229 Move<VkImage> m_depthImage; 230 Move<VkImageView> m_colorAttachmentView; 231 Move<VkRenderPass> m_renderPass; 232 Move<VkFramebuffer> m_framebuffer; 233 234 Move<VkShaderModule> m_vertexShaderModule; 235 Move<VkShaderModule> m_fragmentShaderModule; 236 237 Move<VkPipelineLayout> m_pipelineLayout; 238 Move<VkPipeline> m_graphicsPipeline; 239 240 Move<VkCommandPool> m_cmdPool; 241 Move<VkCommandBuffer> m_cmdBuffer; 242 243 Move<VkFence> m_fence; 244 }; 245 246 const VertexInputTest::GlslTypeDescription VertexInputTest::s_glslTypeDescriptions[GLSL_TYPE_COUNT] = 247 { 248 { "int", 1, 1, GLSL_BASIC_TYPE_INT }, 249 { "ivec2", 2, 1, GLSL_BASIC_TYPE_INT }, 250 { "ivec3", 3, 1, GLSL_BASIC_TYPE_INT }, 251 { "ivec4", 4, 1, GLSL_BASIC_TYPE_INT }, 252 253 { "uint", 1, 1, GLSL_BASIC_TYPE_UINT }, 254 { "uvec2", 2, 1, GLSL_BASIC_TYPE_UINT }, 255 { "uvec3", 3, 1, GLSL_BASIC_TYPE_UINT }, 256 { "uvec4", 4, 1, GLSL_BASIC_TYPE_UINT }, 257 258 { "float", 1, 1, GLSL_BASIC_TYPE_FLOAT }, 259 { "vec2", 2, 1, GLSL_BASIC_TYPE_FLOAT }, 260 { "vec3", 3, 1, GLSL_BASIC_TYPE_FLOAT }, 261 { "vec4", 4, 1, GLSL_BASIC_TYPE_FLOAT }, 262 { "mat2", 2, 2, GLSL_BASIC_TYPE_FLOAT }, 263 { "mat3", 3, 3, GLSL_BASIC_TYPE_FLOAT }, 264 { "mat4", 4, 4, GLSL_BASIC_TYPE_FLOAT }, 265 266 { "double", 1, 1, GLSL_BASIC_TYPE_DOUBLE }, 267 { "dvec2", 2, 1, GLSL_BASIC_TYPE_DOUBLE }, 268 { "dvec3", 3, 1, GLSL_BASIC_TYPE_DOUBLE }, 269 { "dvec4", 4, 1, GLSL_BASIC_TYPE_DOUBLE }, 270 { "dmat2", 2, 2, GLSL_BASIC_TYPE_DOUBLE }, 271 { "dmat3", 3, 3, GLSL_BASIC_TYPE_DOUBLE }, 272 { "dmat4", 4, 4, GLSL_BASIC_TYPE_DOUBLE } 273 }; 274 275 276 VertexInputTest::VertexInputTest (tcu::TestContext& testContext, 277 const std::string& name, 278 const std::string& description, 279 const std::vector<AttributeInfo>& attributeInfos, 280 BindingMapping bindingMapping) 281 282 : vkt::TestCase (testContext, name, description) 283 , m_attributeInfos (attributeInfos) 284 , m_bindingMapping (bindingMapping) 285 { 286 m_usesDoubleType = false; 287 288 for (size_t attributeNdx = 0; attributeNdx < m_attributeInfos.size(); attributeNdx++) 289 { 290 if (s_glslTypeDescriptions[m_attributeInfos[attributeNdx].glslType].basicType == GLSL_BASIC_TYPE_DOUBLE) 291 { 292 m_usesDoubleType = true; 293 break; 294 } 295 } 296 } 297 298 TestInstance* VertexInputTest::createInstance (Context& context) const 299 { 300 // Create enough binding descriptions with random offsets 301 std::vector<VkVertexInputBindingDescription> bindingDescriptions; 302 std::vector<VkDeviceSize> bindingOffsets; 303 304 for (size_t bindingNdx = 0; bindingNdx < m_attributeInfos.size() * 2; bindingNdx++) 305 { 306 // Use STEP_RATE_VERTEX in even bindings and STEP_RATE_INSTANCE in odd bindings 307 const VkVertexInputRate inputRate = (bindingNdx % 2 == 0) ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE; 308 309 // .strideInBytes will be updated when creating the attribute descriptions 310 const VkVertexInputBindingDescription bindingDescription = 311 { 312 (deUint32)bindingNdx, // deUint32 binding; 313 0, // deUint32 stride; 314 inputRate // VkVertexInputRate inputRate; 315 }; 316 317 bindingDescriptions.push_back(bindingDescription); 318 bindingOffsets.push_back(4 * bindingNdx); 319 } 320 321 // Create attribute descriptions, assign them to bindings and update .strideInBytes 322 std::vector<VertexInputInstance::VertexInputAttributeDescription> attributeDescriptions; 323 deUint32 attributeLocation = 0; 324 std::vector<deUint32> attributeOffsets (bindingDescriptions.size(), 0); 325 std::vector<deUint32> attributeMaxSizes (bindingDescriptions.size(), 0); 326 327 for (size_t attributeNdx = 0; attributeNdx < m_attributeInfos.size(); attributeNdx++) 328 { 329 const AttributeInfo& attributeInfo = m_attributeInfos[attributeNdx]; 330 const GlslTypeDescription& glslTypeDescription = s_glslTypeDescriptions[attributeInfo.glslType]; 331 const deUint32 inputSize = getVertexFormatSize(attributeInfo.vkType); 332 deUint32 attributeBinding; 333 334 if (m_bindingMapping == BINDING_MAPPING_ONE_TO_ONE) 335 { 336 if (attributeInfo.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) 337 { 338 attributeBinding = (deUint32)attributeNdx * 2; // Odd binding number 339 } 340 else // attributeInfo.inputRate == VK_VERTEX_INPUT_STEP_RATE_INSTANCE 341 { 342 attributeBinding = (deUint32)attributeNdx * 2 + 1; // Even binding number 343 } 344 } 345 else // m_bindingMapping == BINDING_MAPPING_ONE_TO_MANY 346 { 347 if (attributeInfo.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) 348 { 349 attributeBinding = 0; 350 } 351 else // attributeInfo.inputRate == VK_VERTEX_INPUT_STEP_RATE_INSTANCE 352 { 353 attributeBinding = 1; 354 } 355 } 356 357 for (int descNdx = 0; descNdx < glslTypeDescription.vertexInputCount; descNdx++) 358 { 359 const deUint32 offsetToComponentAlignment = getNextMultipleOffset(getVertexFormatComponentSize(attributeInfo.vkType), 360 (deUint32)bindingOffsets[attributeBinding] + attributeOffsets[attributeBinding]); 361 362 attributeOffsets[attributeBinding] += offsetToComponentAlignment; 363 364 const VertexInputInstance::VertexInputAttributeDescription attributeDescription = 365 { 366 attributeInfo.glslType, // GlslType glslType; 367 descNdx, // int index; 368 { 369 attributeLocation, // deUint32 location; 370 attributeBinding, // deUint32 binding; 371 attributeInfo.vkType, // VkFormat format; 372 attributeOffsets[attributeBinding], // deUint32 offset; 373 }, 374 }; 375 376 bindingDescriptions[attributeBinding].stride += offsetToComponentAlignment + inputSize; 377 attributeOffsets[attributeBinding] += inputSize; 378 attributeMaxSizes[attributeBinding] = de::max(attributeMaxSizes[attributeBinding], getVertexFormatComponentSize(attributeInfo.vkType)); 379 380 //double formats with more than 2 components will take 2 locations 381 const GlslType type = attributeInfo.glslType; 382 if ((type == GLSL_TYPE_DMAT2 || type == GLSL_TYPE_DMAT3 || type == GLSL_TYPE_DMAT4) && 383 (attributeInfo.vkType == VK_FORMAT_R64G64B64_SFLOAT || attributeInfo.vkType == VK_FORMAT_R64G64B64A64_SFLOAT)) 384 { 385 attributeLocation += 2; 386 } 387 else 388 attributeLocation++; 389 390 attributeDescriptions.push_back(attributeDescription); 391 } 392 } 393 394 // Make sure the stride results in aligned access 395 for (deUint32 bindingNdx = 0; bindingNdx < bindingDescriptions.size(); ++bindingNdx) 396 { 397 if (attributeMaxSizes[bindingNdx] > 0) 398 bindingDescriptions[bindingNdx].stride += getNextMultipleOffset(attributeMaxSizes[bindingNdx], bindingDescriptions[bindingNdx].stride); 399 } 400 401 return new VertexInputInstance(context, attributeDescriptions, bindingDescriptions, bindingOffsets); 402 } 403 404 void VertexInputTest::initPrograms (SourceCollections& programCollection) const 405 { 406 std::ostringstream vertexSrc; 407 408 vertexSrc << "#version 440\n" 409 << getGlslInputDeclarations() 410 << "layout(location = 0) out highp vec4 vtxColor;\n" 411 << "out gl_PerVertex {\n" 412 << " vec4 gl_Position;\n" 413 << "};\n"; 414 415 // NOTE: double abs(double x) undefined in glslang ?? 416 if (m_usesDoubleType) 417 vertexSrc << "double abs (double x) { if (x < 0.0LF) return -x; else return x; }\n"; 418 419 vertexSrc << "void main (void)\n" 420 << "{\n" 421 << getGlslVertexCheck() 422 << "}\n"; 423 424 programCollection.glslSources.add("attribute_test_vert") << glu::VertexSource(vertexSrc.str()); 425 426 programCollection.glslSources.add("attribute_test_frag") << glu::FragmentSource( 427 "#version 440\n" 428 "layout(location = 0) in highp vec4 vtxColor;\n" 429 "layout(location = 0) out highp vec4 fragColor;\n" 430 "void main (void)\n" 431 "{\n" 432 " fragColor = vtxColor;\n" 433 "}\n"); 434 } 435 436 std::string VertexInputTest::getGlslInputDeclarations (void) const 437 { 438 std::ostringstream glslInputs; 439 deUint32 location = 0; 440 441 for (size_t attributeNdx = 0; attributeNdx < m_attributeInfos.size(); attributeNdx++) 442 { 443 const GlslTypeDescription& glslTypeDesc = s_glslTypeDescriptions[m_attributeInfos[attributeNdx].glslType]; 444 445 glslInputs << "layout(location = " << location << ") in highp " << glslTypeDesc.name << " attr" << attributeNdx << ";\n"; 446 location += glslTypeDesc.vertexInputCount; 447 } 448 449 return glslInputs.str(); 450 } 451 452 std::string VertexInputTest::getGlslVertexCheck (void) const 453 { 454 std::ostringstream glslCode; 455 int totalInputComponentCount = 0; 456 457 458 glslCode << " int okCount = 0;\n"; 459 460 for (size_t attributeNdx = 0; attributeNdx < m_attributeInfos.size(); attributeNdx++) 461 { 462 glslCode << getGlslAttributeConditions(m_attributeInfos[attributeNdx], (deUint32)attributeNdx); 463 464 const int vertexInputCount = VertexInputTest::s_glslTypeDescriptions[m_attributeInfos[attributeNdx].glslType].vertexInputCount; 465 totalInputComponentCount += vertexInputCount * VertexInputTest::s_glslTypeDescriptions[m_attributeInfos[attributeNdx].glslType].vertexInputComponentCount; 466 } 467 468 glslCode << 469 " if (okCount == " << totalInputComponentCount << ")\n" 470 " {\n" 471 " if (gl_InstanceIndex == 0)\n" 472 " vtxColor = vec4(1.0, 0.0, 0.0, 1.0);\n" 473 " else\n" 474 " vtxColor = vec4(0.0, 0.0, 1.0, 1.0);\n" 475 " }\n" 476 " else\n" 477 " {\n" 478 " vtxColor = vec4(okCount / float(" << totalInputComponentCount << "), 0.0f, 0.0f, 1.0);\n" << 479 " }\n\n" 480 " if (gl_InstanceIndex == 0)\n" 481 " {\n" 482 " if (gl_VertexIndex == 0) gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 483 " else if (gl_VertexIndex == 1) gl_Position = vec4(0.0, -1.0, 0.0, 1.0);\n" 484 " else if (gl_VertexIndex == 2) gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 485 " else if (gl_VertexIndex == 3) gl_Position = vec4(0.0, 1.0, 0.0, 1.0);\n" 486 " else gl_Position = vec4(0.0);\n" 487 " }\n" 488 " else\n" 489 " {\n" 490 " if (gl_VertexIndex == 0) gl_Position = vec4(0.0, -1.0, 0.0, 1.0);\n" 491 " else if (gl_VertexIndex == 1) gl_Position = vec4(1.0, -1.0, 0.0, 1.0);\n" 492 " else if (gl_VertexIndex == 2) gl_Position = vec4(0.0, 1.0, 0.0, 1.0);\n" 493 " else if (gl_VertexIndex == 3) gl_Position = vec4(1.0, 1.0, 0.0, 1.0);\n" 494 " else gl_Position = vec4(0.0);\n" 495 " }\n"; 496 497 return glslCode.str(); 498 } 499 500 std::string VertexInputTest::getGlslAttributeConditions (const AttributeInfo& attributeInfo, deUint32 attributeIndex) const 501 { 502 std::ostringstream glslCode; 503 std::ostringstream attributeVar; 504 const std::string indexId = (attributeInfo.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) ? "gl_VertexIndex" : "gl_InstanceIndex"; 505 const int componentCount = VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].vertexInputComponentCount; 506 const int vertexInputCount = VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].vertexInputCount; 507 const deUint32 totalComponentCount = componentCount * vertexInputCount; 508 const tcu::Vec4 threshold = getFormatThreshold(attributeInfo.vkType); 509 deUint32 componentIndex = 0; 510 511 attributeVar << "attr" << attributeIndex; 512 513 glslCode << std::fixed; 514 515 for (int columnNdx = 0; columnNdx< vertexInputCount; columnNdx++) 516 { 517 for (int rowNdx = 0; rowNdx < componentCount; rowNdx++) 518 { 519 std::string accessStr; 520 { 521 // Build string representing the access to the attribute component 522 std::ostringstream accessStream; 523 accessStream << attributeVar.str(); 524 525 if (vertexInputCount == 1) 526 { 527 if (componentCount > 1) 528 accessStream << "[" << rowNdx << "]"; 529 } 530 else 531 { 532 accessStream << "[" << columnNdx << "][" << rowNdx << "]"; 533 } 534 535 accessStr = accessStream.str(); 536 } 537 538 if (isVertexFormatSint(attributeInfo.vkType)) 539 { 540 glslCode << "\tif (" << accessStr << " == -(" << totalComponentCount << " * " << indexId << " + " << componentIndex << "))\n"; 541 } 542 else if (isVertexFormatUint(attributeInfo.vkType)) 543 { 544 glslCode << "\tif (" << accessStr << " == uint(" << totalComponentCount << " * " << indexId << " + " << componentIndex << "))\n"; 545 } 546 else if (isVertexFormatSfloat(attributeInfo.vkType)) 547 { 548 if (VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].basicType == VertexInputTest::GLSL_BASIC_TYPE_DOUBLE) 549 { 550 glslCode << "\tif (abs(" << accessStr << " + double(0.01 * (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0))) < double(" << threshold[rowNdx] << "))\n"; 551 } 552 else 553 { 554 glslCode << "\tif (abs(" << accessStr << " + (0.01 * (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0))) < " << threshold[rowNdx] << ")\n"; 555 } 556 } 557 else if (isVertexFormatSscaled(attributeInfo.vkType)) 558 { 559 glslCode << "\tif (abs(" << accessStr << " + (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0)) < " << threshold[rowNdx] << ")\n"; 560 } 561 else if (isVertexFormatUscaled(attributeInfo.vkType)) 562 { 563 glslCode << "\t if (abs(" << accessStr << " - (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0)) < " << threshold[rowNdx] << ")\n"; 564 } 565 else if (isVertexFormatSnorm(attributeInfo.vkType)) 566 { 567 const float representableDiff = getRepresentableDifferenceSnorm(attributeInfo.vkType); 568 569 glslCode << "\tif (abs(" << accessStr << " - (-1.0 + " << representableDiff << " * (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0))) < " << threshold[rowNdx] << ")\n"; 570 } 571 else if (isVertexFormatUnorm(attributeInfo.vkType) || isVertexFormatSRGB(attributeInfo.vkType)) 572 { 573 const float representableDiff = getRepresentableDifferenceUnorm(attributeInfo.vkType); 574 575 glslCode << "\tif (abs(" << accessStr << " - " << "(" << representableDiff << " * (" << totalComponentCount << ".0 * float(" << indexId << ") + " << componentIndex << ".0))) < " << threshold[rowNdx] << ")\n"; 576 } 577 else 578 { 579 DE_ASSERT(false); 580 } 581 582 glslCode << "\t\tokCount++;\n\n"; 583 584 componentIndex++; 585 } 586 } 587 return glslCode.str(); 588 } 589 590 tcu::Vec4 VertexInputTest::getFormatThreshold (VkFormat format) 591 { 592 using tcu::Vec4; 593 594 switch (format) 595 { 596 case VK_FORMAT_R32_SFLOAT: 597 case VK_FORMAT_R32G32_SFLOAT: 598 case VK_FORMAT_R32G32B32_SFLOAT: 599 case VK_FORMAT_R32G32B32A32_SFLOAT: 600 case VK_FORMAT_R64_SFLOAT: 601 case VK_FORMAT_R64G64_SFLOAT: 602 case VK_FORMAT_R64G64B64_SFLOAT: 603 case VK_FORMAT_R64G64B64A64_SFLOAT: 604 return Vec4(0.00001f); 605 606 default: 607 break; 608 } 609 610 if (isVertexFormatSnorm(format)) 611 { 612 return Vec4(1.5f * getRepresentableDifferenceSnorm(format)); 613 } 614 else if (isVertexFormatUnorm(format)) 615 { 616 return Vec4(1.5f * getRepresentableDifferenceUnorm(format)); 617 } 618 619 return Vec4(0.001f); 620 } 621 622 GlslTypeCombinationsIterator::GlslTypeCombinationsIterator (deUint32 numValues, deUint32 combinationSize) 623 : CombinationsIterator< std::vector<VertexInputTest::GlslType> > (numValues, combinationSize) 624 , m_combinationValue (std::vector<VertexInputTest::GlslType>(combinationSize)) 625 { 626 DE_ASSERT(numValues <= VertexInputTest::GLSL_TYPE_COUNT); 627 } 628 629 std::vector<VertexInputTest::GlslType> GlslTypeCombinationsIterator::getCombinationValue (const std::vector<deUint32>& combination) 630 { 631 for (size_t combinationItemNdx = 0; combinationItemNdx < combination.size(); combinationItemNdx++) 632 m_combinationValue[combinationItemNdx] = (VertexInputTest::GlslType)combination[combinationItemNdx]; 633 634 return m_combinationValue; 635 } 636 637 VertexInputInstance::VertexInputInstance (Context& context, 638 const AttributeDescriptionList& attributeDescriptions, 639 const std::vector<VkVertexInputBindingDescription>& bindingDescriptions, 640 const std::vector<VkDeviceSize>& bindingOffsets) 641 : vkt::TestInstance (context) 642 , m_renderSize (16, 16) 643 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 644 { 645 DE_ASSERT(bindingDescriptions.size() == bindingOffsets.size()); 646 647 const DeviceInterface& vk = context.getDeviceInterface(); 648 const VkDevice vkDevice = context.getDevice(); 649 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 650 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())); 651 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 652 653 // Create color image 654 { 655 const VkImageCreateInfo colorImageParams = 656 { 657 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 658 DE_NULL, // const void* pNext; 659 0u, // VkImageCreateFlags flags; 660 VK_IMAGE_TYPE_2D, // VkImageType imageType; 661 m_colorFormat, // VkFormat format; 662 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 663 1u, // deUint32 mipLevels; 664 1u, // deUint32 arrayLayers; 665 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 666 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 667 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 668 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 669 1u, // deUint32 queueFamilyIndexCount; 670 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 671 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 672 }; 673 674 m_colorImage = createImage(vk, vkDevice, &colorImageParams); 675 676 // Allocate and bind color image memory 677 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 678 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 679 } 680 681 // Create color attachment view 682 { 683 const VkImageViewCreateInfo colorAttachmentViewParams = 684 { 685 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 686 DE_NULL, // const void* pNext; 687 0u, // VkImageViewCreateFlags flags; 688 *m_colorImage, // VkImage image; 689 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 690 m_colorFormat, // VkFormat format; 691 componentMappingRGBA, // VkComponentMapping components; 692 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 693 }; 694 695 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 696 } 697 698 // Create render pass 699 { 700 const VkAttachmentDescription colorAttachmentDescription = 701 { 702 0u, // VkAttachmentDescriptionFlags flags; 703 m_colorFormat, // VkFormat format; 704 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 705 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 706 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 707 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 708 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 709 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 710 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 711 }; 712 713 const VkAttachmentReference colorAttachmentReference = 714 { 715 0u, // deUint32 attachment; 716 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 717 }; 718 719 const VkSubpassDescription subpassDescription = 720 { 721 0u, // VkSubpassDescriptionFlags flags; 722 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 723 0u, // deUint32 inputAttachmentCount; 724 DE_NULL, // const VkAttachmentReference* pInputAttachments; 725 1u, // deUint32 colorAttachmentCount; 726 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 727 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 728 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 729 0u, // deUint32 preserveAttachmentCount; 730 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 731 }; 732 733 const VkRenderPassCreateInfo renderPassParams = 734 { 735 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 736 DE_NULL, // const void* pNext; 737 0u, // VkRenderPassCreateFlags flags; 738 1u, // deUint32 attachmentCount; 739 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments; 740 1u, // deUint32 subpassCount; 741 &subpassDescription, // const VkSubpassDescription* pSubpasses; 742 0u, // deUint32 dependencyCount; 743 DE_NULL // const VkSubpassDependency* pDependencies; 744 }; 745 746 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 747 } 748 749 // Create framebuffer 750 { 751 const VkFramebufferCreateInfo framebufferParams = 752 { 753 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 754 DE_NULL, // const void* pNext; 755 0u, // VkFramebufferCreateFlags flags; 756 *m_renderPass, // VkRenderPass renderPass; 757 1u, // deUint32 attachmentCount; 758 &m_colorAttachmentView.get(), // const VkImageView* pAttachments; 759 (deUint32)m_renderSize.x(), // deUint32 width; 760 (deUint32)m_renderSize.y(), // deUint32 height; 761 1u // deUint32 layers; 762 }; 763 764 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 765 } 766 767 // Create pipeline layout 768 { 769 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 770 { 771 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 772 DE_NULL, // const void* pNext; 773 0u, // VkPipelineLayoutCreateFlags flags; 774 0u, // deUint32 setLayoutCount; 775 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 776 0u, // deUint32 pushConstantRangeCount; 777 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 778 }; 779 780 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 781 } 782 783 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("attribute_test_vert"), 0); 784 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("attribute_test_frag"), 0); 785 786 787 // Create pipeline 788 { 789 const VkPipelineShaderStageCreateInfo shaderStageParams[2] = 790 { 791 { 792 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 793 DE_NULL, // const void* pNext; 794 0u, // VkPipelineShaderStageCreateFlags flags; 795 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 796 *m_vertexShaderModule, // VkShaderModule module; 797 "main", // const char* pName; 798 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 799 }, 800 { 801 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 802 DE_NULL, // const void* pNext; 803 0u, // VkPipelineShaderStageCreateFlags flags; 804 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 805 *m_fragmentShaderModule, // VkShaderModule module; 806 "main", // const char* pName; 807 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 808 } 809 }; 810 811 // Create vertex attribute array and check if their VK formats are supported 812 std::vector<VkVertexInputAttributeDescription> vkAttributeDescriptions; 813 for (size_t attributeNdx = 0; attributeNdx < attributeDescriptions.size(); attributeNdx++) 814 { 815 const VkVertexInputAttributeDescription& attributeDescription = attributeDescriptions[attributeNdx].vkDescription; 816 817 if (!isSupportedVertexFormat(context, attributeDescription.format)) 818 throw tcu::NotSupportedError(std::string("Unsupported format for vertex input: ") + getFormatName(attributeDescription.format)); 819 820 vkAttributeDescriptions.push_back(attributeDescription); 821 } 822 823 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 824 { 825 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 826 DE_NULL, // const void* pNext; 827 0u, // VkPipelineVertexInputStateCreateFlags flags; 828 (deUint32)bindingDescriptions.size(), // deUint32 vertexBindingDescriptionCount; 829 bindingDescriptions.data(), // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 830 (deUint32)vkAttributeDescriptions.size(), // deUint32 vertexAttributeDescriptionCount; 831 vkAttributeDescriptions.data() // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 832 }; 833 834 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 835 { 836 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 837 DE_NULL, // const void* pNext; 838 0u, // VkPipelineInputAssemblyStateCreateFlags flags; 839 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology; 840 false // VkBool32 primitiveRestartEnable; 841 }; 842 843 const VkViewport viewport = 844 { 845 0.0f, // float x; 846 0.0f, // float y; 847 (float)m_renderSize.x(), // float width; 848 (float)m_renderSize.y(), // float height; 849 0.0f, // float minDepth; 850 1.0f // float maxDepth; 851 }; 852 853 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } }; 854 855 const VkPipelineViewportStateCreateInfo viewportStateParams = 856 { 857 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 858 DE_NULL, // const void* pNext; 859 0u, // VkPipelineViewportStateCreateFlags flags; 860 1u, // deUint32 viewportCount; 861 &viewport, // const VkViewport* pViewports; 862 1u, // deUint32 scissorCount; 863 &scissor // const VkRect2D* pScissors; 864 }; 865 866 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 867 { 868 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 869 DE_NULL, // const void* pNext; 870 0u, // VkPipelineRasterizationStateCreateFlags flags; 871 false, // VkBool32 depthClampEnable; 872 false, // VkBool32 rasterizerDiscardEnable; 873 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 874 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 875 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 876 VK_FALSE, // VkBool32 depthBiasEnable; 877 0.0f, // float depthBiasConstantFactor; 878 0.0f, // float depthBiasClamp; 879 0.0f, // float depthBiasSlopeFactor; 880 1.0f, // float lineWidth; 881 }; 882 883 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 884 { 885 false, // VkBool32 blendEnable; 886 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 887 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 888 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 889 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 890 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 891 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 892 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 893 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 894 }; 895 896 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 897 { 898 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 899 DE_NULL, // const void* pNext; 900 0u, // VkPipelineColorBlendStateCreateFlags flags; 901 false, // VkBool32 logicOpEnable; 902 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 903 1u, // deUint32 attachmentCount; 904 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 905 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 906 }; 907 908 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 909 { 910 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 911 DE_NULL, // const void* pNext; 912 0u, // VkPipelineMultisampleStateCreateFlags flags; 913 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 914 false, // VkBool32 sampleShadingEnable; 915 0.0f, // float minSampleShading; 916 DE_NULL, // const VkSampleMask* pSampleMask; 917 false, // VkBool32 alphaToCoverageEnable; 918 false // VkBool32 alphaToOneEnable; 919 }; 920 921 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = 922 { 923 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 924 DE_NULL, // const void* pNext; 925 0u, // VkPipelineDepthStencilStateCreateFlags flags; 926 false, // VkBool32 depthTestEnable; 927 false, // VkBool32 depthWriteEnable; 928 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 929 false, // VkBool32 depthBoundsTestEnable; 930 false, // VkBool32 stencilTestEnable; 931 // VkStencilOpState front; 932 { 933 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 934 VK_STENCIL_OP_KEEP, // VkStencilOp passOp; 935 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 936 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 937 0u, // deUint32 compareMask; 938 0u, // deUint32 writeMask; 939 0u, // deUint32 reference; 940 }, 941 // VkStencilOpState back; 942 { 943 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 944 VK_STENCIL_OP_KEEP, // VkStencilOp passOp; 945 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 946 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 947 0u, // deUint32 compareMask; 948 0u, // deUint32 writeMask; 949 0u, // deUint32 reference; 950 }, 951 0.0f, // float minDepthBounds; 952 1.0f, // float maxDepthBounds; 953 }; 954 955 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 956 { 957 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 958 DE_NULL, // const void* pNext; 959 0u, // VkPipelineCreateFlags flags; 960 2u, // deUint32 stageCount; 961 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 962 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 963 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 964 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 965 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 966 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 967 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 968 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 969 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 970 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 971 *m_pipelineLayout, // VkPipelineLayout layout; 972 *m_renderPass, // VkRenderPass renderPass; 973 0u, // deUint32 subpass; 974 0u, // VkPipeline basePipelineHandle; 975 0u // deInt32 basePipelineIndex; 976 }; 977 978 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 979 } 980 981 // Create vertex buffer 982 { 983 const VkBufferCreateInfo vertexBufferParams = 984 { 985 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 986 DE_NULL, // const void* pNext; 987 0u, // VkBufferCreateFlags flags; 988 4096u, // VkDeviceSize size; 989 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 990 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 991 1u, // deUint32 queueFamilyIndexCount; 992 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 993 }; 994 995 // Upload data for each vertex input binding 996 for (deUint32 bindingNdx = 0; bindingNdx < bindingDescriptions.size(); bindingNdx++) 997 { 998 Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); 999 de::MovePtr<Allocation> vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible); 1000 1001 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset())); 1002 1003 writeVertexInputData((deUint8*)vertexBufferAlloc->getHostPtr(), bindingDescriptions[bindingNdx], bindingOffsets[bindingNdx], attributeDescriptions); 1004 flushMappedMemoryRange(vk, vkDevice, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferParams.size); 1005 1006 m_vertexBuffers.push_back(vertexBuffer.disown()); 1007 m_vertexBufferAllocs.push_back(vertexBufferAlloc.release()); 1008 } 1009 } 1010 1011 // Create command pool 1012 { 1013 const VkCommandPoolCreateInfo cmdPoolParams = 1014 { 1015 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1016 DE_NULL, // const void* pNext; 1017 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags; 1018 queueFamilyIndex, // deUint32 queueFamilyIndex; 1019 }; 1020 1021 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1022 } 1023 1024 // Create command buffer 1025 { 1026 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 1027 { 1028 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1029 DE_NULL, // const void* pNext; 1030 *m_cmdPool, // VkCommandPool commandPool; 1031 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 1032 1u // deUint32 bufferCount; 1033 }; 1034 1035 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1036 { 1037 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1038 DE_NULL, // const void* pNext; 1039 0u, // VkCommandBufferUsageFlags flags; 1040 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1041 }; 1042 1043 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat); 1044 1045 const VkRenderPassBeginInfo renderPassBeginInfo = 1046 { 1047 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1048 DE_NULL, // const void* pNext; 1049 *m_renderPass, // VkRenderPass renderPass; 1050 *m_framebuffer, // VkFramebuffer framebuffer; 1051 { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea; 1052 1u, // deUint32 clearValueCount; 1053 &attachmentClearValue // const VkClearValue* pClearValues; 1054 }; 1055 1056 const VkImageMemoryBarrier attachmentLayoutBarrier = 1057 { 1058 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1059 DE_NULL, // const void* pNext; 1060 0u, // VkAccessFlags srcAccessMask; 1061 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 1062 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1063 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 1064 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1065 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1066 *m_colorImage, // VkImage image; 1067 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 1068 }; 1069 1070 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo); 1071 1072 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1073 1074 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 1075 0u, DE_NULL, 0u, DE_NULL, 1u, &attachmentLayoutBarrier); 1076 1077 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1078 1079 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline); 1080 1081 std::vector<VkBuffer> vertexBuffers; 1082 for (size_t bufferNdx = 0; bufferNdx < m_vertexBuffers.size(); bufferNdx++) 1083 vertexBuffers.push_back(m_vertexBuffers[bufferNdx]); 1084 1085 if (vertexBuffers.size() <= 1) 1086 { 1087 // One vertex buffer 1088 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, (deUint32)vertexBuffers.size(), vertexBuffers.data(), bindingOffsets.data()); 1089 } 1090 else 1091 { 1092 // Smoke-test vkCmdBindVertexBuffers(..., startBinding, ... ) 1093 1094 const deUint32 firstHalfLength = (deUint32)vertexBuffers.size() / 2; 1095 const deUint32 secondHalfLength = firstHalfLength + (deUint32)(vertexBuffers.size() % 2); 1096 1097 // Bind first half of vertex buffers 1098 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, firstHalfLength, vertexBuffers.data(), bindingOffsets.data()); 1099 1100 // Bind second half of vertex buffers 1101 vk.cmdBindVertexBuffers(*m_cmdBuffer, firstHalfLength, secondHalfLength, 1102 vertexBuffers.data() + firstHalfLength, 1103 bindingOffsets.data() + firstHalfLength); 1104 } 1105 1106 vk.cmdDraw(*m_cmdBuffer, 4, 2, 0, 0); 1107 1108 vk.cmdEndRenderPass(*m_cmdBuffer); 1109 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1110 } 1111 1112 // Create fence 1113 { 1114 const VkFenceCreateInfo fenceParams = 1115 { 1116 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 1117 DE_NULL, // const void* pNext; 1118 0u // VkFenceCreateFlags flags; 1119 }; 1120 1121 m_fence = createFence(vk, vkDevice, &fenceParams); 1122 } 1123 } 1124 1125 VertexInputInstance::~VertexInputInstance (void) 1126 { 1127 const DeviceInterface& vk = m_context.getDeviceInterface(); 1128 const VkDevice vkDevice = m_context.getDevice(); 1129 1130 for (size_t bufferNdx = 0; bufferNdx < m_vertexBuffers.size(); bufferNdx++) 1131 vk.destroyBuffer(vkDevice, m_vertexBuffers[bufferNdx], DE_NULL); 1132 1133 for (size_t allocNdx = 0; allocNdx < m_vertexBufferAllocs.size(); allocNdx++) 1134 delete m_vertexBufferAllocs[allocNdx]; 1135 } 1136 1137 void VertexInputInstance::writeVertexInputData(deUint8* destPtr, const VkVertexInputBindingDescription& bindingDescription, const VkDeviceSize bindingOffset, const AttributeDescriptionList& attributes) 1138 { 1139 const deUint32 vertexCount = (bindingDescription.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) ? (4 * 2) : 2; 1140 1141 deUint8* destOffsetPtr = ((deUint8 *)destPtr) + bindingOffset; 1142 for (deUint32 vertexNdx = 0; vertexNdx < vertexCount; vertexNdx++) 1143 { 1144 for (size_t attributeNdx = 0; attributeNdx < attributes.size(); attributeNdx++) 1145 { 1146 const VertexInputAttributeDescription& attribDesc = attributes[attributeNdx]; 1147 1148 // Only write vertex input data to bindings referenced by attribute descriptions 1149 if (attribDesc.vkDescription.binding == bindingDescription.binding) 1150 { 1151 writeVertexInputValue(destOffsetPtr + attribDesc.vkDescription.offset, attribDesc, vertexNdx); 1152 } 1153 } 1154 destOffsetPtr += bindingDescription.stride; 1155 } 1156 } 1157 1158 void writeVertexInputValueSint (deUint8* destPtr, VkFormat format, int componentNdx, deInt32 value) 1159 { 1160 const deUint32 componentSize = getVertexFormatComponentSize(format); 1161 deUint8* destFormatPtr = ((deUint8*)destPtr) + componentSize * componentNdx; 1162 1163 switch (componentSize) 1164 { 1165 case 1: 1166 *((deInt8*)destFormatPtr) = (deInt8)value; 1167 break; 1168 1169 case 2: 1170 *((deInt16*)destFormatPtr) = (deInt16)value; 1171 break; 1172 1173 case 4: 1174 *((deInt32*)destFormatPtr) = (deInt32)value; 1175 break; 1176 1177 default: 1178 DE_ASSERT(false); 1179 } 1180 } 1181 1182 void writeVertexInputValueUint (deUint8* destPtr, VkFormat format, int componentNdx, deUint32 value) 1183 { 1184 const deUint32 componentSize = getVertexFormatComponentSize(format); 1185 deUint8* destFormatPtr = ((deUint8*)destPtr) + componentSize * componentNdx; 1186 1187 switch (componentSize) 1188 { 1189 case 1: 1190 *((deUint8 *)destFormatPtr) = (deUint8)value; 1191 break; 1192 1193 case 2: 1194 *((deUint16 *)destFormatPtr) = (deUint16)value; 1195 break; 1196 1197 case 4: 1198 *((deUint32 *)destFormatPtr) = (deUint32)value; 1199 break; 1200 1201 default: 1202 DE_ASSERT(false); 1203 } 1204 } 1205 1206 void writeVertexInputValueSfloat (deUint8* destPtr, VkFormat format, int componentNdx, float value) 1207 { 1208 const deUint32 componentSize = getVertexFormatComponentSize(format); 1209 deUint8* destFormatPtr = ((deUint8*)destPtr) + componentSize * componentNdx; 1210 1211 switch (componentSize) 1212 { 1213 case 2: 1214 { 1215 deFloat16 f16 = deFloat32To16(value); 1216 deMemcpy(destFormatPtr, &f16, sizeof(f16)); 1217 break; 1218 } 1219 1220 case 4: 1221 deMemcpy(destFormatPtr, &value, sizeof(value)); 1222 break; 1223 1224 default: 1225 DE_ASSERT(false); 1226 } 1227 } 1228 1229 void VertexInputInstance::writeVertexInputValue (deUint8* destPtr, const VertexInputAttributeDescription& attribute, int indexId) 1230 { 1231 const int vertexInputCount = VertexInputTest::s_glslTypeDescriptions[attribute.glslType].vertexInputCount; 1232 const int componentCount = VertexInputTest::s_glslTypeDescriptions[attribute.glslType].vertexInputComponentCount; 1233 const deUint32 totalComponentCount = componentCount * vertexInputCount; 1234 const deUint32 vertexInputIndex = indexId * totalComponentCount + attribute.vertexInputIndex * componentCount; 1235 const bool hasBGROrder = isVertexFormatComponentOrderBGR(attribute.vkDescription.format); 1236 int swizzledNdx; 1237 1238 for (int componentNdx = 0; componentNdx < componentCount; componentNdx++) 1239 { 1240 if (hasBGROrder) 1241 { 1242 if (componentNdx == 0) 1243 swizzledNdx = 2; 1244 else if (componentNdx == 2) 1245 swizzledNdx = 0; 1246 else 1247 swizzledNdx = componentNdx; 1248 } 1249 else 1250 swizzledNdx = componentNdx; 1251 1252 switch (attribute.glslType) 1253 { 1254 case VertexInputTest::GLSL_TYPE_INT: 1255 case VertexInputTest::GLSL_TYPE_IVEC2: 1256 case VertexInputTest::GLSL_TYPE_IVEC3: 1257 case VertexInputTest::GLSL_TYPE_IVEC4: 1258 writeVertexInputValueSint(destPtr, attribute.vkDescription.format, componentNdx, -(deInt32)(vertexInputIndex + swizzledNdx)); 1259 break; 1260 1261 case VertexInputTest::GLSL_TYPE_UINT: 1262 case VertexInputTest::GLSL_TYPE_UVEC2: 1263 case VertexInputTest::GLSL_TYPE_UVEC3: 1264 case VertexInputTest::GLSL_TYPE_UVEC4: 1265 writeVertexInputValueUint(destPtr, attribute.vkDescription.format, componentNdx, vertexInputIndex + swizzledNdx); 1266 break; 1267 1268 case VertexInputTest::GLSL_TYPE_FLOAT: 1269 case VertexInputTest::GLSL_TYPE_VEC2: 1270 case VertexInputTest::GLSL_TYPE_VEC3: 1271 case VertexInputTest::GLSL_TYPE_VEC4: 1272 case VertexInputTest::GLSL_TYPE_MAT2: 1273 case VertexInputTest::GLSL_TYPE_MAT3: 1274 case VertexInputTest::GLSL_TYPE_MAT4: 1275 if (isVertexFormatSfloat(attribute.vkDescription.format)) 1276 { 1277 writeVertexInputValueSfloat(destPtr, attribute.vkDescription.format, componentNdx, -(0.01f * (float)(vertexInputIndex + swizzledNdx))); 1278 } 1279 else if (isVertexFormatSscaled(attribute.vkDescription.format)) 1280 { 1281 writeVertexInputValueSint(destPtr, attribute.vkDescription.format, componentNdx, -(deInt32)(vertexInputIndex + swizzledNdx)); 1282 } 1283 else if (isVertexFormatUscaled(attribute.vkDescription.format) || isVertexFormatUnorm(attribute.vkDescription.format) || isVertexFormatSRGB(attribute.vkDescription.format)) 1284 { 1285 writeVertexInputValueUint(destPtr, attribute.vkDescription.format, componentNdx, vertexInputIndex + swizzledNdx); 1286 } 1287 else if (isVertexFormatSnorm(attribute.vkDescription.format)) 1288 { 1289 const deInt32 minIntValue = -((1 << (getVertexFormatComponentSize(attribute.vkDescription.format) * 8 - 1))) + 1; 1290 writeVertexInputValueSint(destPtr, attribute.vkDescription.format, componentNdx, minIntValue + (vertexInputIndex + swizzledNdx)); 1291 } 1292 else 1293 DE_ASSERT(false); 1294 break; 1295 1296 case VertexInputTest::GLSL_TYPE_DOUBLE: 1297 case VertexInputTest::GLSL_TYPE_DVEC2: 1298 case VertexInputTest::GLSL_TYPE_DVEC3: 1299 case VertexInputTest::GLSL_TYPE_DVEC4: 1300 case VertexInputTest::GLSL_TYPE_DMAT2: 1301 case VertexInputTest::GLSL_TYPE_DMAT3: 1302 case VertexInputTest::GLSL_TYPE_DMAT4: 1303 *(reinterpret_cast<double *>(destPtr) + componentNdx) = -0.01 * (vertexInputIndex + swizzledNdx); 1304 1305 break; 1306 1307 default: 1308 DE_ASSERT(false); 1309 } 1310 } 1311 } 1312 1313 tcu::TestStatus VertexInputInstance::iterate (void) 1314 { 1315 const DeviceInterface& vk = m_context.getDeviceInterface(); 1316 const VkDevice vkDevice = m_context.getDevice(); 1317 const VkQueue queue = m_context.getUniversalQueue(); 1318 const VkSubmitInfo submitInfo = 1319 { 1320 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 1321 DE_NULL, // const void* pNext; 1322 0u, // deUint32 waitSemaphoreCount; 1323 DE_NULL, // const VkSemaphore* pWaitSemaphores; 1324 (const VkPipelineStageFlags*)DE_NULL, 1325 1u, // deUint32 commandBufferCount; 1326 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 1327 0u, // deUint32 signalSemaphoreCount; 1328 DE_NULL // const VkSemaphore* pSignalSemaphores; 1329 }; 1330 1331 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 1332 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 1333 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/)); 1334 1335 return verifyImage(); 1336 } 1337 1338 bool VertexInputTest::isCompatibleType (VkFormat format, GlslType glslType) 1339 { 1340 const GlslTypeDescription glslTypeDesc = s_glslTypeDescriptions[glslType]; 1341 1342 if ((deUint32)s_glslTypeDescriptions[glslType].vertexInputComponentCount == getVertexFormatComponentCount(format)) 1343 { 1344 switch (glslTypeDesc.basicType) 1345 { 1346 case GLSL_BASIC_TYPE_INT: 1347 return isVertexFormatSint(format); 1348 1349 case GLSL_BASIC_TYPE_UINT: 1350 return isVertexFormatUint(format); 1351 1352 case GLSL_BASIC_TYPE_FLOAT: 1353 return getVertexFormatComponentSize(format) <= 4 && (isVertexFormatSfloat(format) || isVertexFormatSnorm(format) || isVertexFormatUnorm(format) || isVertexFormatSscaled(format) || isVertexFormatUscaled(format) || isVertexFormatSRGB(format)); 1354 1355 case GLSL_BASIC_TYPE_DOUBLE: 1356 return isVertexFormatSfloat(format) && getVertexFormatComponentSize(format) == 8; 1357 1358 default: 1359 DE_ASSERT(false); 1360 return false; 1361 } 1362 } 1363 else 1364 return false; 1365 } 1366 1367 tcu::TestStatus VertexInputInstance::verifyImage (void) 1368 { 1369 bool compareOk = false; 1370 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat); 1371 tcu::TextureLevel reference (tcuColorFormat, m_renderSize.x(), m_renderSize.y()); 1372 const tcu::PixelBufferAccess refRedSubregion (tcu::getSubregion(reference.getAccess(), 1373 deRoundFloatToInt32((float)m_renderSize.x() * 0.0f), 1374 deRoundFloatToInt32((float)m_renderSize.y() * 0.0f), 1375 deRoundFloatToInt32((float)m_renderSize.x() * 0.5f), 1376 deRoundFloatToInt32((float)m_renderSize.y() * 1.0f))); 1377 const tcu::PixelBufferAccess refBlueSubregion (tcu::getSubregion(reference.getAccess(), 1378 deRoundFloatToInt32((float)m_renderSize.x() * 0.5f), 1379 deRoundFloatToInt32((float)m_renderSize.y() * 0.0f), 1380 deRoundFloatToInt32((float)m_renderSize.x() * 0.5f), 1381 deRoundFloatToInt32((float)m_renderSize.y() * 1.0f))); 1382 1383 // Create reference image 1384 tcu::clear(reference.getAccess(), defaultClearColor(tcuColorFormat)); 1385 tcu::clear(refRedSubregion, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 1386 tcu::clear(refBlueSubregion, tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 1387 1388 // Compare result with reference image 1389 { 1390 const DeviceInterface& vk = m_context.getDeviceInterface(); 1391 const VkDevice vkDevice = m_context.getDevice(); 1392 const VkQueue queue = m_context.getUniversalQueue(); 1393 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1394 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 1395 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize); 1396 1397 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(), 1398 "IntImageCompare", 1399 "Image comparison", 1400 reference.getAccess(), 1401 result->getAccess(), 1402 tcu::UVec4(2, 2, 2, 2), 1403 tcu::IVec3(1, 1, 0), 1404 true, 1405 tcu::COMPARE_LOG_RESULT); 1406 } 1407 1408 if (compareOk) 1409 return tcu::TestStatus::pass("Result image matches reference"); 1410 else 1411 return tcu::TestStatus::fail("Image mismatch"); 1412 } 1413 1414 std::string getAttributeInfoCaseName (const VertexInputTest::AttributeInfo& attributeInfo) 1415 { 1416 std::ostringstream caseName; 1417 const std::string formatName = getFormatName(attributeInfo.vkType); 1418 1419 caseName << VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].name << "_as_" << de::toLower(formatName.substr(10)) << "_rate_"; 1420 1421 if (attributeInfo.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) 1422 caseName << "vertex"; 1423 else 1424 caseName << "instance"; 1425 1426 return caseName.str(); 1427 } 1428 1429 std::string getAttributeInfosCaseName (const std::vector<VertexInputTest::AttributeInfo>& attributeInfos) 1430 { 1431 std::ostringstream caseName; 1432 1433 for (size_t attributeNdx = 0; attributeNdx < attributeInfos.size(); attributeNdx++) 1434 { 1435 caseName << getAttributeInfoCaseName(attributeInfos[attributeNdx]); 1436 1437 if (attributeNdx < attributeInfos.size() - 1) 1438 caseName << "-"; 1439 } 1440 1441 return caseName.str(); 1442 } 1443 1444 std::string getAttributeInfoDescription (const VertexInputTest::AttributeInfo& attributeInfo) 1445 { 1446 std::ostringstream caseDesc; 1447 1448 caseDesc << std::string(VertexInputTest::s_glslTypeDescriptions[attributeInfo.glslType].name) << " from type " << getFormatName(attributeInfo.vkType) << " with "; 1449 1450 if (attributeInfo.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) 1451 caseDesc << "vertex input rate "; 1452 else 1453 caseDesc << "instance input rate "; 1454 1455 return caseDesc.str(); 1456 } 1457 1458 std::string getAttributeInfosDescription (const std::vector<VertexInputTest::AttributeInfo>& attributeInfos) 1459 { 1460 std::ostringstream caseDesc; 1461 1462 caseDesc << "Uses vertex attributes:\n"; 1463 1464 for (size_t attributeNdx = 0; attributeNdx < attributeInfos.size(); attributeNdx++) 1465 caseDesc << "\t- " << getAttributeInfoDescription (attributeInfos[attributeNdx]) << "\n"; 1466 1467 return caseDesc.str(); 1468 } 1469 1470 struct CompatibleFormats 1471 { 1472 VertexInputTest::GlslType glslType; 1473 std::vector<VkFormat> compatibleVkFormats; 1474 }; 1475 1476 de::MovePtr<tcu::TestCaseGroup> createSingleAttributeTests (tcu::TestContext& testCtx) 1477 { 1478 const VkFormat vertexFormats[] = 1479 { 1480 // Required, unpacked 1481 VK_FORMAT_R8_UNORM, 1482 VK_FORMAT_R8_SNORM, 1483 VK_FORMAT_R8_UINT, 1484 VK_FORMAT_R8_SINT, 1485 VK_FORMAT_R8G8_UNORM, 1486 VK_FORMAT_R8G8_SNORM, 1487 VK_FORMAT_R8G8_UINT, 1488 VK_FORMAT_R8G8_SINT, 1489 VK_FORMAT_R8G8B8A8_UNORM, 1490 VK_FORMAT_R8G8B8A8_SNORM, 1491 VK_FORMAT_R8G8B8A8_UINT, 1492 VK_FORMAT_R8G8B8A8_SINT, 1493 VK_FORMAT_B8G8R8A8_UNORM, 1494 VK_FORMAT_R16_UNORM, 1495 VK_FORMAT_R16_SNORM, 1496 VK_FORMAT_R16_UINT, 1497 VK_FORMAT_R16_SINT, 1498 VK_FORMAT_R16_SFLOAT, 1499 VK_FORMAT_R16G16_UNORM, 1500 VK_FORMAT_R16G16_SNORM, 1501 VK_FORMAT_R16G16_UINT, 1502 VK_FORMAT_R16G16_SINT, 1503 VK_FORMAT_R16G16_SFLOAT, 1504 VK_FORMAT_R16G16B16A16_UNORM, 1505 VK_FORMAT_R16G16B16A16_SNORM, 1506 VK_FORMAT_R16G16B16A16_UINT, 1507 VK_FORMAT_R16G16B16A16_SINT, 1508 VK_FORMAT_R16G16B16A16_SFLOAT, 1509 VK_FORMAT_R32_UINT, 1510 VK_FORMAT_R32_SINT, 1511 VK_FORMAT_R32_SFLOAT, 1512 VK_FORMAT_R32G32_UINT, 1513 VK_FORMAT_R32G32_SINT, 1514 VK_FORMAT_R32G32_SFLOAT, 1515 VK_FORMAT_R32G32B32_UINT, 1516 VK_FORMAT_R32G32B32_SINT, 1517 VK_FORMAT_R32G32B32_SFLOAT, 1518 VK_FORMAT_R32G32B32A32_UINT, 1519 VK_FORMAT_R32G32B32A32_SINT, 1520 VK_FORMAT_R32G32B32A32_SFLOAT, 1521 1522 // Scaled formats 1523 VK_FORMAT_R8G8_USCALED, 1524 VK_FORMAT_R8G8_SSCALED, 1525 VK_FORMAT_R16_USCALED, 1526 VK_FORMAT_R16_SSCALED, 1527 VK_FORMAT_R8G8B8_USCALED, 1528 VK_FORMAT_R8G8B8_SSCALED, 1529 VK_FORMAT_B8G8R8_USCALED, 1530 VK_FORMAT_B8G8R8_SSCALED, 1531 VK_FORMAT_R8G8B8A8_USCALED, 1532 VK_FORMAT_R8G8B8A8_SSCALED, 1533 VK_FORMAT_B8G8R8A8_USCALED, 1534 VK_FORMAT_B8G8R8A8_SSCALED, 1535 VK_FORMAT_R16G16_USCALED, 1536 VK_FORMAT_R16G16_SSCALED, 1537 VK_FORMAT_R16G16B16_USCALED, 1538 VK_FORMAT_R16G16B16_SSCALED, 1539 VK_FORMAT_R16G16B16A16_USCALED, 1540 VK_FORMAT_R16G16B16A16_SSCALED, 1541 1542 // SRGB formats 1543 VK_FORMAT_R8_SRGB, 1544 VK_FORMAT_R8G8_SRGB, 1545 VK_FORMAT_R8G8B8_SRGB, 1546 VK_FORMAT_B8G8R8_SRGB, 1547 VK_FORMAT_R8G8B8A8_SRGB, 1548 VK_FORMAT_B8G8R8A8_SRGB, 1549 1550 // Double formats 1551 VK_FORMAT_R64_SFLOAT, 1552 VK_FORMAT_R64G64_SFLOAT, 1553 VK_FORMAT_R64G64B64_SFLOAT, 1554 VK_FORMAT_R64G64B64A64_SFLOAT, 1555 }; 1556 1557 de::MovePtr<tcu::TestCaseGroup> singleAttributeTests (new tcu::TestCaseGroup(testCtx, "single_attribute", "Uses one attribute")); 1558 1559 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(vertexFormats); formatNdx++) 1560 { 1561 for (int glslTypeNdx = 0; glslTypeNdx < VertexInputTest::GLSL_TYPE_COUNT; glslTypeNdx++) 1562 { 1563 if (VertexInputTest::isCompatibleType(vertexFormats[formatNdx], (VertexInputTest::GlslType)glslTypeNdx)) 1564 { 1565 // Create test case for RATE_VERTEX 1566 VertexInputTest::AttributeInfo attributeInfo; 1567 attributeInfo.vkType = vertexFormats[formatNdx]; 1568 attributeInfo.glslType = (VertexInputTest::GlslType)glslTypeNdx; 1569 attributeInfo.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 1570 1571 singleAttributeTests->addChild(new VertexInputTest(testCtx, 1572 getAttributeInfoCaseName(attributeInfo), 1573 getAttributeInfoDescription(attributeInfo), 1574 std::vector<VertexInputTest::AttributeInfo>(1, attributeInfo), 1575 VertexInputTest::BINDING_MAPPING_ONE_TO_ONE)); 1576 1577 // Create test case for RATE_INSTANCE 1578 attributeInfo.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE; 1579 1580 singleAttributeTests->addChild(new VertexInputTest(testCtx, 1581 getAttributeInfoCaseName(attributeInfo), 1582 getAttributeInfoDescription(attributeInfo), 1583 std::vector<VertexInputTest::AttributeInfo>(1, attributeInfo), 1584 VertexInputTest::BINDING_MAPPING_ONE_TO_ONE)); 1585 } 1586 } 1587 } 1588 1589 return singleAttributeTests; 1590 } 1591 1592 de::MovePtr<tcu::TestCaseGroup> createMultipleAttributeTests (tcu::TestContext& testCtx) 1593 { 1594 // Required vertex formats, unpacked 1595 const VkFormat vertexFormats[] = 1596 { 1597 VK_FORMAT_R8_UNORM, 1598 VK_FORMAT_R8_SNORM, 1599 VK_FORMAT_R8_UINT, 1600 VK_FORMAT_R8_SINT, 1601 VK_FORMAT_R8G8_UNORM, 1602 VK_FORMAT_R8G8_SNORM, 1603 VK_FORMAT_R8G8_UINT, 1604 VK_FORMAT_R8G8_SINT, 1605 VK_FORMAT_R8G8B8A8_UNORM, 1606 VK_FORMAT_R8G8B8A8_SNORM, 1607 VK_FORMAT_R8G8B8A8_UINT, 1608 VK_FORMAT_R8G8B8A8_SINT, 1609 VK_FORMAT_B8G8R8A8_UNORM, 1610 VK_FORMAT_R16_UNORM, 1611 VK_FORMAT_R16_SNORM, 1612 VK_FORMAT_R16_UINT, 1613 VK_FORMAT_R16_SINT, 1614 VK_FORMAT_R16_SFLOAT, 1615 VK_FORMAT_R16G16_UNORM, 1616 VK_FORMAT_R16G16_SNORM, 1617 VK_FORMAT_R16G16_UINT, 1618 VK_FORMAT_R16G16_SINT, 1619 VK_FORMAT_R16G16_SFLOAT, 1620 VK_FORMAT_R16G16B16A16_UNORM, 1621 VK_FORMAT_R16G16B16A16_SNORM, 1622 VK_FORMAT_R16G16B16A16_UINT, 1623 VK_FORMAT_R16G16B16A16_SINT, 1624 VK_FORMAT_R16G16B16A16_SFLOAT, 1625 VK_FORMAT_R32_UINT, 1626 VK_FORMAT_R32_SINT, 1627 VK_FORMAT_R32_SFLOAT, 1628 VK_FORMAT_R32G32_UINT, 1629 VK_FORMAT_R32G32_SINT, 1630 VK_FORMAT_R32G32_SFLOAT, 1631 VK_FORMAT_R32G32B32_UINT, 1632 VK_FORMAT_R32G32B32_SINT, 1633 VK_FORMAT_R32G32B32_SFLOAT, 1634 VK_FORMAT_R32G32B32A32_UINT, 1635 VK_FORMAT_R32G32B32A32_SINT, 1636 VK_FORMAT_R32G32B32A32_SFLOAT 1637 }; 1638 1639 de::MovePtr<tcu::TestCaseGroup> multipleAttributeTests (new tcu::TestCaseGroup(testCtx, "multiple_attributes", "Uses more than one attribute")); 1640 1641 // Find compatible VK formats for each GLSL vertex type 1642 CompatibleFormats compatibleFormats[VertexInputTest::GLSL_TYPE_COUNT]; 1643 { 1644 for (int glslTypeNdx = 0; glslTypeNdx < VertexInputTest::GLSL_TYPE_COUNT; glslTypeNdx++) 1645 { 1646 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(vertexFormats); formatNdx++) 1647 { 1648 if (VertexInputTest::isCompatibleType(vertexFormats[formatNdx], (VertexInputTest::GlslType)glslTypeNdx)) 1649 compatibleFormats[glslTypeNdx].compatibleVkFormats.push_back(vertexFormats[formatNdx]); 1650 } 1651 } 1652 } 1653 1654 de::Random randomFunc (102030); 1655 GlslTypeCombinationsIterator glslTypeCombinationsItr (VertexInputTest::GLSL_TYPE_DOUBLE, 3); // Exclude double values, which are not included in vertexFormats 1656 de::MovePtr<tcu::TestCaseGroup> oneToOneAttributeTests (new tcu::TestCaseGroup(testCtx, "attributes", "")); 1657 de::MovePtr<tcu::TestCaseGroup> oneToManyAttributeTests (new tcu::TestCaseGroup(testCtx, "attributes", "")); 1658 1659 while (glslTypeCombinationsItr.hasNext()) 1660 { 1661 const std::vector<VertexInputTest::GlslType> glslTypes = glslTypeCombinationsItr.next(); 1662 std::vector<VertexInputTest::AttributeInfo> attributeInfos (glslTypes.size()); 1663 1664 for (size_t attributeNdx = 0; attributeNdx < attributeInfos.size(); attributeNdx++) 1665 { 1666 DE_ASSERT(!compatibleFormats[glslTypes[attributeNdx]].compatibleVkFormats.empty()); 1667 1668 // Select a random compatible format 1669 const std::vector<VkFormat>& formats = compatibleFormats[glslTypes[attributeNdx]].compatibleVkFormats; 1670 const VkFormat format = formats[randomFunc.getUint32() % formats.size()]; 1671 1672 attributeInfos[attributeNdx].glslType = glslTypes[attributeNdx]; 1673 attributeInfos[attributeNdx].inputRate = (attributeNdx % 2 == 0) ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE; 1674 attributeInfos[attributeNdx].vkType = format; 1675 } 1676 1677 const std::string caseName = getAttributeInfosCaseName(attributeInfos); 1678 const std::string caseDesc = getAttributeInfosDescription(attributeInfos); 1679 1680 oneToOneAttributeTests->addChild(new VertexInputTest(testCtx, caseName, caseDesc, attributeInfos, VertexInputTest::BINDING_MAPPING_ONE_TO_ONE)); 1681 oneToManyAttributeTests->addChild(new VertexInputTest(testCtx, caseName, caseDesc, attributeInfos, VertexInputTest::BINDING_MAPPING_ONE_TO_MANY)); 1682 } 1683 1684 de::MovePtr<tcu::TestCaseGroup> bindingOneToOneTests (new tcu::TestCaseGroup(testCtx, "binding_one_to_one", "Each attribute uses a unique binding")); 1685 bindingOneToOneTests->addChild(oneToOneAttributeTests.release()); 1686 multipleAttributeTests->addChild(bindingOneToOneTests.release()); 1687 1688 de::MovePtr<tcu::TestCaseGroup> bindingOneToManyTests (new tcu::TestCaseGroup(testCtx, "binding_one_to_many", "Attributes share the same binding")); 1689 bindingOneToManyTests->addChild(oneToManyAttributeTests.release()); 1690 multipleAttributeTests->addChild(bindingOneToManyTests.release()); 1691 1692 return multipleAttributeTests; 1693 } 1694 1695 } // anonymous 1696 1697 tcu::TestCaseGroup* createVertexInputTests (tcu::TestContext& testCtx) 1698 { 1699 de::MovePtr<tcu::TestCaseGroup> vertexInputTests (new tcu::TestCaseGroup(testCtx, "vertex_input", "")); 1700 1701 vertexInputTests->addChild(createSingleAttributeTests(testCtx).release()); 1702 vertexInputTests->addChild(createMultipleAttributeTests(testCtx).release()); 1703 1704 return vertexInputTests.release(); 1705 } 1706 1707 } // pipeline 1708 } // vkt 1709