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