mirror of https://github.com/libsdl-org/SDL
[Video/KMSDRM] Remove auxiliary AMDGPU compatibility workarounds not needed anymore.
This commit is contained in:
parent
af1f91cb36
commit
cf71e01734
|
@ -57,8 +57,6 @@
|
||||||
|
|
||||||
#define KMSDRM_DRI_PATH "/dev/dri/"
|
#define KMSDRM_DRI_PATH "/dev/dri/"
|
||||||
|
|
||||||
#define AMDGPU_COMPAT 1
|
|
||||||
|
|
||||||
static int set_client_caps (int fd)
|
static int set_client_caps (int fd)
|
||||||
{
|
{
|
||||||
if (KMSDRM_drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1)) {
|
if (KMSDRM_drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1)) {
|
||||||
|
@ -166,6 +164,8 @@ get_driindex(void)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
/**********************/
|
/**********************/
|
||||||
/* DUMB BUFFER Block. */
|
/* DUMB BUFFER Block. */
|
||||||
/**********************/
|
/**********************/
|
||||||
|
@ -317,6 +317,8 @@ err:
|
||||||
/* DUMB BUFFER Block ends. */
|
/* DUMB BUFFER Block ends. */
|
||||||
/***************************/
|
/***************************/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*********************************/
|
/*********************************/
|
||||||
/* Atomic helper functions block */
|
/* Atomic helper functions block */
|
||||||
/*********************************/
|
/*********************************/
|
||||||
|
@ -1010,7 +1012,6 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
dispdata->kms_fence = NULL;
|
dispdata->kms_fence = NULL;
|
||||||
dispdata->gpu_fence = NULL;
|
dispdata->gpu_fence = NULL;
|
||||||
dispdata->kms_out_fence_fd = -1;
|
dispdata->kms_out_fence_fd = -1;
|
||||||
dispdata->dumb_buffer = NULL;
|
|
||||||
dispdata->modeset_pending = SDL_FALSE;
|
dispdata->modeset_pending = SDL_FALSE;
|
||||||
dispdata->gbm_init = SDL_FALSE;
|
dispdata->gbm_init = SDL_FALSE;
|
||||||
|
|
||||||
|
@ -1263,17 +1264,6 @@ KMSDRM_GBMInit (_THIS, SDL_DisplayData *dispdata)
|
||||||
viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC);
|
viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC);
|
||||||
set_client_caps(viddata->drm_fd);
|
set_client_caps(viddata->drm_fd);
|
||||||
|
|
||||||
/* Create aux dumb buffer. It's only useful to keep the PRIMARY PLANE occupied
|
|
||||||
when we destroy the GBM surface and it's KMS buffers, so not being able to
|
|
||||||
create it is not fatal. */
|
|
||||||
dispdata->dumb_buffer = KMSDRM_CreateBuffer(_this);
|
|
||||||
if (!dispdata->dumb_buffer) {
|
|
||||||
ret = SDL_SetError("can't create dumb buffer.");
|
|
||||||
} else {
|
|
||||||
/* Fill the dumb buffer with black pixels. */
|
|
||||||
KMSDRM_FillDumbBuffer(dispdata->dumb_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the GBM device. */
|
/* Create the GBM device. */
|
||||||
viddata->gbm_dev = KMSDRM_gbm_create_device(viddata->drm_fd);
|
viddata->gbm_dev = KMSDRM_gbm_create_device(viddata->drm_fd);
|
||||||
if (!viddata->gbm_dev) {
|
if (!viddata->gbm_dev) {
|
||||||
|
@ -1296,95 +1286,7 @@ KMSDRM_GBMInit (_THIS, SDL_DisplayData *dispdata)
|
||||||
void
|
void
|
||||||
KMSDRM_GBMDeinit (_THIS, SDL_DisplayData *dispdata)
|
KMSDRM_GBMDeinit (_THIS, SDL_DisplayData *dispdata)
|
||||||
{
|
{
|
||||||
KMSDRM_PlaneInfo plane_info = {0};
|
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||||
drmModeModeInfo mode;
|
|
||||||
|
|
||||||
uint32_t blob_id;
|
|
||||||
|
|
||||||
/*****************************************************************/
|
|
||||||
/* */
|
|
||||||
/* BLOCK to safely destroy the DUMB BUFFER. */
|
|
||||||
/* */
|
|
||||||
/* We come from DestroyWindow(), where both DestroySurfaces() */
|
|
||||||
/* and this GBMDeinit() are called, one after another. */
|
|
||||||
/* So the GBM/EGL surfaces and buffers of the windows have */
|
|
||||||
/* already been destroyed already and, because of that, the */
|
|
||||||
/* PRIMARY PLANE is using the DUMB BUFFER. BUT the DUMB BUFFER */
|
|
||||||
/* we use to keep the PRIMARY PLANE occupied when we do */
|
|
||||||
/* DestroySurfaces calls is going to be destroyed one way or */
|
|
||||||
/* another when the program quits so, to prevent the the kernel */
|
|
||||||
/* from disabling the CRTC when it detects the deletion of a */
|
|
||||||
/* buffer that IS IN USE BY THE PRIMARY PLANE, we do one of */
|
|
||||||
/* these: */
|
|
||||||
/* */
|
|
||||||
/* -In AMDGPU, where manually disabling the CRTC and */
|
|
||||||
/* disconnecting the CONNECTOR from the CRTC is an */
|
|
||||||
/* unrecoverable situation, we point the PRIMARY PLANE to */
|
|
||||||
/* the original TTY buffer (not guaranteed to be there for us!) */
|
|
||||||
/* and then destroy the DUMB BUFFER). */
|
|
||||||
/* */
|
|
||||||
/* -In other drivers, we disconnect the CONNECTOR from the CRTC */
|
|
||||||
/* (remember: several connectors can read a CRTC), deactivate */
|
|
||||||
/* the CRTC, and set the PRIMARY PLANE props CRTC_ID and FB_ID */
|
|
||||||
/* to 0. Then we destroy the DUMB BUFFER. */
|
|
||||||
/* We can leave all like this if we are exiting the program: */
|
|
||||||
/* FBCON or whatever will reconfigure things as it needs. */
|
|
||||||
/* */
|
|
||||||
/*****************************************************************/
|
|
||||||
|
|
||||||
/* dispdata->crtc->crtc->mode is the original video mode that was
|
|
||||||
configured on the connector when we lauched the program,
|
|
||||||
dispdata->mode is the current video mode, which could be different,
|
|
||||||
and dispdata->preferred_mode is the native display mode. */
|
|
||||||
mode = dispdata->crtc->crtc->mode;
|
|
||||||
|
|
||||||
#if AMDGPU_COMPAT
|
|
||||||
/* This won't work if the console wasn't correctly restored when a prevous
|
|
||||||
program exited, because in that case the TTY buffer won't be in
|
|
||||||
crtc->crtc->buffer_id, so the following atomic commit will fail. */
|
|
||||||
plane_info.plane = dispdata->display_plane;
|
|
||||||
plane_info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
|
||||||
plane_info.fb_id = dispdata->crtc->crtc->buffer_id;
|
|
||||||
plane_info.src_w = mode.hdisplay;
|
|
||||||
plane_info.src_h = mode.vdisplay;
|
|
||||||
plane_info.crtc_w = mode.hdisplay;
|
|
||||||
plane_info.crtc_h = mode.vdisplay;
|
|
||||||
|
|
||||||
drm_atomic_set_plane_props(&plane_info);
|
|
||||||
#else
|
|
||||||
add_connector_property(dispdata->atomic_req, dispdata->connector , "CRTC_ID", 0);
|
|
||||||
add_crtc_property(dispdata->atomic_req, dispdata->crtc , "ACTIVE", 0);
|
|
||||||
|
|
||||||
/* Since we initialize plane_info to all zeros,
|
|
||||||
ALL PRIMARY PLANE props are set to 0 with this,
|
|
||||||
including FB_ID and CRTC_ID.
|
|
||||||
Not all drivers like FB_ID and CRTC_ID to 0 yet. */
|
|
||||||
plane_info.plane = dispdata->display_plane;
|
|
||||||
drm_atomic_set_plane_props(&plane_info);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Set the props that restore the original video mode. */
|
|
||||||
dispdata->atomic_flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
|
||||||
add_connector_property(dispdata->atomic_req, dispdata->connector, "CRTC_ID", dispdata->crtc->crtc->crtc_id);
|
|
||||||
KMSDRM_drmModeCreatePropertyBlob(viddata->drm_fd, &mode, sizeof(mode), &blob_id);
|
|
||||||
add_crtc_property(dispdata->atomic_req, dispdata->crtc, "MODE_ID", blob_id);
|
|
||||||
add_crtc_property(dispdata->atomic_req, dispdata->crtc, "ACTIVE", 1);
|
|
||||||
|
|
||||||
/* Issue blocking atomic commit. */
|
|
||||||
if (drm_atomic_commit(_this, SDL_TRUE)) {
|
|
||||||
SDL_SetError("Failed to issue atomic commit on video quitting.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Destroy the DUMB buffer if it exists, now that it's not being
|
|
||||||
used anymore by the PRIMARY PLANE. */
|
|
||||||
if (dispdata->dumb_buffer) {
|
|
||||||
KMSDRM_DestroyDumbBuffer(_this, &dispdata->dumb_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************/
|
|
||||||
/* BLOCK to safely destroy the dumb buffer ENDS. */
|
|
||||||
/*************************************************/
|
|
||||||
|
|
||||||
/* Free display plane */
|
/* Free display plane */
|
||||||
free_plane(&dispdata->display_plane);
|
free_plane(&dispdata->display_plane);
|
||||||
|
@ -1425,12 +1327,13 @@ KMSDRM_DestroySurfaces(_THIS, SDL_Window *window)
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
/* BLOCK 1: protect the PRIMARY PLANE before destroying the buffers */
|
/* BLOCK 1: protect the PRIMARY PLANE before destroying the buffers */
|
||||||
/* it's using, by making it point to the dumb buffer. */
|
/* it's using, by making it point to the original CRTC buffer, */
|
||||||
|
/* where the TTY console should be. */
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
plane_info.plane = dispdata->display_plane;
|
plane_info.plane = dispdata->display_plane;
|
||||||
plane_info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
plane_info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
||||||
plane_info.fb_id = dispdata->dumb_buffer->fb_id;
|
plane_info.fb_id = dispdata->crtc->crtc->buffer_id;
|
||||||
plane_info.src_w = dispdata->mode.hdisplay;
|
plane_info.src_w = dispdata->mode.hdisplay;
|
||||||
plane_info.src_h = dispdata->mode.vdisplay;
|
plane_info.src_h = dispdata->mode.vdisplay;
|
||||||
plane_info.crtc_w = dispdata->mode.hdisplay;
|
plane_info.crtc_w = dispdata->mode.hdisplay;
|
||||||
|
@ -1460,7 +1363,6 @@ KMSDRM_DestroySurfaces(_THIS, SDL_Window *window)
|
||||||
windata->next_bo = NULL;
|
windata->next_bo = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/* Destroy the EGL surface. */
|
/* Destroy the EGL surface. */
|
||||||
/* In this eglMakeCurrent() call, we disable the current EGL surface */
|
/* In this eglMakeCurrent() call, we disable the current EGL surface */
|
||||||
|
@ -1576,25 +1478,6 @@ KMSDRM_DestroyWindow(_THIS, SDL_Window *window)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if AMDGPU_COMPAT
|
|
||||||
/* Since vkDestroySurfaceKHR does not destroy the native surface (only the Vulkan one),
|
|
||||||
runnin Vulkan programs leave the last buffer connected to the primary plane,
|
|
||||||
at least on AMDGPU, and the TTY buffer isn't restored.
|
|
||||||
That's not a big problem, but running a GLES program after that will cause the
|
|
||||||
atomic commit we do for restoring the TTY buffer to fail, because the TTY buffer
|
|
||||||
isn't there when we launch the GLES program.
|
|
||||||
So what we do here is "hack" Vulkan and restore the TTY buffer here, as if
|
|
||||||
we were running a GLES program. We get here after the program's vkDestroySurfaceKHR
|
|
||||||
has been called, which allows us to think as if we were in the beginig
|
|
||||||
of a GLES program.
|
|
||||||
THIS IS DONE IN A SEPARATE BLOCK FOR POSSIBLE EASY FUTURE REMOVAL. DON'T OPTIMIZE. */
|
|
||||||
|
|
||||||
if (is_vulkan) {
|
|
||||||
KMSDRM_GBMInit(_this, dispdata);
|
|
||||||
KMSDRM_GBMDeinit(_this, dispdata);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************/
|
/********************************************/
|
||||||
/* Remove from the internal SDL window list */
|
/* Remove from the internal SDL window list */
|
||||||
/********************************************/
|
/********************************************/
|
||||||
|
|
|
@ -39,42 +39,6 @@
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Headers related to dumb buffer creation. */
|
|
||||||
#include <drm_fourcc.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
/**********************/
|
|
||||||
/* DUMB BUFFER Block. */
|
|
||||||
/**********************/
|
|
||||||
|
|
||||||
typedef struct dumb_buffer {
|
|
||||||
|
|
||||||
/* The GEM handle for this buffer, returned by the creation ioctl. */
|
|
||||||
uint32_t gem_handles[4];
|
|
||||||
|
|
||||||
/* The framebuffer ID which is passed to KMS to display. */
|
|
||||||
uint32_t fb_id;
|
|
||||||
|
|
||||||
uint32_t format;
|
|
||||||
uint64_t modifier;
|
|
||||||
|
|
||||||
/* Parameters for our memory-mapped image. */
|
|
||||||
struct {
|
|
||||||
uint32_t *mem;
|
|
||||||
unsigned int size;
|
|
||||||
} dumb;
|
|
||||||
|
|
||||||
unsigned int width;
|
|
||||||
unsigned int height;
|
|
||||||
unsigned int pitches[4]; /* in bytes */
|
|
||||||
unsigned int offsets[4]; /* in bytes */
|
|
||||||
|
|
||||||
} dumb_buffer;
|
|
||||||
|
|
||||||
/***************************/
|
|
||||||
/* DUMB BUFFER Block ends. */
|
|
||||||
/***************************/
|
|
||||||
|
|
||||||
/****************************************************************************************/
|
/****************************************************************************************/
|
||||||
/* Driverdata pointers are void struct* used to store backend-specific variables */
|
/* Driverdata pointers are void struct* used to store backend-specific variables */
|
||||||
/* and info that supports the SDL-side structs like SDL Display Devices, SDL_Windows... */
|
/* and info that supports the SDL-side structs like SDL Display Devices, SDL_Windows... */
|
||||||
|
@ -141,8 +105,6 @@ typedef struct SDL_DisplayData
|
||||||
EGLSurface old_egl_surface;
|
EGLSurface old_egl_surface;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dumb_buffer *dumb_buffer;
|
|
||||||
|
|
||||||
SDL_bool modeset_pending;
|
SDL_bool modeset_pending;
|
||||||
SDL_bool gbm_init;
|
SDL_bool gbm_init;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue