Fixes memory allocation tests

Queries the platform specific alignment restrictions
with a temp buffer instead of estimating.

Components: Vulkan
VK-GL-CTS issue: 1259

Affects:
dEQP-VK.memory.allocation.basic.size_*

Change-Id: I272026f9e29b5606b8a4265ef0034752ac43a71a
(cherry picked from commit 0f658f6c6a12a7356ce494cd6eaf9034da0a84b7)
diff --git a/external/vulkancts/modules/vulkan/memory/vktMemoryAllocationTests.cpp b/external/vulkancts/modules/vulkan/memory/vktMemoryAllocationTests.cpp
index e8c94dc..b8dee25 100644
--- a/external/vulkancts/modules/vulkan/memory/vktMemoryAllocationTests.cpp
+++ b/external/vulkancts/modules/vulkan/memory/vktMemoryAllocationTests.cpp
@@ -58,6 +58,12 @@
 namespace
 {
 
+template<typename T>
+T roundUpToMultiple(const T& a, const T& b)
+{
+	return b * (a / b + (a % b != 0 ? 1 : 0));
+}
+
 enum
 {
 	// The min max for allocation count is 4096. Use 4000 to take into account
@@ -224,6 +230,7 @@
 		, m_config				(config)
 		, m_result				(m_context.getTestContext().getLog())
 		, m_memoryTypeIndex		(0)
+		, m_memoryLimits		(getMemoryLimits(context.getTestContext().getPlatform().getVulkanPlatform()))
 	{
 		DE_ASSERT(!!m_config.memorySize != !!m_config.memoryPercentage);
 	}
@@ -234,6 +241,7 @@
 	const TestConfig						m_config;
 	tcu::ResultCollector					m_result;
 	deUint32								m_memoryTypeIndex;
+	const PlatformMemoryLimits				m_memoryLimits;
 };
 
 
@@ -242,6 +250,33 @@
 	TestLog&								log					= m_context.getTestContext().getLog();
 	const VkDevice							device				= getDevice();
 	const DeviceInterface&					vkd					= getDeviceInterface();
+	VkMemoryRequirements					memReqs;
+	const deUint32							queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
+	VkBufferCreateFlags						createFlags			= (vk::VkBufferCreateFlagBits)0u;
+	VkBufferUsageFlags						usageFlags			= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+	VkSharingMode							sharingMode			= vk::VK_SHARING_MODE_EXCLUSIVE;
+	Move<VkBuffer>							buffer;
+
+	if ((m_memoryProperties.memoryTypes[m_memoryTypeIndex].propertyFlags & vk::VK_MEMORY_PROPERTY_PROTECTED_BIT) == vk::VK_MEMORY_PROPERTY_PROTECTED_BIT)
+	{
+		createFlags |= vk::VK_BUFFER_CREATE_PROTECTED_BIT;
+	}
+
+	// Create a minimal buffer first to get the supported memory types
+	VkBufferCreateInfo						bufferParams		=
+	{
+		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                       // VkStructureType          sType;
+		DE_NULL,                                                    // const void*              pNext;
+		createFlags,                                                // VkBufferCreateFlags      flags;
+		1u,                                                         // VkDeviceSize             size;
+		usageFlags,                                                 // VkBufferUsageFlags       usage;
+		sharingMode,                                                // VkSharingMode            sharingMode;
+		1u,                                                         // uint32_t                 queueFamilyIndexCount;
+		&queueFamilyIndex,                                          // const uint32_t*          pQueueFamilyIndices;
+	};
+
+	buffer = createBuffer(vkd, device, &bufferParams);
+	vkd.getBufferMemoryRequirements(device, *buffer, &memReqs);
 
 	DE_ASSERT(m_config.memoryAllocationCount <= MAX_ALLOCATION_COUNT);
 
@@ -262,11 +297,12 @@
 
 	try
 	{
-		const VkMemoryType		memoryType		= m_memoryProperties.memoryTypes[m_memoryTypeIndex];
-		const VkMemoryHeap		memoryHeap		= m_memoryProperties.memoryHeaps[memoryType.heapIndex];
+		const VkMemoryType		memoryType				= m_memoryProperties.memoryTypes[m_memoryTypeIndex];
+		const VkMemoryHeap		memoryHeap				= m_memoryProperties.memoryHeaps[memoryType.heapIndex];
 
-		const VkDeviceSize		allocationSize	= (m_config.memorySize ? *m_config.memorySize : (VkDeviceSize)(*m_config.memoryPercentage * (float)memoryHeap.size));
-		vector<VkDeviceMemory>	memoryObjects	(m_config.memoryAllocationCount, (VkDeviceMemory)0);
+		const VkDeviceSize		allocationSize			= (m_config.memorySize ? memReqs.size : (VkDeviceSize)(*m_config.memoryPercentage * (float)memoryHeap.size));
+		const VkDeviceSize		roundedUpAllocationSize	= roundUpToMultiple(allocationSize, m_memoryLimits.deviceMemoryAllocationGranularity);
+		vector<VkDeviceMemory>	memoryObjects			(m_config.memoryAllocationCount, (VkDeviceMemory)0);
 
 		log << TestLog::Message << "Memory type index: " << m_memoryTypeIndex << TestLog::EndMessage;
 
@@ -277,7 +313,7 @@
 			log << TestLog::Message << "Memory type: " << memoryType << TestLog::EndMessage;
 			log << TestLog::Message << "Memory heap: " << memoryHeap << TestLog::EndMessage;
 
-			if (allocationSize * m_config.memoryAllocationCount * 8 > memoryHeap.size)
+			if (roundedUpAllocationSize * m_config.memoryAllocationCount * 8 > memoryHeap.size)
 				TCU_THROW(NotSupportedError, "Memory heap doesn't have enough memory.");
 
 #if (DE_PTR_SIZE == 4)