Home | History | Annotate | Download | only in pipeline
      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 "vkQueryUtil.hpp"
     28 #include "tcuTestLog.hpp"
     29 #include <vector>
     30 
     31 namespace vkt
     32 {
     33 namespace pipeline
     34 {
     35 namespace multisample
     36 {
     37 
     38 using namespace vk;
     39 
     40 tcu::TestStatus MSInstanceBaseResolve::iterate (void)
     41 {
     42 	const InstanceInterface&		instance			= m_context.getInstanceInterface();
     43 	const DeviceInterface&			deviceInterface		= m_context.getDeviceInterface();
     44 	const VkDevice					device				= m_context.getDevice();
     45 	const VkPhysicalDevice			physicalDevice		= m_context.getPhysicalDevice();
     46 	const VkPhysicalDeviceFeatures&	features			= m_context.getDeviceFeatures();
     47 	Allocator&						allocator			= m_context.getDefaultAllocator();
     48 	const VkQueue					queue				= m_context.getUniversalQueue();
     49 	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
     50 
     51 	VkImageCreateInfo				imageMSInfo;
     52 	VkImageCreateInfo				imageRSInfo;
     53 
     54 	// Check if image size does not exceed device limits
     55 	validateImageSize(instance, physicalDevice, m_imageType, m_imageMSParams.imageSize);
     56 
     57 	// Check if device supports image format as color attachment
     58 	validateImageFeatureFlags(instance, physicalDevice, mapTextureFormat(m_imageFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
     59 
     60 	imageMSInfo.sType					= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
     61 	imageMSInfo.pNext					= DE_NULL;
     62 	imageMSInfo.flags					= 0u;
     63 	imageMSInfo.imageType				= mapImageType(m_imageType);
     64 	imageMSInfo.format					= mapTextureFormat(m_imageFormat);
     65 	imageMSInfo.extent					= makeExtent3D(getLayerSize(m_imageType, m_imageMSParams.imageSize));
     66 	imageMSInfo.arrayLayers				= getNumLayers(m_imageType, m_imageMSParams.imageSize);
     67 	imageMSInfo.mipLevels				= 1u;
     68 	imageMSInfo.samples					= m_imageMSParams.numSamples;
     69 	imageMSInfo.tiling					= VK_IMAGE_TILING_OPTIMAL;
     70 	imageMSInfo.initialLayout			= VK_IMAGE_LAYOUT_UNDEFINED;
     71 	imageMSInfo.usage					= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
     72 	imageMSInfo.sharingMode				= VK_SHARING_MODE_EXCLUSIVE;
     73 	imageMSInfo.queueFamilyIndexCount	= 0u;
     74 	imageMSInfo.pQueueFamilyIndices		= DE_NULL;
     75 
     76 	if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
     77 	{
     78 		imageMSInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
     79 	}
     80 
     81 	validateImageInfo(instance, physicalDevice, imageMSInfo);
     82 
     83 	const de::UniquePtr<Image> imageMS(new Image(deviceInterface, device, allocator, imageMSInfo, MemoryRequirement::Any));
     84 
     85 	imageRSInfo			= imageMSInfo;
     86 	imageRSInfo.samples	= VK_SAMPLE_COUNT_1_BIT;
     87 
     88 	validateImageInfo(instance, physicalDevice, imageRSInfo);
     89 
     90 	const de::UniquePtr<Image> imageRS(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
     91 
     92 	// Create render pass
     93 	const VkAttachmentDescription attachmentMSDesc =
     94 	{
     95 		(VkAttachmentDescriptionFlags)0u,			// VkAttachmentDescriptionFlags		flags;
     96 		imageMSInfo.format,							// VkFormat							format;
     97 		imageMSInfo.samples,						// VkSampleCountFlagBits			samples;
     98 		VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp;
     99 		VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
    100 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
    101 		VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
    102 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout;
    103 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout;
    104 	};
    105 
    106 	const VkAttachmentDescription attachmentRSDesc =
    107 	{
    108 		(VkAttachmentDescriptionFlags)0u,			// VkAttachmentDescriptionFlags		flags;
    109 		imageRSInfo.format,							// VkFormat							format;
    110 		imageRSInfo.samples,						// VkSampleCountFlagBits			samples;
    111 		VK_ATTACHMENT_LOAD_OP_CLEAR,			// VkAttachmentLoadOp				loadOp;
    112 		VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
    113 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
    114 		VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
    115 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout;
    116 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout;
    117 	};
    118 
    119 	const VkAttachmentDescription attachments[] = { attachmentMSDesc, attachmentRSDesc };
    120 
    121 	const VkAttachmentReference attachmentMSRef =
    122 	{
    123 		0u,											// deUint32			attachment;
    124 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
    125 	};
    126 
    127 	const VkAttachmentReference attachmentRSRef =
    128 	{
    129 		1u,											// deUint32			attachment;
    130 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
    131 	};
    132 
    133 	const VkAttachmentReference* resolveAttachment = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? DE_NULL : &attachmentRSRef;
    134 
    135 	const VkSubpassDescription subpassDescription =
    136 	{
    137 		(VkSubpassDescriptionFlags)0u,						// VkSubpassDescriptionFlags		flags;
    138 		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
    139 		0u,													// deUint32							inputAttachmentCount;
    140 		DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
    141 		1u,													// deUint32							colorAttachmentCount;
    142 		&attachmentMSRef,									// const VkAttachmentReference*		pColorAttachments;
    143 		resolveAttachment,								// const VkAttachmentReference*		pResolveAttachments;
    144 		DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
    145 		0u,													// deUint32							preserveAttachmentCount;
    146 		DE_NULL												// const deUint32*					pPreserveAttachments;
    147 	};
    148 
    149 	const VkRenderPassCreateInfo renderPassInfo =
    150 	{
    151 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
    152 		DE_NULL,											// const void*						pNext;
    153 		(VkRenderPassCreateFlags)0u,						// VkRenderPassCreateFlags			flags;
    154 		2u,													// deUint32							attachmentCount;
    155 		attachments,										// const VkAttachmentDescription*	pAttachments;
    156 		1u,													// deUint32							subpassCount;
    157 		&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
    158 		0u,													// deUint32							dependencyCount;
    159 		DE_NULL												// const VkSubpassDependency*		pDependencies;
    160 	};
    161 
    162 	const Unique<VkRenderPass> renderPass(createRenderPass(deviceInterface, device, &renderPassInfo));
    163 
    164 	const VkImageSubresourceRange fullImageRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageMSInfo.mipLevels, 0u, imageMSInfo.arrayLayers);
    165 
    166 	// Create color attachments image views
    167 	const Unique<VkImageView> imageMSView(makeImageView(deviceInterface, device, **imageMS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
    168 	const Unique<VkImageView> imageRSView(makeImageView(deviceInterface, device, **imageRS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
    169 
    170 	const VkImageView attachmentsViews[] = { *imageMSView, *imageRSView };
    171 
    172 	// Create framebuffer
    173 	const VkFramebufferCreateInfo framebufferInfo =
    174 	{
    175 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType                             sType;
    176 		DE_NULL,									// const void*                                 pNext;
    177 		(VkFramebufferCreateFlags)0u,				// VkFramebufferCreateFlags                    flags;
    178 		*renderPass,								// VkRenderPass                                renderPass;
    179 		2u,											// uint32_t                                    attachmentCount;
    180 		attachmentsViews,							// const VkImageView*                          pAttachments;
    181 		imageMSInfo.extent.width,					// uint32_t                                    width;
    182 		imageMSInfo.extent.height,					// uint32_t                                    height;
    183 		imageMSInfo.arrayLayers,					// uint32_t                                    layers;
    184 	};
    185 
    186 	const Unique<VkFramebuffer> framebuffer(createFramebuffer(deviceInterface, device, &framebufferInfo));
    187 
    188 	// Create pipeline layout
    189 	const VkPipelineLayoutCreateInfo pipelineLayoutParams =
    190 	{
    191 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
    192 		DE_NULL,											// const void*						pNext;
    193 		(VkPipelineLayoutCreateFlags)0u,					// VkPipelineLayoutCreateFlags		flags;
    194 		0u,													// deUint32							setLayoutCount;
    195 		DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
    196 		0u,													// deUint32							pushConstantRangeCount;
    197 		DE_NULL,											// const VkPushConstantRange*		pPushConstantRanges;
    198 	};
    199 
    200 	const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, device, &pipelineLayoutParams));
    201 
    202 	// Create vertex attributes data
    203 	const VertexDataDesc vertexDataDesc = getVertexDataDescripton();
    204 
    205 	de::SharedPtr<Buffer> vertexBuffer = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(vertexDataDesc.dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
    206 	const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation();
    207 
    208 	uploadVertexData(vertexBufferAllocation, vertexDataDesc);
    209 
    210 	flushMappedMemoryRange(deviceInterface, device, vertexBufferAllocation.getMemory(), vertexBufferAllocation.getOffset(), VK_WHOLE_SIZE);
    211 
    212 	const VkVertexInputBindingDescription vertexBinding =
    213 	{
    214 		0u,							// deUint32				binding;
    215 		vertexDataDesc.dataStride,	// deUint32				stride;
    216 		VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputRate	inputRate;
    217 	};
    218 
    219 	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
    220 	{
    221 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,			// VkStructureType                             sType;
    222 		DE_NULL,															// const void*                                 pNext;
    223 		(VkPipelineVertexInputStateCreateFlags)0u,							// VkPipelineVertexInputStateCreateFlags       flags;
    224 		1u,																	// uint32_t                                    vertexBindingDescriptionCount;
    225 		&vertexBinding,														// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
    226 		static_cast<deUint32>(vertexDataDesc.vertexAttribDescVec.size()),	// uint32_t                                    vertexAttributeDescriptionCount;
    227 		dataPointer(vertexDataDesc.vertexAttribDescVec),					// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
    228 	};
    229 
    230 	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
    231 	{
    232 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
    233 		DE_NULL,														// const void*                                 pNext;
    234 		(VkPipelineInputAssemblyStateCreateFlags)0u,					// VkPipelineInputAssemblyStateCreateFlags     flags;
    235 		vertexDataDesc.primitiveTopology,								// VkPrimitiveTopology                         topology;
    236 		VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
    237 	};
    238 
    239 	const VkViewport viewport =
    240 	{
    241 		0.0f, 0.0f,
    242 		static_cast<float>(imageMSInfo.extent.width), static_cast<float>(imageMSInfo.extent.height),
    243 		0.0f, 1.0f
    244 	};
    245 
    246 	const VkRect2D scissor =
    247 	{
    248 		makeOffset2D(0, 0),
    249 		makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
    250 	};
    251 
    252 	const VkPipelineViewportStateCreateInfo viewportStateInfo =
    253 	{
    254 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType                             sType;
    255 		DE_NULL,														// const void*                                 pNext;
    256 		(VkPipelineViewportStateCreateFlags)0u,							// VkPipelineViewportStateCreateFlags          flags;
    257 		1u,																// uint32_t                                    viewportCount;
    258 		&viewport,														// const VkViewport*                           pViewports;
    259 		1u,																// uint32_t                                    scissorCount;
    260 		&scissor,														// const VkRect2D*                             pScissors;
    261 	};
    262 
    263 	const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
    264 	{
    265 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
    266 		DE_NULL,														// const void*                              pNext;
    267 		(VkPipelineRasterizationStateCreateFlags)0u,					// VkPipelineRasterizationStateCreateFlags  flags;
    268 		VK_FALSE,														// VkBool32                                 depthClampEnable;
    269 		VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
    270 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
    271 		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
    272 		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
    273 		VK_FALSE,														// VkBool32									depthBiasEnable;
    274 		0.0f,															// float									depthBiasConstantFactor;
    275 		0.0f,															// float									depthBiasClamp;
    276 		0.0f,															// float									depthBiasSlopeFactor;
    277 		1.0f,															// float									lineWidth;
    278 	};
    279 
    280 	const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
    281 	{
    282 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
    283 		DE_NULL,														// const void*								pNext;
    284 		(VkPipelineMultisampleStateCreateFlags)0u,						// VkPipelineMultisampleStateCreateFlags	flags;
    285 		imageMSInfo.samples,											// VkSampleCountFlagBits					rasterizationSamples;
    286 		features.sampleRateShading,										// VkBool32									sampleShadingEnable;
    287 		1.0f,															// float									minSampleShading;
    288 		DE_NULL,														// const VkSampleMask*						pSampleMask;
    289 		VK_FALSE,														// VkBool32									alphaToCoverageEnable;
    290 		VK_FALSE,														// VkBool32									alphaToOneEnable;
    291 	};
    292 
    293 	const VkStencilOpState stencilOpState = makeStencilOpState
    294 	(
    295 		VK_STENCIL_OP_KEEP,		// stencil fail
    296 		VK_STENCIL_OP_KEEP,		// depth & stencil pass
    297 		VK_STENCIL_OP_KEEP,		// depth only fail
    298 		VK_COMPARE_OP_ALWAYS,	// compare op
    299 		0u,						// compare mask
    300 		0u,						// write mask
    301 		0u						// reference
    302 	);
    303 
    304 	const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
    305 	{
    306 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType							sType;
    307 		DE_NULL,														// const void*								pNext;
    308 		(VkPipelineDepthStencilStateCreateFlags)0u,						// VkPipelineDepthStencilStateCreateFlags	flags;
    309 		VK_FALSE,														// VkBool32									depthTestEnable;
    310 		VK_FALSE,														// VkBool32									depthWriteEnable;
    311 		VK_COMPARE_OP_LESS,												// VkCompareOp								depthCompareOp;
    312 		VK_FALSE,														// VkBool32									depthBoundsTestEnable;
    313 		VK_FALSE,														// VkBool32									stencilTestEnable;
    314 		stencilOpState,													// VkStencilOpState							front;
    315 		stencilOpState,													// VkStencilOpState							back;
    316 		0.0f,															// float									minDepthBounds;
    317 		1.0f,															// float									maxDepthBounds;
    318 	};
    319 
    320 	const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
    321 
    322 	const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
    323 	{
    324 		VK_FALSE,														// VkBool32					blendEnable;
    325 		VK_BLEND_FACTOR_ONE,											// VkBlendFactor			srcColorBlendFactor;
    326 		VK_BLEND_FACTOR_ZERO,											// VkBlendFactor			dstColorBlendFactor;
    327 		VK_BLEND_OP_ADD,												// VkBlendOp				colorBlendOp;
    328 		VK_BLEND_FACTOR_ONE,											// VkBlendFactor			srcAlphaBlendFactor;
    329 		VK_BLEND_FACTOR_ZERO,											// VkBlendFactor			dstAlphaBlendFactor;
    330 		VK_BLEND_OP_ADD,												// VkBlendOp				alphaBlendOp;
    331 		colorComponentsAll,												// VkColorComponentFlags	colorWriteMask;
    332 	};
    333 
    334 	const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
    335 	{
    336 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType;
    337 		DE_NULL,														// const void*									pNext;
    338 		(VkPipelineColorBlendStateCreateFlags)0u,						// VkPipelineColorBlendStateCreateFlags			flags;
    339 		VK_FALSE,														// VkBool32										logicOpEnable;
    340 		VK_LOGIC_OP_COPY,												// VkLogicOp									logicOp;
    341 		1u,																// deUint32										attachmentCount;
    342 		&colorBlendAttachmentState,										// const VkPipelineColorBlendAttachmentState*	pAttachments;
    343 		{ 0.0f, 0.0f, 0.0f, 0.0f },										// float										blendConstants[4];
    344 	};
    345 
    346 	const Unique<VkShaderModule> vsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0));
    347 
    348 	const VkPipelineShaderStageCreateInfo vsShaderStageInfo =
    349 	{
    350 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,			// VkStructureType						sType;
    351 		DE_NULL,														// const void*							pNext;
    352 		(VkPipelineShaderStageCreateFlags)0u,							// VkPipelineShaderStageCreateFlags		flags;
    353 		VK_SHADER_STAGE_VERTEX_BIT,										// VkShaderStageFlagBits				stage;
    354 		*vsModule,														// VkShaderModule						module;
    355 		"main",															// const char*							pName;
    356 		DE_NULL,														// const VkSpecializationInfo*			pSpecializationInfo;
    357 	};
    358 
    359 	const Unique<VkShaderModule> fsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0));
    360 
    361 	const VkPipelineShaderStageCreateInfo fsShaderStageInfo =
    362 	{
    363 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,			// VkStructureType						sType;
    364 		DE_NULL,														// const void*							pNext;
    365 		(VkPipelineShaderStageCreateFlags)0u,							// VkPipelineShaderStageCreateFlags		flags;
    366 		VK_SHADER_STAGE_FRAGMENT_BIT,									// VkShaderStageFlagBits				stage;
    367 		*fsModule,														// VkShaderModule						module;
    368 		"main",															// const char*							pName;
    369 		DE_NULL,														// const VkSpecializationInfo*			pSpecializationInfo;
    370 	};
    371 
    372 	const VkPipelineShaderStageCreateInfo shaderStageInfos[] = { vsShaderStageInfo, fsShaderStageInfo };
    373 
    374 	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
    375 	{
    376 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,				// VkStructureType									sType;
    377 		DE_NULL,														// const void*										pNext;
    378 		(VkPipelineCreateFlags)0,										// VkPipelineCreateFlags							flags;
    379 		2u,																// deUint32											stageCount;
    380 		shaderStageInfos,												// const VkPipelineShaderStageCreateInfo*			pStages;
    381 		&vertexInputStateInfo,											// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
    382 		&inputAssemblyStateInfo,										// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
    383 		DE_NULL,														// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
    384 		&viewportStateInfo,												// const VkPipelineViewportStateCreateInfo*			pViewportState;
    385 		&rasterizationStateInfo,										// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
    386 		&multisampleStateInfo,											// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
    387 		&depthStencilStateInfo,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
    388 		&colorBlendStateInfo,											// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
    389 		DE_NULL,														// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
    390 		*pipelineLayout,												// VkPipelineLayout									layout;
    391 		*renderPass,													// VkRenderPass										renderPass;
    392 		0u,																// deUint32											subpass;
    393 		DE_NULL,														// VkPipeline										basePipelineHandle;
    394 		0u,																// deInt32											basePipelineIndex;
    395 	};
    396 
    397 	// Create graphics pipeline
    398 	const Unique<VkPipeline> graphicsPipeline(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfo));
    399 
    400 	// Create command buffer for compute and transfer oparations
    401 	const Unique<VkCommandPool>	  commandPool(createCommandPool(deviceInterface, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,  queueFamilyIndex));
    402 	const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, device, *commandPool));
    403 
    404 	// Start recording commands
    405 	beginCommandBuffer(deviceInterface, *commandBuffer);
    406 
    407 	{
    408 		VkImageMemoryBarrier imageOutputAttachmentBarriers[2];
    409 
    410 		imageOutputAttachmentBarriers[0] = makeImageMemoryBarrier
    411 		(
    412 			0u,
    413 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    414 			VK_IMAGE_LAYOUT_UNDEFINED,
    415 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
    416 			**imageMS,
    417 			fullImageRange
    418 		);
    419 
    420 		imageOutputAttachmentBarriers[1] = makeImageMemoryBarrier
    421 		(
    422 			0u,
    423 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    424 			VK_IMAGE_LAYOUT_UNDEFINED,
    425 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
    426 			**imageRS,
    427 			fullImageRange
    428 		);
    429 
    430 		deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputAttachmentBarriers);
    431 	}
    432 
    433 	{
    434 		const VkDeviceSize vertexStartOffset = 0u;
    435 
    436 		std::vector<VkClearValue> clearValues;
    437 		clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
    438 		clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
    439 
    440 		const vk::VkRect2D renderArea =
    441 		{
    442 			makeOffset2D(0u, 0u),
    443 			makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
    444 		};
    445 
    446 		// Begin render pass
    447 		const VkRenderPassBeginInfo renderPassBeginInfo =
    448 		{
    449 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
    450 			DE_NULL,										// const void*             pNext;
    451 			*renderPass,										// VkRenderPass            renderPass;
    452 			*framebuffer,									// VkFramebuffer           framebuffer;
    453 			renderArea,										// VkRect2D                renderArea;
    454 			static_cast<deUint32>(clearValues.size()),		// deUint32                clearValueCount;
    455 			&clearValues[0],								// const VkClearValue*     pClearValues;
    456 		};
    457 
    458 		deviceInterface.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
    459 
    460 		// Bind graphics pipeline
    461 		deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
    462 
    463 		// Bind vertex buffer
    464 		deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexStartOffset);
    465 
    466 		// Draw full screen quad
    467 		deviceInterface.cmdDraw(*commandBuffer, vertexDataDesc.verticesCount, 1u, 0u, 0u);
    468 
    469 		// End render pass
    470 		deviceInterface.cmdEndRenderPass(*commandBuffer);
    471 	}
    472 
    473 	const VkImage sourceImage = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? **imageMS : **imageRS;
    474 
    475 	{
    476 		const VkImageMemoryBarrier imageTransferSrcBarrier = makeImageMemoryBarrier
    477 		(
    478 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    479 			VK_ACCESS_TRANSFER_READ_BIT,
    480 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
    481 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
    482 			sourceImage,
    483 			fullImageRange
    484 		);
    485 
    486 		deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageTransferSrcBarrier);
    487 	}
    488 
    489 	// Copy data from resolve image to buffer
    490 	const deUint32				imageRSSizeInBytes = getImageSizeInBytes(imageRSInfo.extent, imageRSInfo.arrayLayers, m_imageFormat, imageRSInfo.mipLevels);
    491 
    492 	const VkBufferCreateInfo	bufferRSInfo = makeBufferCreateInfo(imageRSSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
    493 	const de::UniquePtr<Buffer>	bufferRS(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
    494 
    495 	{
    496 		const VkBufferImageCopy bufferImageCopy =
    497 		{
    498 			0u,																						//	VkDeviceSize				bufferOffset;
    499 			0u,																						//	deUint32					bufferRowLength;
    500 			0u,																						//	deUint32					bufferImageHeight;
    501 			makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers),	//	VkImageSubresourceLayers	imageSubresource;
    502 			makeOffset3D(0, 0, 0),																	//	VkOffset3D					imageOffset;
    503 			imageRSInfo.extent,																		//	VkExtent3D					imageExtent;
    504 		};
    505 
    506 		deviceInterface.cmdCopyImageToBuffer(*commandBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferRS->get(), 1u, &bufferImageCopy);
    507 	}
    508 
    509 	{
    510 		const VkBufferMemoryBarrier bufferRSHostReadBarrier = makeBufferMemoryBarrier
    511 		(
    512 			VK_ACCESS_TRANSFER_WRITE_BIT,
    513 			VK_ACCESS_HOST_READ_BIT,
    514 			bufferRS->get(),
    515 			0u,
    516 			imageRSSizeInBytes
    517 		);
    518 
    519 		deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferRSHostReadBarrier, 0u, DE_NULL);
    520 	}
    521 
    522 	// End recording commands
    523 	VK_CHECK(deviceInterface.endCommandBuffer(*commandBuffer));
    524 
    525 	// Submit commands for execution and wait for completion
    526 	submitCommandsAndWait(deviceInterface, device, queue, *commandBuffer);
    527 
    528 	// Retrieve data from buffer to host memory
    529 	const Allocation& bufferRSAllocation = bufferRS->getAllocation();
    530 
    531 	invalidateMappedMemoryRange(deviceInterface, device, bufferRSAllocation.getMemory(), bufferRSAllocation.getOffset(), VK_WHOLE_SIZE);
    532 
    533 	const tcu::ConstPixelBufferAccess bufferRSData (m_imageFormat,
    534 													imageRSInfo.extent.width,
    535 													imageRSInfo.extent.height,
    536 													imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
    537 													bufferRSAllocation.getHostPtr());
    538 
    539 	std::stringstream imageName;
    540 	imageName << getImageTypeName(m_imageType) << "_" << bufferRSData.getWidth() << "_" << bufferRSData.getHeight() << "_" << bufferRSData.getDepth() << std::endl;
    541 
    542 	m_context.getTestContext().getLog()
    543 		<< tcu::TestLog::Section(imageName.str(), imageName.str())
    544 		<< tcu::LogImage("image", "", bufferRSData)
    545 		<< tcu::TestLog::EndSection;
    546 
    547 	return verifyImageData(imageRSInfo, bufferRSData);
    548 }
    549 
    550 } // multisample
    551 } // pipeline
    552 } // vkt
    553