Home | History | Annotate | Download | only in api
      1 /*-------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2016 The Khronos Group Inc.
      6  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *      http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  *
     20  *//*!
     21  * \file
     22  * \brief Memory Commitment tests
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktApiGetMemoryCommitment.hpp"
     26 
     27 #include "vkDeviceUtil.hpp"
     28 #include "vkQueryUtil.hpp"
     29 #include "vkRefUtil.hpp"
     30 #include "vkImageUtil.hpp"
     31 #include "vkMemUtil.hpp"
     32 #include "vkPrograms.hpp"
     33 #include "vktTestCase.hpp"
     34 #include "vkTypeUtil.cpp"
     35 
     36 #include "tcuTestLog.hpp"
     37 
     38 using namespace vk;
     39 using tcu::TestLog;
     40 
     41 namespace vkt
     42 {
     43 namespace api
     44 {
     45 
     46 struct MemoryCommitmentCaseParams
     47 {
     48 	deUint32	bufferSize;
     49 	deUint32	bufferViewSize;
     50 	deUint32	elementOffset;
     51 };
     52 
     53 class MemoryCommitmentTestInstance : public vkt::TestInstance
     54 {
     55 public:
     56 									MemoryCommitmentTestInstance	(Context& context, MemoryCommitmentCaseParams testCase);
     57 	tcu::TestStatus					iterate							(void);
     58 	deUint32						getMemoryTypeIndex				(VkMemoryPropertyFlags propertyFlag, VkPhysicalDeviceMemoryProperties pMemoryProperties);
     59 	Move<VkCommandPool>				createCommandPool				() const;
     60 	Move<VkCommandBuffer>			allocatePrimaryCommandBuffer	(VkCommandPool commandPool) const;
     61 	void							submitCommandsAndWait			(const DeviceInterface& vkd,
     62 																	 const VkDevice			device,
     63 																	 const VkQueue			queue,
     64 																	 const VkCommandBuffer& cmdBuffer);
     65 	bool							isDeviceMemoryCommitmentOk		(const VkMemoryRequirements memoryRequirements);
     66 
     67 private:
     68 	const tcu::IVec2				m_renderSize;
     69 };
     70 
     71 MemoryCommitmentTestInstance::MemoryCommitmentTestInstance(Context& context, MemoryCommitmentCaseParams testCase)
     72 	: vkt::TestInstance		(context)
     73 	, m_renderSize			(testCase.bufferViewSize, testCase.bufferViewSize)
     74 {
     75 }
     76 
     77 class MemoryCommitmentTestCase : public vkt::TestCase
     78 {
     79 public:
     80 							MemoryCommitmentTestCase	(tcu::TestContext&				testCtx,
     81 														const std::string&				name,
     82 														const std::string&				description,
     83 														MemoryCommitmentCaseParams		memoryCommitmentTestInfo)
     84 							: vkt::TestCase					(testCtx, name, description)
     85 							, m_memoryCommitmentTestInfo	(memoryCommitmentTestInfo)
     86 							{}
     87 	virtual					~MemoryCommitmentTestCase(void){}
     88 	virtual	void			initPrograms	(SourceCollections&	programCollection)	const;
     89 	virtual TestInstance*	createInstance	(Context&			context)			const
     90 							{
     91 								return new MemoryCommitmentTestInstance(context, m_memoryCommitmentTestInfo);
     92 							}
     93 private:
     94 	MemoryCommitmentCaseParams m_memoryCommitmentTestInfo;
     95 };
     96 
     97 tcu::TestStatus MemoryCommitmentTestInstance::iterate(void)
     98 {
     99 	const VkMemoryPropertyFlags				propertyFlag			= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
    100 	const VkPhysicalDevice					physicalDevice			= m_context.getPhysicalDevice();
    101 	const InstanceInterface&				vki						= m_context.getInstanceInterface();
    102 	const VkPhysicalDeviceMemoryProperties	pMemoryProperties		= getPhysicalDeviceMemoryProperties(vki,physicalDevice);
    103 	const deUint32							memoryTypeIndex			= getMemoryTypeIndex(propertyFlag, pMemoryProperties);
    104 	Allocator&								memAlloc				= m_context.getDefaultAllocator();
    105 	bool									isMemoryAllocationOK	= false;
    106 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
    107 	const VkComponentMapping				componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
    108 	const DeviceInterface&					vkd						= m_context.getDeviceInterface();
    109 	const Move<VkCommandPool>				cmdPool					= createCommandPool();
    110 	const Move<VkCommandBuffer>				cmdBuffer				= allocatePrimaryCommandBuffer(*cmdPool);
    111 	const VkDevice							device					= m_context.getDevice();
    112 	Move<VkImageView>						colorAttachmentView;
    113 	Move<VkRenderPass>						renderPass;
    114 	Move<VkFramebuffer>						framebuffer;
    115 	Move<VkDescriptorSetLayout>				descriptorSetLayout;
    116 	Move<VkPipelineLayout>					pipelineLayout;
    117 	Move<VkShaderModule>					vertexShaderModule;
    118 	Move<VkShaderModule>					fragmentShaderModule;
    119 	Move<VkPipeline>						graphicsPipelines;
    120 
    121 	if (memoryTypeIndex == static_cast<deUint32>(-1))
    122 		TCU_THROW(NotSupportedError, "Lazily allocated bit is not supported");
    123 
    124 	const VkImageCreateInfo	imageParams			=
    125 	{
    126 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType		sType;
    127 		DE_NULL,										// const void*			pNext;
    128 		0u,												// VkImageCreateFlags	flags;
    129 		VK_IMAGE_TYPE_2D,								// VkImageType			imageType;
    130 		VK_FORMAT_R32_UINT,								// VkFormat				format;
    131 		{256u, 256u, 1},								// VkExtent3D			extent;
    132 		1u,												// deUint32				mipLevels;
    133 		1u,												// deUint32				arraySize;
    134 		VK_SAMPLE_COUNT_1_BIT,							// deUint32				samples;
    135 		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling		tiling;
    136 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
    137 			VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,	// VkImageUsageFlags	usage;
    138 		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode		sharingMode;
    139 		1u,												// deUint32				queueFamilyCount;
    140 		&queueFamilyIndex,								// const deUint32*		pQueueFamilyIndices;
    141 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout		initialLayout;
    142 	};
    143 
    144 	Move<VkImage>				image				= createImage(vkd, device, &imageParams);
    145 	const VkMemoryRequirements	memoryRequirements	= getImageMemoryRequirements(vkd, device, *image);
    146 	de::MovePtr<Allocation>		imageAlloc			= memAlloc.allocate(memoryRequirements, MemoryRequirement::LazilyAllocated);
    147 
    148 	VK_CHECK(vkd.bindImageMemory(device, *image, imageAlloc->getMemory(), imageAlloc->getOffset()));
    149 
    150 	const VkImageViewCreateInfo colorAttachmentViewParams	=
    151 	{
    152 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
    153 		DE_NULL,											// const void*				pNext;
    154 		0u,													// VkImageViewCreateFlags	flags;
    155 		*image,												// VkImage					image;
    156 		VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
    157 		VK_FORMAT_R32_UINT,									// VkFormat					format;
    158 		componentMappingRGBA,								// VkComponentMapping		components;
    159 		{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
    160 	};
    161 
    162 	colorAttachmentView = createImageView(vkd, device, &colorAttachmentViewParams);
    163 
    164 	// Create render pass
    165 	{
    166 		const VkAttachmentDescription colorAttachmentDescription =
    167 		{
    168 			0u,													// VkAttachmentDescriptionFlags		flags;
    169 			VK_FORMAT_R32_UINT,									// VkFormat							format;
    170 			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
    171 			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
    172 			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
    173 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
    174 			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
    175 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
    176 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
    177 		};
    178 
    179 		const VkAttachmentReference colorAttachmentReference =
    180 		{
    181 			0u,													// deUint32			attachment;
    182 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
    183 		};
    184 
    185 		const VkSubpassDescription subpassDescription =
    186 		{
    187 			0u,													// VkSubpassDescriptionFlags	flags;
    188 			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint			pipelineBindPoint;
    189 			0u,													// deUint32						inputAttachmentCount;
    190 			DE_NULL,											// const VkAttachmentReference*	pInputAttachments;
    191 			1u,													// deUint32						colorAttachmentCount;
    192 			&colorAttachmentReference,							// const VkAttachmentReference*	pColorAttachments;
    193 			DE_NULL,											// const VkAttachmentReference*	pResolveAttachments;
    194 			DE_NULL,											// const VkAttachmentReference*	pDepthStencilAttachment;
    195 			0u,													// deUint32						preserveAttachmentCount;
    196 			DE_NULL												// const VkAttachmentReference*	pPreserveAttachments;
    197 		};
    198 
    199 		const VkRenderPassCreateInfo renderPassParams =
    200 		{
    201 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
    202 			DE_NULL,											// const void*						pNext;
    203 			0u,													// VkRenderPassCreateFlags			flags;
    204 			1u,													// deUint32							attachmentCount;
    205 			&colorAttachmentDescription,						// const VkAttachmentDescription*	pAttachments;
    206 			1u,													// deUint32							subpassCount;
    207 			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
    208 			0u,													// deUint32							dependencyCount;
    209 			DE_NULL												// const VkSubpassDependency*		pDependencies;
    210 		};
    211 
    212 		renderPass = createRenderPass(vkd, device, &renderPassParams);
    213 	}
    214 
    215 	// Create framebuffer
    216 	{
    217 		const VkImageView attachmentBindInfos[1] =
    218 		{
    219 			*colorAttachmentView,
    220 		};
    221 
    222 		const VkFramebufferCreateInfo framebufferParams =
    223 		{
    224 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
    225 			DE_NULL,											// const void*					pNext;
    226 			(VkFramebufferCreateFlags)0,
    227 			*renderPass,										// VkRenderPass					renderPass;
    228 			1u,													// deUint32						attachmentCount;
    229 			attachmentBindInfos,								// const VkImageView*			pAttachments;
    230 			(deUint32)m_renderSize.x(),							// deUint32						width;
    231 			(deUint32)m_renderSize.y(),							// deUint32						height;
    232 			1u													// deUint32						layers;
    233 		};
    234 
    235 		framebuffer = createFramebuffer(vkd, device, &framebufferParams);
    236 	}
    237 
    238 	// Create descriptors
    239 	{
    240 		const VkDescriptorSetLayoutBinding layoutBindings[1] =
    241 		{
    242 			{
    243 				0u,											// deUint32				binding;
    244 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,	// VkDescriptorType		descriptorType;
    245 				1u,											// deUint32				arraySize;
    246 				VK_SHADER_STAGE_ALL,						// VkShaderStageFlags	stageFlags;
    247 				DE_NULL										// const VkSampler*		pImmutableSamplers;
    248 			},
    249 		};
    250 
    251 		const VkDescriptorSetLayoutCreateInfo descriptorLayoutParams =
    252 		{
    253 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType;
    254 			DE_NULL,												// cost void*							pNex;
    255 			(VkDescriptorSetLayoutCreateFlags)0,
    256 			DE_LENGTH_OF_ARRAY(layoutBindings),						// deUint32								count;
    257 			layoutBindings											// const VkDescriptorSetLayoutBinding	pBinding;
    258 		};
    259 
    260 		descriptorSetLayout = createDescriptorSetLayout(vkd, device, &descriptorLayoutParams);
    261 	}
    262 
    263 	// Create pipeline layout
    264 	{
    265 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
    266 		{
    267 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
    268 			DE_NULL,											// const void*					pNext;
    269 			(VkPipelineLayoutCreateFlags)0,
    270 			1u,													// deUint32						descriptorSetCount;
    271 			&*descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
    272 			0u,													// deUint32						pushConstantRangeCount;
    273 			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
    274 		};
    275 
    276 		pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutParams);
    277 	}
    278 
    279 	// Create shaders
    280 	{
    281 		vertexShaderModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0);
    282 		fragmentShaderModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0);
    283 	}
    284 
    285 	// Create pipeline
    286 	{
    287 		const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
    288 		{
    289 			{
    290 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType				sType;
    291 				DE_NULL,													// const void*					pNext;
    292 				(VkPipelineShaderStageCreateFlags)0,
    293 				VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStage				stage;
    294 				*vertexShaderModule,										// VkShader						shader;
    295 				"main",
    296 				DE_NULL														// const VkSpecializationInfo*	pSpecializationInfo;
    297 			},
    298 			{
    299 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType				sType;
    300 				DE_NULL,													// const void*					pNext;
    301 				(VkPipelineShaderStageCreateFlags)0,
    302 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStage				stage;
    303 				*fragmentShaderModule,									// VkShader						shader;
    304 				"main",
    305 				DE_NULL														// const VkSpecializationInfo*	pSpecializationInfo;
    306 			}
    307 		};
    308 
    309 		const VkVertexInputBindingDescription vertexInputBindingDescription =
    310 		{
    311 			0u,								// deUint32					binding;
    312 			sizeof(tcu::Vec4),				// deUint32					strideInBytes;
    313 			VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	stepRate;
    314 		};
    315 
    316 		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[1] =
    317 		{
    318 			{
    319 				0u,									// deUint32	location;
    320 				0u,									// deUint32	binding;
    321 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
    322 				0u									// deUint32	offsetInBytes;
    323 			}
    324 		};
    325 
    326 		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
    327 		{
    328 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
    329 			DE_NULL,														// const void*								pNext;
    330 			(VkPipelineVertexInputStateCreateFlags)0,
    331 			1u,																// deUint32									bindingCount;
    332 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
    333 			1u,																// deUint32									attributeCount;
    334 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
    335 		};
    336 
    337 		const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
    338 		{
    339 			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType		sType;
    340 			DE_NULL,														// const void*			pNext;
    341 			(VkPipelineInputAssemblyStateCreateFlags)0,
    342 			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology	topology;
    343 			false															// VkBool32				primitiveRestartEnable;
    344 		};
    345 
    346 		const VkViewport viewport =
    347 		{
    348 			0.0f,						// float	originX;
    349 			0.0f,						// float	originY;
    350 			(float)m_renderSize.x(),	// float	width;
    351 			(float)m_renderSize.y(),	// float	height;
    352 			0.0f,						// float	minDepth;
    353 			1.0f						// float	maxDepth;
    354 		};
    355 
    356 		const VkRect2D scissor =
    357 		{
    358 			{ 0, 0 },													// VkOffset2D  offset;
    359 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }	// VkExtent2D  extent;
    360 		};
    361 
    362 		const VkPipelineViewportStateCreateInfo viewportStateParams =
    363 		{
    364 			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType		sType;
    365 			DE_NULL,														// const void*			pNext;
    366 			(VkPipelineViewportStateCreateFlags)0,
    367 			1u,																// deUint32				viewportCount;
    368 			&viewport,														// const VkViewport*	pViewports;
    369 			1u,																// deUint32				scissorCount;
    370 			&scissor														// const VkRect2D*		pScissors;
    371 		};
    372 
    373 		const VkPipelineRasterizationStateCreateInfo rasterStateParams =
    374 		{
    375 			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType	sType;
    376 			DE_NULL,														// const void*		pNext;
    377 			(VkPipelineRasterizationStateCreateFlags)0,
    378 			false,															// VkBool32			depthClipEnable;
    379 			false,															// VkBool32			rasterizerDiscardEnable;
    380 			VK_POLYGON_MODE_FILL,											// VkFillMode		fillMode;
    381 			VK_CULL_MODE_NONE,												// VkCullMode		cullMode;
    382 			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace		frontFace;
    383 			VK_FALSE,														// VkBool32			depthBiasEnable;
    384 			0.0f,															// float			depthBias;
    385 			0.0f,															// float			depthBiasClamp;
    386 			0.0f,															// float			slopeScaledDepthBias;
    387 			1.0f,															// float			lineWidth;
    388 		};
    389 
    390 		const VkPipelineMultisampleStateCreateInfo		multisampleStateParams =
    391 		{
    392 			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
    393 			DE_NULL,														// const void*								pNext;
    394 			0u,																// VkPipelineMultisampleStateCreateFlags	flags;
    395 			VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits					rasterizationSamples;
    396 			VK_FALSE,														// VkBool32									sampleShadingEnable;
    397 			0.0f,															// float									minSampleShading;
    398 			DE_NULL,														// const VkSampleMask*						pSampleMask;
    399 			VK_FALSE,														// VkBool32									alphaToCoverageEnable;
    400 			VK_FALSE														// VkBool32									alphaToOneEnable;
    401 		};
    402 
    403 		const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
    404 		{
    405 			false,														// VkBool32			blendEnable;
    406 			VK_BLEND_FACTOR_ONE,										// VkBlend			srcBlendColor;
    407 			VK_BLEND_FACTOR_ZERO,										// VkBlend			destBlendColor;
    408 			VK_BLEND_OP_ADD,											// VkBlendOp		blendOpColor;
    409 			VK_BLEND_FACTOR_ONE,										// VkBlend			srcBlendAlpha;
    410 			VK_BLEND_FACTOR_ZERO,										// VkBlend			destBlendAlpha;
    411 			VK_BLEND_OP_ADD,											// VkBlendOp		blendOpAlpha;
    412 			(VK_COLOR_COMPONENT_R_BIT |
    413 			 VK_COLOR_COMPONENT_G_BIT |
    414 			 VK_COLOR_COMPONENT_B_BIT |
    415 			 VK_COLOR_COMPONENT_A_BIT)									// VkChannelFlags	channelWriteMask;
    416 		};
    417 
    418 		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
    419 		{
    420 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
    421 			DE_NULL,													// const void*									pNext;
    422 			(VkPipelineColorBlendStateCreateFlags)0,
    423 			false,														// VkBool32										logicOpEnable;
    424 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
    425 			1u,															// deUint32										attachmentCount;
    426 			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
    427 			{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
    428 		};
    429 
    430 		const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
    431 		{
    432 			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
    433 			DE_NULL,											// const void*										pNext;
    434 			0u,													// VkPipelineCreateFlags							flags;
    435 			2u,													// deUint32											stageCount;
    436 			shaderStageParams,									// const VkPipelineShaderStageCreateInfo*			pStages;
    437 			&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
    438 			&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
    439 			DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
    440 			&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
    441 			&rasterStateParams,									// const VkPipelineRasterStateCreateInfo*			pRasterState;
    442 			&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
    443 			DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
    444 			&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
    445 			DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
    446 			*pipelineLayout,									// VkPipelineLayout									layout;
    447 			*renderPass,										// VkRenderPass										renderPass;
    448 			0u,													// deUint32											subpass;
    449 			0u,													// VkPipeline										basePipelineHandle;
    450 			0u													// deInt32											basePipelineIndex;
    451 		};
    452 
    453 		graphicsPipelines		= createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineParams);
    454 	}
    455 
    456 	// getMemoryCommitment
    457 	isMemoryAllocationOK = isDeviceMemoryCommitmentOk(memoryRequirements);
    458 
    459 	const deUint32			clearColor[4]	= { 1u, 1u, 1u, 1u };
    460 	const VkClearAttachment	clearAttachment	=
    461 	{
    462 		VK_IMAGE_ASPECT_COLOR_BIT,									// VkImageAspectFlags	aspectMask;
    463 		0u,															// deUint32				colorAttachment;
    464 		makeClearValueColorU32(clearColor[0],
    465 							   clearColor[1],
    466 							   clearColor[2],
    467 							   clearColor[3])						// VkClearValue			clearValue;
    468 	};
    469 
    470 	const VkOffset2D offset =
    471 	{
    472 		0,
    473 		0
    474 	};
    475 
    476 	const VkExtent2D extent =
    477 	{
    478 		256u,
    479 		256u
    480 	};
    481 
    482 	const VkRect2D rect =
    483 	{
    484 		offset,
    485 		extent
    486 	};
    487 
    488 	const VkClearRect clearRect =
    489 	{
    490 		rect,
    491 		1u, // baseArrayLayer
    492 		1u	// layerCount
    493 	};
    494 
    495 	const VkCommandBufferBeginInfo	commandBufferBeginInfo	=
    496 	{
    497 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
    498 		DE_NULL,												// const void*						pNext;
    499 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
    500 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
    501 	};
    502 
    503 	// beginCommandBuffer
    504 	VK_CHECK(vkd.beginCommandBuffer(*cmdBuffer, &commandBufferBeginInfo));
    505 
    506 	const VkExtent3D		extent3D =
    507 	{
    508 		256u,	// width
    509 		256u,	// height
    510 		1u		// depth
    511 	};
    512 
    513 	const VkClearValue clearValues[1] =
    514 	{
    515 		makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f),
    516 	};
    517 
    518 	const VkRenderPassBeginInfo renderPassBeginInfo =
    519 	{
    520 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
    521 		DE_NULL,												// const void*			pNext;
    522 		*renderPass,											// VkRenderPass			renderPass;
    523 		*framebuffer,											// VkFramebuffer		framebuffer;
    524 		{
    525 			{ 0, 0 },
    526 			{ extent3D.width, extent3D.height }
    527 		},														// VkRect2D				renderArea;
    528 		1u,														// deUint32				clearValueCount;
    529 		clearValues												// const VkClearValue*	pClearValues;
    530 	};
    531 
    532 	const VkImageMemoryBarrier initialImageBarrier =
    533 	{
    534 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
    535 		DE_NULL,									// const void*				pNext;
    536 		0,											// VkMemoryOutputFlags		outputMask;
    537 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkMemoryInputFlags		inputMask;
    538 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
    539 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
    540 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
    541 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					destQueueFamilyIndex;
    542 		image.get(),								// VkImage					image;
    543 		{											// VkImageSubresourceRange	subresourceRange;
    544 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
    545 			0u,										// deUint32				baseMipLevel;
    546 			1u,										// deUint32				mipLevels;
    547 			0u,										// deUint32				baseArraySlice;
    548 			1u										// deUint32				arraySize;
    549 		}
    550 	};
    551 
    552 	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);
    553 	vkd.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
    554 	vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipelines);
    555 	// clearAttachments
    556 	vkd.cmdClearAttachments(*cmdBuffer, 1, &clearAttachment, 1u, &clearRect);
    557 	vkd.cmdEndRenderPass(*cmdBuffer);
    558 	vkd.endCommandBuffer(*cmdBuffer);
    559 
    560 	// queueSubmit
    561 	const VkQueue	queue	= m_context.getUniversalQueue();
    562 	submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
    563 
    564 	// getMemoryCommitment
    565 	isMemoryAllocationOK = (isMemoryAllocationOK && isDeviceMemoryCommitmentOk(memoryRequirements)) ? true : false;
    566 
    567 	if (isMemoryAllocationOK)
    568 		return tcu::TestStatus::pass("Pass");
    569 
    570 	return tcu::TestStatus::fail("Fail");
    571 }
    572 
    573 class MemoryCommitmentAllocateOnlyTestInstance : public vkt::TestInstance
    574 {
    575 public:
    576 									MemoryCommitmentAllocateOnlyTestInstance	(Context& context);
    577 	tcu::TestStatus					iterate										(void);
    578 };
    579 
    580 class MemoryCommitmentAllocateOnlyTestCase : public vkt::TestCase
    581 {
    582 public:
    583 							MemoryCommitmentAllocateOnlyTestCase	(tcu::TestContext&				testCtx,
    584 																	const std::string&				name,
    585 																	const std::string&				description)
    586 							: vkt::TestCase							(testCtx, name, description)
    587 							{}
    588 	virtual					~MemoryCommitmentAllocateOnlyTestCase(void){}
    589 	virtual TestInstance*	createInstance	(Context&			context)			const
    590 							{
    591 								return new MemoryCommitmentAllocateOnlyTestInstance(context);
    592 							}
    593 };
    594 
    595 MemoryCommitmentAllocateOnlyTestInstance::MemoryCommitmentAllocateOnlyTestInstance(Context& context)
    596 	: vkt::TestInstance		(context)
    597 {
    598 }
    599 
    600 tcu::TestStatus MemoryCommitmentAllocateOnlyTestInstance::iterate(void)
    601 {
    602 	const VkPhysicalDevice					physicalDevice			= m_context.getPhysicalDevice();
    603 	const VkDevice							device					= m_context.getDevice();
    604 	const InstanceInterface&				vki						= m_context.getInstanceInterface();
    605 	const DeviceInterface&					vkd						= m_context.getDeviceInterface();
    606 	const VkPhysicalDeviceMemoryProperties	pMemoryProperties		= getPhysicalDeviceMemoryProperties(vki,physicalDevice);
    607 	const VkMemoryPropertyFlags				propertyFlag			= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
    608 	const int								arrayLength				= 10;
    609 	VkDeviceSize							pCommittedMemoryInBytes = 0u;
    610 	VkDeviceSize							allocSize[arrayLength];
    611 
    612 	// generating random allocation sizes
    613 	for (int i = 0; i < arrayLength; ++i)
    614 	{
    615 		allocSize[i] = rand() % 1000 + 1;
    616 	}
    617 
    618 	for (deUint32 memoryTypeIndex = 0u; memoryTypeIndex < VK_MAX_MEMORY_TYPES; ++memoryTypeIndex) //for memoryTypes
    619 	{
    620 		if((pMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & propertyFlag) == propertyFlag) //if supports Lazy allocation
    621 		{
    622 			for (int i = 0; i < arrayLength; ++i)
    623 			{
    624 				const VkMemoryAllocateInfo	memAllocInfo =
    625 				{
    626 					VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType		sType
    627 					NULL,									//	const void*			pNext
    628 					allocSize[i],							//	VkDeviceSize		allocationSize
    629 					memoryTypeIndex							//	deUint32			memoryTypeIndex
    630 				};
    631 
    632 				Move<VkDeviceMemory> memory = allocateMemory(vkd, device, &memAllocInfo, (const VkAllocationCallbacks*)DE_NULL);
    633 
    634 				vkd.getDeviceMemoryCommitment(device, memory.get(), &pCommittedMemoryInBytes);
    635 				if(pCommittedMemoryInBytes != 0)
    636 				{
    637 					tcu::TestLog& log = m_context.getTestContext().getLog();
    638 					log << TestLog::Message << "Warning: Memory commitment not null before binding." << TestLog::EndMessage;
    639 				}
    640 				if(pCommittedMemoryInBytes > allocSize[i])
    641 					return tcu::TestStatus::fail("Fail");
    642 
    643 			}
    644 		}
    645 	}
    646 	return tcu::TestStatus::pass("Pass");
    647 }
    648 
    649 void MemoryCommitmentTestInstance::submitCommandsAndWait (const DeviceInterface& vkd, const VkDevice device, const VkQueue queue, const VkCommandBuffer& cmdBuffer)
    650 {
    651 	Move<VkFence> fence = createFence(vkd, device);
    652 
    653 	const VkSubmitInfo	submitInfo	=
    654 	{
    655 		VK_STRUCTURE_TYPE_SUBMIT_INFO,			// VkStructureType			sType;
    656 		DE_NULL,								// const void*				pNext;
    657 		0u,										// deUint32					waitSemaphoreCount;
    658 		DE_NULL,								// const VkSemaphore*		pWaitSemaphores;
    659 		(const VkPipelineStageFlags*)DE_NULL,
    660 		1u,										// deUint32					commandBufferCount;
    661 		&cmdBuffer,								// const VkCommandBuffer*	pCommandBuffers;
    662 		0u,										// deUint32					signalSemaphoreCount;
    663 		DE_NULL									// const VkSemaphore*		pSignalSemaphores;
    664 	};
    665 
    666 	VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *fence));
    667 	VK_CHECK(vkd.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
    668 }
    669 
    670 deUint32 MemoryCommitmentTestInstance::getMemoryTypeIndex(VkMemoryPropertyFlags propertyFlag, VkPhysicalDeviceMemoryProperties pMemoryProperties)
    671 {
    672 	for (deUint32 memoryTypeIndex = 0u; memoryTypeIndex < VK_MAX_MEMORY_TYPES; ++memoryTypeIndex)
    673 	{
    674 		if((pMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & propertyFlag) == propertyFlag)
    675 			return memoryTypeIndex;
    676 	}
    677 
    678 	return static_cast<deUint32>(-1);
    679 }
    680 
    681 void MemoryCommitmentTestCase::initPrograms (SourceCollections& programCollection) const
    682 {
    683 	programCollection.glslSources.add("vert") << glu::VertexSource(
    684 		"#version 310 es\n"
    685 		"layout (location = 0) in highp vec4 a_position;\n"
    686 		"void main()\n"
    687 		"{\n"
    688 		"	gl_Position = a_position;\n"
    689 		"}\n");
    690 
    691 	programCollection.glslSources.add("frag") << glu::FragmentSource(
    692 		"#version 310 es\n"
    693 		"#extension GL_EXT_texture_buffer : enable\n"
    694 		"layout (set=0, binding=0) uniform highp usamplerBuffer u_buffer;\n"
    695 		"layout (location = 0) out highp uint o_color;\n"
    696 		"void main()\n"
    697 		"{\n"
    698 		"	o_color = texelFetch(u_buffer, int(gl_FragCoord.x)).x;\n"
    699 		"}\n");
    700 }
    701 
    702 Move<VkCommandPool> MemoryCommitmentTestInstance::createCommandPool() const
    703 {
    704 	const VkDevice			device				= m_context.getDevice();
    705 	const DeviceInterface&	vkd					= m_context.getDeviceInterface();
    706 	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
    707 
    708 	return vk::createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
    709 }
    710 
    711 Move<VkCommandBuffer> MemoryCommitmentTestInstance::allocatePrimaryCommandBuffer (VkCommandPool commandPool) const
    712 {
    713 	const VkDevice						device					= m_context.getDevice();
    714 	const DeviceInterface&				vkd						= m_context.getDeviceInterface();
    715 
    716 	return vk::allocateCommandBuffer(vkd, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
    717 }
    718 
    719 bool MemoryCommitmentTestInstance::isDeviceMemoryCommitmentOk(const VkMemoryRequirements memoryRequirements)
    720 {
    721 	const VkFormat							colorFormat			= VK_FORMAT_R32_UINT;
    722 	const VkPhysicalDevice					physicalDevice		= m_context.getPhysicalDevice();
    723 	const InstanceInterface&				vki					= m_context.getInstanceInterface();
    724 	const VkMemoryPropertyFlags				propertyFlag		= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
    725 	const VkPhysicalDeviceMemoryProperties	pMemoryProperties	= getPhysicalDeviceMemoryProperties(vki,physicalDevice);
    726 	const VkDeviceSize						pixelDataSize		= m_renderSize.x() * m_renderSize.y() * mapVkFormat(colorFormat).getPixelSize();
    727 
    728 	for (deUint32 memTypeNdx = 0u; memTypeNdx < VK_MAX_MEMORY_TYPES; ++memTypeNdx)
    729 	{
    730 		if((pMemoryProperties.memoryTypes[memTypeNdx].propertyFlags & propertyFlag) == propertyFlag) //if supports Lazy allocation
    731 		{
    732 			const VkMemoryAllocateInfo	memAllocInfo =
    733 			{
    734 				VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,		//	VkStructureType		sType
    735 				NULL,										//	const void*			pNext
    736 				pixelDataSize,								//	VkDeviceSize		allocationSize
    737 				memTypeNdx									//	deUint32			memoryTypeIndex
    738 			};
    739 			const VkDevice			device					= m_context.getDevice();
    740 			const DeviceInterface&	vkd						= m_context.getDeviceInterface();
    741 			Move<VkDeviceMemory>	memory					= allocateMemory(vkd, device, &memAllocInfo, (const VkAllocationCallbacks*)DE_NULL);
    742 			VkDeviceSize			pCommittedMemoryInBytes = 0u;
    743 			vkd.getDeviceMemoryCommitment(device, memory.get(), &pCommittedMemoryInBytes);
    744 			if(pCommittedMemoryInBytes <= memoryRequirements.size)
    745 				return true;
    746 		}
    747 	}
    748 	return false;
    749 }
    750 
    751 tcu::TestCaseGroup* createMemoryCommitmentTests (tcu::TestContext& testCtx)
    752 {
    753 	static const MemoryCommitmentCaseParams info =
    754 	{
    755 		2048u,	// deUint32	bufferSize
    756 		256u,	// deUint32	bufferViewSize
    757 		0u,		// deUint32	elementOffset
    758 	};
    759 
    760 	de::MovePtr<tcu::TestCaseGroup>	getMemoryCommitmentTests	(new tcu::TestCaseGroup(testCtx, "get_memory_commitment", "Memory Commitment Tests"));
    761 
    762 	{
    763 		getMemoryCommitmentTests->addChild(new MemoryCommitmentTestCase(testCtx, "memory_commitment", "memory_commitment_test", info));
    764 		getMemoryCommitmentTests->addChild(new MemoryCommitmentAllocateOnlyTestCase(testCtx, "memory_commitment_allocate_only", "memory_commitment_allocate_only_test"));
    765 	}
    766 
    767 	return getMemoryCommitmentTests.release();
    768 }
    769 
    770 } //api
    771 } //vkt
    772