Buffer memory requirements for VK_KHR_maintenance4

This CL implements vkGetDeviceBufferMemoryRequirements and makes it
so that the buffer memory requirements can be computed without the
need to create a vk::Buffer object.

Bug: b/204502926
Change-Id: If45e4657d10fd1db6e5e495239c98b1a8962a696
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/63291
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Commit-Queue: Alexis Hétu <sugoi@google.com>
diff --git a/src/Vulkan/VkBuffer.cpp b/src/Vulkan/VkBuffer.cpp
index 322f4bd..e4559f4 100644
--- a/src/Vulkan/VkBuffer.cpp
+++ b/src/Vulkan/VkBuffer.cpp
@@ -56,16 +56,11 @@
 	return (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) ? sizeof(uint32_t) * pCreateInfo->queueFamilyIndexCount : 0;
 }
 
-const VkMemoryRequirements Buffer::getMemoryRequirements() const
+const VkMemoryRequirements Buffer::GetMemoryRequirements(VkDeviceSize size, VkBufferUsageFlags usage)
 {
 	VkMemoryRequirements memoryRequirements = {};
 
-	memoryRequirements.size = this->size;
-
-	if(memoryRequirements.size < this->size)  // Overflow occurred
-	{
-		memoryRequirements.size = std::numeric_limits<VkDeviceSize>::max();
-	}
+	memoryRequirements.size = size;
 
 	if(usage & (VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT))
 	{
@@ -89,6 +84,11 @@
 	return memoryRequirements;
 }
 
+const VkMemoryRequirements Buffer::getMemoryRequirements() const
+{
+	return GetMemoryRequirements(size, usage);
+}
+
 bool Buffer::canBindToMemory(DeviceMemory *pDeviceMemory) const
 {
 	return pDeviceMemory->checkExternalMemoryHandleType(supportedExternalMemoryHandleTypes);
diff --git a/src/Vulkan/VkBuffer.hpp b/src/Vulkan/VkBuffer.hpp
index 7da2af1..f9428b8 100644
--- a/src/Vulkan/VkBuffer.hpp
+++ b/src/Vulkan/VkBuffer.hpp
@@ -28,6 +28,7 @@
 	void destroy(const VkAllocationCallbacks *pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkBufferCreateInfo *pCreateInfo);
+	static const VkMemoryRequirements GetMemoryRequirements(VkDeviceSize size, VkBufferUsageFlags usage);
 
 	const VkMemoryRequirements getMemoryRequirements() const;
 	void bind(DeviceMemory *pDeviceMemory, VkDeviceSize pMemoryOffset);
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index f5e5160..c5837ad 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -4131,6 +4131,9 @@
 {
 	TRACE("(VkDevice device = %p, const VkDeviceBufferMemoryRequirements* pInfo = %p, VkMemoryRequirements2* pMemoryRequirements = %p)",
 	      device, pInfo, pMemoryRequirements);
+
+	pMemoryRequirements->memoryRequirements =
+	    vk::Buffer::GetMemoryRequirements(pInfo->pCreateInfo->size, pInfo->pCreateInfo->usage);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements(VkDevice device, const VkDeviceImageMemoryRequirements *pInfo, VkMemoryRequirements2 *pMemoryRequirements)