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
38 namespace vkt
39 {
40 namespace pipeline
41 {
42 namespace multisample
43 {
44
45 using namespace vk;
46
iterate(void)47 tcu::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