xserver: add xorg.conf support for gpu devices. (v2.1)

This allows gpu devices to be specified in xorg.conf Screen sections.

Section "Device"
        Driver "intel"
        Identifier "intel0"
        Option "AccelMethod" "uxa"
EndSection

Section "Device"
        Driver "modesetting"
        Identifier "usb0"
EndSection

Section "Screen"
        Identifier "screen"
        Device "intel0"
        GPUDevice "usb0"
EndSection

This should allow for easier tweaking of driver options which
currently mess up the GPU device discovery process.

v2: add error handling for more than 4 devices, (Emil)
fixup CONF_ defines to consistency
add MAX_GPUDEVICES define
(yes there is two defines, this is consistent
with everywhere else).
remove braces around slp (Mark Kettenis)
man page fixups (Aaron)
v2.1: fixup whitespace (Aaron)

Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie 2015-03-31 16:42:36 +10:00
parent b1029716e4
commit 3b6930c5d0
8 changed files with 86 additions and 13 deletions

View File

@ -126,7 +126,7 @@ static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
int scrnum, MessageType from); int scrnum, MessageType from);
static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor); static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
Bool active); Bool active, Bool gpu);
static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input, static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input,
MessageType from); MessageType from);
static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display); static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
@ -390,7 +390,7 @@ const char **
xf86DriverlistFromConfig(void) xf86DriverlistFromConfig(void)
{ {
int count = 0; int count = 0;
int j; int j, k;
const char **modulearray; const char **modulearray;
screenLayoutPtr slp; screenLayoutPtr slp;
@ -411,8 +411,10 @@ xf86DriverlistFromConfig(void)
*/ */
if (xf86ConfigLayout.screens) { if (xf86ConfigLayout.screens) {
slp = xf86ConfigLayout.screens; slp = xf86ConfigLayout.screens;
while ((slp++)->screen) { while (slp->screen) {
count++; count++;
count += slp->screen->num_gpu_devices;
slp++;
} }
} }
@ -435,6 +437,10 @@ xf86DriverlistFromConfig(void)
while (slp->screen) { while (slp->screen) {
modulearray[count] = slp->screen->device->driver; modulearray[count] = slp->screen->device->driver;
count++; count++;
for (k = 0; k < slp->screen->num_gpu_devices; k++) {
modulearray[count] = slp->screen->gpu_devices[k]->driver;
count++;
}
slp++; slp++;
} }
@ -1631,7 +1637,7 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
idp = conf_layout->lay_inactive_lst; idp = conf_layout->lay_inactive_lst;
count = 0; count = 0;
while (idp) { while (idp) {
if (!configDevice(&gdp[count], idp->inactive_device, FALSE)) if (!configDevice(&gdp[count], idp->inactive_device, FALSE, FALSE))
goto bail; goto bail;
count++; count++;
idp = (XF86ConfInactivePtr) idp->list.next; idp = (XF86ConfInactivePtr) idp->list.next;
@ -1769,6 +1775,7 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
XF86ConfAdaptorLinkPtr conf_adaptor; XF86ConfAdaptorLinkPtr conf_adaptor;
Bool defaultMonitor = FALSE; Bool defaultMonitor = FALSE;
XF86ConfScreenRec local_conf_screen; XF86ConfScreenRec local_conf_screen;
int i;
if (!conf_screen) { if (!conf_screen) {
memset(&local_conf_screen, 0, sizeof(local_conf_screen)); memset(&local_conf_screen, 0, sizeof(local_conf_screen));
@ -1811,12 +1818,20 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n" xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
"\tUsing the first device section listed.\n", screenp->id); "\tUsing the first device section listed.\n", screenp->id);
} }
if (configDevice(screenp->device, conf_screen->scrn_device, TRUE)) { if (configDevice(screenp->device, conf_screen->scrn_device, TRUE, FALSE)) {
screenp->device->myScreenSection = screenp; screenp->device->myScreenSection = screenp;
} }
else { else {
screenp->device = NULL; screenp->device = NULL;
} }
for (i = 0; i < conf_screen->num_gpu_devices; i++) {
screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
screenp->gpu_devices[i]->myScreenSection = screenp;
}
}
screenp->num_gpu_devices = conf_screen->num_gpu_devices;
screenp->options = conf_screen->scrn_option_lst; screenp->options = conf_screen->scrn_option_lst;
/* /*
@ -2110,7 +2125,7 @@ configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
} }
static Bool static Bool
configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active) configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active, Bool gpu)
{ {
int i; int i;
@ -2118,10 +2133,14 @@ configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
return FALSE; return FALSE;
} }
if (active) if (active) {
xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n", if (gpu)
xf86Msg(X_CONFIG, "| |-->GPUDevice \"%s\"\n",
conf_device->dev_identifier); conf_device->dev_identifier);
else else
xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n",
conf_device->dev_identifier);
} else
xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n", xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
conf_device->dev_identifier); conf_device->dev_identifier);

View File

@ -1367,7 +1367,7 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
{ {
GDevPtr gdp, *pgdp = NULL; GDevPtr gdp, *pgdp = NULL;
confScreenPtr screensecptr; confScreenPtr screensecptr;
int i, j; int i, j, k;
if (sectlist) if (sectlist)
*sectlist = NULL; *sectlist = NULL;
@ -1411,6 +1411,17 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr)); pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
pgdp[i++] = screensecptr->device; pgdp[i++] = screensecptr->device;
} }
for (k = 0; k < screensecptr->num_gpu_devices; k++) {
if ((screensecptr->gpu_devices[k]->driver != NULL)
&& (xf86NameCmp(screensecptr->gpu_devices[k]->driver, drivername) == 0)
&& (!screensecptr->gpu_devices[k]->claimed)) {
/*
* we have a matching driver that wasn't claimed, yet
*/
pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
pgdp[i++] = screensecptr->gpu_devices[k];
}
}
} }
/* Then handle the inactive devices */ /* Then handle the inactive devices */

View File

@ -440,6 +440,7 @@ typedef struct _confxvadaptrec {
void *options; void *options;
} confXvAdaptorRec, *confXvAdaptorPtr; } confXvAdaptorRec, *confXvAdaptorPtr;
#define MAX_GPUDEVICES 4
typedef struct _confscreenrec { typedef struct _confscreenrec {
const char *id; const char *id;
int screennum; int screennum;
@ -453,6 +454,9 @@ typedef struct _confscreenrec {
int numxvadaptors; int numxvadaptors;
confXvAdaptorPtr xvadaptors; confXvAdaptorPtr xvadaptors;
void *options; void *options;
int num_gpu_devices;
GDevPtr gpu_devices[MAX_GPUDEVICES];
} confScreenRec, *confScreenPtr; } confScreenRec, *confScreenPtr;
typedef enum { typedef enum {

View File

@ -1906,6 +1906,7 @@ sections have the following format:
.B "Section \*qScreen\*q" .B "Section \*qScreen\*q"
.BI " Identifier \*q" name \*q .BI " Identifier \*q" name \*q
.BI " Device \*q" devid \*q .BI " Device \*q" devid \*q
.BI " GPUDevice \*q" devid \*q
.BI " Monitor \*q" monid \*q .BI " Monitor \*q" monid \*q
.I " entries" .I " entries"
.I " ..." .I " ..."
@ -1949,6 +1950,18 @@ of a
.B Device .B Device
section in the config file. section in the config file.
.TP 7 .TP 7
.BI "GPUDevice \*q" device\-id \*q
This entry specifies the
.B Device
section to be used as a secondary GPU device for this screen. When multiple graphics cards are
present, this is what ties a specific secondary card to a screen. The
.I device\-id
must match the
.B Identifier
of a
.B Device
section in the config file. This can be specified up to 4 times for a single screen.
.TP 7
.BI "Monitor \*q" monitor\-id \*q .BI "Monitor \*q" monitor\-id \*q
specifies which monitor description is to be used for this screen. specifies which monitor description is to be used for this screen.
If a If a

View File

@ -204,6 +204,8 @@ else\
"Multiple \"%s\" lines." "Multiple \"%s\" lines."
#define MUST_BE_OCTAL_MSG \ #define MUST_BE_OCTAL_MSG \
"The number \"%d\" given in this section must be in octal (0xxx) format." "The number \"%d\" given in this section must be in octal (0xxx) format."
#define GPU_DEVICE_TOO_MANY \
"More than %d GPU devices defined."
/* Warning messages */ /* Warning messages */
#define OBSOLETE_MSG \ #define OBSOLETE_MSG \

View File

@ -211,6 +211,7 @@ static xf86ConfigSymTabRec ScreenTab[] = {
{DEFAULTFBBPP, "defaultfbbpp"}, {DEFAULTFBBPP, "defaultfbbpp"},
{VIRTUAL, "virtual"}, {VIRTUAL, "virtual"},
{OPTION, "option"}, {OPTION, "option"},
{GDEVICE, "gpudevice"},
{-1, ""}, {-1, ""},
}; };
@ -270,6 +271,13 @@ xf86parseScreenSection(void)
Error(QUOTE_MSG, "Device"); Error(QUOTE_MSG, "Device");
ptr->scrn_device_str = xf86_lex_val.str; ptr->scrn_device_str = xf86_lex_val.str;
break; break;
case GDEVICE:
if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
Error(QUOTE_MSG, "GPUDevice");
if (ptr->num_gpu_devices == CONF_MAXGPUDEVICES)
Error(GPU_DEVICE_TOO_MANY, CONF_MAXGPUDEVICES);
ptr->scrn_gpu_device_str[ptr->num_gpu_devices++] = xf86_lex_val.str;
break;
case MONITOR: case MONITOR:
if (xf86getSubToken(&(ptr->scrn_comment)) != STRING) if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
Error(QUOTE_MSG, "Monitor"); Error(QUOTE_MSG, "Monitor");
@ -342,7 +350,7 @@ xf86printScreenSection(FILE * cf, XF86ConfScreenPtr ptr)
XF86ConfAdaptorLinkPtr aptr; XF86ConfAdaptorLinkPtr aptr;
XF86ConfDisplayPtr dptr; XF86ConfDisplayPtr dptr;
XF86ModePtr mptr; XF86ModePtr mptr;
int i;
while (ptr) { while (ptr) {
fprintf(cf, "Section \"Screen\"\n"); fprintf(cf, "Section \"Screen\"\n");
if (ptr->scrn_comment) if (ptr->scrn_comment)
@ -353,6 +361,9 @@ xf86printScreenSection(FILE * cf, XF86ConfScreenPtr ptr)
fprintf(cf, "\tDriver \"%s\"\n", ptr->scrn_obso_driver); fprintf(cf, "\tDriver \"%s\"\n", ptr->scrn_obso_driver);
if (ptr->scrn_device_str) if (ptr->scrn_device_str)
fprintf(cf, "\tDevice \"%s\"\n", ptr->scrn_device_str); fprintf(cf, "\tDevice \"%s\"\n", ptr->scrn_device_str);
for (i = 0; i < ptr->num_gpu_devices; i++)
if (ptr->scrn_gpu_device_str[i])
fprintf(cf, "\tGPUDevice \"%s\"\n", ptr->scrn_gpu_device_str[i]);
if (ptr->scrn_monitor_str) if (ptr->scrn_monitor_str)
fprintf(cf, "\tMonitor \"%s\"\n", ptr->scrn_monitor_str); fprintf(cf, "\tMonitor \"%s\"\n", ptr->scrn_monitor_str);
if (ptr->scrn_defaultdepth) if (ptr->scrn_defaultdepth)
@ -426,11 +437,13 @@ void
xf86freeScreenList(XF86ConfScreenPtr ptr) xf86freeScreenList(XF86ConfScreenPtr ptr)
{ {
XF86ConfScreenPtr prev; XF86ConfScreenPtr prev;
int i;
while (ptr) { while (ptr) {
TestFree(ptr->scrn_identifier); TestFree(ptr->scrn_identifier);
TestFree(ptr->scrn_monitor_str); TestFree(ptr->scrn_monitor_str);
TestFree(ptr->scrn_device_str); TestFree(ptr->scrn_device_str);
for (i = 0; i < ptr->num_gpu_devices; i++)
TestFree(ptr->scrn_gpu_device_str[i]);
TestFree(ptr->scrn_comment); TestFree(ptr->scrn_comment);
xf86optionListFree(ptr->scrn_option_lst); xf86optionListFree(ptr->scrn_option_lst);
xf86freeAdaptorLinkList(ptr->scrn_adaptor_lst); xf86freeAdaptorLinkList(ptr->scrn_adaptor_lst);
@ -487,6 +500,7 @@ xf86validateScreen(XF86ConfigPtr p)
XF86ConfScreenPtr screen = p->conf_screen_lst; XF86ConfScreenPtr screen = p->conf_screen_lst;
XF86ConfMonitorPtr monitor; XF86ConfMonitorPtr monitor;
XF86ConfAdaptorLinkPtr adaptor; XF86ConfAdaptorLinkPtr adaptor;
int i;
while (screen) { while (screen) {
if (screen->scrn_obso_driver && !screen->scrn_identifier) if (screen->scrn_obso_driver && !screen->scrn_identifier)
@ -505,6 +519,10 @@ xf86validateScreen(XF86ConfigPtr p)
screen->scrn_device = screen->scrn_device =
xf86findDevice(screen->scrn_device_str, p->conf_device_lst); xf86findDevice(screen->scrn_device_str, p->conf_device_lst);
for (i = 0; i < screen->num_gpu_devices; i++) {
screen->scrn_gpu_devices[i] =
xf86findDevice(screen->scrn_gpu_device_str[i], p->conf_device_lst);
}
adaptor = screen->scrn_adaptor_lst; adaptor = screen->scrn_adaptor_lst;
while (adaptor) { while (adaptor) {
adaptor->al_adaptor = adaptor->al_adaptor =

View File

@ -259,6 +259,7 @@ typedef struct {
XF86ConfVideoAdaptorPtr al_adaptor; XF86ConfVideoAdaptorPtr al_adaptor;
} XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr; } XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr;
#define CONF_MAXGPUDEVICES 4
typedef struct { typedef struct {
GenericListRec list; GenericListRec list;
const char *scrn_identifier; const char *scrn_identifier;
@ -276,6 +277,10 @@ typedef struct {
char *scrn_comment; char *scrn_comment;
int scrn_virtualX, scrn_virtualY; int scrn_virtualX, scrn_virtualY;
char *match_seat; char *match_seat;
int num_gpu_devices;
const char *scrn_gpu_device_str[CONF_MAXGPUDEVICES];
XF86ConfDevicePtr scrn_gpu_devices[CONF_MAXGPUDEVICES];
} XF86ConfScreenRec, *XF86ConfScreenPtr; } XF86ConfScreenRec, *XF86ConfScreenPtr;
typedef struct { typedef struct {

View File

@ -143,6 +143,7 @@ typedef enum {
/* Screen tokens */ /* Screen tokens */
OBSDRIVER, OBSDRIVER,
MDEVICE, MDEVICE,
GDEVICE,
MONITOR, MONITOR,
SCREENNO, SCREENNO,
DEFAULTDEPTH, DEFAULTDEPTH,