early-access version 2281
This commit is contained in:
+20
-61
@@ -30,6 +30,8 @@
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "../../events/default_cursor.h"
|
||||
|
||||
#include "../SDL_pixels_c.h"
|
||||
|
||||
static SDL_Cursor *KMSDRM_CreateDefaultCursor(void);
|
||||
static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y);
|
||||
static int KMSDRM_ShowCursor(SDL_Cursor * cursor);
|
||||
@@ -59,30 +61,6 @@ KMSDRM_CreateDefaultCursor(void)
|
||||
return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
|
||||
}
|
||||
|
||||
/* Converts a pixel from straight-alpha [AA, RR, GG, BB], which the SDL cursor surface has,
|
||||
to premultiplied-alpha [AA. AA*RR, AA*GG, AA*BB].
|
||||
These multiplications have to be done with floats instead of uint32_t's,
|
||||
and the resulting values have to be converted to be relative to the 0-255 interval,
|
||||
where 255 is 1.00 and anything between 0 and 255 is 0.xx. */
|
||||
void legacy_alpha_premultiply_ARGB8888 (uint32_t *pixel) {
|
||||
|
||||
uint32_t A, R, G, B;
|
||||
|
||||
/* Component bytes extraction. */
|
||||
A = (*pixel >> (3 << 3)) & 0xFF;
|
||||
R = (*pixel >> (2 << 3)) & 0xFF;
|
||||
G = (*pixel >> (1 << 3)) & 0xFF;
|
||||
B = (*pixel >> (0 << 3)) & 0xFF;
|
||||
|
||||
/* Alpha pre-multiplication of each component. */
|
||||
R = (float)A * ((float)R /255);
|
||||
G = (float)A * ((float)G /255);
|
||||
B = (float)A * ((float)B /255);
|
||||
|
||||
/* ARGB8888 pixel recomposition. */
|
||||
(*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
|
||||
}
|
||||
|
||||
/* Given a display's driverdata, destroy the cursor BO for it.
|
||||
To be called from KMSDRM_DestroyWindow(), as that's where we
|
||||
destroy the driverdata for the window's display. */
|
||||
@@ -141,7 +119,7 @@ KMSDRM_CreateCursorBO (SDL_VideoDisplay *display) {
|
||||
}
|
||||
|
||||
/* Remove a cursor buffer from a display's DRM cursor BO. */
|
||||
int
|
||||
static int
|
||||
KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -160,7 +138,7 @@ KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display)
|
||||
}
|
||||
|
||||
/* Dump a cursor buffer to a display's DRM cursor BO. */
|
||||
int
|
||||
static int
|
||||
KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor)
|
||||
{
|
||||
SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata;
|
||||
@@ -171,10 +149,10 @@ KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor)
|
||||
uint32_t bo_handle;
|
||||
size_t bo_stride;
|
||||
size_t bufsize;
|
||||
uint32_t *ready_buffer = NULL;
|
||||
uint32_t pixel;
|
||||
uint8_t *ready_buffer = NULL;
|
||||
uint8_t *src_row;
|
||||
|
||||
int i,j;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (!curdata || !dispdata->cursor_bo) {
|
||||
@@ -186,21 +164,17 @@ KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor)
|
||||
bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo);
|
||||
bufsize = bo_stride * dispdata->cursor_h;
|
||||
|
||||
ready_buffer = (uint32_t*)SDL_calloc(1, bufsize);
|
||||
ready_buffer = (uint8_t*)SDL_calloc(1, bufsize);
|
||||
|
||||
if (!ready_buffer) {
|
||||
ret = SDL_OutOfMemory();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Copy from the cursor buffer to a buffer that we can dump to the GBM BO,
|
||||
pre-multiplying by alpha each pixel as we go. */
|
||||
/* Copy from the cursor buffer to a buffer that we can dump to the GBM BO. */
|
||||
for (i = 0; i < curdata->h; i++) {
|
||||
for (j = 0; j < curdata->w; j++) {
|
||||
pixel = ((uint32_t*)curdata->buffer)[i * curdata->w + j];
|
||||
legacy_alpha_premultiply_ARGB8888 (&pixel);
|
||||
SDL_memcpy(ready_buffer + (i * dispdata->cursor_w) + j, &pixel, 4);
|
||||
}
|
||||
src_row = &((uint8_t*)curdata->buffer)[i * curdata->w * 4];
|
||||
SDL_memcpy(ready_buffer + (i * bo_stride), src_row, 4 * curdata->w);
|
||||
}
|
||||
|
||||
/* Dump the cursor buffer to our GBM BO. */
|
||||
@@ -271,13 +245,6 @@ KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
||||
curdata = NULL;
|
||||
ret = NULL;
|
||||
|
||||
/* All code below assumes ARGB8888 format for the cursor surface,
|
||||
like other backends do. Also, the GBM BO pixels have to be
|
||||
alpha-premultiplied, but the SDL surface we receive has
|
||||
straight-alpha pixels, so we always have to convert. */
|
||||
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
|
||||
SDL_assert(surface->pitch == surface->w * 4);
|
||||
|
||||
cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
|
||||
if (!cursor) {
|
||||
SDL_OutOfMemory();
|
||||
@@ -298,8 +265,8 @@ KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
||||
|
||||
/* Configure the cursor buffer info.
|
||||
This buffer has the original size of the cursor surface we are given. */
|
||||
curdata->buffer_pitch = surface->pitch;
|
||||
curdata->buffer_size = surface->pitch * surface->h;
|
||||
curdata->buffer_pitch = surface->w;
|
||||
curdata->buffer_size = surface->w * surface->h * 4;
|
||||
curdata->buffer = (uint32_t*)SDL_malloc(curdata->buffer_size);
|
||||
|
||||
if (!curdata->buffer) {
|
||||
@@ -307,19 +274,13 @@ KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
if (SDL_LockSurface(surface) < 0) {
|
||||
/* Could not lock surface */
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the surface pixels to the cursor buffer, for future use in ShowCursor() */
|
||||
SDL_memcpy(curdata->buffer, surface->pixels, curdata->buffer_size);
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
/* All code below assumes ARGB8888 format for the cursor surface,
|
||||
like other backends do. Also, the GBM BO pixels have to be
|
||||
alpha-premultiplied, but the SDL surface we receive has
|
||||
straight-alpha pixels, so we always have to convert. */
|
||||
SDL_PremultiplyAlpha(surface->w, surface->h,
|
||||
surface->format->format, surface->pixels, surface->pitch,
|
||||
SDL_PIXELFORMAT_ARGB8888, curdata->buffer, surface->w * 4);
|
||||
|
||||
cursor->driverdata = curdata;
|
||||
|
||||
@@ -442,8 +403,6 @@ KMSDRM_WarpMouseGlobal(int x, int y)
|
||||
} else {
|
||||
return SDL_SetError("No mouse or current cursor.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ extern void KMSDRM_QuitMouse(_THIS);
|
||||
|
||||
extern void KMSDRM_CreateCursorBO(SDL_VideoDisplay *display);
|
||||
extern void KMSDRM_DestroyCursorBO(_THIS, SDL_VideoDisplay *display);
|
||||
extern void KMSDRM_InitCursor();
|
||||
extern void KMSDRM_InitCursor(void);
|
||||
|
||||
#endif /* SDL_KMSDRM_mouse_h_ */
|
||||
|
||||
|
||||
+2
-2
@@ -60,9 +60,9 @@ SDL_KMSDRM_SYM(int,drmModeSetCrtc,(int fd, uint32_t crtcId, uint32_t bufferId,
|
||||
uint32_t x, uint32_t y, uint32_t *connectors, int count,
|
||||
drmModeModeInfoPtr mode))
|
||||
SDL_KMSDRM_SYM(int,drmModeCrtcGetGamma,(int fd, uint32_t crtc_id, uint32_t size,
|
||||
uint16_t *red, uint16_t *green, uint16_t *blue))
|
||||
uint16_t *red, uint16_t *green, uint16_t *blue))
|
||||
SDL_KMSDRM_SYM(int,drmModeCrtcSetGamma,(int fd, uint32_t crtc_id, uint32_t size,
|
||||
uint16_t *red, uint16_t *green, uint16_t *blue))
|
||||
uint16_t *red, uint16_t *green, uint16_t *blue))
|
||||
SDL_KMSDRM_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle,
|
||||
uint32_t width, uint32_t height))
|
||||
SDL_KMSDRM_SYM(int,drmModeSetCursor2,(int fd, uint32_t crtcId, uint32_t bo_handle,
|
||||
|
||||
+13
-12
@@ -141,14 +141,12 @@ static int get_dricount(void)
|
||||
|
||||
if (!(stat(KMSDRM_DRI_PATH, &sb) == 0
|
||||
&& S_ISDIR(sb.st_mode))) {
|
||||
printf("The path %s cannot be opened or is not available\n",
|
||||
KMSDRM_DRI_PATH);
|
||||
/*printf("The path %s cannot be opened or is not available\n", KMSDRM_DRI_PATH);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (access(KMSDRM_DRI_PATH, F_OK) == -1) {
|
||||
printf("The path %s cannot be opened\n",
|
||||
KMSDRM_DRI_PATH);
|
||||
/*printf("The path %s cannot be opened\n", KMSDRM_DRI_PATH);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -473,7 +471,7 @@ KMSDRM_WaitPageflip(_THIS, SDL_WindowData *windata) {
|
||||
available on the DRM connector of the display.
|
||||
We use the SDL mode list (which we filled in KMSDRM_GetDisplayModes)
|
||||
because it's ordered, while the list on the connector is mostly random.*/
|
||||
drmModeModeInfo*
|
||||
static drmModeModeInfo*
|
||||
KMSDRM_GetClosestDisplayMode(SDL_VideoDisplay * display,
|
||||
uint32_t width, uint32_t height, uint32_t refresh_rate){
|
||||
|
||||
@@ -504,7 +502,8 @@ uint32_t width, uint32_t height, uint32_t refresh_rate){
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Deinitializes the driverdata of the SDL Displays in the SDL display list. */
|
||||
void KMSDRM_DeinitDisplays (_THIS) {
|
||||
static void
|
||||
KMSDRM_DeinitDisplays (_THIS) {
|
||||
|
||||
SDL_DisplayData *dispdata;
|
||||
int num_displays, i;
|
||||
@@ -533,7 +532,8 @@ void KMSDRM_DeinitDisplays (_THIS) {
|
||||
|
||||
/* Gets a DRM connector, builds an SDL_Display with it, and adds it to the
|
||||
list of SDL Displays in _this->displays[] */
|
||||
void KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) {
|
||||
static void
|
||||
KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) {
|
||||
|
||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||
SDL_DisplayData *dispdata = NULL;
|
||||
@@ -721,7 +721,8 @@ cleanup:
|
||||
closed when we get to the end of this function.
|
||||
This is to be called early, in VideoInit(), because it gets us
|
||||
the videomode information, which SDL needs immediately after VideoInit(). */
|
||||
int KMSDRM_InitDisplays (_THIS) {
|
||||
static int
|
||||
KMSDRM_InitDisplays (_THIS) {
|
||||
|
||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||
drmModeRes *resources = NULL;
|
||||
@@ -815,7 +816,7 @@ cleanup:
|
||||
These things are incompatible with Vulkan, which accesses the same resources
|
||||
internally so they must be free when trying to build a Vulkan surface.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
KMSDRM_GBMInit (_THIS, SDL_DisplayData *dispdata)
|
||||
{
|
||||
SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
|
||||
@@ -839,7 +840,7 @@ KMSDRM_GBMInit (_THIS, SDL_DisplayData *dispdata)
|
||||
}
|
||||
|
||||
/* Deinit the Vulkan-incompatible KMSDRM stuff. */
|
||||
void
|
||||
static void
|
||||
KMSDRM_GBMDeinit (_THIS, SDL_DisplayData *dispdata)
|
||||
{
|
||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||
@@ -860,7 +861,7 @@ KMSDRM_GBMDeinit (_THIS, SDL_DisplayData *dispdata)
|
||||
viddata->gbm_init = SDL_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
KMSDRM_DestroySurfaces(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||
@@ -871,7 +872,7 @@ KMSDRM_DestroySurfaces(_THIS, SDL_Window *window)
|
||||
/**********************************************/
|
||||
/* Wait for last issued pageflip to complete. */
|
||||
/**********************************************/
|
||||
KMSDRM_WaitPageflip(_this, windata);
|
||||
/*KMSDRM_WaitPageflip(_this, windata);*/
|
||||
|
||||
/***********************************************************************/
|
||||
/* Restore the original CRTC configuration: configue the crtc with the */
|
||||
|
||||
+108
-41
@@ -182,34 +182,40 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||
VkInstance instance,
|
||||
VkSurfaceKHR *surface)
|
||||
{
|
||||
VkPhysicalDevice gpu;
|
||||
VkPhysicalDevice gpu = NULL;
|
||||
uint32_t gpu_count;
|
||||
uint32_t display_count;
|
||||
uint32_t mode_count;
|
||||
uint32_t plane_count;
|
||||
uint32_t plane = UINT32_MAX;
|
||||
|
||||
VkPhysicalDevice *physical_devices = NULL;
|
||||
VkPhysicalDeviceProperties *device_props = NULL;
|
||||
VkDisplayPropertiesKHR *displays_props = NULL;
|
||||
VkDisplayModePropertiesKHR *modes_props = NULL;
|
||||
VkDisplayPlanePropertiesKHR *planes_props = NULL;
|
||||
VkDisplayPropertiesKHR *display_props = NULL;
|
||||
VkDisplayModePropertiesKHR *mode_props = NULL;
|
||||
VkDisplayPlanePropertiesKHR *plane_props = NULL;
|
||||
VkDisplayPlaneCapabilitiesKHR plane_caps;
|
||||
|
||||
VkDisplayModeCreateInfoKHR display_mode_create_info;
|
||||
VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info;
|
||||
|
||||
VkExtent2D image_size;
|
||||
VkDisplayKHR display;
|
||||
VkDisplayModeKHR display_mode = (VkDisplayModeKHR)0;
|
||||
VkDisplayModePropertiesKHR display_mode_props = {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;
|
||||
SDL_bool ret = SDL_FALSE;
|
||||
SDL_bool valid_gpu = 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. */
|
||||
int display_index = SDL_atoi(SDL_GetDisplayForWindow(window)->name);
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
/* Get the function pointers for the functions we will use. */
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
|
||||
@@ -239,14 +245,13 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||
(PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)vkGetInstanceProcAddr(
|
||||
instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
|
||||
|
||||
/*PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR =
|
||||
PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR =
|
||||
(PFN_vkGetDisplayPlaneSupportedDisplaysKHR)vkGetInstanceProcAddr(
|
||||
instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
|
||||
|
||||
|
||||
PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR =
|
||||
(PFN_vkGetDisplayPlaneCapabilitiesKHR)vkGetInstanceProcAddr(
|
||||
instance, "vkGetDisplayPlaneCapabilitiesKHR");
|
||||
*/
|
||||
|
||||
PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR =
|
||||
(PFN_vkCreateDisplayModeKHR)vkGetInstanceProcAddr(
|
||||
@@ -329,38 +334,29 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||
}
|
||||
|
||||
/* 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,
|
||||
&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,
|
||||
displays_props[display_index].display,
|
||||
display,
|
||||
&mode_count, NULL);
|
||||
|
||||
if (mode_count == 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;
|
||||
}
|
||||
|
||||
/* Get the props of the videomodes for the display. */
|
||||
modes_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*modes_props));
|
||||
mode_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*mode_props));
|
||||
vkGetDisplayModePropertiesKHR(gpu,
|
||||
displays_props[display_index].display,
|
||||
&mode_count, modes_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);
|
||||
display,
|
||||
&mode_count, mode_props);
|
||||
|
||||
/* Get a video mode equal to the window size among the predefined ones,
|
||||
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
|
||||
buffer, and Vulkan would give us a confusing VK_ERROR_SURFACE_LOST_KHR). */
|
||||
for (i = 0; i < mode_count; i++) {
|
||||
if (modes_props[i].parameters.visibleRegion.width == window->w &&
|
||||
modes_props[i].parameters.visibleRegion.height == window->h)
|
||||
if (mode_props[i].parameters.visibleRegion.width == window->w &&
|
||||
mode_props[i].parameters.visibleRegion.height == window->h)
|
||||
{
|
||||
display_mode_props = modes_props[i];
|
||||
display_mode_props = mode_props[i];
|
||||
mode_found = SDL_TRUE;
|
||||
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.parameters = new_mode_parameters;
|
||||
result = vkCreateDisplayModeKHR(gpu,
|
||||
displays_props[display_index].display,
|
||||
display,
|
||||
&display_mode_create_info,
|
||||
NULL, &display_mode);
|
||||
if (result != VK_SUCCESS) {
|
||||
@@ -414,6 +410,78 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||
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*)SDL_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) {
|
||||
SDL_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! */
|
||||
/********************************************/
|
||||
@@ -424,11 +492,10 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||
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.displayMode = display_mode;
|
||||
/* For now, simply use the first plane. */
|
||||
display_plane_surface_create_info.planeIndex = 0;
|
||||
display_plane_surface_create_info.planeIndex = plane;
|
||||
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.alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
|
||||
display_plane_surface_create_info.alphaMode = alpha_mode;
|
||||
result = vkCreateDisplayPlaneSurfaceKHR(instance,
|
||||
&display_plane_surface_create_info,
|
||||
NULL,
|
||||
@@ -445,14 +512,14 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
|
||||
clean:
|
||||
if (physical_devices)
|
||||
SDL_free (physical_devices);
|
||||
if (displays_props)
|
||||
SDL_free (displays_props);
|
||||
if (display_props)
|
||||
SDL_free (display_props);
|
||||
if (device_props)
|
||||
SDL_free (device_props);
|
||||
if (planes_props)
|
||||
SDL_free (planes_props);
|
||||
if (modes_props)
|
||||
SDL_free (modes_props);
|
||||
if (plane_props)
|
||||
SDL_free (plane_props);
|
||||
if (mode_props)
|
||||
SDL_free (mode_props);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user