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