Add gfx/common/drm_common.c and gfx_common/drm_common.h

This commit is contained in:
twinaphex 2015-11-26 17:12:06 +01:00
parent 7037486148
commit 8f9c652693
6 changed files with 125 additions and 71 deletions

View File

@ -591,6 +591,7 @@ ifeq ($(HAVE_GL_CONTEXT), 1)
endif
ifeq ($(HAVE_KMS), 1)
HAVE_DRM = 1
OBJ += gfx/drivers_context/drm_egl_ctx.o
DEFINES += $(GBM_CFLAGS) $(DRM_CFLAGS) $(EGL_CFLAGS)
LIBS += $(GBM_LIBS) $(DRM_LIBS) $(EGL_LIBS)
@ -706,6 +707,11 @@ ifeq ($(HAVE_EXYNOS), 1)
memory/neon/memcpy-neon.o
LIBS += $(DRM_LIBS) $(EXYNOS_LIBS)
DEFINES += $(DRM_CFLAGS) $(EXYNOS_CFLAGS)
HAVE_DRM = 1
endif
ifeq ($(HAVE_DRM), 1)
OBJ += gfx/common/drm_common.o
endif
ifeq ($(HAVE_DISPMANX), 1)

36
gfx/common/drm_common.c Normal file
View File

@ -0,0 +1,36 @@
/* RetroArch - A frontend for libretro.
* copyright (c) 2011-2015 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "drm_common.h"
uint32_t g_connector_id;
drmModeCrtc *g_orig_crtc;
int g_drm_fd;
/* Restore the original CRTC. */
void drm_restore_crtc(void)
{
if (!g_orig_crtc)
return;
drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id,
g_orig_crtc->buffer_id,
g_orig_crtc->x,
g_orig_crtc->y,
&g_connector_id, 1, &g_orig_crtc->mode);
drmModeFreeCrtc(g_orig_crtc);
g_orig_crtc = NULL;
}

39
gfx/common/drm_common.h Normal file
View File

@ -0,0 +1,39 @@
/* RetroArch - A frontend for libretro.
* copyright (c) 2011-2015 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __DRM_COMMON_H
#define __DRM_COMMON_H
#include <stdint.h>
#include <stddef.h>
#include <xf86drmMode.h>
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t g_connector_id;
extern drmModeCrtc *g_orig_crtc;
extern int g_drm_fd;
/* Restore the original CRTC. */
void drm_restore_crtc(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -32,6 +32,8 @@
#include <retro_inline.h>
#include "../common/drm_common.h"
#include "../../general.h"
#include "../../retroarch.h"
#include "../../runloop.h"
@ -119,16 +121,12 @@ struct exynos_drm
drmModeConnector *connector;
drmModeEncoder *encoder;
drmModeModeInfo *mode;
drmModeCrtc *orig_crtc;
uint32_t crtc_id;
uint32_t connector_id;
};
struct exynos_data
{
char drmname[32];
int fd;
struct exynos_device *device;
struct exynos_drm *drm;
@ -209,21 +207,6 @@ static int exynos_get_device_index(void)
return index;
}
/* Restore the original CRTC. */
static void exynos_restore_crtc(struct exynos_drm *d, int fd)
{
if (!d->orig_crtc)
return;
drmModeSetCrtc(fd, d->orig_crtc->crtc_id,
d->orig_crtc->buffer_id,
d->orig_crtc->x,
d->orig_crtc->y,
&d->connector_id, 1, &d->orig_crtc->mode);
drmModeFreeCrtc(d->orig_crtc);
d->orig_crtc = NULL;
}
static void exynos_clean_up_drm(struct exynos_drm *d, int fd)
{
@ -503,7 +486,7 @@ static int exynos_g2d_init(struct exynos_data *pdata)
{
unsigned i;
struct g2d_image *dst = NULL;
struct g2d_context *g2d = g2d_init(pdata->fd);
struct g2d_context *g2d = g2d_init(g_drm_fd);
if (!g2d)
return -1;
@ -596,7 +579,7 @@ static int exynos_open(struct exynos_data *pdata)
int devidx = exynos_get_device_index();
if (pdata)
pdata->fd = -1;
g_drm_fd = -1;
if (devidx != -1)
snprintf(buf, sizeof(buf), "/dev/dri/card%d", devidx);
@ -683,7 +666,7 @@ static int exynos_open(struct exynos_data *pdata)
fliphandler->evctx.page_flip_handler = exynos_page_flip_handler;
strncpy(pdata->drmname, buf, sizeof(buf));
pdata->fd = fd;
g_drm_fd = fd;
pdata->drm = drm;
pdata->fliphandler = fliphandler;
@ -708,15 +691,14 @@ static void exynos_close(struct exynos_data *pdata)
memset(pdata->drmname, 0, sizeof(char) * 32);
exynos_clean_up_drm(pdata->drm, pdata->fd);
pdata->fd = -1;
exynos_clean_up_drm(pdata->drm, g_drm_fd);
g_drm_fd = -1;
pdata->drm = NULL;
}
static int exynos_init(struct exynos_data *pdata, unsigned bpp)
{
unsigned i;
int fd = pdata->fd;
struct exynos_drm *drm = pdata->drm;
settings_t *settings = config_get_ptr();
@ -754,10 +736,10 @@ static int exynos_init(struct exynos_data *pdata, unsigned bpp)
}
drm->crtc_id = drm->encoder->crtc_id;
drm->connector_id = drm->connector->connector_id;
drm->orig_crtc = drmModeGetCrtc(fd, drm->crtc_id);
g_connector_id = drm->connector->connector_id;
g_orig_crtc = drmModeGetCrtc(g_drm_fd, drm->crtc_id);
if (!drm->orig_crtc)
if (!g_orig_crtc)
RARCH_WARN("[video_exynos]: cannot find original crtc\n");
pdata->width = drm->mode->hdisplay;
@ -778,7 +760,7 @@ static int exynos_init(struct exynos_data *pdata, unsigned bpp)
return 0;
fail:
exynos_restore_crtc(drm, fd);
drm_restore_crtc();
drm->mode = NULL;
@ -790,7 +772,7 @@ static void exynos_deinit(struct exynos_data *pdata)
{
struct exynos_drm *drm = pdata->drm;
exynos_restore_crtc(drm, pdata->fd);
drm_restore_crtc();
drm = NULL;
@ -810,7 +792,7 @@ static int exynos_alloc(struct exynos_data *pdata)
uint32_t pixel_format;
const unsigned flags = 0;
uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
struct exynos_device *device = exynos_device_create(pdata->fd);
struct exynos_device *device = exynos_device_create(g_drm_fd);
if (!device)
{
@ -875,7 +857,7 @@ static int exynos_alloc(struct exynos_data *pdata)
{
handles[0] = pages[i].bo->handle;
if (drmModeAddFB2(pdata->fd, pdata->width, pdata->height,
if (drmModeAddFB2(g_drm_fd, pdata->width, pdata->height,
pixel_format, handles, pitches, offsets,
&pages[i].buf_id, flags))
{
@ -885,7 +867,7 @@ static int exynos_alloc(struct exynos_data *pdata)
}
/* Setup CRTC: display the last allocated page. */
if (drmModeSetCrtc(pdata->fd, pdata->drm->crtc_id,
if (drmModeSetCrtc(g_drm_fd, pdata->drm->crtc_id,
pages[pdata->num_pages - 1].buf_id,
0, 0, &pdata->drm->connector_id, 1, pdata->drm->mode))
{
@ -913,7 +895,7 @@ static void exynos_free(struct exynos_data *pdata)
unsigned i;
/* Disable the CRTC. */
if (drmModeSetCrtc(pdata->fd, pdata->drm->crtc_id, 0,
if (drmModeSetCrtc(g_drm_fd, pdata->drm->crtc_id, 0,
0, 0, NULL, 0, NULL))
RARCH_WARN("[video_exynos]: failed to disable the CRTC.\n");
@ -1134,7 +1116,7 @@ static int exynos_flip(struct exynos_data *pdata, struct exynos_page *page)
exynos_wait_flip(pdata->fliphandler);
/* Issue a page flip at the next vblank interval. */
if (drmModePageFlip(pdata->fd, pdata->drm->crtc_id, page->buf_id,
if (drmModePageFlip(g_drm_fd, pdata->drm->crtc_id, page->buf_id,
DRM_MODE_PAGE_FLIP_EVENT, page) != 0)
{
RARCH_ERR("[video_exynos]: failed to issue page flip\n");

View File

@ -37,6 +37,8 @@
#include <file/dir_list.h>
#include <retro_file.h>
#include "../common/drm_common.h"
#include "../../driver.h"
#include "../../runloop.h"
#include "../common/egl_common.h"
@ -53,14 +55,11 @@
typedef struct gfx_ctx_drm_egl_data
{
RFILE *g_drm;
int g_drm_fd;
uint32_t g_crtc_id;
uint32_t g_connector_id;
unsigned g_fb_width;
unsigned g_fb_height;
drmModeModeInfo *g_drm_mode;
drmModeCrtcPtr g_orig_crtc;
drmModeRes *g_resources;
drmModeConnector *g_connector;
drmModeEncoder *g_encoder;
@ -88,7 +87,7 @@ static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
gfx_ctx_data_get_ptr();
if (drm && fb->fb_id)
drmModeRmFB(drm->g_drm_fd, fb->fb_id);
drmModeRmFB(g_drm_fd, fb->fb_id);
free(fb);
}
@ -113,7 +112,7 @@ static struct drm_fb *drm_fb_get_from_bo(
RARCH_LOG("[KMS/EGL]: New FB: %ux%u (stride: %u).\n", width, height, stride);
ret = drmModeAddFB(drm->g_drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id);
ret = drmModeAddFB(g_drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id);
if (ret < 0)
goto error;
@ -181,7 +180,7 @@ static bool wait_flip(gfx_ctx_drm_egl_data_t *drm, bool block)
if (!waiting_for_flip)
return false;
fds.fd = drm->g_drm_fd;
fds.fd = g_drm_fd;
fds.events = POLLIN;
evctx.version = DRM_EVENT_CONTEXT_VERSION;
evctx.page_flip_handler = page_flip_handler;
@ -200,7 +199,7 @@ static bool wait_flip(gfx_ctx_drm_egl_data_t *drm, bool block)
break;
if (fds.revents & POLLIN)
drmHandleEvent(drm->g_drm_fd, &evctx);
drmHandleEvent(g_drm_fd, &evctx);
else
break;
}
@ -226,7 +225,7 @@ static bool queue_flip(gfx_ctx_drm_egl_data_t *drm)
fb = (struct drm_fb*)drm_fb_get_from_bo(drm, drm->g_next_bo);
if (drmModePageFlip(drm->g_drm_fd, drm->g_crtc_id, fb->fb_id,
if (drmModePageFlip(g_drm_fd, drm->g_crtc_id, fb->fb_id,
DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip) == 0)
return true;
@ -314,10 +313,7 @@ static void free_drm_resources(gfx_ctx_drm_egl_data_t *drm)
if (drm->g_resources)
drmModeFreeResources(drm->g_resources);
if (drm->g_orig_crtc)
drmModeFreeCrtc(drm->g_orig_crtc);
if (drm->g_drm_fd >= 0)
if (g_drm_fd >= 0)
retro_fclose(drm->g_drm);
drm->g_gbm_surface = NULL;
@ -325,8 +321,7 @@ static void free_drm_resources(gfx_ctx_drm_egl_data_t *drm)
drm->g_encoder = NULL;
drm->g_connector = NULL;
drm->g_resources = NULL;
drm->g_orig_crtc = NULL;
drm->g_drm_fd = -1;
g_drm_fd = -1;
}
static void gfx_ctx_drm_egl_destroy_resources(gfx_ctx_drm_egl_data_t *drm)
@ -340,20 +335,12 @@ static void gfx_ctx_drm_egl_destroy_resources(gfx_ctx_drm_egl_data_t *drm)
egl_destroy(NULL);
/* Restore original CRTC. */
if (drm->g_orig_crtc)
{
drmModeSetCrtc(drm->g_drm_fd, drm->g_orig_crtc->crtc_id,
drm->g_orig_crtc->buffer_id,
drm->g_orig_crtc->x,
drm->g_orig_crtc->y,
&drm->g_connector_id, 1, &drm->g_orig_crtc->mode);
}
drm_restore_crtc();
free_drm_resources(drm);
drm->g_drm_mode = NULL;
drm->g_crtc_id = 0;
drm->g_connector_id = 0;
g_connector_id = 0;
drm->g_fb_width = 0;
drm->g_fb_height = 0;
@ -376,10 +363,11 @@ static bool gfx_ctx_drm_egl_init(void *data)
if (!drm)
return false;
drm->g_drm_fd = -1;
g_drm_fd = -1;
gpu_descriptors = dir_list_new("/dev/dri", NULL, false, false);
nextgpu:
drm_restore_crtc();
free_drm_resources(drm);
if (!gpu_descriptors || gpu_index == gpu_descriptors->size)
@ -396,9 +384,9 @@ nextgpu:
goto nextgpu;
}
drm->g_drm_fd = retro_get_fd(drm->g_drm);
g_drm_fd = retro_get_fd(drm->g_drm);
drm->g_resources = drmModeGetResources(drm->g_drm_fd);
drm->g_resources = drmModeGetResources(g_drm_fd);
if (!drm->g_resources)
{
RARCH_WARN("[KMS/EGL]: Couldn't get device resources.\n");
@ -413,7 +401,7 @@ nextgpu:
for (i = 0; i < drm->g_resources->count_connectors; i++)
{
drmModeConnectorPtr conn = drmModeGetConnector(
drm->g_drm_fd, drm->g_resources->connectors[i]);
g_drm_fd, drm->g_resources->connectors[i]);
if (conn)
{
@ -432,7 +420,7 @@ nextgpu:
monitor_index = 0;
for (i = 0; i < drm->g_resources->count_connectors; i++)
{
drm->g_connector = drmModeGetConnector(drm->g_drm_fd,
drm->g_connector = drmModeGetConnector(g_drm_fd,
drm->g_resources->connectors[i]);
if (!drm->g_connector)
@ -457,7 +445,7 @@ nextgpu:
for (i = 0; i < drm->g_resources->count_encoders; i++)
{
drm->g_encoder = drmModeGetEncoder(drm->g_drm_fd,
drm->g_encoder = drmModeGetEncoder(g_drm_fd,
drm->g_resources->encoders[i]);
if (!drm->g_encoder)
@ -486,18 +474,18 @@ nextgpu:
}
drm->g_crtc_id = drm->g_encoder->crtc_id;
drm->g_orig_crtc = drmModeGetCrtc(drm->g_drm_fd, drm->g_crtc_id);
if (!drm->g_orig_crtc)
g_orig_crtc = drmModeGetCrtc(g_drm_fd, drm->g_crtc_id);
if (!g_orig_crtc)
RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n");
drm->g_connector_id = drm->g_connector->connector_id;
g_connector_id = drm->g_connector->connector_id;
/* First mode is assumed to be the "optimal"
* one for get_video_size() purposes. */
drm->g_fb_width = drm->g_connector->modes[0].hdisplay;
drm->g_fb_height = drm->g_connector->modes[0].vdisplay;
drm->g_gbm_dev = gbm_create_device(drm->g_drm_fd);
drm->g_gbm_dev = gbm_create_device(g_drm_fd);
if (!drm->g_gbm_dev)
{
@ -743,8 +731,8 @@ static bool gfx_ctx_drm_egl_set_video_mode(void *data,
drm->g_bo = gbm_surface_lock_front_buffer(drm->g_gbm_surface);
fb = drm_fb_get_from_bo(drm, drm->g_bo);
ret = drmModeSetCrtc(drm->g_drm_fd,
drm->g_crtc_id, fb->fb_id, 0, 0, &drm->g_connector_id, 1, drm->g_drm_mode);
ret = drmModeSetCrtc(g_drm_fd,
drm->g_crtc_id, fb->fb_id, 0, 0, &g_connector_id, 1, drm->g_drm_mode);
if (ret < 0)
goto error;

View File

@ -128,6 +128,9 @@ VIDEO CONTEXT
#include "../gfx/drivers_context/cgl_ctx.c"
#endif
#ifdef HAVE_DRM
#include "../gfx/common/drm_common.c"
#endif
#if defined(HAVE_OPENGL)