vktShaderRender.cpp revision 94128dffb454628346f09bb736e0f4ace9df0b9e
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, deUint32 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 // \todo [2015-10-09 elecro] remove the 'hackPadding' variable if the driver support small uniforms, 546 // that is for example one float big uniforms. 547 const deUint32 hackPadding = size < 4 * sizeof(float) ? (deUint32)(3u * sizeof(float)) : 0u; 548 549 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform()); 550 uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 551 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size + hackPadding); 552 uniformInfo->location = bindingLocation; 553 uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer)); 554 uniformInfo->alloc = AllocationSp(alloc.release()); 555 556 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo))); 557} 558 559void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, deUint32 dataSize, const void* data) 560{ 561 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_ALL); 562 m_descriptorPoolBuilder.addType(descriptorType); 563 564 setupUniformData(bindingLocation, dataSize, data); 565} 566 567void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation, 568 vk::VkFormat format, 569 deUint32 sizePerElement, 570 deUint32 count, 571 const void* dataPtr) 572{ 573 // Add binding specification 574 const deUint32 binding = (deUint32)m_vertexBindingDescription.size(); 575 const VkVertexInputBindingDescription bindingDescription = 576 { 577 binding, // deUint32 binding; 578 sizePerElement, // deUint32 stride; 579 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate stepRate; 580 }; 581 582 m_vertexBindingDescription.push_back(bindingDescription); 583 584 // Add location and format specification 585 const VkVertexInputAttributeDescription attributeDescription = 586 { 587 bindingLocation, // deUint32 location; 588 binding, // deUint32 binding; 589 format, // VkFormat format; 590 0u, // deUint32 offset; 591 }; 592 593 m_vertexattributeDescription.push_back(attributeDescription); 594 595 // Upload data to buffer 596 const VkDevice vkDevice = m_context.getDevice(); 597 const DeviceInterface& vk = m_context.getDeviceInterface(); 598 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 599 600 const VkDeviceSize inputSize = sizePerElement * count; 601 const VkBufferCreateInfo vertexBufferParams = 602 { 603 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 604 DE_NULL, // const void* pNext; 605 0u, // VkBufferCreateFlags flags; 606 inputSize, // VkDeviceSize size; 607 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 608 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 609 1u, // deUint32 queueFamilyCount; 610 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 611 }; 612 613 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams); 614 de::MovePtr<vk::Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 615 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset())); 616 617 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize); 618 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize); 619 620 m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer))); 621 m_vertexBufferAllocs.push_back(AllocationSp(alloc.release())); 622} 623 624void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type) 625{ 626 const EnabledBaseAttribute attribute = 627 { 628 bindingLocation, // deUint32 location; 629 type // BaseAttributeType type; 630 }; 631 m_enabledBaseAttributes.push_back(attribute); 632} 633 634void ShaderRenderCaseInstance::setup (void) 635{ 636} 637 638void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords) 639{ 640 m_uniformSetup.setup(*this, constCoords); 641} 642 643void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type) 644{ 645 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break 646 647 switch(type) 648 { 649 // Bool 650 UNIFORM_CASE(UB_FALSE, 0); 651 UNIFORM_CASE(UB_TRUE, 1); 652 653 // BVec4 654 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0)); 655 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1)); 656 657 // Integer 658 UNIFORM_CASE(UI_ZERO, 0); 659 UNIFORM_CASE(UI_ONE, 1); 660 UNIFORM_CASE(UI_TWO, 2); 661 UNIFORM_CASE(UI_THREE, 3); 662 UNIFORM_CASE(UI_FOUR, 4); 663 UNIFORM_CASE(UI_FIVE, 5); 664 UNIFORM_CASE(UI_SIX, 6); 665 UNIFORM_CASE(UI_SEVEN, 7); 666 UNIFORM_CASE(UI_EIGHT, 8); 667 UNIFORM_CASE(UI_ONEHUNDREDONE, 101); 668 669 // IVec2 670 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1)); 671 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0)); 672 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1)); 673 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2)); 674 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3)); 675 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4)); 676 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5)); 677 678 // IVec3 679 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1)); 680 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0)); 681 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1)); 682 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2)); 683 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3)); 684 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4)); 685 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5)); 686 687 // IVec4 688 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1)); 689 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0)); 690 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1)); 691 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2)); 692 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3)); 693 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4)); 694 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5)); 695 696 // Float 697 UNIFORM_CASE(UF_ZERO, 0.0f); 698 UNIFORM_CASE(UF_ONE, 1.0f); 699 UNIFORM_CASE(UF_TWO, 2.0f); 700 UNIFORM_CASE(UF_THREE, 3.0f); 701 UNIFORM_CASE(UF_FOUR, 4.0f); 702 UNIFORM_CASE(UF_FIVE, 5.0f); 703 UNIFORM_CASE(UF_SIX, 6.0f); 704 UNIFORM_CASE(UF_SEVEN, 7.0f); 705 UNIFORM_CASE(UF_EIGHT, 8.0f); 706 707 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f); 708 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f); 709 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f); 710 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f); 711 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f); 712 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f); 713 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f); 714 715 // Vec2 716 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f)); 717 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f)); 718 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f)); 719 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f)); 720 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f)); 721 722 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f)); 723 724 // Vec3 725 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f)); 726 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f)); 727 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f)); 728 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f)); 729 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f)); 730 731 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f)); 732 733 // Vec4 734 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f)); 735 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f)); 736 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f)); 737 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f)); 738 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f)); 739 740 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f)); 741 742 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 743 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f)); 744 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 745 746 default: 747 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage; 748 break; 749 } 750 751 #undef UNIFORM_CASE 752} 753 754const tcu::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const 755{ 756 return tcu::IVec2(de::min(m_renderSize.x(), s_maxRenderWidth), 757 de::min(m_renderSize.y(), s_maxRenderHeight)); 758} 759 760Move<VkImage> ShaderRenderCaseInstance::createImage2D (const tcu::Texture2D& texture, 761 const VkFormat format, 762 const VkImageUsageFlags usage, 763 const VkImageTiling tiling) 764{ 765 const VkDevice vkDevice = m_context.getDevice(); 766 const DeviceInterface& vk = m_context.getDeviceInterface(); 767 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 768 769 const VkImageCreateInfo imageCreateInfo = 770 { 771 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 772 DE_NULL, // const void* pNext; 773 0, // VkImageCreateFlags flags; 774 VK_IMAGE_TYPE_2D, // VkImageType imageType; 775 format, // VkFormat format; 776 { texture.getWidth(), texture.getHeight(), 1 }, // 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, layout.size); 817 818 return allocation; 819} 820 821void ShaderRenderCaseInstance::copyTilingImageToOptimal (const vk::VkImage& srcImage, 822 const vk::VkImage& dstImage, 823 deInt32 width, 824 deInt32 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 0u // 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 DE_NULL, // VkRenderPass renderPass; 859 0u, // deUint32 subpass; 860 DE_NULL, // VkFramebuffer framebuffer; 861 VK_FALSE, // VkBool32 occlusionQueryEnable; 862 (VkQueryControlFlags)0, 863 (VkQueryPipelineStatisticFlags)0, 864 }; 865 866 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 867 868 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 869 870 // Add image barriers 871 const VkImageMemoryBarrier layoutBarriers[2] = 872 { 873 createImageMemoryBarrier(srcImage, (VkAccessFlags)0u, (VkAccessFlags)0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL), 874 createImageMemoryBarrier(dstImage, (VkAccessFlags)0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) 875 }; 876 877 for (deUint32 barrierNdx = 0; barrierNdx < DE_LENGTH_OF_ARRAY(layoutBarriers); barrierNdx++) 878 { 879 const VkImageMemoryBarrier* memoryBarrier = &layoutBarriers[barrierNdx]; 880 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void * const*)&memoryBarrier); 881 } 882 883 // Add image copy 884 const VkImageCopy imageCopy = 885 { 886 { 887 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 888 0u, // deUint32 mipLevel; 889 0u, // deUint32 arrayLayer; 890 1u // deUint32 arraySize; 891 }, // VkImageSubresourceCopy srcSubresource; 892 { 893 0, // int32 x; 894 0, // int32 y; 895 0 // int32 z; 896 }, // VkOffset3D srcOffset; 897 { 898 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 899 0u, // deUint32 mipLevel; 900 0u, // deUint32 arrayLayer; 901 1u // deUint32 arraySize; 902 }, // VkImageSubresourceCopy destSubResource; 903 { 904 0, // int32 x; 905 0, // int32 y; 906 0 // int32 z; 907 }, // VkOffset3D dstOffset; 908 { 909 width, // int32 width; 910 height, // int32 height; 911 1, // int32 depth 912 } // VkExtent3D extent; 913 }; 914 915 vk.cmdCopyImage(*cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopy); 916 917 // Add destination barrier 918 const VkImageMemoryBarrier dstBarrier = 919 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); 920 921 const void* const* barrier = (const void* const*)&dstBarrier; 922 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void* const*)&barrier); 923 924 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 925 926 const VkFenceCreateInfo fenceParams = 927 { 928 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 929 DE_NULL, // const void* pNext; 930 0u // VkFenceCreateFlags flags; 931 }; 932 const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceParams)); 933 const VkSubmitInfo submitInfo = 934 { 935 VK_STRUCTURE_TYPE_SUBMIT_INFO, 936 DE_NULL, 937 0u, 938 (const VkSemaphore*)DE_NULL, 939 1u, 940 &cmdBuffer.get(), 941 0u, 942 (const VkSemaphore*)DE_NULL, 943 }; 944 945 946 // Execute copy 947 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); 948 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 949 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/)); 950} 951 952void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID) 953{ 954 DE_ASSERT(textureID < m_textures.size()); 955 956 const VkDevice vkDevice = m_context.getDevice(); 957 const DeviceInterface& vk = m_context.getDeviceInterface(); 958 const TextureBinding& textureBinding = *m_textures[textureID]; 959 const tcu::Texture2D& refTexture = textureBinding.get2D(); 960 const tcu::Sampler& refSampler = textureBinding.getSampler(); 961 const VkFormat format = refTexture.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) 962 ? VK_FORMAT_R8G8B8A8_UNORM 963 : VK_FORMAT_R8G8B8_UNORM; 964 965 // Create & alloc the image 966 Move<VkImage> vkTexture; 967 de::MovePtr<Allocation> allocation; 968 969 if (isSupportedLinearTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format)) 970 { 971 vkTexture = createImage2D(refTexture, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR); 972 allocation = uploadImage2D(refTexture, *vkTexture); 973 } 974 else if (isSupportedOptimalTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format)) 975 { 976 Move<VkImage> stagingTexture (createImage2D(refTexture, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR)); 977 de::MovePtr<Allocation> stagingAlloc (uploadImage2D(refTexture, *stagingTexture)); 978 979 const VkImageUsageFlags dstUsageFlags = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; 980 vkTexture = createImage2D(refTexture, format, dstUsageFlags, VK_IMAGE_TILING_OPTIMAL); 981 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any); 982 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset())); 983 984 copyTilingImageToOptimal(*stagingTexture, *vkTexture, refTexture.getWidth(), refTexture.getHeight()); 985 } 986 else 987 { 988 TCU_THROW(InternalError, "Unable to create 2D image"); 989 } 990 991 // Create sampler 992 const bool compareEnabled = (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE); 993 const VkSamplerCreateInfo samplerParams = 994 { 995 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType; 996 DE_NULL, // const void* pNext; 997 (VkSamplerCreateFlags)0, 998 mapFilterMode(refSampler.magFilter), // VkTexFilter magFilter; 999 mapFilterMode(refSampler.minFilter), // VkTexFilter minFilter; 1000 mapMipmapMode(refSampler.minFilter), // VkTexMipmapMode mipMode; 1001 mapWrapMode(refSampler.wrapS), // VkTexAddressMode addressModeU; 1002 mapWrapMode(refSampler.wrapT), // VkTexAddressMode addressModeV; 1003 mapWrapMode(refSampler.wrapR), // VkTexAddressMode addressModeW; 1004 refSampler.lodThreshold, // float mipLodBias; 1005 1, // float maxAnisotropy; 1006 compareEnabled, // VkBool32 compareEnable; 1007 mapCompareMode(refSampler.compare), // VkCompareOp compareOp; 1008 0.0f, // float minLod; 1009 0.0f, // float maxLod; 1010 VK_BORDER_COLOR_INT_OPAQUE_WHITE, // VkBorderColor boderColor; 1011 VK_FALSE, // VkBool32 unnormalizerdCoordinates; 1012 }; 1013 1014 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams); 1015 1016 const VkImageViewCreateInfo viewParams = 1017 { 1018 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1019 NULL, // const voide* pNext; 1020 0u, // VkImageViewCreateFlags flags; 1021 *vkTexture, // VkImage image; 1022 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1023 format, // VkFormat format; 1024 { 1025 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r; 1026 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g; 1027 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b; 1028 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a; 1029 }, // VkChannelMapping channels; 1030 { 1031 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1032 0, // deUint32 baseMipLevel; 1033 1, // deUint32 mipLevels; 1034 0, // deUint32 baseArraySlice; 1035 1 // deUint32 arraySize; 1036 }, // VkImageSubresourceRange subresourceRange; 1037 }; 1038 1039 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams); 1040 1041 const vk::VkDescriptorImageInfo descriptor = 1042 { 1043 sampler.get(), // VkSampler sampler; 1044 imageView.get(), // VkImageView imageView; 1045 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout; 1046 }; 1047 1048 de::MovePtr<SamplerUniform> uniform(new SamplerUniform()); 1049 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 1050 uniform->descriptor = descriptor; 1051 uniform->location = bindingLocation; 1052 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture)); 1053 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView)); 1054 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler)); 1055 uniform->alloc = AllocationSp(allocation.release()); 1056 1057 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, &uniform->descriptor.sampler); 1058 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 1059 1060 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform))); 1061} 1062 1063void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid) 1064{ 1065 /* Configuration of the vertex input attributes: 1066 a_position is at location 0 1067 a_coords is at location 1 1068 a_unitCoords is at location 2 1069 a_one is at location 3 1070 1071 User attributes starts from at the location 4. 1072 */ 1073 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions()); 1074 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords()); 1075 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords()); 1076 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne()); 1077 1078 static const struct 1079 { 1080 BaseAttributeType type; 1081 int userNdx; 1082 } userAttributes[] = 1083 { 1084 { A_IN0, 0 }, 1085 { A_IN1, 1 }, 1086 { A_IN2, 2 }, 1087 { A_IN3, 3 } 1088 }; 1089 1090 static const struct 1091 { 1092 BaseAttributeType matrixType; 1093 int numCols; 1094 int numRows; 1095 } matrices[] = 1096 { 1097 { MAT2, 2, 2 }, 1098 { MAT2x3, 2, 3 }, 1099 { MAT2x4, 2, 4 }, 1100 { MAT3x2, 3, 2 }, 1101 { MAT3, 3, 3 }, 1102 { MAT3x4, 3, 4 }, 1103 { MAT4x2, 4, 2 }, 1104 { MAT4x3, 4, 3 }, 1105 { MAT4, 4, 4 } 1106 }; 1107 1108 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++) 1109 { 1110 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++) 1111 { 1112 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type) 1113 continue; 1114 1115 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx)); 1116 } 1117 1118 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++) 1119 { 1120 1121 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type) 1122 continue; 1123 1124 const int numCols = matrices[matNdx].numCols; 1125 1126 for (int colNdx = 0; colNdx < numCols; colNdx++) 1127 { 1128 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx)); 1129 } 1130 } 1131 } 1132} 1133 1134void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid) 1135{ 1136 const VkDevice vkDevice = m_context.getDevice(); 1137 const DeviceInterface& vk = m_context.getDeviceInterface(); 1138 const VkQueue queue = m_context.getUniversalQueue(); 1139 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1140 1141 // Create color image 1142 { 1143 const VkImageCreateInfo colorImageParams = 1144 { 1145 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1146 DE_NULL, // const void* pNext; 1147 0u, // VkImageCreateFlags flags; 1148 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1149 m_colorFormat, // VkFormat format; 1150 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 1151 1u, // deUint32 mipLevels; 1152 1u, // deUint32 arraySize; 1153 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 1154 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1155 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 1156 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1157 1u, // deUint32 queueFamilyCount; 1158 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1159 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1160 }; 1161 1162 m_colorImage = createImage(vk, vkDevice, &colorImageParams); 1163 1164 // Allocate and bind color image memory 1165 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 1166 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 1167 } 1168 1169 // Create color attachment view 1170 { 1171 const VkImageViewCreateInfo colorImageViewParams = 1172 { 1173 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1174 DE_NULL, // const void* pNext; 1175 0u, // VkImageViewCreateFlags flags; 1176 *m_colorImage, // VkImage image; 1177 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1178 m_colorFormat, // VkFormat format; 1179 { 1180 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r; 1181 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g; 1182 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b; 1183 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a; 1184 }, // VkChannelMapping channels; 1185 { 1186 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1187 0, // deUint32 baseMipLevel; 1188 1, // deUint32 mipLevels; 1189 0, // deUint32 baseArraySlice; 1190 1 // deUint32 arraySize; 1191 }, // VkImageSubresourceRange subresourceRange; 1192 }; 1193 1194 m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams); 1195 } 1196 1197 // Create render pass 1198 { 1199 const VkAttachmentDescription attachmentDescription = 1200 { 1201 (VkAttachmentDescriptionFlags)0, 1202 m_colorFormat, // VkFormat format; 1203 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 1204 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 1205 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1206 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1207 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1208 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 1209 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 1210 }; 1211 1212 const VkAttachmentReference attachmentReference = 1213 { 1214 0u, // deUint32 attachment; 1215 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 1216 }; 1217 1218 const VkSubpassDescription subpassDescription = 1219 { 1220 0u, // VkSubpassDescriptionFlags flags; 1221 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 1222 0u, // deUint32 inputCount; 1223 DE_NULL, // constVkAttachmentReference* pInputAttachments; 1224 1u, // deUint32 colorCount; 1225 &attachmentReference, // constVkAttachmentReference* pColorAttachments; 1226 DE_NULL, // constVkAttachmentReference* pResolveAttachments; 1227 DE_NULL, // VkAttachmentReference depthStencilAttachment; 1228 0u, // deUint32 preserveCount; 1229 DE_NULL // constVkAttachmentReference* pPreserveAttachments; 1230 }; 1231 1232 const VkRenderPassCreateInfo renderPassParams = 1233 { 1234 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 1235 DE_NULL, // const void* pNext; 1236 (VkRenderPassCreateFlags)0, 1237 1u, // deUint32 attachmentCount; 1238 &attachmentDescription, // const VkAttachmentDescription* pAttachments; 1239 1u, // deUint32 subpassCount; 1240 &subpassDescription, // const VkSubpassDescription* pSubpasses; 1241 0u, // deUint32 dependencyCount; 1242 DE_NULL // const VkSubpassDependency* pDependencies; 1243 }; 1244 1245 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 1246 } 1247 1248 // Create framebuffer 1249 { 1250 const VkFramebufferCreateInfo framebufferParams = 1251 { 1252 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 1253 DE_NULL, // const void* pNext; 1254 (VkFramebufferCreateFlags)0, 1255 *m_renderPass, // VkRenderPass renderPass; 1256 1u, // deUint32 attachmentCount; 1257 &*m_colorImageView, // const VkImageView* pAttachments; 1258 (deUint32)m_renderSize.x(), // deUint32 width; 1259 (deUint32)m_renderSize.y(), // deUint32 height; 1260 1u // deUint32 layers; 1261 }; 1262 1263 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 1264 } 1265 1266 // Create descriptors 1267 { 1268 setupUniforms(quadGrid.getConstCoords()); 1269 1270 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice); 1271 m_descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1272 1273 { 1274 const VkDescriptorSetAllocateInfo allocInfo = 1275 { 1276 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 1277 DE_NULL, 1278 *m_descriptorPool, 1279 1u, 1280 &m_descriptorSetLayout.get(), 1281 }; 1282 1283 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo); 1284 } 1285 1286 for (deUint32 i = 0; i < m_uniformInfos.size(); i++) 1287 { 1288 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get(); 1289 deUint32 location = uniformInfo->location; 1290 1291 if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) 1292 { 1293 const BufferUniform* bufferInfo = dynamic_cast<const BufferUniform*>(uniformInfo); 1294 1295 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor); 1296 } 1297 else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 1298 { 1299 const SamplerUniform* samplerInfo = dynamic_cast<const SamplerUniform*>(uniformInfo); 1300 1301 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor); 1302 } 1303 else 1304 DE_FATAL("Impossible"); 1305 } 1306 1307 m_descriptorSetUpdateBuilder.update(vk, vkDevice); 1308 } 1309 1310 // Create pipeline layout 1311 { 1312 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 1313 { 1314 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 1315 DE_NULL, // const void* pNext; 1316 (VkPipelineLayoutCreateFlags)0, 1317 1u, // deUint32 descriptorSetCount; 1318 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 1319 0u, // deUint32 pushConstantRangeCount; 1320 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 1321 }; 1322 1323 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 1324 } 1325 1326 // Create shaders 1327 { 1328 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0); 1329 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0); 1330 } 1331 1332 // Create pipeline 1333 { 1334 const VkPipelineShaderStageCreateInfo shaderStageParams[2] = 1335 { 1336 { 1337 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1338 DE_NULL, // const void* pNext; 1339 (VkPipelineShaderStageCreateFlags)0, 1340 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStage stage; 1341 *m_vertexShaderModule, // VkShader shader; 1342 "main", 1343 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1344 }, 1345 { 1346 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1347 DE_NULL, // const void* pNext; 1348 (VkPipelineShaderStageCreateFlags)0, 1349 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStage stage; 1350 *m_fragmentShaderModule, // VkShader shader; 1351 "main", 1352 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1353 } 1354 }; 1355 1356 // Add test case specific attributes 1357 if (m_attribFunc) 1358 m_attribFunc(*this, quadGrid.getNumVertices()); 1359 1360 // Add base attributes 1361 setupDefaultInputs(quadGrid); 1362 1363 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 1364 { 1365 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1366 DE_NULL, // const void* pNext; 1367 (VkPipelineVertexInputStateCreateFlags)0, 1368 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount; 1369 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1370 (deUint32)m_vertexattributeDescription.size(), // deUint32 attributeCount; 1371 &m_vertexattributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 1372 }; 1373 1374 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 1375 { 1376 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 1377 DE_NULL, // const void* pNext; 1378 (VkPipelineInputAssemblyStateCreateFlags)0, 1379 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; 1380 false // VkBool32 primitiveRestartEnable; 1381 }; 1382 1383 const VkViewport viewport = 1384 { 1385 0.0f, // float originX; 1386 0.0f, // float originY; 1387 (float)m_renderSize.x(), // float width; 1388 (float)m_renderSize.y(), // float height; 1389 0.0f, // float minDepth; 1390 1.0f // float maxDepth; 1391 }; 1392 1393 const VkRect2D scissor = 1394 { 1395 { 1396 0u, // deUint32 x; 1397 0u, // deUint32 y; 1398 }, // VkOffset2D offset; 1399 { 1400 m_renderSize.x(), // deUint32 width; 1401 m_renderSize.y(), // deUint32 height; 1402 }, // VkExtent2D extent; 1403 }; 1404 1405 const VkPipelineViewportStateCreateInfo viewportStateParams = 1406 { 1407 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 1408 DE_NULL, // const void* pNext; 1409 (VkPipelineViewportStateCreateFlags)0, 1410 1u, // deUint32 viewportCount; 1411 &viewport, // const VkViewport* pViewports; 1412 1u, // deUint32 scissorsCount; 1413 &scissor, // const VkRect2D* pScissors; 1414 }; 1415 1416 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 1417 { 1418 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 1419 DE_NULL, // const void* pNext; 1420 (VkPipelineRasterizationStateCreateFlags)0, 1421 false, // VkBool32 depthClipEnable; 1422 false, // VkBool32 rasterizerDiscardEnable; 1423 VK_POLYGON_MODE_FILL, // VkFillMode fillMode; 1424 VK_CULL_MODE_NONE, // VkCullMode cullMode; 1425 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 1426 false, // VkBool32 depthBiasEnable; 1427 0.0f, // float depthBias; 1428 0.0f, // float depthBiasClamp; 1429 0.0f, // float slopeScaledDepthBias; 1430 1.0f, // float lineWidth; 1431 }; 1432 1433 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 1434 { 1435 false, // VkBool32 blendEnable; 1436 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor; 1437 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor; 1438 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; 1439 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha; 1440 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha; 1441 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; 1442 (VK_COLOR_COMPONENT_R_BIT | 1443 VK_COLOR_COMPONENT_G_BIT | 1444 VK_COLOR_COMPONENT_B_BIT | 1445 VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask; 1446 }; 1447 1448 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 1449 { 1450 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 1451 DE_NULL, // const void* pNext; 1452 (VkPipelineColorBlendStateCreateFlags)0, 1453 false, // VkBool32 logicOpEnable; 1454 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 1455 1u, // deUint32 attachmentCount; 1456 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 1457 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4]; 1458 }; 1459 1460 const VkPipelineDynamicStateCreateInfo dynamicStateInfo = 1461 { 1462 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; 1463 DE_NULL, // const void* pNext; 1464 (VkPipelineDynamicStateCreateFlags)0, 1465 0u, // deUint32 dynamicStateCount; 1466 DE_NULL // const VkDynamicState* pDynamicStates; 1467 }; 1468 1469 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 1470 { 1471 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 1472 DE_NULL, // const void* pNext; 1473 0u, // VkPipelineCreateFlags flags; 1474 2u, // deUint32 stageCount; 1475 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 1476 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 1477 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 1478 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 1479 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 1480 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState; 1481 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 1482 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 1483 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 1484 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 1485 *m_pipelineLayout, // VkPipelineLayout layout; 1486 *m_renderPass, // VkRenderPass renderPass; 1487 0u, // deUint32 subpass; 1488 0u, // VkPipeline basePipelineHandle; 1489 0u // deInt32 basePipelineIndex; 1490 }; 1491 1492 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 1493 } 1494 1495 // Create vertex indices buffer 1496 { 1497 const VkDeviceSize indiceBufferSize = quadGrid.getNumTriangles() * 3 * sizeof(deUint16); 1498 const VkBufferCreateInfo indiceBufferParams = 1499 { 1500 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1501 DE_NULL, // const void* pNext; 1502 0u, // VkBufferCreateFlags flags; 1503 indiceBufferSize, // VkDeviceSize size; 1504 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage; 1505 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1506 1u, // deUint32 queueFamilyCount; 1507 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1508 }; 1509 1510 m_indiceBuffer = createBuffer(vk, vkDevice, &indiceBufferParams); 1511 m_indiceBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible); 1512 1513 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset())); 1514 1515 // Load vertice indices into buffer 1516 deMemcpy(m_indiceBufferAlloc->getHostPtr(), quadGrid.getIndices(), (size_t)indiceBufferSize); 1517 flushMappedMemoryRange(vk, vkDevice, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset(), indiceBufferSize); 1518 } 1519 1520 // Create command pool 1521 { 1522 const VkCommandPoolCreateInfo cmdPoolParams = 1523 { 1524 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1525 DE_NULL, // const void* pNext; 1526 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 1527 queueFamilyIndex, // deUint32 queueFamilyIndex; 1528 }; 1529 1530 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1531 } 1532 1533 // Create command buffer 1534 { 1535 const VkCommandBufferAllocateInfo cmdBufferParams = 1536 { 1537 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1538 DE_NULL, // const void* pNext; 1539 *m_cmdPool, // VkCmdPool cmdPool; 1540 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 1541 1u // deUint32 bufferCount; 1542 }; 1543 1544 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1545 { 1546 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1547 DE_NULL, // const void* pNext; 1548 0u, // VkCmdBufferOptimizeFlags flags; 1549 DE_NULL, // VkRenderPass renderPass; 1550 0u, // deUint32 subpass; 1551 DE_NULL, // VkFramebuffer framebuffer; 1552 VK_FALSE, 1553 (VkQueryControlFlags)0, 1554 (VkQueryPipelineStatisticFlags)0, 1555 }; 1556 1557 const VkClearValue clearValues = makeClearValueColorF32(m_clearColor.x(), 1558 m_clearColor.y(), 1559 m_clearColor.z(), 1560 m_clearColor.w()); 1561 1562 const VkRenderPassBeginInfo renderPassBeginInfo = 1563 { 1564 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1565 DE_NULL, // const void* pNext; 1566 *m_renderPass, // VkRenderPass renderPass; 1567 *m_framebuffer, // VkFramebuffer framebuffer; 1568 { { 0, 0 }, {m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea; 1569 1, // deUint32 clearValueCount; 1570 &clearValues, // const VkClearValue* pClearValues; 1571 }; 1572 1573 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 1574 1575 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1576 1577 // Add texture barriers 1578 std::vector<VkImageMemoryBarrier> barriers; 1579 std::vector<void*> barrierPtrs; 1580 1581 for(deUint32 i = 0; i < m_uniformInfos.size(); i++) 1582 { 1583 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get(); 1584 1585 if (uniformInfo->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 1586 { 1587 continue; 1588 } 1589 1590 const SamplerUniform* sampler = static_cast<const SamplerUniform*>(uniformInfo); 1591 1592 const VkAccessFlags outputMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; 1593 const VkImageMemoryBarrier textureBarrier = createImageMemoryBarrier(sampler->image->get(), outputMask, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 1594 1595 barriers.push_back(textureBarrier); 1596 barrierPtrs.push_back((void*)&barriers.back()); 1597 } 1598 1599 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)); 1600 1601 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1602 1603 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline); 1604 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL); 1605 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16); 1606 1607 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size(); 1608 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0); 1609 1610 std::vector<VkBuffer> buffers(numberOfVertexAttributes); 1611 for (size_t i = 0; i < numberOfVertexAttributes; i++) 1612 { 1613 buffers[i] = m_vertexBuffers[i].get()->get(); 1614 } 1615 1616 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]); 1617 vk.cmdDrawIndexed(*m_cmdBuffer, quadGrid.getNumTriangles() * 3, 1, 0, 0, 0); 1618 1619 vk.cmdEndRenderPass(*m_cmdBuffer); 1620 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1621 } 1622 1623 // Create fence 1624 { 1625 const VkFenceCreateInfo fenceParams = 1626 { 1627 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 1628 DE_NULL, // const void* pNext; 1629 0u // VkFenceCreateFlags flags; 1630 }; 1631 m_fence = createFence(vk, vkDevice, &fenceParams); 1632 } 1633 1634 // Execute Draw 1635 { 1636 const VkSubmitInfo submitInfo = 1637 { 1638 VK_STRUCTURE_TYPE_SUBMIT_INFO, 1639 DE_NULL, 1640 0u, 1641 (const VkSemaphore*)DE_NULL, 1642 1u, 1643 &m_cmdBuffer.get(), 1644 0u, 1645 (const VkSemaphore*)DE_NULL, 1646 }; 1647 1648 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 1649 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 1650 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/)); 1651 } 1652 1653 // Read back the result 1654 { 1655 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y()); 1656 const VkBufferCreateInfo readImageBufferParams = 1657 { 1658 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1659 DE_NULL, // const void* pNext; 1660 0u, // VkBufferCreateFlags flags; 1661 imageSizeBytes, // VkDeviceSize size; 1662 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 1663 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1664 1u, // deUint32 queueFamilyCount; 1665 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1666 }; 1667 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, vkDevice, &readImageBufferParams)); 1668 const de::UniquePtr<Allocation> readImageBufferMemory (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible)); 1669 1670 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset())); 1671 1672 // Copy image to buffer 1673 const VkCommandBufferAllocateInfo cmdBufferParams = 1674 { 1675 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1676 DE_NULL, // const void* pNext; 1677 *m_cmdPool, // VkCmdPool cmdPool; 1678 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 1679 1u // deUint32 bufferCount; 1680 }; 1681 1682 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1683 { 1684 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1685 DE_NULL, // const void* pNext; 1686 0u, // VkCmdBufferOptimizeFlags flags; 1687 DE_NULL, // VkRenderPass renderPass; 1688 0u, // deUint32 subpass; 1689 DE_NULL, // VkFramebuffer framebuffer; 1690 VK_FALSE, 1691 (VkQueryControlFlags)0, 1692 (VkQueryPipelineStatisticFlags)0, 1693 }; 1694 1695 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 1696 1697 const VkBufferImageCopy copyParams = 1698 { 1699 0u, // VkDeviceSize bufferOffset; 1700 (deUint32)m_renderSize.x(), // deUint32 bufferRowLength; 1701 (deUint32)m_renderSize.y(), // deUint32 bufferImageHeight; 1702 { 1703 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 1704 0u, // deUint32 mipLevel; 1705 0u, // deUint32 arraySlice; 1706 1u, // deUint32 arraySize; 1707 }, // VkImageSubresourceCopy imageSubresource; 1708 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 1709 { m_renderSize.x(), m_renderSize.y(), 1u } // VkExtent3D imageExtent; 1710 }; 1711 const VkSubmitInfo submitInfo = 1712 { 1713 VK_STRUCTURE_TYPE_SUBMIT_INFO, 1714 DE_NULL, 1715 0u, 1716 (const VkSemaphore*)DE_NULL, 1717 1u, 1718 &cmdBuffer.get(), 1719 0u, 1720 (const VkSemaphore*)DE_NULL, 1721 }; 1722 1723 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 1724 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params); 1725 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1726 1727 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 1728 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 1729 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); 1730 1731 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes); 1732 1733 const tcu::TextureFormat resultFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 1734 const tcu::ConstPixelBufferAccess resultAccess (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr()); 1735 1736 tcu::copy(result.getAccess(), resultAccess); 1737 } 1738} 1739 1740void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid) 1741{ 1742 // Buffer info. 1743 const int width = result.getWidth(); 1744 const int height = result.getHeight(); 1745 const int gridSize = quadGrid.getGridSize(); 1746 const int stride = gridSize + 1; 1747 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check 1748 ShaderEvalContext evalCtx (quadGrid); 1749 1750 // Evaluate color for each vertex. 1751 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1)); 1752 for (int y = 0; y < gridSize+1; y++) 1753 for (int x = 0; x < gridSize+1; x++) 1754 { 1755 const float sx = (float)x / (float)gridSize; 1756 const float sy = (float)y / (float)gridSize; 1757 const int vtxNdx = ((y * (gridSize+1)) + x); 1758 1759 evalCtx.reset(sx, sy); 1760 m_evaluator.evaluate(evalCtx); 1761 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader. 1762 tcu::Vec4 color = evalCtx.color; 1763 1764 if (!hasAlpha) 1765 color.w() = 1.0f; 1766 1767 colors[vtxNdx] = color; 1768 } 1769 1770 // Render quads. 1771 for (int y = 0; y < gridSize; y++) 1772 for (int x = 0; x < gridSize; x++) 1773 { 1774 const float x0 = (float)x / (float)gridSize; 1775 const float x1 = (float)(x + 1) / (float)gridSize; 1776 const float y0 = (float)y / (float)gridSize; 1777 const float y1 = (float)(y + 1) / (float)gridSize; 1778 1779 const float sx0 = x0 * (float)width; 1780 const float sx1 = x1 * (float)width; 1781 const float sy0 = y0 * (float)height; 1782 const float sy1 = y1 * (float)height; 1783 const float oosx = 1.0f / (sx1 - sx0); 1784 const float oosy = 1.0f / (sy1 - sy0); 1785 1786 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f); 1787 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f); 1788 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f); 1789 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f); 1790 1791 const int v00 = (y * stride) + x; 1792 const int v01 = (y * stride) + x + 1; 1793 const int v10 = ((y + 1) * stride) + x; 1794 const int v11 = ((y + 1) * stride) + x + 1; 1795 const tcu::Vec4 c00 = colors[v00]; 1796 const tcu::Vec4 c01 = colors[v01]; 1797 const tcu::Vec4 c10 = colors[v10]; 1798 const tcu::Vec4 c11 = colors[v11]; 1799 1800 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1); 1801 1802 for (int iy = iy0; iy < iy1; iy++) 1803 for (int ix = ix0; ix < ix1; ix++) 1804 { 1805 DE_ASSERT(deInBounds32(ix, 0, width)); 1806 DE_ASSERT(deInBounds32(iy, 0, height)); 1807 1808 const float sfx = (float)ix + 0.5f; 1809 const float sfy = (float)iy + 0.5f; 1810 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f); 1811 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f); 1812 1813 // Triangle quad interpolation. 1814 const bool tri = fx1 + fy1 <= 1.0f; 1815 const float tx = tri ? fx1 : (1.0f-fx1); 1816 const float ty = tri ? fy1 : (1.0f-fy1); 1817 const tcu::Vec4& t0 = tri ? c00 : c11; 1818 const tcu::Vec4& t1 = tri ? c01 : c10; 1819 const tcu::Vec4& t2 = tri ? c10 : c01; 1820 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty; 1821 1822 result.setPixel(ix, iy, tcu::RGBA(color)); 1823 } 1824 } 1825} 1826 1827void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid) 1828{ 1829 // Buffer info. 1830 const int width = result.getWidth(); 1831 const int height = result.getHeight(); 1832 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check 1833 ShaderEvalContext evalCtx (quadGrid); 1834 1835 // Render. 1836 for (int y = 0; y < height; y++) 1837 for (int x = 0; x < width; x++) 1838 { 1839 const float sx = ((float)x + 0.5f) / (float)width; 1840 const float sy = ((float)y + 0.5f) / (float)height; 1841 1842 evalCtx.reset(sx, sy); 1843 m_evaluator.evaluate(evalCtx); 1844 // Select either clear color or computed color based on discarded bit. 1845 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color; 1846 1847 if (!hasAlpha) 1848 color.w() = 1.0f; 1849 1850 result.setPixel(x, y, tcu::RGBA(color)); 1851 } 1852} 1853 1854bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold) 1855{ 1856 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT); 1857} 1858 1859} // sr 1860} // vkt 1861