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