mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-14 03:52:30 +00:00
chore(build): use SDL3
This commit is contained in:
parent
9d04a35d87
commit
b3c0734a9e
3286 changed files with 866354 additions and 554996 deletions
161
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmdyn.c
vendored
Normal file
161
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmdyn.c
vendored
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_KMSDRM
|
||||
|
||||
#define DEBUG_DYNAMIC_KMSDRM 0
|
||||
|
||||
#include "SDL_kmsdrmdyn.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *lib;
|
||||
const char *libname;
|
||||
} kmsdrmdynlib;
|
||||
|
||||
#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM
|
||||
#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM NULL
|
||||
#endif
|
||||
|
||||
static kmsdrmdynlib kmsdrmlibs[] = {
|
||||
{ NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM },
|
||||
{ NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC }
|
||||
};
|
||||
|
||||
static void *KMSDRM_GetSym(const char *fnname, int *pHasModule, bool required)
|
||||
{
|
||||
int i;
|
||||
void *fn = NULL;
|
||||
for (i = 0; i < SDL_arraysize(kmsdrmlibs); i++) {
|
||||
if (kmsdrmlibs[i].lib) {
|
||||
fn = SDL_LoadFunction(kmsdrmlibs[i].lib, fnname);
|
||||
if (fn) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG_DYNAMIC_KMSDRM
|
||||
if (fn)
|
||||
SDL_Log("KMSDRM: Found '%s' in %s (%p)", fnname, kmsdrmlibs[i].libname, fn);
|
||||
else
|
||||
SDL_Log("KMSDRM: Symbol '%s' NOT FOUND!", fnname);
|
||||
#endif
|
||||
|
||||
if (!fn && required) {
|
||||
*pHasModule = 0; // kill this module.
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
#endif // SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
|
||||
|
||||
// Define all the function pointers and wrappers...
|
||||
#define SDL_KMSDRM_MODULE(modname) int SDL_KMSDRM_HAVE_##modname = 0;
|
||||
#define SDL_KMSDRM_SYM(rc, fn, params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL;
|
||||
#define SDL_KMSDRM_SYM_CONST(type, name) SDL_DYNKMSDRMCONST_##name KMSDRM_##name = NULL;
|
||||
#define SDL_KMSDRM_SYM_OPT(rc, fn, params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL;
|
||||
#include "SDL_kmsdrmsym.h"
|
||||
|
||||
static int kmsdrm_load_refcount = 0;
|
||||
|
||||
void SDL_KMSDRM_UnloadSymbols(void)
|
||||
{
|
||||
// Don't actually unload if more than one module is using the libs...
|
||||
if (kmsdrm_load_refcount > 0) {
|
||||
if (--kmsdrm_load_refcount == 0) {
|
||||
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
|
||||
int i;
|
||||
#endif
|
||||
|
||||
// set all the function pointers to NULL.
|
||||
#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 0;
|
||||
#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = NULL;
|
||||
#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = NULL;
|
||||
#define SDL_KMSDRM_SYM_OPT(rc, fn, params) KMSDRM_##fn = NULL;
|
||||
#include "SDL_kmsdrmsym.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
|
||||
for (i = 0; i < SDL_arraysize(kmsdrmlibs); i++) {
|
||||
if (kmsdrmlibs[i].lib) {
|
||||
SDL_UnloadObject(kmsdrmlibs[i].lib);
|
||||
kmsdrmlibs[i].lib = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns non-zero if all needed symbols were loaded.
|
||||
bool SDL_KMSDRM_LoadSymbols(void)
|
||||
{
|
||||
bool result = true; // always succeed if not using Dynamic KMSDRM stuff.
|
||||
|
||||
// deal with multiple modules needing these symbols...
|
||||
if (kmsdrm_load_refcount++ == 0) {
|
||||
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
|
||||
int i;
|
||||
int *thismod = NULL;
|
||||
for (i = 0; i < SDL_arraysize(kmsdrmlibs); i++) {
|
||||
if (kmsdrmlibs[i].libname) {
|
||||
kmsdrmlibs[i].lib = SDL_LoadObject(kmsdrmlibs[i].libname);
|
||||
}
|
||||
}
|
||||
|
||||
#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; // default yes
|
||||
#include "SDL_kmsdrmsym.h"
|
||||
|
||||
#define SDL_KMSDRM_MODULE(modname) thismod = &SDL_KMSDRM_HAVE_##modname;
|
||||
#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn)KMSDRM_GetSym(#fn, thismod, true);
|
||||
#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = *(SDL_DYNKMSDRMCONST_##name *)KMSDRM_GetSym(#name, thismod, true);
|
||||
#define SDL_KMSDRM_SYM_OPT(rc, fn, params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn)KMSDRM_GetSym(#fn, thismod, false);
|
||||
#include "SDL_kmsdrmsym.h"
|
||||
|
||||
if ((SDL_KMSDRM_HAVE_LIBDRM) && (SDL_KMSDRM_HAVE_GBM)) {
|
||||
// all required symbols loaded.
|
||||
SDL_ClearError();
|
||||
} else {
|
||||
// in case something got loaded...
|
||||
SDL_KMSDRM_UnloadSymbols();
|
||||
result = false;
|
||||
}
|
||||
|
||||
#else // no dynamic KMSDRM
|
||||
|
||||
#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; // default yes
|
||||
#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = fn;
|
||||
#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = name;
|
||||
#define SDL_KMSDRM_SYM_OPT(rc, fn, params) KMSDRM_##fn = fn;
|
||||
#include "SDL_kmsdrmsym.h"
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // SDL_VIDEO_DRIVER_KMSDRM
|
||||
54
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmdyn.h
vendored
Normal file
54
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmdyn.h
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_kmsdrmdyn_h_
|
||||
#define SDL_kmsdrmdyn_h_
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include <gbm.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern bool SDL_KMSDRM_LoadSymbols(void);
|
||||
extern void SDL_KMSDRM_UnloadSymbols(void);
|
||||
|
||||
// Declare all the function pointers and wrappers...
|
||||
#define SDL_KMSDRM_SYM(rc, fn, params) \
|
||||
typedef rc(*SDL_DYNKMSDRMFN_##fn) params; \
|
||||
extern SDL_DYNKMSDRMFN_##fn KMSDRM_##fn;
|
||||
#define SDL_KMSDRM_SYM_CONST(type, name) \
|
||||
typedef type SDL_DYNKMSDRMCONST_##name; \
|
||||
extern SDL_DYNKMSDRMCONST_##name KMSDRM_##name;
|
||||
#define SDL_KMSDRM_SYM_OPT(rc, fn, params) \
|
||||
typedef rc(*SDL_DYNKMSDRMFN_##fn) params; \
|
||||
extern SDL_DYNKMSDRMFN_##fn KMSDRM_##fn;
|
||||
#include "SDL_kmsdrmsym.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDL_kmsdrmdyn_h_
|
||||
44
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmevents.c
vendored
Normal file
44
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmevents.c
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_KMSDRM
|
||||
|
||||
#include "SDL_kmsdrmvideo.h"
|
||||
#include "SDL_kmsdrmevents.h"
|
||||
|
||||
#ifdef SDL_INPUT_LINUXEV
|
||||
#include "../../core/linux/SDL_evdev.h"
|
||||
#elif defined SDL_INPUT_WSCONS
|
||||
#include "../../core/openbsd/SDL_wscons.h"
|
||||
#endif
|
||||
|
||||
void KMSDRM_PumpEvents(SDL_VideoDevice *_this)
|
||||
{
|
||||
#ifdef SDL_INPUT_LINUXEV
|
||||
SDL_EVDEV_Poll();
|
||||
#elif defined SDL_INPUT_WSCONS
|
||||
SDL_WSCONS_PumpEvents();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // SDL_VIDEO_DRIVER_KMSDRM
|
||||
29
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmevents.h
vendored
Normal file
29
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmevents.h
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_kmsdrmevents_h_
|
||||
#define SDL_kmsdrmevents_h_
|
||||
|
||||
extern void KMSDRM_PumpEvents(SDL_VideoDevice *_this);
|
||||
|
||||
#endif // SDL_kmsdrmevents_h_
|
||||
410
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmmouse.c
vendored
Normal file
410
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmmouse.c
vendored
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_KMSDRM
|
||||
|
||||
#include "SDL_kmsdrmvideo.h"
|
||||
#include "SDL_kmsdrmmouse.h"
|
||||
#include "SDL_kmsdrmdyn.h"
|
||||
|
||||
#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 bool KMSDRM_ShowCursor(SDL_Cursor *cursor);
|
||||
static bool KMSDRM_MoveCursor(SDL_Cursor *cursor);
|
||||
static void KMSDRM_FreeCursor(SDL_Cursor *cursor);
|
||||
|
||||
/**************************************************************************************/
|
||||
// BEFORE CODING ANYTHING MOUSE/CURSOR RELATED, REMEMBER THIS.
|
||||
// How does SDL manage cursors internally? First, mouse =! cursor. The mouse can have
|
||||
// many cursors in mouse->cursors.
|
||||
// -SDL tells us to create a cursor with KMSDRM_CreateCursor(). It can create many
|
||||
// cursosr with this, not only one.
|
||||
// -SDL stores those cursors in a cursors array, in mouse->cursors.
|
||||
// -Whenever it wants (or the programmer wants) takes a cursor from that array
|
||||
// and shows it on screen with KMSDRM_ShowCursor().
|
||||
// KMSDRM_ShowCursor() simply shows or hides the cursor it receives: it does NOT
|
||||
// mind if it's mouse->cur_cursor, etc.
|
||||
// -If KMSDRM_ShowCursor() returns successfully, that cursor becomes
|
||||
// mouse->cur_cursor and mouse->cursor_shown is 1.
|
||||
/**************************************************************************************/
|
||||
|
||||
static SDL_Cursor *KMSDRM_CreateDefaultCursor(void)
|
||||
{
|
||||
return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
|
||||
}
|
||||
|
||||
/* Given a display's internal, destroy the cursor BO for it.
|
||||
To be called from KMSDRM_DestroyWindow(), as that's where we
|
||||
destroy the internal for the window's display. */
|
||||
void KMSDRM_DestroyCursorBO(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
|
||||
{
|
||||
SDL_DisplayData *dispdata = display->internal;
|
||||
|
||||
// Destroy the curso GBM BO.
|
||||
if (dispdata->cursor_bo) {
|
||||
KMSDRM_gbm_bo_destroy(dispdata->cursor_bo);
|
||||
dispdata->cursor_bo = NULL;
|
||||
dispdata->cursor_bo_drm_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a display's internal, create the cursor BO for it.
|
||||
To be called from KMSDRM_CreateWindow(), as that's where we
|
||||
build a window and assign a display to it. */
|
||||
bool KMSDRM_CreateCursorBO(SDL_VideoDisplay *display)
|
||||
{
|
||||
|
||||
SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
||||
SDL_VideoData *viddata = dev->internal;
|
||||
SDL_DisplayData *dispdata = display->internal;
|
||||
|
||||
if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev,
|
||||
GBM_FORMAT_ARGB8888,
|
||||
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) {
|
||||
return SDL_SetError("Unsupported pixel format for cursor");
|
||||
}
|
||||
|
||||
if (KMSDRM_drmGetCap(viddata->drm_fd,
|
||||
DRM_CAP_CURSOR_WIDTH, &dispdata->cursor_w) ||
|
||||
KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT,
|
||||
&dispdata->cursor_h)) {
|
||||
return SDL_SetError("Could not get the recommended GBM cursor size");
|
||||
}
|
||||
|
||||
if (dispdata->cursor_w == 0 || dispdata->cursor_h == 0) {
|
||||
return SDL_SetError("Could not get an usable GBM cursor size");
|
||||
}
|
||||
|
||||
dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev,
|
||||
dispdata->cursor_w, dispdata->cursor_h,
|
||||
GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR);
|
||||
|
||||
if (!dispdata->cursor_bo) {
|
||||
return SDL_SetError("Could not create GBM cursor BO");
|
||||
}
|
||||
|
||||
dispdata->cursor_bo_drm_fd = viddata->drm_fd;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Remove a cursor buffer from a display's DRM cursor BO.
|
||||
static bool KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
SDL_DisplayData *dispdata = display->internal;
|
||||
SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
||||
SDL_VideoData *viddata = video_device->internal;
|
||||
|
||||
const int rc = KMSDRM_drmModeSetCursor(viddata->drm_fd, dispdata->crtc->crtc_id, 0, 0, 0);
|
||||
if (rc < 0) {
|
||||
result = SDL_SetError("drmModeSetCursor() failed: %s", strerror(-rc));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Dump a cursor buffer to a display's DRM cursor BO.
|
||||
static bool KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor)
|
||||
{
|
||||
SDL_DisplayData *dispdata = display->internal;
|
||||
SDL_CursorData *curdata = cursor->internal;
|
||||
SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
||||
SDL_VideoData *viddata = video_device->internal;
|
||||
|
||||
uint32_t bo_handle;
|
||||
size_t bo_stride;
|
||||
size_t bufsize;
|
||||
uint8_t *ready_buffer = NULL;
|
||||
uint8_t *src_row;
|
||||
|
||||
int i, rc;
|
||||
bool result = true;
|
||||
|
||||
if (!curdata || !dispdata->cursor_bo) {
|
||||
return SDL_SetError("Cursor or display not initialized properly.");
|
||||
}
|
||||
|
||||
/* Prepare a buffer we can dump to our GBM BO (different
|
||||
size, alpha premultiplication...) */
|
||||
bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo);
|
||||
bufsize = bo_stride * dispdata->cursor_h;
|
||||
|
||||
ready_buffer = (uint8_t *)SDL_calloc(1, bufsize);
|
||||
|
||||
if (!ready_buffer) {
|
||||
result = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Copy from the cursor buffer to a buffer that we can dump to the GBM BO.
|
||||
for (i = 0; i < curdata->h; i++) {
|
||||
src_row = &((uint8_t *)curdata->buffer)[i * curdata->w * 4];
|
||||
SDL_memcpy(ready_buffer + (i * bo_stride), src_row, (size_t)4 * curdata->w);
|
||||
}
|
||||
|
||||
// Dump the cursor buffer to our GBM BO.
|
||||
if (KMSDRM_gbm_bo_write(dispdata->cursor_bo, ready_buffer, bufsize)) {
|
||||
result = SDL_SetError("Could not write to GBM cursor BO");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Put the GBM BO buffer on screen using the DRM interface.
|
||||
bo_handle = KMSDRM_gbm_bo_get_handle(dispdata->cursor_bo).u32;
|
||||
if (curdata->hot_x == 0 && curdata->hot_y == 0) {
|
||||
rc = KMSDRM_drmModeSetCursor(viddata->drm_fd, dispdata->crtc->crtc_id,
|
||||
bo_handle, dispdata->cursor_w, dispdata->cursor_h);
|
||||
} else {
|
||||
rc = KMSDRM_drmModeSetCursor2(viddata->drm_fd, dispdata->crtc->crtc_id,
|
||||
bo_handle, dispdata->cursor_w, dispdata->cursor_h, curdata->hot_x, curdata->hot_y);
|
||||
}
|
||||
if (rc < 0) {
|
||||
result = SDL_SetError("Failed to set DRM cursor: %s", strerror(-rc));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
if (ready_buffer) {
|
||||
SDL_free(ready_buffer);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// This is only for freeing the SDL_cursor.
|
||||
static void KMSDRM_FreeCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
SDL_CursorData *curdata;
|
||||
|
||||
// Even if the cursor is not ours, free it.
|
||||
if (cursor) {
|
||||
curdata = cursor->internal;
|
||||
// Free cursor buffer
|
||||
if (curdata->buffer) {
|
||||
SDL_free(curdata->buffer);
|
||||
curdata->buffer = NULL;
|
||||
}
|
||||
// Free cursor itself
|
||||
if (cursor->internal) {
|
||||
SDL_free(cursor->internal);
|
||||
}
|
||||
SDL_free(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
/* This simply gets the cursor soft-buffer ready.
|
||||
We don't copy it to a GBO BO until ShowCursor() because the cusor GBM BO (living
|
||||
in dispata) is destroyed and recreated when we recreate windows, etc. */
|
||||
static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
||||
{
|
||||
SDL_CursorData *curdata;
|
||||
SDL_Cursor *cursor, *result;
|
||||
|
||||
curdata = NULL;
|
||||
result = NULL;
|
||||
|
||||
cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
|
||||
if (!cursor) {
|
||||
goto cleanup;
|
||||
}
|
||||
curdata = (SDL_CursorData *)SDL_calloc(1, sizeof(*curdata));
|
||||
if (!curdata) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// hox_x and hot_y are the coordinates of the "tip of the cursor" from it's base.
|
||||
curdata->hot_x = hot_x;
|
||||
curdata->hot_y = hot_y;
|
||||
curdata->w = surface->w;
|
||||
curdata->h = surface->h;
|
||||
curdata->buffer = NULL;
|
||||
|
||||
/* Configure the cursor buffer info.
|
||||
This buffer has the original size of the cursor surface we are given. */
|
||||
curdata->buffer_pitch = surface->w;
|
||||
curdata->buffer_size = (size_t)surface->w * surface->h * 4;
|
||||
curdata->buffer = (uint32_t *)SDL_malloc(curdata->buffer_size);
|
||||
|
||||
if (!curdata->buffer) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* 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, surface->pixels, surface->pitch,
|
||||
SDL_PIXELFORMAT_ARGB8888, curdata->buffer, surface->w * 4, true);
|
||||
|
||||
cursor->internal = curdata;
|
||||
|
||||
result = cursor;
|
||||
|
||||
cleanup:
|
||||
if (!result) {
|
||||
if (curdata) {
|
||||
if (curdata->buffer) {
|
||||
SDL_free(curdata->buffer);
|
||||
}
|
||||
SDL_free(curdata);
|
||||
}
|
||||
if (cursor) {
|
||||
SDL_free(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Show the specified cursor, or hide if cursor is NULL or has no focus.
|
||||
static bool KMSDRM_ShowCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
SDL_VideoDisplay *display;
|
||||
SDL_Window *window;
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
int i;
|
||||
bool result = true;
|
||||
|
||||
// Get the mouse focused window, if any.
|
||||
window = mouse->focus;
|
||||
|
||||
if (!window || !cursor) {
|
||||
/* If no window is focused by mouse or cursor is NULL,
|
||||
since we have no window (no mouse->focus) and hence
|
||||
we have no display, we simply hide mouse on all displays.
|
||||
This happens on video quit, where we get here after
|
||||
the mouse focus has been unset, yet SDL wants to
|
||||
restore the system default cursor (makes no sense here). */
|
||||
SDL_DisplayID *displays = SDL_GetDisplays(NULL);
|
||||
if (displays) {
|
||||
// Iterate on the displays, hiding the cursor.
|
||||
for (i = 0; i < displays[i]; i++) {
|
||||
display = SDL_GetVideoDisplay(displays[i]);
|
||||
result = KMSDRM_RemoveCursorFromBO(display);
|
||||
}
|
||||
SDL_free(displays);
|
||||
}
|
||||
} else {
|
||||
display = SDL_GetVideoDisplayForWindow(window);
|
||||
if (display) {
|
||||
if (cursor) {
|
||||
/* Dump the cursor to the display DRM cursor BO so it becomes visible
|
||||
on that display. */
|
||||
result = KMSDRM_DumpCursorToBO(display, cursor);
|
||||
} else {
|
||||
// Hide the cursor on that display.
|
||||
result = KMSDRM_RemoveCursorFromBO(display);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool KMSDRM_WarpMouseGlobal(float x, float y)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
if (mouse && mouse->cur_cursor && mouse->focus) {
|
||||
SDL_Window *window = mouse->focus;
|
||||
SDL_DisplayData *dispdata = SDL_GetDisplayDriverDataForWindow(window);
|
||||
|
||||
// Update internal mouse position.
|
||||
SDL_SendMouseMotion(0, mouse->focus, SDL_GLOBAL_MOUSE_ID, false, x, y);
|
||||
|
||||
// And now update the cursor graphic position on screen.
|
||||
if (dispdata->cursor_bo) {
|
||||
const int rc = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, (int)x, (int)y);
|
||||
if (rc < 0) {
|
||||
return SDL_SetError("drmModeMoveCursor() failed: %s", strerror(-rc));
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return SDL_SetError("Cursor not initialized properly.");
|
||||
}
|
||||
} else {
|
||||
return SDL_SetError("No mouse or current cursor.");
|
||||
}
|
||||
}
|
||||
|
||||
static bool KMSDRM_WarpMouse(SDL_Window *window, float x, float y)
|
||||
{
|
||||
// Only one global/fullscreen window is supported
|
||||
return KMSDRM_WarpMouseGlobal(x, y);
|
||||
}
|
||||
|
||||
void KMSDRM_InitMouse(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
SDL_DisplayData *dispdata = display->internal;
|
||||
|
||||
mouse->CreateCursor = KMSDRM_CreateCursor;
|
||||
mouse->ShowCursor = KMSDRM_ShowCursor;
|
||||
mouse->MoveCursor = KMSDRM_MoveCursor;
|
||||
mouse->FreeCursor = KMSDRM_FreeCursor;
|
||||
mouse->WarpMouse = KMSDRM_WarpMouse;
|
||||
mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal;
|
||||
|
||||
/* Only create the default cursor for this display if we haven't done so before,
|
||||
we don't want several cursors to be created for the same display. */
|
||||
if (!dispdata->default_cursor_init) {
|
||||
SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor());
|
||||
dispdata->default_cursor_init = true;
|
||||
}
|
||||
}
|
||||
|
||||
void KMSDRM_QuitMouse(SDL_VideoDevice *_this)
|
||||
{
|
||||
// TODO: ?
|
||||
}
|
||||
|
||||
// This is called when a mouse motion event occurs
|
||||
static bool KMSDRM_MoveCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
/* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
|
||||
That's why we move the cursor graphic ONLY. */
|
||||
if (mouse && mouse->cur_cursor && mouse->focus) {
|
||||
SDL_Window *window = mouse->focus;
|
||||
SDL_DisplayData *dispdata = SDL_GetDisplayDriverDataForWindow(window);
|
||||
|
||||
if (!dispdata->cursor_bo) {
|
||||
return SDL_SetError("Cursor not initialized properly.");
|
||||
}
|
||||
|
||||
const int rc = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, (int)mouse->x, (int)mouse->y);
|
||||
if (rc < 0) {
|
||||
return SDL_SetError("drmModeMoveCursor() failed: %s", strerror(-rc));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // SDL_VIDEO_DRIVER_KMSDRM
|
||||
53
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmmouse.h
vendored
Normal file
53
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmmouse.h
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_KMSDRM_mouse_h_
|
||||
#define SDL_KMSDRM_mouse_h_
|
||||
|
||||
#include <gbm.h>
|
||||
|
||||
#define MAX_CURSOR_W 512
|
||||
#define MAX_CURSOR_H 512
|
||||
|
||||
struct SDL_CursorData
|
||||
{
|
||||
int hot_x, hot_y;
|
||||
int w, h;
|
||||
|
||||
/* The buffer where we store the mouse bitmap ready to be used.
|
||||
We get it ready and filled in CreateCursor(), and copy it
|
||||
to a GBM BO in ShowCursor().*/
|
||||
uint32_t *buffer;
|
||||
size_t buffer_size;
|
||||
size_t buffer_pitch;
|
||||
|
||||
};
|
||||
|
||||
extern void KMSDRM_InitMouse(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
|
||||
extern void KMSDRM_QuitMouse(SDL_VideoDevice *_this);
|
||||
|
||||
extern bool KMSDRM_CreateCursorBO(SDL_VideoDisplay *display);
|
||||
extern void KMSDRM_DestroyCursorBO(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
|
||||
extern void KMSDRM_InitCursor(void);
|
||||
|
||||
#endif // SDL_KMSDRM_mouse_h_
|
||||
203
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmopengles.c
vendored
Normal file
203
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmopengles.c
vendored
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_KMSDRM
|
||||
|
||||
#include "SDL_kmsdrmvideo.h"
|
||||
#include "SDL_kmsdrmopengles.h"
|
||||
#include "SDL_kmsdrmdyn.h"
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef EGL_PLATFORM_GBM_MESA
|
||||
#define EGL_PLATFORM_GBM_MESA 0x31D7
|
||||
#endif
|
||||
|
||||
// EGL implementation of SDL OpenGL support
|
||||
|
||||
void KMSDRM_GLES_DefaultProfileConfig(SDL_VideoDevice *_this, int *mask, int *major, int *minor)
|
||||
{
|
||||
/* if SDL was _also_ built with the Raspberry Pi driver (so we're
|
||||
definitely a Pi device) or with the ROCKCHIP video driver
|
||||
(it's a ROCKCHIP device), default to GLES2. */
|
||||
#if defined(SDL_VIDEO_DRIVER_RPI) || defined(SDL_VIDEO_DRIVER_ROCKCHIP)
|
||||
*mask = SDL_GL_CONTEXT_PROFILE_ES;
|
||||
*major = 2;
|
||||
*minor = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool KMSDRM_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path)
|
||||
{
|
||||
/* Just pretend you do this here, but don't do it until KMSDRM_CreateWindow(),
|
||||
where we do the same library load we would normally do here.
|
||||
because this gets called by SDL_CreateWindow() before KMSDR_CreateWindow(),
|
||||
so gbm dev isn't yet created when this is called, AND we can't alter the
|
||||
call order in SDL_CreateWindow(). */
|
||||
#if 0
|
||||
NativeDisplayType display = (NativeDisplayType)_this->internal->gbm_dev;
|
||||
return SDL_EGL_LoadLibrary(_this, path, display, EGL_PLATFORM_GBM_MESA);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void KMSDRM_GLES_UnloadLibrary(SDL_VideoDevice *_this)
|
||||
{
|
||||
/* As with KMSDRM_GLES_LoadLibrary(), we define our own "dummy" unloading function
|
||||
so we manually unload the library whenever we want. */
|
||||
}
|
||||
|
||||
SDL_EGL_CreateContext_impl(KMSDRM)
|
||||
|
||||
bool KMSDRM_GLES_SetSwapInterval(SDL_VideoDevice *_this, int interval)
|
||||
{
|
||||
if (!_this->egl_data) {
|
||||
return SDL_SetError("EGL not initialized");
|
||||
}
|
||||
|
||||
if (interval == 0 || interval == 1) {
|
||||
_this->egl_data->egl_swapinterval = interval;
|
||||
} else {
|
||||
return SDL_SetError("Only swap intervals of 0 or 1 are supported");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KMSDRM_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *windata = window->internal;
|
||||
SDL_DisplayData *dispdata = SDL_GetDisplayDriverDataForWindow(window);
|
||||
SDL_VideoData *viddata = _this->internal;
|
||||
KMSDRM_FBInfo *fb_info;
|
||||
int ret = 0;
|
||||
|
||||
/* Always wait for the previous issued flip before issuing a new one,
|
||||
even if you do async flips. */
|
||||
uint32_t flip_flags = DRM_MODE_PAGE_FLIP_EVENT;
|
||||
|
||||
// Skip the swap if we've switched away to another VT
|
||||
if (windata->egl_surface == EGL_NO_SURFACE) {
|
||||
// Wait a bit, throttling to ~100 FPS
|
||||
SDL_Delay(10);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Recreate the GBM / EGL surfaces if the display mode has changed
|
||||
if (windata->egl_surface_dirty) {
|
||||
KMSDRM_CreateSurfaces(_this, window);
|
||||
}
|
||||
|
||||
/* Wait for confirmation that the next front buffer has been flipped, at which
|
||||
point the previous front buffer can be released */
|
||||
if (!KMSDRM_WaitPageflip(_this, windata)) {
|
||||
return SDL_SetError("Wait for previous pageflip failed");
|
||||
}
|
||||
|
||||
// Release the previous front buffer
|
||||
if (windata->bo) {
|
||||
KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo);
|
||||
windata->bo = NULL;
|
||||
}
|
||||
|
||||
windata->bo = windata->next_bo;
|
||||
|
||||
/* Mark a buffer to become the next front buffer.
|
||||
This won't happen until pagelip completes. */
|
||||
if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display,
|
||||
windata->egl_surface))) {
|
||||
return SDL_SetError("eglSwapBuffers failed");
|
||||
}
|
||||
|
||||
/* From the GBM surface, get the next BO to become the next front buffer,
|
||||
and lock it so it can't be allocated as a back buffer (to prevent EGL
|
||||
from drawing into it!) */
|
||||
windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs);
|
||||
if (!windata->next_bo) {
|
||||
return SDL_SetError("Could not lock front buffer on GBM surface");
|
||||
}
|
||||
|
||||
// Get an actual usable fb for the next front buffer.
|
||||
fb_info = KMSDRM_FBFromBO(_this, windata->next_bo);
|
||||
if (!fb_info) {
|
||||
return SDL_SetError("Could not get a framebuffer");
|
||||
}
|
||||
|
||||
if (!windata->bo) {
|
||||
/* On the first swap, immediately present the new front buffer. Before
|
||||
drmModePageFlip can be used the CRTC has to be configured to use
|
||||
the current connector and mode with drmModeSetCrtc */
|
||||
ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd,
|
||||
dispdata->crtc->crtc_id, fb_info->fb_id, 0, 0,
|
||||
&dispdata->connector->connector_id, 1, &dispdata->mode);
|
||||
|
||||
if (ret) {
|
||||
return SDL_SetError("Could not set videomode on CRTC.");
|
||||
}
|
||||
} else {
|
||||
/* On subsequent swaps, queue the new front buffer to be flipped during
|
||||
the next vertical blank
|
||||
|
||||
Remember: drmModePageFlip() never blocks, it just issues the flip,
|
||||
which will be done during the next vblank, or immediately if
|
||||
we pass the DRM_MODE_PAGE_FLIP_ASYNC flag.
|
||||
Since calling drmModePageFlip() will return EBUSY if we call it
|
||||
without having completed the last issued flip, we must pass the
|
||||
DRM_MODE_PAGE_FLIP_ASYNC if we don't block on EGL (egl_swapinterval = 0).
|
||||
That makes it flip immediately, without waiting for the next vblank
|
||||
to do so, so even if we don't block on EGL, the flip will have completed
|
||||
when we get here again. */
|
||||
if (_this->egl_data->egl_swapinterval == 0 && viddata->async_pageflip_support) {
|
||||
flip_flags |= DRM_MODE_PAGE_FLIP_ASYNC;
|
||||
}
|
||||
|
||||
ret = KMSDRM_drmModePageFlip(viddata->drm_fd, dispdata->crtc->crtc_id,
|
||||
fb_info->fb_id, flip_flags, &windata->waiting_for_flip);
|
||||
|
||||
if (ret == 0) {
|
||||
windata->waiting_for_flip = true;
|
||||
} else {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
|
||||
}
|
||||
|
||||
/* Wait immediately for vsync (as if we only had two buffers).
|
||||
Even if we are already doing a WaitPageflip at the beginning of this
|
||||
function, this is NOT redundant because here we wait immediately
|
||||
after submitting the image to the screen, reducing lag, and if
|
||||
we have waited here, there won't be a pending pageflip so the
|
||||
WaitPageflip at the beginning of this function will be a no-op.
|
||||
Just leave it here and don't worry.
|
||||
Run your SDL program with "SDL_VIDEO_DOUBLE_BUFFER=1 <program_name>"
|
||||
to enable this. */
|
||||
if (windata->double_buffer) {
|
||||
if (!KMSDRM_WaitPageflip(_this, windata)) {
|
||||
return SDL_SetError("Immediate wait for previous pageflip failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_EGL_MakeCurrent_impl(KMSDRM)
|
||||
|
||||
#endif // SDL_VIDEO_DRIVER_KMSDRM
|
||||
42
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmopengles.h
vendored
Normal file
42
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmopengles.h
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_kmsdrmopengles_h_
|
||||
#define SDL_kmsdrmopengles_h_
|
||||
|
||||
#include "../SDL_egl_c.h"
|
||||
|
||||
// OpenGLES functions
|
||||
#define KMSDRM_GLES_GetAttribute SDL_EGL_GetAttribute
|
||||
#define KMSDRM_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal
|
||||
#define KMSDRM_GLES_DestroyContext SDL_EGL_DestroyContext
|
||||
#define KMSDRM_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
|
||||
|
||||
extern void KMSDRM_GLES_DefaultProfileConfig(SDL_VideoDevice *_this, int *mask, int *major, int *minor);
|
||||
extern bool KMSDRM_GLES_SetSwapInterval(SDL_VideoDevice *_this, int interval);
|
||||
extern bool KMSDRM_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path);
|
||||
extern void KMSDRM_GLES_UnloadLibrary(SDL_VideoDevice *_this);
|
||||
extern SDL_GLContext KMSDRM_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern bool KMSDRM_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern bool KMSDRM_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context);
|
||||
|
||||
#endif // SDL_kmsdrmopengles_h_
|
||||
145
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmsym.h
vendored
Normal file
145
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmsym.h
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* *INDENT-OFF* */ // clang-format off
|
||||
|
||||
#ifndef SDL_KMSDRM_MODULE
|
||||
#define SDL_KMSDRM_MODULE(modname)
|
||||
#endif
|
||||
|
||||
#ifndef SDL_KMSDRM_SYM
|
||||
#define SDL_KMSDRM_SYM(rc,fn,params)
|
||||
#endif
|
||||
|
||||
#ifndef SDL_KMSDRM_SYM_CONST
|
||||
#define SDL_KMSDRM_SYM_CONST(type, name)
|
||||
#endif
|
||||
|
||||
#ifndef SDL_KMSDRM_SYM_OPT
|
||||
#define SDL_KMSDRM_SYM_OPT(rc,fn,params)
|
||||
#endif
|
||||
|
||||
|
||||
SDL_KMSDRM_MODULE(LIBDRM)
|
||||
SDL_KMSDRM_SYM(void,drmModeFreeResources,(drmModeResPtr ptr))
|
||||
SDL_KMSDRM_SYM(void,drmModeFreeFB,(drmModeFBPtr ptr))
|
||||
SDL_KMSDRM_SYM(void,drmModeFreeCrtc,(drmModeCrtcPtr ptr))
|
||||
SDL_KMSDRM_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr))
|
||||
SDL_KMSDRM_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr))
|
||||
SDL_KMSDRM_SYM(int,drmGetCap,(int fd, uint64_t capability, uint64_t *value))
|
||||
SDL_KMSDRM_SYM(int,drmSetMaster,(int fd))
|
||||
SDL_KMSDRM_SYM(int,drmDropMaster,(int fd))
|
||||
SDL_KMSDRM_SYM(int,drmAuthMagic,(int fd, drm_magic_t magic))
|
||||
SDL_KMSDRM_SYM(drmModeResPtr,drmModeGetResources,(int fd))
|
||||
SDL_KMSDRM_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
||||
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
|
||||
uint32_t *buf_id))
|
||||
|
||||
SDL_KMSDRM_SYM_OPT(int,drmModeAddFB2,(int fd, uint32_t width, uint32_t height,
|
||||
uint32_t pixel_format, const uint32_t bo_handles[4],
|
||||
const uint32_t pitches[4], const uint32_t offsets[4],
|
||||
uint32_t *buf_id, uint32_t flags))
|
||||
|
||||
SDL_KMSDRM_SYM_OPT(int,drmModeAddFB2WithModifiers,(int fd, uint32_t width,
|
||||
uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4],
|
||||
const uint32_t pitches[4], const uint32_t offsets[4],
|
||||
const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags))
|
||||
|
||||
SDL_KMSDRM_SYM_OPT(const char *,drmModeGetConnectorTypeName,(uint32_t connector_type))
|
||||
|
||||
SDL_KMSDRM_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId))
|
||||
SDL_KMSDRM_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf))
|
||||
SDL_KMSDRM_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId))
|
||||
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,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,
|
||||
uint32_t width, uint32_t height,
|
||||
int32_t hot_x, int32_t hot_y))
|
||||
SDL_KMSDRM_SYM(int,drmModeMoveCursor,(int fd, uint32_t crtcId, int x, int y))
|
||||
SDL_KMSDRM_SYM(drmModeEncoderPtr,drmModeGetEncoder,(int fd, uint32_t encoder_id))
|
||||
SDL_KMSDRM_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connector_id))
|
||||
SDL_KMSDRM_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx))
|
||||
SDL_KMSDRM_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id,
|
||||
uint32_t flags, void *user_data))
|
||||
|
||||
// Planes stuff.
|
||||
SDL_KMSDRM_SYM(int,drmSetClientCap,(int fd, uint64_t capability, uint64_t value))
|
||||
SDL_KMSDRM_SYM(drmModePlaneResPtr,drmModeGetPlaneResources,(int fd))
|
||||
SDL_KMSDRM_SYM(drmModePlanePtr,drmModeGetPlane,(int fd, uint32_t plane_id))
|
||||
SDL_KMSDRM_SYM(drmModeObjectPropertiesPtr,drmModeObjectGetProperties,(int fd,uint32_t object_id,uint32_t object_type))
|
||||
SDL_KMSDRM_SYM(int,drmModeObjectSetProperty,(int fd, uint32_t object_id,
|
||||
uint32_t object_type, uint32_t property_id,
|
||||
uint64_t value))
|
||||
SDL_KMSDRM_SYM(drmModePropertyPtr,drmModeGetProperty,(int fd, uint32_t propertyId))
|
||||
|
||||
SDL_KMSDRM_SYM(void,drmModeFreeProperty,(drmModePropertyPtr ptr))
|
||||
SDL_KMSDRM_SYM(void,drmModeFreeObjectProperties,(drmModeObjectPropertiesPtr ptr))
|
||||
SDL_KMSDRM_SYM(void,drmModeFreePlane,(drmModePlanePtr ptr))
|
||||
SDL_KMSDRM_SYM(void,drmModeFreePlaneResources,(drmModePlaneResPtr ptr))
|
||||
SDL_KMSDRM_SYM(int,drmModeSetPlane,(int fd, uint32_t plane_id, uint32_t crtc_id,
|
||||
uint32_t fb_id, uint32_t flags,
|
||||
int32_t crtc_x, int32_t crtc_y,
|
||||
uint32_t crtc_w, uint32_t crtc_h,
|
||||
uint32_t src_x, uint32_t src_y,
|
||||
uint32_t src_w, uint32_t src_h))
|
||||
// Planes stuff ends.
|
||||
|
||||
SDL_KMSDRM_MODULE(GBM)
|
||||
SDL_KMSDRM_SYM(int,gbm_device_is_format_supported,(struct gbm_device *gbm,
|
||||
uint32_t format, uint32_t usage))
|
||||
SDL_KMSDRM_SYM(void,gbm_device_destroy,(struct gbm_device *gbm))
|
||||
SDL_KMSDRM_SYM(struct gbm_device *,gbm_create_device,(int fd))
|
||||
SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_width,(struct gbm_bo *bo))
|
||||
SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_height,(struct gbm_bo *bo))
|
||||
SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride,(struct gbm_bo *bo))
|
||||
SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_format,(struct gbm_bo *bo))
|
||||
SDL_KMSDRM_SYM(union gbm_bo_handle,gbm_bo_get_handle,(struct gbm_bo *bo))
|
||||
SDL_KMSDRM_SYM(int,gbm_bo_write,(struct gbm_bo *bo, const void *buf, size_t count))
|
||||
SDL_KMSDRM_SYM(struct gbm_device *,gbm_bo_get_device,(struct gbm_bo *bo))
|
||||
SDL_KMSDRM_SYM(void,gbm_bo_set_user_data,(struct gbm_bo *bo, void *data,
|
||||
void (*destroy_user_data)(struct gbm_bo *, void *)))
|
||||
SDL_KMSDRM_SYM(void *,gbm_bo_get_user_data,(struct gbm_bo *bo))
|
||||
SDL_KMSDRM_SYM(void,gbm_bo_destroy,(struct gbm_bo *bo))
|
||||
SDL_KMSDRM_SYM(struct gbm_bo *,gbm_bo_create,(struct gbm_device *gbm,
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t format, uint32_t usage))
|
||||
SDL_KMSDRM_SYM(struct gbm_surface *,gbm_surface_create,(struct gbm_device *gbm,
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t format, uint32_t flags))
|
||||
SDL_KMSDRM_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf))
|
||||
SDL_KMSDRM_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf))
|
||||
SDL_KMSDRM_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo))
|
||||
|
||||
SDL_KMSDRM_SYM_OPT(uint64_t,gbm_bo_get_modifier,(struct gbm_bo *bo))
|
||||
SDL_KMSDRM_SYM_OPT(int,gbm_bo_get_plane_count,(struct gbm_bo *bo))
|
||||
SDL_KMSDRM_SYM_OPT(uint32_t,gbm_bo_get_offset,(struct gbm_bo *bo, int plane))
|
||||
SDL_KMSDRM_SYM_OPT(uint32_t,gbm_bo_get_stride_for_plane,(struct gbm_bo *bo, int plane))
|
||||
SDL_KMSDRM_SYM_OPT(union gbm_bo_handle,gbm_bo_get_handle_for_plane,(struct gbm_bo *bo, int plane))
|
||||
|
||||
#undef SDL_KMSDRM_MODULE
|
||||
#undef SDL_KMSDRM_SYM
|
||||
#undef SDL_KMSDRM_SYM_CONST
|
||||
#undef SDL_KMSDRM_SYM_OPT
|
||||
|
||||
/* *INDENT-ON* */ // clang-format on
|
||||
1820
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmvideo.c
vendored
Normal file
1820
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmvideo.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
176
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmvideo.h
vendored
Normal file
176
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmvideo.h
vendored
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_kmsdrmvideo_h
|
||||
#define SDL_kmsdrmvideo_h
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include <gbm.h>
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#ifndef DRM_FORMAT_MOD_INVALID
|
||||
#define DRM_FORMAT_MOD_INVALID 0x00ffffffffffffffULL
|
||||
#endif
|
||||
|
||||
#ifndef DRM_MODE_FB_MODIFIERS
|
||||
#define DRM_MODE_FB_MODIFIERS 2
|
||||
#endif
|
||||
|
||||
#ifndef DRM_MODE_PAGE_FLIP_ASYNC
|
||||
#define DRM_MODE_PAGE_FLIP_ASYNC 2
|
||||
#endif
|
||||
|
||||
#ifndef DRM_MODE_OBJECT_CONNECTOR
|
||||
#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
|
||||
#endif
|
||||
|
||||
#ifndef DRM_MODE_OBJECT_CRTC
|
||||
#define DRM_MODE_OBJECT_CRTC 0xcccccccc
|
||||
#endif
|
||||
|
||||
#ifndef DRM_CAP_ASYNC_PAGE_FLIP
|
||||
#define DRM_CAP_ASYNC_PAGE_FLIP 7
|
||||
#endif
|
||||
|
||||
#ifndef DRM_CAP_CURSOR_WIDTH
|
||||
#define DRM_CAP_CURSOR_WIDTH 8
|
||||
#endif
|
||||
|
||||
#ifndef DRM_CAP_CURSOR_HEIGHT
|
||||
#define DRM_CAP_CURSOR_HEIGHT 9
|
||||
#endif
|
||||
|
||||
#ifndef GBM_FORMAT_ARGB8888
|
||||
#define GBM_FORMAT_ARGB8888 ((uint32_t)('A') | ((uint32_t)('R') << 8) | ((uint32_t)('2') << 16) | ((uint32_t)('4') << 24))
|
||||
#define GBM_BO_USE_CURSOR (1 << 1)
|
||||
#define GBM_BO_USE_WRITE (1 << 3)
|
||||
#define GBM_BO_USE_LINEAR (1 << 4)
|
||||
#endif
|
||||
|
||||
struct SDL_VideoData
|
||||
{
|
||||
int devindex; // device index that was passed on creation
|
||||
int drm_fd; // DRM file desc
|
||||
char devpath[32]; // DRM dev path.
|
||||
|
||||
struct gbm_device *gbm_dev;
|
||||
|
||||
bool video_init; // Has VideoInit succeeded?
|
||||
bool vulkan_mode; // Are we in Vulkan mode? One VK window is enough to be.
|
||||
bool async_pageflip_support; // Does the hardware support async. pageflips?
|
||||
|
||||
SDL_Window **windows;
|
||||
int max_windows;
|
||||
int num_windows;
|
||||
|
||||
/* Even if we have several displays, we only have to
|
||||
open 1 FD and create 1 gbm device. */
|
||||
bool gbm_init;
|
||||
|
||||
};
|
||||
|
||||
struct SDL_DisplayModeData
|
||||
{
|
||||
int mode_index;
|
||||
};
|
||||
|
||||
struct SDL_DisplayData
|
||||
{
|
||||
drmModeConnector *connector;
|
||||
drmModeCrtc *crtc;
|
||||
drmModeModeInfo mode;
|
||||
drmModeModeInfo original_mode;
|
||||
drmModeModeInfo fullscreen_mode;
|
||||
|
||||
drmModeCrtc *saved_crtc; // CRTC to restore on quit
|
||||
bool saved_vrr;
|
||||
|
||||
/* DRM & GBM cursor stuff lives here, not in an SDL_Cursor's internal struct,
|
||||
because setting/unsetting up these is done on window creation/destruction,
|
||||
where we may not have an SDL_Cursor at all (so no SDL_Cursor internal).
|
||||
There's only one cursor GBM BO because we only support one cursor. */
|
||||
struct gbm_bo *cursor_bo;
|
||||
int cursor_bo_drm_fd;
|
||||
uint64_t cursor_w, cursor_h;
|
||||
|
||||
bool default_cursor_init;
|
||||
};
|
||||
|
||||
struct SDL_WindowData
|
||||
{
|
||||
SDL_VideoData *viddata;
|
||||
/* SDL internals expect EGL surface to be here, and in KMSDRM the GBM surface is
|
||||
what supports the EGL surface on the driver side, so all these surfaces and buffers
|
||||
are expected to be here, in the struct pointed by SDL_Window internal pointer:
|
||||
this one. So don't try to move these to dispdata! */
|
||||
struct gbm_surface *gs;
|
||||
struct gbm_bo *bo;
|
||||
struct gbm_bo *next_bo;
|
||||
|
||||
bool waiting_for_flip;
|
||||
bool double_buffer;
|
||||
|
||||
EGLSurface egl_surface;
|
||||
bool egl_surface_dirty;
|
||||
};
|
||||
|
||||
typedef struct KMSDRM_FBInfo
|
||||
{
|
||||
int drm_fd; // DRM file desc
|
||||
uint32_t fb_id; // DRM framebuffer ID
|
||||
} KMSDRM_FBInfo;
|
||||
|
||||
// Helper functions
|
||||
extern bool KMSDRM_CreateSurfaces(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern KMSDRM_FBInfo *KMSDRM_FBFromBO(SDL_VideoDevice *_this, struct gbm_bo *bo);
|
||||
extern KMSDRM_FBInfo *KMSDRM_FBFromBO2(SDL_VideoDevice *_this, struct gbm_bo *bo, int w, int h);
|
||||
extern bool KMSDRM_WaitPageflip(SDL_VideoDevice *_this, SDL_WindowData *windata);
|
||||
|
||||
/****************************************************************************/
|
||||
// SDL_VideoDevice functions declaration
|
||||
/****************************************************************************/
|
||||
|
||||
// Display and window functions
|
||||
extern bool KMSDRM_VideoInit(SDL_VideoDevice *_this);
|
||||
extern void KMSDRM_VideoQuit(SDL_VideoDevice *_this);
|
||||
extern bool KMSDRM_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
|
||||
extern bool KMSDRM_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
|
||||
extern bool KMSDRM_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
|
||||
extern void KMSDRM_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern bool KMSDRM_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void KMSDRM_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern SDL_FullscreenResult KMSDRM_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *_display, SDL_FullscreenOp fullscreen);
|
||||
extern void KMSDRM_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void KMSDRM_HideWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void KMSDRM_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void KMSDRM_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void KMSDRM_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void KMSDRM_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void KMSDRM_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
#endif // SDL_kmsdrmvideo_h
|
||||
520
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmvulkan.c
vendored
Normal file
520
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmvulkan.c
vendored
Normal file
|
|
@ -0,0 +1,520 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author Manuel Alfayate Corchere <redwindwanderer@gmail.com>.
|
||||
* Based on Jacob Lifshay's SDL_x11vulkan.c.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_KMSDRM)
|
||||
|
||||
#include "../SDL_vulkan_internal.h"
|
||||
|
||||
#include "SDL_kmsdrmvideo.h"
|
||||
#include "SDL_kmsdrmdyn.h"
|
||||
#include "SDL_kmsdrmvulkan.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef SDL_PLATFORM_OPENBSD
|
||||
#define DEFAULT_VULKAN "libvulkan.so"
|
||||
#else
|
||||
#define DEFAULT_VULKAN "libvulkan.so.1"
|
||||
#endif
|
||||
|
||||
bool KMSDRM_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
|
||||
{
|
||||
VkExtensionProperties *extensions = NULL;
|
||||
Uint32 i, extensionCount = 0;
|
||||
bool hasSurfaceExtension = false;
|
||||
bool hasDisplayExtension = false;
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
|
||||
|
||||
if (_this->vulkan_config.loader_handle) {
|
||||
return SDL_SetError("Vulkan already loaded");
|
||||
}
|
||||
|
||||
// Load the Vulkan library
|
||||
if (!path) {
|
||||
path = SDL_GetHint(SDL_HINT_VULKAN_LIBRARY);
|
||||
}
|
||||
if (!path) {
|
||||
path = DEFAULT_VULKAN;
|
||||
}
|
||||
|
||||
_this->vulkan_config.loader_handle = SDL_LoadObject(path);
|
||||
|
||||
if (!_this->vulkan_config.loader_handle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_strlcpy(_this->vulkan_config.loader_path, path,
|
||||
SDL_arraysize(_this->vulkan_config.loader_path));
|
||||
|
||||
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
|
||||
_this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
|
||||
|
||||
if (!vkGetInstanceProcAddr) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
_this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
|
||||
_this->vulkan_config.vkEnumerateInstanceExtensionProperties =
|
||||
(void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
|
||||
VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
|
||||
|
||||
if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
extensions = SDL_Vulkan_CreateInstanceExtensionsList(
|
||||
(PFN_vkEnumerateInstanceExtensionProperties)
|
||||
_this->vulkan_config.vkEnumerateInstanceExtensionProperties,
|
||||
&extensionCount);
|
||||
|
||||
if (!extensions) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < extensionCount; i++) {
|
||||
if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
|
||||
hasSurfaceExtension = true;
|
||||
} else if (SDL_strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, extensions[i].extensionName) == 0) {
|
||||
hasDisplayExtension = true;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(extensions);
|
||||
|
||||
if (!hasSurfaceExtension) {
|
||||
SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension");
|
||||
goto fail;
|
||||
} else if (!hasDisplayExtension) {
|
||||
SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_DISPLAY_EXTENSION_NAME "extension");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
SDL_UnloadObject(_this->vulkan_config.loader_handle);
|
||||
_this->vulkan_config.loader_handle = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
void KMSDRM_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
|
||||
{
|
||||
if (_this->vulkan_config.loader_handle) {
|
||||
SDL_UnloadObject(_this->vulkan_config.loader_handle);
|
||||
_this->vulkan_config.loader_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
// Here we can put whatever Vulkan extensions we want to be enabled
|
||||
// at instance creation, which is done in the programs, not in SDL.
|
||||
// So: programs call SDL_Vulkan_GetInstanceExtensions() and here
|
||||
// we put the extensions specific to this backend so the programs
|
||||
// get a list with the extension we want, so they can include that
|
||||
// list in the ppEnabledExtensionNames and EnabledExtensionCount
|
||||
// members of the VkInstanceCreateInfo struct passed to
|
||||
// vkCreateInstance().
|
||||
/*********************************************************************/
|
||||
char const* const* KMSDRM_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
|
||||
Uint32 *count)
|
||||
{
|
||||
static const char *const extensionsForKMSDRM[] = {
|
||||
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_DISPLAY_EXTENSION_NAME
|
||||
};
|
||||
if (count) {
|
||||
*count = SDL_arraysize(extensionsForKMSDRM);
|
||||
}
|
||||
return extensionsForKMSDRM;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
// First thing to know is that we don't call vkCreateInstance() here.
|
||||
// Instead, programs using SDL and Vulkan create their Vulkan instance
|
||||
// and we get it here, ready to use.
|
||||
// Extensions specific for this platform are activated in
|
||||
// KMSDRM_Vulkan_GetInstanceExtensions(), like we do with
|
||||
// VK_KHR_DISPLAY_EXTENSION_NAME, which is what we need for x-less VK.
|
||||
/***********************************************************************/
|
||||
bool KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
|
||||
SDL_Window *window,
|
||||
VkInstance instance,
|
||||
const struct VkAllocationCallbacks *allocator,
|
||||
VkSurfaceKHR *surface)
|
||||
{
|
||||
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 *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;
|
||||
bool ret = false;
|
||||
bool valid_gpu = false;
|
||||
bool mode_found = false;
|
||||
bool plane_supports_display = false;
|
||||
|
||||
// Get the display index from the display being used by the window.
|
||||
int display_index = SDL_GetDisplayIndex(SDL_GetDisplayForWindow(window));
|
||||
int i, j;
|
||||
|
||||
// Get the function pointers for the functions we will use.
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
|
||||
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
|
||||
|
||||
PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR =
|
||||
(PFN_vkCreateDisplayPlaneSurfaceKHR)vkGetInstanceProcAddr(
|
||||
instance, "vkCreateDisplayPlaneSurfaceKHR");
|
||||
|
||||
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices =
|
||||
(PFN_vkEnumeratePhysicalDevices)vkGetInstanceProcAddr(
|
||||
instance, "vkEnumeratePhysicalDevices");
|
||||
|
||||
PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties =
|
||||
(PFN_vkGetPhysicalDeviceProperties)vkGetInstanceProcAddr(
|
||||
instance, "vkGetPhysicalDeviceProperties");
|
||||
|
||||
PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR =
|
||||
(PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)vkGetInstanceProcAddr(
|
||||
instance, "vkGetPhysicalDeviceDisplayPropertiesKHR");
|
||||
|
||||
PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR =
|
||||
(PFN_vkGetDisplayModePropertiesKHR)vkGetInstanceProcAddr(
|
||||
instance, "vkGetDisplayModePropertiesKHR");
|
||||
|
||||
PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR =
|
||||
(PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)vkGetInstanceProcAddr(
|
||||
instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
|
||||
|
||||
PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR =
|
||||
(PFN_vkGetDisplayPlaneSupportedDisplaysKHR)vkGetInstanceProcAddr(
|
||||
instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
|
||||
|
||||
PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR =
|
||||
(PFN_vkGetDisplayPlaneCapabilitiesKHR)vkGetInstanceProcAddr(
|
||||
instance, "vkGetDisplayPlaneCapabilitiesKHR");
|
||||
|
||||
PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR =
|
||||
(PFN_vkCreateDisplayModeKHR)vkGetInstanceProcAddr(
|
||||
instance, "vkCreateDisplayModeKHR");
|
||||
|
||||
if (!_this->vulkan_config.loader_handle) {
|
||||
SDL_SetError("Vulkan is not loaded");
|
||||
goto clean;
|
||||
}
|
||||
|
||||
/*************************************/
|
||||
// Block for vulkan surface creation
|
||||
/*************************************/
|
||||
|
||||
/****************************************************************/
|
||||
// If we got vkCreateDisplayPlaneSurfaceKHR() pointer, it means
|
||||
// that the VK_KHR_Display extension is active on the instance.
|
||||
// That's the central extension we need for x-less VK!
|
||||
/****************************************************************/
|
||||
if (!vkCreateDisplayPlaneSurfaceKHR) {
|
||||
SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME
|
||||
" extension is not enabled in the Vulkan instance.");
|
||||
goto clean;
|
||||
}
|
||||
|
||||
/* A GPU (or physical_device, in vkcube terms) is a physical GPU.
|
||||
A machine with more than one video output doesn't need to have more than one GPU,
|
||||
like the Pi4 which has 1 GPU and 2 video outputs.
|
||||
Just in case, we test that the GPU we choose is Vulkan-capable.
|
||||
If there are new reports about VK init failures, hardcode
|
||||
gpu = physical_devices[0], instead of probing, and go with that.
|
||||
*/
|
||||
|
||||
// Get the physical device count.
|
||||
vkEnumeratePhysicalDevices(instance, &gpu_count, NULL);
|
||||
|
||||
if (gpu_count == 0) {
|
||||
SDL_SetError("Vulkan can't find physical devices (gpus).");
|
||||
goto clean;
|
||||
}
|
||||
|
||||
// Get the physical devices.
|
||||
physical_devices = SDL_malloc(sizeof(VkPhysicalDevice) * gpu_count);
|
||||
device_props = SDL_malloc(sizeof(VkPhysicalDeviceProperties));
|
||||
vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices);
|
||||
|
||||
// Iterate on the physical devices.
|
||||
for (i = 0; i < gpu_count; i++) {
|
||||
|
||||
// Get the physical device properties.
|
||||
vkGetPhysicalDeviceProperties(
|
||||
physical_devices[i],
|
||||
device_props);
|
||||
|
||||
// Is this device a real GPU that supports API version 1 at least?
|
||||
if (device_props->apiVersion >= 1 &&
|
||||
(device_props->deviceType == 1 || device_props->deviceType == 2)) {
|
||||
gpu = physical_devices[i];
|
||||
valid_gpu = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid_gpu) {
|
||||
SDL_SetError("Vulkan can't find a valid physical device (gpu).");
|
||||
goto clean;
|
||||
}
|
||||
|
||||
/* A display is a video output. 1 GPU can have N displays.
|
||||
Vulkan only counts the connected displays.
|
||||
Get the display count of the GPU. */
|
||||
vkGetPhysicalDeviceDisplayPropertiesKHR(gpu, &display_count, NULL);
|
||||
if (display_count == 0) {
|
||||
SDL_SetError("Vulkan can't find any displays.");
|
||||
goto clean;
|
||||
}
|
||||
|
||||
// Get the props of the displays of the physical device.
|
||||
display_props = (VkDisplayPropertiesKHR *)SDL_malloc(display_count * sizeof(*display_props));
|
||||
vkGetPhysicalDeviceDisplayPropertiesKHR(gpu,
|
||||
&display_count,
|
||||
display_props);
|
||||
|
||||
// Get the chosen display based on the display index.
|
||||
display = display_props[display_index].display;
|
||||
|
||||
// Get the list of the display videomodes.
|
||||
vkGetDisplayModePropertiesKHR(gpu,
|
||||
display,
|
||||
&mode_count, NULL);
|
||||
|
||||
if (mode_count == 0) {
|
||||
SDL_SetError("Vulkan can't find any video modes for display %i (%s)", 0,
|
||||
display_props[display_index].displayName);
|
||||
goto clean;
|
||||
}
|
||||
|
||||
mode_props = (VkDisplayModePropertiesKHR *)SDL_malloc(mode_count * sizeof(*mode_props));
|
||||
vkGetDisplayModePropertiesKHR(gpu,
|
||||
display,
|
||||
&mode_count, mode_props);
|
||||
|
||||
/* Get a video mode equal to the window size among the predefined ones,
|
||||
if possible.
|
||||
REMEMBER: We have to get a small enough videomode for the window size,
|
||||
because videomode determines how big the scanout region is and we can't
|
||||
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 (mode_props[i].parameters.visibleRegion.width == window->w &&
|
||||
mode_props[i].parameters.visibleRegion.height == window->h) {
|
||||
display_mode_props = mode_props[i];
|
||||
mode_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
/* Couldn't find a suitable mode among the predefined ones, so try to create our own.
|
||||
This won't work for some video chips atm (like Pi's VideoCore) so these are limited
|
||||
to supported resolutions. Don't try to use "closest" resolutions either, because
|
||||
those are often bigger than the window size, thus causing out-of-bunds scanout. */
|
||||
new_mode_parameters.visibleRegion.width = window->w;
|
||||
new_mode_parameters.visibleRegion.height = window->h;
|
||||
/* SDL (and DRM, if we look at drmModeModeInfo vrefresh) uses plain integer Hz for
|
||||
display mode refresh rate, but Vulkan expects higher precision. */
|
||||
new_mode_parameters.refreshRate = (uint32_t)(window->current_fullscreen_mode.refresh_rate * 1000);
|
||||
|
||||
SDL_zero(display_mode_create_info);
|
||||
display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
|
||||
display_mode_create_info.parameters = new_mode_parameters;
|
||||
result = vkCreateDisplayModeKHR(gpu,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Just in case we get here without a display_mode.
|
||||
if (!display_mode) {
|
||||
SDL_SetError("Vulkan couldn't get a display mode.");
|
||||
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 = false;
|
||||
for (j = 0; j < supported_displays_count; j++) {
|
||||
if (supported_displays[j] == display) {
|
||||
plane_supports_display = 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 appropriate plane, error out.
|
||||
if (plane == UINT32_MAX) {
|
||||
SDL_SetError("Vulkan couldn't find an appropriate plane.");
|
||||
goto clean;
|
||||
}
|
||||
|
||||
/********************************************/
|
||||
// Let's finally create the Vulkan surface!
|
||||
/********************************************/
|
||||
|
||||
image_size.width = window->w;
|
||||
image_size.height = window->h;
|
||||
|
||||
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;
|
||||
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 = alpha_mode;
|
||||
result = vkCreateDisplayPlaneSurfaceKHR(instance,
|
||||
&display_plane_surface_create_info,
|
||||
allocator,
|
||||
surface);
|
||||
if (result != VK_SUCCESS) {
|
||||
SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s",
|
||||
SDL_Vulkan_GetResultString(result));
|
||||
goto clean;
|
||||
}
|
||||
|
||||
ret = true; // success!
|
||||
|
||||
clean:
|
||||
if (physical_devices) {
|
||||
SDL_free(physical_devices);
|
||||
}
|
||||
if (display_props) {
|
||||
SDL_free(display_props);
|
||||
}
|
||||
if (device_props) {
|
||||
SDL_free(device_props);
|
||||
}
|
||||
if (plane_props) {
|
||||
SDL_free(plane_props);
|
||||
}
|
||||
if (mode_props) {
|
||||
SDL_free(mode_props);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void KMSDRM_Vulkan_DestroySurface(SDL_VideoDevice *_this,
|
||||
VkInstance instance,
|
||||
VkSurfaceKHR surface,
|
||||
const struct VkAllocationCallbacks *allocator)
|
||||
{
|
||||
if (_this->vulkan_config.loader_handle) {
|
||||
SDL_Vulkan_DestroySurface_Internal(_this->vulkan_config.vkGetInstanceProcAddr, instance, surface, allocator);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
51
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmvulkan.h
vendored
Normal file
51
vendor/sdl-3.2.10/src/video/kmsdrm/SDL_kmsdrmvulkan.h
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author Manuel Alfayate Corchere <redwindwanderer@gmail.com>.
|
||||
* Based on Jacob Lifshay's SDL_x11vulkan.c.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_kmsdrm_vulkan_h_
|
||||
#define SDL_kmsdrm_vulkan_h_
|
||||
|
||||
#include <SDL3/SDL_vulkan.h>
|
||||
|
||||
#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_KMSDRM)
|
||||
|
||||
extern bool KMSDRM_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
|
||||
extern void KMSDRM_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
|
||||
extern char const* const* KMSDRM_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count);
|
||||
extern bool KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
|
||||
SDL_Window *window,
|
||||
VkInstance instance,
|
||||
const struct VkAllocationCallbacks *allocator,
|
||||
VkSurfaceKHR *surface);
|
||||
extern void KMSDRM_Vulkan_DestroySurface(SDL_VideoDevice *_this,
|
||||
VkInstance instance,
|
||||
VkSurfaceKHR surface,
|
||||
const struct VkAllocationCallbacks *allocator);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SDL_kmsdrm_vulkan_h_
|
||||
Loading…
Add table
Add a link
Reference in a new issue