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