• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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