vktShaderRender.cpp revision e148980e7f95d8a113a7dc84b13ca9906f33869f
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 s_gridSize = 2; 72static const int s_maxRenderWidth = 128; 73static const int s_maxRenderHeight = 128; 74static const tcu::Vec4 s_defaultClearColor = 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 (s_defaultClearColor) 475 , m_memAlloc (context.getDefaultAllocator()) 476 , m_isVertexCase (isVertexCase) 477 , m_evaluator (evaluator) 478 , m_uniformSetup (uniformSetup) 479 , m_attribFunc (attribFunc) 480 , m_renderSize (100, 100) 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::IVec2 viewportSize = getViewportSize(); 495 const int width = viewportSize.x(); 496 const int height = viewportSize.y(); 497 498 QuadGrid quadGrid (m_isVertexCase ? s_gridSize : 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::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const 751{ 752 return tcu::IVec2(de::min(m_renderSize.x(), s_maxRenderWidth), 753 de::min(m_renderSize.y(), s_maxRenderHeight)); 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 { texture.getWidth(), texture.getHeight(), 1 }, // VkExtend3D extent; 773 1u, // deUint32 mipLevels; 774 1u, // deUint32 arraySize; 775 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 776 tiling, // VkImageTiling tiling; 777 usage, // VkImageUsageFlags usage; 778 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 779 1, // deuint32 queueFamilyCount; 780 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 781 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 782 }; 783 784 Move<VkImage> vkTexture = createImage(vk, vkDevice, &imageCreateInfo); 785 return vkTexture; 786} 787 788de::MovePtr<Allocation> ShaderRenderCaseInstance::uploadImage2D (const tcu::Texture2D& refTexture, 789 const VkImage& vkTexture) 790{ 791 const VkDevice vkDevice = m_context.getDevice(); 792 const DeviceInterface& vk = m_context.getDeviceInterface(); 793 794 de::MovePtr<Allocation> allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible); 795 VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset())); 796 797 const VkImageSubresource subres = 798 { 799 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 800 0u, // deUint32 mipLevel; 801 0u // deUint32 arraySlice 802 }; 803 804 VkSubresourceLayout layout; 805 vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout); 806 807 tcu::ConstPixelBufferAccess access = refTexture.getLevel(0); 808 tcu::PixelBufferAccess destAccess (refTexture.getFormat(), refTexture.getWidth(), refTexture.getHeight(), 1, allocation->getHostPtr()); 809 810 tcu::copy(destAccess, access); 811 812 flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation, layout.size); 813 814 return allocation; 815} 816 817void ShaderRenderCaseInstance::copyTilingImageToOptimal (const vk::VkImage& srcImage, 818 const vk::VkImage& dstImage, 819 deInt32 width, 820 deInt32 height) 821{ 822 const VkDevice vkDevice = m_context.getDevice(); 823 const DeviceInterface& vk = m_context.getDeviceInterface(); 824 const VkQueue queue = m_context.getUniversalQueue(); 825 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 826 827 // Create command pool 828 const VkCommandPoolCreateInfo cmdPoolParams = 829 { 830 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 831 DE_NULL, // const void* pNext; 832 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 833 queueFamilyIndex, // deUint32 queueFamilyIndex; 834 }; 835 836 Move<VkCommandPool> cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 837 838 // Create command buffer 839 const VkCommandBufferAllocateInfo cmdBufferParams = 840 { 841 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 842 DE_NULL, // const void* pNext; 843 *cmdPool, // VkCommandPool commandPool; 844 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 845 1u // deUint32 bufferCount; 846 }; 847 848 const VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 849 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 850 { 851 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 852 DE_NULL, // const void* pNext; 853 usageFlags, // VkCommandBufferUsageFlags flags; 854 DE_NULL, // VkRenderPass renderPass; 855 0u, // deUint32 subpass; 856 DE_NULL, // VkFramebuffer framebuffer; 857 VK_FALSE, // VkBool32 occlusionQueryEnable; 858 (VkQueryControlFlags)0, 859 (VkQueryPipelineStatisticFlags)0, 860 }; 861 862 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 863 864 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 865 866 // Add image barriers 867 const VkImageMemoryBarrier layoutBarriers[2] = 868 { 869 createImageMemoryBarrier(srcImage, (VkAccessFlags)0u, (VkAccessFlags)0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL), 870 createImageMemoryBarrier(dstImage, (VkAccessFlags)0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) 871 }; 872 873 for (deUint32 barrierNdx = 0; barrierNdx < DE_LENGTH_OF_ARRAY(layoutBarriers); barrierNdx++) 874 { 875 const VkImageMemoryBarrier* memoryBarrier = &layoutBarriers[barrierNdx]; 876 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void * const*)&memoryBarrier); 877 } 878 879 // Add image copy 880 const VkImageCopy imageCopy = 881 { 882 { 883 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 884 0u, // deUint32 mipLevel; 885 0u, // deUint32 arrayLayer; 886 1u // deUint32 arraySize; 887 }, // VkImageSubresourceCopy srcSubresource; 888 { 889 0, // int32 x; 890 0, // int32 y; 891 0 // int32 z; 892 }, // VkOffset3D srcOffset; 893 { 894 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 895 0u, // deUint32 mipLevel; 896 0u, // deUint32 arrayLayer; 897 1u // deUint32 arraySize; 898 }, // VkImageSubresourceCopy destSubResource; 899 { 900 0, // int32 x; 901 0, // int32 y; 902 0 // int32 z; 903 }, // VkOffset3D dstOffset; 904 { 905 width, // int32 width; 906 height, // int32 height; 907 1, // int32 depth 908 } // VkExtent3D extent; 909 }; 910 911 vk.cmdCopyImage(*cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopy); 912 913 // Add destination barrier 914 const VkImageMemoryBarrier dstBarrier = 915 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); 916 917 const void* const* barrier = (const void* const*)&dstBarrier; 918 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void* const*)&barrier); 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 1u, 936 &cmdBuffer.get(), 937 0u, 938 (const VkSemaphore*)DE_NULL, 939 }; 940 941 942 // Execute copy 943 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); 944 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 945 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/)); 946} 947 948void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID) 949{ 950 DE_ASSERT(textureID < m_textures.size()); 951 952 const VkDevice vkDevice = m_context.getDevice(); 953 const DeviceInterface& vk = m_context.getDeviceInterface(); 954 const TextureBinding& textureBinding = *m_textures[textureID]; 955 const tcu::Texture2D& refTexture = textureBinding.get2D(); 956 const tcu::Sampler& refSampler = textureBinding.getSampler(); 957 const VkFormat format = refTexture.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) 958 ? VK_FORMAT_R8G8B8A8_UNORM 959 : VK_FORMAT_R8G8B8_UNORM; 960 961 // Create & alloc the image 962 Move<VkImage> vkTexture; 963 de::MovePtr<Allocation> allocation; 964 965 if (isSupportedLinearTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format)) 966 { 967 vkTexture = createImage2D(refTexture, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR); 968 allocation = uploadImage2D(refTexture, *vkTexture); 969 } 970 else if (isSupportedOptimalTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format)) 971 { 972 Move<VkImage> stagingTexture (createImage2D(refTexture, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR)); 973 de::MovePtr<Allocation> stagingAlloc (uploadImage2D(refTexture, *stagingTexture)); 974 975 const VkImageUsageFlags dstUsageFlags = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; 976 vkTexture = createImage2D(refTexture, format, dstUsageFlags, VK_IMAGE_TILING_OPTIMAL); 977 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any); 978 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset())); 979 980 copyTilingImageToOptimal(*stagingTexture, *vkTexture, refTexture.getWidth(), refTexture.getHeight()); 981 } 982 else 983 { 984 TCU_THROW(InternalError, "Unable to create 2D image"); 985 } 986 987 // Create sampler 988 const bool compareEnabled = (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE); 989 const VkSamplerCreateInfo samplerParams = 990 { 991 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType; 992 DE_NULL, // const void* pNext; 993 (VkSamplerCreateFlags)0, 994 mapFilterMode(refSampler.magFilter), // VkTexFilter magFilter; 995 mapFilterMode(refSampler.minFilter), // VkTexFilter minFilter; 996 mapMipmapMode(refSampler.minFilter), // VkTexMipmapMode mipMode; 997 mapWrapMode(refSampler.wrapS), // VkTexAddressMode addressModeU; 998 mapWrapMode(refSampler.wrapT), // VkTexAddressMode addressModeV; 999 mapWrapMode(refSampler.wrapR), // VkTexAddressMode addressModeW; 1000 refSampler.lodThreshold, // float mipLodBias; 1001 1, // float maxAnisotropy; 1002 compareEnabled, // VkBool32 compareEnable; 1003 mapCompareMode(refSampler.compare), // VkCompareOp compareOp; 1004 0.0f, // float minLod; 1005 0.0f, // float maxLod; 1006 VK_BORDER_COLOR_INT_OPAQUE_WHITE, // VkBorderColor boderColor; 1007 VK_FALSE, // VkBool32 unnormalizerdCoordinates; 1008 }; 1009 1010 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams); 1011 1012 const VkImageViewCreateInfo viewParams = 1013 { 1014 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1015 NULL, // const voide* pNext; 1016 0u, // VkImageViewCreateFlags flags; 1017 *vkTexture, // VkImage image; 1018 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1019 format, // VkFormat format; 1020 { 1021 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r; 1022 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g; 1023 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b; 1024 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a; 1025 }, // VkChannelMapping channels; 1026 { 1027 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1028 0, // deUint32 baseMipLevel; 1029 1, // deUint32 mipLevels; 1030 0, // deUint32 baseArraySlice; 1031 1 // deUint32 arraySize; 1032 }, // VkImageSubresourceRange subresourceRange; 1033 }; 1034 1035 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams); 1036 1037 const vk::VkDescriptorImageInfo descriptor = 1038 { 1039 sampler.get(), // VkSampler sampler; 1040 imageView.get(), // VkImageView imageView; 1041 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout; 1042 }; 1043 1044 de::MovePtr<SamplerUniform> uniform(new SamplerUniform()); 1045 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 1046 uniform->descriptor = descriptor; 1047 uniform->location = bindingLocation; 1048 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture)); 1049 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView)); 1050 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler)); 1051 uniform->alloc = AllocationSp(allocation.release()); 1052 1053 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, &uniform->descriptor.sampler); 1054 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 1055 1056 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform))); 1057} 1058 1059void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid) 1060{ 1061 /* Configuration of the vertex input attributes: 1062 a_position is at location 0 1063 a_coords is at location 1 1064 a_unitCoords is at location 2 1065 a_one is at location 3 1066 1067 User attributes starts from at the location 4. 1068 */ 1069 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions()); 1070 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords()); 1071 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords()); 1072 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne()); 1073 1074 static const struct 1075 { 1076 BaseAttributeType type; 1077 int userNdx; 1078 } userAttributes[] = 1079 { 1080 { A_IN0, 0 }, 1081 { A_IN1, 1 }, 1082 { A_IN2, 2 }, 1083 { A_IN3, 3 } 1084 }; 1085 1086 static const struct 1087 { 1088 BaseAttributeType matrixType; 1089 int numCols; 1090 int numRows; 1091 } matrices[] = 1092 { 1093 { MAT2, 2, 2 }, 1094 { MAT2x3, 2, 3 }, 1095 { MAT2x4, 2, 4 }, 1096 { MAT3x2, 3, 2 }, 1097 { MAT3, 3, 3 }, 1098 { MAT3x4, 3, 4 }, 1099 { MAT4x2, 4, 2 }, 1100 { MAT4x3, 4, 3 }, 1101 { MAT4, 4, 4 } 1102 }; 1103 1104 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++) 1105 { 1106 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++) 1107 { 1108 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type) 1109 continue; 1110 1111 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx)); 1112 } 1113 1114 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++) 1115 { 1116 1117 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type) 1118 continue; 1119 1120 const int numCols = matrices[matNdx].numCols; 1121 1122 for (int colNdx = 0; colNdx < numCols; colNdx++) 1123 { 1124 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx)); 1125 } 1126 } 1127 } 1128} 1129 1130void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid) 1131{ 1132 const VkDevice vkDevice = m_context.getDevice(); 1133 const DeviceInterface& vk = m_context.getDeviceInterface(); 1134 const VkQueue queue = m_context.getUniversalQueue(); 1135 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1136 1137 // Create color image 1138 { 1139 const VkImageCreateInfo colorImageParams = 1140 { 1141 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1142 DE_NULL, // const void* pNext; 1143 0u, // VkImageCreateFlags flags; 1144 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1145 m_colorFormat, // VkFormat format; 1146 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 1147 1u, // deUint32 mipLevels; 1148 1u, // deUint32 arraySize; 1149 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 1150 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1151 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 1152 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1153 1u, // deUint32 queueFamilyCount; 1154 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1155 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1156 }; 1157 1158 m_colorImage = createImage(vk, vkDevice, &colorImageParams); 1159 1160 // Allocate and bind color image memory 1161 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 1162 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 1163 } 1164 1165 // Create color attachment view 1166 { 1167 const VkImageViewCreateInfo colorImageViewParams = 1168 { 1169 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1170 DE_NULL, // const void* pNext; 1171 0u, // VkImageViewCreateFlags flags; 1172 *m_colorImage, // VkImage image; 1173 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1174 m_colorFormat, // VkFormat format; 1175 { 1176 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r; 1177 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g; 1178 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b; 1179 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a; 1180 }, // VkChannelMapping channels; 1181 { 1182 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1183 0, // deUint32 baseMipLevel; 1184 1, // deUint32 mipLevels; 1185 0, // deUint32 baseArraySlice; 1186 1 // deUint32 arraySize; 1187 }, // VkImageSubresourceRange subresourceRange; 1188 }; 1189 1190 m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams); 1191 } 1192 1193 // Create render pass 1194 { 1195 const VkAttachmentDescription attachmentDescription = 1196 { 1197 (VkAttachmentDescriptionFlags)0, 1198 m_colorFormat, // VkFormat format; 1199 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 1200 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 1201 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1202 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1203 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1204 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 1205 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 1206 }; 1207 1208 const VkAttachmentReference attachmentReference = 1209 { 1210 0u, // deUint32 attachment; 1211 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 1212 }; 1213 1214 const VkSubpassDescription subpassDescription = 1215 { 1216 0u, // VkSubpassDescriptionFlags flags; 1217 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 1218 0u, // deUint32 inputCount; 1219 DE_NULL, // constVkAttachmentReference* pInputAttachments; 1220 1u, // deUint32 colorCount; 1221 &attachmentReference, // constVkAttachmentReference* pColorAttachments; 1222 DE_NULL, // constVkAttachmentReference* pResolveAttachments; 1223 DE_NULL, // VkAttachmentReference depthStencilAttachment; 1224 0u, // deUint32 preserveCount; 1225 DE_NULL // constVkAttachmentReference* pPreserveAttachments; 1226 }; 1227 1228 const VkRenderPassCreateInfo renderPassParams = 1229 { 1230 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 1231 DE_NULL, // const void* pNext; 1232 (VkRenderPassCreateFlags)0, 1233 1u, // deUint32 attachmentCount; 1234 &attachmentDescription, // const VkAttachmentDescription* pAttachments; 1235 1u, // deUint32 subpassCount; 1236 &subpassDescription, // const VkSubpassDescription* pSubpasses; 1237 0u, // deUint32 dependencyCount; 1238 DE_NULL // const VkSubpassDependency* pDependencies; 1239 }; 1240 1241 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 1242 } 1243 1244 // Create framebuffer 1245 { 1246 const VkFramebufferCreateInfo framebufferParams = 1247 { 1248 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 1249 DE_NULL, // const void* pNext; 1250 (VkFramebufferCreateFlags)0, 1251 *m_renderPass, // VkRenderPass renderPass; 1252 1u, // deUint32 attachmentCount; 1253 &*m_colorImageView, // const VkImageView* pAttachments; 1254 (deUint32)m_renderSize.x(), // deUint32 width; 1255 (deUint32)m_renderSize.y(), // deUint32 height; 1256 1u // deUint32 layers; 1257 }; 1258 1259 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 1260 } 1261 1262 // Create descriptors 1263 { 1264 setupUniforms(quadGrid.getConstCoords()); 1265 1266 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice); 1267 m_descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1268 1269 { 1270 const VkDescriptorSetAllocateInfo allocInfo = 1271 { 1272 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 1273 DE_NULL, 1274 *m_descriptorPool, 1275 1u, 1276 &m_descriptorSetLayout.get(), 1277 }; 1278 1279 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo); 1280 } 1281 1282 for (deUint32 i = 0; i < m_uniformInfos.size(); i++) 1283 { 1284 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get(); 1285 deUint32 location = uniformInfo->location; 1286 1287 if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) 1288 { 1289 const BufferUniform* bufferInfo = dynamic_cast<const BufferUniform*>(uniformInfo); 1290 1291 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor); 1292 } 1293 else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 1294 { 1295 const SamplerUniform* samplerInfo = dynamic_cast<const SamplerUniform*>(uniformInfo); 1296 1297 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor); 1298 } 1299 else 1300 DE_FATAL("Impossible"); 1301 } 1302 1303 m_descriptorSetUpdateBuilder.update(vk, vkDevice); 1304 } 1305 1306 // Create pipeline layout 1307 { 1308 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 1309 { 1310 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 1311 DE_NULL, // const void* pNext; 1312 (VkPipelineLayoutCreateFlags)0, 1313 1u, // deUint32 descriptorSetCount; 1314 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 1315 0u, // deUint32 pushConstantRangeCount; 1316 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 1317 }; 1318 1319 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 1320 } 1321 1322 // Create shaders 1323 { 1324 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0); 1325 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0); 1326 } 1327 1328 // Create pipeline 1329 { 1330 const VkPipelineShaderStageCreateInfo shaderStageParams[2] = 1331 { 1332 { 1333 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1334 DE_NULL, // const void* pNext; 1335 (VkPipelineShaderStageCreateFlags)0, 1336 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStage stage; 1337 *m_vertexShaderModule, // VkShader shader; 1338 "main", 1339 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1340 }, 1341 { 1342 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1343 DE_NULL, // const void* pNext; 1344 (VkPipelineShaderStageCreateFlags)0, 1345 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStage stage; 1346 *m_fragmentShaderModule, // VkShader shader; 1347 "main", 1348 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1349 } 1350 }; 1351 1352 // Add test case specific attributes 1353 if (m_attribFunc) 1354 m_attribFunc(*this, quadGrid.getNumVertices()); 1355 1356 // Add base attributes 1357 setupDefaultInputs(quadGrid); 1358 1359 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 1360 { 1361 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1362 DE_NULL, // const void* pNext; 1363 (VkPipelineVertexInputStateCreateFlags)0, 1364 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount; 1365 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1366 (deUint32)m_vertexattributeDescription.size(), // deUint32 attributeCount; 1367 &m_vertexattributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 1368 }; 1369 1370 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 1371 { 1372 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 1373 DE_NULL, // const void* pNext; 1374 (VkPipelineInputAssemblyStateCreateFlags)0, 1375 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; 1376 false // VkBool32 primitiveRestartEnable; 1377 }; 1378 1379 const VkViewport viewport = 1380 { 1381 0.0f, // float originX; 1382 0.0f, // float originY; 1383 (float)m_renderSize.x(), // float width; 1384 (float)m_renderSize.y(), // float height; 1385 0.0f, // float minDepth; 1386 1.0f // float maxDepth; 1387 }; 1388 1389 const VkRect2D scissor = 1390 { 1391 { 1392 0u, // deUint32 x; 1393 0u, // deUint32 y; 1394 }, // VkOffset2D offset; 1395 { 1396 m_renderSize.x(), // deUint32 width; 1397 m_renderSize.y(), // deUint32 height; 1398 }, // VkExtent2D extent; 1399 }; 1400 1401 const VkPipelineViewportStateCreateInfo viewportStateParams = 1402 { 1403 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 1404 DE_NULL, // const void* pNext; 1405 (VkPipelineViewportStateCreateFlags)0, 1406 1u, // deUint32 viewportCount; 1407 &viewport, // const VkViewport* pViewports; 1408 1u, // deUint32 scissorsCount; 1409 &scissor, // const VkRect2D* pScissors; 1410 }; 1411 1412 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 1413 { 1414 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 1415 DE_NULL, // const void* pNext; 1416 (VkPipelineRasterizationStateCreateFlags)0, 1417 false, // VkBool32 depthClipEnable; 1418 false, // VkBool32 rasterizerDiscardEnable; 1419 VK_POLYGON_MODE_FILL, // VkFillMode fillMode; 1420 VK_CULL_MODE_NONE, // VkCullMode cullMode; 1421 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 1422 false, // VkBool32 depthBiasEnable; 1423 0.0f, // float depthBias; 1424 0.0f, // float depthBiasClamp; 1425 0.0f, // float slopeScaledDepthBias; 1426 1.0f, // float lineWidth; 1427 }; 1428 1429 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1430 { 1431 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1432 DE_NULL, // const void* pNext; 1433 0u, // VkPipelineMultisampleStateCreateFlags flags; 1434 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 1435 VK_FALSE, // VkBool32 sampleShadingEnable; 1436 0.0f, // float minSampleShading; 1437 DE_NULL, // const VkSampleMask* pSampleMask; 1438 VK_FALSE, // VkBool32 alphaToCoverageEnable; 1439 VK_FALSE // VkBool32 alphaToOneEnable; 1440 }; 1441 1442 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 1443 { 1444 false, // VkBool32 blendEnable; 1445 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor; 1446 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor; 1447 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; 1448 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha; 1449 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha; 1450 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; 1451 (VK_COLOR_COMPONENT_R_BIT | 1452 VK_COLOR_COMPONENT_G_BIT | 1453 VK_COLOR_COMPONENT_B_BIT | 1454 VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask; 1455 }; 1456 1457 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 1458 { 1459 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 1460 DE_NULL, // const void* pNext; 1461 (VkPipelineColorBlendStateCreateFlags)0, 1462 false, // VkBool32 logicOpEnable; 1463 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 1464 1u, // deUint32 attachmentCount; 1465 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 1466 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4]; 1467 }; 1468 1469 const VkPipelineDynamicStateCreateInfo dynamicStateInfo = 1470 { 1471 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; 1472 DE_NULL, // const void* pNext; 1473 (VkPipelineDynamicStateCreateFlags)0, 1474 0u, // deUint32 dynamicStateCount; 1475 DE_NULL // const VkDynamicState* pDynamicStates; 1476 }; 1477 1478 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 1479 { 1480 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 1481 DE_NULL, // const void* pNext; 1482 0u, // VkPipelineCreateFlags flags; 1483 2u, // deUint32 stageCount; 1484 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 1485 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 1486 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 1487 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 1488 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 1489 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState; 1490 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 1491 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 1492 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 1493 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 1494 *m_pipelineLayout, // VkPipelineLayout layout; 1495 *m_renderPass, // VkRenderPass renderPass; 1496 0u, // deUint32 subpass; 1497 0u, // VkPipeline basePipelineHandle; 1498 0u // deInt32 basePipelineIndex; 1499 }; 1500 1501 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 1502 } 1503 1504 // Create vertex indices buffer 1505 { 1506 const VkDeviceSize indiceBufferSize = quadGrid.getNumTriangles() * 3 * sizeof(deUint16); 1507 const VkBufferCreateInfo indiceBufferParams = 1508 { 1509 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1510 DE_NULL, // const void* pNext; 1511 0u, // VkBufferCreateFlags flags; 1512 indiceBufferSize, // VkDeviceSize size; 1513 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage; 1514 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1515 1u, // deUint32 queueFamilyCount; 1516 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1517 }; 1518 1519 m_indiceBuffer = createBuffer(vk, vkDevice, &indiceBufferParams); 1520 m_indiceBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible); 1521 1522 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset())); 1523 1524 // Load vertice indices into buffer 1525 deMemcpy(m_indiceBufferAlloc->getHostPtr(), quadGrid.getIndices(), (size_t)indiceBufferSize); 1526 flushMappedMemoryRange(vk, vkDevice, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset(), indiceBufferSize); 1527 } 1528 1529 // Create command pool 1530 { 1531 const VkCommandPoolCreateInfo cmdPoolParams = 1532 { 1533 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1534 DE_NULL, // const void* pNext; 1535 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 1536 queueFamilyIndex, // deUint32 queueFamilyIndex; 1537 }; 1538 1539 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1540 } 1541 1542 // Create command buffer 1543 { 1544 const VkCommandBufferAllocateInfo cmdBufferParams = 1545 { 1546 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1547 DE_NULL, // const void* pNext; 1548 *m_cmdPool, // VkCmdPool cmdPool; 1549 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 1550 1u // deUint32 bufferCount; 1551 }; 1552 1553 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1554 { 1555 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1556 DE_NULL, // const void* pNext; 1557 0u, // VkCmdBufferOptimizeFlags flags; 1558 DE_NULL, // VkRenderPass renderPass; 1559 0u, // deUint32 subpass; 1560 DE_NULL, // VkFramebuffer framebuffer; 1561 VK_FALSE, 1562 (VkQueryControlFlags)0, 1563 (VkQueryPipelineStatisticFlags)0, 1564 }; 1565 1566 const VkClearValue clearValues = makeClearValueColorF32(m_clearColor.x(), 1567 m_clearColor.y(), 1568 m_clearColor.z(), 1569 m_clearColor.w()); 1570 1571 const VkRenderPassBeginInfo renderPassBeginInfo = 1572 { 1573 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1574 DE_NULL, // const void* pNext; 1575 *m_renderPass, // VkRenderPass renderPass; 1576 *m_framebuffer, // VkFramebuffer framebuffer; 1577 { { 0, 0 }, {m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea; 1578 1, // deUint32 clearValueCount; 1579 &clearValues, // const VkClearValue* pClearValues; 1580 }; 1581 1582 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 1583 1584 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1585 1586 // Add texture barriers 1587 std::vector<VkImageMemoryBarrier> barriers; 1588 std::vector<void*> barrierPtrs; 1589 1590 for(deUint32 i = 0; i < m_uniformInfos.size(); i++) 1591 { 1592 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get(); 1593 1594 if (uniformInfo->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 1595 { 1596 continue; 1597 } 1598 1599 const SamplerUniform* sampler = static_cast<const SamplerUniform*>(uniformInfo); 1600 1601 const VkAccessFlags outputMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; 1602 const VkImageMemoryBarrier textureBarrier = createImageMemoryBarrier(sampler->image->get(), outputMask, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 1603 1604 barriers.push_back(textureBarrier); 1605 barrierPtrs.push_back((void*)&barriers.back()); 1606 } 1607 1608 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, (deUint32)barrierPtrs.size(), (barrierPtrs.size() ? (const void * const*)&barrierPtrs[0] : DE_NULL)); 1609 1610 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1611 1612 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline); 1613 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL); 1614 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16); 1615 1616 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size(); 1617 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0); 1618 1619 std::vector<VkBuffer> buffers(numberOfVertexAttributes); 1620 for (size_t i = 0; i < numberOfVertexAttributes; i++) 1621 { 1622 buffers[i] = m_vertexBuffers[i].get()->get(); 1623 } 1624 1625 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]); 1626 vk.cmdDrawIndexed(*m_cmdBuffer, quadGrid.getNumTriangles() * 3, 1, 0, 0, 0); 1627 1628 vk.cmdEndRenderPass(*m_cmdBuffer); 1629 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1630 } 1631 1632 // Create fence 1633 { 1634 const VkFenceCreateInfo fenceParams = 1635 { 1636 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 1637 DE_NULL, // const void* pNext; 1638 0u // VkFenceCreateFlags flags; 1639 }; 1640 m_fence = createFence(vk, vkDevice, &fenceParams); 1641 } 1642 1643 // Execute Draw 1644 { 1645 const VkSubmitInfo submitInfo = 1646 { 1647 VK_STRUCTURE_TYPE_SUBMIT_INFO, 1648 DE_NULL, 1649 0u, 1650 (const VkSemaphore*)DE_NULL, 1651 1u, 1652 &m_cmdBuffer.get(), 1653 0u, 1654 (const VkSemaphore*)DE_NULL, 1655 }; 1656 1657 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 1658 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 1659 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/)); 1660 } 1661 1662 // Read back the result 1663 { 1664 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y()); 1665 const VkBufferCreateInfo readImageBufferParams = 1666 { 1667 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1668 DE_NULL, // const void* pNext; 1669 0u, // VkBufferCreateFlags flags; 1670 imageSizeBytes, // VkDeviceSize size; 1671 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 1672 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1673 1u, // deUint32 queueFamilyCount; 1674 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1675 }; 1676 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, vkDevice, &readImageBufferParams)); 1677 const de::UniquePtr<Allocation> readImageBufferMemory (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible)); 1678 1679 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset())); 1680 1681 // Copy image to buffer 1682 const VkCommandBufferAllocateInfo cmdBufferParams = 1683 { 1684 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1685 DE_NULL, // const void* pNext; 1686 *m_cmdPool, // VkCmdPool cmdPool; 1687 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 1688 1u // deUint32 bufferCount; 1689 }; 1690 1691 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1692 { 1693 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1694 DE_NULL, // const void* pNext; 1695 0u, // VkCmdBufferOptimizeFlags flags; 1696 DE_NULL, // VkRenderPass renderPass; 1697 0u, // deUint32 subpass; 1698 DE_NULL, // VkFramebuffer framebuffer; 1699 VK_FALSE, 1700 (VkQueryControlFlags)0, 1701 (VkQueryPipelineStatisticFlags)0, 1702 }; 1703 1704 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 1705 1706 const VkBufferImageCopy copyParams = 1707 { 1708 0u, // VkDeviceSize bufferOffset; 1709 (deUint32)m_renderSize.x(), // deUint32 bufferRowLength; 1710 (deUint32)m_renderSize.y(), // deUint32 bufferImageHeight; 1711 { 1712 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 1713 0u, // deUint32 mipLevel; 1714 0u, // deUint32 arraySlice; 1715 1u, // deUint32 arraySize; 1716 }, // VkImageSubresourceCopy imageSubresource; 1717 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 1718 { m_renderSize.x(), m_renderSize.y(), 1u } // VkExtent3D imageExtent; 1719 }; 1720 const VkSubmitInfo submitInfo = 1721 { 1722 VK_STRUCTURE_TYPE_SUBMIT_INFO, 1723 DE_NULL, 1724 0u, 1725 (const VkSemaphore*)DE_NULL, 1726 1u, 1727 &cmdBuffer.get(), 1728 0u, 1729 (const VkSemaphore*)DE_NULL, 1730 }; 1731 1732 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 1733 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params); 1734 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1735 1736 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 1737 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 1738 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); 1739 1740 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes); 1741 1742 const tcu::TextureFormat resultFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 1743 const tcu::ConstPixelBufferAccess resultAccess (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr()); 1744 1745 tcu::copy(result.getAccess(), resultAccess); 1746 } 1747} 1748 1749void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid) 1750{ 1751 // Buffer info. 1752 const int width = result.getWidth(); 1753 const int height = result.getHeight(); 1754 const int gridSize = quadGrid.getGridSize(); 1755 const int stride = gridSize + 1; 1756 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check 1757 ShaderEvalContext evalCtx (quadGrid); 1758 1759 // Evaluate color for each vertex. 1760 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1)); 1761 for (int y = 0; y < gridSize+1; y++) 1762 for (int x = 0; x < gridSize+1; x++) 1763 { 1764 const float sx = (float)x / (float)gridSize; 1765 const float sy = (float)y / (float)gridSize; 1766 const int vtxNdx = ((y * (gridSize+1)) + x); 1767 1768 evalCtx.reset(sx, sy); 1769 m_evaluator.evaluate(evalCtx); 1770 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader. 1771 tcu::Vec4 color = evalCtx.color; 1772 1773 if (!hasAlpha) 1774 color.w() = 1.0f; 1775 1776 colors[vtxNdx] = color; 1777 } 1778 1779 // Render quads. 1780 for (int y = 0; y < gridSize; y++) 1781 for (int x = 0; x < gridSize; x++) 1782 { 1783 const float x0 = (float)x / (float)gridSize; 1784 const float x1 = (float)(x + 1) / (float)gridSize; 1785 const float y0 = (float)y / (float)gridSize; 1786 const float y1 = (float)(y + 1) / (float)gridSize; 1787 1788 const float sx0 = x0 * (float)width; 1789 const float sx1 = x1 * (float)width; 1790 const float sy0 = y0 * (float)height; 1791 const float sy1 = y1 * (float)height; 1792 const float oosx = 1.0f / (sx1 - sx0); 1793 const float oosy = 1.0f / (sy1 - sy0); 1794 1795 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f); 1796 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f); 1797 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f); 1798 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f); 1799 1800 const int v00 = (y * stride) + x; 1801 const int v01 = (y * stride) + x + 1; 1802 const int v10 = ((y + 1) * stride) + x; 1803 const int v11 = ((y + 1) * stride) + x + 1; 1804 const tcu::Vec4 c00 = colors[v00]; 1805 const tcu::Vec4 c01 = colors[v01]; 1806 const tcu::Vec4 c10 = colors[v10]; 1807 const tcu::Vec4 c11 = colors[v11]; 1808 1809 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1); 1810 1811 for (int iy = iy0; iy < iy1; iy++) 1812 for (int ix = ix0; ix < ix1; ix++) 1813 { 1814 DE_ASSERT(deInBounds32(ix, 0, width)); 1815 DE_ASSERT(deInBounds32(iy, 0, height)); 1816 1817 const float sfx = (float)ix + 0.5f; 1818 const float sfy = (float)iy + 0.5f; 1819 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f); 1820 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f); 1821 1822 // Triangle quad interpolation. 1823 const bool tri = fx1 + fy1 <= 1.0f; 1824 const float tx = tri ? fx1 : (1.0f-fx1); 1825 const float ty = tri ? fy1 : (1.0f-fy1); 1826 const tcu::Vec4& t0 = tri ? c00 : c11; 1827 const tcu::Vec4& t1 = tri ? c01 : c10; 1828 const tcu::Vec4& t2 = tri ? c10 : c01; 1829 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty; 1830 1831 result.setPixel(ix, iy, tcu::RGBA(color)); 1832 } 1833 } 1834} 1835 1836void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid) 1837{ 1838 // Buffer info. 1839 const int width = result.getWidth(); 1840 const int height = result.getHeight(); 1841 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check 1842 ShaderEvalContext evalCtx (quadGrid); 1843 1844 // Render. 1845 for (int y = 0; y < height; y++) 1846 for (int x = 0; x < width; x++) 1847 { 1848 const float sx = ((float)x + 0.5f) / (float)width; 1849 const float sy = ((float)y + 0.5f) / (float)height; 1850 1851 evalCtx.reset(sx, sy); 1852 m_evaluator.evaluate(evalCtx); 1853 // Select either clear color or computed color based on discarded bit. 1854 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color; 1855 1856 if (!hasAlpha) 1857 color.w() = 1.0f; 1858 1859 result.setPixel(x, y, tcu::RGBA(color)); 1860 } 1861} 1862 1863bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold) 1864{ 1865 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT); 1866} 1867 1868} // sr 1869} // vkt 1870