early-access version 2281

This commit is contained in:
pineappleEA
2021-12-07 02:20:09 +01:00
parent c2ae6d480a
commit c4fa174d53
591 changed files with 36978 additions and 18653 deletions
+20 -61
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}