mirror of https://github.com/encounter/SDL.git
Search for an appropiate plane instead of simply using the first one.
This commit is contained in:
parent
23ffa3d914
commit
b1e492d1fc
|
@ -187,29 +187,35 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||||
uint32_t display_count;
|
uint32_t display_count;
|
||||||
uint32_t mode_count;
|
uint32_t mode_count;
|
||||||
uint32_t plane_count;
|
uint32_t plane_count;
|
||||||
|
uint32_t plane = UINT32_MAX;
|
||||||
|
|
||||||
VkPhysicalDevice *physical_devices = NULL;
|
VkPhysicalDevice *physical_devices = NULL;
|
||||||
VkPhysicalDeviceProperties *device_props = NULL;
|
VkPhysicalDeviceProperties *device_props = NULL;
|
||||||
VkDisplayPropertiesKHR *displays_props = NULL;
|
VkDisplayPropertiesKHR *display_props = NULL;
|
||||||
VkDisplayModePropertiesKHR *modes_props = NULL;
|
VkDisplayModePropertiesKHR *mode_props = NULL;
|
||||||
VkDisplayPlanePropertiesKHR *planes_props = NULL;
|
VkDisplayPlanePropertiesKHR *plane_props = NULL;
|
||||||
|
VkDisplayPlaneCapabilitiesKHR plane_caps;
|
||||||
|
|
||||||
VkDisplayModeCreateInfoKHR display_mode_create_info;
|
VkDisplayModeCreateInfoKHR display_mode_create_info;
|
||||||
VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info;
|
VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info;
|
||||||
|
|
||||||
VkExtent2D image_size;
|
VkExtent2D image_size;
|
||||||
|
VkDisplayKHR display;
|
||||||
VkDisplayModeKHR display_mode = (VkDisplayModeKHR)0;
|
VkDisplayModeKHR display_mode = (VkDisplayModeKHR)0;
|
||||||
VkDisplayModePropertiesKHR display_mode_props = {0};
|
VkDisplayModePropertiesKHR display_mode_props = {0};
|
||||||
VkDisplayModeParametersKHR new_mode_parameters = { {0, 0}, 0};
|
VkDisplayModeParametersKHR new_mode_parameters = { {0, 0}, 0};
|
||||||
|
/* Prefer a plane that supports per-pixel alpha. */
|
||||||
|
VkDisplayPlaneAlphaFlagBitsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
|
||||||
VkResult result;
|
VkResult result;
|
||||||
SDL_bool ret = SDL_FALSE;
|
SDL_bool ret = SDL_FALSE;
|
||||||
SDL_bool valid_gpu = SDL_FALSE;
|
SDL_bool valid_gpu = SDL_FALSE;
|
||||||
SDL_bool mode_found = SDL_FALSE;
|
SDL_bool mode_found = SDL_FALSE;
|
||||||
|
SDL_bool plane_supports_display = SDL_FALSE;
|
||||||
|
|
||||||
/* Get the display index from the display being used by the window. */
|
/* Get the display index from the display being used by the window. */
|
||||||
int display_index = SDL_atoi(SDL_GetDisplayForWindow(window)->name);
|
int display_index = SDL_atoi(SDL_GetDisplayForWindow(window)->name);
|
||||||
int i;
|
int i, j;
|
||||||
|
|
||||||
/* Get the function pointers for the functions we will use. */
|
/* Get the function pointers for the functions we will use. */
|
||||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
|
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
|
||||||
|
@ -239,14 +245,13 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||||
(PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)vkGetInstanceProcAddr(
|
(PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)vkGetInstanceProcAddr(
|
||||||
instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
|
instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
|
||||||
|
|
||||||
/*PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR =
|
PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR =
|
||||||
(PFN_vkGetDisplayPlaneSupportedDisplaysKHR)vkGetInstanceProcAddr(
|
(PFN_vkGetDisplayPlaneSupportedDisplaysKHR)vkGetInstanceProcAddr(
|
||||||
instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
|
instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
|
||||||
|
|
||||||
PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR =
|
PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR =
|
||||||
(PFN_vkGetDisplayPlaneCapabilitiesKHR)vkGetInstanceProcAddr(
|
(PFN_vkGetDisplayPlaneCapabilitiesKHR)vkGetInstanceProcAddr(
|
||||||
instance, "vkGetDisplayPlaneCapabilitiesKHR");
|
instance, "vkGetDisplayPlaneCapabilitiesKHR");
|
||||||
*/
|
|
||||||
|
|
||||||
PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR =
|
PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR =
|
||||||
(PFN_vkCreateDisplayModeKHR)vkGetInstanceProcAddr(
|
(PFN_vkCreateDisplayModeKHR)vkGetInstanceProcAddr(
|
||||||
|
@ -329,38 +334,29 @@ 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 *) SDL_malloc(display_count * sizeof(*displays_props));
|
display_props = (VkDisplayPropertiesKHR *) SDL_malloc(display_count * sizeof(*display_props));
|
||||||
vkGetPhysicalDeviceDisplayPropertiesKHR(gpu,
|
vkGetPhysicalDeviceDisplayPropertiesKHR(gpu,
|
||||||
&display_count,
|
&display_count,
|
||||||
displays_props);
|
display_props);
|
||||||
|
|
||||||
/* Get the videomode count for the first display. */
|
/* Get the chosen display based on the display index. */
|
||||||
|
display = display_props[display_index].display;
|
||||||
|
|
||||||
|
/* Get the list of the display videomodes. */
|
||||||
vkGetDisplayModePropertiesKHR(gpu,
|
vkGetDisplayModePropertiesKHR(gpu,
|
||||||
displays_props[display_index].display,
|
display,
|
||||||
&mode_count, NULL);
|
&mode_count, NULL);
|
||||||
|
|
||||||
if (mode_count == 0) {
|
if (mode_count == 0) {
|
||||||
SDL_SetError("Vulkan can't find any video modes for display %i (%s)\n", 0,
|
SDL_SetError("Vulkan can't find any video modes for display %i (%s)\n", 0,
|
||||||
displays_props[display_index].displayName);
|
display_props[display_index].displayName);
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the props of the videomodes for the display. */
|
mode_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*mode_props));
|
||||||
modes_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*modes_props));
|
|
||||||
vkGetDisplayModePropertiesKHR(gpu,
|
vkGetDisplayModePropertiesKHR(gpu,
|
||||||
displays_props[display_index].display,
|
display,
|
||||||
&mode_count, modes_props);
|
&mode_count, mode_props);
|
||||||
|
|
||||||
/* Get the planes count of the physical device. */
|
|
||||||
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, NULL);
|
|
||||||
if (plane_count == 0) {
|
|
||||||
SDL_SetError("Vulkan can't find any planes.");
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the props of the planes for the physical device. */
|
|
||||||
planes_props = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count);
|
|
||||||
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, planes_props);
|
|
||||||
|
|
||||||
/* Get a video mode equal to the window size among the predefined ones,
|
/* Get a video mode equal to the window size among the predefined ones,
|
||||||
if possible.
|
if possible.
|
||||||
|
@ -369,10 +365,10 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||||
scanout a region bigger than the window (we would be reading past the
|
scanout a region bigger than the window (we would be reading past the
|
||||||
buffer, and Vulkan would give us a confusing VK_ERROR_SURFACE_LOST_KHR). */
|
buffer, and Vulkan would give us a confusing VK_ERROR_SURFACE_LOST_KHR). */
|
||||||
for (i = 0; i < mode_count; i++) {
|
for (i = 0; i < mode_count; i++) {
|
||||||
if (modes_props[i].parameters.visibleRegion.width == window->w &&
|
if (mode_props[i].parameters.visibleRegion.width == window->w &&
|
||||||
modes_props[i].parameters.visibleRegion.height == window->h)
|
mode_props[i].parameters.visibleRegion.height == window->h)
|
||||||
{
|
{
|
||||||
display_mode_props = modes_props[i];
|
display_mode_props = mode_props[i];
|
||||||
mode_found = SDL_TRUE;
|
mode_found = SDL_TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -399,7 +395,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||||
display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
|
display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
|
||||||
display_mode_create_info.parameters = new_mode_parameters;
|
display_mode_create_info.parameters = new_mode_parameters;
|
||||||
result = vkCreateDisplayModeKHR(gpu,
|
result = vkCreateDisplayModeKHR(gpu,
|
||||||
displays_props[display_index].display,
|
display,
|
||||||
&display_mode_create_info,
|
&display_mode_create_info,
|
||||||
NULL, &display_mode);
|
NULL, &display_mode);
|
||||||
if (result != VK_SUCCESS) {
|
if (result != VK_SUCCESS) {
|
||||||
|
@ -414,6 +410,77 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the list of the physical device planes. */
|
||||||
|
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, NULL);
|
||||||
|
if (plane_count == 0) {
|
||||||
|
SDL_SetError("Vulkan can't find any planes.");
|
||||||
|
goto clean;
|
||||||
|
}
|
||||||
|
plane_props = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count);
|
||||||
|
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, plane_props);
|
||||||
|
|
||||||
|
/* Iterate on the list of planes of the physical device
|
||||||
|
to find a plane that matches these criteria:
|
||||||
|
-It must be compatible with the chosen display + mode.
|
||||||
|
-It isn't currently bound to another display.
|
||||||
|
-It supports per-pixel alpha, if possible. */
|
||||||
|
for (i = 0; i < plane_count; i++) {
|
||||||
|
|
||||||
|
uint32_t supported_displays_count = 0;
|
||||||
|
VkDisplayKHR* supported_displays;
|
||||||
|
|
||||||
|
/* See if the plane is compatible with the current display. */
|
||||||
|
vkGetDisplayPlaneSupportedDisplaysKHR(gpu, i, &supported_displays_count, NULL);
|
||||||
|
if (supported_displays_count == 0) {
|
||||||
|
/* This plane doesn't support any displays. Continue to the next plane. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the list of displays supported by this plane. */
|
||||||
|
supported_displays = (VkDisplayKHR*)malloc(sizeof(VkDisplayKHR) * supported_displays_count);
|
||||||
|
vkGetDisplayPlaneSupportedDisplaysKHR(gpu, i,
|
||||||
|
&supported_displays_count, supported_displays);
|
||||||
|
|
||||||
|
/* The plane must be bound to the chosen display, or not in use.
|
||||||
|
If none of these is true, iterate to another plane. */
|
||||||
|
if (!((plane_props[i].currentDisplay == display) ||
|
||||||
|
(plane_props[i].currentDisplay == VK_NULL_HANDLE)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Iterate the list of displays supported by this plane
|
||||||
|
in order to find out if the chosen display is among them. */
|
||||||
|
plane_supports_display = SDL_FALSE;
|
||||||
|
for (j = 0; j < supported_displays_count; j++) {
|
||||||
|
if (supported_displays[j] == display) {
|
||||||
|
plane_supports_display = SDL_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the list of displays supported by this plane. */
|
||||||
|
if (supported_displays)
|
||||||
|
free(supported_displays);
|
||||||
|
|
||||||
|
/* If the display is not supported by this plane, iterate to the next plane. */
|
||||||
|
if (!plane_supports_display) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Want a plane that supports the alpha mode we have chosen. */
|
||||||
|
vkGetDisplayPlaneCapabilitiesKHR(gpu, display_mode, i, &plane_caps);
|
||||||
|
if (plane_caps.supportedAlpha == alpha_mode) {
|
||||||
|
/* Yep, this plane is alright. */
|
||||||
|
plane = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we couldn't find an appropiate plane, error out. */
|
||||||
|
if (plane == UINT32_MAX) {
|
||||||
|
SDL_SetError("Vulkan couldn't find an appropiate plane.");
|
||||||
|
goto clean;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************/
|
/********************************************/
|
||||||
/* Let's finally create the Vulkan surface! */
|
/* Let's finally create the Vulkan surface! */
|
||||||
/********************************************/
|
/********************************************/
|
||||||
|
@ -424,11 +491,10 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||||
SDL_zero(display_plane_surface_create_info);
|
SDL_zero(display_plane_surface_create_info);
|
||||||
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. */
|
display_plane_surface_create_info.planeIndex = plane;
|
||||||
display_plane_surface_create_info.planeIndex = 0;
|
|
||||||
display_plane_surface_create_info.imageExtent = image_size;
|
display_plane_surface_create_info.imageExtent = image_size;
|
||||||
display_plane_surface_create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
display_plane_surface_create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
||||||
display_plane_surface_create_info.alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
|
display_plane_surface_create_info.alphaMode = alpha_mode;
|
||||||
result = vkCreateDisplayPlaneSurfaceKHR(instance,
|
result = vkCreateDisplayPlaneSurfaceKHR(instance,
|
||||||
&display_plane_surface_create_info,
|
&display_plane_surface_create_info,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -445,14 +511,14 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||||
clean:
|
clean:
|
||||||
if (physical_devices)
|
if (physical_devices)
|
||||||
SDL_free (physical_devices);
|
SDL_free (physical_devices);
|
||||||
if (displays_props)
|
if (display_props)
|
||||||
SDL_free (displays_props);
|
SDL_free (display_props);
|
||||||
if (device_props)
|
if (device_props)
|
||||||
SDL_free (device_props);
|
SDL_free (device_props);
|
||||||
if (planes_props)
|
if (plane_props)
|
||||||
SDL_free (planes_props);
|
SDL_free (plane_props);
|
||||||
if (modes_props)
|
if (mode_props)
|
||||||
SDL_free (modes_props);
|
SDL_free (mode_props);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue