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