vktShaderRender.cpp revision 9931d9632ce1e900213ddd41ebd25a36cc93536e
1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Samsung Electronics Co., Ltd. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and/or associated documentation files (the 10 * "Materials"), to deal in the Materials without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sublicense, and/or sell copies of the Materials, and to 13 * permit persons to whom the Materials are furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice(s) and this permission notice shall be included 17 * in all copies or substantial portions of the Materials. 18 * 19 * The Materials are Confidential Information as defined by the 20 * Khronos Membership Agreement until designated non-confidential by Khronos, 21 * at which point this condition clause shall be removed. 22 * 23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 30 * 31 *//*! 32 * \file 33 * \brief Vulkan ShaderRenderCase 34 *//*--------------------------------------------------------------------*/ 35 36#include "vktShaderRender.hpp" 37 38#include "tcuImageCompare.hpp" 39#include "tcuImageIO.hpp" 40#include "tcuTestLog.hpp" 41#include "tcuTextureUtil.hpp" 42#include "tcuSurface.hpp" 43#include "tcuVector.hpp" 44 45#include "deFilePath.hpp" 46#include "deMath.h" 47#include "deUniquePtr.hpp" 48 49#include "vkDeviceUtil.hpp" 50#include "vkImageUtil.hpp" 51#include "vkPlatform.hpp" 52#include "vkQueryUtil.hpp" 53#include "vkRef.hpp" 54#include "vkRefUtil.hpp" 55#include "vkStrUtil.hpp" 56#include "vkTypeUtil.hpp" 57 58#include <vector> 59#include <string> 60 61namespace vkt 62{ 63namespace sr 64{ 65 66using namespace vk; 67 68namespace 69{ 70 71static const int GRID_SIZE = 2; 72static const deUint32 MAX_RENDER_WIDTH = 128; 73static const deUint32 MAX_RENDER_HEIGHT = 128; 74static const tcu::Vec4 DEFAULT_CLEAR_COLOR = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f); 75 76static bool isSupportedLinearTilingFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format) 77{ 78 VkFormatProperties formatProps; 79 80 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps); 81 82 return (formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u; 83} 84 85static bool isSupportedOptimalTilingFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format) 86{ 87 VkFormatProperties formatProps; 88 89 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps); 90 91 return (formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u; 92} 93 94static VkImageMemoryBarrier createImageMemoryBarrier (const VkImage& image, 95 VkAccessFlags srcAccessMask, 96 VkAccessFlags dstAccessMask, 97 VkImageLayout oldLayout, 98 VkImageLayout newLayout) 99{ 100 VkImageMemoryBarrier imageMemoryBarrier = 101 { 102 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 103 DE_NULL, // const void* pNext; 104 srcAccessMask, // VkAccessFlags srcAccessMask; 105 dstAccessMask, // VkAccessFlags dstAccessMask; 106 oldLayout, // VkImageLayout oldLayout; 107 newLayout, // VkImageLayout newLayout; 108 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 109 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 110 image, // VkImage image; 111 { 112 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 113 0, // deUint32 baseMipLevel; 114 1, // deUint32 mipLevels; 115 0, // deUint32 baseArrayLayer; 116 1 // deUint32 arraySize; 117 } // VkImageSubresourceRange subresourceRange; 118 }; 119 return imageMemoryBarrier; 120} 121 122} // anonymous 123 124// QuadGrid. 125 126class QuadGrid 127{ 128public: 129 QuadGrid (int gridSize, 130 int screenWidth, 131 int screenHeight, 132 const tcu::Vec4& constCoords, 133 const std::vector<tcu::Mat4>& userAttribTransforms, 134 const std::vector<TextureBindingSp>& textures); 135 ~QuadGrid (void); 136 137 int getGridSize (void) const { return m_gridSize; } 138 int getNumVertices (void) const { return m_numVertices; } 139 int getNumTriangles (void) const { return m_numTriangles; } 140 const tcu::Vec4& getConstCoords (void) const { return m_constCoords; } 141 const std::vector<tcu::Mat4> getUserAttribTransforms (void) const { return m_userAttribTransforms; } 142 const std::vector<TextureBindingSp>& getTextures (void) const { return m_textures; } 143 144 const tcu::Vec4* getPositions (void) const { return &m_positions[0]; } 145 const float* getAttribOne (void) const { return &m_attribOne[0]; } 146 const tcu::Vec4* getCoords (void) const { return &m_coords[0]; } 147 const tcu::Vec4* getUnitCoords (void) const { return &m_unitCoords[0]; } 148 149 const tcu::Vec4* getUserAttrib (int attribNdx) const { return &m_userAttribs[attribNdx][0]; } 150 const deUint16* getIndices (void) const { return &m_indices[0]; } 151 152 tcu::Vec4 getCoords (float sx, float sy) const; 153 tcu::Vec4 getUnitCoords (float sx, float sy) const; 154 155 int getNumUserAttribs (void) const { return (int)m_userAttribTransforms.size(); } 156 tcu::Vec4 getUserAttrib (int attribNdx, float sx, float sy) const; 157 158private: 159 const int m_gridSize; 160 const int m_numVertices; 161 const int m_numTriangles; 162 const tcu::Vec4 m_constCoords; 163 const std::vector<tcu::Mat4> m_userAttribTransforms; 164 165 const std::vector<TextureBindingSp>& m_textures; 166 167 std::vector<tcu::Vec4> m_screenPos; 168 std::vector<tcu::Vec4> m_positions; 169 std::vector<tcu::Vec4> m_coords; //!< Near-unit coordinates, roughly [-2.0 .. 2.0]. 170 std::vector<tcu::Vec4> m_unitCoords; //!< Positive-only coordinates [0.0 .. 1.5]. 171 std::vector<float> m_attribOne; 172 std::vector<tcu::Vec4> m_userAttribs[ShaderEvalContext::MAX_TEXTURES]; 173 std::vector<deUint16> m_indices; 174}; 175 176QuadGrid::QuadGrid (int gridSize, 177 int width, 178 int height, 179 const tcu::Vec4& constCoords, 180 const std::vector<tcu::Mat4>& userAttribTransforms, 181 const std::vector<TextureBindingSp>& textures) 182 : m_gridSize (gridSize) 183 , m_numVertices ((gridSize + 1) * (gridSize + 1)) 184 , m_numTriangles (gridSize * gridSize * 2) 185 , m_constCoords (constCoords) 186 , m_userAttribTransforms (userAttribTransforms) 187 , m_textures (textures) 188{ 189 const tcu::Vec4 viewportScale ((float)width, (float)height, 0.0f, 0.0f); 190 191 // Compute vertices. 192 m_screenPos.resize(m_numVertices); 193 m_positions.resize(m_numVertices); 194 m_coords.resize(m_numVertices); 195 m_unitCoords.resize(m_numVertices); 196 m_attribOne.resize(m_numVertices); 197 198 // User attributes. 199 for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++) 200 m_userAttribs[attrNdx].resize(m_numVertices); 201 202 for (int y = 0; y < gridSize+1; y++) 203 for (int x = 0; x < gridSize+1; x++) 204 { 205 float sx = (float)x / (float)gridSize; 206 float sy = (float)y / (float)gridSize; 207 float fx = 2.0f * sx - 1.0f; 208 float fy = 2.0f * sy - 1.0f; 209 int vtxNdx = ((y * (gridSize+1)) + x); 210 211 m_positions[vtxNdx] = tcu::Vec4(fx, fy, 0.0f, 1.0f); 212 m_coords[vtxNdx] = getCoords(sx, sy); 213 m_unitCoords[vtxNdx] = getUnitCoords(sx, sy); 214 m_attribOne[vtxNdx] = 1.0f; 215 216 m_screenPos[vtxNdx] = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale; 217 218 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++) 219 m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy); 220 } 221 222 // Compute indices. 223 m_indices.resize(3 * m_numTriangles); 224 for (int y = 0; y < gridSize; y++) 225 for (int x = 0; x < gridSize; x++) 226 { 227 int stride = gridSize + 1; 228 int v00 = (y * stride) + x; 229 int v01 = (y * stride) + x + 1; 230 int v10 = ((y+1) * stride) + x; 231 int v11 = ((y+1) * stride) + x + 1; 232 233 int baseNdx = ((y * gridSize) + x) * 6; 234 m_indices[baseNdx + 0] = (deUint16)v10; 235 m_indices[baseNdx + 1] = (deUint16)v00; 236 m_indices[baseNdx + 2] = (deUint16)v01; 237 238 m_indices[baseNdx + 3] = (deUint16)v10; 239 m_indices[baseNdx + 4] = (deUint16)v01; 240 m_indices[baseNdx + 5] = (deUint16)v11; 241 } 242} 243 244QuadGrid::~QuadGrid (void) 245{ 246} 247 248inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const 249{ 250 const float fx = 2.0f * sx - 1.0f; 251 const float fy = 2.0f * sy - 1.0f; 252 return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy); 253} 254 255inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const 256{ 257 return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy); 258} 259 260inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const 261{ 262 // homogeneous normalized screen-space coordinates 263 return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f); 264} 265 266// TextureBinding 267 268TextureBinding::TextureBinding (const tcu::Archive& archive, 269 const char* filename, 270 const Type type, 271 const tcu::Sampler& sampler) 272 : m_type (type) 273 , m_sampler (sampler) 274{ 275 switch(m_type) 276 { 277 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break; 278 default: 279 DE_FATAL("Unsupported texture type"); 280 } 281} 282 283TextureBinding::~TextureBinding (void) 284{ 285 switch(m_type) 286 { 287 case TYPE_2D: delete m_binding.tex2D; break; 288 default: break; 289 } 290} 291 292 293de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename) 294{ 295 tcu::TextureLevel level; 296 tcu::ImageIO::loadImage(level, archive, filename); 297 298 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) || 299 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8)); 300 301 // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated 302 de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight())); 303 304 // Fill level 0. 305 texture->allocLevel(0); 306 tcu::copy(texture->getLevel(0), level.getAccess()); 307 308 return texture; 309} 310 311// ShaderEvalContext. 312 313ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid) 314 : constCoords (quadGrid.getConstCoords()) 315 , isDiscarded (false) 316 , m_quadGrid (quadGrid) 317{ 318 const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures(); 319 DE_ASSERT((int)bindings.size() <= MAX_TEXTURES); 320 321 // Fill in texture array. 322 for (int ndx = 0; ndx < (int)bindings.size(); ndx++) 323 { 324 const TextureBinding& binding = *bindings[ndx]; 325 326 if (binding.getType() == TextureBinding::TYPE_NONE) 327 continue; 328 329 textures[ndx].sampler = binding.getSampler(); 330 331 switch (binding.getType()) 332 { 333 case TextureBinding::TYPE_2D: textures[ndx].tex2D = &binding.get2D(); break; 334 // \todo [2015-09-07 elecro] Add support for the other binding types 335 /* 336 case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube = binding.getCube(); break; 337 case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray = binding.get2DArray(); break; 338 case TextureBinding::TYPE_3D: textures[ndx].tex3D = binding.get3D(); break; 339 */ 340 default: 341 TCU_THROW(InternalError, "Handling of texture binding type not implemented"); 342 } 343 } 344} 345 346ShaderEvalContext::~ShaderEvalContext (void) 347{ 348} 349 350void ShaderEvalContext::reset (float sx, float sy) 351{ 352 // Clear old values 353 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 354 isDiscarded = false; 355 356 // Compute coords 357 coords = m_quadGrid.getCoords(sx, sy); 358 unitCoords = m_quadGrid.getUnitCoords(sx, sy); 359 360 // Compute user attributes. 361 const int numAttribs = m_quadGrid.getNumUserAttribs(); 362 DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS); 363 for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++) 364 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy); 365} 366 367tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords) 368{ 369 if (textures[unitNdx].tex2D) 370 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f); 371 else 372 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); 373} 374 375// ShaderEvaluator. 376 377ShaderEvaluator::ShaderEvaluator (void) 378 : m_evalFunc(DE_NULL) 379{ 380} 381 382ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc) 383 : m_evalFunc(evalFunc) 384{ 385} 386 387ShaderEvaluator::~ShaderEvaluator (void) 388{ 389} 390 391void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const 392{ 393 DE_ASSERT(m_evalFunc); 394 m_evalFunc(ctx); 395} 396 397// UniformSetup. 398 399UniformSetup::UniformSetup (void) 400 : m_setupFunc(DE_NULL) 401{ 402} 403 404UniformSetup::UniformSetup (UniformSetupFunc setupFunc) 405 : m_setupFunc(setupFunc) 406{ 407} 408 409UniformSetup::~UniformSetup (void) 410{ 411} 412 413void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const 414{ 415 if (m_setupFunc) 416 m_setupFunc(instance, constCoords); 417} 418 419// ShaderRenderCase. 420 421ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx, 422 const std::string& name, 423 const std::string& description, 424 const bool isVertexCase, 425 const ShaderEvalFunc evalFunc, 426 const UniformSetup* uniformSetup, 427 const AttributeSetupFunc attribFunc) 428 : vkt::TestCase (testCtx, name, description) 429 , m_isVertexCase (isVertexCase) 430 , m_evaluator (new ShaderEvaluator(evalFunc)) 431 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup()) 432 , m_attribFunc (attribFunc) 433{} 434 435ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx, 436 const std::string& name, 437 const std::string& description, 438 const bool isVertexCase, 439 const ShaderEvaluator* evaluator, 440 const UniformSetup* uniformSetup, 441 const AttributeSetupFunc attribFunc) 442 : vkt::TestCase (testCtx, name, description) 443 , m_isVertexCase (isVertexCase) 444 , m_evaluator (evaluator) 445 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup()) 446 , m_attribFunc (attribFunc) 447{} 448 449ShaderRenderCase::~ShaderRenderCase (void) 450{ 451} 452 453void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const 454{ 455 programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource); 456 programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource); 457} 458 459TestInstance* ShaderRenderCase::createInstance (Context& context) const 460{ 461 DE_ASSERT(m_evaluator != DE_NULL); 462 DE_ASSERT(m_uniformSetup != DE_NULL); 463 return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc); 464} 465 466// ShaderRenderCaseInstance. 467 468ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, 469 const bool isVertexCase, 470 const ShaderEvaluator& evaluator, 471 const UniformSetup& uniformSetup, 472 const AttributeSetupFunc attribFunc) 473 : vkt::TestInstance (context) 474 , m_clearColor (DEFAULT_CLEAR_COLOR) 475 , m_memAlloc (context.getDefaultAllocator()) 476 , m_isVertexCase (isVertexCase) 477 , m_evaluator (evaluator) 478 , m_uniformSetup (uniformSetup) 479 , m_attribFunc (attribFunc) 480 , m_renderSize (128, 128) 481 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 482{ 483} 484 485ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void) 486{ 487} 488 489tcu::TestStatus ShaderRenderCaseInstance::iterate (void) 490{ 491 setup(); 492 493 // Create quad grid. 494 const tcu::UVec2 viewportSize = getViewportSize(); 495 const int width = viewportSize.x(); 496 const int height = viewportSize.y(); 497 498 QuadGrid quadGrid (m_isVertexCase ? GRID_SIZE : 4, width, height, tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms, m_textures); 499 500 // Render result. 501 tcu::Surface resImage (width, height); 502 render(resImage, quadGrid); 503 504 // Compute reference. 505 tcu::Surface refImage (width, height); 506 if (m_isVertexCase) 507 computeVertexReference(refImage, quadGrid); 508 else 509 computeFragmentReference(refImage, quadGrid); 510 511 // Compare. 512 const bool compareOk = compareImages(resImage, refImage, 0.05f); 513 514 if (compareOk) 515 return tcu::TestStatus::pass("Result image matches reference"); 516 else 517 return tcu::TestStatus::fail("Image mismatch"); 518} 519 520void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr) 521{ 522 const VkDevice vkDevice = m_context.getDevice(); 523 const DeviceInterface& vk = m_context.getDeviceInterface(); 524 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 525 526 const VkBufferCreateInfo uniformBufferParams = 527 { 528 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 529 DE_NULL, // const void* pNext; 530 0u, // VkBufferCreateFlags flags; 531 size, // VkDeviceSize size; 532 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage; 533 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 534 1u, // deUint32 queueFamilyCount; 535 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 536 }; 537 538 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams); 539 de::MovePtr<Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 540 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset())); 541 542 deMemcpy(alloc->getHostPtr(), dataPtr, size); 543 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size); 544 545 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform()); 546 uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 547 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size); 548 uniformInfo->location = bindingLocation; 549 uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer)); 550 uniformInfo->alloc = AllocationSp(alloc.release()); 551 552 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo))); 553} 554 555void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, size_t dataSize, const void* data) 556{ 557 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_ALL); 558 m_descriptorPoolBuilder.addType(descriptorType); 559 560 setupUniformData(bindingLocation, dataSize, data); 561} 562 563void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation, 564 vk::VkFormat format, 565 deUint32 sizePerElement, 566 deUint32 count, 567 const void* dataPtr) 568{ 569 // Add binding specification 570 const deUint32 binding = (deUint32)m_vertexBindingDescription.size(); 571 const VkVertexInputBindingDescription bindingDescription = 572 { 573 binding, // deUint32 binding; 574 sizePerElement, // deUint32 stride; 575 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate stepRate; 576 }; 577 578 m_vertexBindingDescription.push_back(bindingDescription); 579 580 // Add location and format specification 581 const VkVertexInputAttributeDescription attributeDescription = 582 { 583 bindingLocation, // deUint32 location; 584 binding, // deUint32 binding; 585 format, // VkFormat format; 586 0u, // deUint32 offset; 587 }; 588 589 m_vertexattributeDescription.push_back(attributeDescription); 590 591 // Upload data to buffer 592 const VkDevice vkDevice = m_context.getDevice(); 593 const DeviceInterface& vk = m_context.getDeviceInterface(); 594 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 595 596 const VkDeviceSize inputSize = sizePerElement * count; 597 const VkBufferCreateInfo vertexBufferParams = 598 { 599 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 600 DE_NULL, // const void* pNext; 601 0u, // VkBufferCreateFlags flags; 602 inputSize, // VkDeviceSize size; 603 VK_BUFFER_USAGE_VERTEX_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, &vertexBufferParams); 610 de::MovePtr<vk::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_t)inputSize); 614 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize); 615 616 m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer))); 617 m_vertexBufferAllocs.push_back(AllocationSp(alloc.release())); 618} 619 620void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type) 621{ 622 const EnabledBaseAttribute attribute = 623 { 624 bindingLocation, // deUint32 location; 625 type // BaseAttributeType type; 626 }; 627 m_enabledBaseAttributes.push_back(attribute); 628} 629 630void ShaderRenderCaseInstance::setup (void) 631{ 632} 633 634void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords) 635{ 636 m_uniformSetup.setup(*this, constCoords); 637} 638 639void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type) 640{ 641 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break 642 643 switch(type) 644 { 645 // Bool 646 UNIFORM_CASE(UB_FALSE, 0); 647 UNIFORM_CASE(UB_TRUE, 1); 648 649 // BVec4 650 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0)); 651 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1)); 652 653 // Integer 654 UNIFORM_CASE(UI_ZERO, 0); 655 UNIFORM_CASE(UI_ONE, 1); 656 UNIFORM_CASE(UI_TWO, 2); 657 UNIFORM_CASE(UI_THREE, 3); 658 UNIFORM_CASE(UI_FOUR, 4); 659 UNIFORM_CASE(UI_FIVE, 5); 660 UNIFORM_CASE(UI_SIX, 6); 661 UNIFORM_CASE(UI_SEVEN, 7); 662 UNIFORM_CASE(UI_EIGHT, 8); 663 UNIFORM_CASE(UI_ONEHUNDREDONE, 101); 664 665 // IVec2 666 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1)); 667 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0)); 668 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1)); 669 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2)); 670 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3)); 671 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4)); 672 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5)); 673 674 // IVec3 675 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1)); 676 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0)); 677 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1)); 678 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2)); 679 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3)); 680 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4)); 681 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5)); 682 683 // IVec4 684 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1)); 685 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0)); 686 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1)); 687 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2)); 688 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3)); 689 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4)); 690 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5)); 691 692 // Float 693 UNIFORM_CASE(UF_ZERO, 0.0f); 694 UNIFORM_CASE(UF_ONE, 1.0f); 695 UNIFORM_CASE(UF_TWO, 2.0f); 696 UNIFORM_CASE(UF_THREE, 3.0f); 697 UNIFORM_CASE(UF_FOUR, 4.0f); 698 UNIFORM_CASE(UF_FIVE, 5.0f); 699 UNIFORM_CASE(UF_SIX, 6.0f); 700 UNIFORM_CASE(UF_SEVEN, 7.0f); 701 UNIFORM_CASE(UF_EIGHT, 8.0f); 702 703 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f); 704 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f); 705 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f); 706 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f); 707 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f); 708 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f); 709 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f); 710 711 // Vec2 712 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f)); 713 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f)); 714 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f)); 715 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f)); 716 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f)); 717 718 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f)); 719 720 // Vec3 721 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f)); 722 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f)); 723 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f)); 724 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f)); 725 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f)); 726 727 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f)); 728 729 // Vec4 730 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f)); 731 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f)); 732 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f)); 733 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f)); 734 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f)); 735 736 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f)); 737 738 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 739 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f)); 740 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 741 742 default: 743 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage; 744 break; 745 } 746 747 #undef UNIFORM_CASE 748} 749 750const tcu::UVec2 ShaderRenderCaseInstance::getViewportSize (void) const 751{ 752 return tcu::UVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH), 753 de::min(m_renderSize.y(), MAX_RENDER_HEIGHT)); 754} 755 756Move<VkImage> ShaderRenderCaseInstance::createImage2D (const tcu::Texture2D& texture, 757 const VkFormat format, 758 const VkImageUsageFlags usage, 759 const VkImageTiling tiling) 760{ 761 const VkDevice vkDevice = m_context.getDevice(); 762 const DeviceInterface& vk = m_context.getDeviceInterface(); 763 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 764 765 const VkImageCreateInfo imageCreateInfo = 766 { 767 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 768 DE_NULL, // const void* pNext; 769 0, // VkImageCreateFlags flags; 770 VK_IMAGE_TYPE_2D, // VkImageType imageType; 771 format, // VkFormat format; 772 { 773 (deUint32)texture.getWidth(), 774 (deUint32)texture.getHeight(), 775 1u 776 }, // VkExtend3D extent; 777 1u, // deUint32 mipLevels; 778 1u, // deUint32 arraySize; 779 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 780 tiling, // VkImageTiling tiling; 781 usage, // VkImageUsageFlags usage; 782 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 783 1, // deuint32 queueFamilyCount; 784 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 785 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 786 }; 787 788 Move<VkImage> vkTexture = createImage(vk, vkDevice, &imageCreateInfo); 789 return vkTexture; 790} 791 792de::MovePtr<Allocation> ShaderRenderCaseInstance::uploadImage2D (const tcu::Texture2D& refTexture, 793 const VkImage& vkTexture) 794{ 795 const VkDevice vkDevice = m_context.getDevice(); 796 const DeviceInterface& vk = m_context.getDeviceInterface(); 797 798 de::MovePtr<Allocation> allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible); 799 VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset())); 800 801 const VkImageSubresource subres = 802 { 803 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 804 0u, // deUint32 mipLevel; 805 0u // deUint32 arraySlice 806 }; 807 808 VkSubresourceLayout layout; 809 vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout); 810 811 tcu::ConstPixelBufferAccess access = refTexture.getLevel(0); 812 tcu::PixelBufferAccess destAccess (refTexture.getFormat(), refTexture.getWidth(), refTexture.getHeight(), 1, allocation->getHostPtr()); 813 814 tcu::copy(destAccess, access); 815 816 flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation->getOffset(), layout.size); 817 818 return allocation; 819} 820 821void ShaderRenderCaseInstance::copyTilingImageToOptimal (const vk::VkImage& srcImage, 822 const vk::VkImage& dstImage, 823 deUint32 width, 824 deUint32 height) 825{ 826 const VkDevice vkDevice = m_context.getDevice(); 827 const DeviceInterface& vk = m_context.getDeviceInterface(); 828 const VkQueue queue = m_context.getUniversalQueue(); 829 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 830 831 // Create command pool 832 const VkCommandPoolCreateInfo cmdPoolParams = 833 { 834 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 835 DE_NULL, // const void* pNext; 836 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 837 queueFamilyIndex, // deUint32 queueFamilyIndex; 838 }; 839 840 Move<VkCommandPool> cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 841 842 // Create command buffer 843 const VkCommandBufferAllocateInfo cmdBufferParams = 844 { 845 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 846 DE_NULL, // const void* pNext; 847 *cmdPool, // VkCommandPool commandPool; 848 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 849 1u // deUint32 bufferCount; 850 }; 851 852 const VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 853 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 854 { 855 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 856 DE_NULL, // const void* pNext; 857 usageFlags, // VkCommandBufferUsageFlags flags; 858 (const VkCommandBufferInheritanceInfo*)DE_NULL, 859 }; 860 861 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 862 863 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 864 865 // Add image barriers 866 const VkImageMemoryBarrier layoutBarriers[2] = 867 { 868 createImageMemoryBarrier(srcImage, (VkAccessFlags)0u, (VkAccessFlags)0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL), 869 createImageMemoryBarrier(dstImage, (VkAccessFlags)0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) 870 }; 871 872 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 873 0, (const VkMemoryBarrier*)DE_NULL, 874 0, (const VkBufferMemoryBarrier*)DE_NULL, 875 DE_LENGTH_OF_ARRAY(layoutBarriers), layoutBarriers); 876 877 // Add image copy 878 const VkImageCopy imageCopy = 879 { 880 { 881 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 882 0u, // deUint32 mipLevel; 883 0u, // deUint32 arrayLayer; 884 1u // deUint32 arraySize; 885 }, // VkImageSubresourceCopy srcSubresource; 886 { 887 0, // int32 x; 888 0, // int32 y; 889 0 // int32 z; 890 }, // VkOffset3D srcOffset; 891 { 892 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 893 0u, // deUint32 mipLevel; 894 0u, // deUint32 arrayLayer; 895 1u // deUint32 arraySize; 896 }, // VkImageSubresourceCopy destSubResource; 897 { 898 0, // int32 x; 899 0, // int32 y; 900 0 // int32 z; 901 }, // VkOffset3D dstOffset; 902 { 903 width, // int32 width; 904 height, // int32 height; 905 1, // int32 depth 906 } // VkExtent3D extent; 907 }; 908 909 vk.cmdCopyImage(*cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopy); 910 911 // Add destination barrier 912 const VkImageMemoryBarrier dstBarrier = 913 createImageMemoryBarrier(dstImage, VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, 0u, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 914 915 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 916 0, (const VkMemoryBarrier*)DE_NULL, 917 0, (const VkBufferMemoryBarrier*)DE_NULL, 918 1, &dstBarrier); 919 920 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 921 922 const VkFenceCreateInfo fenceParams = 923 { 924 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 925 DE_NULL, // const void* pNext; 926 0u // VkFenceCreateFlags flags; 927 }; 928 const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceParams)); 929 const VkSubmitInfo submitInfo = 930 { 931 VK_STRUCTURE_TYPE_SUBMIT_INFO, 932 DE_NULL, 933 0u, 934 (const VkSemaphore*)DE_NULL, 935 (const VkPipelineStageFlags*)DE_NULL, 936 1u, 937 &cmdBuffer.get(), 938 0u, 939 (const VkSemaphore*)DE_NULL, 940 }; 941 942 943 // Execute copy 944 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); 945 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 946 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/)); 947} 948 949void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID) 950{ 951 DE_ASSERT(textureID < m_textures.size()); 952 953 const VkDevice vkDevice = m_context.getDevice(); 954 const DeviceInterface& vk = m_context.getDeviceInterface(); 955 const TextureBinding& textureBinding = *m_textures[textureID]; 956 const tcu::Texture2D& refTexture = textureBinding.get2D(); 957 const tcu::Sampler& refSampler = textureBinding.getSampler(); 958 const VkFormat format = refTexture.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) 959 ? VK_FORMAT_R8G8B8A8_UNORM 960 : VK_FORMAT_R8G8B8_UNORM; 961 962 // Create & alloc the image 963 Move<VkImage> vkTexture; 964 de::MovePtr<Allocation> allocation; 965 966 if (isSupportedLinearTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format)) 967 { 968 vkTexture = createImage2D(refTexture, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR); 969 allocation = uploadImage2D(refTexture, *vkTexture); 970 } 971 else if (isSupportedOptimalTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format)) 972 { 973 Move<VkImage> stagingTexture (createImage2D(refTexture, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR)); 974 de::MovePtr<Allocation> stagingAlloc (uploadImage2D(refTexture, *stagingTexture)); 975 976 const VkImageUsageFlags dstUsageFlags = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; 977 vkTexture = createImage2D(refTexture, format, dstUsageFlags, VK_IMAGE_TILING_OPTIMAL); 978 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any); 979 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset())); 980 981 copyTilingImageToOptimal(*stagingTexture, *vkTexture, refTexture.getWidth(), refTexture.getHeight()); 982 } 983 else 984 { 985 TCU_THROW(InternalError, "Unable to create 2D image"); 986 } 987 988 // Create sampler 989 const VkSamplerCreateInfo samplerParams = mapSampler(refSampler, refTexture.getFormat()); 990 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams); 991 992 const VkImageViewCreateInfo viewParams = 993 { 994 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 995 NULL, // const voide* pNext; 996 0u, // VkImageViewCreateFlags flags; 997 *vkTexture, // VkImage image; 998 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 999 format, // VkFormat format; 1000 { 1001 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r; 1002 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g; 1003 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b; 1004 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a; 1005 }, // VkChannelMapping channels; 1006 { 1007 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1008 0, // deUint32 baseMipLevel; 1009 1, // deUint32 mipLevels; 1010 0, // deUint32 baseArraySlice; 1011 1 // deUint32 arraySize; 1012 }, // VkImageSubresourceRange subresourceRange; 1013 }; 1014 1015 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams); 1016 1017 const vk::VkDescriptorImageInfo descriptor = 1018 { 1019 sampler.get(), // VkSampler sampler; 1020 imageView.get(), // VkImageView imageView; 1021 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout; 1022 }; 1023 1024 de::MovePtr<SamplerUniform> uniform(new SamplerUniform()); 1025 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 1026 uniform->descriptor = descriptor; 1027 uniform->location = bindingLocation; 1028 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture)); 1029 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView)); 1030 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler)); 1031 uniform->alloc = AllocationSp(allocation.release()); 1032 1033 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, &uniform->descriptor.sampler); 1034 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 1035 1036 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform))); 1037} 1038 1039void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid) 1040{ 1041 /* Configuration of the vertex input attributes: 1042 a_position is at location 0 1043 a_coords is at location 1 1044 a_unitCoords is at location 2 1045 a_one is at location 3 1046 1047 User attributes starts from at the location 4. 1048 */ 1049 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions()); 1050 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords()); 1051 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords()); 1052 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne()); 1053 1054 static const struct 1055 { 1056 BaseAttributeType type; 1057 int userNdx; 1058 } userAttributes[] = 1059 { 1060 { A_IN0, 0 }, 1061 { A_IN1, 1 }, 1062 { A_IN2, 2 }, 1063 { A_IN3, 3 } 1064 }; 1065 1066 static const struct 1067 { 1068 BaseAttributeType matrixType; 1069 int numCols; 1070 int numRows; 1071 } matrices[] = 1072 { 1073 { MAT2, 2, 2 }, 1074 { MAT2x3, 2, 3 }, 1075 { MAT2x4, 2, 4 }, 1076 { MAT3x2, 3, 2 }, 1077 { MAT3, 3, 3 }, 1078 { MAT3x4, 3, 4 }, 1079 { MAT4x2, 4, 2 }, 1080 { MAT4x3, 4, 3 }, 1081 { MAT4, 4, 4 } 1082 }; 1083 1084 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++) 1085 { 1086 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++) 1087 { 1088 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type) 1089 continue; 1090 1091 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx)); 1092 } 1093 1094 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++) 1095 { 1096 1097 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type) 1098 continue; 1099 1100 const int numCols = matrices[matNdx].numCols; 1101 1102 for (int colNdx = 0; colNdx < numCols; colNdx++) 1103 { 1104 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx)); 1105 } 1106 } 1107 } 1108} 1109 1110void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid) 1111{ 1112 const VkDevice vkDevice = m_context.getDevice(); 1113 const DeviceInterface& vk = m_context.getDeviceInterface(); 1114 const VkQueue queue = m_context.getUniversalQueue(); 1115 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1116 1117 // Create color image 1118 { 1119 const VkImageCreateInfo colorImageParams = 1120 { 1121 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1122 DE_NULL, // const void* pNext; 1123 0u, // VkImageCreateFlags flags; 1124 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1125 m_colorFormat, // VkFormat format; 1126 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 1127 1u, // deUint32 mipLevels; 1128 1u, // deUint32 arraySize; 1129 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 1130 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1131 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 1132 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1133 1u, // deUint32 queueFamilyCount; 1134 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1135 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1136 }; 1137 1138 m_colorImage = createImage(vk, vkDevice, &colorImageParams); 1139 1140 // Allocate and bind color image memory 1141 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 1142 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 1143 } 1144 1145 // Create color attachment view 1146 { 1147 const VkImageViewCreateInfo colorImageViewParams = 1148 { 1149 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1150 DE_NULL, // const void* pNext; 1151 0u, // VkImageViewCreateFlags flags; 1152 *m_colorImage, // VkImage image; 1153 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1154 m_colorFormat, // VkFormat format; 1155 { 1156 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r; 1157 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g; 1158 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b; 1159 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a; 1160 }, // VkChannelMapping channels; 1161 { 1162 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1163 0, // deUint32 baseMipLevel; 1164 1, // deUint32 mipLevels; 1165 0, // deUint32 baseArraySlice; 1166 1 // deUint32 arraySize; 1167 }, // VkImageSubresourceRange subresourceRange; 1168 }; 1169 1170 m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams); 1171 } 1172 1173 // Create render pass 1174 { 1175 const VkAttachmentDescription attachmentDescription = 1176 { 1177 (VkAttachmentDescriptionFlags)0, 1178 m_colorFormat, // VkFormat format; 1179 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 1180 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 1181 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1182 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1183 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1184 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 1185 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 1186 }; 1187 1188 const VkAttachmentReference attachmentReference = 1189 { 1190 0u, // deUint32 attachment; 1191 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 1192 }; 1193 1194 const VkSubpassDescription subpassDescription = 1195 { 1196 0u, // VkSubpassDescriptionFlags flags; 1197 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 1198 0u, // deUint32 inputCount; 1199 DE_NULL, // constVkAttachmentReference* pInputAttachments; 1200 1u, // deUint32 colorCount; 1201 &attachmentReference, // constVkAttachmentReference* pColorAttachments; 1202 DE_NULL, // constVkAttachmentReference* pResolveAttachments; 1203 DE_NULL, // VkAttachmentReference depthStencilAttachment; 1204 0u, // deUint32 preserveCount; 1205 DE_NULL // constVkAttachmentReference* pPreserveAttachments; 1206 }; 1207 1208 const VkRenderPassCreateInfo renderPassParams = 1209 { 1210 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 1211 DE_NULL, // const void* pNext; 1212 (VkRenderPassCreateFlags)0, 1213 1u, // deUint32 attachmentCount; 1214 &attachmentDescription, // const VkAttachmentDescription* pAttachments; 1215 1u, // deUint32 subpassCount; 1216 &subpassDescription, // const VkSubpassDescription* pSubpasses; 1217 0u, // deUint32 dependencyCount; 1218 DE_NULL // const VkSubpassDependency* pDependencies; 1219 }; 1220 1221 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 1222 } 1223 1224 // Create framebuffer 1225 { 1226 const VkFramebufferCreateInfo framebufferParams = 1227 { 1228 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 1229 DE_NULL, // const void* pNext; 1230 (VkFramebufferCreateFlags)0, 1231 *m_renderPass, // VkRenderPass renderPass; 1232 1u, // deUint32 attachmentCount; 1233 &*m_colorImageView, // const VkImageView* pAttachments; 1234 (deUint32)m_renderSize.x(), // deUint32 width; 1235 (deUint32)m_renderSize.y(), // deUint32 height; 1236 1u // deUint32 layers; 1237 }; 1238 1239 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 1240 } 1241 1242 // Create descriptors 1243 { 1244 setupUniforms(quadGrid.getConstCoords()); 1245 1246 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice); 1247 if (!m_uniformInfos.empty()) 1248 { 1249 m_descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1250 const VkDescriptorSetAllocateInfo allocInfo = 1251 { 1252 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 1253 DE_NULL, 1254 *m_descriptorPool, 1255 1u, 1256 &m_descriptorSetLayout.get(), 1257 }; 1258 1259 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo); 1260 } 1261 1262 for (deUint32 i = 0; i < m_uniformInfos.size(); i++) 1263 { 1264 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get(); 1265 deUint32 location = uniformInfo->location; 1266 1267 if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) 1268 { 1269 const BufferUniform* bufferInfo = dynamic_cast<const BufferUniform*>(uniformInfo); 1270 1271 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor); 1272 } 1273 else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 1274 { 1275 const SamplerUniform* samplerInfo = dynamic_cast<const SamplerUniform*>(uniformInfo); 1276 1277 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor); 1278 } 1279 else 1280 DE_FATAL("Impossible"); 1281 } 1282 1283 m_descriptorSetUpdateBuilder.update(vk, vkDevice); 1284 } 1285 1286 // Create pipeline layout 1287 { 1288 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 1289 { 1290 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 1291 DE_NULL, // const void* pNext; 1292 (VkPipelineLayoutCreateFlags)0, 1293 1u, // deUint32 descriptorSetCount; 1294 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 1295 0u, // deUint32 pushConstantRangeCount; 1296 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 1297 }; 1298 1299 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 1300 } 1301 1302 // Create shaders 1303 { 1304 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0); 1305 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0); 1306 } 1307 1308 // Create pipeline 1309 { 1310 const VkPipelineShaderStageCreateInfo shaderStageParams[2] = 1311 { 1312 { 1313 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1314 DE_NULL, // const void* pNext; 1315 (VkPipelineShaderStageCreateFlags)0, 1316 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStage stage; 1317 *m_vertexShaderModule, // VkShader shader; 1318 "main", 1319 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1320 }, 1321 { 1322 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1323 DE_NULL, // const void* pNext; 1324 (VkPipelineShaderStageCreateFlags)0, 1325 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStage stage; 1326 *m_fragmentShaderModule, // VkShader shader; 1327 "main", 1328 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1329 } 1330 }; 1331 1332 // Add test case specific attributes 1333 if (m_attribFunc) 1334 m_attribFunc(*this, quadGrid.getNumVertices()); 1335 1336 // Add base attributes 1337 setupDefaultInputs(quadGrid); 1338 1339 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 1340 { 1341 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1342 DE_NULL, // const void* pNext; 1343 (VkPipelineVertexInputStateCreateFlags)0, 1344 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount; 1345 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1346 (deUint32)m_vertexattributeDescription.size(), // deUint32 attributeCount; 1347 &m_vertexattributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 1348 }; 1349 1350 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 1351 { 1352 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 1353 DE_NULL, // const void* pNext; 1354 (VkPipelineInputAssemblyStateCreateFlags)0, 1355 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; 1356 false // VkBool32 primitiveRestartEnable; 1357 }; 1358 1359 const VkViewport viewport = 1360 { 1361 0.0f, // float originX; 1362 0.0f, // float originY; 1363 (float)m_renderSize.x(), // float width; 1364 (float)m_renderSize.y(), // float height; 1365 0.0f, // float minDepth; 1366 1.0f // float maxDepth; 1367 }; 1368 1369 const VkRect2D scissor = 1370 { 1371 { 1372 0u, // deUint32 x; 1373 0u, // deUint32 y; 1374 }, // VkOffset2D offset; 1375 { 1376 m_renderSize.x(), // deUint32 width; 1377 m_renderSize.y(), // deUint32 height; 1378 }, // VkExtent2D extent; 1379 }; 1380 1381 const VkPipelineViewportStateCreateInfo viewportStateParams = 1382 { 1383 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 1384 DE_NULL, // const void* pNext; 1385 (VkPipelineViewportStateCreateFlags)0, 1386 1u, // deUint32 viewportCount; 1387 &viewport, // const VkViewport* pViewports; 1388 1u, // deUint32 scissorsCount; 1389 &scissor, // const VkRect2D* pScissors; 1390 }; 1391 1392 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 1393 { 1394 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 1395 DE_NULL, // const void* pNext; 1396 (VkPipelineRasterizationStateCreateFlags)0, 1397 false, // VkBool32 depthClipEnable; 1398 false, // VkBool32 rasterizerDiscardEnable; 1399 VK_POLYGON_MODE_FILL, // VkFillMode fillMode; 1400 VK_CULL_MODE_NONE, // VkCullMode cullMode; 1401 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 1402 false, // VkBool32 depthBiasEnable; 1403 0.0f, // float depthBias; 1404 0.0f, // float depthBiasClamp; 1405 0.0f, // float slopeScaledDepthBias; 1406 1.0f, // float lineWidth; 1407 }; 1408 1409 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1410 { 1411 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1412 DE_NULL, // const void* pNext; 1413 0u, // VkPipelineMultisampleStateCreateFlags flags; 1414 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 1415 VK_FALSE, // VkBool32 sampleShadingEnable; 1416 0.0f, // float minSampleShading; 1417 DE_NULL, // const VkSampleMask* pSampleMask; 1418 VK_FALSE, // VkBool32 alphaToCoverageEnable; 1419 VK_FALSE // VkBool32 alphaToOneEnable; 1420 }; 1421 1422 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 1423 { 1424 false, // VkBool32 blendEnable; 1425 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor; 1426 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor; 1427 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; 1428 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha; 1429 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha; 1430 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; 1431 (VK_COLOR_COMPONENT_R_BIT | 1432 VK_COLOR_COMPONENT_G_BIT | 1433 VK_COLOR_COMPONENT_B_BIT | 1434 VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask; 1435 }; 1436 1437 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 1438 { 1439 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 1440 DE_NULL, // const void* pNext; 1441 (VkPipelineColorBlendStateCreateFlags)0, 1442 false, // VkBool32 logicOpEnable; 1443 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 1444 1u, // deUint32 attachmentCount; 1445 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 1446 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4]; 1447 }; 1448 1449 const VkPipelineDynamicStateCreateInfo dynamicStateInfo = 1450 { 1451 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; 1452 DE_NULL, // const void* pNext; 1453 (VkPipelineDynamicStateCreateFlags)0, 1454 0u, // deUint32 dynamicStateCount; 1455 DE_NULL // const VkDynamicState* pDynamicStates; 1456 }; 1457 1458 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 1459 { 1460 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 1461 DE_NULL, // const void* pNext; 1462 0u, // VkPipelineCreateFlags flags; 1463 2u, // deUint32 stageCount; 1464 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 1465 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 1466 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 1467 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 1468 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 1469 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState; 1470 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 1471 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 1472 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 1473 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 1474 *m_pipelineLayout, // VkPipelineLayout layout; 1475 *m_renderPass, // VkRenderPass renderPass; 1476 0u, // deUint32 subpass; 1477 0u, // VkPipeline basePipelineHandle; 1478 0u // deInt32 basePipelineIndex; 1479 }; 1480 1481 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 1482 } 1483 1484 // Create vertex indices buffer 1485 { 1486 const VkDeviceSize indiceBufferSize = quadGrid.getNumTriangles() * 3 * sizeof(deUint16); 1487 const VkBufferCreateInfo indiceBufferParams = 1488 { 1489 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1490 DE_NULL, // const void* pNext; 1491 0u, // VkBufferCreateFlags flags; 1492 indiceBufferSize, // VkDeviceSize size; 1493 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage; 1494 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1495 1u, // deUint32 queueFamilyCount; 1496 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1497 }; 1498 1499 m_indiceBuffer = createBuffer(vk, vkDevice, &indiceBufferParams); 1500 m_indiceBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible); 1501 1502 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset())); 1503 1504 // Load vertice indices into buffer 1505 deMemcpy(m_indiceBufferAlloc->getHostPtr(), quadGrid.getIndices(), (size_t)indiceBufferSize); 1506 flushMappedMemoryRange(vk, vkDevice, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset(), indiceBufferSize); 1507 } 1508 1509 // Create command pool 1510 { 1511 const VkCommandPoolCreateInfo cmdPoolParams = 1512 { 1513 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1514 DE_NULL, // const void* pNext; 1515 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 1516 queueFamilyIndex, // deUint32 queueFamilyIndex; 1517 }; 1518 1519 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1520 } 1521 1522 // Create command buffer 1523 { 1524 const VkCommandBufferAllocateInfo cmdBufferParams = 1525 { 1526 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1527 DE_NULL, // const void* pNext; 1528 *m_cmdPool, // VkCmdPool cmdPool; 1529 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 1530 1u // deUint32 bufferCount; 1531 }; 1532 1533 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1534 { 1535 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1536 DE_NULL, // const void* pNext; 1537 0u, // VkCmdBufferOptimizeFlags flags; 1538 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1539 }; 1540 1541 const VkClearValue clearValues = makeClearValueColorF32(m_clearColor.x(), 1542 m_clearColor.y(), 1543 m_clearColor.z(), 1544 m_clearColor.w()); 1545 1546 const VkRenderPassBeginInfo renderPassBeginInfo = 1547 { 1548 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1549 DE_NULL, // const void* pNext; 1550 *m_renderPass, // VkRenderPass renderPass; 1551 *m_framebuffer, // VkFramebuffer framebuffer; 1552 { { 0, 0 }, {m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea; 1553 1, // deUint32 clearValueCount; 1554 &clearValues, // const VkClearValue* pClearValues; 1555 }; 1556 1557 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 1558 1559 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1560 1561 // Add texture barriers 1562 std::vector<VkImageMemoryBarrier> barriers; 1563 1564 for(deUint32 i = 0; i < m_uniformInfos.size(); i++) 1565 { 1566 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get(); 1567 1568 if (uniformInfo->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 1569 { 1570 continue; 1571 } 1572 1573 const SamplerUniform* sampler = static_cast<const SamplerUniform*>(uniformInfo); 1574 1575 const VkAccessFlags outputMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; 1576 const VkImageMemoryBarrier textureBarrier = createImageMemoryBarrier(sampler->image->get(), outputMask, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 1577 1578 barriers.push_back(textureBarrier); 1579 } 1580 1581 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 1582 0, (const VkMemoryBarrier*)DE_NULL, 1583 0, (const VkBufferMemoryBarrier*)DE_NULL, 1584 (deUint32)barriers.size(), (barriers.empty() ? (const VkImageMemoryBarrier*)DE_NULL : &barriers[0])); 1585 1586 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1587 1588 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline); 1589 if (!m_uniformInfos.empty()) 1590 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL); 1591 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16); 1592 1593 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size(); 1594 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0); 1595 1596 std::vector<VkBuffer> buffers(numberOfVertexAttributes); 1597 for (size_t i = 0; i < numberOfVertexAttributes; i++) 1598 { 1599 buffers[i] = m_vertexBuffers[i].get()->get(); 1600 } 1601 1602 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]); 1603 vk.cmdDrawIndexed(*m_cmdBuffer, quadGrid.getNumTriangles() * 3, 1, 0, 0, 0); 1604 1605 vk.cmdEndRenderPass(*m_cmdBuffer); 1606 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1607 } 1608 1609 // Create fence 1610 { 1611 const VkFenceCreateInfo fenceParams = 1612 { 1613 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 1614 DE_NULL, // const void* pNext; 1615 0u // VkFenceCreateFlags flags; 1616 }; 1617 m_fence = createFence(vk, vkDevice, &fenceParams); 1618 } 1619 1620 // Execute Draw 1621 { 1622 const VkSubmitInfo submitInfo = 1623 { 1624 VK_STRUCTURE_TYPE_SUBMIT_INFO, 1625 DE_NULL, 1626 0u, 1627 (const VkSemaphore*)DE_NULL, 1628 (const VkPipelineStageFlags*)DE_NULL, 1629 1u, 1630 &m_cmdBuffer.get(), 1631 0u, 1632 (const VkSemaphore*)DE_NULL, 1633 }; 1634 1635 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 1636 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 1637 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/)); 1638 } 1639 1640 // Read back the result 1641 { 1642 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y()); 1643 const VkBufferCreateInfo readImageBufferParams = 1644 { 1645 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1646 DE_NULL, // const void* pNext; 1647 0u, // VkBufferCreateFlags flags; 1648 imageSizeBytes, // VkDeviceSize size; 1649 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 1650 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1651 1u, // deUint32 queueFamilyCount; 1652 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1653 }; 1654 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, vkDevice, &readImageBufferParams)); 1655 const de::UniquePtr<Allocation> readImageBufferMemory (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible)); 1656 1657 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset())); 1658 1659 // Copy image to buffer 1660 const VkCommandBufferAllocateInfo cmdBufferParams = 1661 { 1662 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1663 DE_NULL, // const void* pNext; 1664 *m_cmdPool, // VkCmdPool cmdPool; 1665 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 1666 1u // deUint32 bufferCount; 1667 }; 1668 1669 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1670 { 1671 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1672 DE_NULL, // const void* pNext; 1673 0u, // VkCmdBufferOptimizeFlags flags; 1674 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1675 }; 1676 1677 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 1678 1679 const VkBufferImageCopy copyParams = 1680 { 1681 0u, // VkDeviceSize bufferOffset; 1682 (deUint32)m_renderSize.x(), // deUint32 bufferRowLength; 1683 (deUint32)m_renderSize.y(), // deUint32 bufferImageHeight; 1684 { 1685 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 1686 0u, // deUint32 mipLevel; 1687 0u, // deUint32 arraySlice; 1688 1u, // deUint32 arraySize; 1689 }, // VkImageSubresourceCopy imageSubresource; 1690 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 1691 { m_renderSize.x(), m_renderSize.y(), 1u } // VkExtent3D imageExtent; 1692 }; 1693 const VkSubmitInfo submitInfo = 1694 { 1695 VK_STRUCTURE_TYPE_SUBMIT_INFO, 1696 DE_NULL, 1697 0u, 1698 (const VkSemaphore*)DE_NULL, 1699 (const VkPipelineStageFlags*)DE_NULL, 1700 1u, 1701 &cmdBuffer.get(), 1702 0u, 1703 (const VkSemaphore*)DE_NULL, 1704 }; 1705 1706 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 1707 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params); 1708 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1709 1710 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 1711 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 1712 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); 1713 1714 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes); 1715 1716 const tcu::TextureFormat resultFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 1717 const tcu::ConstPixelBufferAccess resultAccess (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr()); 1718 1719 tcu::copy(result.getAccess(), resultAccess); 1720 } 1721} 1722 1723void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid) 1724{ 1725 // Buffer info. 1726 const int width = result.getWidth(); 1727 const int height = result.getHeight(); 1728 const int gridSize = quadGrid.getGridSize(); 1729 const int stride = gridSize + 1; 1730 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check 1731 ShaderEvalContext evalCtx (quadGrid); 1732 1733 // Evaluate color for each vertex. 1734 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1)); 1735 for (int y = 0; y < gridSize+1; y++) 1736 for (int x = 0; x < gridSize+1; x++) 1737 { 1738 const float sx = (float)x / (float)gridSize; 1739 const float sy = (float)y / (float)gridSize; 1740 const int vtxNdx = ((y * (gridSize+1)) + x); 1741 1742 evalCtx.reset(sx, sy); 1743 m_evaluator.evaluate(evalCtx); 1744 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader. 1745 tcu::Vec4 color = evalCtx.color; 1746 1747 if (!hasAlpha) 1748 color.w() = 1.0f; 1749 1750 colors[vtxNdx] = color; 1751 } 1752 1753 // Render quads. 1754 for (int y = 0; y < gridSize; y++) 1755 for (int x = 0; x < gridSize; x++) 1756 { 1757 const float x0 = (float)x / (float)gridSize; 1758 const float x1 = (float)(x + 1) / (float)gridSize; 1759 const float y0 = (float)y / (float)gridSize; 1760 const float y1 = (float)(y + 1) / (float)gridSize; 1761 1762 const float sx0 = x0 * (float)width; 1763 const float sx1 = x1 * (float)width; 1764 const float sy0 = y0 * (float)height; 1765 const float sy1 = y1 * (float)height; 1766 const float oosx = 1.0f / (sx1 - sx0); 1767 const float oosy = 1.0f / (sy1 - sy0); 1768 1769 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f); 1770 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f); 1771 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f); 1772 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f); 1773 1774 const int v00 = (y * stride) + x; 1775 const int v01 = (y * stride) + x + 1; 1776 const int v10 = ((y + 1) * stride) + x; 1777 const int v11 = ((y + 1) * stride) + x + 1; 1778 const tcu::Vec4 c00 = colors[v00]; 1779 const tcu::Vec4 c01 = colors[v01]; 1780 const tcu::Vec4 c10 = colors[v10]; 1781 const tcu::Vec4 c11 = colors[v11]; 1782 1783 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1); 1784 1785 for (int iy = iy0; iy < iy1; iy++) 1786 for (int ix = ix0; ix < ix1; ix++) 1787 { 1788 DE_ASSERT(deInBounds32(ix, 0, width)); 1789 DE_ASSERT(deInBounds32(iy, 0, height)); 1790 1791 const float sfx = (float)ix + 0.5f; 1792 const float sfy = (float)iy + 0.5f; 1793 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f); 1794 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f); 1795 1796 // Triangle quad interpolation. 1797 const bool tri = fx1 + fy1 <= 1.0f; 1798 const float tx = tri ? fx1 : (1.0f-fx1); 1799 const float ty = tri ? fy1 : (1.0f-fy1); 1800 const tcu::Vec4& t0 = tri ? c00 : c11; 1801 const tcu::Vec4& t1 = tri ? c01 : c10; 1802 const tcu::Vec4& t2 = tri ? c10 : c01; 1803 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty; 1804 1805 result.setPixel(ix, iy, tcu::RGBA(color)); 1806 } 1807 } 1808} 1809 1810void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid) 1811{ 1812 // Buffer info. 1813 const int width = result.getWidth(); 1814 const int height = result.getHeight(); 1815 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check 1816 ShaderEvalContext evalCtx (quadGrid); 1817 1818 // Render. 1819 for (int y = 0; y < height; y++) 1820 for (int x = 0; x < width; x++) 1821 { 1822 const float sx = ((float)x + 0.5f) / (float)width; 1823 const float sy = ((float)y + 0.5f) / (float)height; 1824 1825 evalCtx.reset(sx, sy); 1826 m_evaluator.evaluate(evalCtx); 1827 // Select either clear color or computed color based on discarded bit. 1828 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color; 1829 1830 if (!hasAlpha) 1831 color.w() = 1.0f; 1832 1833 result.setPixel(x, y, tcu::RGBA(color)); 1834 } 1835} 1836 1837bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold) 1838{ 1839 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT); 1840} 1841 1842} // sr 1843} // vkt 1844