[KMSDRM] Fix intermitent bug in Vulkan initialization on Raspberry Pi 4.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
diff --git a/src/video/kmsdrm/SDL_kmsdrmvulkan.c b/src/video/kmsdrm/SDL_kmsdrmvulkan.c
index a429f42..3492298 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvulkan.c
+++ b/src/video/kmsdrm/SDL_kmsdrmvulkan.c
@@ -189,6 +189,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
uint32_t plane_count;
VkPhysicalDevice *physical_devices = NULL;
+ VkPhysicalDeviceProperties *device_props = NULL;
VkDisplayPropertiesKHR *displays_props = NULL;
VkDisplayModePropertiesKHR *modes_props = NULL;
VkDisplayPlanePropertiesKHR *planes_props = NULL;
@@ -203,6 +204,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
VkResult result;
SDL_bool ret = SDL_FALSE;
+ SDL_bool valid_gpu = SDL_FALSE;
SDL_bool mode_found = SDL_FALSE;
/* We don't receive a display index in KMSDRM_CreateDevice(), only
@@ -214,8 +216,6 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
int i;
- SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
-
/* Get the function pointers for the functions we will use. */
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
@@ -228,6 +228,10 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
(PFN_vkEnumeratePhysicalDevices)vkGetInstanceProcAddr(
instance, "vkEnumeratePhysicalDevices");
+ PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties =
+ (PFN_vkGetPhysicalDeviceProperties)vkGetInstanceProcAddr(
+ instance, "vkGetPhysicalDeviceProperties");
+
PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR =
(PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)vkGetInstanceProcAddr(
instance, "vkGetPhysicalDeviceDisplayPropertiesKHR");
@@ -275,6 +279,12 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
goto clean;
}
+ /* A GPU (or physical_device, in vkcube terms) is a physical GPU.
+ A machine with more than one video output doesn't need to have more than one GPU,
+ like the Pi4 which has 1 GPU and 2 video outputs.
+ Just in case, we test that the GPU we choose is Vulkan-capable.
+ */
+
/* Get the physical device count. */
vkEnumeratePhysicalDevices(instance, &gpu_count, NULL);
@@ -285,13 +295,31 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
/* Get the physical devices. */
physical_devices = SDL_malloc(sizeof(VkPhysicalDevice) * gpu_count);
+ device_props = SDL_malloc(sizeof(VkPhysicalDeviceProperties));
vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices);
- /* A GPU (or physical_device, in vkcube terms) is a GPU. A machine with more
- than one video output doen't need to have more than one GPU, like the Pi4
- which has 1 GPU and 2 video outputs.
- We grab the GPU/physical_device with the index we got in KMSDR_CreateDevice(). */
- gpu = physical_devices[viddata->devindex];
+ /* Iterate on the physical devices. */
+ for (i = 0; i < gpu_count; i++) {
+
+ /* Get the physical device properties. */
+ vkGetPhysicalDeviceProperties(
+ physical_devices[i],
+ device_props
+ );
+
+ /* Is this device a real GPU that supports API version 1 at least? */
+ if (device_props->apiVersion >= 1 &&
+ (device_props->deviceType == 1 || device_props->deviceType == 2))
+ {
+ gpu = physical_devices[i];
+ valid_gpu = SDL_TRUE;
+ }
+ }
+
+ if (!valid_gpu) {
+ SDL_SetError("Vulkan can't find a valid physical device (gpu).");
+ goto clean;
+ }
/* A display is a video output. 1 GPU can have N displays.
Vulkan only counts the connected displays.