Hi Ryan,
That's interesting. I also want to do this but in another way:
one modesetting DDX display on iGPU and render on dGPU
Attach the prototype patch and the xorg.conf should be
Section "ServerFlags"
Option "AutoAddGPU" "off"
EndSection
Section "Device"
Identifier "Intel"
Driver "modesetting"
Option "RenderPath" "radeon"
Option "RenderDriver" "radeonsi"
EndSection
Regards,
Qiang
________________________________________
From: xorg-driver-ati <[email protected]> on behalf of Ryan
Ross <[email protected]>
Sent: Thursday, July 21, 2016 11:49:32 AM
To: [email protected]
Subject: Making the discrete AMD GPU the default GPU in a Mux-less setup with
an integrated Intel GPU in Mint 18 (Xenial)
Greetings,
I have a Toshiba Satellite P55T-B5340 that I am attempting to persuade
to boot X using the discrete GPU, and only the discrete GPU. It's been a
lot of fun, because it's muxless (no hardware switch, vgaswitcharoo
seems only to crash it), and the GPU I want to use has no dedicated
outputs (and so, somehow, has to steal them from the integrated GPU,
using magic from what I can tell...). I've attempted to adapt the Nvidia
approach, which sadly only appears to work for glxinfo; attempts to use
"modesetting", screens, and AllowEmptyInitialConfiguration appear to
have no (positive) effect on X, as it really wants this GPU to be hooked
up to some form of output (or it will unload the module). On the upside,
the discrete GPU is quite happy with the 'radeon' driver.
Additional Information:
The iGPU is an Intel HD 4600 Graphics (CPU is a i7-4710HQ).
The dGPU is an AMD/ATI Venus Pro (Radeon HD 8850M / R9 M265X).
Output from xrandr --listproviders is as follows:
Providers: number : 3
Provider 0: id: 0x6d cap: 0x9, Source Output, Sink Offload crtcs: 4
outputs: 4 associated providers: 2 name:Intel
Provider 1: id: 0x45 cap: 0x6, Sink Output, Source Offload crtcs: 6
outputs: 0 associated providers: 2 name:VERDE @ pci:0000:01:00.0
Provider 2: id: 0x45 cap: 0x6, Sink Output, Source Offload crtcs: 6
outputs: 0 associated providers: 2 name:VERDE @ pci:0000:01:00.0
Pages I've looked at, solutions I've tried:
https://wiki.archlinux.org/index.php/PRIME
https://www.mankier.com/5/xorg.conf#Outputclass_Section
http://us.download.nvidia.com/XFree86/Linux-x86/364.15/README/randr14.html
and a search through both Google and this greater mailing list for
'discrete gpu', finding some interesting stuff, but nothing applicable.
Has anyone some magic glitter to spare, or perhaps some working
knowledge of how I might get this beast into the proper configuration?
Many Thanks,
Ryan
_______________________________________________
xorg-driver-ati mailing list
[email protected]
https://lists.x.org/mailman/listinfo/xorg-driver-ati
From c27cc30f7c24bcb1f544054f2f6b07a9b8139f76 Mon Sep 17 00:00:00 2001
From: Qiang Yu <[email protected]>
Date: Wed, 29 Jun 2016 18:31:56 +0800
Subject: modesetting: support render device different than
display device (v2)
V2:
1. fix always create bo as linear even in normal case
2. disable present page flip when different render and display device
3. move some variable declaration at the function beginning
Signed-off-by: Qiang Yu <[email protected]>
---
hw/xfree86/drivers/modesetting/dri2.c | 13 ++++++-
hw/xfree86/drivers/modesetting/driver.c | 46 +++++++++++++++++++++--
hw/xfree86/drivers/modesetting/driver.h | 3 ++
hw/xfree86/drivers/modesetting/drmmode_display.c | 47 ++++++++++++++++++++----
hw/xfree86/drivers/modesetting/drmmode_display.h | 2 +
hw/xfree86/drivers/modesetting/present.c | 4 ++
6 files changed, 103 insertions(+), 12 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index 3fef3ac..575c3f4 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -806,6 +806,8 @@ ms_dri2_screen_init(ScreenPtr screen)
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
DRI2InfoRec info;
+ const char *driverNames[2];
+ const char *driver;
if (!glamor_supports_pixmap_import_export(screen)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -829,9 +831,9 @@ ms_dri2_screen_init(ScreenPtr screen)
}
memset(&info, '\0', sizeof(info));
- info.fd = ms->fd;
+ info.fd = ms->rfd;
info.driverName = NULL; /* Compat field, unused. */
- info.deviceName = drmGetDeviceNameFromFd(ms->fd);
+ info.deviceName = drmGetDeviceNameFromFd(ms->rfd);
info.version = 4;
info.CreateBuffer = ms_dri2_create_buffer;
@@ -845,6 +847,13 @@ ms_dri2_screen_init(ScreenPtr screen)
info.numDrivers = 0;
info.driverNames = NULL;
+
+ driver = xf86FindOptionValue(ms->pEnt->device->options, "RenderDriver");
+ if (driver) {
+ driverNames[0] = driverNames[1] = info.driverName = driver;
+ info.driverNames = driverNames;
+ }
+
return DRI2ScreenInit(screen, &info);
}
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index fec0b9a..b1b7ecc 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -126,6 +126,8 @@ static const OptionInfoRec Options[] = {
{OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE},
{OPTION_PAGEFLIP, "PageFlip", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE},
+ {OPTION_RENDER_PATH, "RenderPath", OPTV_STRING, {0}, FALSE},
+ {OPTION_RENDER_DRIVER, "RenderDriver", OPTV_STRING, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -626,6 +628,12 @@ FreeRec(ScrnInfoPtr pScrn)
modesettingEntPtr ms_ent;
int ret;
+ if (ms->fd != ms->rfd) {
+ if (ms->drmmode.gbm)
+ gbm_device_destroy(ms->drmmode.gbm);
+ drmClose(ms->rfd);
+ }
+
ms_ent = ms_ent_priv(pScrn);
ms_ent->fd_ref--;
if (!ms_ent->fd_ref) {
@@ -665,7 +673,7 @@ try_enable_glamor(ScrnInfoPtr pScrn)
}
if (xf86LoadSubModule(pScrn, GLAMOR_EGL_MODULE_NAME)) {
- if (glamor_egl_init(pScrn, ms->fd)) {
+ if (glamor_egl_init(pScrn, ms->rfd)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "glamor initialized\n");
ms->drmmode.glamor = TRUE;
} else {
@@ -699,6 +707,7 @@ ms_get_drm_master_fd(ScrnInfoPtr pScrn)
modesettingPtr ms;
modesettingEntPtr ms_ent;
char *BusID = NULL;
+ const char *render;
ms = modesettingPTR(pScrn);
ms_ent = ms_ent_priv(pScrn);
@@ -756,6 +765,25 @@ ms_get_drm_master_fd(ScrnInfoPtr pScrn)
if (ms->fd < 0)
return FALSE;
+ ms->rfd = ms->fd;
+ render = xf86FindOptionValue(ms->pEnt->device->options, "RenderPath");
+ if (render) {
+ int fd;
+
+ if (!strncmp("pci:", render, 4))
+ fd = drmOpen(NULL, render);
+ else if (render[0] == '/')
+ fd = open(render, O_RDWR);
+ else
+ fd = drmOpen(render, NULL);
+
+ if (fd >= 0) {
+ ms->rfd = fd;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "select render: %s\n", render);
+ }
+ }
+
ms_ent->fd = ms->fd;
ms_ent->fd_ref = 1;
return TRUE;
@@ -1096,6 +1124,9 @@ SetMaster(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n",
strerror(errno));
+ if (ms->fd != ms->rfd)
+ ret = drmSetMaster(ms->rfd);
+
return ret == 0;
}
@@ -1112,8 +1143,15 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
return FALSE;
#ifdef GLAMOR_HAS_GBM
- if (ms->drmmode.glamor)
- ms->drmmode.gbm = glamor_egl_get_gbm_device(pScreen);
+ if (ms->drmmode.glamor) {
+ if (ms->fd == ms->rfd)
+ ms->drmmode.gbm = glamor_egl_get_gbm_device(pScreen);
+ else
+ ms->drmmode.gbm = gbm_create_device(ms->fd);
+ if (!ms->drmmode.gbm)
+ return FALSE;
+ ms->drmmode.rgbm = glamor_egl_get_gbm_device(pScreen);
+ }
#endif
/* HW dependent - FIXME */
@@ -1299,6 +1337,8 @@ LeaveVT(ScrnInfoPtr pScrn)
#endif
drmDropMaster(ms->fd);
+ if (ms->fd != ms->rfd)
+ drmDropMaster(ms->rfd);
}
/*
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index 5e1c5d9..4b7b41a 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -52,6 +52,8 @@ typedef enum {
OPTION_ACCEL_METHOD,
OPTION_PAGEFLIP,
OPTION_ZAPHOD_HEADS,
+ OPTION_RENDER_PATH,
+ OPTION_RENDER_DRIVER,
} modesettingOpts;
typedef struct
@@ -85,6 +87,7 @@ struct ms_drm_queue {
typedef struct _modesettingRec {
int fd;
+ int rfd;
int Chipset;
EntityInfoPtr pEnt;
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 2259c5a..c8c46bb 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -89,10 +89,12 @@ drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
int ret;
#ifdef GLAMOR_HAS_GBM
- if (bo->gbm) {
+ if (bo->gbm)
gbm_bo_destroy(bo->gbm);
- bo->gbm = NULL;
- }
+ if (bo->rgbm && bo->gbm != bo->rgbm)
+ gbm_bo_destroy(bo->rgbm);
+ bo->gbm = NULL;
+ bo->rgbm = NULL;
#endif
if (bo->dumb) {
@@ -163,9 +165,26 @@ drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
{
#ifdef GLAMOR_HAS_GBM
if (drmmode->glamor) {
+ int usage = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT;
+ if (drmmode->gbm != drmmode->rgbm)
+ usage |= GBM_BO_USE_LINEAR;
bo->gbm = gbm_bo_create(drmmode->gbm, width, height,
- GBM_FORMAT_ARGB8888,
- GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+ GBM_FORMAT_ARGB8888, usage);
+ bo->rgbm = bo->gbm;
+ if (drmmode->gbm != drmmode->rgbm && bo->gbm) {
+ int fd = gbm_bo_get_fd(bo->gbm);
+ if (fd >= 0) {
+ struct gbm_import_fd_data import_data = { 0 };
+ import_data.fd = fd;
+ import_data.width = gbm_bo_get_width(bo->gbm);
+ import_data.height = gbm_bo_get_height(bo->gbm);
+ import_data.stride = gbm_bo_get_stride(bo->gbm);
+ import_data.format = gbm_bo_get_format(bo->gbm);
+ bo->rgbm = gbm_bo_import(drmmode->rgbm, GBM_BO_IMPORT_FD, &import_data, 0);
+ close(fd);
+ }
+ return bo->rgbm != NULL;
+ }
return bo->gbm != NULL;
}
#endif
@@ -185,7 +204,21 @@ drmmode_bo_for_pixmap(drmmode_ptr drmmode, drmmode_bo *bo, PixmapPtr pixmap)
#ifdef GLAMOR_HAS_GBM
if (drmmode->glamor) {
- bo->gbm = glamor_gbm_bo_from_pixmap(screen, pixmap);
+ bo->gbm = NULL;
+ bo->rgbm = glamor_gbm_bo_from_pixmap(screen, pixmap);
+ if (drmmode->gbm != drmmode->rgbm && bo->rgbm) {
+ int fd = gbm_bo_get_fd(bo->rgbm);
+ if (fd >= 0) {
+ struct gbm_import_fd_data import_data = { 0 };
+ import_data.fd = fd;
+ import_data.width = gbm_bo_get_width(bo->rgbm);
+ import_data.height = gbm_bo_get_height(bo->rgbm);
+ import_data.stride = gbm_bo_get_stride(bo->rgbm);
+ import_data.format = gbm_bo_get_format(bo->rgbm);
+ bo->gbm = gbm_bo_import(drmmode->gbm, GBM_BO_IMPORT_FD, &import_data, 0);
+ close(fd);
+ }
+ }
bo->dumb = NULL;
return bo->gbm != NULL;
}
@@ -1597,7 +1630,7 @@ drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo)
}
#ifdef GLAMOR_HAS_GBM
- if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) {
+ if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->rgbm)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
return FALSE;
}
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index fca68a6..5560a0b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -40,6 +40,7 @@ typedef struct {
struct dumb_bo *dumb;
#ifdef GLAMOR_HAS_GBM
struct gbm_bo *gbm;
+ struct gbm_bo *rgbm;
#endif
} drmmode_bo;
@@ -51,6 +52,7 @@ typedef struct {
ScrnInfoPtr scrn;
struct gbm_device *gbm;
+ struct gbm_device *rgbm;
#ifdef CONFIG_UDEV_KMS
struct udev_monitor *uevent_monitor;
diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index 9a664f9..b4338be 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -552,6 +552,10 @@ ms_present_check_flip(RRCrtcPtr crtc,
if (pixmap->devKind != drmmode_bo_get_pitch(&ms->drmmode.front_bo))
return FALSE;
+ /* can't flip to a user created bo with tile */
+ if (ms->fd != ms->rfd)
+ return FALSE;
+
/* Make sure there's a bo we can get to */
/* XXX: actually do this. also...is it sufficient?
* if (!glamor_get_pixmap_private(pixmap))
--
1.9.1
_______________________________________________
xorg-driver-ati mailing list
[email protected]
https://lists.x.org/mailman/listinfo/xorg-driver-ati