SDL: Vulkan: Only return memory types which are a superset of what we need

From 1558d52a0a9f2f63f85543488b2a4d9427c0ffc9 Mon Sep 17 00:00:00 2001
From: David Gow <[EMAIL REDACTED]>
Date: Sun, 25 Feb 2024 17:04:19 +0800
Subject: [PATCH] Vulkan: Only return memory types which are a superset of what
 we need

VULKAN_FindMemoryTypeIndex() tries first to get a perfectly matching
memory type, then falls back to selecting any memory type which overlaps
with the requested flags.

However, some of the flags requested are actually required, so if -- for
example -- we request a memory type with
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, but get one without it, all future
calls to vkMapMemory() will fail with:

vkMapMemory(): Mapping memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set. Memory has type 0 which has properties VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT. The Vulkan spec states:
memory must have been created with a memory type that reports VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT.


(This occurs, for instance, on the totally non-conformant hasvk driver
for Intel Haswell integrated GPUs, which otherwise works fine.)

Instead, make sure that any memory type found has a superset of the
requested flags, so it'll always be appropriate.

Of course, this makes it _less_ likely for a memory type to be found, so
it does make #9130 worse in some ways. See the next patch for details.

Signed-off-by: David Gow <david@ingeniumdigital.com>
---
 src/render/vulkan/SDL_render_vulkan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/render/vulkan/SDL_render_vulkan.c b/src/render/vulkan/SDL_render_vulkan.c
index 9005d9a33b87..c7f422590db0 100644
--- a/src/render/vulkan/SDL_render_vulkan.c
+++ b/src/render/vulkan/SDL_render_vulkan.c
@@ -1172,7 +1172,7 @@ static SDL_bool VULKAN_FindMemoryTypeIndex(VULKAN_RenderData *rendererData, uint
     if (!foundExactMatch) {
         for (memoryTypeIndex = 0; memoryTypeIndex < rendererData->physicalDeviceMemoryProperties.memoryTypeCount; memoryTypeIndex++) {
             if (typeBits & (1 << memoryTypeIndex)) {
-                if (rendererData->physicalDeviceMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & flags) {
+                if ((rendererData->physicalDeviceMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & flags) == flags) {
                     break;
                 }
             }