[KMS/DRM][Vulkan] Only try to create a display mode when no suitable mode is found.

This commit is contained in:
Manuel Alfayate Corchete 2020-12-23 16:22:46 +01:00
parent 0ed4d92938
commit a6dc838d52

View File

@ -197,11 +197,13 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info; VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info;
VkExtent2D image_size; VkExtent2D image_size;
VkDisplayModeKHR display_mode; VkDisplayModeKHR *display_mode = NULL;
VkDisplayModePropertiesKHR display_mode_props = {0}; VkDisplayModePropertiesKHR display_mode_props = {0};
VkDisplayModeParametersKHR new_mode_parameters = {0};
VkResult result; VkResult result;
SDL_bool ret = SDL_FALSE; SDL_bool ret = SDL_FALSE;
SDL_bool mode_found = SDL_FALSE;
/* We don't receive a display index in KMSDRM_CreateDevice(), only /* We don't receive a display index in KMSDRM_CreateDevice(), only
a device index, which determines the GPU to use, but not the output. 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. */ /* 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); vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices);
/* A GPU (or physical_device, in vkcube terms) is a GPU. A machine with more /* 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. */ /* 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, vkGetPhysicalDeviceDisplayPropertiesKHR(gpu,
&display_count, &display_count,
displays_props); displays_props);
@ -318,7 +320,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
} }
/* Get the props of the videomodes for the first display. */ /* 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, vkGetDisplayModePropertiesKHR(gpu,
displays_props[display_index].display, displays_props[display_index].display,
&mode_count, modes_props); &mode_count, modes_props);
@ -331,7 +333,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
} }
/* Get the props of the planes for the physical device. */ /* 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); vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, planes_props);
/* Get a video mode equal or smaller than the window size. REMEMBER: /* 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) modes_props[i].parameters.visibleRegion.height <= window->h)
{ {
display_mode_props = modes_props[i]; display_mode_props = modes_props[i];
mode_found = SDL_TRUE;
break; break;
} }
} }
if (display_mode_props.parameters.visibleRegion.width == 0 if (mode_found &&
|| display_mode_props.parameters.visibleRegion.height == 0) 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."); /* Found a suitable mode among the predefined ones. Use that. */
goto clean; 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. */ /* Just in case we get here without a display_mode. */
display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR; if (!display_mode) {
display_mode_create_info.parameters = display_mode_props.parameters; SDL_SetError("Vulkan couldn't get a display mode.");
result = vkCreateDisplayModeKHR(gpu, goto clean;
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;
} }
/********************************************/
/* Let's finally create the Vulkan surface! */ /* Let's finally create the Vulkan surface! */
/********************************************/
image_size.width = window->w; image_size.width = window->w;
image_size.height = window->h; image_size.height = window->h;
display_plane_surface_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR; 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. */ /* For now, simply use the first plane. */
display_plane_surface_create_info.planeIndex = 0; display_plane_surface_create_info.planeIndex = 0;
display_plane_surface_create_info.imageExtent = image_size; display_plane_surface_create_info.imageExtent = image_size;
@ -392,13 +406,13 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
clean: clean:
if (physical_devices) if (physical_devices)
free (physical_devices); SDL_free (physical_devices);
if (displays_props) if (displays_props)
free (displays_props); SDL_free (displays_props);
if (planes_props) if (planes_props)
free (planes_props); SDL_free (planes_props);
if (modes_props) if (modes_props)
free (modes_props); SDL_free (modes_props);
return ret; return ret;
} }