[KMS/DRM][Vulkan] Only try to create a display mode when no suitable mode is found.
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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
diff --git a/src/video/kmsdrm/SDL_kmsdrmvulkan.c b/src/video/kmsdrm/SDL_kmsdrmvulkan.c
index b3160ed..bd7f8e4 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvulkan.c
+++ b/src/video/kmsdrm/SDL_kmsdrmvulkan.c
@@ -197,11 +197,13 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info;
VkExtent2D image_size;
- VkDisplayModeKHR display_mode;
+ VkDisplayModeKHR *display_mode = NULL;
VkDisplayModePropertiesKHR display_mode_props = {0};
+ VkDisplayModeParametersKHR new_mode_parameters = {0};
VkResult result;
SDL_bool ret = SDL_FALSE;
+ SDL_bool mode_found = SDL_FALSE;
/* We don't receive a display index in KMSDRM_CreateDevice(), only
a device index, which determines the GPU to use, but not the output.
@@ -282,7 +284,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
}
/* Get the physical devices. */
- physical_devices = malloc(sizeof(VkPhysicalDevice) * gpu_count);
+ physical_devices = SDL_malloc(sizeof(VkPhysicalDevice) * gpu_count);
vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices);
/* A GPU (or physical_device, in vkcube terms) is a GPU. A machine with more
@@ -301,7 +303,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
}
/* Get the props of the displays of the physical device. */
- displays_props = (VkDisplayPropertiesKHR *) malloc(display_count * sizeof(*displays_props));
+ displays_props = (VkDisplayPropertiesKHR *) SDL_malloc(display_count * sizeof(*displays_props));
vkGetPhysicalDeviceDisplayPropertiesKHR(gpu,
&display_count,
displays_props);
@@ -318,7 +320,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
}
/* Get the props of the videomodes for the first display. */
- modes_props = (VkDisplayModePropertiesKHR *) malloc(mode_count * sizeof(*modes_props));
+ modes_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*modes_props));
vkGetDisplayModePropertiesKHR(gpu,
displays_props[display_index].display,
&mode_count, modes_props);
@@ -331,7 +333,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
}
/* Get the props of the planes for the physical device. */
- planes_props = malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count);
+ planes_props = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count);
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, planes_props);
/* Get a video mode equal or smaller than the window size. REMEMBER:
@@ -344,36 +346,48 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
modes_props[i].parameters.visibleRegion.height <= window->h)
{
display_mode_props = modes_props[i];
+ mode_found = SDL_TRUE;
break;
}
}
- if (display_mode_props.parameters.visibleRegion.width == 0
- || display_mode_props.parameters.visibleRegion.height == 0)
- {
- SDL_SetError("Vulkan can't find a proper display mode for the window size.");
- goto clean;
+ if (mode_found &&
+ display_mode_props.parameters.visibleRegion.width > 0 &&
+ display_mode_props.parameters.visibleRegion.height > 0 ) {
+ /* Found a suitable mode among the predefined ones. Use that. */
+ display_mode = &(display_mode_props.displayMode);
+ } else {
+ /* Can't find a suitable mode among the predefined ones, so try to create our own. */
+ new_mode_parameters.visibleRegion.width = window->w;
+ new_mode_parameters.visibleRegion.height = window->h;
+ new_mode_parameters.refreshRate = 60000; /* Always use 60Hz for now. */
+ display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
+ display_mode_create_info.parameters = new_mode_parameters;
+ result = vkCreateDisplayModeKHR(gpu,
+ displays_props[display_index].display,
+ &display_mode_create_info,
+ NULL, display_mode);
+ if (result != VK_SUCCESS) {
+ SDL_SetError("Vulkan couldn't find a predefined mode for that window size and couldn't create a suitable mode.");
+ goto clean;
+ }
}
- /* We have the props of the display mode, but we need an actual display mode. */
- display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
- display_mode_create_info.parameters = display_mode_props.parameters;
- result = vkCreateDisplayModeKHR(gpu,
- displays_props[display_index].display,
- &display_mode_create_info,
- NULL, &display_mode);
- if (result != VK_SUCCESS) {
- SDL_SetError("Vulkan can't create the display mode.");
- goto clean;
+ /* Just in case we get here without a display_mode. */
+ if (!display_mode) {
+ SDL_SetError("Vulkan couldn't get a display mode.");
+ goto clean;
}
+ /********************************************/
/* Let's finally create the Vulkan surface! */
+ /********************************************/
image_size.width = window->w;
image_size.height = window->h;
display_plane_surface_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR;
- display_plane_surface_create_info.displayMode = display_mode;
+ display_plane_surface_create_info.displayMode = *display_mode;
/* For now, simply use the first plane. */
display_plane_surface_create_info.planeIndex = 0;
display_plane_surface_create_info.imageExtent = image_size;
@@ -392,13 +406,13 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
clean:
if (physical_devices)
- free (physical_devices);
+ SDL_free (physical_devices);
if (displays_props)
- free (displays_props);
+ SDL_free (displays_props);
if (planes_props)
- free (planes_props);
+ SDL_free (planes_props);
if (modes_props)
- free (modes_props);
+ SDL_free (modes_props);
return ret;
}