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