Make create_buffer test use platform limits

The create_buffer tests use a maximum buffer size of half the heap size
as reported by vkGetPhysicalDeviceMemoryProperties. On systems where
device memory comes out of system memory, due to the memory in use in
the system the selected buffer size may be too large.

The heap size is checked against the platform limits, the min is taken
and that is used as the basis for calculating the buffer size to test

Affects:

dEQP-VK.api.buffer.createBuffer_*

Components: Vulkan

VK-GL-CTS issue: 362

Change-Id: I7a644e8e48b961dad0d19675e3d54add4b11d99c
diff --git a/external/vulkancts/modules/vulkan/api/vktApiBufferTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiBufferTests.cpp
index 8ccd621..1cebc7d 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiBufferTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiBufferTests.cpp
@@ -32,6 +32,7 @@
 #include "vkRefUtil.hpp"
 #include "vkPlatform.hpp"
 #include "vktTestCase.hpp"
+#include "tcuPlatform.hpp"
 
 namespace vkt
 {
@@ -41,6 +42,35 @@
 {
 using namespace vk;
 
+PlatformMemoryLimits getPlatformMemoryLimits (Context& context)
+{
+	PlatformMemoryLimits	memoryLimits;
+
+	context.getTestContext().getPlatform().getVulkanPlatform().getMemoryLimits(memoryLimits);
+
+	return memoryLimits;
+}
+
+VkDeviceSize getMaxBufferSize(const VkDeviceSize& bufferSize,
+							  const VkDeviceSize& alignment,
+							  const PlatformMemoryLimits& limits)
+{
+	VkDeviceSize size = bufferSize;
+
+	if (limits.totalDeviceLocalMemory == 0)
+	{
+		// 'UMA' systems where device memory counts against system memory
+		size = std::min(bufferSize, limits.totalSystemMemory - alignment);
+	}
+	else
+	{
+		// 'LMA' systems where device memory is local to the GPU
+		size = std::min(bufferSize, limits.totalDeviceLocalMemory - alignment);
+	}
+
+	return size;
+}
+
 struct BufferCaseParameters
 {
 	VkBufferUsageFlags	usage;
@@ -243,9 +273,21 @@
 		const deUint32		heapTypeIndex	= (deUint32)deCtz32(memReqs.memoryTypeBits);
 		const VkMemoryType	memoryType		= memoryProperties.memoryTypes[heapTypeIndex];
 		const VkMemoryHeap	memoryHeap		= memoryProperties.memoryHeaps[memoryType.heapIndex];
-		const VkDeviceSize	maxBufferSize	= alignDeviceSize(memoryHeap.size >> 1, memReqs.alignment);
 		const deUint32		shrinkBits		= 4;	// number of bits to shift when reducing the size with each iteration
 
+		// Buffer size - Choose half of the reported heap size for the maximum buffer size, we
+		// should attempt to test as large a portion as possible.
+		//
+		// However on a system where device memory is shared with the system, the maximum size
+		// should be tested against the platform memory limits as significant portion of the heap
+		// may already be in use by the operating system and other running processes.
+		const VkDeviceSize  availableBufferSize	= getMaxBufferSize(memoryHeap.size,
+																   memReqs.alignment,
+																   getPlatformMemoryLimits(m_context));
+
+		// For our test buffer size, halve the maximum available size and align
+		const VkDeviceSize maxBufferSize = alignDeviceSize(availableBufferSize >> 1, memReqs.alignment);
+
 		size = std::min(size, maxBufferSize);
 
 		while (*memory == DE_NULL)