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