1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2022 The Khronos Group Inc. 6 * Copyright (c) 2022 Google Inc. 7 * Copyright (c) 2023 LunarG, Inc. 8 * Copyright (c) 2023 Nintendo 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); 11 * you may not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 * 22 *//*! 23 * \file vktPipelineMultisampleResolveRenderAreaTests.hpp 24 * \brief Multisample resolve tests where a render area is less than an 25 * attachment size. 26 *//*--------------------------------------------------------------------*/ 27 28#include "vktPipelineMultisampleResolveRenderAreaTests.hpp" 29#include "vktTestCaseUtil.hpp" 30#include "vktTestGroupUtil.hpp" 31 32#include "vkCmdUtil.hpp" 33#include "vkImageUtil.hpp" 34#include "vkMemUtil.hpp" 35#include "vkObjUtil.hpp" 36#include "vkRefUtil.hpp" 37#include "vkTypeUtil.hpp" 38 39#include "tcuImageCompare.hpp" 40#include "tcuTestLog.hpp" 41 42namespace vkt 43{ 44namespace pipeline 45{ 46using namespace vk; 47using de::UniquePtr; 48 49namespace 50{ 51 52enum class TestShape 53{ 54 SHAPE_RECTANGLE, 55 SHAPE_DIAMOND, 56 SHAPE_PARALLELOGRAM 57}; 58 59class MultisampleRenderAreaTestInstance : public TestInstance 60{ 61public: 62 MultisampleRenderAreaTestInstance (Context& context, 63 const PipelineConstructionType pipelineConstructionType, 64 const deUint32 sampleCount, 65 const tcu::IVec2 framebufferSize, 66 const TestShape testShape, 67 const VkFormat colorFormat) 68 : TestInstance (context) 69 , m_pipelineConstructionType (pipelineConstructionType) 70 , m_sampleCount (sampleCount) 71 , m_framebufferSize (framebufferSize) 72 , m_testShape (testShape) 73 , m_colorFormat (colorFormat) 74 {} 75 76 tcu::TestStatus iterate (void); 77 78private: 79 VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& imageSize, const deUint32 sampleCount); 80 81 RenderPassWrapper makeRenderPass (const DeviceInterface& vk, 82 const VkDevice device, 83 const VkFormat colorFormat, 84 const VkImageLayout initialLayout); 85 86 void preparePipelineWrapper (GraphicsPipelineWrapper& gpw, 87 const PipelineLayoutWrapper& pipelineLayout, 88 const VkRenderPass renderPass, 89 const ShaderWrapper vertexModule, 90 const ShaderWrapper fragmentModule, 91 const tcu::IVec2& framebufferSize); 92 93 const PipelineConstructionType m_pipelineConstructionType; 94 const deUint32 m_sampleCount; 95 const tcu::IVec2 m_framebufferSize; 96 const TestShape m_testShape; 97 const VkFormat m_colorFormat; 98}; 99 100VkImageCreateInfo MultisampleRenderAreaTestInstance::makeImageCreateInfo(const tcu::IVec2& imageSize, const deUint32 sampleCount) 101{ 102 const VkImageCreateInfo imageParams = 103 { 104 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 105 DE_NULL, // const void* pNext; 106 (VkImageCreateFlags)0, // VkImageCreateFlags flags; 107 VK_IMAGE_TYPE_2D, // VkImageType imageType; 108 m_colorFormat, // VkFormat format; 109 makeExtent3D(imageSize.x(), imageSize.y(), 1), // VkExtent3D extent; 110 1u, // deUint32 mipLevels; 111 1u, // deUint32 arrayLayers; 112 sampleCount < 2u ? VK_SAMPLE_COUNT_1_BIT : (VkSampleCountFlagBits)m_sampleCount, // VkSampleCountFlagBits samples; 113 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 114 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 115 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 116 0u, // deUint32 queueFamilyIndexCount; 117 DE_NULL, // const deUint32* pQueueFamilyIndices; 118 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 119 }; 120 121 return imageParams; 122} 123 124RenderPassWrapper MultisampleRenderAreaTestInstance::makeRenderPass (const DeviceInterface& vk, 125 const VkDevice device, 126 const VkFormat colorFormat, 127 const VkImageLayout initialLayout) 128{ 129 const VkAttachmentDescription colorAttachmentDescription = 130 { 131 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 132 colorFormat, // VkFormat format; 133 (VkSampleCountFlagBits)m_sampleCount, // VkSampleCountFlagBits samples; 134 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 135 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 136 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 137 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 138 initialLayout, // VkImageLayout initialLayout; 139 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 140 }; 141 142 const VkAttachmentDescription resolveAttachmentDescription = 143 { 144 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 145 colorFormat, // VkFormat format; 146 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 147 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 148 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 149 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 150 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 151 initialLayout, // VkImageLayout initialLayout; 152 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 153 }; 154 155 std::vector<VkAttachmentDescription> attachmentDescriptions; 156 157 attachmentDescriptions.push_back(colorAttachmentDescription); 158 attachmentDescriptions.push_back(resolveAttachmentDescription); 159 160 const VkAttachmentReference colorAttachmentRef = 161 { 162 0u, // uint32_t attachment; 163 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 164 }; 165 166 const VkAttachmentReference resolveAttachmentRef = 167 { 168 1u, // uint32_t attachment; 169 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 170 }; 171 172 const VkSubpassDescription subpassDescription = 173 { 174 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 175 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 176 0u, // uint32_t inputAttachmentCount; 177 DE_NULL, // const VkAttachmentReference* pInputAttachments; 178 1u, // uint32_t colorAttachmentCount; 179 &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments; 180 &resolveAttachmentRef, // const VkAttachmentReference* pResolveAttachments; 181 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 182 0u, // uint32_t preserveAttachmentCount; 183 DE_NULL // const uint32_t* pPreserveAttachments; 184 }; 185 186 const VkRenderPassCreateInfo renderPassInfo = 187 { 188 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 189 DE_NULL, // const void* pNext; 190 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 191 (deUint32)attachmentDescriptions.size(), // uint32_t attachmentCount; 192 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments; 193 1u, // uint32_t subpassCount; 194 &subpassDescription, // const VkSubpassDescription* pSubpasses; 195 0u, // uint32_t dependencyCount; 196 DE_NULL, // const VkSubpassDependency* pDependencies; 197 }; 198 199 return RenderPassWrapper(m_pipelineConstructionType, vk, device, &renderPassInfo); 200} 201 202void MultisampleRenderAreaTestInstance::preparePipelineWrapper (GraphicsPipelineWrapper& gpw, 203 const PipelineLayoutWrapper& pipelineLayout, 204 const VkRenderPass renderPass, 205 const ShaderWrapper vertexModule, 206 const ShaderWrapper fragmentModule, 207 const tcu::IVec2& framebufferSize) 208{ 209 const std::vector<VkViewport> viewports { makeViewport(framebufferSize) }; 210 const std::vector<VkRect2D> scissors { makeRect2D(framebufferSize) }; 211 VkSampleMask sampleMask = 0xffff; 212 213 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo 214 { 215 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType 216 DE_NULL, // const void* pNext 217 0u, // VkPipelineMultisampleStateCreateFlags flags 218 (VkSampleCountFlagBits)m_sampleCount, // VkSampleCountFlagBits rasterizationSamples 219 DE_FALSE, // VkBool32 sampleShadingEnable 220 0.0f, // float minSampleShading 221 &sampleMask, // const VkSampleMask* pSampleMask 222 DE_FALSE, // VkBool32 alphaToCoverageEnable 223 DE_FALSE, // VkBool32 alphaToOneEnable 224 }; 225 226 gpw.setDefaultDepthStencilState() 227 .setDefaultColorBlendState() 228 .setDefaultRasterizationState() 229 .setupVertexInputState() 230 .setupPreRasterizationShaderState(viewports, 231 scissors, 232 pipelineLayout, 233 renderPass, 234 0u, 235 vertexModule) 236 .setupFragmentShaderState(pipelineLayout, 237 renderPass, 238 0u, 239 fragmentModule, 240 DE_NULL, 241 &multisampleStateCreateInfo) 242 .setupFragmentOutputState(renderPass, 0u, DE_NULL, &multisampleStateCreateInfo) 243 .setMonolithicPipelineLayout(pipelineLayout) 244 .buildPipeline(); 245} 246 247tcu::TestStatus MultisampleRenderAreaTestInstance::iterate (void) 248{ 249 const InstanceInterface& vki = m_context.getInstanceInterface(); 250 const DeviceInterface& vk = m_context.getDeviceInterface(); 251 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 252 const VkDevice device = m_context.getDevice(); 253 Allocator& allocator = m_context.getDefaultAllocator(); 254 const VkQueue queue = m_context.getUniversalQueue(); 255 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 256 const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 257 258 const ShaderWrapper vertexModule (ShaderWrapper(vk, device, m_context.getBinaryCollection().get("vert"), 0u)); 259 const ShaderWrapper fragmentModule (ShaderWrapper(vk, device, m_context.getBinaryCollection().get("frag"), 0u)); 260 261 const Unique<VkImage> colorImage (makeImage(vk, device, makeImageCreateInfo(m_framebufferSize, m_sampleCount))); 262 const UniquePtr<Allocation> colorImageAlloc (bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any)); 263 const Unique<VkImageView> colorImageView (makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, colorSubresourceRange)); 264 265 const Unique<VkImage> resolveColorImage (makeImage(vk, device, makeImageCreateInfo(m_framebufferSize, 1u))); 266 const UniquePtr<Allocation> resolveColorImageAlloc (bindImage(vk, device, allocator, *resolveColorImage, MemoryRequirement::Any)); 267 const Unique<VkImageView> resolveColorImageView (makeImageView(vk, device, *resolveColorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, colorSubresourceRange)); 268 269 const VkImage images[] = { *colorImage, *resolveColorImage }; 270 const VkImageView attachmentImages[] = { *colorImageView, *resolveColorImageView }; 271 const deUint32 numUsedAttachmentImages = DE_LENGTH_OF_ARRAY(attachmentImages); 272 273 const VkDeviceSize colorBufferSizeBytes = tcu::getPixelSize(mapVkFormat(m_colorFormat)) * m_framebufferSize.x() * m_framebufferSize.y(); 274 const Unique<VkBuffer> colorBufferResults (makeBuffer(vk, device, colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT)); 275 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBufferResults, MemoryRequirement::HostVisible)); 276 277 RenderPassWrapper renderPassOne (makeRenderPass(vk, device, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED)); 278 RenderPassWrapper renderPassTwo (makeRenderPass(vk, device, m_colorFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 279 renderPassOne.createFramebuffer(vk, device, numUsedAttachmentImages, images, attachmentImages, m_framebufferSize.x(), m_framebufferSize.y()); 280 renderPassTwo.createFramebuffer(vk, device, numUsedAttachmentImages, images, attachmentImages, m_framebufferSize.x(), m_framebufferSize.y()); 281 282 const PipelineLayoutWrapper pipelineLayout (m_pipelineConstructionType, vk, device); 283 GraphicsPipelineWrapper graphicsPipeline {vki, vk, physicalDevice, device, m_context.getDeviceExtensions(), m_pipelineConstructionType}; 284 285 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 286 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 287 288 // Main vertex buffer 289 const deUint32 numVertices = 6; 290 const VkDeviceSize vertexBufferSizeBytes = 256; 291 const Unique<VkBuffer> vertexBuffer (makeBuffer(vk, device, vertexBufferSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)); 292 const UniquePtr<Allocation> vertexBufferAlloc (bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible)); 293 294 preparePipelineWrapper(graphicsPipeline, pipelineLayout, *renderPassOne, vertexModule, fragmentModule, m_framebufferSize); 295 296 { 297 tcu::Vec4* const pVertices = reinterpret_cast<tcu::Vec4*>(vertexBufferAlloc->getHostPtr()); 298 299 // The shapes should fit just and just inside the renderArea. 300 if (m_testShape == TestShape::SHAPE_RECTANGLE) 301 { 302 float size = 0.5f; 303 304 pVertices[0] = tcu::Vec4(size, -size, 0.0f, 1.0f); 305 pVertices[1] = tcu::Vec4(-size, -size, 0.0f, 1.0f); 306 pVertices[2] = tcu::Vec4(-size, size, 0.0f, 1.0f); 307 308 pVertices[3] = tcu::Vec4(-size, size, 0.0f, 1.0f); 309 pVertices[4] = tcu::Vec4(size, size, 0.0f, 1.0f); 310 pVertices[5] = tcu::Vec4(size, -size, 0.0f, 1.0f); 311 } 312 313 if (m_testShape == TestShape::SHAPE_DIAMOND) 314 { 315 float size = 0.5f; 316 317 pVertices[0] = tcu::Vec4( size, 0.0f, 0.0f, 1.0f); 318 pVertices[1] = tcu::Vec4(-0.0f, -size, 0.0f, 1.0f); 319 pVertices[2] = tcu::Vec4(-size, 0.0f, 0.0f, 1.0f); 320 321 pVertices[3] = tcu::Vec4( size, 0.0f, 0.0f, 1.0f); 322 pVertices[4] = tcu::Vec4(-size, 0.0f, 0.0f, 1.0f); 323 pVertices[5] = tcu::Vec4(-0.0f, size, 0.0f, 1.0f); 324 } 325 326 if (m_testShape == TestShape::SHAPE_PARALLELOGRAM) 327 { 328 float size = 0.3125f; 329 330 pVertices[0] = tcu::Vec4(size, -size, 0.0f, 1.0f); 331 pVertices[1] = tcu::Vec4(-0.5f, -size, 0.0f, 1.0f); 332 pVertices[2] = tcu::Vec4(-size, size, 0.0f, 1.0f); 333 334 pVertices[3] = tcu::Vec4(-size, size, 0.0f, 1.0f); 335 pVertices[4] = tcu::Vec4(0.5f, size, 0.0f, 1.0f); 336 pVertices[5] = tcu::Vec4(size, -size, 0.0f, 1.0f); 337 } 338 339 flushAlloc(vk, device, *vertexBufferAlloc); 340 } 341 342 const VkDeviceSize vertexBufferOffset = 0ull; 343 344 const VkRect2D testRenderArea = 345 { 346 makeOffset2D(m_framebufferSize.x() / 4u, m_framebufferSize.x() / 4u), 347 makeExtent2D(m_framebufferSize.x() / 2u, m_framebufferSize.y() / 2u), 348 }; 349 350 const std::vector<VkClearValue> clearValuesFullArea = { makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)), makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)) }; 351 const std::vector<VkClearValue> clearValuesTestArea = { makeClearValueColor(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)), makeClearValueColor(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)) }; 352 353 beginCommandBuffer(vk, *commandBuffer); 354 355 const VkRect2D fullRenderArea = 356 { 357 makeOffset2D(0u, 0u), 358 makeExtent2D(m_framebufferSize.x(), m_framebufferSize.y()), 359 }; 360 361 // Clear whole render area with red color. 362 renderPassOne.begin(vk, *commandBuffer, fullRenderArea, static_cast<deUint32>(clearValuesFullArea.size()), clearValuesFullArea.data()); 363 renderPassTwo.end(vk, *commandBuffer); 364 365 // Draw shape when render area size is halved. 366 renderPassTwo.begin(vk, *commandBuffer, testRenderArea, static_cast<deUint32>(clearValuesTestArea.size()), clearValuesTestArea.data()); 367 vk.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset); 368 graphicsPipeline.bind(*commandBuffer); 369 vk.cmdDraw(*commandBuffer, numVertices, 1u, 0u, 0u); 370 renderPassTwo.end(vk, *commandBuffer); 371 372 copyImageToBuffer(vk, *commandBuffer, *resolveColorImage, *colorBufferResults, m_framebufferSize, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); 373 374 endCommandBuffer(vk, *commandBuffer); 375 submitCommandsAndWait(vk, device, queue, *commandBuffer); 376 377 // Verify color output 378 { 379 invalidateAlloc(vk, device, *colorBufferAlloc); 380 381 tcu::TestLog& log = m_context.getTestContext().getLog(); 382 const Unique<VkBuffer> testBufferResults (makeBuffer(vk, device, colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT)); 383 tcu::ConstPixelBufferAccess imageAccess (mapVkFormat(m_colorFormat), m_framebufferSize.x(), m_framebufferSize.y(), 1, colorBufferAlloc->getHostPtr()); 384 385 // Color check for rendered shape. Shape color is yellow. 386 if (imageAccess.getPixel(m_framebufferSize.x() / 2, m_framebufferSize.y() / 2) != tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f)) 387 { 388 log << tcu::TestLog::Image("color0", "Rendered image", imageAccess); 389 return tcu::TestStatus::fail("Pixel check failed: shape color"); 390 } 391 392 // Color check for the second render area. Clear color should be green. 393 if (m_testShape != TestShape::SHAPE_RECTANGLE) // In this case the shape has covered the whole render area. 394 { 395 if (imageAccess.getPixel(m_framebufferSize.x() / 4 + 1, m_framebufferSize.y() / 4 + 1) != tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)) 396 { 397 log << tcu::TestLog::Image("color0", "Rendered image", imageAccess); 398 return tcu::TestStatus::fail("Pixel check failed inside the render area"); 399 } 400 } 401 402 // Color check for possible overflowed multisample pixels outside of the second render area. 403 // Clear color after the first beginRenderPass should be red. 404 const int minValue = m_framebufferSize.y() / 4 - 1; 405 const int maxValue = m_framebufferSize.y() - m_framebufferSize.y() / 4; 406 407 for (int y = 0; y < m_framebufferSize.y(); y++) 408 { 409 for (int x = 0; x < m_framebufferSize.x(); x++) 410 { 411 if (!(x > minValue && y > minValue && x < maxValue && y < maxValue)) 412 { 413 if (imageAccess.getPixel(x, y) != tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)) 414 { 415 log << tcu::TestLog::Message << "Incorrect color value " << imageAccess.getPixel(x, y) << " at location (" << x << ", " << y << ")" << tcu::TestLog::EndMessage; 416 log << tcu::TestLog::Image("color0", "Rendered image", imageAccess); 417 return tcu::TestStatus::fail("Pixel check failed outside the render area"); 418 } 419 } 420 } 421 } 422 } 423 424 return tcu::TestStatus::pass("Success"); 425} 426 427class MultisampleRenderAreaTest : public TestCase 428{ 429public: 430 MultisampleRenderAreaTest (tcu::TestContext& testCtx, 431 const std::string name, 432 const PipelineConstructionType pipelineConstructionType, 433 const deUint32 sampleCount, 434 const tcu::IVec2 framebufferSize, 435 const TestShape testShape, 436 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM) 437 : TestCase(testCtx, name) 438 , m_pipelineConstructionType (pipelineConstructionType) 439 , m_sampleCount (sampleCount) 440 , m_framebufferSize (framebufferSize) 441 , m_testShape (testShape) 442 , m_colorFormat (colorFormat) 443 {} 444 445 void initPrograms (SourceCollections& programCollection) const; 446 TestInstance* createInstance (Context& context) const; 447 virtual void checkSupport (Context& context) const; 448 449private: 450 451 const PipelineConstructionType m_pipelineConstructionType; 452 const deUint32 m_sampleCount; 453 const tcu::IVec2 m_framebufferSize; 454 const TestShape m_testShape; 455 const VkFormat m_colorFormat; 456}; 457 458void MultisampleRenderAreaTest::initPrograms(SourceCollections& programCollection) const 459{ 460 // Vertex shader 461 { 462 std::ostringstream src; 463 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 464 << "\n" 465 << "layout(location = 0) in vec4 position;\n" 466 << "\n" 467 << "void main (void)\n" 468 << "{\n" 469 << " gl_Position = position;\n" 470 << "}\n"; 471 472 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); 473 } 474 475 // Fragment shader 476 { 477 std::ostringstream frg; 478 frg << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 479 << "\n" 480 << "layout(location = 0) out vec4 fragColor;\n" 481 << "\n" 482 << "void main (void)\n" 483 << "{\n" 484 << " fragColor = vec4(1.0, 1.0, 0.0, 1.0);\n" 485 << "}\n"; 486 487 programCollection.glslSources.add("frag") << glu::FragmentSource(frg.str()); 488 } 489} 490 491TestInstance* MultisampleRenderAreaTest::createInstance(Context& context) const 492{ 493 return new MultisampleRenderAreaTestInstance(context, m_pipelineConstructionType, m_sampleCount, m_framebufferSize, m_testShape, m_colorFormat); 494} 495 496void MultisampleRenderAreaTest::checkSupport(Context& context) const 497{ 498 // Check support for MSAA image format used in the test. 499 const InstanceInterface& vki = context.getInstanceInterface(); 500 const VkPhysicalDevice physDevice = context.getPhysicalDevice(); 501 502 VkImageFormatProperties formatProperties; 503 504 vki.getPhysicalDeviceImageFormatProperties (physDevice, m_colorFormat, 505 VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, 506 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 507 0u, &formatProperties); 508 509 if ((formatProperties.sampleCounts & m_sampleCount) == 0) 510 TCU_THROW(NotSupportedError, "Format does not support this number of samples"); 511 512 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType); 513} 514 515} // anonymous 516 517tcu::TestCaseGroup* createMultisampleResolveRenderpassRenderAreaTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType) 518{ 519 // resolving multisample image tests 520 de::MovePtr<tcu::TestCaseGroup> testGroupResolve(new tcu::TestCaseGroup(testCtx, "resolve")); 521 522 de::MovePtr<tcu::TestCaseGroup> testGroupRenderArea(new tcu::TestCaseGroup(testCtx, "renderpass_renderarea", "renderpass render area tests")); 523 524 static const struct 525 { 526 std::string shapeName; 527 TestShape testShape; 528 } shapes[] = 529 { 530 { "rectangle", TestShape::SHAPE_RECTANGLE }, 531 { "diamond", TestShape::SHAPE_DIAMOND }, 532 { "parallelogram", TestShape::SHAPE_PARALLELOGRAM } 533 }; 534 535 static const struct 536 { 537 std::string caseName; 538 const deUint32 sampleCount; 539 } cases[] = 540 { 541 { "samples_2", 2u, }, 542 { "samples_4", 4u, }, 543 { "samples_8", 8u, }, 544 { "samples_16", 16u }, 545 }; 546 547 for (const auto& testShape : shapes) 548 { 549 for (const auto& testCase : cases) 550 { 551 testGroupRenderArea->addChild(new MultisampleRenderAreaTest(testCtx, testShape.shapeName + "_" + testCase.caseName, pipelineConstructionType, testCase.sampleCount, tcu::IVec2(32, 32), testShape.testShape)); 552 } 553 } 554 555 testGroupResolve->addChild(testGroupRenderArea.release()); 556 557 return testGroupResolve.release(); 558} 559 560} // pipeline 561} // vkt 562