Merge remote-tracking branch 'airlied/for-keithp'

This commit is contained in:
Keith Packard 2015-05-11 15:49:34 -07:00
commit d7091a21d9
14 changed files with 577 additions and 56 deletions

View File

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

View File

@ -1369,7 +1369,7 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
{
GDevPtr gdp, *pgdp = NULL;
confScreenPtr screensecptr;
int i, j;
int i, j, k;
if (sectlist)
*sectlist = NULL;
@ -1413,6 +1413,17 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr));
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 */

View File

@ -440,6 +440,7 @@ typedef struct _confxvadaptrec {
void *options;
} confXvAdaptorRec, *confXvAdaptorPtr;
#define MAX_GPUDEVICES 4
typedef struct _confscreenrec {
const char *id;
int screennum;
@ -453,6 +454,9 @@ typedef struct _confscreenrec {
int numxvadaptors;
confXvAdaptorPtr xvadaptors;
void *options;
int num_gpu_devices;
GDevPtr gpu_devices[MAX_GPUDEVICES];
} confScreenRec, *confScreenPtr;
typedef enum {
@ -512,6 +516,9 @@ typedef struct _confdrirec {
#define NUM_RESERVED_POINTERS 14
#define NUM_RESERVED_FUNCS 10
/* let clients know they can use this */
#define XF86_SCRN_HAS_PREFER_CLONE 1
typedef void *(*funcPointer) (void);
/* flags for depth 24 pixmap options */
@ -768,6 +775,9 @@ typedef struct _ScrnInfoRec {
ClockRangePtr clockRanges;
int adjustFlags;
/* initial rightof support disable */
int preferClone;
/*
* These can be used when the minor ABI version is incremented.
* The NUM_* parameters must be reduced appropriately to keep the

View File

@ -326,6 +326,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
continue;
drmmode_output = output->driver_private;
if (drmmode_output->output_id == -1)
continue;
output_ids[output_count] =
drmmode_output->mode_output->connector_id;
output_count++;
@ -366,10 +368,14 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
/* go through all the outputs and force DPMS them back on? */
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
drmmode_output_private_ptr drmmode_output;
if (output->crtc != crtc)
continue;
drmmode_output = output->driver_private;
if (drmmode_output->output_id == -1)
continue;
output->funcs->dpms(output, DPMSModeOn);
}
}
@ -687,7 +693,7 @@ drmmode_crtc_vblank_pipe(int crtc_id)
}
static void
drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num)
{
xf86CrtcPtr crtc;
drmmode_crtc_private_ptr drmmode_crtc;
@ -698,7 +704,7 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
drmmode_crtc->mode_crtc =
drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]);
drmmode_crtc->drmmode = drmmode;
drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num);
crtc->driver_private = drmmode_crtc;
@ -712,6 +718,9 @@ drmmode_output_detect(xf86OutputPtr output)
drmmode_ptr drmmode = drmmode_output->drmmode;
xf86OutputStatus status;
if (drmmode_output->output_id == -1)
return XF86OutputStatusDisconnected;
drmModeFreeConnector(drmmode_output->mode_output);
drmmode_output->mode_output =
@ -740,6 +749,46 @@ drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
return MODE_OK;
}
static void
drmmode_output_attach_tile(xf86OutputPtr output)
{
drmmode_output_private_ptr drmmode_output = output->driver_private;
drmModeConnectorPtr koutput = drmmode_output->mode_output;
drmmode_ptr drmmode = drmmode_output->drmmode;
int i;
struct xf86CrtcTileInfo tile_info, *set = NULL;
if (!koutput) {
xf86OutputSetTile(output, NULL);
return;
}
/* look for a TILE property */
for (i = 0; i < koutput->count_props; i++) {
drmModePropertyPtr props;
props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
if (!props)
continue;
if (!(props->flags & DRM_MODE_PROP_BLOB)) {
drmModeFreeProperty(props);
continue;
}
if (!strcmp(props->name, "TILE")) {
drmModeFreePropertyBlob(drmmode_output->tile_blob);
drmmode_output->tile_blob =
drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
}
drmModeFreeProperty(props);
}
if (drmmode_output->tile_blob) {
if (xf86OutputParseKMSTile(drmmode_output->tile_blob->data, drmmode_output->tile_blob->length, &tile_info) == TRUE)
set = &tile_info;
}
xf86OutputSetTile(output, set);
}
static Bool
has_panel_fitter(xf86OutputPtr output)
{
@ -848,6 +897,8 @@ drmmode_output_get_modes(xf86OutputPtr output)
}
xf86OutputSetEDID(output, mon);
drmmode_output_attach_tile(output);
/* modes should already be available */
for (i = 0; i < koutput->count_modes; i++) {
Mode = xnfalloc(sizeof(DisplayModeRec));
@ -873,11 +924,13 @@ drmmode_output_destroy(xf86OutputPtr output)
free(drmmode_output->props[i].atoms);
}
free(drmmode_output->props);
for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) {
drmModeFreeEncoder(drmmode_output->mode_encoders[i]);
if (drmmode_output->mode_output) {
for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) {
drmModeFreeEncoder(drmmode_output->mode_encoders[i]);
}
drmModeFreeConnector(drmmode_output->mode_output);
}
free(drmmode_output->mode_encoders);
drmModeFreeConnector(drmmode_output->mode_output);
free(drmmode_output);
output->driver_private = NULL;
}
@ -1111,22 +1164,134 @@ static const char *const output_names[] = {
"DSI",
};
static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
drmmode_output_private_ptr drmmode_output;
drmmode_output = output->driver_private;
if (drmmode_output->output_id == id)
return output;
}
return NULL;
}
static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path)
{
char *conn;
char conn_id[5];
int id, len;
char *blob_data;
if (!path_blob)
return -1;
blob_data = path_blob->data;
/* we only handle MST paths for now */
if (strncmp(blob_data, "mst:", 4))
return -1;
conn = strchr(blob_data + 4, '-');
if (!conn)
return -1;
len = conn - (blob_data + 4);
if (len + 1> 5)
return -1;
memcpy(conn_id, blob_data + 4, len);
conn_id[len + 1] = '\0';
id = strtoul(conn_id, NULL, 10);
*conn_base_id = id;
*path = conn + 1;
return 0;
}
static void
drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name,
drmModePropertyBlobPtr path_blob)
{
int ret;
char *extra_path;
int conn_id;
xf86OutputPtr output;
ret = parse_path_blob(path_blob, &conn_id, &extra_path);
if (ret == -1)
goto fallback;
output = find_output(pScrn, conn_id);
if (!output)
goto fallback;
snprintf(name, 32, "%s-%s", output->name, extra_path);
return;
fallback:
if (koutput->connector_type >= MS_ARRAY_SIZE(output_names))
snprintf(name, 32, "Unknown-%d", koutput->connector_type_id - 1);
#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT
else if (pScrn->is_gpu)
snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id - 1);
#endif
else
snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1);
}
static void
drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, Bool dynamic)
{
xf86OutputPtr output;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
drmModeConnectorPtr koutput;
drmModeEncoderPtr *kencoders = NULL;
drmmode_output_private_ptr drmmode_output;
drmModePropertyPtr props;
char name[32];
int i;
drmModePropertyBlobPtr path_blob = NULL;
koutput =
drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
drmModeGetConnector(drmmode->fd, mode_res->connectors[num]);
if (!koutput)
return;
for (i = 0; i < koutput->count_props; i++) {
props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
if (!strcmp(props->name, "PATH")) {
path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
drmModeFreeProperty(props);
break;
}
drmModeFreeProperty(props);
}
}
drmmode_create_name(pScrn, koutput, name, path_blob);
if (path_blob)
drmModeFreePropertyBlob(path_blob);
if (path_blob && dynamic) {
/* see if we have an output with this name already
and hook stuff up */
for (i = 0; i < xf86_config->num_output; i++) {
output = xf86_config->output[i];
if (strncmp(output->name, name, 32))
continue;
drmmode_output = output->driver_private;
drmmode_output->output_id = mode_res->connectors[num];
drmmode_output->mode_output = koutput;
return;
}
}
kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders);
if (!kencoders) {
goto out_free_encoders;
@ -1139,17 +1304,6 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
}
}
/* need to do smart conversion here for compat with non-kms ATI driver */
if (koutput->connector_type >= MS_ARRAY_SIZE(output_names))
snprintf(name, 32, "Unknown-%d", koutput->connector_type_id - 1);
else if (pScrn->is_gpu)
snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type],
pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1,
koutput->connector_type_id - 1);
else
snprintf(name, 32, "%s-%d", output_names[koutput->connector_type],
koutput->connector_type_id - 1);
output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name);
if (!output) {
goto out_free_encoders;
@ -1161,7 +1315,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
goto out_free_encoders;
}
drmmode_output->output_id = drmmode->mode_res->connectors[num];
drmmode_output->output_id = mode_res->connectors[num];
drmmode_output->mode_output = koutput;
drmmode_output->mode_encoders = kencoders;
drmmode_output->drmmode = drmmode;
@ -1192,6 +1346,8 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
}
}
if (dynamic)
output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output);
return;
out_free_encoders:
if (kencoders) {
@ -1231,7 +1387,7 @@ find_clones(ScrnInfoPtr scrn, xf86OutputPtr output)
}
static void
drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, drmModeResPtr mode_res)
{
int i, j;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@ -1246,8 +1402,8 @@ drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) {
int k;
for (k = 0; k < drmmode->mode_res->count_encoders; k++) {
if (drmmode->mode_res->encoders[k] ==
for (k = 0; k < mode_res->count_encoders; k++) {
if (mode_res->encoders[k] ==
drmmode_output->mode_encoders[j]->encoder_id)
drmmode_output->enc_mask |= (1 << k);
}
@ -1425,6 +1581,7 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
int i;
int ret;
uint64_t value = 0;
drmModeResPtr mode_res;
/* check for dumb capability */
ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_BUFFER, &value);
@ -1438,23 +1595,24 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
drmmode->scrn = pScrn;
drmmode->cpp = cpp;
drmmode->mode_res = drmModeGetResources(drmmode->fd);
if (!drmmode->mode_res)
mode_res = drmModeGetResources(drmmode->fd);
if (!mode_res)
return FALSE;
xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width,
drmmode->mode_res->max_height);
for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width,
mode_res->max_height);
for (i = 0; i < mode_res->count_crtcs; i++)
if (!xf86IsEntityShared(pScrn->entityList[0]) ||
pScrn->confScreen->device->screen == i)
drmmode_crtc_init(pScrn, drmmode, i);
drmmode_crtc_init(pScrn, drmmode, mode_res, i);
for (i = 0; i < drmmode->mode_res->count_connectors; i++)
drmmode_output_init(pScrn, drmmode, i);
for (i = 0; i < mode_res->count_connectors; i++)
drmmode_output_init(pScrn, drmmode, mode_res, i, FALSE);
/* workout clones */
drmmode_clones_init(pScrn, drmmode);
drmmode_clones_init(pScrn, drmmode, mode_res);
drmModeFreeResources(mode_res);
#if XF86_CRTC_VERSION >= 5
xf86ProviderSetup(pScrn, NULL, "modesetting");
#endif
@ -1618,11 +1776,78 @@ drmmode_handle_uevents(int fd, void *closure)
drmmode_ptr drmmode = closure;
ScrnInfoPtr scrn = drmmode->scrn;
struct udev_device *dev;
drmModeResPtr mode_res;
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int i, j;
Bool found;
Bool changed = FALSE;
dev = udev_monitor_receive_device(drmmode->uevent_monitor);
if (!dev)
return;
mode_res = drmModeGetResources(drmmode->fd);
if (!mode_res)
goto out;
if (mode_res->count_crtcs != config->num_crtc) {
ErrorF("number of CRTCs changed - failed to handle, %d vs %d\n", mode_res->count_crtcs, config->num_crtc);
goto out_free_res;
}
/* figure out if we have gotten rid of any connectors
traverse old output list looking for outputs */
for (i = 0; i < config->num_output; i++) {
xf86OutputPtr output = config->output[i];
drmmode_output_private_ptr drmmode_output;
drmmode_output = output->driver_private;
found = FALSE;
for (j = 0; j < mode_res->count_connectors; j++) {
if (mode_res->connectors[j] == drmmode_output->output_id) {
found = TRUE;
break;
}
}
if (found)
continue;
drmModeFreeConnector(drmmode_output->mode_output);
drmmode_output->mode_output = NULL;
drmmode_output->output_id = -1;
changed = TRUE;
}
/* find new output ids we don't have outputs for */
for (i = 0; i < mode_res->count_connectors; i++) {
found = FALSE;
for (j = 0; j < config->num_output; j++) {
xf86OutputPtr output = config->output[j];
drmmode_output_private_ptr drmmode_output;
drmmode_output = output->driver_private;
if (mode_res->connectors[i] == drmmode_output->output_id) {
found = TRUE;
break;
}
}
if (found)
continue;
changed = TRUE;
drmmode_output_init(scrn, drmmode, mode_res, i, 1);
}
if (changed) {
RRSetChanged(xf86ScrnToScreen(scrn));
RRTellChanged(xf86ScrnToScreen(scrn));
}
out_free_res:
drmModeFreeResources(mode_res);
out:
RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
udev_device_unref(dev);
}

View File

@ -47,7 +47,6 @@ typedef struct {
int fd;
unsigned fb_id;
unsigned old_fb_id;
drmModeResPtr mode_res;
drmModeFBPtr mode_fb;
int cpp;
ScrnInfoPtr scrn;
@ -121,6 +120,7 @@ typedef struct {
drmModeConnectorPtr mode_output;
drmModeEncoderPtr *mode_encoders;
drmModePropertyBlobPtr edid_blob;
drmModePropertyBlobPtr tile_blob;
int dpms_enum_id;
int num_props;
drmmode_prop_ptr props;

View File

@ -1906,6 +1906,7 @@ sections have the following format:
.B "Section \*qScreen\*q"
.BI " Identifier \*q" name \*q
.BI " Device \*q" devid \*q
.BI " GPUDevice \*q" devid \*q
.BI " Monitor \*q" monid \*q
.I " entries"
.I " ..."
@ -1949,6 +1950,18 @@ of a
.B Device
section in the config file.
.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
specifies which monitor description is to be used for this screen.
If a

View File

@ -1124,6 +1124,15 @@ xf86InitialOutputPositions(ScrnInfoPtr scrn, DisplayModePtr * modes)
int o;
int min_x, min_y;
/* check for initial right-of heuristic */
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
if (output->initial_x || output->initial_y)
return TRUE;
}
for (o = 0; o < config->num_output; o++) {
xf86OutputPtr output = config->output[o];
@ -2103,6 +2112,118 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
return match;
}
static int
numEnabledOutputs(xf86CrtcConfigPtr config, Bool *enabled)
{
int i = 0, p;
for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
return i;
}
static Bool
xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
DisplayModePtr *modes, Bool *enabled,
int width, int height)
{
int o;
int w = 0;
Bool has_tile = FALSE;
uint32_t configured_outputs;
if (scrn->preferClone)
return FALSE;
if (numEnabledOutputs(config, enabled) < 2)
return FALSE;
for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
DisplayModePtr mode =
xf86OutputHasPreferredMode(config->output[o], width, height);
if (!mode)
return FALSE;
w += mode->HDisplay;
}
if (w > width)
return FALSE;
w = 0;
configured_outputs = 0;
for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
DisplayModePtr mode =
xf86OutputHasPreferredMode(config->output[o], width, height);
if (configured_outputs & (1 << o))
continue;
if (config->output[o]->tile_info.group_id) {
has_tile = TRUE;
continue;
}
config->output[o]->initial_x = w;
w += mode->HDisplay;
configured_outputs |= (1 << o);
modes[o] = mode;
}
if (has_tile) {
for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
int ht, vt, ot;
int add_x, cur_x = w;
struct xf86CrtcTileInfo *tile_info = &config->output[o]->tile_info, *this_tile;
if (configured_outputs & (1 << o))
continue;
if (!tile_info->group_id)
continue;
if (tile_info->tile_h_loc != 0 && tile_info->tile_v_loc != 0)
continue;
for (ht = 0; ht < tile_info->num_h_tile; ht++) {
int cur_y = 0;
add_x = 0;
for (vt = 0; vt < tile_info->num_v_tile; vt++) {
for (ot = -1; nextEnabledOutput(config, enabled, &ot); ) {
DisplayModePtr mode =
xf86OutputHasPreferredMode(config->output[ot], width, height);
if (!config->output[ot]->tile_info.group_id)
continue;
this_tile = &config->output[ot]->tile_info;
if (this_tile->group_id != tile_info->group_id)
continue;
if (this_tile->tile_h_loc != ht ||
this_tile->tile_v_loc != vt)
continue;
config->output[ot]->initial_x = cur_x;
config->output[ot]->initial_y = cur_y;
if (vt == 0)
add_x = this_tile->tile_h_size;
cur_y += this_tile->tile_v_size;
configured_outputs |= (1 << ot);
modes[ot] = mode;
}
}
cur_x += add_x;
}
w = cur_x;
}
}
return TRUE;
}
static Bool
xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
DisplayModePtr * modes, Bool *enabled,
@ -2179,14 +2300,10 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
*/
if (!ret)
do {
int i = 0;
float aspect = 0.0;
DisplayModePtr a = NULL, b = NULL;
/* count the number of enabled outputs */
for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++);
if (i != 1)
if (numEnabledOutputs(config, enabled) != 1)
break;
p = -1;
@ -2492,6 +2609,8 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
else {
if (xf86TargetUserpref(scrn, config, modes, enabled, width, height))
xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n");
else if (xf86TargetRightOf(scrn, config, modes, enabled, width, height))
xf86DrvMsg(i, X_INFO, "Using spanning desktop for initial modes\n");
else if (xf86TargetPreferred
(scrn, config, modes, enabled, width, height))
xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n");
@ -2511,9 +2630,11 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
"Output %s enabled but has no modes\n",
config->output[o]->name);
else
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"Output %s using initial mode %s\n",
config->output[o]->name, modes[o]->name);
xf86DrvMsg (scrn->scrnIndex, X_INFO,
"Output %s using initial mode %s +%d+%d\n",
config->output[o]->name, modes[o]->name,
config->output[o]->initial_x,
config->output[o]->initial_y);
}
/*

View File

@ -1562,6 +1562,70 @@ xf86RandR12CreateObjects12(ScreenPtr pScreen)
return TRUE;
}
static void
xf86RandR12CreateMonitors(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int o, ot;
int ht, vt;
int ret;
char buf[25];
for (o = 0; o < config->num_output; o++) {
xf86OutputPtr output = config->output[o];
struct xf86CrtcTileInfo *tile_info = &output->tile_info, *this_tile;
RRMonitorPtr monitor;
int output_num, num_outputs;
if (!tile_info->group_id)
continue;
if (tile_info->tile_h_loc ||
tile_info->tile_v_loc)
continue;
num_outputs = tile_info->num_h_tile * tile_info->num_v_tile;
monitor = RRMonitorAlloc(num_outputs);
if (!monitor)
return;
monitor->pScreen = pScreen;
snprintf(buf, 25, "Auto-Monitor-%d", tile_info->group_id);
monitor->name = MakeAtom(buf, strlen(buf), TRUE);
monitor->primary = 0;
monitor->automatic = TRUE;
memset(&monitor->geometry.box, 0, sizeof(monitor->geometry.box));
output_num = 0;
for (ht = 0; ht < tile_info->num_h_tile; ht++) {
for (vt = 0; vt < tile_info->num_v_tile; vt++) {
for (ot = 0; ot < config->num_output; ot++) {
this_tile = &config->output[ot]->tile_info;
if (this_tile->group_id != tile_info->group_id)
continue;
if (this_tile->tile_h_loc != ht ||
this_tile->tile_v_loc != vt)
continue;
monitor->outputs[output_num] = config->output[ot]->randr_output->id;
output_num++;
}
}
}
ret = RRMonitorAdd(serverClient, pScreen, monitor);
if (ret) {
RRMonitorFree(monitor);
return;
}
}
}
static Bool
xf86RandR12CreateScreenResources12(ScreenPtr pScreen)
{
@ -1577,6 +1641,8 @@ xf86RandR12CreateScreenResources12(ScreenPtr pScreen)
RRScreenSetSizeRange(pScreen, config->minWidth, config->minHeight,
config->maxWidth, config->maxHeight);
xf86RandR12CreateMonitors(pScreen);
return TRUE;
}

View File

@ -204,6 +204,8 @@ else\
"Multiple \"%s\" lines."
#define MUST_BE_OCTAL_MSG \
"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 */
#define OBSOLETE_MSG \

View File

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

View File

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

View File

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

View File

@ -1016,6 +1016,15 @@ RRMonitorFreeList(RRMonitorPtr monitors, int nmon);
void
RRMonitorClose(ScreenPtr screen);
RRMonitorPtr
RRMonitorAlloc(int noutput);
int
RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor);
void
RRMonitorFree(RRMonitorPtr monitor);
int
ProcRRGetMonitors(ClientPtr client);

View File

@ -389,13 +389,13 @@ RRMonitorCountList(ScreenPtr screen)
return nmon;
}
static void
void
RRMonitorFree(RRMonitorPtr monitor)
{
free(monitor);
}
static RRMonitorPtr
RRMonitorPtr
RRMonitorAlloc(int noutput)
{
RRMonitorPtr monitor;
@ -451,7 +451,7 @@ RRMonitorMatchesOutputName(ScreenPtr screen, Atom name)
return FALSE;
}
static int
int
RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor)
{
rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);