1/*------------------------------------------------------------------------ 2* Vulkan Conformance Tests 3* ------------------------ 4* 5* Copyright (c) 2016 The Khronos Group Inc. 6* Copyright (c) 2023 LunarG, Inc. 7* Copyright (c) 2023 Nintendo 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 vktPipelineMultisampleBaseResolve.cpp 23* \brief Base class for tests that check results of multisample resolve 24*//*--------------------------------------------------------------------*/ 25 26#include "vktPipelineMultisampleBaseResolve.hpp" 27#include "vktPipelineMakeUtil.hpp" 28#include "vkBuilderUtil.hpp" 29#include "vkBarrierUtil.hpp" 30#include "vkTypeUtil.hpp" 31#include "vkCmdUtil.hpp" 32#include "vkObjUtil.hpp" 33#include "vkBufferWithMemory.hpp" 34#include "vkImageWithMemory.hpp" 35#include "tcuTestLog.hpp" 36#include <vector> 37 38namespace vkt 39{ 40namespace pipeline 41{ 42namespace multisample 43{ 44 45using namespace vk; 46 47tcu::TestStatus MSInstanceBaseResolve::iterate (void) 48{ 49 // cases creating this tests are defined using templates and we do not have easy access 50 // to image type - to do this check in checkSupport bigger reffactoring would be needed 51#ifndef CTS_USES_VULKANSC 52 if (m_context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && 53 !m_context.getPortabilitySubsetFeatures().multisampleArrayImage && 54 (m_imageType == IMAGE_TYPE_2D_ARRAY) && 55 (m_imageMSParams.numSamples != VK_SAMPLE_COUNT_1_BIT) && 56 (m_imageMSParams.imageSize.z() != 1)) 57 { 58 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Implementation does not support image array with multiple samples per texel"); 59 } 60#endif // CTS_USES_VULKANSC 61 62 const InstanceInterface& instance = m_context.getInstanceInterface(); 63 const DeviceInterface& deviceInterface = m_context.getDeviceInterface(); 64 const VkDevice device = m_context.getDevice(); 65 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 66 const VkPhysicalDeviceFeatures& features = m_context.getDeviceFeatures(); 67 Allocator& allocator = m_context.getDefaultAllocator(); 68 const VkQueue queue = m_context.getUniversalQueue(); 69 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 70 const bool usePushConstants = (m_imageMSParams.componentData.source == ComponentSource::PUSH_CONSTANT); 71 const deUint32 pushConstantSize = static_cast<deUint32>(sizeof(decltype(m_imageMSParams.componentData.index))); 72 73 VkImageCreateInfo imageMSInfo; 74 VkImageCreateInfo imageRSInfo; 75 76 // Check if image size does not exceed device limits 77 validateImageSize(instance, physicalDevice, m_imageType, m_imageMSParams.imageSize); 78 79 // Check if device supports image format as color attachment 80 validateImageFeatureFlags(instance, physicalDevice, mapTextureFormat(m_imageFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); 81 82 imageMSInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 83 imageMSInfo.pNext = DE_NULL; 84 imageMSInfo.flags = 0u; 85 imageMSInfo.imageType = mapImageType(m_imageType); 86 imageMSInfo.format = mapTextureFormat(m_imageFormat); 87 imageMSInfo.extent = makeExtent3D(getLayerSize(m_imageType, m_imageMSParams.imageSize)); 88 imageMSInfo.arrayLayers = getNumLayers(m_imageType, m_imageMSParams.imageSize); 89 imageMSInfo.mipLevels = 1u; 90 imageMSInfo.samples = m_imageMSParams.numSamples; 91 imageMSInfo.tiling = VK_IMAGE_TILING_OPTIMAL; 92 imageMSInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 93 imageMSInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 94 imageMSInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 95 imageMSInfo.queueFamilyIndexCount = 0u; 96 imageMSInfo.pQueueFamilyIndices = DE_NULL; 97 98 if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY) 99 { 100 imageMSInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; 101 } 102 103 validateImageInfo(instance, physicalDevice, imageMSInfo); 104 105 const de::UniquePtr<ImageWithMemory> imageMS(new ImageWithMemory(deviceInterface, device, allocator, imageMSInfo, MemoryRequirement::Any)); 106 107 imageRSInfo = imageMSInfo; 108 imageRSInfo.samples = VK_SAMPLE_COUNT_1_BIT; 109 110 validateImageInfo(instance, physicalDevice, imageRSInfo); 111 112 const de::UniquePtr<ImageWithMemory> imageRS(new ImageWithMemory(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any)); 113 114 // Create render pass 115 const VkAttachmentDescription attachmentMSDesc = 116 { 117 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags; 118 imageMSInfo.format, // VkFormat format; 119 imageMSInfo.samples, // VkSampleCountFlagBits samples; 120 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 121 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 122 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 123 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 124 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 125 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 126 }; 127 128 const VkAttachmentDescription attachmentRSDesc = 129 { 130 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags; 131 imageRSInfo.format, // VkFormat format; 132 imageRSInfo.samples, // VkSampleCountFlagBits samples; 133 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 134 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 135 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 136 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 137 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 138 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 139 }; 140 141 const VkAttachmentDescription attachments[] = { attachmentMSDesc, attachmentRSDesc }; 142 143 const VkAttachmentReference attachmentMSRef = 144 { 145 0u, // deUint32 attachment; 146 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 147 }; 148 149 const VkAttachmentReference attachmentRSRef = 150 { 151 1u, // deUint32 attachment; 152 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 153 }; 154 155 const VkAttachmentReference* resolveAttachment = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? DE_NULL : &attachmentRSRef; 156 157 const VkSubpassDescription subpassDescription = 158 { 159 (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags; 160 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 161 0u, // deUint32 inputAttachmentCount; 162 DE_NULL, // const VkAttachmentReference* pInputAttachments; 163 1u, // deUint32 colorAttachmentCount; 164 &attachmentMSRef, // const VkAttachmentReference* pColorAttachments; 165 resolveAttachment, // const VkAttachmentReference* pResolveAttachments; 166 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 167 0u, // deUint32 preserveAttachmentCount; 168 DE_NULL // const deUint32* pPreserveAttachments; 169 }; 170 171 const VkRenderPassCreateInfo renderPassInfo = 172 { 173 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 174 DE_NULL, // const void* pNext; 175 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; 176 2u, // deUint32 attachmentCount; 177 attachments, // const VkAttachmentDescription* pAttachments; 178 1u, // deUint32 subpassCount; 179 &subpassDescription, // const VkSubpassDescription* pSubpasses; 180 0u, // deUint32 dependencyCount; 181 DE_NULL // const VkSubpassDependency* pDependencies; 182 }; 183 184 RenderPassWrapper renderPass (m_imageMSParams.pipelineConstructionType, deviceInterface, device, &renderPassInfo); 185 186 const VkImageSubresourceRange fullImageRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageMSInfo.mipLevels, 0u, imageMSInfo.arrayLayers); 187 188 // Create color attachments image views 189 const Unique<VkImageView> imageMSView(makeImageView(deviceInterface, device, **imageMS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange)); 190 const Unique<VkImageView> imageRSView(makeImageView(deviceInterface, device, **imageRS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange)); 191 192 std::vector<VkImage> images = { **imageMS, **imageRS}; 193 const VkImageView attachmentsViews[] = { *imageMSView, *imageRSView }; 194 195 // Create framebuffer 196 const VkFramebufferCreateInfo framebufferInfo = 197 { 198 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 199 DE_NULL, // const void* pNext; 200 (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags; 201 *renderPass, // VkRenderPass renderPass; 202 2u, // uint32_t attachmentCount; 203 attachmentsViews, // const VkImageView* pAttachments; 204 imageMSInfo.extent.width, // uint32_t width; 205 imageMSInfo.extent.height, // uint32_t height; 206 imageMSInfo.arrayLayers, // uint32_t layers; 207 }; 208 209 renderPass.createFramebuffer(deviceInterface, device, &framebufferInfo, images); 210 211 std::vector<vk::VkPushConstantRange> pushConstantRanges; 212 213 if (usePushConstants) 214 { 215 const vk::VkPushConstantRange pushConstantRange = 216 { 217 vk::VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags; 218 0u, // deUint32 offset; 219 pushConstantSize, // deUint32 size; 220 }; 221 pushConstantRanges.push_back(pushConstantRange); 222 } 223 224 // Create pipeline layout 225 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 226 { 227 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 228 DE_NULL, // const void* pNext; 229 (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags; 230 0u, // deUint32 setLayoutCount; 231 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 232 static_cast<deUint32>(pushConstantRanges.size()), // deUint32 pushConstantRangeCount; 233 (pushConstantRanges.empty() ? nullptr : pushConstantRanges.data()), // const VkPushConstantRange* pPushConstantRanges; 234 }; 235 236 const PipelineLayoutWrapper pipelineLayout(m_imageMSParams.pipelineConstructionType, deviceInterface, device, &pipelineLayoutParams); 237 238 // Create vertex attributes data 239 const VertexDataDesc vertexDataDesc = getVertexDataDescripton(); 240 241 de::SharedPtr<BufferWithMemory> vertexBuffer = de::SharedPtr<BufferWithMemory>(new BufferWithMemory(deviceInterface, device, allocator, makeBufferCreateInfo(vertexDataDesc.dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible)); 242 const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation(); 243 244 uploadVertexData(vertexBufferAllocation, vertexDataDesc); 245 246 flushAlloc(deviceInterface, device, vertexBufferAllocation); 247 248 const VkVertexInputBindingDescription vertexBinding = 249 { 250 0u, // deUint32 binding; 251 vertexDataDesc.dataStride, // deUint32 stride; 252 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate; 253 }; 254 255 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = 256 { 257 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 258 DE_NULL, // const void* pNext; 259 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags; 260 1u, // uint32_t vertexBindingDescriptionCount; 261 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 262 static_cast<deUint32>(vertexDataDesc.vertexAttribDescVec.size()), // uint32_t vertexAttributeDescriptionCount; 263 dataPointer(vertexDataDesc.vertexAttribDescVec), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 264 }; 265 266 const std::vector<VkViewport> viewports { makeViewport(imageMSInfo.extent) }; 267 const std::vector<VkRect2D> scissors { makeRect2D(imageMSInfo.extent) }; 268 269 const VkPipelineMultisampleStateCreateInfo multisampleStateInfo 270 { 271 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 272 DE_NULL, // const void* pNext; 273 (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags; 274 imageMSInfo.samples, // VkSampleCountFlagBits rasterizationSamples; 275 features.sampleRateShading, // VkBool32 sampleShadingEnable; 276 1.0f, // float minSampleShading; 277 DE_NULL, // const VkSampleMask* pSampleMask; 278 VK_FALSE, // VkBool32 alphaToCoverageEnable; 279 VK_FALSE, // VkBool32 alphaToOneEnable; 280 }; 281 282 const ShaderWrapper vsModule(ShaderWrapper(deviceInterface, device, m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0)); 283 const ShaderWrapper fsModule(ShaderWrapper(deviceInterface, device, m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0)); 284 285 // Create graphics pipeline 286 GraphicsPipelineWrapper graphicsPipeline(instance, deviceInterface, physicalDevice, device, m_context.getDeviceExtensions(), m_imageMSParams.pipelineConstructionType); 287 graphicsPipeline.setDefaultRasterizationState() 288 .setDefaultColorBlendState() 289 .setDefaultDepthStencilState() 290 .setDefaultTopology(vertexDataDesc.primitiveTopology) 291 .setupVertexInputState(&vertexInputStateInfo) 292 .setupPreRasterizationShaderState(viewports, 293 scissors, 294 pipelineLayout, 295 *renderPass, 296 0u, 297 vsModule) 298 .setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fsModule, DE_NULL, &multisampleStateInfo) 299 .setupFragmentOutputState(*renderPass, 0, DE_NULL, &multisampleStateInfo) 300 .setMonolithicPipelineLayout(pipelineLayout) 301 .buildPipeline(); 302 303 // Create command buffer for compute and transfer oparations 304 const Unique<VkCommandPool> commandPool(createCommandPool(deviceInterface, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 305 const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, device, *commandPool)); 306 307 // Start recording commands 308 beginCommandBuffer(deviceInterface, *commandBuffer); 309 310 { 311 VkImageMemoryBarrier imageOutputAttachmentBarriers[2]; 312 313 imageOutputAttachmentBarriers[0] = makeImageMemoryBarrier 314 ( 315 0u, 316 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 317 VK_IMAGE_LAYOUT_UNDEFINED, 318 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 319 **imageMS, 320 fullImageRange 321 ); 322 323 imageOutputAttachmentBarriers[1] = makeImageMemoryBarrier 324 ( 325 0u, 326 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 327 VK_IMAGE_LAYOUT_UNDEFINED, 328 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 329 **imageRS, 330 fullImageRange 331 ); 332 333 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputAttachmentBarriers); 334 } 335 336 { 337 const VkDeviceSize vertexStartOffset = 0u; 338 339 std::vector<VkClearValue> clearValues; 340 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))); 341 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))); 342 343 renderPass.begin(deviceInterface, *commandBuffer, makeRect2D(0, 0, imageMSInfo.extent.width, imageMSInfo.extent.height), (deUint32)clearValues.size(), &clearValues[0]); 344 345 // Bind graphics pipeline 346 graphicsPipeline.bind(*commandBuffer); 347 348 // Bind vertex buffer 349 deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexStartOffset); 350 351 // Push constants. 352 if (usePushConstants) 353 deviceInterface.cmdPushConstants(*commandBuffer, *pipelineLayout, vk::VK_SHADER_STAGE_ALL, 0u, pushConstantSize, &m_imageMSParams.componentData.index); 354 355 // Draw full screen quad 356 deviceInterface.cmdDraw(*commandBuffer, vertexDataDesc.verticesCount, 1u, 0u, 0u); 357 358 // End render pass 359 renderPass.end(deviceInterface, *commandBuffer); 360 } 361 362 const VkImage sourceImage = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? **imageMS : **imageRS; 363 364 { 365 const VkImageMemoryBarrier imageTransferSrcBarrier = makeImageMemoryBarrier 366 ( 367 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 368 VK_ACCESS_TRANSFER_READ_BIT, 369 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 370 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 371 sourceImage, 372 fullImageRange 373 ); 374 375 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageTransferSrcBarrier); 376 } 377 378 // Copy data from resolve image to buffer 379 const deUint32 imageRSSizeInBytes = getImageSizeInBytes(imageRSInfo.extent, imageRSInfo.arrayLayers, m_imageFormat, imageRSInfo.mipLevels); 380 381 const VkBufferCreateInfo bufferRSInfo = makeBufferCreateInfo(imageRSSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT); 382 const de::UniquePtr<BufferWithMemory> bufferRS(new BufferWithMemory(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible)); 383 384 { 385 const VkBufferImageCopy bufferImageCopy = 386 { 387 0u, // VkDeviceSize bufferOffset; 388 0u, // deUint32 bufferRowLength; 389 0u, // deUint32 bufferImageHeight; 390 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), // VkImageSubresourceLayers imageSubresource; 391 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 392 imageRSInfo.extent, // VkExtent3D imageExtent; 393 }; 394 395 deviceInterface.cmdCopyImageToBuffer(*commandBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferRS->get(), 1u, &bufferImageCopy); 396 } 397 398 { 399 const VkBufferMemoryBarrier bufferRSHostReadBarrier = makeBufferMemoryBarrier 400 ( 401 VK_ACCESS_TRANSFER_WRITE_BIT, 402 VK_ACCESS_HOST_READ_BIT, 403 bufferRS->get(), 404 0u, 405 imageRSSizeInBytes 406 ); 407 408 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferRSHostReadBarrier, 0u, DE_NULL); 409 } 410 411 // End recording commands 412 endCommandBuffer(deviceInterface, *commandBuffer); 413 414 // Submit commands for execution and wait for completion 415 submitCommandsAndWait(deviceInterface, device, queue, *commandBuffer); 416 417 // Retrieve data from buffer to host memory 418 const Allocation& bufferRSAllocation = bufferRS->getAllocation(); 419 420 invalidateAlloc(deviceInterface, device, bufferRSAllocation); 421 422 const tcu::ConstPixelBufferAccess bufferRSData (m_imageFormat, 423 imageRSInfo.extent.width, 424 imageRSInfo.extent.height, 425 imageRSInfo.extent.depth * imageRSInfo.arrayLayers, 426 bufferRSAllocation.getHostPtr()); 427 428 std::stringstream imageName; 429 imageName << getImageTypeName(m_imageType) << "_" << bufferRSData.getWidth() << "_" << bufferRSData.getHeight() << "_" << bufferRSData.getDepth() << std::endl; 430 431 m_context.getTestContext().getLog() 432 << tcu::TestLog::Section(imageName.str(), imageName.str()) 433 << tcu::LogImage("image", "", bufferRSData) 434 << tcu::TestLog::EndSection; 435 436 return verifyImageData(imageRSInfo, bufferRSData); 437} 438 439} // multisample 440} // pipeline 441} // vkt 442