1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Samsung Electronics Co., Ltd. 7 * Copyright (c) 2016 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Vulkan ShaderRenderCase 24 *//*--------------------------------------------------------------------*/ 25 26 #include "vktShaderRender.hpp" 27 28 #include "tcuImageCompare.hpp" 29 #include "tcuImageIO.hpp" 30 #include "tcuTestLog.hpp" 31 #include "tcuTextureUtil.hpp" 32 #include "tcuSurface.hpp" 33 #include "tcuVector.hpp" 34 35 #include "deFilePath.hpp" 36 #include "deMath.h" 37 #include "deUniquePtr.hpp" 38 39 #include "vkDeviceUtil.hpp" 40 #include "vkImageUtil.hpp" 41 #include "vkPlatform.hpp" 42 #include "vkQueryUtil.hpp" 43 #include "vkRef.hpp" 44 #include "vkRefUtil.hpp" 45 #include "vkStrUtil.hpp" 46 #include "vkTypeUtil.hpp" 47 48 #include <vector> 49 #include <string> 50 51 namespace vkt 52 { 53 namespace sr 54 { 55 56 using namespace vk; 57 58 namespace 59 { 60 61 static const int GRID_SIZE = 64; 62 static const deUint32 MAX_RENDER_WIDTH = 128; 63 static const deUint32 MAX_RENDER_HEIGHT = 128; 64 static const tcu::Vec4 DEFAULT_CLEAR_COLOR = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f); 65 66 static VkImageViewType textureTypeToImageViewType (TextureBinding::Type type) 67 { 68 switch (type) 69 { 70 case TextureBinding::TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D; 71 case TextureBinding::TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D; 72 case TextureBinding::TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D; 73 case TextureBinding::TYPE_CUBE_MAP: return VK_IMAGE_VIEW_TYPE_CUBE; 74 case TextureBinding::TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY; 75 case TextureBinding::TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; 76 case TextureBinding::TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; 77 78 default: 79 DE_FATAL("Impossible"); 80 return (VkImageViewType)0; 81 } 82 } 83 84 static VkImageType viewTypeToImageType (VkImageViewType type) 85 { 86 switch (type) 87 { 88 case VK_IMAGE_VIEW_TYPE_1D: 89 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return VK_IMAGE_TYPE_1D; 90 case VK_IMAGE_VIEW_TYPE_2D: 91 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return VK_IMAGE_TYPE_2D; 92 case VK_IMAGE_VIEW_TYPE_3D: return VK_IMAGE_TYPE_3D; 93 case VK_IMAGE_VIEW_TYPE_CUBE: 94 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return VK_IMAGE_TYPE_2D; 95 96 default: 97 DE_FATAL("Impossible"); 98 return (VkImageType)0; 99 } 100 } 101 102 /*! Gets the next multiple of a given divisor */ 103 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value) 104 { 105 if (value % divisor == 0) 106 { 107 return value; 108 } 109 return value + divisor - (value % divisor); 110 } 111 112 /*! Gets the next value that is multiple of all given divisors */ 113 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value) 114 { 115 deUint32 nextMultiple = value; 116 bool nextMultipleFound = false; 117 118 while (true) 119 { 120 nextMultipleFound = true; 121 122 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++) 123 nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0); 124 125 if (nextMultipleFound) 126 break; 127 128 DE_ASSERT(nextMultiple < ~((deUint32)0u)); 129 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1); 130 } 131 132 return nextMultiple; 133 } 134 135 } // anonymous 136 137 // QuadGrid. 138 139 class QuadGrid 140 { 141 public: 142 QuadGrid (int gridSize, 143 int screenWidth, 144 int screenHeight, 145 const tcu::Vec4& constCoords, 146 const std::vector<tcu::Mat4>& userAttribTransforms, 147 const std::vector<TextureBindingSp>& textures); 148 ~QuadGrid (void); 149 150 int getGridSize (void) const { return m_gridSize; } 151 int getNumVertices (void) const { return m_numVertices; } 152 int getNumTriangles (void) const { return m_numTriangles; } 153 const tcu::Vec4& getConstCoords (void) const { return m_constCoords; } 154 const std::vector<tcu::Mat4> getUserAttribTransforms (void) const { return m_userAttribTransforms; } 155 const std::vector<TextureBindingSp>& getTextures (void) const { return m_textures; } 156 157 const tcu::Vec4* getPositions (void) const { return &m_positions[0]; } 158 const float* getAttribOne (void) const { return &m_attribOne[0]; } 159 const tcu::Vec4* getCoords (void) const { return &m_coords[0]; } 160 const tcu::Vec4* getUnitCoords (void) const { return &m_unitCoords[0]; } 161 162 const tcu::Vec4* getUserAttrib (int attribNdx) const { return &m_userAttribs[attribNdx][0]; } 163 const deUint16* getIndices (void) const { return &m_indices[0]; } 164 165 tcu::Vec4 getCoords (float sx, float sy) const; 166 tcu::Vec4 getUnitCoords (float sx, float sy) const; 167 168 int getNumUserAttribs (void) const { return (int)m_userAttribTransforms.size(); } 169 tcu::Vec4 getUserAttrib (int attribNdx, float sx, float sy) const; 170 171 private: 172 const int m_gridSize; 173 const int m_numVertices; 174 const int m_numTriangles; 175 const tcu::Vec4 m_constCoords; 176 const std::vector<tcu::Mat4> m_userAttribTransforms; 177 178 const std::vector<TextureBindingSp>& m_textures; 179 180 std::vector<tcu::Vec4> m_screenPos; 181 std::vector<tcu::Vec4> m_positions; 182 std::vector<tcu::Vec4> m_coords; //!< Near-unit coordinates, roughly [-2.0 .. 2.0]. 183 std::vector<tcu::Vec4> m_unitCoords; //!< Positive-only coordinates [0.0 .. 1.5]. 184 std::vector<float> m_attribOne; 185 std::vector<tcu::Vec4> m_userAttribs[ShaderEvalContext::MAX_TEXTURES]; 186 std::vector<deUint16> m_indices; 187 }; 188 189 QuadGrid::QuadGrid (int gridSize, 190 int width, 191 int height, 192 const tcu::Vec4& constCoords, 193 const std::vector<tcu::Mat4>& userAttribTransforms, 194 const std::vector<TextureBindingSp>& textures) 195 : m_gridSize (gridSize) 196 , m_numVertices ((gridSize + 1) * (gridSize + 1)) 197 , m_numTriangles (gridSize * gridSize * 2) 198 , m_constCoords (constCoords) 199 , m_userAttribTransforms (userAttribTransforms) 200 , m_textures (textures) 201 { 202 const tcu::Vec4 viewportScale ((float)width, (float)height, 0.0f, 0.0f); 203 204 // Compute vertices. 205 m_screenPos.resize(m_numVertices); 206 m_positions.resize(m_numVertices); 207 m_coords.resize(m_numVertices); 208 m_unitCoords.resize(m_numVertices); 209 m_attribOne.resize(m_numVertices); 210 211 // User attributes. 212 for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++) 213 m_userAttribs[attrNdx].resize(m_numVertices); 214 215 for (int y = 0; y < gridSize+1; y++) 216 for (int x = 0; x < gridSize+1; x++) 217 { 218 float sx = (float)x / (float)gridSize; 219 float sy = (float)y / (float)gridSize; 220 float fx = 2.0f * sx - 1.0f; 221 float fy = 2.0f * sy - 1.0f; 222 int vtxNdx = ((y * (gridSize+1)) + x); 223 224 m_positions[vtxNdx] = tcu::Vec4(fx, fy, 0.0f, 1.0f); 225 m_coords[vtxNdx] = getCoords(sx, sy); 226 m_unitCoords[vtxNdx] = getUnitCoords(sx, sy); 227 m_attribOne[vtxNdx] = 1.0f; 228 229 m_screenPos[vtxNdx] = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale; 230 231 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++) 232 m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy); 233 } 234 235 // Compute indices. 236 m_indices.resize(3 * m_numTriangles); 237 for (int y = 0; y < gridSize; y++) 238 for (int x = 0; x < gridSize; x++) 239 { 240 int stride = gridSize + 1; 241 int v00 = (y * stride) + x; 242 int v01 = (y * stride) + x + 1; 243 int v10 = ((y+1) * stride) + x; 244 int v11 = ((y+1) * stride) + x + 1; 245 246 int baseNdx = ((y * gridSize) + x) * 6; 247 m_indices[baseNdx + 0] = (deUint16)v10; 248 m_indices[baseNdx + 1] = (deUint16)v00; 249 m_indices[baseNdx + 2] = (deUint16)v01; 250 251 m_indices[baseNdx + 3] = (deUint16)v10; 252 m_indices[baseNdx + 4] = (deUint16)v01; 253 m_indices[baseNdx + 5] = (deUint16)v11; 254 } 255 } 256 257 QuadGrid::~QuadGrid (void) 258 { 259 } 260 261 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const 262 { 263 const float fx = 2.0f * sx - 1.0f; 264 const float fy = 2.0f * sy - 1.0f; 265 return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy); 266 } 267 268 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const 269 { 270 return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy); 271 } 272 273 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const 274 { 275 // homogeneous normalized screen-space coordinates 276 return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f); 277 } 278 279 // TextureBinding 280 281 TextureBinding::TextureBinding (const tcu::Archive& archive, 282 const char* filename, 283 const Type type, 284 const tcu::Sampler& sampler) 285 : m_type (type) 286 , m_sampler (sampler) 287 { 288 switch(m_type) 289 { 290 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break; 291 default: 292 DE_FATAL("Unsupported texture type"); 293 } 294 } 295 296 TextureBinding::TextureBinding (const tcu::Texture1D* tex1D, const tcu::Sampler& sampler) 297 : m_type (TYPE_1D) 298 , m_sampler (sampler) 299 { 300 m_binding.tex1D = tex1D; 301 } 302 303 TextureBinding::TextureBinding (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler) 304 : m_type (TYPE_2D) 305 , m_sampler (sampler) 306 { 307 m_binding.tex2D = tex2D; 308 } 309 310 TextureBinding::TextureBinding (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler) 311 : m_type (TYPE_3D) 312 , m_sampler (sampler) 313 { 314 m_binding.tex3D = tex3D; 315 } 316 317 TextureBinding::TextureBinding (const tcu::TextureCube* texCube, const tcu::Sampler& sampler) 318 : m_type (TYPE_CUBE_MAP) 319 , m_sampler (sampler) 320 { 321 m_binding.texCube = texCube; 322 } 323 324 TextureBinding::TextureBinding (const tcu::Texture1DArray* tex1DArray, const tcu::Sampler& sampler) 325 : m_type (TYPE_1D_ARRAY) 326 , m_sampler (sampler) 327 { 328 m_binding.tex1DArray = tex1DArray; 329 } 330 331 TextureBinding::TextureBinding (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler) 332 : m_type (TYPE_2D_ARRAY) 333 , m_sampler (sampler) 334 { 335 m_binding.tex2DArray = tex2DArray; 336 } 337 338 TextureBinding::TextureBinding (const tcu::TextureCubeArray* texCubeArray, const tcu::Sampler& sampler) 339 : m_type (TYPE_CUBE_ARRAY) 340 , m_sampler (sampler) 341 { 342 m_binding.texCubeArray = texCubeArray; 343 } 344 345 TextureBinding::~TextureBinding (void) 346 { 347 switch(m_type) 348 { 349 case TYPE_1D: delete m_binding.tex1D; break; 350 case TYPE_2D: delete m_binding.tex2D; break; 351 case TYPE_3D: delete m_binding.tex3D; break; 352 case TYPE_CUBE_MAP: delete m_binding.texCube; break; 353 case TYPE_1D_ARRAY: delete m_binding.tex1DArray; break; 354 case TYPE_2D_ARRAY: delete m_binding.tex2DArray; break; 355 case TYPE_CUBE_ARRAY: delete m_binding.texCubeArray; break; 356 default: break; 357 } 358 } 359 360 de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename) 361 { 362 tcu::TextureLevel level; 363 tcu::ImageIO::loadImage(level, archive, filename); 364 365 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) || 366 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8)); 367 368 // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated 369 de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight())); 370 371 // Fill level 0. 372 texture->allocLevel(0); 373 tcu::copy(texture->getLevel(0), level.getAccess()); 374 375 return texture; 376 } 377 378 // ShaderEvalContext. 379 380 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid) 381 : constCoords (quadGrid.getConstCoords()) 382 , isDiscarded (false) 383 , m_quadGrid (quadGrid) 384 { 385 const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures(); 386 DE_ASSERT((int)bindings.size() <= MAX_TEXTURES); 387 388 // Fill in texture array. 389 for (int ndx = 0; ndx < (int)bindings.size(); ndx++) 390 { 391 const TextureBinding& binding = *bindings[ndx]; 392 393 if (binding.getType() == TextureBinding::TYPE_NONE) 394 continue; 395 396 textures[ndx].sampler = binding.getSampler(); 397 398 switch (binding.getType()) 399 { 400 case TextureBinding::TYPE_1D: textures[ndx].tex1D = &binding.get1D(); break; 401 case TextureBinding::TYPE_2D: textures[ndx].tex2D = &binding.get2D(); break; 402 case TextureBinding::TYPE_3D: textures[ndx].tex3D = &binding.get3D(); break; 403 case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube = &binding.getCube(); break; 404 case TextureBinding::TYPE_1D_ARRAY: textures[ndx].tex1DArray = &binding.get1DArray(); break; 405 case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray = &binding.get2DArray(); break; 406 case TextureBinding::TYPE_CUBE_ARRAY: textures[ndx].texCubeArray = &binding.getCubeArray(); break; 407 default: 408 TCU_THROW(InternalError, "Handling of texture binding type not implemented"); 409 } 410 } 411 } 412 413 ShaderEvalContext::~ShaderEvalContext (void) 414 { 415 } 416 417 void ShaderEvalContext::reset (float sx, float sy) 418 { 419 // Clear old values 420 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 421 isDiscarded = false; 422 423 // Compute coords 424 coords = m_quadGrid.getCoords(sx, sy); 425 unitCoords = m_quadGrid.getUnitCoords(sx, sy); 426 427 // Compute user attributes. 428 const int numAttribs = m_quadGrid.getNumUserAttribs(); 429 DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS); 430 for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++) 431 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy); 432 } 433 434 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords) 435 { 436 if (textures[unitNdx].tex2D) 437 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f); 438 else 439 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 440 } 441 442 // ShaderEvaluator. 443 444 ShaderEvaluator::ShaderEvaluator (void) 445 : m_evalFunc(DE_NULL) 446 { 447 } 448 449 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc) 450 : m_evalFunc(evalFunc) 451 { 452 } 453 454 ShaderEvaluator::~ShaderEvaluator (void) 455 { 456 } 457 458 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const 459 { 460 DE_ASSERT(m_evalFunc); 461 m_evalFunc(ctx); 462 } 463 464 // UniformSetup. 465 466 UniformSetup::UniformSetup (void) 467 : m_setupFunc(DE_NULL) 468 { 469 } 470 471 UniformSetup::UniformSetup (UniformSetupFunc setupFunc) 472 : m_setupFunc(setupFunc) 473 { 474 } 475 476 UniformSetup::~UniformSetup (void) 477 { 478 } 479 480 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const 481 { 482 if (m_setupFunc) 483 m_setupFunc(instance, constCoords); 484 } 485 486 // ShaderRenderCase. 487 488 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx, 489 const std::string& name, 490 const std::string& description, 491 const bool isVertexCase, 492 const ShaderEvalFunc evalFunc, 493 const UniformSetup* uniformSetup, 494 const AttributeSetupFunc attribFunc) 495 : vkt::TestCase (testCtx, name, description) 496 , m_isVertexCase (isVertexCase) 497 , m_evaluator (new ShaderEvaluator(evalFunc)) 498 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup()) 499 , m_attribFunc (attribFunc) 500 {} 501 502 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx, 503 const std::string& name, 504 const std::string& description, 505 const bool isVertexCase, 506 const ShaderEvaluator* evaluator, 507 const UniformSetup* uniformSetup, 508 const AttributeSetupFunc attribFunc) 509 : vkt::TestCase (testCtx, name, description) 510 , m_isVertexCase (isVertexCase) 511 , m_evaluator (evaluator) 512 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup()) 513 , m_attribFunc (attribFunc) 514 {} 515 516 ShaderRenderCase::~ShaderRenderCase (void) 517 { 518 } 519 520 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const 521 { 522 programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource); 523 programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource); 524 } 525 526 TestInstance* ShaderRenderCase::createInstance (Context& context) const 527 { 528 DE_ASSERT(m_evaluator != DE_NULL); 529 DE_ASSERT(m_uniformSetup != DE_NULL); 530 return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc); 531 } 532 533 // ShaderRenderCaseInstance. 534 535 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context) 536 : vkt::TestInstance (context) 537 , m_imageBackingMode (IMAGE_BACKING_MODE_REGULAR) 538 , m_sparseContext (createSparseContext()) 539 , m_memAlloc (getAllocator()) 540 , m_clearColor (DEFAULT_CLEAR_COLOR) 541 , m_isVertexCase (false) 542 , m_vertexShaderName ("vert") 543 , m_fragmentShaderName ("frag") 544 , m_renderSize (128, 128) 545 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 546 , m_evaluator (DE_NULL) 547 , m_uniformSetup (DE_NULL) 548 , m_attribFunc (DE_NULL) 549 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT) 550 { 551 } 552 553 554 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, 555 const bool isVertexCase, 556 const ShaderEvaluator& evaluator, 557 const UniformSetup& uniformSetup, 558 const AttributeSetupFunc attribFunc, 559 const ImageBackingMode imageBackingMode) 560 : vkt::TestInstance (context) 561 , m_imageBackingMode (imageBackingMode) 562 , m_sparseContext (createSparseContext()) 563 , m_memAlloc (getAllocator()) 564 , m_clearColor (DEFAULT_CLEAR_COLOR) 565 , m_isVertexCase (isVertexCase) 566 , m_vertexShaderName ("vert") 567 , m_fragmentShaderName ("frag") 568 , m_renderSize (128, 128) 569 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 570 , m_evaluator (&evaluator) 571 , m_uniformSetup (&uniformSetup) 572 , m_attribFunc (attribFunc) 573 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT) 574 { 575 } 576 577 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, 578 const bool isVertexCase, 579 const ShaderEvaluator* evaluator, 580 const UniformSetup* uniformSetup, 581 const AttributeSetupFunc attribFunc, 582 const ImageBackingMode imageBackingMode) 583 : vkt::TestInstance (context) 584 , m_imageBackingMode (imageBackingMode) 585 , m_sparseContext (createSparseContext()) 586 , m_memAlloc (getAllocator()) 587 , m_clearColor (DEFAULT_CLEAR_COLOR) 588 , m_isVertexCase (isVertexCase) 589 , m_vertexShaderName ("vert") 590 , m_fragmentShaderName ("frag") 591 , m_renderSize (128, 128) 592 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 593 , m_evaluator (evaluator) 594 , m_uniformSetup (uniformSetup) 595 , m_attribFunc (attribFunc) 596 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT) 597 { 598 } 599 600 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps) 601 { 602 const std::vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice); 603 604 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++) 605 { 606 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps) 607 return (deUint32)queueNdx; 608 } 609 610 TCU_THROW(NotSupportedError, "No matching queue found"); 611 } 612 613 614 ShaderRenderCaseInstance::SparseContext::SparseContext (vkt::Context& context) 615 : m_context (context) 616 , m_queueFamilyIndex (findQueueFamilyIndexWithCaps(context.getInstanceInterface(), context.getPhysicalDevice(), VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_SPARSE_BINDING_BIT)) 617 , m_device (createDevice()) 618 , m_deviceInterface (context.getInstanceInterface(), *m_device) 619 , m_allocator (createAllocator()) 620 { 621 m_deviceInterface.getDeviceQueue(*m_device, m_queueFamilyIndex, 0, &m_queue); 622 } 623 624 Move<VkDevice> ShaderRenderCaseInstance::SparseContext::createDevice () const 625 { 626 const InstanceInterface& vk = m_context.getInstanceInterface(); 627 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 628 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(vk, physicalDevice); 629 630 VkDeviceQueueCreateInfo queueInfo; 631 VkDeviceCreateInfo deviceInfo; 632 const float queuePriority = 1.0f; 633 634 deMemset(&queueInfo, 0, sizeof(queueInfo)); 635 deMemset(&deviceInfo, 0, sizeof(deviceInfo)); 636 637 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 638 queueInfo.pNext = DE_NULL; 639 queueInfo.flags = (VkDeviceQueueCreateFlags)0u; 640 queueInfo.queueFamilyIndex = m_queueFamilyIndex; 641 queueInfo.queueCount = 1u; 642 queueInfo.pQueuePriorities = &queuePriority; 643 644 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 645 deviceInfo.pNext = DE_NULL; 646 deviceInfo.queueCreateInfoCount = 1u; 647 deviceInfo.pQueueCreateInfos = &queueInfo; 648 deviceInfo.enabledExtensionCount = 0u; 649 deviceInfo.ppEnabledExtensionNames = DE_NULL; 650 deviceInfo.enabledLayerCount = 0u; 651 deviceInfo.ppEnabledLayerNames = DE_NULL; 652 deviceInfo.pEnabledFeatures = &deviceFeatures; 653 654 return vk::createDevice(vk, physicalDevice, &deviceInfo); 655 } 656 657 vk::Allocator* ShaderRenderCaseInstance::SparseContext::createAllocator () const 658 { 659 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()); 660 return new SimpleAllocator(m_deviceInterface, *m_device, memoryProperties); 661 } 662 663 ShaderRenderCaseInstance::SparseContext* ShaderRenderCaseInstance::createSparseContext (void) const 664 { 665 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) 666 { 667 return new SparseContext(m_context); 668 } 669 670 return DE_NULL; 671 } 672 673 vk::Allocator& ShaderRenderCaseInstance::getAllocator (void) const 674 { 675 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) 676 { 677 return *m_sparseContext->m_allocator; 678 } 679 680 return m_context.getDefaultAllocator(); 681 } 682 683 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void) 684 { 685 } 686 687 VkDevice ShaderRenderCaseInstance::getDevice (void) const 688 { 689 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) 690 return *m_sparseContext->m_device; 691 692 return m_context.getDevice(); 693 } 694 695 deUint32 ShaderRenderCaseInstance::getUniversalQueueFamilyIndex (void) const 696 { 697 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) 698 return m_sparseContext->m_queueFamilyIndex; 699 700 return m_context.getUniversalQueueFamilyIndex(); 701 } 702 703 const DeviceInterface& ShaderRenderCaseInstance::getDeviceInterface (void) const 704 { 705 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) 706 return m_sparseContext->m_deviceInterface; 707 708 return m_context.getDeviceInterface(); 709 } 710 711 VkQueue ShaderRenderCaseInstance::getUniversalQueue (void) const 712 { 713 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) 714 return m_sparseContext->m_queue; 715 716 return m_context.getUniversalQueue(); 717 } 718 719 VkPhysicalDevice ShaderRenderCaseInstance::getPhysicalDevice (void) const 720 { 721 // Same in sparse and regular case 722 return m_context.getPhysicalDevice(); 723 } 724 725 const InstanceInterface& ShaderRenderCaseInstance::getInstanceInterface (void) const 726 { 727 // Same in sparse and regular case 728 return m_context.getInstanceInterface(); 729 } 730 731 tcu::TestStatus ShaderRenderCaseInstance::iterate (void) 732 { 733 setup(); 734 735 // Create quad grid. 736 const tcu::UVec2 viewportSize = getViewportSize(); 737 const int width = viewportSize.x(); 738 const int height = viewportSize.y(); 739 740 m_quadGrid = de::MovePtr<QuadGrid>(new QuadGrid(m_isVertexCase ? GRID_SIZE : 4, width, height, getDefaultConstCoords(), m_userAttribTransforms, m_textures)); 741 742 // Render result. 743 tcu::Surface resImage (width, height); 744 745 render(m_quadGrid->getNumVertices(), m_quadGrid->getNumTriangles(), m_quadGrid->getIndices(), m_quadGrid->getConstCoords()); 746 tcu::copy(resImage.getAccess(), m_resultImage.getAccess()); 747 748 // Compute reference. 749 tcu::Surface refImage (width, height); 750 if (m_isVertexCase) 751 computeVertexReference(refImage, *m_quadGrid); 752 else 753 computeFragmentReference(refImage, *m_quadGrid); 754 755 // Compare. 756 const bool compareOk = compareImages(resImage, refImage, 0.1f); 757 758 if (compareOk) 759 return tcu::TestStatus::pass("Result image matches reference"); 760 else 761 return tcu::TestStatus::fail("Image mismatch"); 762 } 763 764 void ShaderRenderCaseInstance::setup (void) 765 { 766 m_resultImage = tcu::TextureLevel(); 767 m_descriptorSetLayoutBuilder = de::MovePtr<DescriptorSetLayoutBuilder> (new DescriptorSetLayoutBuilder()); 768 m_descriptorPoolBuilder = de::MovePtr<DescriptorPoolBuilder> (new DescriptorPoolBuilder()); 769 m_descriptorSetUpdateBuilder = de::MovePtr<DescriptorSetUpdateBuilder> (new DescriptorSetUpdateBuilder()); 770 771 m_uniformInfos.clear(); 772 m_vertexBindingDescription.clear(); 773 m_vertexAttributeDescription.clear(); 774 m_vertexBuffers.clear(); 775 m_vertexBufferAllocs.clear(); 776 m_pushConstantRanges.clear(); 777 } 778 779 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr) 780 { 781 const VkDevice vkDevice = getDevice(); 782 const DeviceInterface& vk = getDeviceInterface(); 783 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 784 785 const VkBufferCreateInfo uniformBufferParams = 786 { 787 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 788 DE_NULL, // const void* pNext; 789 0u, // VkBufferCreateFlags flags; 790 size, // VkDeviceSize size; 791 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage; 792 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 793 1u, // deUint32 queueFamilyCount; 794 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 795 }; 796 797 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams); 798 de::MovePtr<Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 799 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset())); 800 801 deMemcpy(alloc->getHostPtr(), dataPtr, size); 802 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size); 803 804 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform()); 805 uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 806 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size); 807 uniformInfo->location = bindingLocation; 808 uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer)); 809 uniformInfo->alloc = AllocationSp(alloc.release()); 810 811 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo))); 812 } 813 814 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, size_t dataSize, const void* data) 815 { 816 m_descriptorSetLayoutBuilder->addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_ALL); 817 m_descriptorPoolBuilder->addType(descriptorType); 818 819 setupUniformData(bindingLocation, dataSize, data); 820 } 821 822 void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation, 823 vk::VkFormat format, 824 deUint32 sizePerElement, 825 deUint32 count, 826 const void* dataPtr) 827 { 828 // Add binding specification 829 const deUint32 binding = (deUint32)m_vertexBindingDescription.size(); 830 const VkVertexInputBindingDescription bindingDescription = 831 { 832 binding, // deUint32 binding; 833 sizePerElement, // deUint32 stride; 834 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate stepRate; 835 }; 836 837 m_vertexBindingDescription.push_back(bindingDescription); 838 839 // Add location and format specification 840 const VkVertexInputAttributeDescription attributeDescription = 841 { 842 bindingLocation, // deUint32 location; 843 binding, // deUint32 binding; 844 format, // VkFormat format; 845 0u, // deUint32 offset; 846 }; 847 848 m_vertexAttributeDescription.push_back(attributeDescription); 849 850 // Upload data to buffer 851 const VkDevice vkDevice = getDevice(); 852 const DeviceInterface& vk = getDeviceInterface(); 853 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 854 855 const VkDeviceSize inputSize = sizePerElement * count; 856 const VkBufferCreateInfo vertexBufferParams = 857 { 858 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 859 DE_NULL, // const void* pNext; 860 0u, // VkBufferCreateFlags flags; 861 inputSize, // VkDeviceSize size; 862 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 863 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 864 1u, // deUint32 queueFamilyCount; 865 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 866 }; 867 868 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams); 869 de::MovePtr<vk::Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 870 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset())); 871 872 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize); 873 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize); 874 875 m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer))); 876 m_vertexBufferAllocs.push_back(AllocationSp(alloc.release())); 877 } 878 879 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type) 880 { 881 const EnabledBaseAttribute attribute = 882 { 883 bindingLocation, // deUint32 location; 884 type // BaseAttributeType type; 885 }; 886 m_enabledBaseAttributes.push_back(attribute); 887 } 888 889 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords) 890 { 891 if (m_uniformSetup) 892 m_uniformSetup->setup(*this, constCoords); 893 } 894 895 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type) 896 { 897 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break 898 899 switch(type) 900 { 901 // Bool 902 UNIFORM_CASE(UB_FALSE, 0); 903 UNIFORM_CASE(UB_TRUE, 1); 904 905 // BVec4 906 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0)); 907 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1)); 908 909 // Integer 910 UNIFORM_CASE(UI_ZERO, 0); 911 UNIFORM_CASE(UI_ONE, 1); 912 UNIFORM_CASE(UI_TWO, 2); 913 UNIFORM_CASE(UI_THREE, 3); 914 UNIFORM_CASE(UI_FOUR, 4); 915 UNIFORM_CASE(UI_FIVE, 5); 916 UNIFORM_CASE(UI_SIX, 6); 917 UNIFORM_CASE(UI_SEVEN, 7); 918 UNIFORM_CASE(UI_EIGHT, 8); 919 UNIFORM_CASE(UI_ONEHUNDREDONE, 101); 920 921 // IVec2 922 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1)); 923 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0)); 924 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1)); 925 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2)); 926 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3)); 927 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4)); 928 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5)); 929 930 // IVec3 931 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1)); 932 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0)); 933 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1)); 934 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2)); 935 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3)); 936 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4)); 937 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5)); 938 939 // IVec4 940 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1)); 941 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0)); 942 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1)); 943 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2)); 944 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3)); 945 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4)); 946 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5)); 947 948 // Float 949 UNIFORM_CASE(UF_ZERO, 0.0f); 950 UNIFORM_CASE(UF_ONE, 1.0f); 951 UNIFORM_CASE(UF_TWO, 2.0f); 952 UNIFORM_CASE(UF_THREE, 3.0f); 953 UNIFORM_CASE(UF_FOUR, 4.0f); 954 UNIFORM_CASE(UF_FIVE, 5.0f); 955 UNIFORM_CASE(UF_SIX, 6.0f); 956 UNIFORM_CASE(UF_SEVEN, 7.0f); 957 UNIFORM_CASE(UF_EIGHT, 8.0f); 958 959 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f); 960 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f); 961 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f); 962 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f); 963 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f); 964 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f); 965 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f); 966 967 // Vec2 968 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f)); 969 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f)); 970 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f)); 971 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f)); 972 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f)); 973 974 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f)); 975 976 // Vec3 977 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f)); 978 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f)); 979 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f)); 980 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f)); 981 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f)); 982 983 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f)); 984 985 // Vec4 986 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f)); 987 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f)); 988 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f)); 989 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f)); 990 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f)); 991 992 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f)); 993 994 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 995 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f)); 996 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 997 998 default: 999 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage; 1000 break; 1001 } 1002 1003 #undef UNIFORM_CASE 1004 } 1005 1006 const tcu::UVec2 ShaderRenderCaseInstance::getViewportSize (void) const 1007 { 1008 return tcu::UVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH), 1009 de::min(m_renderSize.y(), MAX_RENDER_HEIGHT)); 1010 } 1011 1012 void ShaderRenderCaseInstance::setSampleCount (VkSampleCountFlagBits sampleCount) 1013 { 1014 m_sampleCount = sampleCount; 1015 } 1016 1017 bool ShaderRenderCaseInstance::isMultiSampling (void) const 1018 { 1019 return m_sampleCount != VK_SAMPLE_COUNT_1_BIT; 1020 } 1021 1022 void ShaderRenderCaseInstance::uploadImage (const tcu::TextureFormat& texFormat, 1023 const TextureData& textureData, 1024 const tcu::Sampler& refSampler, 1025 deUint32 mipLevels, 1026 deUint32 arrayLayers, 1027 VkImage destImage) 1028 { 1029 const VkDevice vkDevice = getDevice(); 1030 const DeviceInterface& vk = getDeviceInterface(); 1031 const VkQueue queue = getUniversalQueue(); 1032 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 1033 1034 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE; 1035 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 1036 deUint32 bufferSize = 0u; 1037 Move<VkBuffer> buffer; 1038 de::MovePtr<Allocation> bufferAlloc; 1039 Move<VkCommandPool> cmdPool; 1040 Move<VkCommandBuffer> cmdBuffer; 1041 Move<VkFence> fence; 1042 std::vector<VkBufferImageCopy> copyRegions; 1043 std::vector<deUint32> offsetMultiples; 1044 1045 offsetMultiples.push_back(4u); 1046 offsetMultiples.push_back(texFormat.getPixelSize()); 1047 1048 // Calculate buffer size 1049 for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit) 1050 { 1051 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit) 1052 { 1053 const tcu::ConstPixelBufferAccess& access = *lit; 1054 1055 bufferSize = getNextMultiple(offsetMultiples, bufferSize); 1056 bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize(); 1057 } 1058 } 1059 1060 // Create source buffer 1061 { 1062 const VkBufferCreateInfo bufferParams = 1063 { 1064 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1065 DE_NULL, // const void* pNext; 1066 0u, // VkBufferCreateFlags flags; 1067 bufferSize, // VkDeviceSize size; 1068 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 1069 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1070 0u, // deUint32 queueFamilyIndexCount; 1071 DE_NULL, // const deUint32* pQueueFamilyIndices; 1072 }; 1073 1074 buffer = createBuffer(vk, vkDevice, &bufferParams); 1075 bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 1076 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 1077 } 1078 1079 // Create command pool and buffer 1080 { 1081 const VkCommandPoolCreateInfo cmdPoolParams = 1082 { 1083 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1084 DE_NULL, // const void* pNext; 1085 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags; 1086 queueFamilyIndex, // deUint32 queueFamilyIndex; 1087 }; 1088 1089 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1090 1091 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 1092 { 1093 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1094 DE_NULL, // const void* pNext; 1095 *cmdPool, // VkCommandPool commandPool; 1096 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 1097 1u, // deUint32 bufferCount; 1098 }; 1099 1100 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo); 1101 } 1102 1103 // Create fence 1104 { 1105 const VkFenceCreateInfo fenceParams = 1106 { 1107 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 1108 DE_NULL, // const void* pNext; 1109 0u // VkFenceCreateFlags flags; 1110 }; 1111 1112 fence = createFence(vk, vkDevice, &fenceParams); 1113 } 1114 1115 // Barriers for copying buffer to image 1116 const VkBufferMemoryBarrier preBufferBarrier = 1117 { 1118 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1119 DE_NULL, // const void* pNext; 1120 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 1121 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1122 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1123 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1124 *buffer, // VkBuffer buffer; 1125 0u, // VkDeviceSize offset; 1126 bufferSize // VkDeviceSize size; 1127 }; 1128 1129 const VkImageMemoryBarrier preImageBarrier = 1130 { 1131 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1132 DE_NULL, // const void* pNext; 1133 0u, // VkAccessFlags srcAccessMask; 1134 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1135 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1136 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 1137 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1138 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1139 destImage, // VkImage image; 1140 { // VkImageSubresourceRange subresourceRange; 1141 aspectMask, // VkImageAspect aspect; 1142 0u, // deUint32 baseMipLevel; 1143 mipLevels, // deUint32 mipLevels; 1144 0u, // deUint32 baseArraySlice; 1145 arrayLayers // deUint32 arraySize; 1146 } 1147 }; 1148 1149 const VkImageMemoryBarrier postImageBarrier = 1150 { 1151 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1152 DE_NULL, // const void* pNext; 1153 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1154 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 1155 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1156 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout; 1157 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1158 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1159 destImage, // VkImage image; 1160 { // VkImageSubresourceRange subresourceRange; 1161 aspectMask, // VkImageAspect aspect; 1162 0u, // deUint32 baseMipLevel; 1163 mipLevels, // deUint32 mipLevels; 1164 0u, // deUint32 baseArraySlice; 1165 arrayLayers // deUint32 arraySize; 1166 } 1167 }; 1168 1169 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1170 { 1171 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1172 DE_NULL, // const void* pNext; 1173 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 1174 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1175 }; 1176 1177 // Get copy regions and write buffer data 1178 { 1179 deUint32 layerDataOffset = 0; 1180 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr(); 1181 1182 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++) 1183 { 1184 const TextureLayerData& layerData = textureData[levelNdx]; 1185 1186 for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++) 1187 { 1188 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset); 1189 1190 const tcu::ConstPixelBufferAccess& access = layerData[layerNdx]; 1191 const tcu::PixelBufferAccess destAccess (access.getFormat(), access.getSize(), destPtr + layerDataOffset); 1192 1193 const VkBufferImageCopy layerRegion = 1194 { 1195 layerDataOffset, // VkDeviceSize bufferOffset; 1196 (deUint32)access.getWidth(), // deUint32 bufferRowLength; 1197 (deUint32)access.getHeight(), // deUint32 bufferImageHeight; 1198 { // VkImageSubresourceLayers imageSubresource; 1199 aspectMask, // VkImageAspectFlags aspectMask; 1200 (deUint32)levelNdx, // uint32_t mipLevel; 1201 (deUint32)layerNdx, // uint32_t baseArrayLayer; 1202 1u // uint32_t layerCount; 1203 }, 1204 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 1205 { // VkExtent3D imageExtent; 1206 (deUint32)access.getWidth(), 1207 (deUint32)access.getHeight(), 1208 (deUint32)access.getDepth() 1209 } 1210 }; 1211 1212 copyRegions.push_back(layerRegion); 1213 tcu::copy(destAccess, access); 1214 1215 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize(); 1216 } 1217 } 1218 } 1219 1220 flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize); 1221 1222 // Copy buffer to image 1223 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 1224 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier); 1225 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data()); 1226 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); 1227 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1228 1229 const VkSubmitInfo submitInfo = 1230 { 1231 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 1232 DE_NULL, // const void* pNext; 1233 0u, // deUint32 waitSemaphoreCount; 1234 DE_NULL, // const VkSemaphore* pWaitSemaphores; 1235 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 1236 1u, // deUint32 commandBufferCount; 1237 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 1238 0u, // deUint32 signalSemaphoreCount; 1239 DE_NULL // const VkSemaphore* pSignalSemaphores; 1240 }; 1241 1242 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 1243 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */)); 1244 } 1245 1246 void ShaderRenderCaseInstance::clearImage (const tcu::Sampler& refSampler, 1247 deUint32 mipLevels, 1248 deUint32 arrayLayers, 1249 VkImage destImage) 1250 { 1251 const VkDevice vkDevice = m_context.getDevice(); 1252 const DeviceInterface& vk = m_context.getDeviceInterface(); 1253 const VkQueue queue = m_context.getUniversalQueue(); 1254 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1255 1256 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE; 1257 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 1258 Move<VkCommandPool> cmdPool; 1259 Move<VkCommandBuffer> cmdBuffer; 1260 Move<VkFence> fence; 1261 1262 VkClearValue clearValue; 1263 deMemset(&clearValue, 0, sizeof(clearValue)); 1264 1265 1266 // Create command pool and buffer 1267 { 1268 const VkCommandPoolCreateInfo cmdPoolParams = 1269 { 1270 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1271 DE_NULL, // const void* pNext; 1272 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags; 1273 queueFamilyIndex, // deUint32 queueFamilyIndex; 1274 }; 1275 1276 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1277 1278 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 1279 { 1280 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1281 DE_NULL, // const void* pNext; 1282 *cmdPool, // VkCommandPool commandPool; 1283 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 1284 1u, // deUint32 bufferCount; 1285 }; 1286 1287 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo); 1288 } 1289 1290 // Create fence 1291 { 1292 const VkFenceCreateInfo fenceParams = 1293 { 1294 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 1295 DE_NULL, // const void* pNext; 1296 0u // VkFenceCreateFlags flags; 1297 }; 1298 1299 fence = createFence(vk, vkDevice, &fenceParams); 1300 } 1301 1302 const VkImageMemoryBarrier preImageBarrier = 1303 { 1304 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1305 DE_NULL, // const void* pNext; 1306 0u, // VkAccessFlags srcAccessMask; 1307 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1308 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1309 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 1310 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1311 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1312 destImage, // VkImage image; 1313 { // VkImageSubresourceRange subresourceRange; 1314 aspectMask, // VkImageAspect aspect; 1315 0u, // deUint32 baseMipLevel; 1316 mipLevels, // deUint32 mipLevels; 1317 0u, // deUint32 baseArraySlice; 1318 arrayLayers // deUint32 arraySize; 1319 } 1320 }; 1321 1322 const VkImageMemoryBarrier postImageBarrier = 1323 { 1324 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1325 DE_NULL, // const void* pNext; 1326 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1327 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 1328 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1329 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout; 1330 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1331 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1332 destImage, // VkImage image; 1333 { // VkImageSubresourceRange subresourceRange; 1334 aspectMask, // VkImageAspect aspect; 1335 0u, // deUint32 baseMipLevel; 1336 mipLevels, // deUint32 mipLevels; 1337 0u, // deUint32 baseArraySlice; 1338 arrayLayers // deUint32 arraySize; 1339 } 1340 }; 1341 1342 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1343 { 1344 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1345 DE_NULL, // const void* pNext; 1346 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 1347 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1348 }; 1349 1350 1351 const VkImageSubresourceRange clearRange = 1352 { 1353 aspectMask, // VkImageAspectFlags aspectMask; 1354 0u, // deUint32 baseMipLevel; 1355 mipLevels, // deUint32 levelCount; 1356 0u, // deUint32 baseArrayLayer; 1357 arrayLayers // deUint32 layerCount; 1358 }; 1359 1360 // Copy buffer to image 1361 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 1362 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier); 1363 if (aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) 1364 { 1365 vk.cmdClearColorImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &clearRange); 1366 } 1367 else 1368 { 1369 vk.cmdClearDepthStencilImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &clearRange); 1370 } 1371 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); 1372 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1373 1374 const VkSubmitInfo submitInfo = 1375 { 1376 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 1377 DE_NULL, // const void* pNext; 1378 0u, // deUint32 waitSemaphoreCount; 1379 DE_NULL, // const VkSemaphore* pWaitSemaphores; 1380 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 1381 1u, // deUint32 commandBufferCount; 1382 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 1383 0u, // deUint32 signalSemaphoreCount; 1384 DE_NULL // const VkSemaphore* pSignalSemaphores; 1385 }; 1386 1387 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 1388 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */)); 1389 } 1390 1391 // Sparse utility function 1392 Move<VkSemaphore> makeSemaphore (const DeviceInterface& vk, const VkDevice device) 1393 { 1394 const VkSemaphoreCreateInfo semaphoreCreateInfo = 1395 { 1396 VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, 1397 DE_NULL, 1398 0u 1399 }; 1400 1401 return createSemaphore(vk, device, &semaphoreCreateInfo); 1402 } 1403 1404 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel) 1405 { 1406 VkExtent3D result; 1407 1408 result.width = std::max(baseExtents.width >> mipLevel, 1u); 1409 result.height = std::max(baseExtents.height >> mipLevel, 1u); 1410 result.depth = std::max(baseExtents.depth >> mipLevel, 1u); 1411 1412 return result; 1413 } 1414 1415 tcu::UVec3 alignedDivide (const VkExtent3D& extent, const VkExtent3D& divisor) 1416 { 1417 tcu::UVec3 result; 1418 1419 result.x() = extent.width / divisor.width + ((extent.width % divisor.width != 0) ? 1u : 0u); 1420 result.y() = extent.height / divisor.height + ((extent.height % divisor.height != 0) ? 1u : 0u); 1421 result.z() = extent.depth / divisor.depth + ((extent.depth % divisor.depth != 0) ? 1u : 0u); 1422 1423 return result; 1424 } 1425 1426 bool isImageSizeSupported (const VkImageType imageType, const tcu::UVec3& imageSize, const vk::VkPhysicalDeviceLimits& limits) 1427 { 1428 switch (imageType) 1429 { 1430 case VK_IMAGE_TYPE_1D: 1431 return (imageSize.x() <= limits.maxImageDimension1D 1432 && imageSize.y() == 1 1433 && imageSize.z() == 1); 1434 case VK_IMAGE_TYPE_2D: 1435 return (imageSize.x() <= limits.maxImageDimension2D 1436 && imageSize.y() <= limits.maxImageDimension2D 1437 && imageSize.z() == 1); 1438 case VK_IMAGE_TYPE_3D: 1439 return (imageSize.x() <= limits.maxImageDimension3D 1440 && imageSize.y() <= limits.maxImageDimension3D 1441 && imageSize.z() <= limits.maxImageDimension3D); 1442 default: 1443 DE_FATAL("Unknown image type"); 1444 return false; 1445 } 1446 } 1447 1448 void ShaderRenderCaseInstance::checkSparseSupport (const VkImageType imageType) const 1449 { 1450 const InstanceInterface& instance = getInstanceInterface(); 1451 const VkPhysicalDevice physicalDevice = getPhysicalDevice(); 1452 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice); 1453 1454 if (!deviceFeatures.shaderResourceResidency) 1455 TCU_THROW(NotSupportedError, "Required feature: shaderResourceResidency."); 1456 1457 if (!deviceFeatures.sparseBinding) 1458 TCU_THROW(NotSupportedError, "Required feature: sparseBinding."); 1459 1460 if (imageType == VK_IMAGE_TYPE_2D && !deviceFeatures.sparseResidencyImage2D) 1461 TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage2D."); 1462 1463 if (imageType == VK_IMAGE_TYPE_3D && !deviceFeatures.sparseResidencyImage3D) 1464 TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage3D."); 1465 } 1466 1467 void ShaderRenderCaseInstance::uploadSparseImage (const tcu::TextureFormat& texFormat, 1468 const TextureData& textureData, 1469 const tcu::Sampler& refSampler, 1470 const deUint32 mipLevels, 1471 const deUint32 arrayLayers, 1472 const VkImage sparseImage, 1473 const VkImageCreateInfo& imageCreateInfo, 1474 const tcu::UVec3 texSize) 1475 { 1476 const VkDevice vkDevice = getDevice(); 1477 const DeviceInterface& vk = getDeviceInterface(); 1478 const VkPhysicalDevice physicalDevice = getPhysicalDevice(); 1479 const VkQueue queue = getUniversalQueue(); 1480 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 1481 const InstanceInterface& instance = getInstanceInterface(); 1482 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice); 1483 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice); 1484 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE; 1485 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 1486 1487 const Unique<VkSemaphore> imageMemoryBindSemaphore(makeSemaphore(vk, vkDevice)); 1488 deUint32 bufferSize = 0u; 1489 std::vector<deUint32> offsetMultiples; 1490 offsetMultiples.push_back(4u); 1491 offsetMultiples.push_back(texFormat.getPixelSize()); 1492 1493 if (isImageSizeSupported(imageCreateInfo.imageType, texSize, deviceProperties.limits) == false) 1494 TCU_THROW(NotSupportedError, "Image size not supported for device."); 1495 1496 // Calculate buffer size 1497 for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit) 1498 { 1499 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit) 1500 { 1501 const tcu::ConstPixelBufferAccess& access = *lit; 1502 1503 bufferSize = getNextMultiple(offsetMultiples, bufferSize); 1504 bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize(); 1505 } 1506 } 1507 1508 { 1509 deUint32 sparseMemoryReqCount = 0; 1510 1511 vk.getImageSparseMemoryRequirements(vkDevice, sparseImage, &sparseMemoryReqCount, DE_NULL); 1512 1513 DE_ASSERT(sparseMemoryReqCount != 0); 1514 1515 std::vector<VkSparseImageMemoryRequirements> sparseImageMemoryRequirements; 1516 sparseImageMemoryRequirements.resize(sparseMemoryReqCount); 1517 1518 vk.getImageSparseMemoryRequirements(vkDevice, sparseImage, &sparseMemoryReqCount, &sparseImageMemoryRequirements[0]); 1519 1520 const deUint32 noMatchFound = ~((deUint32)0); 1521 1522 deUint32 colorAspectIndex = noMatchFound; 1523 for (deUint32 memoryReqNdx = 0; memoryReqNdx < sparseMemoryReqCount; ++memoryReqNdx) 1524 { 1525 if (sparseImageMemoryRequirements[memoryReqNdx].formatProperties.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) 1526 { 1527 colorAspectIndex = memoryReqNdx; 1528 break; 1529 } 1530 } 1531 1532 if (colorAspectIndex == noMatchFound) 1533 TCU_THROW(NotSupportedError, "Not supported image aspect - the test supports currently only VK_IMAGE_ASPECT_COLOR_BIT."); 1534 1535 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vk, vkDevice, sparseImage); 1536 1537 deUint32 memoryType = noMatchFound; 1538 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx) 1539 { 1540 if ((memoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 && 1541 MemoryRequirement::Any.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags)) 1542 { 1543 memoryType = memoryTypeNdx; 1544 break; 1545 } 1546 } 1547 1548 if (memoryType == noMatchFound) 1549 TCU_THROW(NotSupportedError, "No matching memory type found."); 1550 1551 if (memoryRequirements.size > deviceProperties.limits.sparseAddressSpaceSize) 1552 TCU_THROW(NotSupportedError, "Required memory size for sparse resource exceeds device limits."); 1553 1554 // Check if the image format supports sparse oprerations 1555 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = 1556 getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.samples, imageCreateInfo.usage, imageCreateInfo.tiling); 1557 1558 if (sparseImageFormatPropVec.size() == 0) 1559 TCU_THROW(NotSupportedError, "The image format does not support sparse operations."); 1560 1561 const VkSparseImageMemoryRequirements aspectRequirements = sparseImageMemoryRequirements[colorAspectIndex]; 1562 const VkExtent3D imageGranularity = aspectRequirements.formatProperties.imageGranularity; 1563 1564 std::vector<VkSparseImageMemoryBind> imageResidencyMemoryBinds; 1565 std::vector<VkSparseMemoryBind> imageMipTailMemoryBinds; 1566 1567 for (deUint32 layerNdx = 0; layerNdx < arrayLayers; ++ layerNdx) 1568 { 1569 for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx) 1570 { 1571 const VkExtent3D mipExtent = mipLevelExtents(imageCreateInfo.extent, mipLevelNdx); 1572 const tcu::UVec3 numSparseBinds = alignedDivide(mipExtent, imageGranularity); 1573 const tcu::UVec3 lastBlockExtent = tcu::UVec3(mipExtent.width % imageGranularity.width ? mipExtent.width % imageGranularity.width : imageGranularity.width, 1574 mipExtent.height % imageGranularity.height ? mipExtent.height % imageGranularity.height : imageGranularity.height, 1575 mipExtent.depth % imageGranularity.depth ? mipExtent.depth % imageGranularity.depth : imageGranularity.depth ); 1576 1577 for (deUint32 z = 0; z < numSparseBinds.z(); ++z) 1578 for (deUint32 y = 0; y < numSparseBinds.y(); ++y) 1579 for (deUint32 x = 0; x < numSparseBinds.x(); ++x) 1580 { 1581 const VkMemoryRequirements allocRequirements = 1582 { 1583 // 28.7.5 alignment shows the block size in bytes 1584 memoryRequirements.alignment, // VkDeviceSize size; 1585 memoryRequirements.alignment, // VkDeviceSize alignment; 1586 memoryRequirements.memoryTypeBits, // uint32_t memoryTypeBits; 1587 }; 1588 1589 de::SharedPtr<Allocation> allocation(m_memAlloc.allocate(allocRequirements, MemoryRequirement::Any).release()); 1590 1591 m_allocations.push_back(allocation); 1592 1593 VkOffset3D offset; 1594 offset.x = x*imageGranularity.width; 1595 offset.y = y*imageGranularity.height; 1596 offset.z = z*imageGranularity.depth; 1597 1598 VkExtent3D extent; 1599 extent.width = (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : imageGranularity.width; 1600 extent.height = (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : imageGranularity.height; 1601 extent.depth = (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : imageGranularity.depth; 1602 1603 const VkSparseImageMemoryBind imageMemoryBind = 1604 { 1605 { 1606 aspectMask, // VkImageAspectFlags aspectMask; 1607 mipLevelNdx,// uint32_t mipLevel; 1608 layerNdx, // uint32_t arrayLayer; 1609 }, // VkImageSubresource subresource; 1610 offset, // VkOffset3D offset; 1611 extent, // VkExtent3D extent; 1612 allocation->getMemory(), // VkDeviceMemory memory; 1613 allocation->getOffset(), // VkDeviceSize memoryOffset; 1614 0u, // VkSparseMemoryBindFlags flags; 1615 }; 1616 1617 imageResidencyMemoryBinds.push_back(imageMemoryBind); 1618 } 1619 } 1620 1621 // Handle MIP tail. There are two cases to consider here: 1622 // 1623 // 1) VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is requested by the driver: each layer needs a separate tail. 1624 // 2) otherwise: only one tail is needed. 1625 { 1626 if ( imageMipTailMemoryBinds.size() == 0 || 1627 (imageMipTailMemoryBinds.size() != 0 && (aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) == 0)) 1628 { 1629 const VkMemoryRequirements allocRequirements = 1630 { 1631 aspectRequirements.imageMipTailSize, // VkDeviceSize size; 1632 memoryRequirements.alignment, // VkDeviceSize alignment; 1633 memoryRequirements.memoryTypeBits, // uint32_t memoryTypeBits; 1634 }; 1635 1636 const de::SharedPtr<Allocation> allocation(m_memAlloc.allocate(allocRequirements, MemoryRequirement::Any).release()); 1637 1638 const VkSparseMemoryBind imageMipTailMemoryBind = 1639 { 1640 aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride, // VkDeviceSize resourceOffset; 1641 aspectRequirements.imageMipTailSize, // VkDeviceSize size; 1642 allocation->getMemory(), // VkDeviceMemory memory; 1643 allocation->getOffset(), // VkDeviceSize memoryOffset; 1644 0u, // VkSparseMemoryBindFlags flags; 1645 }; 1646 1647 m_allocations.push_back(allocation); 1648 imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind); 1649 } 1650 } 1651 } 1652 1653 VkBindSparseInfo bindSparseInfo = 1654 { 1655 VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, //VkStructureType sType; 1656 DE_NULL, //const void* pNext; 1657 0u, //deUint32 waitSemaphoreCount; 1658 DE_NULL, //const VkSemaphore* pWaitSemaphores; 1659 0u, //deUint32 bufferBindCount; 1660 DE_NULL, //const VkSparseBufferMemoryBindInfo* pBufferBinds; 1661 0u, //deUint32 imageOpaqueBindCount; 1662 DE_NULL, //const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds; 1663 0u, //deUint32 imageBindCount; 1664 DE_NULL, //const VkSparseImageMemoryBindInfo* pImageBinds; 1665 1u, //deUint32 signalSemaphoreCount; 1666 &imageMemoryBindSemaphore.get() //const VkSemaphore* pSignalSemaphores; 1667 }; 1668 1669 VkSparseImageMemoryBindInfo imageResidencyBindInfo; 1670 VkSparseImageOpaqueMemoryBindInfo imageMipTailBindInfo; 1671 1672 if (imageResidencyMemoryBinds.size() > 0) 1673 { 1674 imageResidencyBindInfo.image = sparseImage; 1675 imageResidencyBindInfo.bindCount = static_cast<deUint32>(imageResidencyMemoryBinds.size()); 1676 imageResidencyBindInfo.pBinds = &imageResidencyMemoryBinds[0]; 1677 1678 bindSparseInfo.imageBindCount = 1u; 1679 bindSparseInfo.pImageBinds = &imageResidencyBindInfo; 1680 } 1681 1682 if (imageMipTailMemoryBinds.size() > 0) 1683 { 1684 imageMipTailBindInfo.image = sparseImage; 1685 imageMipTailBindInfo.bindCount = static_cast<deUint32>(imageMipTailMemoryBinds.size()); 1686 imageMipTailBindInfo.pBinds = &imageMipTailMemoryBinds[0]; 1687 1688 bindSparseInfo.imageOpaqueBindCount = 1u; 1689 bindSparseInfo.pImageOpaqueBinds = &imageMipTailBindInfo; 1690 } 1691 1692 VK_CHECK(vk.queueBindSparse(queue, 1u, &bindSparseInfo, DE_NULL)); 1693 } 1694 1695 Move<VkCommandPool> cmdPool; 1696 Move<VkCommandBuffer> cmdBuffer; 1697 // Create command pool 1698 { 1699 const VkCommandPoolCreateInfo cmdPoolParams = 1700 { 1701 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1702 DE_NULL, // const void* pNext; 1703 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags; 1704 queueFamilyIndex, // deUint32 queueFamilyIndex; 1705 }; 1706 1707 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1708 } 1709 1710 { 1711 // Create command buffer 1712 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 1713 { 1714 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1715 DE_NULL, // const void* pNext; 1716 *cmdPool, // VkCommandPool commandPool; 1717 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 1718 1u, // deUint32 bufferCount; 1719 }; 1720 1721 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo); 1722 } 1723 1724 // Create source buffer 1725 const VkBufferCreateInfo bufferParams = 1726 { 1727 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1728 DE_NULL, // const void* pNext; 1729 0u, // VkBufferCreateFlags flags; 1730 bufferSize, // VkDeviceSize size; 1731 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 1732 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1733 0u, // deUint32 queueFamilyIndexCount; 1734 DE_NULL, // const deUint32* pQueueFamilyIndices; 1735 }; 1736 1737 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &bufferParams); 1738 de::MovePtr<Allocation> bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 1739 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 1740 1741 // Barriers for copying buffer to image 1742 const VkBufferMemoryBarrier preBufferBarrier = 1743 { 1744 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1745 DE_NULL, // const void* pNext; 1746 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 1747 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1748 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1749 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1750 *buffer, // VkBuffer buffer; 1751 0u, // VkDeviceSize offset; 1752 bufferSize // VkDeviceSize size; 1753 }; 1754 1755 const VkImageMemoryBarrier preImageBarrier = 1756 { 1757 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1758 DE_NULL, // const void* pNext; 1759 0u, // VkAccessFlags srcAccessMask; 1760 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1761 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1762 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 1763 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1764 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1765 sparseImage, // VkImage image; 1766 { // VkImageSubresourceRange subresourceRange; 1767 aspectMask, // VkImageAspect aspect; 1768 0u, // deUint32 baseMipLevel; 1769 mipLevels, // deUint32 mipLevels; 1770 0u, // deUint32 baseArraySlice; 1771 arrayLayers // deUint32 arraySize; 1772 } 1773 }; 1774 1775 const VkImageMemoryBarrier postImageBarrier = 1776 { 1777 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1778 DE_NULL, // const void* pNext; 1779 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1780 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 1781 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1782 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout; 1783 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1784 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1785 sparseImage, // VkImage image; 1786 { // VkImageSubresourceRange subresourceRange; 1787 aspectMask, // VkImageAspect aspect; 1788 0u, // deUint32 baseMipLevel; 1789 mipLevels, // deUint32 mipLevels; 1790 0u, // deUint32 baseArraySlice; 1791 arrayLayers // deUint32 arraySize; 1792 } 1793 }; 1794 1795 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1796 { 1797 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1798 DE_NULL, // const void* pNext; 1799 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 1800 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1801 }; 1802 1803 std::vector<VkBufferImageCopy> copyRegions; 1804 // Get copy regions and write buffer data 1805 { 1806 deUint32 layerDataOffset = 0; 1807 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr(); 1808 1809 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++) 1810 { 1811 const TextureLayerData& layerData = textureData[levelNdx]; 1812 1813 for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++) 1814 { 1815 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset); 1816 1817 const tcu::ConstPixelBufferAccess& access = layerData[layerNdx]; 1818 const tcu::PixelBufferAccess destAccess (access.getFormat(), access.getSize(), destPtr + layerDataOffset); 1819 1820 const VkBufferImageCopy layerRegion = 1821 { 1822 layerDataOffset, // VkDeviceSize bufferOffset; 1823 (deUint32)access.getWidth(), // deUint32 bufferRowLength; 1824 (deUint32)access.getHeight(), // deUint32 bufferImageHeight; 1825 { // VkImageSubresourceLayers imageSubresource; 1826 aspectMask, // VkImageAspectFlags aspectMask; 1827 (deUint32)levelNdx, // uint32_t mipLevel; 1828 (deUint32)layerNdx, // uint32_t baseArrayLayer; 1829 1u // uint32_t layerCount; 1830 }, 1831 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 1832 { // VkExtent3D imageExtent; 1833 (deUint32)access.getWidth(), 1834 (deUint32)access.getHeight(), 1835 (deUint32)access.getDepth() 1836 } 1837 }; 1838 1839 copyRegions.push_back(layerRegion); 1840 tcu::copy(destAccess, access); 1841 1842 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize(); 1843 } 1844 } 1845 } 1846 1847 // Copy buffer to image 1848 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 1849 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier); 1850 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, sparseImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data()); 1851 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); 1852 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1853 1854 const VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; 1855 1856 const VkSubmitInfo submitInfo = 1857 { 1858 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 1859 DE_NULL, // const void* pNext; 1860 1u, // deUint32 waitSemaphoreCount; 1861 &imageMemoryBindSemaphore.get(), // const VkSemaphore* pWaitSemaphores; 1862 &pipelineStageFlags, // const VkPipelineStageFlags* pWaitDstStageMask; 1863 1u, // deUint32 commandBufferCount; 1864 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 1865 0u, // deUint32 signalSemaphoreCount; 1866 DE_NULL // const VkSemaphore* pSignalSemaphores; 1867 }; 1868 1869 const VkFenceCreateInfo fenceParams = 1870 { 1871 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 1872 DE_NULL, // const void* pNext; 1873 0u // VkFenceCreateFlags flags; 1874 }; 1875 1876 Move<VkFence> fence = createFence(vk, vkDevice, &fenceParams); 1877 1878 try 1879 { 1880 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 1881 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */)); 1882 } 1883 catch (...) 1884 { 1885 VK_CHECK(vk.deviceWaitIdle(vkDevice)); 1886 throw; 1887 } 1888 } 1889 1890 void ShaderRenderCaseInstance::useSampler (deUint32 bindingLocation, deUint32 textureId) 1891 { 1892 DE_ASSERT(textureId < m_textures.size()); 1893 1894 const TextureBinding& textureBinding = *m_textures[textureId]; 1895 const TextureBinding::Type textureType = textureBinding.getType(); 1896 const tcu::Sampler& refSampler = textureBinding.getSampler(); 1897 const TextureBinding::Parameters& textureParams = textureBinding.getParameters(); 1898 const bool isMSTexture = textureParams.samples != vk::VK_SAMPLE_COUNT_1_BIT; 1899 deUint32 mipLevels = 1u; 1900 deUint32 arrayLayers = 1u; 1901 tcu::TextureFormat texFormat; 1902 tcu::UVec3 texSize; 1903 TextureData textureData; 1904 1905 if (textureType == TextureBinding::TYPE_2D) 1906 { 1907 const tcu::Texture2D& texture = textureBinding.get2D(); 1908 1909 texFormat = texture.getFormat(); 1910 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u); 1911 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1912 arrayLayers = 1u; 1913 1914 textureData.resize(mipLevels); 1915 1916 for (deUint32 level = 0; level < mipLevels; ++level) 1917 { 1918 if (texture.isLevelEmpty(level)) 1919 continue; 1920 1921 textureData[level].push_back(texture.getLevel(level)); 1922 } 1923 } 1924 else if (textureType == TextureBinding::TYPE_CUBE_MAP) 1925 { 1926 const tcu::TextureCube& texture = textureBinding.getCube(); 1927 1928 texFormat = texture.getFormat(); 1929 texSize = tcu::UVec3(texture.getSize(), texture.getSize(), 1u); 1930 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1931 arrayLayers = 6u; 1932 1933 static const tcu::CubeFace cubeFaceMapping[tcu::CUBEFACE_LAST] = 1934 { 1935 tcu::CUBEFACE_POSITIVE_X, 1936 tcu::CUBEFACE_NEGATIVE_X, 1937 tcu::CUBEFACE_POSITIVE_Y, 1938 tcu::CUBEFACE_NEGATIVE_Y, 1939 tcu::CUBEFACE_POSITIVE_Z, 1940 tcu::CUBEFACE_NEGATIVE_Z 1941 }; 1942 1943 textureData.resize(mipLevels); 1944 1945 for (deUint32 level = 0; level < mipLevels; ++level) 1946 { 1947 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx) 1948 { 1949 tcu::CubeFace face = cubeFaceMapping[faceNdx]; 1950 1951 if (texture.isLevelEmpty(face, level)) 1952 continue; 1953 1954 textureData[level].push_back(texture.getLevelFace(level, face)); 1955 } 1956 } 1957 } 1958 else if (textureType == TextureBinding::TYPE_2D_ARRAY) 1959 { 1960 const tcu::Texture2DArray& texture = textureBinding.get2DArray(); 1961 1962 texFormat = texture.getFormat(); 1963 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u); 1964 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1965 arrayLayers = (deUint32)texture.getNumLayers(); 1966 1967 textureData.resize(mipLevels); 1968 1969 for (deUint32 level = 0; level < mipLevels; ++level) 1970 { 1971 if (texture.isLevelEmpty(level)) 1972 continue; 1973 1974 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level); 1975 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 1976 1977 for (deUint32 layer = 0; layer < arrayLayers; ++layer) 1978 { 1979 const deUint32 layerOffset = layerSize * layer; 1980 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 1981 textureData[level].push_back(layerData); 1982 } 1983 } 1984 } 1985 else if (textureType == TextureBinding::TYPE_3D) 1986 { 1987 const tcu::Texture3D& texture = textureBinding.get3D(); 1988 1989 texFormat = texture.getFormat(); 1990 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), texture.getDepth()); 1991 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1992 arrayLayers = 1u; 1993 1994 textureData.resize(mipLevels); 1995 1996 for (deUint32 level = 0; level < mipLevels; ++level) 1997 { 1998 if (texture.isLevelEmpty(level)) 1999 continue; 2000 2001 textureData[level].push_back(texture.getLevel(level)); 2002 } 2003 } 2004 else if (textureType == TextureBinding::TYPE_1D) 2005 { 2006 const tcu::Texture1D& texture = textureBinding.get1D(); 2007 2008 texFormat = texture.getFormat(); 2009 texSize = tcu::UVec3(texture.getWidth(), 1, 1); 2010 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 2011 arrayLayers = 1u; 2012 2013 textureData.resize(mipLevels); 2014 2015 for (deUint32 level = 0; level < mipLevels; ++level) 2016 { 2017 if (texture.isLevelEmpty(level)) 2018 continue; 2019 2020 textureData[level].push_back(texture.getLevel(level)); 2021 } 2022 } 2023 else if (textureType == TextureBinding::TYPE_1D_ARRAY) 2024 { 2025 const tcu::Texture1DArray& texture = textureBinding.get1DArray(); 2026 2027 texFormat = texture.getFormat(); 2028 texSize = tcu::UVec3(texture.getWidth(), 1, 1); 2029 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 2030 arrayLayers = (deUint32)texture.getNumLayers(); 2031 2032 textureData.resize(mipLevels); 2033 2034 for (deUint32 level = 0; level < mipLevels; ++level) 2035 { 2036 if (texture.isLevelEmpty(level)) 2037 continue; 2038 2039 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level); 2040 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize(); 2041 2042 for (deUint32 layer = 0; layer < arrayLayers; ++layer) 2043 { 2044 const deUint32 layerOffset = layerSize * layer; 2045 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 2046 textureData[level].push_back(layerData); 2047 } 2048 } 2049 } 2050 else if (textureType == TextureBinding::TYPE_CUBE_ARRAY) 2051 { 2052 const tcu::TextureCubeArray& texture = textureBinding.getCubeArray(); 2053 texFormat = texture.getFormat(); 2054 texSize = tcu::UVec3(texture.getSize(), texture.getSize(), 1); 2055 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 2056 arrayLayers = texture.getDepth(); 2057 2058 textureData.resize(mipLevels); 2059 2060 for (deUint32 level = 0; level < mipLevels; ++level) 2061 { 2062 if (texture.isLevelEmpty(level)) 2063 continue; 2064 2065 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level); 2066 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 2067 2068 for (deUint32 layer = 0; layer < arrayLayers; ++layer) 2069 { 2070 const deUint32 layerOffset = layerSize * layer; 2071 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 2072 textureData[level].push_back(layerData); 2073 } 2074 } 2075 } 2076 else 2077 { 2078 TCU_THROW(InternalError, "Invalid texture type"); 2079 } 2080 2081 createSamplerUniform(bindingLocation, textureType, textureBinding.getParameters().initialization, texFormat, texSize, textureData, refSampler, mipLevels, arrayLayers, textureParams); 2082 } 2083 2084 void ShaderRenderCaseInstance::setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges) 2085 { 2086 m_pushConstantRanges.clear(); 2087 for (deUint32 i = 0; i < rangeCount; ++i) 2088 { 2089 m_pushConstantRanges.push_back(pcRanges[i]); 2090 } 2091 } 2092 2093 void ShaderRenderCaseInstance::updatePushConstants (vk::VkCommandBuffer, vk::VkPipelineLayout) 2094 { 2095 } 2096 2097 void ShaderRenderCaseInstance::createSamplerUniform (deUint32 bindingLocation, 2098 TextureBinding::Type textureType, 2099 TextureBinding::Init textureInit, 2100 const tcu::TextureFormat& texFormat, 2101 const tcu::UVec3 texSize, 2102 const TextureData& textureData, 2103 const tcu::Sampler& refSampler, 2104 deUint32 mipLevels, 2105 deUint32 arrayLayers, 2106 TextureBinding::Parameters textureParams) 2107 { 2108 const VkDevice vkDevice = getDevice(); 2109 const DeviceInterface& vk = getDeviceInterface(); 2110 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 2111 2112 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE; 2113 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 2114 const VkImageViewType imageViewType = textureTypeToImageViewType(textureType); 2115 const VkImageType imageType = viewTypeToImageType(imageViewType); 2116 const VkFormat format = mapTextureFormat(texFormat); 2117 const bool isCube = imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; 2118 VkImageCreateFlags imageCreateFlags = isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0; 2119 VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 2120 Move<VkImage> vkTexture; 2121 de::MovePtr<Allocation> allocation; 2122 2123 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) 2124 { 2125 checkSparseSupport(imageType); 2126 imageCreateFlags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT; 2127 } 2128 2129 // Create image 2130 const VkImageCreateInfo imageParams = 2131 { 2132 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 2133 DE_NULL, // const void* pNext; 2134 imageCreateFlags, // VkImageCreateFlags flags; 2135 imageType, // VkImageType imageType; 2136 format, // VkFormat format; 2137 { // VkExtent3D extent; 2138 texSize.x(), 2139 texSize.y(), 2140 texSize.z() 2141 }, 2142 mipLevels, // deUint32 mipLevels; 2143 arrayLayers, // deUint32 arrayLayers; 2144 textureParams.samples, // VkSampleCountFlagBits samples; 2145 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 2146 imageUsageFlags, // VkImageUsageFlags usage; 2147 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2148 1u, // deUint32 queueFamilyIndexCount; 2149 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 2150 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 2151 }; 2152 2153 vkTexture = createImage(vk, vkDevice, &imageParams); 2154 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any); 2155 2156 if (m_imageBackingMode != IMAGE_BACKING_MODE_SPARSE) 2157 { 2158 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset())); 2159 } 2160 2161 switch (textureInit) 2162 { 2163 case TextureBinding::INIT_UPLOAD_DATA: 2164 { 2165 // upload*Image functions use cmdCopyBufferToImage, which is invalid for multisample images 2166 DE_ASSERT(textureParams.samples == VK_SAMPLE_COUNT_1_BIT); 2167 2168 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) 2169 { 2170 uploadSparseImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture, imageParams, texSize); 2171 } 2172 else 2173 { 2174 // Upload texture data 2175 uploadImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture); 2176 } 2177 break; 2178 } 2179 case TextureBinding::INIT_CLEAR: 2180 clearImage(refSampler, mipLevels, arrayLayers, *vkTexture); 2181 break; 2182 default: 2183 DE_FATAL("Impossible"); 2184 } 2185 2186 // Create sampler 2187 const VkSamplerCreateInfo samplerParams = mapSampler(refSampler, texFormat); 2188 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams); 2189 const deUint32 baseMipLevel = textureParams.baseMipLevel; 2190 const vk::VkComponentMapping components = textureParams.componentMapping; 2191 const VkImageViewCreateInfo viewParams = 2192 { 2193 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 2194 NULL, // const voide* pNext; 2195 0u, // VkImageViewCreateFlags flags; 2196 *vkTexture, // VkImage image; 2197 imageViewType, // VkImageViewType viewType; 2198 format, // VkFormat format; 2199 components, // VkChannelMapping channels; 2200 { 2201 aspectMask, // VkImageAspectFlags aspectMask; 2202 baseMipLevel, // deUint32 baseMipLevel; 2203 mipLevels - baseMipLevel, // deUint32 mipLevels; 2204 0, // deUint32 baseArraySlice; 2205 arrayLayers // deUint32 arraySize; 2206 }, // VkImageSubresourceRange subresourceRange; 2207 }; 2208 2209 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams); 2210 2211 const vk::VkDescriptorImageInfo descriptor = 2212 { 2213 sampler.get(), // VkSampler sampler; 2214 imageView.get(), // VkImageView imageView; 2215 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout imageLayout; 2216 }; 2217 2218 de::MovePtr<SamplerUniform> uniform(new SamplerUniform()); 2219 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 2220 uniform->descriptor = descriptor; 2221 uniform->location = bindingLocation; 2222 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture)); 2223 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView)); 2224 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler)); 2225 uniform->alloc = AllocationSp(allocation.release()); 2226 2227 m_descriptorSetLayoutBuilder->addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, DE_NULL); 2228 m_descriptorPoolBuilder->addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 2229 2230 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform))); 2231 } 2232 2233 void ShaderRenderCaseInstance::setupDefaultInputs (void) 2234 { 2235 /* Configuration of the vertex input attributes: 2236 a_position is at location 0 2237 a_coords is at location 1 2238 a_unitCoords is at location 2 2239 a_one is at location 3 2240 2241 User attributes starts from at the location 4. 2242 */ 2243 2244 DE_ASSERT(m_quadGrid); 2245 const QuadGrid& quadGrid = *m_quadGrid; 2246 2247 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions()); 2248 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords()); 2249 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords()); 2250 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne()); 2251 2252 static const struct 2253 { 2254 BaseAttributeType type; 2255 int userNdx; 2256 } userAttributes[] = 2257 { 2258 { A_IN0, 0 }, 2259 { A_IN1, 1 }, 2260 { A_IN2, 2 }, 2261 { A_IN3, 3 } 2262 }; 2263 2264 static const struct 2265 { 2266 BaseAttributeType matrixType; 2267 int numCols; 2268 int numRows; 2269 } matrices[] = 2270 { 2271 { MAT2, 2, 2 }, 2272 { MAT2x3, 2, 3 }, 2273 { MAT2x4, 2, 4 }, 2274 { MAT3x2, 3, 2 }, 2275 { MAT3, 3, 3 }, 2276 { MAT3x4, 3, 4 }, 2277 { MAT4x2, 4, 2 }, 2278 { MAT4x3, 4, 3 }, 2279 { MAT4, 4, 4 } 2280 }; 2281 2282 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++) 2283 { 2284 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++) 2285 { 2286 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type) 2287 continue; 2288 2289 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx)); 2290 } 2291 2292 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++) 2293 { 2294 2295 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type) 2296 continue; 2297 2298 const int numCols = matrices[matNdx].numCols; 2299 2300 for (int colNdx = 0; colNdx < numCols; colNdx++) 2301 { 2302 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx)); 2303 } 2304 } 2305 } 2306 } 2307 2308 void ShaderRenderCaseInstance::render (deUint32 numVertices, 2309 deUint32 numTriangles, 2310 const deUint16* indices, 2311 const tcu::Vec4& constCoords) 2312 { 2313 render(numVertices, numTriangles * 3, indices, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, constCoords); 2314 } 2315 2316 void ShaderRenderCaseInstance::render (deUint32 numVertices, 2317 deUint32 numIndices, 2318 const deUint16* indices, 2319 VkPrimitiveTopology topology, 2320 const tcu::Vec4& constCoords) 2321 { 2322 const VkDevice vkDevice = getDevice(); 2323 const DeviceInterface& vk = getDeviceInterface(); 2324 const VkQueue queue = getUniversalQueue(); 2325 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 2326 2327 vk::Move<vk::VkImage> colorImage; 2328 de::MovePtr<vk::Allocation> colorImageAlloc; 2329 vk::Move<vk::VkImageView> colorImageView; 2330 vk::Move<vk::VkImage> resolvedImage; 2331 de::MovePtr<vk::Allocation> resolvedImageAlloc; 2332 vk::Move<vk::VkImageView> resolvedImageView; 2333 vk::Move<vk::VkRenderPass> renderPass; 2334 vk::Move<vk::VkFramebuffer> framebuffer; 2335 vk::Move<vk::VkPipelineLayout> pipelineLayout; 2336 vk::Move<vk::VkPipeline> graphicsPipeline; 2337 vk::Move<vk::VkShaderModule> vertexShaderModule; 2338 vk::Move<vk::VkShaderModule> fragmentShaderModule; 2339 vk::Move<vk::VkBuffer> indexBuffer; 2340 de::MovePtr<vk::Allocation> indexBufferAlloc; 2341 vk::Move<vk::VkDescriptorSetLayout> descriptorSetLayout; 2342 vk::Move<vk::VkDescriptorPool> descriptorPool; 2343 vk::Move<vk::VkDescriptorSet> descriptorSet; 2344 vk::Move<vk::VkCommandPool> cmdPool; 2345 vk::Move<vk::VkCommandBuffer> cmdBuffer; 2346 vk::Move<vk::VkFence> fence; 2347 2348 // Create color image 2349 { 2350 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 2351 VkImageFormatProperties properties; 2352 2353 if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(), 2354 m_colorFormat, 2355 VK_IMAGE_TYPE_2D, 2356 VK_IMAGE_TILING_OPTIMAL, 2357 imageUsage, 2358 0u, 2359 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)) 2360 { 2361 TCU_THROW(NotSupportedError, "Format not supported"); 2362 } 2363 2364 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount) 2365 { 2366 TCU_THROW(NotSupportedError, "Format not supported"); 2367 } 2368 2369 const VkImageCreateInfo colorImageParams = 2370 { 2371 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 2372 DE_NULL, // const void* pNext; 2373 0u, // VkImageCreateFlags flags; 2374 VK_IMAGE_TYPE_2D, // VkImageType imageType; 2375 m_colorFormat, // VkFormat format; 2376 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 2377 1u, // deUint32 mipLevels; 2378 1u, // deUint32 arraySize; 2379 m_sampleCount, // deUint32 samples; 2380 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 2381 imageUsage, // VkImageUsageFlags usage; 2382 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2383 1u, // deUint32 queueFamilyCount; 2384 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 2385 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 2386 }; 2387 2388 colorImage = createImage(vk, vkDevice, &colorImageParams); 2389 2390 // Allocate and bind color image memory 2391 colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any); 2392 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset())); 2393 } 2394 2395 // Create color attachment view 2396 { 2397 const VkImageViewCreateInfo colorImageViewParams = 2398 { 2399 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 2400 DE_NULL, // const void* pNext; 2401 0u, // VkImageViewCreateFlags flags; 2402 *colorImage, // VkImage image; 2403 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 2404 m_colorFormat, // VkFormat format; 2405 { 2406 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r; 2407 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g; 2408 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b; 2409 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a; 2410 }, // VkChannelMapping channels; 2411 { 2412 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 2413 0, // deUint32 baseMipLevel; 2414 1, // deUint32 mipLevels; 2415 0, // deUint32 baseArraySlice; 2416 1 // deUint32 arraySize; 2417 }, // VkImageSubresourceRange subresourceRange; 2418 }; 2419 2420 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams); 2421 } 2422 2423 if (isMultiSampling()) 2424 { 2425 // Resolved Image 2426 { 2427 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 2428 VkImageFormatProperties properties; 2429 2430 if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(), 2431 m_colorFormat, 2432 VK_IMAGE_TYPE_2D, 2433 VK_IMAGE_TILING_OPTIMAL, 2434 imageUsage, 2435 0, 2436 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)) 2437 { 2438 TCU_THROW(NotSupportedError, "Format not supported"); 2439 } 2440 2441 const VkImageCreateInfo imageCreateInfo = 2442 { 2443 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 2444 DE_NULL, // const void* pNext; 2445 0u, // VkImageCreateFlags flags; 2446 VK_IMAGE_TYPE_2D, // VkImageType imageType; 2447 m_colorFormat, // VkFormat format; 2448 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 2449 1u, // deUint32 mipLevels; 2450 1u, // deUint32 arrayLayers; 2451 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 2452 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 2453 imageUsage, // VkImageUsageFlags usage; 2454 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2455 1u, // deUint32 queueFamilyIndexCount; 2456 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 2457 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 2458 }; 2459 2460 resolvedImage = vk::createImage(vk, vkDevice, &imageCreateInfo, DE_NULL); 2461 resolvedImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *resolvedImage), MemoryRequirement::Any); 2462 VK_CHECK(vk.bindImageMemory(vkDevice, *resolvedImage, resolvedImageAlloc->getMemory(), resolvedImageAlloc->getOffset())); 2463 } 2464 2465 // Resolved Image View 2466 { 2467 const VkImageViewCreateInfo imageViewCreateInfo = 2468 { 2469 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 2470 DE_NULL, // const void* pNext; 2471 0u, // VkImageViewCreateFlags flags; 2472 *resolvedImage, // VkImage image; 2473 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 2474 m_colorFormat, // VkFormat format; 2475 { 2476 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r; 2477 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g; 2478 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b; 2479 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a; 2480 }, 2481 { 2482 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 2483 0u, // deUint32 baseMipLevel; 2484 1u, // deUint32 mipLevels; 2485 0u, // deUint32 baseArrayLayer; 2486 1u, // deUint32 arraySize; 2487 }, // VkImageSubresourceRange subresourceRange; 2488 }; 2489 2490 resolvedImageView = vk::createImageView(vk, vkDevice, &imageViewCreateInfo, DE_NULL); 2491 } 2492 } 2493 2494 // Create render pass 2495 { 2496 const VkAttachmentDescription attachmentDescription[] = 2497 { 2498 { 2499 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 2500 m_colorFormat, // VkFormat format; 2501 m_sampleCount, // deUint32 samples; 2502 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 2503 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 2504 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 2505 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 2506 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 2507 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 2508 }, 2509 { 2510 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 2511 m_colorFormat, // VkFormat format; 2512 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 2513 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 2514 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 2515 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 2516 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 2517 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 2518 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 2519 } 2520 }; 2521 2522 const VkAttachmentReference attachmentReference = 2523 { 2524 0u, // deUint32 attachment; 2525 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 2526 }; 2527 2528 const VkAttachmentReference resolveAttachmentRef = 2529 { 2530 1u, // deUint32 attachment; 2531 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 2532 }; 2533 2534 const VkSubpassDescription subpassDescription = 2535 { 2536 0u, // VkSubpassDescriptionFlags flags; 2537 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 2538 0u, // deUint32 inputCount; 2539 DE_NULL, // constVkAttachmentReference* pInputAttachments; 2540 1u, // deUint32 colorCount; 2541 &attachmentReference, // constVkAttachmentReference* pColorAttachments; 2542 isMultiSampling() ? &resolveAttachmentRef : DE_NULL,// constVkAttachmentReference* pResolveAttachments; 2543 DE_NULL, // VkAttachmentReference depthStencilAttachment; 2544 0u, // deUint32 preserveCount; 2545 DE_NULL // constVkAttachmentReference* pPreserveAttachments; 2546 }; 2547 2548 const VkRenderPassCreateInfo renderPassParams = 2549 { 2550 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 2551 DE_NULL, // const void* pNext; 2552 0u, // VkRenderPassCreateFlags flags; 2553 isMultiSampling() ? 2u : 1u, // deUint32 attachmentCount; 2554 attachmentDescription, // const VkAttachmentDescription* pAttachments; 2555 1u, // deUint32 subpassCount; 2556 &subpassDescription, // const VkSubpassDescription* pSubpasses; 2557 0u, // deUint32 dependencyCount; 2558 DE_NULL // const VkSubpassDependency* pDependencies; 2559 }; 2560 2561 renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 2562 } 2563 2564 // Create framebuffer 2565 { 2566 const VkImageView attachments[] = 2567 { 2568 *colorImageView, 2569 *resolvedImageView 2570 }; 2571 2572 const VkFramebufferCreateInfo framebufferParams = 2573 { 2574 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 2575 DE_NULL, // const void* pNext; 2576 (VkFramebufferCreateFlags)0, 2577 *renderPass, // VkRenderPass renderPass; 2578 isMultiSampling() ? 2u : 1u, // deUint32 attachmentCount; 2579 attachments, // const VkImageView* pAttachments; 2580 (deUint32)m_renderSize.x(), // deUint32 width; 2581 (deUint32)m_renderSize.y(), // deUint32 height; 2582 1u // deUint32 layers; 2583 }; 2584 2585 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 2586 } 2587 2588 // Create descriptors 2589 { 2590 setupUniforms(constCoords); 2591 2592 descriptorSetLayout = m_descriptorSetLayoutBuilder->build(vk, vkDevice); 2593 if (!m_uniformInfos.empty()) 2594 { 2595 descriptorPool = m_descriptorPoolBuilder->build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 2596 const VkDescriptorSetAllocateInfo allocInfo = 2597 { 2598 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 2599 DE_NULL, 2600 *descriptorPool, 2601 1u, 2602 &descriptorSetLayout.get(), 2603 }; 2604 2605 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo); 2606 } 2607 2608 for (deUint32 i = 0; i < m_uniformInfos.size(); i++) 2609 { 2610 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get(); 2611 deUint32 location = uniformInfo->location; 2612 2613 if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) 2614 { 2615 const BufferUniform* bufferInfo = dynamic_cast<const BufferUniform*>(uniformInfo); 2616 2617 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor); 2618 } 2619 else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 2620 { 2621 const SamplerUniform* samplerInfo = dynamic_cast<const SamplerUniform*>(uniformInfo); 2622 2623 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor); 2624 } 2625 else 2626 DE_FATAL("Impossible"); 2627 } 2628 2629 m_descriptorSetUpdateBuilder->update(vk, vkDevice); 2630 } 2631 2632 // Create pipeline layout 2633 { 2634 const VkPushConstantRange* const pcRanges = m_pushConstantRanges.empty() ? DE_NULL : &m_pushConstantRanges[0]; 2635 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 2636 { 2637 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 2638 DE_NULL, // const void* pNext; 2639 (VkPipelineLayoutCreateFlags)0, 2640 1u, // deUint32 descriptorSetCount; 2641 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 2642 deUint32(m_pushConstantRanges.size()), // deUint32 pushConstantRangeCount; 2643 pcRanges // const VkPushConstantRange* pPushConstantRanges; 2644 }; 2645 2646 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 2647 } 2648 2649 // Create shaders 2650 { 2651 vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_vertexShaderName), 0); 2652 fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_fragmentShaderName), 0); 2653 } 2654 2655 // Create pipeline 2656 { 2657 const VkPipelineShaderStageCreateInfo shaderStageParams[2] = 2658 { 2659 { 2660 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2661 DE_NULL, // const void* pNext; 2662 (VkPipelineShaderStageCreateFlags)0, 2663 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStage stage; 2664 *vertexShaderModule, // VkShader shader; 2665 "main", 2666 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2667 }, 2668 { 2669 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2670 DE_NULL, // const void* pNext; 2671 (VkPipelineShaderStageCreateFlags)0, 2672 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStage stage; 2673 *fragmentShaderModule, // VkShader shader; 2674 "main", 2675 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2676 } 2677 }; 2678 2679 // Add test case specific attributes 2680 if (m_attribFunc) 2681 m_attribFunc(*this, numVertices); 2682 2683 // Add base attributes 2684 setupDefaultInputs(); 2685 2686 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 2687 { 2688 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 2689 DE_NULL, // const void* pNext; 2690 (VkPipelineVertexInputStateCreateFlags)0, 2691 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount; 2692 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 2693 (deUint32)m_vertexAttributeDescription.size(), // deUint32 attributeCount; 2694 &m_vertexAttributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 2695 }; 2696 2697 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 2698 { 2699 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 2700 DE_NULL, // const void* pNext; 2701 (VkPipelineInputAssemblyStateCreateFlags)0, 2702 topology, // VkPrimitiveTopology topology; 2703 false // VkBool32 primitiveRestartEnable; 2704 }; 2705 2706 const VkViewport viewport = 2707 { 2708 0.0f, // float originX; 2709 0.0f, // float originY; 2710 (float)m_renderSize.x(), // float width; 2711 (float)m_renderSize.y(), // float height; 2712 0.0f, // float minDepth; 2713 1.0f // float maxDepth; 2714 }; 2715 2716 const VkRect2D scissor = 2717 { 2718 { 2719 0u, // deUint32 x; 2720 0u, // deUint32 y; 2721 }, // VkOffset2D offset; 2722 { 2723 m_renderSize.x(), // deUint32 width; 2724 m_renderSize.y(), // deUint32 height; 2725 }, // VkExtent2D extent; 2726 }; 2727 2728 const VkPipelineViewportStateCreateInfo viewportStateParams = 2729 { 2730 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 2731 DE_NULL, // const void* pNext; 2732 0u, // VkPipelineViewportStateCreateFlags flags; 2733 1u, // deUint32 viewportCount; 2734 &viewport, // const VkViewport* pViewports; 2735 1u, // deUint32 scissorsCount; 2736 &scissor, // const VkRect2D* pScissors; 2737 }; 2738 2739 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 2740 { 2741 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 2742 DE_NULL, // const void* pNext; 2743 (VkPipelineRasterizationStateCreateFlags)0, 2744 false, // VkBool32 depthClipEnable; 2745 false, // VkBool32 rasterizerDiscardEnable; 2746 VK_POLYGON_MODE_FILL, // VkFillMode fillMode; 2747 VK_CULL_MODE_NONE, // VkCullMode cullMode; 2748 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 2749 false, // VkBool32 depthBiasEnable; 2750 0.0f, // float depthBias; 2751 0.0f, // float depthBiasClamp; 2752 0.0f, // float slopeScaledDepthBias; 2753 1.0f, // float lineWidth; 2754 }; 2755 2756 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 2757 { 2758 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 2759 DE_NULL, // const void* pNext; 2760 0u, // VkPipelineMultisampleStateCreateFlags flags; 2761 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples; 2762 VK_FALSE, // VkBool32 sampleShadingEnable; 2763 0.0f, // float minSampleShading; 2764 DE_NULL, // const VkSampleMask* pSampleMask; 2765 VK_FALSE, // VkBool32 alphaToCoverageEnable; 2766 VK_FALSE // VkBool32 alphaToOneEnable; 2767 }; 2768 2769 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 2770 { 2771 false, // VkBool32 blendEnable; 2772 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor; 2773 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor; 2774 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; 2775 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha; 2776 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha; 2777 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; 2778 (VK_COLOR_COMPONENT_R_BIT | 2779 VK_COLOR_COMPONENT_G_BIT | 2780 VK_COLOR_COMPONENT_B_BIT | 2781 VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask; 2782 }; 2783 2784 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 2785 { 2786 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 2787 DE_NULL, // const void* pNext; 2788 (VkPipelineColorBlendStateCreateFlags)0, 2789 false, // VkBool32 logicOpEnable; 2790 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 2791 1u, // deUint32 attachmentCount; 2792 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 2793 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4]; 2794 }; 2795 2796 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 2797 { 2798 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 2799 DE_NULL, // const void* pNext; 2800 0u, // VkPipelineCreateFlags flags; 2801 2u, // deUint32 stageCount; 2802 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 2803 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 2804 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 2805 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 2806 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 2807 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState; 2808 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 2809 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 2810 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 2811 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 2812 *pipelineLayout, // VkPipelineLayout layout; 2813 *renderPass, // VkRenderPass renderPass; 2814 0u, // deUint32 subpass; 2815 0u, // VkPipeline basePipelineHandle; 2816 0u // deInt32 basePipelineIndex; 2817 }; 2818 2819 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 2820 } 2821 2822 // Create vertex indices buffer 2823 if (numIndices != 0) 2824 { 2825 const VkDeviceSize indexBufferSize = numIndices * sizeof(deUint16); 2826 const VkBufferCreateInfo indexBufferParams = 2827 { 2828 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 2829 DE_NULL, // const void* pNext; 2830 0u, // VkBufferCreateFlags flags; 2831 indexBufferSize, // VkDeviceSize size; 2832 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage; 2833 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2834 1u, // deUint32 queueFamilyCount; 2835 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 2836 }; 2837 2838 indexBuffer = createBuffer(vk, vkDevice, &indexBufferParams); 2839 indexBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), MemoryRequirement::HostVisible); 2840 2841 VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset())); 2842 2843 // Load vertice indices into buffer 2844 deMemcpy(indexBufferAlloc->getHostPtr(), indices, (size_t)indexBufferSize); 2845 flushMappedMemoryRange(vk, vkDevice, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset(), indexBufferSize); 2846 } 2847 2848 // Create command pool 2849 { 2850 const VkCommandPoolCreateInfo cmdPoolParams = 2851 { 2852 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 2853 DE_NULL, // const void* pNext; 2854 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 2855 queueFamilyIndex, // deUint32 queueFamilyIndex; 2856 }; 2857 2858 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 2859 } 2860 2861 // Create command buffer 2862 { 2863 const VkCommandBufferAllocateInfo cmdBufferParams = 2864 { 2865 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 2866 DE_NULL, // const void* pNext; 2867 *cmdPool, // VkCmdPool cmdPool; 2868 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 2869 1u // deUint32 bufferCount; 2870 }; 2871 2872 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 2873 { 2874 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 2875 DE_NULL, // const void* pNext; 2876 0u, // VkCmdBufferOptimizeFlags flags; 2877 (const VkCommandBufferInheritanceInfo*)DE_NULL, 2878 }; 2879 2880 const VkClearValue clearValues = makeClearValueColorF32(m_clearColor.x(), 2881 m_clearColor.y(), 2882 m_clearColor.z(), 2883 m_clearColor.w()); 2884 2885 const VkRenderPassBeginInfo renderPassBeginInfo = 2886 { 2887 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 2888 DE_NULL, // const void* pNext; 2889 *renderPass, // VkRenderPass renderPass; 2890 *framebuffer, // VkFramebuffer framebuffer; 2891 { { 0, 0 }, {m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea; 2892 1, // deUint32 clearValueCount; 2893 &clearValues, // const VkClearValue* pClearValues; 2894 }; 2895 2896 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 2897 2898 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 2899 2900 { 2901 const VkImageMemoryBarrier imageBarrier = 2902 { 2903 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2904 DE_NULL, // const void* pNext; 2905 0u, // VkAccessFlags srcAccessMask; 2906 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2907 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2908 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2909 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2910 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2911 *colorImage, // VkImage image; 2912 { // VkImageSubresourceRange subresourceRange; 2913 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 2914 0u, // deUint32 baseMipLevel; 2915 1u, // deUint32 mipLevels; 2916 0u, // deUint32 baseArrayLayer; 2917 1u, // deUint32 arraySize; 2918 } 2919 }; 2920 2921 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1, &imageBarrier); 2922 2923 if (isMultiSampling()) { 2924 // add multisample barrier 2925 const VkImageMemoryBarrier multiSampleImageBarrier = 2926 { 2927 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2928 DE_NULL, // const void* pNext; 2929 0u, // VkAccessFlags srcAccessMask; 2930 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2931 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2932 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2933 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2934 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2935 *resolvedImage, // VkImage image; 2936 { // VkImageSubresourceRange subresourceRange; 2937 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 2938 0u, // deUint32 baseMipLevel; 2939 1u, // deUint32 mipLevels; 2940 0u, // deUint32 baseArrayLayer; 2941 1u, // deUint32 arraySize; 2942 } 2943 }; 2944 2945 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1, &multiSampleImageBarrier); 2946 } 2947 } 2948 2949 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 2950 updatePushConstants(*cmdBuffer, *pipelineLayout); 2951 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline); 2952 if (!m_uniformInfos.empty()) 2953 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL); 2954 2955 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size(); 2956 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0); 2957 2958 std::vector<VkBuffer> buffers(numberOfVertexAttributes); 2959 for (size_t i = 0; i < numberOfVertexAttributes; i++) 2960 { 2961 buffers[i] = m_vertexBuffers[i].get()->get(); 2962 } 2963 2964 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]); 2965 if (numIndices != 0) 2966 { 2967 vk.cmdBindIndexBuffer(*cmdBuffer, *indexBuffer, 0, VK_INDEX_TYPE_UINT16); 2968 vk.cmdDrawIndexed(*cmdBuffer, numIndices, 1, 0, 0, 0); 2969 } 2970 else 2971 vk.cmdDraw(*cmdBuffer, numVertices, 1, 0, 1); 2972 2973 vk.cmdEndRenderPass(*cmdBuffer); 2974 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 2975 } 2976 2977 // Create fence 2978 { 2979 const VkFenceCreateInfo fenceParams = 2980 { 2981 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 2982 DE_NULL, // const void* pNext; 2983 0u // VkFenceCreateFlags flags; 2984 }; 2985 fence = createFence(vk, vkDevice, &fenceParams); 2986 } 2987 2988 // Execute Draw 2989 { 2990 const VkSubmitInfo submitInfo = 2991 { 2992 VK_STRUCTURE_TYPE_SUBMIT_INFO, 2993 DE_NULL, 2994 0u, 2995 (const VkSemaphore*)DE_NULL, 2996 (const VkPipelineStageFlags*)DE_NULL, 2997 1u, 2998 &cmdBuffer.get(), 2999 0u, 3000 (const VkSemaphore*)DE_NULL, 3001 }; 3002 3003 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 3004 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/)); 3005 } 3006 3007 // Read back the result 3008 { 3009 const tcu::TextureFormat resultFormat = mapVkFormat(m_colorFormat); 3010 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(resultFormat.getPixelSize() * m_renderSize.x() * m_renderSize.y()); 3011 const VkBufferCreateInfo readImageBufferParams = 3012 { 3013 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 3014 DE_NULL, // const void* pNext; 3015 0u, // VkBufferCreateFlags flags; 3016 imageSizeBytes, // VkDeviceSize size; 3017 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 3018 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3019 1u, // deUint32 queueFamilyCount; 3020 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 3021 }; 3022 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, vkDevice, &readImageBufferParams)); 3023 const de::UniquePtr<Allocation> readImageBufferMemory (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible)); 3024 3025 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset())); 3026 3027 // Copy image to buffer 3028 const VkCommandBufferAllocateInfo cmdBufferParams = 3029 { 3030 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 3031 DE_NULL, // const void* pNext; 3032 *cmdPool, // VkCmdPool cmdPool; 3033 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 3034 1u // deUint32 bufferCount; 3035 }; 3036 3037 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 3038 { 3039 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 3040 DE_NULL, // const void* pNext; 3041 0u, // VkCmdBufferOptimizeFlags flags; 3042 (const VkCommandBufferInheritanceInfo*)DE_NULL, 3043 }; 3044 3045 const Move<VkCommandBuffer> resultCmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 3046 3047 const VkBufferImageCopy copyParams = 3048 { 3049 0u, // VkDeviceSize bufferOffset; 3050 (deUint32)m_renderSize.x(), // deUint32 bufferRowLength; 3051 (deUint32)m_renderSize.y(), // deUint32 bufferImageHeight; 3052 { 3053 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 3054 0u, // deUint32 mipLevel; 3055 0u, // deUint32 arraySlice; 3056 1u, // deUint32 arraySize; 3057 }, // VkImageSubresourceCopy imageSubresource; 3058 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 3059 { m_renderSize.x(), m_renderSize.y(), 1u } // VkExtent3D imageExtent; 3060 }; 3061 const VkSubmitInfo submitInfo = 3062 { 3063 VK_STRUCTURE_TYPE_SUBMIT_INFO, 3064 DE_NULL, 3065 0u, 3066 (const VkSemaphore*)DE_NULL, 3067 (const VkPipelineStageFlags*)DE_NULL, 3068 1u, 3069 &resultCmdBuffer.get(), 3070 0u, 3071 (const VkSemaphore*)DE_NULL, 3072 }; 3073 3074 VK_CHECK(vk.beginCommandBuffer(*resultCmdBuffer, &cmdBufferBeginInfo)); 3075 3076 const VkImageMemoryBarrier imageBarrier = 3077 { 3078 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 3079 DE_NULL, // const void* pNext; 3080 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; 3081 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 3082 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; 3083 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 3084 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 3085 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 3086 isMultiSampling() ? *resolvedImage : *colorImage, // VkImage image; 3087 { // VkImageSubresourceRange subresourceRange; 3088 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 3089 0u, // deUint32 baseMipLevel; 3090 1u, // deUint32 mipLevels; 3091 0u, // deUint32 baseArraySlice; 3092 1u // deUint32 arraySize; 3093 } 3094 }; 3095 3096 const VkBufferMemoryBarrier bufferBarrier = 3097 { 3098 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 3099 DE_NULL, // const void* pNext; 3100 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 3101 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 3102 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 3103 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 3104 *readImageBuffer, // VkBuffer buffer; 3105 0u, // VkDeviceSize offset; 3106 imageSizeBytes // VkDeviceSize size; 3107 }; 3108 3109 vk.cmdPipelineBarrier(*resultCmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier); 3110 vk.cmdCopyImageToBuffer(*resultCmdBuffer, isMultiSampling() ? *resolvedImage : *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params); 3111 vk.cmdPipelineBarrier(*resultCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 3112 3113 VK_CHECK(vk.endCommandBuffer(*resultCmdBuffer)); 3114 3115 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); 3116 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 3117 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */)); 3118 3119 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes); 3120 3121 const tcu::ConstPixelBufferAccess resultAccess (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr()); 3122 3123 m_resultImage.setStorage(resultFormat, m_renderSize.x(), m_renderSize.y()); 3124 tcu::copy(m_resultImage.getAccess(), resultAccess); 3125 } 3126 } 3127 3128 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid) 3129 { 3130 DE_ASSERT(m_evaluator); 3131 3132 // Buffer info. 3133 const int width = result.getWidth(); 3134 const int height = result.getHeight(); 3135 const int gridSize = quadGrid.getGridSize(); 3136 const int stride = gridSize + 1; 3137 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check 3138 ShaderEvalContext evalCtx (quadGrid); 3139 3140 // Evaluate color for each vertex. 3141 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1)); 3142 for (int y = 0; y < gridSize+1; y++) 3143 for (int x = 0; x < gridSize+1; x++) 3144 { 3145 const float sx = (float)x / (float)gridSize; 3146 const float sy = (float)y / (float)gridSize; 3147 const int vtxNdx = ((y * (gridSize+1)) + x); 3148 3149 evalCtx.reset(sx, sy); 3150 m_evaluator->evaluate(evalCtx); 3151 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader. 3152 tcu::Vec4 color = evalCtx.color; 3153 3154 if (!hasAlpha) 3155 color.w() = 1.0f; 3156 3157 colors[vtxNdx] = color; 3158 } 3159 3160 // Render quads. 3161 for (int y = 0; y < gridSize; y++) 3162 for (int x = 0; x < gridSize; x++) 3163 { 3164 const float x0 = (float)x / (float)gridSize; 3165 const float x1 = (float)(x + 1) / (float)gridSize; 3166 const float y0 = (float)y / (float)gridSize; 3167 const float y1 = (float)(y + 1) / (float)gridSize; 3168 3169 const float sx0 = x0 * (float)width; 3170 const float sx1 = x1 * (float)width; 3171 const float sy0 = y0 * (float)height; 3172 const float sy1 = y1 * (float)height; 3173 const float oosx = 1.0f / (sx1 - sx0); 3174 const float oosy = 1.0f / (sy1 - sy0); 3175 3176 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f); 3177 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f); 3178 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f); 3179 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f); 3180 3181 const int v00 = (y * stride) + x; 3182 const int v01 = (y * stride) + x + 1; 3183 const int v10 = ((y + 1) * stride) + x; 3184 const int v11 = ((y + 1) * stride) + x + 1; 3185 const tcu::Vec4 c00 = colors[v00]; 3186 const tcu::Vec4 c01 = colors[v01]; 3187 const tcu::Vec4 c10 = colors[v10]; 3188 const tcu::Vec4 c11 = colors[v11]; 3189 3190 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1); 3191 3192 for (int iy = iy0; iy < iy1; iy++) 3193 for (int ix = ix0; ix < ix1; ix++) 3194 { 3195 DE_ASSERT(deInBounds32(ix, 0, width)); 3196 DE_ASSERT(deInBounds32(iy, 0, height)); 3197 3198 const float sfx = (float)ix + 0.5f; 3199 const float sfy = (float)iy + 0.5f; 3200 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f); 3201 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f); 3202 3203 // Triangle quad interpolation. 3204 const bool tri = fx1 + fy1 <= 1.0f; 3205 const float tx = tri ? fx1 : (1.0f-fx1); 3206 const float ty = tri ? fy1 : (1.0f-fy1); 3207 const tcu::Vec4& t0 = tri ? c00 : c11; 3208 const tcu::Vec4& t1 = tri ? c01 : c10; 3209 const tcu::Vec4& t2 = tri ? c10 : c01; 3210 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty; 3211 3212 result.setPixel(ix, iy, tcu::RGBA(color)); 3213 } 3214 } 3215 } 3216 3217 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid) 3218 { 3219 DE_ASSERT(m_evaluator); 3220 3221 // Buffer info. 3222 const int width = result.getWidth(); 3223 const int height = result.getHeight(); 3224 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check 3225 ShaderEvalContext evalCtx (quadGrid); 3226 3227 // Render. 3228 for (int y = 0; y < height; y++) 3229 for (int x = 0; x < width; x++) 3230 { 3231 const float sx = ((float)x + 0.5f) / (float)width; 3232 const float sy = ((float)y + 0.5f) / (float)height; 3233 3234 evalCtx.reset(sx, sy); 3235 m_evaluator->evaluate(evalCtx); 3236 // Select either clear color or computed color based on discarded bit. 3237 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color; 3238 3239 if (!hasAlpha) 3240 color.w() = 1.0f; 3241 3242 result.setPixel(x, y, tcu::RGBA(color)); 3243 } 3244 } 3245 3246 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold) 3247 { 3248 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT); 3249 } 3250 3251 } // sr 3252 } // vkt 3253