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.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkObjUtil.hpp"
37 
38 #include "tcuTestLog.hpp"
39 
40 using namespace vk;
41 using tcu::TestLog;
42 
43 namespace vkt
44 {
45 namespace api
46 {
47 
48 struct MemoryCommitmentCaseParams
49 {
50 	deUint32	bufferSize;
51 	deUint32	bufferViewSize;
52 	deUint32	elementOffset;
53 };
54 
55 namespace
56 {
57 
getMemoryTypeIndices(VkMemoryPropertyFlags propertyFlag, const VkPhysicalDeviceMemoryProperties& pMemoryProperties)58 std::vector<deUint32> getMemoryTypeIndices (VkMemoryPropertyFlags propertyFlag, const VkPhysicalDeviceMemoryProperties& pMemoryProperties)
59 {
60 	std::vector<deUint32> indices;
61 	for (deUint32 typeIndex = 0u; typeIndex < pMemoryProperties.memoryTypeCount; ++typeIndex)
62 	{
63 		if ((pMemoryProperties.memoryTypes[typeIndex].propertyFlags & propertyFlag) == propertyFlag)
64 			indices.push_back(typeIndex);
65 	}
66 	return indices;
67 }
68 
69 }
70 
71 class MemoryCommitmentTestInstance : public vkt::TestInstance
72 {
73 public:
74 									MemoryCommitmentTestInstance	(Context& context, MemoryCommitmentCaseParams testCase);
75 	tcu::TestStatus					iterate							(void);
76 	Move<VkCommandPool>				createCommandPool				() const;
77 	Move<VkCommandBuffer>			allocatePrimaryCommandBuffer	(VkCommandPool commandPool) const;
78 	bool							isDeviceMemoryCommitmentOk		(const VkMemoryRequirements memoryRequirements);
79 
80 private:
81 	const tcu::IVec2				m_renderSize;
82 };
83 
MemoryCommitmentTestInstance(Context& context, MemoryCommitmentCaseParams testCase)84 MemoryCommitmentTestInstance::MemoryCommitmentTestInstance(Context& context, MemoryCommitmentCaseParams testCase)
85 	: vkt::TestInstance		(context)
86 	, m_renderSize			(testCase.bufferViewSize, testCase.bufferViewSize)
87 {
88 }
89 
90 class MemoryCommitmentTestCase : public vkt::TestCase
91 {
92 public:
MemoryCommitmentTestCase(tcu::TestContext& testCtx, const std::string& name, MemoryCommitmentCaseParams memoryCommitmentTestInfo)93 							MemoryCommitmentTestCase	(tcu::TestContext&				testCtx,
94 														const std::string&				name,
95 														MemoryCommitmentCaseParams		memoryCommitmentTestInfo)
96 							: vkt::TestCase					(testCtx, name)
97 							, m_memoryCommitmentTestInfo	(memoryCommitmentTestInfo)
98 							{}
~MemoryCommitmentTestCase(void)99 	virtual					~MemoryCommitmentTestCase(void){}
100 	virtual	void			initPrograms	(SourceCollections&	programCollection)	const;
createInstance(Context& context) const101 	virtual TestInstance*	createInstance	(Context&			context)			const
102 							{
103 								return new MemoryCommitmentTestInstance(context, m_memoryCommitmentTestInfo);
104 							}
105 private:
106 	MemoryCommitmentCaseParams m_memoryCommitmentTestInfo;
107 };
108 
iterate(void)109 tcu::TestStatus MemoryCommitmentTestInstance::iterate(void)
110 {
111 	const VkMemoryPropertyFlags				propertyFlag			= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
112 	const VkPhysicalDevice					physicalDevice			= m_context.getPhysicalDevice();
113 	const InstanceInterface&				vki						= m_context.getInstanceInterface();
114 	const VkPhysicalDeviceMemoryProperties	pMemoryProperties		= getPhysicalDeviceMemoryProperties(vki,physicalDevice);
115 	const std::vector<deUint32>				memoryTypeIndices		= getMemoryTypeIndices(propertyFlag, pMemoryProperties);
116 	Allocator&								memAlloc				= m_context.getDefaultAllocator();
117 	bool									isMemoryAllocationOK	= false;
118 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
119 	const VkComponentMapping				componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
120 	const DeviceInterface&					vkd						= m_context.getDeviceInterface();
121 	const Move<VkCommandPool>				cmdPool					= createCommandPool();
122 	const Move<VkCommandBuffer>				cmdBuffer				= allocatePrimaryCommandBuffer(*cmdPool);
123 	const VkDevice							device					= m_context.getDevice();
124 	Move<VkImageView>						colorAttachmentView;
125 	Move<VkRenderPass>						renderPass;
126 	Move<VkFramebuffer>						framebuffer;
127 	Move<VkDescriptorSetLayout>				descriptorSetLayout;
128 	Move<VkPipelineLayout>					pipelineLayout;
129 	Move<VkShaderModule>					vertexShaderModule;
130 	Move<VkShaderModule>					fragmentShaderModule;
131 	Move<VkPipeline>						graphicsPipelines;
132 
133 	// Note we can still fail later if none of lazily allocated memory types can be used with the image below.
134 	if (memoryTypeIndices.empty())
135 		TCU_THROW(NotSupportedError, "Lazily allocated bit is not supported by any memory type");
136 
137 	const VkImageCreateInfo	imageParams			=
138 	{
139 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType		sType;
140 		DE_NULL,										// const void*			pNext;
141 		0u,												// VkImageCreateFlags	flags;
142 		VK_IMAGE_TYPE_2D,								// VkImageType			imageType;
143 		VK_FORMAT_R32_UINT,								// VkFormat				format;
144 		{256u, 256u, 1},								// VkExtent3D			extent;
145 		1u,												// deUint32				mipLevels;
146 		1u,												// deUint32				arraySize;
147 		VK_SAMPLE_COUNT_1_BIT,							// deUint32				samples;
148 		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling		tiling;
149 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
150 			VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,	// VkImageUsageFlags	usage;
151 		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode		sharingMode;
152 		1u,												// deUint32				queueFamilyCount;
153 		&queueFamilyIndex,								// const deUint32*		pQueueFamilyIndices;
154 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout		initialLayout;
155 	};
156 
157 	Move<VkImage>				image				= createImage(vkd, device, &imageParams);
158 	const VkMemoryRequirements	memoryRequirements	= getImageMemoryRequirements(vkd, device, *image);
159 	de::MovePtr<Allocation>		imageAlloc			= memAlloc.allocate(memoryRequirements, MemoryRequirement::LazilyAllocated);
160 
161 	VK_CHECK(vkd.bindImageMemory(device, *image, imageAlloc->getMemory(), imageAlloc->getOffset()));
162 
163 	const VkImageViewCreateInfo colorAttachmentViewParams	=
164 	{
165 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
166 		DE_NULL,											// const void*				pNext;
167 		0u,													// VkImageViewCreateFlags	flags;
168 		*image,												// VkImage					image;
169 		VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
170 		VK_FORMAT_R32_UINT,									// VkFormat					format;
171 		componentMappingRGBA,								// VkComponentMapping		components;
172 		{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
173 	};
174 
175 	colorAttachmentView = createImageView(vkd, device, &colorAttachmentViewParams);
176 
177 	// Create render pass
178 	renderPass = makeRenderPass(vkd, device, VK_FORMAT_R32_UINT);
179 
180 	// Create framebuffer
181 	{
182 		const VkImageView attachmentBindInfos[1] =
183 		{
184 			*colorAttachmentView,
185 		};
186 
187 		const VkFramebufferCreateInfo framebufferParams =
188 		{
189 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
190 			DE_NULL,											// const void*					pNext;
191 			(VkFramebufferCreateFlags)0,
192 			*renderPass,										// VkRenderPass					renderPass;
193 			1u,													// deUint32						attachmentCount;
194 			attachmentBindInfos,								// const VkImageView*			pAttachments;
195 			(deUint32)m_renderSize.x(),							// deUint32						width;
196 			(deUint32)m_renderSize.y(),							// deUint32						height;
197 			1u													// deUint32						layers;
198 		};
199 
200 		framebuffer = createFramebuffer(vkd, device, &framebufferParams);
201 	}
202 
203 	// Create descriptors
204 	{
205 		const VkDescriptorSetLayoutBinding layoutBindings[1] =
206 		{
207 			{
208 				0u,											// deUint32				binding;
209 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,	// VkDescriptorType		descriptorType;
210 				1u,											// deUint32				arraySize;
211 				VK_SHADER_STAGE_ALL,						// VkShaderStageFlags	stageFlags;
212 				DE_NULL										// const VkSampler*		pImmutableSamplers;
213 			},
214 		};
215 
216 		const VkDescriptorSetLayoutCreateInfo descriptorLayoutParams =
217 		{
218 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType;
219 			DE_NULL,												// const void*							pNext;
220 			(VkDescriptorSetLayoutCreateFlags)0,
221 			DE_LENGTH_OF_ARRAY(layoutBindings),						// deUint32								count;
222 			layoutBindings											// const VkDescriptorSetLayoutBinding	pBinding;
223 		};
224 
225 		descriptorSetLayout = createDescriptorSetLayout(vkd, device, &descriptorLayoutParams);
226 	}
227 
228 	// Create pipeline layout
229 	{
230 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
231 		{
232 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
233 			DE_NULL,											// const void*					pNext;
234 			(VkPipelineLayoutCreateFlags)0,
235 			1u,													// deUint32						descriptorSetCount;
236 			&*descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
237 			0u,													// deUint32						pushConstantRangeCount;
238 			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
239 		};
240 
241 		pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutParams);
242 	}
243 
244 	// Create shaders
245 	{
246 		vertexShaderModule		= createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0);
247 		fragmentShaderModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0);
248 	}
249 
250 	// Create pipeline
251 	{
252 		const std::vector<VkViewport>	viewports	(1, makeViewport(m_renderSize));
253 		const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_renderSize));
254 
255 		graphicsPipelines = makeGraphicsPipeline(vkd,					// const DeviceInterface&            vk
256 												 device,				// const VkDevice                    device
257 												 *pipelineLayout,		// const VkPipelineLayout            pipelineLayout
258 												 *vertexShaderModule,	// const VkShaderModule              vertexShaderModule
259 												 DE_NULL,				// const VkShaderModule              tessellationControlModule
260 												 DE_NULL,				// const VkShaderModule              tessellationEvalModule
261 												 DE_NULL,				// const VkShaderModule              geometryShaderModule
262 												 *fragmentShaderModule,	// const VkShaderModule              fragmentShaderModule
263 												 *renderPass,			// const VkRenderPass                renderPass
264 												 viewports,				// const std::vector<VkViewport>&    viewports
265 												 scissors);				// const std::vector<VkRect2D>&      scissors
266 	}
267 
268 	// getMemoryCommitment
269 	isMemoryAllocationOK = isDeviceMemoryCommitmentOk(memoryRequirements);
270 
271 	const deUint32			clearColor[4]	= { 1u, 1u, 1u, 1u };
272 	const VkClearAttachment	clearAttachment	=
273 	{
274 		VK_IMAGE_ASPECT_COLOR_BIT,									// VkImageAspectFlags	aspectMask;
275 		0u,															// deUint32				colorAttachment;
276 		makeClearValueColorU32(clearColor[0],
277 							   clearColor[1],
278 							   clearColor[2],
279 							   clearColor[3])						// VkClearValue			clearValue;
280 	};
281 
282 	const VkOffset2D offset =
283 	{
284 		0,
285 		0
286 	};
287 
288 	const VkExtent2D extent =
289 	{
290 		256u,
291 		256u
292 	};
293 
294 	const VkRect2D rect =
295 	{
296 		offset,
297 		extent
298 	};
299 
300 	const VkClearRect clearRect =
301 	{
302 		rect,
303 		0u, // baseArrayLayer
304 		1u	// layerCount
305 	};
306 
307 	// beginCommandBuffer
308 	beginCommandBuffer(vkd, *cmdBuffer);
309 
310 	const VkImageMemoryBarrier initialImageBarrier =
311 	{
312 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
313 		DE_NULL,									// const void*				pNext;
314 		0,											// VkMemoryOutputFlags		outputMask;
315 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkMemoryInputFlags		inputMask;
316 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
317 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
318 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
319 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					destQueueFamilyIndex;
320 		image.get(),								// VkImage					image;
321 		{											// VkImageSubresourceRange	subresourceRange;
322 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
323 			0u,										// deUint32				baseMipLevel;
324 			1u,										// deUint32				mipLevels;
325 			0u,										// deUint32				baseArraySlice;
326 			1u										// deUint32				arraySize;
327 		}
328 	};
329 
330 	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);
331 	beginRenderPass(vkd, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, 256u, 256u), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
332 	vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipelines);
333 	// clearAttachments
334 	vkd.cmdClearAttachments(*cmdBuffer, 1, &clearAttachment, 1u, &clearRect);
335 	endRenderPass(vkd, *cmdBuffer);
336 	endCommandBuffer(vkd, *cmdBuffer);
337 
338 	// queueSubmit
339 	const VkQueue	queue	= m_context.getUniversalQueue();
340 	submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
341 
342 	// getMemoryCommitment
343 	isMemoryAllocationOK = (isMemoryAllocationOK && isDeviceMemoryCommitmentOk(memoryRequirements)) ? true : false;
344 
345 	if (isMemoryAllocationOK)
346 		return tcu::TestStatus::pass("Pass");
347 
348 	return tcu::TestStatus::fail("Fail");
349 }
350 
351 class MemoryCommitmentAllocateOnlyTestInstance : public vkt::TestInstance
352 {
353 public:
354 									MemoryCommitmentAllocateOnlyTestInstance	(Context& context);
355 	tcu::TestStatus					iterate										(void);
356 };
357 
358 class MemoryCommitmentAllocateOnlyTestCase : public vkt::TestCase
359 {
360 public:
MemoryCommitmentAllocateOnlyTestCase(tcu::TestContext& testCtx, const std::string& name)361 							MemoryCommitmentAllocateOnlyTestCase	(tcu::TestContext&				testCtx,
362 																	const std::string&				name)
363 							: vkt::TestCase							(testCtx, name)
364 							{}
~MemoryCommitmentAllocateOnlyTestCase(void)365 	virtual					~MemoryCommitmentAllocateOnlyTestCase(void){}
createInstance(Context& context) const366 	virtual TestInstance*	createInstance	(Context&			context)			const
367 							{
368 								return new MemoryCommitmentAllocateOnlyTestInstance(context);
369 							}
370 };
371 
MemoryCommitmentAllocateOnlyTestInstance(Context& context)372 MemoryCommitmentAllocateOnlyTestInstance::MemoryCommitmentAllocateOnlyTestInstance(Context& context)
373 	: vkt::TestInstance		(context)
374 {
375 }
376 
iterate(void)377 tcu::TestStatus MemoryCommitmentAllocateOnlyTestInstance::iterate(void)
378 {
379 	const VkPhysicalDevice					physicalDevice			= m_context.getPhysicalDevice();
380 	const VkDevice							device					= m_context.getDevice();
381 	const InstanceInterface&				vki						= m_context.getInstanceInterface();
382 	const DeviceInterface&					vkd						= m_context.getDeviceInterface();
383 	const VkPhysicalDeviceMemoryProperties	pMemoryProperties		= getPhysicalDeviceMemoryProperties(vki,physicalDevice);
384 	const VkMemoryPropertyFlags				propertyFlag			= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
385 	const std::vector<deUint32>				memoryTypeIndices		= getMemoryTypeIndices(propertyFlag, pMemoryProperties);
386 	const int								arrayLength				= 10;
387 	VkDeviceSize							pCommittedMemoryInBytes = 0u;
388 	VkDeviceSize							allocSize[arrayLength];
389 
390 	if (memoryTypeIndices.empty())
391 		TCU_THROW(NotSupportedError, "Lazily allocated bit is not supported by any memory type");
392 
393 	// generating random allocation sizes
394 	for (int i = 0; i < arrayLength; ++i)
395 	{
396 		allocSize[i] = rand() % 1000 + 1;
397 	}
398 
399 	for (const auto memoryTypeIndex : memoryTypeIndices)
400 	{
401 		for (int i = 0; i < arrayLength; ++i)
402 		{
403 			const VkMemoryAllocateInfo	memAllocInfo =
404 			{
405 				VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType		sType
406 				NULL,									//	const void*			pNext
407 				allocSize[i],							//	VkDeviceSize		allocationSize
408 				memoryTypeIndex							//	deUint32			memoryTypeIndex
409 			};
410 
411 			Move<VkDeviceMemory> memory = allocateMemory(vkd, device, &memAllocInfo, (const VkAllocationCallbacks*)DE_NULL);
412 
413 			vkd.getDeviceMemoryCommitment(device, memory.get(), &pCommittedMemoryInBytes);
414 			if(pCommittedMemoryInBytes != 0)
415 			{
416 				tcu::TestLog& log = m_context.getTestContext().getLog();
417 				log << TestLog::Message << "Warning: Memory commitment not null before binding." << TestLog::EndMessage;
418 			}
419 			if(pCommittedMemoryInBytes > allocSize[i])
420 				return tcu::TestStatus::fail("Fail");
421 
422 		}
423 	}
424 	return tcu::TestStatus::pass("Pass");
425 }
426 
initPrograms(SourceCollections& programCollection) const427 void MemoryCommitmentTestCase::initPrograms (SourceCollections& programCollection) const
428 {
429 	programCollection.glslSources.add("vert") << glu::VertexSource(
430 		"#version 310 es\n"
431 		"layout (location = 0) in highp vec4 a_position;\n"
432 		"void main()\n"
433 		"{\n"
434 		"	gl_Position = a_position;\n"
435 		"}\n");
436 
437 	programCollection.glslSources.add("frag") << glu::FragmentSource(
438 		"#version 310 es\n"
439 		"#extension GL_EXT_texture_buffer : enable\n"
440 		"layout (set=0, binding=0) uniform highp usamplerBuffer u_buffer;\n"
441 		"layout (location = 0) out highp uint o_color;\n"
442 		"void main()\n"
443 		"{\n"
444 		"	o_color = texelFetch(u_buffer, int(gl_FragCoord.x)).x;\n"
445 		"}\n");
446 }
447 
createCommandPool() const448 Move<VkCommandPool> MemoryCommitmentTestInstance::createCommandPool() const
449 {
450 	const VkDevice			device				= m_context.getDevice();
451 	const DeviceInterface&	vkd					= m_context.getDeviceInterface();
452 	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
453 
454 	return vk::createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
455 }
456 
allocatePrimaryCommandBuffer(VkCommandPool commandPool) const457 Move<VkCommandBuffer> MemoryCommitmentTestInstance::allocatePrimaryCommandBuffer (VkCommandPool commandPool) const
458 {
459 	const VkDevice						device					= m_context.getDevice();
460 	const DeviceInterface&				vkd						= m_context.getDeviceInterface();
461 
462 	return vk::allocateCommandBuffer(vkd, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
463 }
464 
isDeviceMemoryCommitmentOk(const VkMemoryRequirements memoryRequirements)465 bool MemoryCommitmentTestInstance::isDeviceMemoryCommitmentOk(const VkMemoryRequirements memoryRequirements)
466 {
467 	const VkFormat							colorFormat			= VK_FORMAT_R32_UINT;
468 	const VkPhysicalDevice					physicalDevice		= m_context.getPhysicalDevice();
469 	const InstanceInterface&				vki					= m_context.getInstanceInterface();
470 	const VkMemoryPropertyFlags				propertyFlag		= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
471 	const VkPhysicalDeviceMemoryProperties	pMemoryProperties	= getPhysicalDeviceMemoryProperties(vki,physicalDevice);
472 	const VkDeviceSize						pixelDataSize		= m_renderSize.x() * m_renderSize.y() * mapVkFormat(colorFormat).getPixelSize();
473 
474 	for (deUint32 memTypeNdx = 0u; memTypeNdx < VK_MAX_MEMORY_TYPES; ++memTypeNdx)
475 	{
476 		if((pMemoryProperties.memoryTypes[memTypeNdx].propertyFlags & propertyFlag) == propertyFlag) //if supports Lazy allocation
477 		{
478 			const VkMemoryAllocateInfo	memAllocInfo =
479 			{
480 				VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,		//	VkStructureType		sType
481 				NULL,										//	const void*			pNext
482 				pixelDataSize,								//	VkDeviceSize		allocationSize
483 				memTypeNdx									//	deUint32			memoryTypeIndex
484 			};
485 			const VkDevice			device					= m_context.getDevice();
486 			const DeviceInterface&	vkd						= m_context.getDeviceInterface();
487 			Move<VkDeviceMemory>	memory					= allocateMemory(vkd, device, &memAllocInfo, (const VkAllocationCallbacks*)DE_NULL);
488 			VkDeviceSize			pCommittedMemoryInBytes = 0u;
489 			vkd.getDeviceMemoryCommitment(device, memory.get(), &pCommittedMemoryInBytes);
490 			if(pCommittedMemoryInBytes <= memoryRequirements.size)
491 				return true;
492 		}
493 	}
494 	return false;
495 }
496 
createMemoryCommitmentTests(tcu::TestContext& testCtx)497 tcu::TestCaseGroup* createMemoryCommitmentTests (tcu::TestContext& testCtx)
498 {
499 	static const MemoryCommitmentCaseParams info =
500 	{
501 		2048u,	// deUint32	bufferSize
502 		256u,	// deUint32	bufferViewSize
503 		0u,		// deUint32	elementOffset
504 	};
505 
506 	de::MovePtr<tcu::TestCaseGroup>	getMemoryCommitmentTests	(new tcu::TestCaseGroup(testCtx, "get_memory_commitment"));
507 
508 	{
509 		getMemoryCommitmentTests->addChild(new MemoryCommitmentTestCase(testCtx, "memory_commitment", info));
510 		getMemoryCommitmentTests->addChild(new MemoryCommitmentAllocateOnlyTestCase(testCtx, "memory_commitment_allocate_only"));
511 	}
512 
513 	return getMemoryCommitmentTests.release();
514 }
515 
516 } //api
517 } //vkt
518