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#include "vkCmdUtil.hpp" 48#include "vkObjUtil.hpp" 49 50#include <vector> 51#include <string> 52 53namespace vkt 54{ 55namespace sr 56{ 57 58using namespace vk; 59 60VkImageViewType textureTypeToImageViewType (TextureBinding::Type type) 61{ 62 switch (type) 63 { 64 case TextureBinding::TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D; 65 case TextureBinding::TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D; 66 case TextureBinding::TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D; 67 case TextureBinding::TYPE_CUBE_MAP: return VK_IMAGE_VIEW_TYPE_CUBE; 68 case TextureBinding::TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY; 69 case TextureBinding::TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; 70 case TextureBinding::TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; 71 72 default: 73 DE_FATAL("Impossible"); 74 return (VkImageViewType)0; 75 } 76} 77 78VkImageType viewTypeToImageType (VkImageViewType type) 79{ 80 switch (type) 81 { 82 case VK_IMAGE_VIEW_TYPE_1D: 83 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return VK_IMAGE_TYPE_1D; 84 case VK_IMAGE_VIEW_TYPE_2D: 85 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return VK_IMAGE_TYPE_2D; 86 case VK_IMAGE_VIEW_TYPE_3D: return VK_IMAGE_TYPE_3D; 87 case VK_IMAGE_VIEW_TYPE_CUBE: 88 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return VK_IMAGE_TYPE_2D; 89 90 default: 91 DE_FATAL("Impossible"); 92 return (VkImageType)0; 93 } 94} 95 96vk::VkImageUsageFlags textureUsageFlags (void) 97{ 98 return (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); 99} 100 101vk::VkImageCreateFlags textureCreateFlags (vk::VkImageViewType viewType, ShaderRenderCaseInstance::ImageBackingMode backingMode) 102{ 103 const bool isCube = (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY); 104 VkImageCreateFlags imageCreateFlags = (isCube ? static_cast<VkImageCreateFlags>(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) : 0u); 105 106 if (backingMode == ShaderRenderCaseInstance::IMAGE_BACKING_MODE_SPARSE) 107 imageCreateFlags |= (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT); 108 109 return imageCreateFlags; 110} 111 112namespace 113{ 114 115static const deUint32 MAX_RENDER_WIDTH = 128; 116static const deUint32 MAX_RENDER_HEIGHT = 128; 117static const tcu::Vec4 DEFAULT_CLEAR_COLOR = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f); 118 119/*! Gets the next multiple of a given divisor */ 120static deUint32 getNextMultiple (deUint32 divisor, deUint32 value) 121{ 122 if (value % divisor == 0) 123 { 124 return value; 125 } 126 return value + divisor - (value % divisor); 127} 128 129/*! Gets the next value that is multiple of all given divisors */ 130static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value) 131{ 132 deUint32 nextMultiple = value; 133 bool nextMultipleFound = false; 134 135 while (true) 136 { 137 nextMultipleFound = true; 138 139 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++) 140 nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0); 141 142 if (nextMultipleFound) 143 break; 144 145 DE_ASSERT(nextMultiple < ~((deUint32)0u)); 146 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1); 147 } 148 149 return nextMultiple; 150} 151 152} // anonymous 153 154// QuadGrid. 155 156class QuadGrid 157{ 158public: 159 QuadGrid (int gridSize, 160 int screenWidth, 161 int screenHeight, 162 const tcu::Vec4& constCoords, 163 const std::vector<tcu::Mat4>& userAttribTransforms, 164 const std::vector<TextureBindingSp>& textures); 165 ~QuadGrid (void); 166 167 int getGridSize (void) const { return m_gridSize; } 168 int getNumVertices (void) const { return m_numVertices; } 169 int getNumTriangles (void) const { return m_numTriangles; } 170 const tcu::Vec4& getConstCoords (void) const { return m_constCoords; } 171 const std::vector<tcu::Mat4> getUserAttribTransforms (void) const { return m_userAttribTransforms; } 172 const std::vector<TextureBindingSp>& getTextures (void) const { return m_textures; } 173 174 const tcu::Vec4* getPositions (void) const { return &m_positions[0]; } 175 const float* getAttribOne (void) const { return &m_attribOne[0]; } 176 const tcu::Vec4* getCoords (void) const { return &m_coords[0]; } 177 const tcu::Vec4* getUnitCoords (void) const { return &m_unitCoords[0]; } 178 179 const tcu::Vec4* getUserAttrib (int attribNdx) const { return &m_userAttribs[attribNdx][0]; } 180 const deUint16* getIndices (void) const { return &m_indices[0]; } 181 182 tcu::Vec4 getCoords (float sx, float sy) const; 183 tcu::Vec4 getUnitCoords (float sx, float sy) const; 184 185 int getNumUserAttribs (void) const { return (int)m_userAttribTransforms.size(); } 186 tcu::Vec4 getUserAttrib (int attribNdx, float sx, float sy) const; 187 188private: 189 const int m_gridSize; 190 const int m_numVertices; 191 const int m_numTriangles; 192 const tcu::Vec4 m_constCoords; 193 const std::vector<tcu::Mat4> m_userAttribTransforms; 194 195 const std::vector<TextureBindingSp>& m_textures; 196 197 std::vector<tcu::Vec4> m_screenPos; 198 std::vector<tcu::Vec4> m_positions; 199 std::vector<tcu::Vec4> m_coords; //!< Near-unit coordinates, roughly [-2.0 .. 2.0]. 200 std::vector<tcu::Vec4> m_unitCoords; //!< Positive-only coordinates [0.0 .. 1.5]. 201 std::vector<float> m_attribOne; 202 std::vector<tcu::Vec4> m_userAttribs[ShaderEvalContext::MAX_TEXTURES]; 203 std::vector<deUint16> m_indices; 204}; 205 206QuadGrid::QuadGrid (int gridSize, 207 int width, 208 int height, 209 const tcu::Vec4& constCoords, 210 const std::vector<tcu::Mat4>& userAttribTransforms, 211 const std::vector<TextureBindingSp>& textures) 212 : m_gridSize (gridSize) 213 , m_numVertices ((gridSize + 1) * (gridSize + 1)) 214 , m_numTriangles (gridSize * gridSize * 2) 215 , m_constCoords (constCoords) 216 , m_userAttribTransforms (userAttribTransforms) 217 , m_textures (textures) 218{ 219 const tcu::Vec4 viewportScale ((float)width, (float)height, 0.0f, 0.0f); 220 221 // Compute vertices. 222 m_screenPos.resize(m_numVertices); 223 m_positions.resize(m_numVertices); 224 m_coords.resize(m_numVertices); 225 m_unitCoords.resize(m_numVertices); 226 m_attribOne.resize(m_numVertices); 227 228 // User attributes. 229 for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++) 230 m_userAttribs[attrNdx].resize(m_numVertices); 231 232 for (int y = 0; y < gridSize+1; y++) 233 for (int x = 0; x < gridSize+1; x++) 234 { 235 float sx = (float)x / (float)gridSize; 236 float sy = (float)y / (float)gridSize; 237 float fx = 2.0f * sx - 1.0f; 238 float fy = 2.0f * sy - 1.0f; 239 int vtxNdx = ((y * (gridSize+1)) + x); 240 241 m_positions[vtxNdx] = tcu::Vec4(fx, fy, 0.0f, 1.0f); 242 m_coords[vtxNdx] = getCoords(sx, sy); 243 m_unitCoords[vtxNdx] = getUnitCoords(sx, sy); 244 m_attribOne[vtxNdx] = 1.0f; 245 246 m_screenPos[vtxNdx] = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale; 247 248 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++) 249 m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy); 250 } 251 252 // Compute indices. 253 m_indices.resize(3 * m_numTriangles); 254 for (int y = 0; y < gridSize; y++) 255 for (int x = 0; x < gridSize; x++) 256 { 257 int stride = gridSize + 1; 258 int v00 = (y * stride) + x; 259 int v01 = (y * stride) + x + 1; 260 int v10 = ((y+1) * stride) + x; 261 int v11 = ((y+1) * stride) + x + 1; 262 263 int baseNdx = ((y * gridSize) + x) * 6; 264 m_indices[baseNdx + 0] = (deUint16)v10; 265 m_indices[baseNdx + 1] = (deUint16)v00; 266 m_indices[baseNdx + 2] = (deUint16)v01; 267 268 m_indices[baseNdx + 3] = (deUint16)v10; 269 m_indices[baseNdx + 4] = (deUint16)v01; 270 m_indices[baseNdx + 5] = (deUint16)v11; 271 } 272} 273 274QuadGrid::~QuadGrid (void) 275{ 276} 277 278inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const 279{ 280 const float fx = 2.0f * sx - 1.0f; 281 const float fy = 2.0f * sy - 1.0f; 282 return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy); 283} 284 285inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const 286{ 287 return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy); 288} 289 290inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const 291{ 292 // homogeneous normalized screen-space coordinates 293 return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f); 294} 295 296// TextureBinding 297 298TextureBinding::TextureBinding (const tcu::Archive& archive, 299 const char* filename, 300 const Type type, 301 const tcu::Sampler& sampler) 302 : m_type (type) 303 , m_sampler (sampler) 304{ 305 switch(m_type) 306 { 307 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break; 308 default: 309 DE_FATAL("Unsupported texture type"); 310 } 311} 312 313TextureBinding::TextureBinding (const tcu::Texture1D* tex1D, const tcu::Sampler& sampler) 314 : m_type (TYPE_1D) 315 , m_sampler (sampler) 316{ 317 m_binding.tex1D = tex1D; 318} 319 320TextureBinding::TextureBinding (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler) 321 : m_type (TYPE_2D) 322 , m_sampler (sampler) 323{ 324 m_binding.tex2D = tex2D; 325} 326 327TextureBinding::TextureBinding (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler) 328 : m_type (TYPE_3D) 329 , m_sampler (sampler) 330{ 331 m_binding.tex3D = tex3D; 332} 333 334TextureBinding::TextureBinding (const tcu::TextureCube* texCube, const tcu::Sampler& sampler) 335 : m_type (TYPE_CUBE_MAP) 336 , m_sampler (sampler) 337{ 338 m_binding.texCube = texCube; 339} 340 341TextureBinding::TextureBinding (const tcu::Texture1DArray* tex1DArray, const tcu::Sampler& sampler) 342 : m_type (TYPE_1D_ARRAY) 343 , m_sampler (sampler) 344{ 345 m_binding.tex1DArray = tex1DArray; 346} 347 348TextureBinding::TextureBinding (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler) 349 : m_type (TYPE_2D_ARRAY) 350 , m_sampler (sampler) 351{ 352 m_binding.tex2DArray = tex2DArray; 353} 354 355TextureBinding::TextureBinding (const tcu::TextureCubeArray* texCubeArray, const tcu::Sampler& sampler) 356 : m_type (TYPE_CUBE_ARRAY) 357 , m_sampler (sampler) 358{ 359 m_binding.texCubeArray = texCubeArray; 360} 361 362TextureBinding::~TextureBinding (void) 363{ 364 switch(m_type) 365 { 366 case TYPE_1D: delete m_binding.tex1D; break; 367 case TYPE_2D: delete m_binding.tex2D; break; 368 case TYPE_3D: delete m_binding.tex3D; break; 369 case TYPE_CUBE_MAP: delete m_binding.texCube; break; 370 case TYPE_1D_ARRAY: delete m_binding.tex1DArray; break; 371 case TYPE_2D_ARRAY: delete m_binding.tex2DArray; break; 372 case TYPE_CUBE_ARRAY: delete m_binding.texCubeArray; break; 373 default: break; 374 } 375} 376 377de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename) 378{ 379 tcu::TextureLevel level; 380 tcu::ImageIO::loadImage(level, archive, filename); 381 382 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) || 383 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8)); 384 385 // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated 386 de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight())); 387 388 // Fill level 0. 389 texture->allocLevel(0); 390 tcu::copy(texture->getLevel(0), level.getAccess()); 391 392 return texture; 393} 394 395// ShaderEvalContext. 396 397ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid) 398 : constCoords (quadGrid.getConstCoords()) 399 , isDiscarded (false) 400 , m_quadGrid (quadGrid) 401{ 402 const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures(); 403 DE_ASSERT((int)bindings.size() <= MAX_TEXTURES); 404 405 // Fill in texture array. 406 for (int ndx = 0; ndx < (int)bindings.size(); ndx++) 407 { 408 const TextureBinding& binding = *bindings[ndx]; 409 410 if (binding.getType() == TextureBinding::TYPE_NONE) 411 continue; 412 413 textures[ndx].sampler = binding.getSampler(); 414 415 switch (binding.getType()) 416 { 417 case TextureBinding::TYPE_1D: textures[ndx].tex1D = &binding.get1D(); break; 418 case TextureBinding::TYPE_2D: textures[ndx].tex2D = &binding.get2D(); break; 419 case TextureBinding::TYPE_3D: textures[ndx].tex3D = &binding.get3D(); break; 420 case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube = &binding.getCube(); break; 421 case TextureBinding::TYPE_1D_ARRAY: textures[ndx].tex1DArray = &binding.get1DArray(); break; 422 case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray = &binding.get2DArray(); break; 423 case TextureBinding::TYPE_CUBE_ARRAY: textures[ndx].texCubeArray = &binding.getCubeArray(); break; 424 default: 425 TCU_THROW(InternalError, "Handling of texture binding type not implemented"); 426 } 427 } 428} 429 430ShaderEvalContext::~ShaderEvalContext (void) 431{ 432} 433 434void ShaderEvalContext::reset (float sx, float sy) 435{ 436 // Clear old values 437 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 438 isDiscarded = false; 439 440 // Compute coords 441 coords = m_quadGrid.getCoords(sx, sy); 442 unitCoords = m_quadGrid.getUnitCoords(sx, sy); 443 444 // Compute user attributes. 445 const int numAttribs = m_quadGrid.getNumUserAttribs(); 446 DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS); 447 for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++) 448 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy); 449} 450 451tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords) 452{ 453 if (textures[unitNdx].tex2D) 454 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f); 455 else 456 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 457} 458 459// ShaderEvaluator. 460 461ShaderEvaluator::ShaderEvaluator (void) 462 : m_evalFunc(DE_NULL) 463{ 464} 465 466ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc) 467 : m_evalFunc(evalFunc) 468{ 469} 470 471ShaderEvaluator::~ShaderEvaluator (void) 472{ 473} 474 475void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const 476{ 477 DE_ASSERT(m_evalFunc); 478 m_evalFunc(ctx); 479} 480 481// UniformSetup. 482 483UniformSetup::UniformSetup (void) 484 : m_setupFunc(DE_NULL) 485{ 486} 487 488UniformSetup::UniformSetup (UniformSetupFunc setupFunc) 489 : m_setupFunc(setupFunc) 490{ 491} 492 493UniformSetup::~UniformSetup (void) 494{ 495} 496 497void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const 498{ 499 if (m_setupFunc) 500 m_setupFunc(instance, constCoords); 501} 502 503// ShaderRenderCase. 504 505ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx, 506 const std::string& name, 507 const bool isVertexCase, 508 const ShaderEvalFunc evalFunc, 509 const UniformSetup* uniformSetup, 510 const AttributeSetupFunc attribFunc) 511 : vkt::TestCase (testCtx, name) 512 , m_isVertexCase (isVertexCase) 513 , m_evaluator (new ShaderEvaluator(evalFunc)) 514 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup()) 515 , m_attribFunc (attribFunc) 516{} 517 518ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx, 519 const std::string& name, 520 const bool isVertexCase, 521 const ShaderEvaluator* evaluator, 522 const UniformSetup* uniformSetup, 523 const AttributeSetupFunc attribFunc) 524 : vkt::TestCase (testCtx, name) 525 , m_isVertexCase (isVertexCase) 526 , m_evaluator (evaluator) 527 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup()) 528 , m_attribFunc (attribFunc) 529{} 530 531ShaderRenderCase::~ShaderRenderCase (void) 532{ 533} 534 535void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const 536{ 537 programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource); 538 programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource); 539} 540 541TestInstance* ShaderRenderCase::createInstance (Context& context) const 542{ 543 DE_ASSERT(m_evaluator != DE_NULL); 544 DE_ASSERT(m_uniformSetup != DE_NULL); 545 return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc); 546} 547 548// ShaderRenderCaseInstance. 549 550ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context) 551 : vkt::TestInstance (context) 552 , m_imageBackingMode (IMAGE_BACKING_MODE_REGULAR) 553 , m_quadGridSize (static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT)) 554 , m_memAlloc (getAllocator()) 555 , m_clearColor (DEFAULT_CLEAR_COLOR) 556 , m_isVertexCase (false) 557 , m_vertexShaderName ("vert") 558 , m_fragmentShaderName ("frag") 559 , m_renderSize (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT) 560 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 561 , m_evaluator (DE_NULL) 562 , m_uniformSetup (DE_NULL) 563 , m_attribFunc (DE_NULL) 564 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT) 565 , m_fuzzyCompare (true) 566{ 567} 568 569 570ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, 571 const bool isVertexCase, 572 const ShaderEvaluator& evaluator, 573 const UniformSetup& uniformSetup, 574 const AttributeSetupFunc attribFunc, 575 const ImageBackingMode imageBackingMode, 576 const deUint32 gridSize, 577 const bool fuzzyCompare) 578 : vkt::TestInstance (context) 579 , m_imageBackingMode (imageBackingMode) 580 , m_quadGridSize (gridSize == static_cast<deUint32>(GRID_SIZE_DEFAULTS) 581 ? (isVertexCase 582 ? static_cast<deUint32>(GRID_SIZE_DEFAULT_VERTEX) 583 : static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT)) 584 : gridSize) 585 , m_memAlloc (getAllocator()) 586 , m_clearColor (DEFAULT_CLEAR_COLOR) 587 , m_isVertexCase (isVertexCase) 588 , m_vertexShaderName ("vert") 589 , m_fragmentShaderName ("frag") 590 , m_renderSize (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT) 591 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 592 , m_evaluator (&evaluator) 593 , m_uniformSetup (&uniformSetup) 594 , m_attribFunc (attribFunc) 595 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT) 596 , m_fuzzyCompare (fuzzyCompare) 597{ 598} 599 600ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, 601 const bool isVertexCase, 602 const ShaderEvaluator* evaluator, 603 const UniformSetup* uniformSetup, 604 const AttributeSetupFunc attribFunc, 605 const ImageBackingMode imageBackingMode, 606 const deUint32 gridSize) 607 : vkt::TestInstance (context) 608 , m_imageBackingMode (imageBackingMode) 609 , m_quadGridSize (gridSize == static_cast<deUint32>(GRID_SIZE_DEFAULTS) 610 ? (isVertexCase 611 ? static_cast<deUint32>(GRID_SIZE_DEFAULT_VERTEX) 612 : static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT)) 613 : gridSize) 614 , m_memAlloc (getAllocator()) 615 , m_clearColor (DEFAULT_CLEAR_COLOR) 616 , m_isVertexCase (isVertexCase) 617 , m_vertexShaderName ("vert") 618 , m_fragmentShaderName ("frag") 619 , m_renderSize (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT) 620 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 621 , m_evaluator (evaluator) 622 , m_uniformSetup (uniformSetup) 623 , m_attribFunc (attribFunc) 624 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT) 625 , m_fuzzyCompare (false) 626{ 627} 628 629vk::Allocator& ShaderRenderCaseInstance::getAllocator (void) const 630{ 631 return m_context.getDefaultAllocator(); 632} 633 634ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void) 635{ 636} 637 638VkDevice ShaderRenderCaseInstance::getDevice (void) const 639{ 640 return m_context.getDevice(); 641} 642 643deUint32 ShaderRenderCaseInstance::getUniversalQueueFamilyIndex (void) const 644{ 645 return m_context.getUniversalQueueFamilyIndex(); 646} 647 648deUint32 ShaderRenderCaseInstance::getSparseQueueFamilyIndex (void) const 649{ 650 return m_context.getSparseQueueFamilyIndex(); 651} 652 653const DeviceInterface& ShaderRenderCaseInstance::getDeviceInterface (void) const 654{ 655 return m_context.getDeviceInterface(); 656} 657 658VkQueue ShaderRenderCaseInstance::getUniversalQueue (void) const 659{ 660 return m_context.getUniversalQueue(); 661} 662 663VkQueue ShaderRenderCaseInstance::getSparseQueue (void) const 664{ 665 return m_context.getSparseQueue(); 666} 667 668VkPhysicalDevice ShaderRenderCaseInstance::getPhysicalDevice (void) const 669{ 670 return m_context.getPhysicalDevice(); 671} 672 673const InstanceInterface& ShaderRenderCaseInstance::getInstanceInterface (void) const 674{ 675 return m_context.getInstanceInterface(); 676} 677 678tcu::TestStatus ShaderRenderCaseInstance::iterate (void) 679{ 680 setup(); 681 682 // Create quad grid. 683 const tcu::UVec2 viewportSize = getViewportSize(); 684 const int width = viewportSize.x(); 685 const int height = viewportSize.y(); 686 687 m_quadGrid = de::MovePtr<QuadGrid>(new QuadGrid(m_quadGridSize, width, height, getDefaultConstCoords(), m_userAttribTransforms, m_textures)); 688 689 // Render result. 690 tcu::Surface resImage (width, height); 691 692 render(m_quadGrid->getNumVertices(), m_quadGrid->getNumTriangles(), m_quadGrid->getIndices(), m_quadGrid->getConstCoords()); 693 tcu::copy(resImage.getAccess(), m_resultImage.getAccess()); 694 695 // Compute reference. 696 tcu::Surface refImage (width, height); 697 if (m_isVertexCase) 698 computeVertexReference(refImage, *m_quadGrid); 699 else 700 computeFragmentReference(refImage, *m_quadGrid); 701 702 // Compare. 703 const bool compareOk = compareImages(resImage, refImage, 0.2f); 704 705 if (compareOk) 706 return tcu::TestStatus::pass("Result image matches reference"); 707 else 708 return tcu::TestStatus::fail("Image mismatch"); 709} 710 711void ShaderRenderCaseInstance::setup (void) 712{ 713 m_resultImage = tcu::TextureLevel(); 714 m_descriptorSetLayoutBuilder = de::MovePtr<DescriptorSetLayoutBuilder> (new DescriptorSetLayoutBuilder()); 715 m_descriptorPoolBuilder = de::MovePtr<DescriptorPoolBuilder> (new DescriptorPoolBuilder()); 716 m_descriptorSetUpdateBuilder = de::MovePtr<DescriptorSetUpdateBuilder> (new DescriptorSetUpdateBuilder()); 717 718 m_uniformInfos.clear(); 719 m_vertexBindingDescription.clear(); 720 m_vertexAttributeDescription.clear(); 721 m_vertexBuffers.clear(); 722 m_vertexBufferAllocs.clear(); 723 m_pushConstantRanges.clear(); 724} 725 726void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr) 727{ 728 const VkDevice vkDevice = getDevice(); 729 const DeviceInterface& vk = getDeviceInterface(); 730 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 731 732 const VkBufferCreateInfo uniformBufferParams = 733 { 734 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 735 DE_NULL, // const void* pNext; 736 0u, // VkBufferCreateFlags flags; 737 size, // VkDeviceSize size; 738 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage; 739 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 740 1u, // deUint32 queueFamilyCount; 741 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 742 }; 743 744 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams); 745 de::MovePtr<Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 746 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset())); 747 748 deMemcpy(alloc->getHostPtr(), dataPtr, size); 749 flushAlloc(vk, vkDevice, *alloc); 750 751 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform()); 752 uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 753 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size); 754 uniformInfo->location = bindingLocation; 755 uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer)); 756 uniformInfo->alloc = AllocationSp(alloc.release()); 757 758 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo))); 759} 760 761void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, size_t dataSize, const void* data) 762{ 763 m_descriptorSetLayoutBuilder->addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_ALL); 764 m_descriptorPoolBuilder->addType(descriptorType); 765 766 setupUniformData(bindingLocation, dataSize, data); 767} 768 769void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation, 770 vk::VkFormat format, 771 deUint32 sizePerElement, 772 deUint32 count, 773 const void* dataPtr) 774{ 775 // Portability requires stride to be multiply of minVertexInputBindingStrideAlignment 776 // this value is usually 4 and current tests meet this requirement but 777 // if this changes in future then this limit should be verified in checkSupport 778#ifndef CTS_USES_VULKANSC 779 if (m_context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && 780 ((sizePerElement % m_context.getPortabilitySubsetProperties().minVertexInputBindingStrideAlignment) != 0)) 781 { 782 DE_FATAL("stride is not multiply of minVertexInputBindingStrideAlignment"); 783 } 784#endif // CTS_USES_VULKANSC 785 786 // Add binding specification 787 const deUint32 binding = (deUint32)m_vertexBindingDescription.size(); 788 const VkVertexInputBindingDescription bindingDescription = 789 { 790 binding, // deUint32 binding; 791 sizePerElement, // deUint32 stride; 792 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate stepRate; 793 }; 794 795 m_vertexBindingDescription.push_back(bindingDescription); 796 797 // Add location and format specification 798 const VkVertexInputAttributeDescription attributeDescription = 799 { 800 bindingLocation, // deUint32 location; 801 binding, // deUint32 binding; 802 format, // VkFormat format; 803 0u, // deUint32 offset; 804 }; 805 806 m_vertexAttributeDescription.push_back(attributeDescription); 807 808 // Upload data to buffer 809 const VkDevice vkDevice = getDevice(); 810 const DeviceInterface& vk = getDeviceInterface(); 811 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 812 813 const VkDeviceSize inputSize = sizePerElement * count; 814 const VkBufferCreateInfo vertexBufferParams = 815 { 816 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 817 DE_NULL, // const void* pNext; 818 0u, // VkBufferCreateFlags flags; 819 inputSize, // VkDeviceSize size; 820 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 821 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 822 1u, // deUint32 queueFamilyCount; 823 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 824 }; 825 826 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams); 827 de::MovePtr<vk::Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 828 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset())); 829 830 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize); 831 flushAlloc(vk, vkDevice, *alloc); 832 833 m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer))); 834 m_vertexBufferAllocs.push_back(AllocationSp(alloc.release())); 835} 836 837void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type) 838{ 839 const EnabledBaseAttribute attribute = 840 { 841 bindingLocation, // deUint32 location; 842 type // BaseAttributeType type; 843 }; 844 m_enabledBaseAttributes.push_back(attribute); 845} 846 847void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords) 848{ 849 if (m_uniformSetup) 850 m_uniformSetup->setup(*this, constCoords); 851} 852 853void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type) 854{ 855 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break 856 857 switch(type) 858 { 859 // Bool 860 UNIFORM_CASE(UB_FALSE, 0); 861 UNIFORM_CASE(UB_TRUE, 1); 862 863 // BVec4 864 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0)); 865 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1)); 866 867 // Integer 868 UNIFORM_CASE(UI_ZERO, 0); 869 UNIFORM_CASE(UI_ONE, 1); 870 UNIFORM_CASE(UI_TWO, 2); 871 UNIFORM_CASE(UI_THREE, 3); 872 UNIFORM_CASE(UI_FOUR, 4); 873 UNIFORM_CASE(UI_FIVE, 5); 874 UNIFORM_CASE(UI_SIX, 6); 875 UNIFORM_CASE(UI_SEVEN, 7); 876 UNIFORM_CASE(UI_EIGHT, 8); 877 UNIFORM_CASE(UI_ONEHUNDREDONE, 101); 878 879 // IVec2 880 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1)); 881 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0)); 882 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1)); 883 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2)); 884 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3)); 885 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4)); 886 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5)); 887 888 // IVec3 889 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1)); 890 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0)); 891 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1)); 892 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2)); 893 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3)); 894 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4)); 895 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5)); 896 897 // IVec4 898 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1)); 899 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0)); 900 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1)); 901 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2)); 902 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3)); 903 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4)); 904 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5)); 905 906 // Float 907 UNIFORM_CASE(UF_ZERO, 0.0f); 908 UNIFORM_CASE(UF_ONE, 1.0f); 909 UNIFORM_CASE(UF_TWO, 2.0f); 910 UNIFORM_CASE(UF_THREE, 3.0f); 911 UNIFORM_CASE(UF_FOUR, 4.0f); 912 UNIFORM_CASE(UF_FIVE, 5.0f); 913 UNIFORM_CASE(UF_SIX, 6.0f); 914 UNIFORM_CASE(UF_SEVEN, 7.0f); 915 UNIFORM_CASE(UF_EIGHT, 8.0f); 916 917 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f); 918 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f); 919 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f); 920 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f); 921 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f); 922 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f); 923 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f); 924 925 // Vec2 926 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f)); 927 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f)); 928 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f)); 929 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f)); 930 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f)); 931 932 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f)); 933 934 // Vec3 935 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f)); 936 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f)); 937 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f)); 938 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f)); 939 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f)); 940 941 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f)); 942 943 // Vec4 944 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f)); 945 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f)); 946 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f)); 947 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f)); 948 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f)); 949 950 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f)); 951 952 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 953 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f)); 954 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 955 956 default: 957 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage; 958 break; 959 } 960 961 #undef UNIFORM_CASE 962} 963 964const tcu::UVec2 ShaderRenderCaseInstance::getViewportSize (void) const 965{ 966 return tcu::UVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH), 967 de::min(m_renderSize.y(), MAX_RENDER_HEIGHT)); 968} 969 970void ShaderRenderCaseInstance::setSampleCount (VkSampleCountFlagBits sampleCount) 971{ 972 m_sampleCount = sampleCount; 973} 974 975bool ShaderRenderCaseInstance::isMultiSampling (void) const 976{ 977 return m_sampleCount != VK_SAMPLE_COUNT_1_BIT; 978} 979 980void ShaderRenderCaseInstance::uploadImage (const tcu::TextureFormat& texFormat, 981 const TextureData& textureData, 982 const tcu::Sampler& refSampler, 983 deUint32 mipLevels, 984 deUint32 arrayLayers, 985 VkImage destImage) 986{ 987 const VkDevice vkDevice = getDevice(); 988 const DeviceInterface& vk = getDeviceInterface(); 989 const VkQueue queue = getUniversalQueue(); 990 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 991 992 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE; 993 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 994 deUint32 bufferSize = 0u; 995 Move<VkBuffer> buffer; 996 de::MovePtr<Allocation> bufferAlloc; 997 std::vector<VkBufferImageCopy> copyRegions; 998 std::vector<deUint32> offsetMultiples; 999 1000 offsetMultiples.push_back(4u); 1001 offsetMultiples.push_back(texFormat.getPixelSize()); 1002 1003 // Calculate buffer size 1004 for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit) 1005 { 1006 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit) 1007 { 1008 const tcu::ConstPixelBufferAccess& access = *lit; 1009 1010 bufferSize = getNextMultiple(offsetMultiples, bufferSize); 1011 bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize(); 1012 } 1013 } 1014 1015 // Create source buffer 1016 { 1017 const VkBufferCreateInfo bufferParams = 1018 { 1019 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1020 DE_NULL, // const void* pNext; 1021 0u, // VkBufferCreateFlags flags; 1022 bufferSize, // VkDeviceSize size; 1023 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 1024 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1025 0u, // deUint32 queueFamilyIndexCount; 1026 DE_NULL, // const deUint32* pQueueFamilyIndices; 1027 }; 1028 1029 buffer = createBuffer(vk, vkDevice, &bufferParams); 1030 bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 1031 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 1032 } 1033 1034 // Get copy regions and write buffer data 1035 { 1036 deUint32 layerDataOffset = 0; 1037 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr(); 1038 1039 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++) 1040 { 1041 const TextureLayerData& layerData = textureData[levelNdx]; 1042 1043 for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++) 1044 { 1045 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset); 1046 1047 const tcu::ConstPixelBufferAccess& access = layerData[layerNdx]; 1048 const tcu::PixelBufferAccess destAccess (access.getFormat(), access.getSize(), destPtr + layerDataOffset); 1049 1050 const VkBufferImageCopy layerRegion = 1051 { 1052 layerDataOffset, // VkDeviceSize bufferOffset; 1053 (deUint32)access.getWidth(), // deUint32 bufferRowLength; 1054 (deUint32)access.getHeight(), // deUint32 bufferImageHeight; 1055 { // VkImageSubresourceLayers imageSubresource; 1056 aspectMask, // VkImageAspectFlags aspectMask; 1057 (deUint32)levelNdx, // uint32_t mipLevel; 1058 (deUint32)layerNdx, // uint32_t baseArrayLayer; 1059 1u // uint32_t layerCount; 1060 }, 1061 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 1062 { // VkExtent3D imageExtent; 1063 (deUint32)access.getWidth(), 1064 (deUint32)access.getHeight(), 1065 (deUint32)access.getDepth() 1066 } 1067 }; 1068 1069 copyRegions.push_back(layerRegion); 1070 tcu::copy(destAccess, access); 1071 1072 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize(); 1073 } 1074 } 1075 } 1076 1077 flushAlloc(vk, vkDevice, *bufferAlloc); 1078 1079 if(m_externalCommandPool.get() != DE_NULL) 1080 copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, aspectMask, mipLevels, arrayLayers, destImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT, &(m_externalCommandPool.get()->get())); 1081 else 1082 copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, aspectMask, mipLevels, arrayLayers, destImage); 1083} 1084 1085void ShaderRenderCaseInstance::clearImage (const tcu::Sampler& refSampler, 1086 deUint32 mipLevels, 1087 deUint32 arrayLayers, 1088 VkImage destImage) 1089{ 1090 const VkDevice vkDevice = m_context.getDevice(); 1091 const DeviceInterface& vk = m_context.getDeviceInterface(); 1092 const VkQueue queue = m_context.getUniversalQueue(); 1093 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1094 1095 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE; 1096 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 1097 Move<VkCommandPool> cmdPool; 1098 Move<VkCommandBuffer> cmdBuffer; 1099 1100 VkClearValue clearValue; 1101 deMemset(&clearValue, 0, sizeof(clearValue)); 1102 1103 1104 // Create command pool 1105 VkCommandPool activeCmdPool; 1106 if (m_externalCommandPool.get() == DE_NULL) 1107 { 1108 // Create local command pool 1109 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 1110 activeCmdPool = *cmdPool; 1111 } 1112 else 1113 { 1114 // Use external command pool if available 1115 activeCmdPool = m_externalCommandPool.get()->get(); 1116 } 1117 // Create command buffer 1118 cmdBuffer = allocateCommandBuffer(vk, vkDevice, activeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 1119 1120 const VkImageMemoryBarrier preImageBarrier = 1121 { 1122 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1123 DE_NULL, // const void* pNext; 1124 0u, // VkAccessFlags srcAccessMask; 1125 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1126 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1127 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 1128 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1129 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1130 destImage, // VkImage image; 1131 { // VkImageSubresourceRange subresourceRange; 1132 aspectMask, // VkImageAspect aspect; 1133 0u, // deUint32 baseMipLevel; 1134 mipLevels, // deUint32 mipLevels; 1135 0u, // deUint32 baseArraySlice; 1136 arrayLayers // deUint32 arraySize; 1137 } 1138 }; 1139 1140 const VkImageMemoryBarrier postImageBarrier = 1141 { 1142 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1143 DE_NULL, // const void* pNext; 1144 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1145 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 1146 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1147 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout; 1148 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1149 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1150 destImage, // VkImage image; 1151 { // VkImageSubresourceRange subresourceRange; 1152 aspectMask, // VkImageAspect aspect; 1153 0u, // deUint32 baseMipLevel; 1154 mipLevels, // deUint32 mipLevels; 1155 0u, // deUint32 baseArraySlice; 1156 arrayLayers // deUint32 arraySize; 1157 } 1158 }; 1159 1160 const VkImageSubresourceRange clearRange = 1161 { 1162 aspectMask, // VkImageAspectFlags aspectMask; 1163 0u, // deUint32 baseMipLevel; 1164 mipLevels, // deUint32 levelCount; 1165 0u, // deUint32 baseArrayLayer; 1166 arrayLayers // deUint32 layerCount; 1167 }; 1168 1169 // Copy buffer to image 1170 beginCommandBuffer(vk, *cmdBuffer); 1171 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier); 1172 if (aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) 1173 { 1174 vk.cmdClearColorImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &clearRange); 1175 } 1176 else 1177 { 1178 vk.cmdClearDepthStencilImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &clearRange); 1179 } 1180 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); 1181 endCommandBuffer(vk, *cmdBuffer); 1182 1183 submitCommandsAndWait(vk, vkDevice, queue, cmdBuffer.get()); 1184} 1185 1186VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel) 1187{ 1188 VkExtent3D result; 1189 1190 result.width = std::max(baseExtents.width >> mipLevel, 1u); 1191 result.height = std::max(baseExtents.height >> mipLevel, 1u); 1192 result.depth = std::max(baseExtents.depth >> mipLevel, 1u); 1193 1194 return result; 1195} 1196 1197tcu::UVec3 alignedDivide (const VkExtent3D& extent, const VkExtent3D& divisor) 1198{ 1199 tcu::UVec3 result; 1200 1201 result.x() = extent.width / divisor.width + ((extent.width % divisor.width != 0) ? 1u : 0u); 1202 result.y() = extent.height / divisor.height + ((extent.height % divisor.height != 0) ? 1u : 0u); 1203 result.z() = extent.depth / divisor.depth + ((extent.depth % divisor.depth != 0) ? 1u : 0u); 1204 1205 return result; 1206} 1207 1208bool isImageSizeSupported (const VkImageType imageType, const tcu::UVec3& imageSize, const vk::VkPhysicalDeviceLimits& limits) 1209{ 1210 switch (imageType) 1211 { 1212 case VK_IMAGE_TYPE_1D: 1213 return (imageSize.x() <= limits.maxImageDimension1D 1214 && imageSize.y() == 1 1215 && imageSize.z() == 1); 1216 case VK_IMAGE_TYPE_2D: 1217 return (imageSize.x() <= limits.maxImageDimension2D 1218 && imageSize.y() <= limits.maxImageDimension2D 1219 && imageSize.z() == 1); 1220 case VK_IMAGE_TYPE_3D: 1221 return (imageSize.x() <= limits.maxImageDimension3D 1222 && imageSize.y() <= limits.maxImageDimension3D 1223 && imageSize.z() <= limits.maxImageDimension3D); 1224 default: 1225 DE_FATAL("Unknown image type"); 1226 return false; 1227 } 1228} 1229 1230void ShaderRenderCaseInstance::checkSparseSupport (const VkImageCreateInfo& imageInfo) const 1231{ 1232#ifdef CTS_USES_VULKANSC 1233 TCU_THROW(NotSupportedError, "Vulkan SC does not support sparse operations"); 1234#endif // CTS_USES_VULKANSC 1235 const InstanceInterface& instance = getInstanceInterface(); 1236 const VkPhysicalDevice physicalDevice = getPhysicalDevice(); 1237 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice); 1238#ifndef CTS_USES_VULKANSC 1239 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties( 1240 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling); 1241#endif // CTS_USES_VULKANSC 1242 1243 if (!deviceFeatures.shaderResourceResidency) 1244 TCU_THROW(NotSupportedError, "Required feature: shaderResourceResidency."); 1245 1246 if (!deviceFeatures.sparseBinding) 1247 TCU_THROW(NotSupportedError, "Required feature: sparseBinding."); 1248 1249 if (imageInfo.imageType == VK_IMAGE_TYPE_2D && !deviceFeatures.sparseResidencyImage2D) 1250 TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage2D."); 1251 1252 if (imageInfo.imageType == VK_IMAGE_TYPE_3D && !deviceFeatures.sparseResidencyImage3D) 1253 TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage3D."); 1254#ifndef CTS_USES_VULKANSC 1255 if (sparseImageFormatPropVec.size() == 0) 1256 TCU_THROW(NotSupportedError, "The image format does not support sparse operations"); 1257#endif // CTS_USES_VULKANSC 1258} 1259 1260#ifndef CTS_USES_VULKANSC 1261void ShaderRenderCaseInstance::uploadSparseImage (const tcu::TextureFormat& texFormat, 1262 const TextureData& textureData, 1263 const tcu::Sampler& refSampler, 1264 const deUint32 mipLevels, 1265 const deUint32 arrayLayers, 1266 const VkImage sparseImage, 1267 const VkImageCreateInfo& imageCreateInfo, 1268 const tcu::UVec3 texSize) 1269{ 1270 const VkDevice vkDevice = getDevice(); 1271 const DeviceInterface& vk = getDeviceInterface(); 1272 const VkPhysicalDevice physicalDevice = getPhysicalDevice(); 1273 const VkQueue queue = getUniversalQueue(); 1274 const VkQueue sparseQueue = getSparseQueue(); 1275 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 1276 const InstanceInterface& instance = getInstanceInterface(); 1277 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice); 1278 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE; 1279 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 1280 const Unique<VkSemaphore> imageMemoryBindSemaphore(createSemaphore(vk, vkDevice)); 1281 Move<VkBuffer> buffer; 1282 deUint32 bufferSize = 0u; 1283 de::MovePtr<Allocation> bufferAlloc; 1284 std::vector<VkBufferImageCopy> copyRegions; 1285 std::vector<deUint32> offsetMultiples; 1286 1287 offsetMultiples.push_back(4u); 1288 offsetMultiples.push_back(texFormat.getPixelSize()); 1289 1290 if (isImageSizeSupported(imageCreateInfo.imageType, texSize, deviceProperties.limits) == false) 1291 TCU_THROW(NotSupportedError, "Image size not supported for device."); 1292 1293 allocateAndBindSparseImage(vk, vkDevice, physicalDevice, instance, imageCreateInfo, *imageMemoryBindSemaphore, sparseQueue, m_memAlloc, m_allocations, texFormat, sparseImage); 1294 1295 // Calculate buffer size 1296 for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit) 1297 { 1298 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit) 1299 { 1300 const tcu::ConstPixelBufferAccess& access = *lit; 1301 1302 bufferSize = getNextMultiple(offsetMultiples, bufferSize); 1303 bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize(); 1304 } 1305 } 1306 1307 { 1308 // Create source buffer 1309 const VkBufferCreateInfo bufferParams = 1310 { 1311 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1312 DE_NULL, // const void* pNext; 1313 0u, // VkBufferCreateFlags flags; 1314 bufferSize, // VkDeviceSize size; 1315 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 1316 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1317 0u, // deUint32 queueFamilyIndexCount; 1318 DE_NULL, // const deUint32* pQueueFamilyIndices; 1319 }; 1320 1321 buffer = createBuffer(vk, vkDevice, &bufferParams); 1322 bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 1323 1324 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 1325 } 1326 1327 // Get copy regions and write buffer data 1328 { 1329 deUint32 layerDataOffset = 0; 1330 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr(); 1331 1332 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++) 1333 { 1334 const TextureLayerData& layerData = textureData[levelNdx]; 1335 1336 for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++) 1337 { 1338 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset); 1339 1340 const tcu::ConstPixelBufferAccess& access = layerData[layerNdx]; 1341 const tcu::PixelBufferAccess destAccess (access.getFormat(), access.getSize(), destPtr + layerDataOffset); 1342 1343 const VkBufferImageCopy layerRegion = 1344 { 1345 layerDataOffset, // VkDeviceSize bufferOffset; 1346 (deUint32)access.getWidth(), // deUint32 bufferRowLength; 1347 (deUint32)access.getHeight(), // deUint32 bufferImageHeight; 1348 { // VkImageSubresourceLayers imageSubresource; 1349 aspectMask, // VkImageAspectFlags aspectMask; 1350 (deUint32)levelNdx, // uint32_t mipLevel; 1351 (deUint32)layerNdx, // uint32_t baseArrayLayer; 1352 1u // uint32_t layerCount; 1353 }, 1354 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 1355 { // VkExtent3D imageExtent; 1356 (deUint32)access.getWidth(), 1357 (deUint32)access.getHeight(), 1358 (deUint32)access.getDepth() 1359 } 1360 }; 1361 1362 copyRegions.push_back(layerRegion); 1363 tcu::copy(destAccess, access); 1364 1365 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize(); 1366 } 1367 } 1368 } 1369 copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, &(*imageMemoryBindSemaphore), aspectMask, mipLevels, arrayLayers, sparseImage); 1370} 1371#endif // CTS_USES_VULKANSC 1372 1373void ShaderRenderCaseInstance::useSampler (deUint32 bindingLocation, deUint32 textureId) 1374{ 1375 DE_ASSERT(textureId < m_textures.size()); 1376 1377 const TextureBinding& textureBinding = *m_textures[textureId]; 1378 const TextureBinding::Type textureType = textureBinding.getType(); 1379 const tcu::Sampler& refSampler = textureBinding.getSampler(); 1380 const TextureBinding::Parameters& textureParams = textureBinding.getParameters(); 1381 const bool isMSTexture = textureParams.samples != vk::VK_SAMPLE_COUNT_1_BIT; 1382 deUint32 mipLevels = 1u; 1383 deUint32 arrayLayers = 1u; 1384 tcu::TextureFormat texFormat; 1385 tcu::UVec3 texSize; 1386 TextureData textureData; 1387 1388 if (textureType == TextureBinding::TYPE_2D) 1389 { 1390 const tcu::Texture2D& texture = textureBinding.get2D(); 1391 1392 texFormat = texture.getFormat(); 1393 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u); 1394 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1395 arrayLayers = 1u; 1396 1397 textureData.resize(mipLevels); 1398 1399 for (deUint32 level = 0; level < mipLevels; ++level) 1400 { 1401 if (texture.isLevelEmpty(level)) 1402 continue; 1403 1404 textureData[level].push_back(texture.getLevel(level)); 1405 } 1406 } 1407 else if (textureType == TextureBinding::TYPE_CUBE_MAP) 1408 { 1409 const tcu::TextureCube& texture = textureBinding.getCube(); 1410 1411 texFormat = texture.getFormat(); 1412 texSize = tcu::UVec3(texture.getSize(), texture.getSize(), 1u); 1413 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1414 arrayLayers = 6u; 1415 1416 static const tcu::CubeFace cubeFaceMapping[tcu::CUBEFACE_LAST] = 1417 { 1418 tcu::CUBEFACE_POSITIVE_X, 1419 tcu::CUBEFACE_NEGATIVE_X, 1420 tcu::CUBEFACE_POSITIVE_Y, 1421 tcu::CUBEFACE_NEGATIVE_Y, 1422 tcu::CUBEFACE_POSITIVE_Z, 1423 tcu::CUBEFACE_NEGATIVE_Z 1424 }; 1425 1426 textureData.resize(mipLevels); 1427 1428 for (deUint32 level = 0; level < mipLevels; ++level) 1429 { 1430 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx) 1431 { 1432 tcu::CubeFace face = cubeFaceMapping[faceNdx]; 1433 1434 if (texture.isLevelEmpty(face, level)) 1435 continue; 1436 1437 textureData[level].push_back(texture.getLevelFace(level, face)); 1438 } 1439 } 1440 } 1441 else if (textureType == TextureBinding::TYPE_2D_ARRAY) 1442 { 1443 const tcu::Texture2DArray& texture = textureBinding.get2DArray(); 1444 1445 texFormat = texture.getFormat(); 1446 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u); 1447 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1448 arrayLayers = (deUint32)texture.getNumLayers(); 1449 1450 textureData.resize(mipLevels); 1451 1452 for (deUint32 level = 0; level < mipLevels; ++level) 1453 { 1454 if (texture.isLevelEmpty(level)) 1455 continue; 1456 1457 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level); 1458 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 1459 1460 for (deUint32 layer = 0; layer < arrayLayers; ++layer) 1461 { 1462 const deUint32 layerOffset = layerSize * layer; 1463 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 1464 textureData[level].push_back(layerData); 1465 } 1466 } 1467 } 1468 else if (textureType == TextureBinding::TYPE_3D) 1469 { 1470 const tcu::Texture3D& texture = textureBinding.get3D(); 1471 1472 texFormat = texture.getFormat(); 1473 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), texture.getDepth()); 1474 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1475 arrayLayers = 1u; 1476 1477 textureData.resize(mipLevels); 1478 1479 for (deUint32 level = 0; level < mipLevels; ++level) 1480 { 1481 if (texture.isLevelEmpty(level)) 1482 continue; 1483 1484 textureData[level].push_back(texture.getLevel(level)); 1485 } 1486 } 1487 else if (textureType == TextureBinding::TYPE_1D) 1488 { 1489 const tcu::Texture1D& texture = textureBinding.get1D(); 1490 1491 texFormat = texture.getFormat(); 1492 texSize = tcu::UVec3(texture.getWidth(), 1, 1); 1493 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1494 arrayLayers = 1u; 1495 1496 textureData.resize(mipLevels); 1497 1498 for (deUint32 level = 0; level < mipLevels; ++level) 1499 { 1500 if (texture.isLevelEmpty(level)) 1501 continue; 1502 1503 textureData[level].push_back(texture.getLevel(level)); 1504 } 1505 } 1506 else if (textureType == TextureBinding::TYPE_1D_ARRAY) 1507 { 1508 const tcu::Texture1DArray& texture = textureBinding.get1DArray(); 1509 1510 texFormat = texture.getFormat(); 1511 texSize = tcu::UVec3(texture.getWidth(), 1, 1); 1512 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1513 arrayLayers = (deUint32)texture.getNumLayers(); 1514 1515 textureData.resize(mipLevels); 1516 1517 for (deUint32 level = 0; level < mipLevels; ++level) 1518 { 1519 if (texture.isLevelEmpty(level)) 1520 continue; 1521 1522 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level); 1523 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize(); 1524 1525 for (deUint32 layer = 0; layer < arrayLayers; ++layer) 1526 { 1527 const deUint32 layerOffset = layerSize * layer; 1528 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 1529 textureData[level].push_back(layerData); 1530 } 1531 } 1532 } 1533 else if (textureType == TextureBinding::TYPE_CUBE_ARRAY) 1534 { 1535 const tcu::TextureCubeArray& texture = textureBinding.getCubeArray(); 1536 texFormat = texture.getFormat(); 1537 texSize = tcu::UVec3(texture.getSize(), texture.getSize(), 1); 1538 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels(); 1539 arrayLayers = texture.getDepth(); 1540 1541 textureData.resize(mipLevels); 1542 1543 for (deUint32 level = 0; level < mipLevels; ++level) 1544 { 1545 if (texture.isLevelEmpty(level)) 1546 continue; 1547 1548 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level); 1549 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 1550 1551 for (deUint32 layer = 0; layer < arrayLayers; ++layer) 1552 { 1553 const deUint32 layerOffset = layerSize * layer; 1554 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 1555 textureData[level].push_back(layerData); 1556 } 1557 } 1558 } 1559 else 1560 { 1561 TCU_THROW(InternalError, "Invalid texture type"); 1562 } 1563 1564 createSamplerUniform(bindingLocation, textureType, textureBinding.getParameters().initialization, texFormat, texSize, textureData, refSampler, mipLevels, arrayLayers, textureParams); 1565} 1566 1567void ShaderRenderCaseInstance::setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges) 1568{ 1569 m_pushConstantRanges.clear(); 1570 for (deUint32 i = 0; i < rangeCount; ++i) 1571 { 1572 m_pushConstantRanges.push_back(pcRanges[i]); 1573 } 1574} 1575 1576void ShaderRenderCaseInstance::updatePushConstants (vk::VkCommandBuffer, vk::VkPipelineLayout) 1577{ 1578} 1579 1580void ShaderRenderCaseInstance::createSamplerUniform (deUint32 bindingLocation, 1581 TextureBinding::Type textureType, 1582 TextureBinding::Init textureInit, 1583 const tcu::TextureFormat& texFormat, 1584 const tcu::UVec3 texSize, 1585 const TextureData& textureData, 1586 const tcu::Sampler& refSampler, 1587 deUint32 mipLevels, 1588 deUint32 arrayLayers, 1589 TextureBinding::Parameters textureParams) 1590{ 1591 const VkDevice vkDevice = getDevice(); 1592 const DeviceInterface& vk = getDeviceInterface(); 1593 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 1594 const deUint32 sparseFamilyIndex = (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) ? getSparseQueueFamilyIndex() : queueFamilyIndex; 1595 1596 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE; 1597 1598 // when isShadowSampler is true mapSampler utill will set compareEnabled in 1599 // VkSamplerCreateInfo to true and in portability this functionality is under 1600 // feature flag - note that this is safety check as this is known at the 1601 // TestCase level and NotSupportedError should be thrown from checkSupport 1602#ifndef CTS_USES_VULKANSC 1603 if (isShadowSampler && 1604 m_context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && 1605 !m_context.getPortabilitySubsetFeatures().mutableComparisonSamplers) 1606 { 1607 DE_FATAL("mutableComparisonSamplers support should be checked in checkSupport"); 1608 } 1609#endif // CTS_USES_VULKANSC 1610 1611 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 1612 const VkImageViewType imageViewType = textureTypeToImageViewType(textureType); 1613 const VkImageType imageType = viewTypeToImageType(imageViewType); 1614 const VkSharingMode sharingMode = (queueFamilyIndex != sparseFamilyIndex) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE; 1615 const VkFormat format = mapTextureFormat(texFormat); 1616 const VkImageUsageFlags imageUsageFlags = textureUsageFlags(); 1617 const VkImageCreateFlags imageCreateFlags = textureCreateFlags(imageViewType, m_imageBackingMode); 1618 1619 const deUint32 queueIndexCount = (queueFamilyIndex != sparseFamilyIndex) ? 2 : 1; 1620 const deUint32 queueIndices[] = 1621 { 1622 queueFamilyIndex, 1623 sparseFamilyIndex 1624 }; 1625 1626 Move<VkImage> vkTexture; 1627 de::MovePtr<Allocation> allocation; 1628 1629 // Create image 1630 const VkImageCreateInfo imageParams = 1631 { 1632 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1633 DE_NULL, // const void* pNext; 1634 imageCreateFlags, // VkImageCreateFlags flags; 1635 imageType, // VkImageType imageType; 1636 format, // VkFormat format; 1637 { // VkExtent3D extent; 1638 texSize.x(), 1639 texSize.y(), 1640 texSize.z() 1641 }, 1642 mipLevels, // deUint32 mipLevels; 1643 arrayLayers, // deUint32 arrayLayers; 1644 textureParams.samples, // VkSampleCountFlagBits samples; 1645 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1646 imageUsageFlags, // VkImageUsageFlags usage; 1647 sharingMode, // VkSharingMode sharingMode; 1648 queueIndexCount, // deUint32 queueFamilyIndexCount; 1649 queueIndices, // const deUint32* pQueueFamilyIndices; 1650 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 1651 }; 1652 1653 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) 1654 { 1655 checkSparseSupport(imageParams); 1656 } 1657 1658 vkTexture = createImage(vk, vkDevice, &imageParams); 1659 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any); 1660 1661 if (m_imageBackingMode != IMAGE_BACKING_MODE_SPARSE) 1662 { 1663 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset())); 1664 } 1665 1666 switch (textureInit) 1667 { 1668 case TextureBinding::INIT_UPLOAD_DATA: 1669 { 1670 // upload*Image functions use cmdCopyBufferToImage, which is invalid for multisample images 1671 DE_ASSERT(textureParams.samples == VK_SAMPLE_COUNT_1_BIT); 1672 1673 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) 1674 { 1675#ifndef CTS_USES_VULKANSC 1676 uploadSparseImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture, imageParams, texSize); 1677#endif // CTS_USES_VULKANSC 1678 } 1679 else 1680 { 1681 // Upload texture data 1682 uploadImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture); 1683 } 1684 break; 1685 } 1686 case TextureBinding::INIT_CLEAR: 1687 clearImage(refSampler, mipLevels, arrayLayers, *vkTexture); 1688 break; 1689 default: 1690 DE_FATAL("Impossible"); 1691 } 1692 1693 // Create sampler 1694 const auto& minMaxLod = textureParams.minMaxLod; 1695 const VkSamplerCreateInfo samplerParams = (minMaxLod 1696 ? mapSampler(refSampler, texFormat, minMaxLod.get().minLod, minMaxLod.get().maxLod) 1697 : mapSampler(refSampler, texFormat)); 1698 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams); 1699 const deUint32 baseMipLevel = textureParams.baseMipLevel; 1700 const vk::VkComponentMapping components = textureParams.componentMapping; 1701 const VkImageViewCreateInfo viewParams = 1702 { 1703 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1704 NULL, // const voide* pNext; 1705 0u, // VkImageViewCreateFlags flags; 1706 *vkTexture, // VkImage image; 1707 imageViewType, // VkImageViewType viewType; 1708 format, // VkFormat format; 1709 components, // VkChannelMapping channels; 1710 { 1711 aspectMask, // VkImageAspectFlags aspectMask; 1712 baseMipLevel, // deUint32 baseMipLevel; 1713 mipLevels - baseMipLevel, // deUint32 mipLevels; 1714 0, // deUint32 baseArraySlice; 1715 arrayLayers // deUint32 arraySize; 1716 }, // VkImageSubresourceRange subresourceRange; 1717 }; 1718 1719 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams); 1720 1721 const vk::VkDescriptorImageInfo descriptor = 1722 { 1723 sampler.get(), // VkSampler sampler; 1724 imageView.get(), // VkImageView imageView; 1725 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout imageLayout; 1726 }; 1727 1728 de::MovePtr<SamplerUniform> uniform(new SamplerUniform()); 1729 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 1730 uniform->descriptor = descriptor; 1731 uniform->location = bindingLocation; 1732 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture)); 1733 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView)); 1734 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler)); 1735 uniform->alloc = AllocationSp(allocation.release()); 1736 1737 m_descriptorSetLayoutBuilder->addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, DE_NULL); 1738 m_descriptorPoolBuilder->addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 1739 1740 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform))); 1741} 1742 1743void ShaderRenderCaseInstance::setupDefaultInputs (void) 1744{ 1745 /* Configuration of the vertex input attributes: 1746 a_position is at location 0 1747 a_coords is at location 1 1748 a_unitCoords is at location 2 1749 a_one is at location 3 1750 1751 User attributes starts from at the location 4. 1752 */ 1753 1754 DE_ASSERT(m_quadGrid); 1755 const QuadGrid& quadGrid = *m_quadGrid; 1756 1757 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions()); 1758 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords()); 1759 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords()); 1760 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne()); 1761 1762 static const struct 1763 { 1764 BaseAttributeType type; 1765 int userNdx; 1766 } userAttributes[] = 1767 { 1768 { A_IN0, 0 }, 1769 { A_IN1, 1 }, 1770 { A_IN2, 2 }, 1771 { A_IN3, 3 } 1772 }; 1773 1774 static const struct 1775 { 1776 BaseAttributeType matrixType; 1777 int numCols; 1778 int numRows; 1779 } matrices[] = 1780 { 1781 { MAT2, 2, 2 }, 1782 { MAT2x3, 2, 3 }, 1783 { MAT2x4, 2, 4 }, 1784 { MAT3x2, 3, 2 }, 1785 { MAT3, 3, 3 }, 1786 { MAT3x4, 3, 4 }, 1787 { MAT4x2, 4, 2 }, 1788 { MAT4x3, 4, 3 }, 1789 { MAT4, 4, 4 } 1790 }; 1791 1792 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++) 1793 { 1794 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++) 1795 { 1796 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type) 1797 continue; 1798 1799 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx)); 1800 } 1801 1802 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++) 1803 { 1804 1805 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type) 1806 continue; 1807 1808 const int numCols = matrices[matNdx].numCols; 1809 1810 for (int colNdx = 0; colNdx < numCols; colNdx++) 1811 { 1812 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx)); 1813 } 1814 } 1815 } 1816} 1817 1818void ShaderRenderCaseInstance::render (deUint32 numVertices, 1819 deUint32 numTriangles, 1820 const deUint16* indices, 1821 const tcu::Vec4& constCoords) 1822{ 1823 render(numVertices, numTriangles * 3, indices, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, constCoords); 1824} 1825 1826void ShaderRenderCaseInstance::render (deUint32 numVertices, 1827 deUint32 numIndices, 1828 const deUint16* indices, 1829 VkPrimitiveTopology topology, 1830 const tcu::Vec4& constCoords) 1831{ 1832 const VkDevice vkDevice = getDevice(); 1833 const DeviceInterface& vk = getDeviceInterface(); 1834 const VkQueue queue = getUniversalQueue(); 1835 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); 1836 1837 vk::Move<vk::VkImage> colorImage; 1838 de::MovePtr<vk::Allocation> colorImageAlloc; 1839 vk::Move<vk::VkImageView> colorImageView; 1840 vk::Move<vk::VkImage> resolvedImage; 1841 de::MovePtr<vk::Allocation> resolvedImageAlloc; 1842 vk::Move<vk::VkImageView> resolvedImageView; 1843 vk::Move<vk::VkRenderPass> renderPass; 1844 vk::Move<vk::VkFramebuffer> framebuffer; 1845 vk::Move<vk::VkPipelineLayout> pipelineLayout; 1846 vk::Move<vk::VkPipeline> graphicsPipeline; 1847 vk::Move<vk::VkShaderModule> vertexShaderModule; 1848 vk::Move<vk::VkShaderModule> fragmentShaderModule; 1849 vk::Move<vk::VkBuffer> indexBuffer; 1850 de::MovePtr<vk::Allocation> indexBufferAlloc; 1851 vk::Move<vk::VkDescriptorSetLayout> descriptorSetLayout; 1852 vk::Move<vk::VkDescriptorPool> descriptorPool; 1853 vk::Move<vk::VkDescriptorSet> descriptorSet; 1854 vk::Move<vk::VkCommandPool> cmdPool; 1855 vk::Move<vk::VkCommandBuffer> cmdBuffer; 1856 1857 // Create color image 1858 { 1859 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1860 VkImageFormatProperties properties; 1861 1862 if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(), 1863 m_colorFormat, 1864 VK_IMAGE_TYPE_2D, 1865 VK_IMAGE_TILING_OPTIMAL, 1866 imageUsage, 1867 0u, 1868 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)) 1869 { 1870 TCU_THROW(NotSupportedError, "Format not supported"); 1871 } 1872 1873 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount) 1874 { 1875 TCU_THROW(NotSupportedError, "Format not supported"); 1876 } 1877 1878 const VkImageCreateInfo colorImageParams = 1879 { 1880 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1881 DE_NULL, // const void* pNext; 1882 0u, // VkImageCreateFlags flags; 1883 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1884 m_colorFormat, // VkFormat format; 1885 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 1886 1u, // deUint32 mipLevels; 1887 1u, // deUint32 arraySize; 1888 m_sampleCount, // deUint32 samples; 1889 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1890 imageUsage, // VkImageUsageFlags usage; 1891 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1892 1u, // deUint32 queueFamilyCount; 1893 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1894 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1895 }; 1896 1897 colorImage = createImage(vk, vkDevice, &colorImageParams); 1898 1899 // Allocate and bind color image memory 1900 colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any); 1901 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset())); 1902 } 1903 1904 // Create color attachment view 1905 { 1906 const VkImageViewCreateInfo colorImageViewParams = 1907 { 1908 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1909 DE_NULL, // const void* pNext; 1910 0u, // VkImageViewCreateFlags flags; 1911 *colorImage, // VkImage image; 1912 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1913 m_colorFormat, // VkFormat format; 1914 { 1915 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r; 1916 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g; 1917 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b; 1918 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a; 1919 }, // VkChannelMapping channels; 1920 { 1921 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1922 0, // deUint32 baseMipLevel; 1923 1, // deUint32 mipLevels; 1924 0, // deUint32 baseArraySlice; 1925 1 // deUint32 arraySize; 1926 }, // VkImageSubresourceRange subresourceRange; 1927 }; 1928 1929 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams); 1930 } 1931 1932 if (isMultiSampling()) 1933 { 1934 // Resolved Image 1935 { 1936 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 1937 VkImageFormatProperties properties; 1938 1939 if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(), 1940 m_colorFormat, 1941 VK_IMAGE_TYPE_2D, 1942 VK_IMAGE_TILING_OPTIMAL, 1943 imageUsage, 1944 0, 1945 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)) 1946 { 1947 TCU_THROW(NotSupportedError, "Format not supported"); 1948 } 1949 1950 const VkImageCreateInfo imageCreateInfo = 1951 { 1952 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1953 DE_NULL, // const void* pNext; 1954 0u, // VkImageCreateFlags flags; 1955 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1956 m_colorFormat, // VkFormat format; 1957 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 1958 1u, // deUint32 mipLevels; 1959 1u, // deUint32 arrayLayers; 1960 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1961 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1962 imageUsage, // VkImageUsageFlags usage; 1963 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1964 1u, // deUint32 queueFamilyIndexCount; 1965 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1966 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 1967 }; 1968 1969 resolvedImage = vk::createImage(vk, vkDevice, &imageCreateInfo, DE_NULL); 1970 resolvedImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *resolvedImage), MemoryRequirement::Any); 1971 VK_CHECK(vk.bindImageMemory(vkDevice, *resolvedImage, resolvedImageAlloc->getMemory(), resolvedImageAlloc->getOffset())); 1972 } 1973 1974 // Resolved Image View 1975 { 1976 const VkImageViewCreateInfo imageViewCreateInfo = 1977 { 1978 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1979 DE_NULL, // const void* pNext; 1980 0u, // VkImageViewCreateFlags flags; 1981 *resolvedImage, // VkImage image; 1982 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1983 m_colorFormat, // VkFormat format; 1984 { 1985 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r; 1986 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g; 1987 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b; 1988 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a; 1989 }, 1990 { 1991 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1992 0u, // deUint32 baseMipLevel; 1993 1u, // deUint32 mipLevels; 1994 0u, // deUint32 baseArrayLayer; 1995 1u, // deUint32 arraySize; 1996 }, // VkImageSubresourceRange subresourceRange; 1997 }; 1998 1999 resolvedImageView = vk::createImageView(vk, vkDevice, &imageViewCreateInfo, DE_NULL); 2000 } 2001 } 2002 2003 // Create render pass 2004 { 2005 const VkAttachmentDescription attachmentDescription[] = 2006 { 2007 { 2008 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 2009 m_colorFormat, // VkFormat format; 2010 m_sampleCount, // deUint32 samples; 2011 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 2012 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 2013 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 2014 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 2015 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 2016 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 2017 }, 2018 { 2019 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 2020 m_colorFormat, // VkFormat format; 2021 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 2022 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 2023 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 2024 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 2025 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 2026 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 2027 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 2028 } 2029 }; 2030 2031 const VkAttachmentReference attachmentReference = 2032 { 2033 0u, // deUint32 attachment; 2034 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 2035 }; 2036 2037 const VkAttachmentReference resolveAttachmentRef = 2038 { 2039 1u, // deUint32 attachment; 2040 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 2041 }; 2042 2043 const VkSubpassDescription subpassDescription = 2044 { 2045 0u, // VkSubpassDescriptionFlags flags; 2046 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 2047 0u, // deUint32 inputCount; 2048 DE_NULL, // constVkAttachmentReference* pInputAttachments; 2049 1u, // deUint32 colorCount; 2050 &attachmentReference, // constVkAttachmentReference* pColorAttachments; 2051 isMultiSampling() ? &resolveAttachmentRef : DE_NULL,// constVkAttachmentReference* pResolveAttachments; 2052 DE_NULL, // VkAttachmentReference depthStencilAttachment; 2053 0u, // deUint32 preserveCount; 2054 DE_NULL // constVkAttachmentReference* pPreserveAttachments; 2055 }; 2056 2057 const VkRenderPassCreateInfo renderPassParams = 2058 { 2059 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 2060 DE_NULL, // const void* pNext; 2061 0u, // VkRenderPassCreateFlags flags; 2062 isMultiSampling() ? 2u : 1u, // deUint32 attachmentCount; 2063 attachmentDescription, // const VkAttachmentDescription* pAttachments; 2064 1u, // deUint32 subpassCount; 2065 &subpassDescription, // const VkSubpassDescription* pSubpasses; 2066 0u, // deUint32 dependencyCount; 2067 DE_NULL // const VkSubpassDependency* pDependencies; 2068 }; 2069 2070 renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 2071 } 2072 2073 // Create framebuffer 2074 { 2075 const VkImageView attachments[] = 2076 { 2077 *colorImageView, 2078 *resolvedImageView 2079 }; 2080 2081 const VkFramebufferCreateInfo framebufferParams = 2082 { 2083 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 2084 DE_NULL, // const void* pNext; 2085 (VkFramebufferCreateFlags)0, 2086 *renderPass, // VkRenderPass renderPass; 2087 isMultiSampling() ? 2u : 1u, // deUint32 attachmentCount; 2088 attachments, // const VkImageView* pAttachments; 2089 (deUint32)m_renderSize.x(), // deUint32 width; 2090 (deUint32)m_renderSize.y(), // deUint32 height; 2091 1u // deUint32 layers; 2092 }; 2093 2094 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 2095 } 2096 2097 // Create descriptors 2098 { 2099 setupUniforms(constCoords); 2100 2101 descriptorSetLayout = m_descriptorSetLayoutBuilder->build(vk, vkDevice); 2102 if (!m_uniformInfos.empty()) 2103 { 2104 descriptorPool = m_descriptorPoolBuilder->build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 2105 const VkDescriptorSetAllocateInfo allocInfo = 2106 { 2107 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 2108 DE_NULL, 2109 *descriptorPool, 2110 1u, 2111 &descriptorSetLayout.get(), 2112 }; 2113 2114 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo); 2115 } 2116 2117 for (deUint32 i = 0; i < m_uniformInfos.size(); i++) 2118 { 2119 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get(); 2120 deUint32 location = uniformInfo->location; 2121 2122 if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) 2123 { 2124 const BufferUniform* bufferInfo = dynamic_cast<const BufferUniform*>(uniformInfo); 2125 2126 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor); 2127 } 2128 else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 2129 { 2130 const SamplerUniform* samplerInfo = dynamic_cast<const SamplerUniform*>(uniformInfo); 2131 2132 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor); 2133 } 2134 else 2135 DE_FATAL("Impossible"); 2136 } 2137 2138 m_descriptorSetUpdateBuilder->update(vk, vkDevice); 2139 } 2140 2141 // Create pipeline layout 2142 { 2143 const VkPushConstantRange* const pcRanges = m_pushConstantRanges.empty() ? DE_NULL : &m_pushConstantRanges[0]; 2144 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 2145 { 2146 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 2147 DE_NULL, // const void* pNext; 2148 (VkPipelineLayoutCreateFlags)0, 2149 1u, // deUint32 descriptorSetCount; 2150 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 2151 deUint32(m_pushConstantRanges.size()), // deUint32 pushConstantRangeCount; 2152 pcRanges // const VkPushConstantRange* pPushConstantRanges; 2153 }; 2154 2155 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 2156 } 2157 2158 // Create shaders 2159 { 2160 vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_vertexShaderName), 0); 2161 fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_fragmentShaderName), 0); 2162 } 2163 2164 // Create pipeline 2165 { 2166 // Add test case specific attributes 2167 if (m_attribFunc) 2168 m_attribFunc(*this, numVertices); 2169 2170 // Add base attributes 2171 setupDefaultInputs(); 2172 2173 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 2174 { 2175 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 2176 DE_NULL, // const void* pNext; 2177 (VkPipelineVertexInputStateCreateFlags)0, 2178 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount; 2179 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 2180 (deUint32)m_vertexAttributeDescription.size(), // deUint32 attributeCount; 2181 &m_vertexAttributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 2182 }; 2183 2184 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize)); 2185 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize)); 2186 2187 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 2188 { 2189 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 2190 DE_NULL, // const void* pNext; 2191 0u, // VkPipelineMultisampleStateCreateFlags flags; 2192 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples; 2193 VK_FALSE, // VkBool32 sampleShadingEnable; 2194 0.0f, // float minSampleShading; 2195 DE_NULL, // const VkSampleMask* pSampleMask; 2196 VK_FALSE, // VkBool32 alphaToCoverageEnable; 2197 VK_FALSE // VkBool32 alphaToOneEnable; 2198 }; 2199 2200 graphicsPipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk 2201 vkDevice, // const VkDevice device 2202 *pipelineLayout, // const VkPipelineLayout pipelineLayout 2203 *vertexShaderModule, // const VkShaderModule vertexShaderModule 2204 DE_NULL, // const VkShaderModule tessellationControlShaderModule 2205 DE_NULL, // const VkShaderModule tessellationEvalShaderModule 2206 DE_NULL, // const VkShaderModule geometryShaderModule 2207 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule 2208 *renderPass, // const VkRenderPass renderPass 2209 viewports, // const std::vector<VkViewport>& viewports 2210 scissors, // const std::vector<VkRect2D>& scissors 2211 topology, // const VkPrimitiveTopology topology 2212 0u, // const deUint32 subpass 2213 0u, // const deUint32 patchControlPoints 2214 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo 2215 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo 2216 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo 2217 } 2218 2219 // Create vertex indices buffer 2220 if (numIndices != 0) 2221 { 2222 const VkDeviceSize indexBufferSize = numIndices * sizeof(deUint16); 2223 const VkBufferCreateInfo indexBufferParams = 2224 { 2225 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 2226 DE_NULL, // const void* pNext; 2227 0u, // VkBufferCreateFlags flags; 2228 indexBufferSize, // VkDeviceSize size; 2229 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage; 2230 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2231 1u, // deUint32 queueFamilyCount; 2232 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 2233 }; 2234 2235 indexBuffer = createBuffer(vk, vkDevice, &indexBufferParams); 2236 indexBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), MemoryRequirement::HostVisible); 2237 2238 VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset())); 2239 2240 // Load vertice indices into buffer 2241 deMemcpy(indexBufferAlloc->getHostPtr(), indices, (size_t)indexBufferSize); 2242 flushAlloc(vk, vkDevice, *indexBufferAlloc); 2243 } 2244 2245 VkCommandPool activeCmdPool; 2246 if (m_externalCommandPool.get() == DE_NULL) 2247 { 2248 // Create local command pool 2249 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 2250 activeCmdPool = *cmdPool; 2251 } 2252 else 2253 { 2254 // Use external command pool if available 2255 activeCmdPool = m_externalCommandPool.get()->get(); 2256 } 2257 2258 // Create command buffer 2259 { 2260 cmdBuffer = allocateCommandBuffer(vk, vkDevice, activeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 2261 2262 beginCommandBuffer(vk, *cmdBuffer); 2263 2264 { 2265 const VkImageMemoryBarrier imageBarrier = 2266 { 2267 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2268 DE_NULL, // const void* pNext; 2269 0u, // VkAccessFlags srcAccessMask; 2270 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2271 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2272 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2273 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2274 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2275 *colorImage, // VkImage image; 2276 { // VkImageSubresourceRange subresourceRange; 2277 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 2278 0u, // deUint32 baseMipLevel; 2279 1u, // deUint32 mipLevels; 2280 0u, // deUint32 baseArrayLayer; 2281 1u, // deUint32 arraySize; 2282 } 2283 }; 2284 2285 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); 2286 2287 if (isMultiSampling()) { 2288 // add multisample barrier 2289 const VkImageMemoryBarrier multiSampleImageBarrier = 2290 { 2291 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2292 DE_NULL, // const void* pNext; 2293 0u, // VkAccessFlags srcAccessMask; 2294 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2295 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2296 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2297 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2298 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2299 *resolvedImage, // VkImage image; 2300 { // VkImageSubresourceRange subresourceRange; 2301 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 2302 0u, // deUint32 baseMipLevel; 2303 1u, // deUint32 mipLevels; 2304 0u, // deUint32 baseArrayLayer; 2305 1u, // deUint32 arraySize; 2306 } 2307 }; 2308 2309 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); 2310 } 2311 } 2312 2313 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), m_clearColor); 2314 2315 updatePushConstants(*cmdBuffer, *pipelineLayout); 2316 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline); 2317 if (!m_uniformInfos.empty()) 2318 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL); 2319 2320 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size(); 2321 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0); 2322 2323 std::vector<VkBuffer> buffers(numberOfVertexAttributes); 2324 for (size_t i = 0; i < numberOfVertexAttributes; i++) 2325 { 2326 buffers[i] = m_vertexBuffers[i].get()->get(); 2327 } 2328 2329 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]); 2330 if (numIndices != 0) 2331 { 2332 vk.cmdBindIndexBuffer(*cmdBuffer, *indexBuffer, 0, VK_INDEX_TYPE_UINT16); 2333 vk.cmdDrawIndexed(*cmdBuffer, numIndices, 1, 0, 0, 0); 2334 } 2335 else 2336 vk.cmdDraw(*cmdBuffer, numVertices, 1, 0, 0); 2337 2338 endRenderPass(vk, *cmdBuffer); 2339 endCommandBuffer(vk, *cmdBuffer); 2340 } 2341 2342 // Execute Draw 2343 submitCommandsAndWait(vk, vkDevice, queue, cmdBuffer.get()); 2344 2345 // Read back the result 2346 { 2347 const tcu::TextureFormat resultFormat = mapVkFormat(m_colorFormat); 2348 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(resultFormat.getPixelSize() * m_renderSize.x() * m_renderSize.y()); 2349 const VkBufferCreateInfo readImageBufferParams = 2350 { 2351 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 2352 DE_NULL, // const void* pNext; 2353 0u, // VkBufferCreateFlags flags; 2354 imageSizeBytes, // VkDeviceSize size; 2355 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 2356 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2357 1u, // deUint32 queueFamilyCount; 2358 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 2359 }; 2360 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, vkDevice, &readImageBufferParams)); 2361 const de::UniquePtr<Allocation> readImageBufferMemory (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible)); 2362 2363 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset())); 2364 2365 // Copy image to buffer 2366 const Move<VkCommandBuffer> resultCmdBuffer = allocateCommandBuffer(vk, vkDevice, activeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 2367 2368 beginCommandBuffer(vk, *resultCmdBuffer); 2369 2370 copyImageToBuffer(vk, *resultCmdBuffer, isMultiSampling() ? *resolvedImage : *colorImage, *readImageBuffer, tcu::IVec2(m_renderSize.x(), m_renderSize.y())); 2371 2372 endCommandBuffer(vk, *resultCmdBuffer); 2373 2374 submitCommandsAndWait(vk, vkDevice, queue, resultCmdBuffer.get()); 2375 2376 invalidateAlloc(vk, vkDevice, *readImageBufferMemory); 2377 2378 const tcu::ConstPixelBufferAccess resultAccess (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr()); 2379 2380 m_resultImage.setStorage(resultFormat, m_renderSize.x(), m_renderSize.y()); 2381 tcu::copy(m_resultImage.getAccess(), resultAccess); 2382 } 2383} 2384 2385void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid) 2386{ 2387 DE_ASSERT(m_evaluator); 2388 2389 // Buffer info. 2390 const int width = result.getWidth(); 2391 const int height = result.getHeight(); 2392 const int gridSize = quadGrid.getGridSize(); 2393 const int stride = gridSize + 1; 2394 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check 2395 ShaderEvalContext evalCtx (quadGrid); 2396 2397 // Evaluate color for each vertex. 2398 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1)); 2399 for (int y = 0; y < gridSize+1; y++) 2400 for (int x = 0; x < gridSize+1; x++) 2401 { 2402 const float sx = (float)x / (float)gridSize; 2403 const float sy = (float)y / (float)gridSize; 2404 const int vtxNdx = ((y * (gridSize+1)) + x); 2405 2406 evalCtx.reset(sx, sy); 2407 m_evaluator->evaluate(evalCtx); 2408 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader. 2409 tcu::Vec4 color = evalCtx.color; 2410 2411 if (!hasAlpha) 2412 color.w() = 1.0f; 2413 2414 colors[vtxNdx] = color; 2415 } 2416 2417 // Render quads. 2418 for (int y = 0; y < gridSize; y++) 2419 for (int x = 0; x < gridSize; x++) 2420 { 2421 const float x0 = (float)x / (float)gridSize; 2422 const float x1 = (float)(x + 1) / (float)gridSize; 2423 const float y0 = (float)y / (float)gridSize; 2424 const float y1 = (float)(y + 1) / (float)gridSize; 2425 2426 const float sx0 = x0 * (float)width; 2427 const float sx1 = x1 * (float)width; 2428 const float sy0 = y0 * (float)height; 2429 const float sy1 = y1 * (float)height; 2430 const float oosx = 1.0f / (sx1 - sx0); 2431 const float oosy = 1.0f / (sy1 - sy0); 2432 2433 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f); 2434 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f); 2435 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f); 2436 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f); 2437 2438 const int v00 = (y * stride) + x; 2439 const int v01 = (y * stride) + x + 1; 2440 const int v10 = ((y + 1) * stride) + x; 2441 const int v11 = ((y + 1) * stride) + x + 1; 2442 const tcu::Vec4 c00 = colors[v00]; 2443 const tcu::Vec4 c01 = colors[v01]; 2444 const tcu::Vec4 c10 = colors[v10]; 2445 const tcu::Vec4 c11 = colors[v11]; 2446 2447 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1); 2448 2449 for (int iy = iy0; iy < iy1; iy++) 2450 for (int ix = ix0; ix < ix1; ix++) 2451 { 2452 DE_ASSERT(deInBounds32(ix, 0, width)); 2453 DE_ASSERT(deInBounds32(iy, 0, height)); 2454 2455 const float sfx = (float)ix + 0.5f; 2456 const float sfy = (float)iy + 0.5f; 2457 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f); 2458 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f); 2459 2460 // Triangle quad interpolation. 2461 const bool tri = fx1 + fy1 <= 1.0f; 2462 const float tx = tri ? fx1 : (1.0f-fx1); 2463 const float ty = tri ? fy1 : (1.0f-fy1); 2464 const tcu::Vec4& t0 = tri ? c00 : c11; 2465 const tcu::Vec4& t1 = tri ? c01 : c10; 2466 const tcu::Vec4& t2 = tri ? c10 : c01; 2467 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty; 2468 2469 result.setPixel(ix, iy, tcu::RGBA(color)); 2470 } 2471 } 2472} 2473 2474void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid) 2475{ 2476 DE_ASSERT(m_evaluator); 2477 2478 // Buffer info. 2479 const int width = result.getWidth(); 2480 const int height = result.getHeight(); 2481 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check 2482 ShaderEvalContext evalCtx (quadGrid); 2483 2484 // Render. 2485 for (int y = 0; y < height; y++) 2486 for (int x = 0; x < width; x++) 2487 { 2488 const float sx = ((float)x + 0.5f) / (float)width; 2489 const float sy = ((float)y + 0.5f) / (float)height; 2490 2491 evalCtx.reset(sx, sy); 2492 m_evaluator->evaluate(evalCtx); 2493 // Select either clear color or computed color based on discarded bit. 2494 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color; 2495 2496 if (!hasAlpha) 2497 color.w() = 1.0f; 2498 2499 result.setPixel(x, y, tcu::RGBA(color)); 2500 } 2501} 2502 2503bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold) 2504{ 2505 if (m_fuzzyCompare) 2506 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_EVERYTHING); 2507 else 2508 return tcu::pixelThresholdCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_EVERYTHING); 2509} 2510 2511} // sr 2512} // vkt 2513