/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Memory Commitment tests
 *//*--------------------------------------------------------------------*/

#include "vktApiGetMemoryCommitment.hpp"

#include "vkDeviceUtil.cpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPrograms.hpp"
#include "vktTestCase.hpp"
#include "vkTypeUtil.cpp"

using namespace vk;
using tcu::TestLog;

namespace vkt
{
namespace api
{

struct MemoryCommitmentCaseParams
{
	deUint32	bufferSize;
	deUint32	bufferViewSize;
	deUint32	elementOffset;
};

class MemoryCommitmentTestInstance : public vkt::TestInstance
{
public:
									MemoryCommitmentTestInstance	(Context& context, MemoryCommitmentCaseParams testCase);
	tcu::TestStatus					iterate							(void);
	deUint32						getMemoryTypeIndex				(VkMemoryPropertyFlags propertyFlag, VkPhysicalDeviceMemoryProperties pMemoryProperties);
	Move<VkCommandPool>				createCommandPool				() const;
	Move<VkCommandBuffer>			allocatePrimaryCommandBuffer	(VkCommandPool commandPool) const;
	void							submitCommandsAndWait			(const DeviceInterface& vkd,
																	 const VkDevice			device,
																	 const VkQueue			queue,
																	 const VkCommandBuffer& cmdBuffer);
	bool							isDeviceMemoryCommitmentOk		(const VkMemoryRequirements memoryRequirements);

private:
	const tcu::IVec2				m_renderSize;
};

MemoryCommitmentTestInstance::MemoryCommitmentTestInstance(Context& context, MemoryCommitmentCaseParams testCase)
	: vkt::TestInstance		(context)
	, m_renderSize			(testCase.bufferViewSize, testCase.bufferViewSize)
{
}

class MemoryCommitmentTestCase : public vkt::TestCase
{
public:
							MemoryCommitmentTestCase	(tcu::TestContext&				testCtx,
														const std::string&				name,
														const std::string&				description,
														MemoryCommitmentCaseParams		memoryCommitmentTestInfo)
							: vkt::TestCase					(testCtx, name, description)
							, m_memoryCommitmentTestInfo	(memoryCommitmentTestInfo)
							{}
	virtual					~MemoryCommitmentTestCase(void){}
	virtual	void			initPrograms	(SourceCollections&	programCollection)	const;
	virtual TestInstance*	createInstance	(Context&			context)			const
							{
								return new MemoryCommitmentTestInstance(context, m_memoryCommitmentTestInfo);
							}
private:
	MemoryCommitmentCaseParams m_memoryCommitmentTestInfo;
};

tcu::TestStatus MemoryCommitmentTestInstance::iterate(void)
{
	const VkMemoryPropertyFlags				propertyFlag			= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
	const VkPhysicalDevice					physicalDevice			= m_context.getPhysicalDevice();
	const InstanceInterface&				vki						= m_context.getInstanceInterface();
	const VkPhysicalDeviceMemoryProperties	pMemoryProperties		= getPhysicalDeviceMemoryProperties(vki,physicalDevice);
	const deUint32							memoryTypeIndex			= getMemoryTypeIndex(propertyFlag, pMemoryProperties);
	Allocator&								memAlloc				= m_context.getDefaultAllocator();
	bool									isMemoryAllocationOK	= false;
	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const VkComponentMapping				componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
	const DeviceInterface&					vkd						= m_context.getDeviceInterface();
	const Move<VkCommandPool>				cmdPool					= createCommandPool();
	const Move<VkCommandBuffer>				cmdBuffer				= allocatePrimaryCommandBuffer(*cmdPool);
	const VkDevice							device					= m_context.getDevice();
	Move<VkImageView>						colorAttachmentView;
	Move<VkRenderPass>						renderPass;
	Move<VkFramebuffer>						framebuffer;
	Move<VkDescriptorSetLayout>				descriptorSetLayout;
	Move<VkPipelineLayout>					pipelineLayout;
	Move<VkShaderModule>					vertexShaderModule;
	Move<VkShaderModule>					fragmentShaderModule;
	Move<VkPipeline>						graphicsPipelines;

	if(memoryTypeIndex == -1u)
		TCU_THROW(NotSupportedError, "Lazily allocated bit is not supported");

	const VkImageCreateInfo	imageParams			=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType		sType;
		DE_NULL,										// const void*			pNext;
		0u,												// VkImageCreateFlags	flags;
		VK_IMAGE_TYPE_2D,								// VkImageType			imageType;
		VK_FORMAT_R32_UINT,								// VkFormat				format;
		{256u, 256u, 1},								// VkExtent3D			extent;
		1u,												// deUint32				mipLevels;
		1u,												// deUint32				arraySize;
		VK_SAMPLE_COUNT_1_BIT,							// deUint32				samples;
		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling		tiling;
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
			VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,	// VkImageUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode		sharingMode;
		1u,												// deUint32				queueFamilyCount;
		&queueFamilyIndex,								// const deUint32*		pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout		initialLayout;
	};

	Move<VkImage>				image				= createImage(vkd, device, &imageParams);
	const VkMemoryRequirements	memoryRequirements	= getImageMemoryRequirements(vkd, device, *image);
	de::MovePtr<Allocation>		imageAlloc			= memAlloc.allocate(memoryRequirements, MemoryRequirement::LazilyAllocated);

	VK_CHECK(vkd.bindImageMemory(device, *image, imageAlloc->getMemory(), imageAlloc->getOffset()));

	const VkImageViewCreateInfo colorAttachmentViewParams	=
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
		DE_NULL,											// const void*				pNext;
		0u,													// VkImageViewCreateFlags	flags;
		*image,												// VkImage					image;
		VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
		VK_FORMAT_R32_UINT,									// VkFormat					format;
		componentMappingRGBA,								// VkComponentMapping		components;
		{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
	};

	colorAttachmentView = createImageView(vkd, device, &colorAttachmentViewParams);

	// Create render pass
	{
		const VkAttachmentDescription colorAttachmentDescription =
		{
			0u,													// VkAttachmentDescriptionFlags		flags;
			VK_FORMAT_R32_UINT,									// VkFormat							format;
			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
		};

		const VkAttachmentReference colorAttachmentReference =
		{
			0u,													// deUint32			attachment;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
		};

		const VkSubpassDescription subpassDescription =
		{
			0u,													// VkSubpassDescriptionFlags	flags;
			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint			pipelineBindPoint;
			0u,													// deUint32						inputAttachmentCount;
			DE_NULL,											// const VkAttachmentReference*	pInputAttachments;
			1u,													// deUint32						colorAttachmentCount;
			&colorAttachmentReference,							// const VkAttachmentReference*	pColorAttachments;
			DE_NULL,											// const VkAttachmentReference*	pResolveAttachments;
			DE_NULL,											// const VkAttachmentReference*	pDepthStencilAttachment;
			0u,													// deUint32						preserveAttachmentCount;
			DE_NULL												// const VkAttachmentReference*	pPreserveAttachments;
		};

		const VkRenderPassCreateInfo renderPassParams =
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
			DE_NULL,											// const void*						pNext;
			0u,													// VkRenderPassCreateFlags			flags;
			1u,													// deUint32							attachmentCount;
			&colorAttachmentDescription,						// const VkAttachmentDescription*	pAttachments;
			1u,													// deUint32							subpassCount;
			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
			0u,													// deUint32							dependencyCount;
			DE_NULL												// const VkSubpassDependency*		pDependencies;
		};

		renderPass = createRenderPass(vkd, device, &renderPassParams);
	}

	// Create framebuffer
	{
		const VkImageView attachmentBindInfos[1] =
		{
			*colorAttachmentView,
		};

		const VkFramebufferCreateInfo framebufferParams =
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
			DE_NULL,											// const void*					pNext;
			(VkFramebufferCreateFlags)0,
			*renderPass,										// VkRenderPass					renderPass;
			1u,													// deUint32						attachmentCount;
			attachmentBindInfos,								// const VkImageView*			pAttachments;
			(deUint32)m_renderSize.x(),							// deUint32						width;
			(deUint32)m_renderSize.y(),							// deUint32						height;
			1u													// deUint32						layers;
		};

		framebuffer = createFramebuffer(vkd, device, &framebufferParams);
	}

	// Create descriptors
	{
		const VkDescriptorSetLayoutBinding layoutBindings[1] =
		{
			{
				0u,											// deUint32				binding;
				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,	// VkDescriptorType		descriptorType;
				1u,											// deUint32				arraySize;
				VK_SHADER_STAGE_ALL,						// VkShaderStageFlags	stageFlags;
				DE_NULL										// const VkSampler*		pImmutableSamplers;
			},
		};

		const VkDescriptorSetLayoutCreateInfo descriptorLayoutParams =
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType;
			DE_NULL,												// cost void*							pNexŧ;
			(VkDescriptorSetLayoutCreateFlags)0,
			DE_LENGTH_OF_ARRAY(layoutBindings),						// deUint32								count;
			layoutBindings											// const VkDescriptorSetLayoutBinding	pBinding;
		};

		descriptorSetLayout = createDescriptorSetLayout(vkd, device, &descriptorLayoutParams);
	}

	// Create pipeline layout
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
			DE_NULL,											// const void*					pNext;
			(VkPipelineLayoutCreateFlags)0,
			1u,													// deUint32						descriptorSetCount;
			&*descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
			0u,													// deUint32						pushConstantRangeCount;
			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
		};

		pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutParams);
	}

	// Create shaders
	{
		vertexShaderModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0);
		fragmentShaderModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0);
	}

	// Create pipeline
	{
		const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
		{
			{
				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType				sType;
				DE_NULL,													// const void*					pNext;
				(VkPipelineShaderStageCreateFlags)0,
				VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStage				stage;
				*vertexShaderModule,										// VkShader						shader;
				"main",
				DE_NULL														// const VkSpecializationInfo*	pSpecializationInfo;
			},
			{
				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType				sType;
				DE_NULL,													// const void*					pNext;
				(VkPipelineShaderStageCreateFlags)0,
				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStage				stage;
				*fragmentShaderModule,									// VkShader						shader;
				"main",
				DE_NULL														// const VkSpecializationInfo*	pSpecializationInfo;
			}
		};

		const VkVertexInputBindingDescription vertexInputBindingDescription =
		{
			0u,								// deUint32					binding;
			sizeof(tcu::Vec4),				// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	stepRate;
		};

		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[1] =
		{
			{
				0u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				0u									// deUint32	offsetInBytes;
			}
		};

		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
			DE_NULL,														// const void*								pNext;
			(VkPipelineVertexInputStateCreateFlags)0,
			1u,																// deUint32									bindingCount;
			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
			1u,																// deUint32									attributeCount;
			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
		};

		const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,														// const void*			pNext;
			(VkPipelineInputAssemblyStateCreateFlags)0,
			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology	topology;
			false															// VkBool32				primitiveRestartEnable;
		};

		const VkViewport viewport =
		{
			0.0f,						// float	originX;
			0.0f,						// float	originY;
			(float)m_renderSize.x(),	// float	width;
			(float)m_renderSize.y(),	// float	height;
			0.0f,						// float	minDepth;
			1.0f						// float	maxDepth;
		};

		const VkRect2D scissor =
		{
			{ 0, 0 },													// VkOffset2D  offset;
			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }	// VkExtent2D  extent;
		};

		const VkPipelineViewportStateCreateInfo viewportStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType		sType;
			DE_NULL,														// const void*			pNext;
			(VkPipelineViewportStateCreateFlags)0,
			1u,																// deUint32				viewportCount;
			&viewport,														// const VkViewport*	pViewports;
			1u,																// deUint32				scissorCount;
			&scissor														// const VkRect2D*		pScissors;
		};

		const VkPipelineRasterizationStateCreateInfo rasterStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType	sType;
			DE_NULL,														// const void*		pNext;
			(VkPipelineRasterizationStateCreateFlags)0,
			false,															// VkBool32			depthClipEnable;
			false,															// VkBool32			rasterizerDiscardEnable;
			VK_POLYGON_MODE_FILL,											// VkFillMode		fillMode;
			VK_CULL_MODE_NONE,												// VkCullMode		cullMode;
			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace		frontFace;
			VK_FALSE,														// VkBool32			depthBiasEnable;
			0.0f,															// float			depthBias;
			0.0f,															// float			depthBiasClamp;
			0.0f,															// float			slopeScaledDepthBias;
			1.0f,															// float			lineWidth;
		};

		const VkPipelineMultisampleStateCreateInfo		multisampleStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
			DE_NULL,														// const void*								pNext;
			0u,																// VkPipelineMultisampleStateCreateFlags	flags;
			VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits					rasterizationSamples;
			VK_FALSE,														// VkBool32									sampleShadingEnable;
			0.0f,															// float									minSampleShading;
			DE_NULL,														// const VkSampleMask*						pSampleMask;
			VK_FALSE,														// VkBool32									alphaToCoverageEnable;
			VK_FALSE														// VkBool32									alphaToOneEnable;
		};

		const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
		{
			false,														// VkBool32			blendEnable;
			VK_BLEND_FACTOR_ONE,										// VkBlend			srcBlendColor;
			VK_BLEND_FACTOR_ZERO,										// VkBlend			destBlendColor;
			VK_BLEND_OP_ADD,											// VkBlendOp		blendOpColor;
			VK_BLEND_FACTOR_ONE,										// VkBlend			srcBlendAlpha;
			VK_BLEND_FACTOR_ZERO,										// VkBlend			destBlendAlpha;
			VK_BLEND_OP_ADD,											// VkBlendOp		blendOpAlpha;
			(VK_COLOR_COMPONENT_R_BIT |
			 VK_COLOR_COMPONENT_G_BIT |
			 VK_COLOR_COMPONENT_B_BIT |
			 VK_COLOR_COMPONENT_A_BIT)									// VkChannelFlags	channelWriteMask;
		};

		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
			DE_NULL,													// const void*									pNext;
			(VkPipelineColorBlendStateCreateFlags)0,
			false,														// VkBool32										logicOpEnable;
			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
			1u,															// deUint32										attachmentCount;
			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
			{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
		};

		const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
		{
			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
			DE_NULL,											// const void*										pNext;
			0u,													// VkPipelineCreateFlags							flags;
			2u,													// deUint32											stageCount;
			shaderStageParams,									// const VkPipelineShaderStageCreateInfo*			pStages;
			&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
			&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
			DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
			&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
			&rasterStateParams,									// const VkPipelineRasterStateCreateInfo*			pRasterState;
			&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
			DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
			&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
			DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
			*pipelineLayout,									// VkPipelineLayout									layout;
			*renderPass,										// VkRenderPass										renderPass;
			0u,													// deUint32											subpass;
			0u,													// VkPipeline										basePipelineHandle;
			0u													// deInt32											basePipelineIndex;
		};

		graphicsPipelines		= createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineParams);
	}

	// getMemoryCommitment
	isMemoryAllocationOK = isDeviceMemoryCommitmentOk(memoryRequirements);

	const deUint32			clearColor[4]	= { 1u, 1u, 1u, 1u };
	const VkClearAttachment	clearAttachment	=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,									// VkImageAspectFlags	aspectMask;
		0u,															// deUint32				colorAttachment;
		makeClearValueColorU32(clearColor[0],
							   clearColor[1],
							   clearColor[2],
							   clearColor[3])						// VkClearValue			clearValue;
	};

	const VkOffset2D offset =
	{
		0,
		0
	};

	const VkExtent2D extent =
	{
		256u,
		256u
	};

	const VkRect2D rect =
	{
		offset,
		extent
	};

	const VkClearRect clearRect =
	{
		rect,
		1u, // baseArrayLayer
		1u	// layerCount
	};

	const VkCommandBufferBeginInfo	commandBufferBeginInfo	=
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
		DE_NULL,												// const void*						pNext;
		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
		(const VkCommandBufferInheritanceInfo*)DE_NULL,
	};

	// beginCommandBuffer
	VK_CHECK(vkd.beginCommandBuffer(*cmdBuffer, &commandBufferBeginInfo));

	const VkExtent3D		extent3D =
	{
		256u,	// width
		256u,	// height
		1u		// depth
	};

	const VkClearValue clearValues[1] =
	{
		makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f),
	};

	const VkRenderPassBeginInfo renderPassBeginInfo =
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
		DE_NULL,												// const void*			pNext;
		*renderPass,											// VkRenderPass			renderPass;
		*framebuffer,											// VkFramebuffer		framebuffer;
		{
			{ 0, 0 },
			{ extent3D.width, extent3D.height }
		},														// VkRect2D				renderArea;
		1u,														// deUint32				clearValueCount;
		clearValues												// const VkClearValue*	pClearValues;
	};

	const VkImageMemoryBarrier initialImageBarrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		0,											// VkMemoryOutputFlags		outputMask;
		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkMemoryInputFlags		inputMask;
		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					destQueueFamilyIndex;
		image.get(),								// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
			0u,										// deUint32				baseMipLevel;
			1u,										// deUint32				mipLevels;
			0u,										// deUint32				baseArraySlice;
			1u										// deUint32				arraySize;
		}
	};

	vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &initialImageBarrier);
	vkd.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
	vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipelines);
	// clearAttachments
	vkd.cmdClearAttachments(*cmdBuffer, 1, &clearAttachment, 1u, &clearRect);
	vkd.cmdEndRenderPass(*cmdBuffer);
	vkd.endCommandBuffer(*cmdBuffer);

	// queueSubmit
	const VkQueue	queue	= m_context.getUniversalQueue();
	submitCommandsAndWait(vkd, device, queue, *cmdBuffer);

	// getMemoryCommitment
	isMemoryAllocationOK = (isMemoryAllocationOK && isDeviceMemoryCommitmentOk(memoryRequirements)) ? true : false;

	if (isMemoryAllocationOK)
		return tcu::TestStatus::pass("Pass");

	return tcu::TestStatus::fail("Fail");
}

class MemoryCommitmentAllocateOnlyTestInstance : public vkt::TestInstance
{
public:
									MemoryCommitmentAllocateOnlyTestInstance	(Context& context);
	tcu::TestStatus					iterate										(void);
};

class MemoryCommitmentAllocateOnlyTestCase : public vkt::TestCase
{
public:
							MemoryCommitmentAllocateOnlyTestCase	(tcu::TestContext&				testCtx,
																	const std::string&				name,
																	const std::string&				description)
							: vkt::TestCase							(testCtx, name, description)
							{}
	virtual					~MemoryCommitmentAllocateOnlyTestCase(void){}
	virtual TestInstance*	createInstance	(Context&			context)			const
							{
								return new MemoryCommitmentAllocateOnlyTestInstance(context);
							}
};

MemoryCommitmentAllocateOnlyTestInstance::MemoryCommitmentAllocateOnlyTestInstance(Context& context)
	: vkt::TestInstance		(context)
{
}

tcu::TestStatus MemoryCommitmentAllocateOnlyTestInstance::iterate(void)
{
	const VkPhysicalDevice					physicalDevice			= m_context.getPhysicalDevice();
	const VkDevice							device					= m_context.getDevice();
	const InstanceInterface&				vki						= m_context.getInstanceInterface();
	const DeviceInterface&					vkd						= m_context.getDeviceInterface();
	const VkPhysicalDeviceMemoryProperties	pMemoryProperties		= getPhysicalDeviceMemoryProperties(vki,physicalDevice);
	const VkMemoryPropertyFlags				propertyFlag			= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
	const int								arrayLength				= 10;
	VkDeviceSize							pCommittedMemoryInBytes = 0u;
	VkDeviceSize							allocSize[arrayLength];

	// generating random allocation sizes
	for (int i = 0; i < arrayLength; ++i)
	{
		allocSize[i] = rand() % 1000 + 1;
	}

	for (deUint32 memoryTypeIndex = 0u; memoryTypeIndex < VK_MAX_MEMORY_TYPES; ++memoryTypeIndex) //for memoryTypes
	{
		if((pMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & propertyFlag) == propertyFlag) //if supports Lazy allocation
		{
			for (int i = 0; i < arrayLength; ++i)
			{
				const VkMemoryAllocateInfo	memAllocInfo =
				{
					VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType		sType
					NULL,									//	const void*			pNext
					allocSize[i],							//	VkDeviceSize		allocationSize
					memoryTypeIndex							//	deUint32			memoryTypeIndex
				};

				Move<VkDeviceMemory> memory = allocateMemory(vkd, device, &memAllocInfo, (const VkAllocationCallbacks*)DE_NULL);

				vkd.getDeviceMemoryCommitment(device, memory.get(), &pCommittedMemoryInBytes);
				if(pCommittedMemoryInBytes != 0)
				{
					tcu::TestLog& log = m_context.getTestContext().getLog();
					log << TestLog::Message << "Warning: Memory commitment not null before binding." << TestLog::EndMessage;
				}
				if(pCommittedMemoryInBytes > allocSize[i])
					return tcu::TestStatus::fail("Fail");

			}
		}
	}
	return tcu::TestStatus::pass("Pass");
}

void MemoryCommitmentTestInstance::submitCommandsAndWait (const DeviceInterface& vkd, const VkDevice device, const VkQueue queue, const VkCommandBuffer& cmdBuffer)
{
	const VkFenceCreateInfo fenceParams =
	{
		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
		DE_NULL,								// const void*			pNext;
		0u										// VkFenceCreateFlags	flags;
	};

	Move<VkFence> fence = createFence(vkd, device, &fenceParams);

	const VkSubmitInfo	submitInfo	=
	{
		VK_STRUCTURE_TYPE_SUBMIT_INFO,			// VkStructureType			sType;
		DE_NULL,								// const void*				pNext;
		0u,										// deUint32					waitSemaphoreCount;
		DE_NULL,								// const VkSemaphore*		pWaitSemaphores;
		(const VkPipelineStageFlags*)DE_NULL,
		1u,										// deUint32					commandBufferCount;
		&cmdBuffer,								// const VkCommandBuffer*	pCommandBuffers;
		0u,										// deUint32					signalSemaphoreCount;
		DE_NULL									// const VkSemaphore*		pSignalSemaphores;
	};

	VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *fence));
	VK_CHECK(vkd.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
}

deUint32 MemoryCommitmentTestInstance::getMemoryTypeIndex(VkMemoryPropertyFlags propertyFlag, VkPhysicalDeviceMemoryProperties pMemoryProperties)
{
	for (deUint32 memoryTypeIndex = 0u; memoryTypeIndex < VK_MAX_MEMORY_TYPES; ++memoryTypeIndex)
	{
		if((pMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & propertyFlag) == propertyFlag)
			return memoryTypeIndex;
	}
	return -1u;
}

void MemoryCommitmentTestCase::initPrograms (SourceCollections& programCollection) const
{
	programCollection.glslSources.add("vert") << glu::VertexSource(
		"#version 310 es\n"
		"layout (location = 0) in highp vec4 a_position;\n"
		"void main()\n"
		"{\n"
		"	gl_Position = a_position;\n"
		"}\n");

	programCollection.glslSources.add("frag") << glu::FragmentSource(
		"#version 310 es\n"
		"#extension GL_EXT_texture_buffer : enable\n"
		"layout (set=0, binding=0) uniform highp usamplerBuffer u_buffer;\n"
		"layout (location = 0) out highp uint o_color;\n"
		"void main()\n"
		"{\n"
		"	o_color = texelFetch(u_buffer, int(gl_FragCoord.x)).x;\n"
		"}\n");
}

Move<VkCommandPool> MemoryCommitmentTestInstance::createCommandPool() const
{
	const VkDevice					device				= m_context.getDevice();
	const DeviceInterface&			vkd					= m_context.getDeviceInterface();
	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const VkCommandPoolCreateInfo	cmdPoolCreateInfo	=
	{
		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType             sType;
		DE_NULL,										// const void*                 pNext;
		VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,			// VkCommandPoolCreateFlags    flags;
		queueFamilyIndex								// deUint32                    queueFamilyIndex;
	};

	return vk::createCommandPool(vkd, device, &cmdPoolCreateInfo, DE_NULL);
}

Move<VkCommandBuffer> MemoryCommitmentTestInstance::allocatePrimaryCommandBuffer (VkCommandPool commandPool) const
{
	const VkDevice						device					= m_context.getDevice();
	const DeviceInterface&				vkd						= m_context.getDeviceInterface();
	const VkCommandBufferAllocateInfo	cmdBufferAllocateInfo	=
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType             sType;
		DE_NULL,										// const void*                 pNext;
		commandPool,									// VkCommandPool               commandPool;
		VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel        level;
		1												// deUint32                    commandBufferCount;
	};

	return vk::allocateCommandBuffer(vkd, device, &cmdBufferAllocateInfo);
}

bool MemoryCommitmentTestInstance::isDeviceMemoryCommitmentOk(const VkMemoryRequirements memoryRequirements)
{
	const VkFormat							colorFormat			= VK_FORMAT_R32_UINT;
	const VkPhysicalDevice					physicalDevice		= m_context.getPhysicalDevice();
	const InstanceInterface&				vki					= m_context.getInstanceInterface();
	const VkMemoryPropertyFlags				propertyFlag		= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
	const VkPhysicalDeviceMemoryProperties	pMemoryProperties	= getPhysicalDeviceMemoryProperties(vki,physicalDevice);
	const VkDeviceSize						pixelDataSize		= m_renderSize.x() * m_renderSize.y() * mapVkFormat(colorFormat).getPixelSize();

	for (deUint32 memTypeNdx = 0u; memTypeNdx < VK_MAX_MEMORY_TYPES; ++memTypeNdx)
	{
		if((pMemoryProperties.memoryTypes[memTypeNdx].propertyFlags & propertyFlag) == propertyFlag) //if supports Lazy allocation
		{
			const VkMemoryAllocateInfo	memAllocInfo =
			{
				VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,		//	VkStructureType		sType
				NULL,										//	const void*			pNext
				pixelDataSize,								//	VkDeviceSize		allocationSize
				memTypeNdx									//	deUint32			memoryTypeIndex
			};
			const VkDevice			device					= m_context.getDevice();
			const DeviceInterface&	vkd						= m_context.getDeviceInterface();
			Move<VkDeviceMemory>	memory					= allocateMemory(vkd, device, &memAllocInfo, (const VkAllocationCallbacks*)DE_NULL);
			VkDeviceSize			pCommittedMemoryInBytes = 0u;
			vkd.getDeviceMemoryCommitment(device, memory.get(), &pCommittedMemoryInBytes);
			if(pCommittedMemoryInBytes <= memoryRequirements.size)
				return true;
		}
	}
	return false;
}

tcu::TestCaseGroup* createMemoryCommitmentTests (tcu::TestContext& testCtx)
{
	static const MemoryCommitmentCaseParams info =
	{
		2048u,	// deUint32	bufferSize
		256u,	// deUint32	bufferViewSize
		0u,		// deUint32	elementOffset
	};

	de::MovePtr<tcu::TestCaseGroup>	getMemoryCommitmentTests	(new tcu::TestCaseGroup(testCtx, "get_memory_commitment", "Memory Commitment Tests"));

	{
		getMemoryCommitmentTests->addChild(new MemoryCommitmentTestCase(testCtx, "memory_commitment", "memory_commitment_test", info));
		getMemoryCommitmentTests->addChild(new MemoryCommitmentAllocateOnlyTestCase(testCtx, "memory_commitment_allocate_only", "memory_commitment_allocate_only_test"));
	}

	return getMemoryCommitmentTests.release();
}

} //api
} //vkt
