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