xorg-x11-server/xserver-prime-fixes.patch

1334 lines
48 KiB
Diff
Raw Normal View History

From af52ce756cca18ebf00fadbf21a5617881beed09 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Fri, 13 May 2016 15:58:10 +0200
Subject: [PATCH v2 xserver 01/12] xrandrprovider: Do not use separate lists
for unbound / source / offload slaves
A single provider can be both a offload and source slave at the same time,
the use of seperate lists breaks in this case e.g. :
xrandr --listproviders
Providers: number : 2
Provider 0: id: 0x7b cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 3 outputs: 2 associated providers: 0 name:modesetting
Provider 1: id: 0x46 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 2 outputs: 5 associated providers: 0 name:modesetting
xrandr --setprovideroutputsource 1 0x7b
xrandr --listproviders
Providers: number : 2
Provider 0: id: 0x7b cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 3 outputs: 2 associated providers: 1 name:modesetting
Provider 1: id: 0x46 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 2 outputs: 5 associated providers: 1 name:modesetting
xrandr --setprovideroffloadsink 1 0x7b
xrandr --listproviders
Providers: number : 3
Provider 0: id: 0x7b cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 3 outputs: 2 associated providers: 2 name:modesetting
Provider 1: id: 0x46 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 2 outputs: 5 associated providers: 2 name:modesetting
Provider 2: id: 0x46 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 2 outputs: 5 associated providers: 2 name:modesetting
Not good. The problem is that the provider with id 0x46 now is on both
the output_slave_list and the offload_slave_list of the master screen.
This commit fixes this by unifying all 3 lists into a single slaves list.
Note that this does change the struct _Screen definition, so this is an ABI
break. I do not expect any of the drivers to actually use the removed / changed
fields so a recompile should suffice.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit 5c7af02b103790ac1fb6a71822788892c70290b6)
---
dix/dispatch.c | 30 ++++++++++++++-----------
hw/xfree86/dri2/dri2.c | 7 ++++--
hw/xfree86/modes/xf86RandR12.c | 11 ++--------
include/scrnintstr.h | 15 ++++++-------
present/present.c | 2 +-
randr/randr.c | 42 ++++++++++++++---------------------
randr/rrcrtc.c | 16 +++++++++++---
randr/rrmonitor.c | 17 +++++++++++---
randr/rroutput.c | 10 ++++-----
randr/rrprovider.c | 50 ++++++++++++++----------------------------
randr/rrscreen.c | 12 +++++++---
11 files changed, 104 insertions(+), 108 deletions(-)
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 2c20124..b9af349 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3790,9 +3790,7 @@ static int init_screen(ScreenPtr pScreen, int i, Bool gpu)
pScreen->CreateScreenResources = 0;
xorg_list_init(&pScreen->pixmap_dirty_list);
- xorg_list_init(&pScreen->unattached_list);
- xorg_list_init(&pScreen->output_slave_list);
- xorg_list_init(&pScreen->offload_slave_list);
+ xorg_list_init(&pScreen->slave_list);
/*
* This loop gets run once for every Screen that gets added,
@@ -3951,7 +3949,7 @@ AttachUnboundGPU(ScreenPtr pScreen, ScreenPtr new)
{
assert(new->isGPU);
assert(!new->current_master);
- xorg_list_add(&new->unattached_head, &pScreen->unattached_list);
+ xorg_list_add(&new->slave_head, &pScreen->slave_list);
new->current_master = pScreen;
}
@@ -3959,7 +3957,9 @@ void
DetachUnboundGPU(ScreenPtr slave)
{
assert(slave->isGPU);
- xorg_list_del(&slave->unattached_head);
+ assert(!slave->is_output_slave);
+ assert(!slave->is_offload_slave);
+ xorg_list_del(&slave->slave_head);
slave->current_master = NULL;
}
@@ -3967,31 +3967,35 @@ void
AttachOutputGPU(ScreenPtr pScreen, ScreenPtr new)
{
assert(new->isGPU);
- xorg_list_add(&new->output_head, &pScreen->output_slave_list);
- new->current_master = pScreen;
+ assert(!new->is_output_slave);
+ assert(new->current_master == pScreen);
+ new->is_output_slave = TRUE;
+ new->current_master->output_slaves++;
}
void
DetachOutputGPU(ScreenPtr slave)
{
assert(slave->isGPU);
- xorg_list_del(&slave->output_head);
- slave->current_master = NULL;
+ assert(slave->is_output_slave);
+ slave->current_master->output_slaves--;
+ slave->is_output_slave = FALSE;
}
void
AttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new)
{
assert(new->isGPU);
- xorg_list_add(&new->offload_head, &pScreen->offload_slave_list);
- new->current_master = pScreen;
+ assert(!new->is_offload_slave);
+ assert(new->current_master == pScreen);
+ new->is_offload_slave = TRUE;
}
void
DetachOffloadGPU(ScreenPtr slave)
{
assert(slave->isGPU);
- xorg_list_del(&slave->offload_head);
- slave->current_master = NULL;
+ assert(slave->is_offload_slave);
+ slave->is_offload_slave = FALSE;
}
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index d55be19..7e84ae3 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -186,12 +186,15 @@ static ScreenPtr
GetScreenPrime(ScreenPtr master, int prime_id)
{
ScreenPtr slave;
- if (prime_id == 0 || xorg_list_is_empty(&master->offload_slave_list)) {
+ if (prime_id == 0) {
return master;
}
- xorg_list_for_each_entry(slave, &master->offload_slave_list, offload_head) {
+ xorg_list_for_each_entry(slave, &master->slave_list, slave_head) {
DRI2ScreenPtr ds;
+ if (!slave->is_offload_slave)
+ continue;
+
ds = DRI2GetScreen(slave);
if (ds == NULL)
continue;
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 60d2254..4a21766 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1836,10 +1836,7 @@ xf86RandR14ProviderSetOutputSource(ScreenPtr pScreen,
{
if (!source_provider) {
if (provider->output_source) {
- ScreenPtr cmScreen = pScreen->current_master;
-
xf86DetachOutputGPU(pScreen);
- AttachUnboundGPU(cmScreen, pScreen);
}
provider->output_source = NULL;
return TRUE;
@@ -1850,7 +1847,6 @@ xf86RandR14ProviderSetOutputSource(ScreenPtr pScreen,
SetRootClip(source_provider->pScreen, ROOT_CLIP_NONE);
- DetachUnboundGPU(pScreen);
AttachOutputGPU(source_provider->pScreen, pScreen);
provider->output_source = source_provider;
@@ -1865,9 +1861,7 @@ xf86RandR14ProviderSetOffloadSink(ScreenPtr pScreen,
{
if (!sink_provider) {
if (provider->offload_sink) {
- ScreenPtr cmScreen = pScreen->current_master;
xf86DetachOutputGPU(pScreen);
- AttachUnboundGPU(cmScreen, pScreen);
}
provider->offload_sink = NULL;
@@ -1877,7 +1871,6 @@ xf86RandR14ProviderSetOffloadSink(ScreenPtr pScreen,
if (provider->offload_sink == sink_provider)
return TRUE;
- DetachUnboundGPU(pScreen);
AttachOffloadGPU(sink_provider->pScreen, pScreen);
provider->offload_sink = sink_provider;
@@ -1956,12 +1949,12 @@ xf86RandR14ProviderDestroy(ScreenPtr screen, RRProviderPtr provider)
config->randr_provider->offload_sink = NULL;
RRSetChanged(screen);
}
- else if (config->randr_provider->output_source) {
+ if (config->randr_provider->output_source) {
xf86DetachOutputGPU(screen);
config->randr_provider->output_source = NULL;
RRSetChanged(screen);
}
- else if (screen->current_master)
+ if (screen->current_master)
DetachUnboundGPU(screen);
}
config->randr_provider = NULL;
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 2e617c4..63ef55c 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -590,13 +590,14 @@ typedef struct _Screen {
Bool isGPU;
- struct xorg_list unattached_list;
- struct xorg_list unattached_head;
-
+ /* Info on this screen's slaves (if any) */
+ struct xorg_list slave_list;
+ struct xorg_list slave_head;
+ int output_slaves;
+ /* Info for when this screen is a slave */
ScreenPtr current_master;
-
- struct xorg_list output_slave_list;
- struct xorg_list output_head;
+ Bool is_output_slave;
+ Bool is_offload_slave;
SharePixmapBackingProcPtr SharePixmapBacking;
SetSharedPixmapBackingProcPtr SetSharedPixmapBacking;
@@ -605,8 +606,6 @@ typedef struct _Screen {
StopPixmapTrackingProcPtr StopPixmapTracking;
struct xorg_list pixmap_dirty_list;
- struct xorg_list offload_slave_list;
- struct xorg_list offload_head;
ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap;
XYToWindowProcPtr XYToWindow;
diff --git a/present/present.c b/present/present.c
index cebd2f7..5210832 100644
--- a/present/present.c
+++ b/present/present.c
@@ -145,7 +145,7 @@ present_check_flip(RRCrtcPtr crtc,
return FALSE;
/* Fail to flip if we have slave outputs */
- if (!xorg_list_is_empty(&screen->output_slave_list))
+ if (screen->output_slaves)
return FALSE;
/* Make sure the window hasn't been redirected with Composite */
diff --git a/randr/randr.c b/randr/randr.c
index ad1dda2..1829a64 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -483,7 +483,10 @@ TellChanged(WindowPtr pWin, void *value)
RRDeliverCrtcEvent(client, pWin, crtc);
}
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
+ if (!iter->is_output_slave)
+ continue;
+
pSlaveScrPriv = rrGetScrPriv(iter);
for (i = 0; i < pSlaveScrPriv->numCrtcs; i++) {
RRCrtcPtr crtc = pSlaveScrPriv->crtcs[i];
@@ -502,7 +505,10 @@ TellChanged(WindowPtr pWin, void *value)
RRDeliverOutputEvent(client, pWin, output);
}
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
+ if (!iter->is_output_slave)
+ continue;
+
pSlaveScrPriv = rrGetScrPriv(iter);
for (i = 0; i < pSlaveScrPriv->numOutputs; i++) {
RROutputPtr output = pSlaveScrPriv->outputs[i];
@@ -514,17 +520,7 @@ TellChanged(WindowPtr pWin, void *value)
}
if (pRREvent->mask & RRProviderChangeNotifyMask) {
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
- pSlaveScrPriv = rrGetScrPriv(iter);
- if (pSlaveScrPriv->provider->changed)
- RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
- }
- xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
- pSlaveScrPriv = rrGetScrPriv(iter);
- if (pSlaveScrPriv->provider->changed)
- RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
- }
- xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
pSlaveScrPriv = rrGetScrPriv(iter);
if (pSlaveScrPriv->provider->changed)
RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
@@ -602,21 +598,15 @@ RRTellChanged(ScreenPtr pScreen)
for (i = 0; i < pScrPriv->numCrtcs; i++)
pScrPriv->crtcs[i]->changed = FALSE;
- xorg_list_for_each_entry(iter, &master->output_slave_list, output_head) {
- pSlaveScrPriv = rrGetScrPriv(iter);
- pSlaveScrPriv->provider->changed = FALSE;
- for (i = 0; i < pSlaveScrPriv->numOutputs; i++)
- pSlaveScrPriv->outputs[i]->changed = FALSE;
- for (i = 0; i < pSlaveScrPriv->numCrtcs; i++)
- pSlaveScrPriv->crtcs[i]->changed = FALSE;
- }
- xorg_list_for_each_entry(iter, &master->offload_slave_list, offload_head) {
- pSlaveScrPriv = rrGetScrPriv(iter);
- pSlaveScrPriv->provider->changed = FALSE;
- }
- xorg_list_for_each_entry(iter, &master->unattached_list, unattached_head) {
+ xorg_list_for_each_entry(iter, &master->slave_list, slave_head) {
pSlaveScrPriv = rrGetScrPriv(iter);
pSlaveScrPriv->provider->changed = FALSE;
+ if (iter->is_output_slave) {
+ for (i = 0; i < pSlaveScrPriv->numOutputs; i++)
+ pSlaveScrPriv->outputs[i]->changed = FALSE;
+ for (i = 0; i < pSlaveScrPriv->numCrtcs; i++)
+ pSlaveScrPriv->crtcs[i]->changed = FALSE;
+ }
}
if (mastersp->layoutChanged) {
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 9bc456b..91f7a20 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -499,8 +499,12 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
RegionUnion(&total_region, &total_region, &new_crtc_region);
}
- xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) {
rrScrPrivPtr slave_priv = rrGetScrPriv(slave);
+
+ if (!slave->is_output_slave)
+ continue;
+
for (c = 0; c < slave_priv->numCrtcs; c++) {
RRCrtcPtr slave_crtc = slave_priv->crtcs[c];
@@ -1673,7 +1677,10 @@ RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x,
if (ret == TRUE)
return;
- xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) {
+ if (!slave->is_output_slave)
+ continue;
+
ret = check_all_screen_crtcs(slave, x, y);
if (ret == TRUE)
return;
@@ -1684,7 +1691,10 @@ RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x,
if (ret == TRUE)
return;
- xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) {
+ if (!slave->is_output_slave)
+ continue;
+
ret = constrain_all_screen_crtcs(pDev, slave, x, y);
if (ret == TRUE)
return;
diff --git a/randr/rrmonitor.c b/randr/rrmonitor.c
index ba310ea..3f6e03e 100644
--- a/randr/rrmonitor.c
+++ b/randr/rrmonitor.c
@@ -202,8 +202,12 @@ RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active)
/* Count the number of crtcs in this and any slave screens */
numCrtcs = pScrPriv->numCrtcs;
- xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &screen->slave_list, slave_head) {
rrScrPrivPtr pSlavePriv;
+
+ if (!slave->is_output_slave)
+ continue;
+
pSlavePriv = rrGetScrPriv(slave);
numCrtcs += pSlavePriv->numCrtcs;
}
@@ -220,8 +224,12 @@ RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active)
mon_list->server_crtc[c] = pScrPriv->crtcs[sc];
}
- xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &screen->slave_list, slave_head) {
rrScrPrivPtr pSlavePriv;
+
+ if (!slave->is_output_slave)
+ continue;
+
pSlavePriv = rrGetScrPriv(slave);
for (sc = 0; sc < pSlavePriv->numCrtcs; sc++, c++) {
if (pSlavePriv->crtcs[sc]->mode != NULL)
@@ -471,7 +479,10 @@ RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor)
return BadValue;
}
- xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &screen->slave_list, slave_head) {
+ if (!slave->is_output_slave)
+ continue;
+
if (RRMonitorMatchesOutputName(slave, monitor->name)) {
client->errorValue = monitor->name;
return BadValue;
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 686ae49..a8efec4 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -570,12 +570,10 @@ ProcRRSetOutputPrimary(ClientPtr client)
RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
xorg_list_for_each_entry(slave,
- &pWin->drawable.pScreen->output_slave_list,
- output_head) {
- rrScrPrivPtr pSlavePriv;
- pSlavePriv = rrGetScrPriv(slave);
-
- RRSetPrimaryOutput(slave, pSlavePriv, output);
+ &pWin->drawable.pScreen->slave_list,
+ slave_head) {
+ if (slave->is_output_slave)
+ RRSetPrimaryOutput(slave, rrGetScrPriv(slave), output);
}
}
diff --git a/randr/rrprovider.c b/randr/rrprovider.c
index 5329f41..8ef4726 100644
--- a/randr/rrprovider.c
+++ b/randr/rrprovider.c
@@ -72,15 +72,7 @@ ProcRRGetProviders (ClientPtr client)
if (pScrPriv->provider)
total_providers++;
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
- pScrPriv = rrGetScrPriv(iter);
- total_providers += pScrPriv->provider ? 1 : 0;
- }
- xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
- pScrPriv = rrGetScrPriv(iter);
- total_providers += pScrPriv->provider ? 1 : 0;
- }
- xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
pScrPriv = rrGetScrPriv(iter);
total_providers += pScrPriv->provider ? 1 : 0;
}
@@ -116,13 +108,7 @@ ProcRRGetProviders (ClientPtr client)
providers = (RRProvider *)extra;
ADD_PROVIDER(pScreen);
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
- ADD_PROVIDER(iter);
- }
- xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
- ADD_PROVIDER(iter);
- }
- xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
ADD_PROVIDER(iter);
}
}
@@ -182,12 +168,13 @@ ProcRRGetProviderInfo (ClientPtr client)
/* count associated providers */
if (provider->offload_sink)
rep.nAssociatedProviders++;
- if (provider->output_source)
- rep.nAssociatedProviders++;
- xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head)
- rep.nAssociatedProviders++;
- xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head)
+ if (provider->output_source &&
+ provider->output_source != provider->offload_sink)
rep.nAssociatedProviders++;
+ xorg_list_for_each_entry(provscreen, &pScreen->slave_list, slave_head) {
+ if (provscreen->is_output_slave || provscreen->is_offload_slave)
+ rep.nAssociatedProviders++;
+ }
rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs +
(rep.nAssociatedProviders * 2) + bytes_to_int32(rep.nameLength));
@@ -237,27 +224,22 @@ ProcRRGetProviderInfo (ClientPtr client)
swapl(&prov_cap[i]);
i++;
}
- xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(provscreen, &pScreen->slave_list, slave_head) {
+ if (!provscreen->is_output_slave && !provscreen->is_offload_slave)
+ continue;
pScrProvPriv = rrGetScrPriv(provscreen);
providers[i] = pScrProvPriv->provider->id;
if (client->swapped)
swapl(&providers[i]);
- prov_cap[i] = RR_Capability_SinkOutput;
+ prov_cap[i] = 0;
+ if (provscreen->is_output_slave)
+ prov_cap[i] |= RR_Capability_SinkOutput;
+ if (provscreen->is_offload_slave)
+ prov_cap[i] |= RR_Capability_SourceOffload;
if (client->swapped)
swapl(&prov_cap[i]);
i++;
}
- xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) {
- pScrProvPriv = rrGetScrPriv(provscreen);
- providers[i] = pScrProvPriv->provider->id;
- if (client->swapped)
- swapl(&providers[i]);
- prov_cap[i] = RR_Capability_SourceOffload;
- if (client->swapped)
- swapl(&prov_cap[i]);
- i++;
- }
-
memcpy(name, provider->name, rep.nameLength);
if (client->swapped) {
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index d0ca91e..a69f0bc 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -391,7 +391,10 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
update_totals(pScreen, pScrPriv);
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
+ if (!iter->is_output_slave)
+ continue;
+
pScrPriv = rrGetScrPriv(iter);
if (query)
@@ -447,7 +450,10 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
}
update_arrays(pScreen, pScrPriv, primary_crtc, has_primary);
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
+ if (!iter->is_output_slave)
+ continue;
+
pScrPriv = rrGetScrPriv(iter);
update_arrays(iter, pScrPriv, primary_crtc, has_primary);
@@ -500,7 +506,7 @@ rrGetScreenResources(ClientPtr client, Bool query)
if (!RRGetInfo(pScreen, query))
return BadAlloc;
- if (!xorg_list_is_empty(&pScreen->output_slave_list))
+ if (pScreen->output_slaves)
return rrGetMultiScreenResources(client, query, pScreen);
if (!pScrPriv) {
--
2.9.3
From 877f91e8a6f1600a112095bec789ce5d56277401 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 14 Jun 2016 11:58:01 +0200
Subject: [PATCH v2 xserver 02/12] modesetting: Load on GPU-s with 0 outputs
In newer laptops with switchable graphics, the GPU may have 0 outputs,
in this case the modesetting driver should still load if the GPU is
SourceOffload capable, so that it can be used as an offload source provider.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
(cherry picked from commit 60ad701a6a8cb9f1eacb72acfe2cb8d3b7a865dc)
---
hw/xfree86/drivers/modesetting/driver.c | 29 ++++++++++++++++++------
hw/xfree86/drivers/modesetting/drmmode_display.c | 6 ++---
2 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 14f80b3..718966b 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -215,14 +215,26 @@ open_hw(const char *dev)
}
static int
-check_outputs(int fd)
+check_outputs(int fd, int *count)
{
drmModeResPtr res = drmModeGetResources(fd);
int ret;
if (!res)
return FALSE;
+
+ if (count)
+ *count = res->count_connectors;
+
ret = res->count_connectors > 0;
+#if defined DRM_CAP_PRIME && GLAMOR_HAS_GBM_LINEAR
+ if (ret == FALSE) {
+ uint64_t value = 0;
+ if (drmGetCap(fd, DRM_CAP_PRIME, &value) == 0 &&
+ (value & DRM_PRIME_CAP_EXPORT))
+ ret = TRUE;
+ }
+#endif
drmModeFreeResources(res);
return ret;
}
@@ -237,13 +249,13 @@ probe_hw(const char *dev, struct xf86_platform_device *platform_dev)
fd = xf86_platform_device_odev_attributes(platform_dev)->fd;
if (fd == -1)
return FALSE;
- return check_outputs(fd);
+ return check_outputs(fd, NULL);
}
#endif
fd = open_hw(dev);
if (fd != -1) {
- int ret = check_outputs(fd);
+ int ret = check_outputs(fd, NULL);
close(fd);
return ret;
@@ -286,7 +298,7 @@ probe_hw_pci(const char *dev, struct pci_device *pdev)
devid = ms_DRICreatePCIBusID(pdev);
if (id && devid && !strcmp(id, devid))
- ret = check_outputs(fd);
+ ret = check_outputs(fd, NULL);
close(fd);
free(id);
@@ -787,7 +799,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
EntityInfoPtr pEnt;
uint64_t value = 0;
int ret;
- int bppflags;
+ int bppflags, connector_count;
int defaultdepth, defaultbpp;
if (pScrn->numEntities != 1)
@@ -824,6 +836,9 @@ PreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
ms->drmmode.fd = ms->fd;
+ if (!check_outputs(ms->fd, &connector_count))
+ return FALSE;
+
drmmode_get_default_bpp(pScrn, &ms->drmmode, &defaultdepth, &defaultbpp);
if (defaultdepth == 24 && defaultbpp == 24) {
ms->drmmode.force_24_32 = TRUE;
@@ -915,7 +930,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
#ifdef DRM_CAP_PRIME
ret = drmGetCap(ms->fd, DRM_CAP_PRIME, &value);
if (ret == 0) {
- if (value & DRM_PRIME_CAP_IMPORT) {
+ if (connector_count && (value & DRM_PRIME_CAP_IMPORT)) {
pScrn->capabilities |= RR_Capability_SinkOutput;
if (ms->drmmode.glamor)
pScrn->capabilities |= RR_Capability_SinkOffload;
@@ -943,7 +958,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
}
}
- if (pScrn->modes == NULL) {
+ if (!(pScrn->is_gpu && connector_count == 0) && pScrn->modes == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
return FALSE;
}
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 9c54310..cc78890 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1657,10 +1657,8 @@ static Bool
drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-
- drmmode_crtc_private_ptr
- drmmode_crtc = xf86_config->crtc[0]->driver_private;
- drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ modesettingPtr ms = modesettingPTR(scrn);
+ drmmode_ptr drmmode = &ms->drmmode;
drmmode_bo old_front;
Bool ret;
ScreenPtr screen = xf86ScrnToScreen(scrn);
--
2.9.3
From 32aed4dbf891fbef391340ac0b6767d723b76d85 Mon Sep 17 00:00:00 2001
From: Hans De Goede <hdegoede@redhat.com>
Date: Mon, 8 Aug 2016 14:53:59 +0200
Subject: [PATCH v2 xserver 03/12] Fix Xorg -configure not working anymore
Xorg -configure relies on the bus implementation, e.g.
xf86pciBus.c to call xf86AddBusDeviceToConfigure(). The new
xf86platformBus code does not have support for this.
Almost all drivers support both the xf86platformBus and xf86pciBus
nowadays, and the generic xf86Bus xf86CallDriverProbe() function
prefers the new xf86platformBus probe method when available.
Since the platformBus paths do not call xf86AddBusDeviceToConfigure()
this results in Xorg -configure failing with the following error:
"No devices to configure. Configuration failed.".
Adding support for the xf86Configure code to xf86platformBus.c
is non trivial and since we advise users to normally run without
any Xorg.conf at all not worth the trouble.
However some users still want to use Xorg -configure to generate a
template config file, this commit implements a minimal fix to make
things work again for PCI devices by skipping the platform
probe method when xf86DoConfigure is set.
This has been tested on a system with integrated intel graphics,
with both the intel and modesetting drivers and restores Xorg -configure
functionality on both cases.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 48c5c23a1b250c7f9d7a1747c76e4669ebf752cf)
---
hw/xfree86/common/xf86Bus.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index bd36fc5..5b93940 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -78,7 +78,8 @@ xf86CallDriverProbe(DriverPtr drv, Bool detect_only)
Bool foundScreen = FALSE;
#ifdef XSERVER_PLATFORM_BUS
- if (drv->platformProbe != NULL) {
+ /* xf86platformBus.c does not support Xorg -configure */
+ if (!xf86DoConfigure && drv->platformProbe != NULL) {
foundScreen = xf86platformProbeDev(drv);
}
if (ServerIsNotSeat0() && foundScreen)
--
2.9.3
From cd62e7435c3fafe42c2b595a6c8fb525d8bce386 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 15 Aug 2016 10:44:57 +0200
Subject: [PATCH v2 xserver 04/12] modesetting: ms_dri2_create_buffer: check
screen of existing front buffers
If a frontbuffer drawable already has a pixmap, make sure it was created
on the right screen.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xfree86/drivers/modesetting/dri2.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index 83cb3e0..b810d59 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -117,17 +117,6 @@ get_drawable_pixmap(DrawablePtr drawable)
return screen->GetWindowPixmap((WindowPtr) drawable);
}
-static PixmapPtr
-get_front_buffer(DrawablePtr drawable)
-{
- PixmapPtr pixmap;
-
- pixmap = get_drawable_pixmap(drawable);
- pixmap->refcnt++;
-
- return pixmap;
-}
-
static DRI2Buffer2Ptr
ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
unsigned int format)
@@ -151,8 +140,13 @@ ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
}
pixmap = NULL;
- if (attachment == DRI2BufferFrontLeft)
- pixmap = get_front_buffer(drawable);
+ if (attachment == DRI2BufferFrontLeft) {
+ pixmap = get_drawable_pixmap(drawable);
+ if (pixmap && pixmap->drawable.pScreen != screen)
+ pixmap = NULL;
+ if (pixmap)
+ pixmap->refcnt++;
+ }
if (pixmap == NULL) {
int pixmap_width = drawable->width;
--
2.9.3
From 05f67c4ba2b311a5fcd2f39a93fdcbd85f5d22fc Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 15 Aug 2016 11:10:15 +0200
Subject: [PATCH v2 xserver 05/12] modesetting: Remove some dead code
The "if (pixmap) ..." block this commit removes is inside an
"if (pixmap == NULL) ..." block, so it will never execute.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xfree86/drivers/modesetting/dri2.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index b810d59..9bc56c2 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -186,8 +186,6 @@ ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
pixmap_cpp,
0);
if (pixmap == NULL) {
- if (pixmap)
- screen->DestroyPixmap(pixmap);
free(private);
free(buffer);
return NULL;
--
2.9.3
From b09d88a2b007e8e3738b1c263f4f9ef0fb1e7b89 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 15 Aug 2016 12:02:54 +0200
Subject: [PATCH v2 xserver 06/12] modesetting: Implement DRI2InfoRec version 9
callbacks
Implement the CreateBuffer2 / DestroyBuffer2 / CopyRegion2 DRI2InfoRec
version 9 callbacks, this is necessary for being an offload source
provider with DRI2.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xfree86/drivers/modesetting/dri2.c | 64 ++++++++++++++++++++++++++++++-----
1 file changed, 55 insertions(+), 9 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index 9bc56c2..ed94d63 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -118,10 +118,9 @@ get_drawable_pixmap(DrawablePtr drawable)
}
static DRI2Buffer2Ptr
-ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
- unsigned int format)
+ms_dri2_create_buffer2(ScreenPtr screen, DrawablePtr drawable,
+ unsigned int attachment, unsigned int format)
{
- ScreenPtr screen = drawable->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
DRI2Buffer2Ptr buffer;
PixmapPtr pixmap;
@@ -218,6 +217,14 @@ ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
return buffer;
}
+static DRI2Buffer2Ptr
+ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
+ unsigned int format)
+{
+ return ms_dri2_create_buffer2(drawable->pScreen, drawable, attachment,
+ format);
+}
+
static void
ms_dri2_reference_buffer(DRI2Buffer2Ptr buffer)
{
@@ -227,7 +234,8 @@ ms_dri2_reference_buffer(DRI2Buffer2Ptr buffer)
}
}
-static void ms_dri2_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
+static void ms_dri2_destroy_buffer2(ScreenPtr unused, DrawablePtr unused2,
+ DRI2Buffer2Ptr buffer)
{
if (!buffer)
return;
@@ -245,28 +253,55 @@ static void ms_dri2_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
}
}
+static void ms_dri2_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
+{
+ ms_dri2_destroy_buffer2(NULL, drawable, buffer);
+}
+
static void
-ms_dri2_copy_region(DrawablePtr drawable, RegionPtr pRegion,
- DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer)
+ms_dri2_copy_region2(ScreenPtr screen, DrawablePtr drawable, RegionPtr pRegion,
+ DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer)
{
ms_dri2_buffer_private_ptr src_priv = sourceBuffer->driverPrivate;
ms_dri2_buffer_private_ptr dst_priv = destBuffer->driverPrivate;
PixmapPtr src_pixmap = src_priv->pixmap;
PixmapPtr dst_pixmap = dst_priv->pixmap;
- ScreenPtr screen = drawable->pScreen;
DrawablePtr src = (sourceBuffer->attachment == DRI2BufferFrontLeft)
? drawable : &src_pixmap->drawable;
DrawablePtr dst = (destBuffer->attachment == DRI2BufferFrontLeft)
? drawable : &dst_pixmap->drawable;
+ int off_x = 0, off_y = 0;
+ Bool translate = FALSE;
RegionPtr pCopyClip;
GCPtr gc;
+ if (destBuffer->attachment == DRI2BufferFrontLeft &&
+ drawable->pScreen != screen) {
+ dst = DRI2UpdatePrime(drawable, destBuffer);
+ if (!dst)
+ return;
+ if (dst != drawable)
+ translate = TRUE;
+ }
+
+ if (translate && drawable->type == DRAWABLE_WINDOW) {
+#ifdef COMPOSITE
+ PixmapPtr pixmap = get_drawable_pixmap(drawable);
+ off_x = -pixmap->screen_x;
+ off_y = -pixmap->screen_y;
+#endif
+ off_x += drawable->x;
+ off_y += drawable->y;
+ }
+
gc = GetScratchGC(dst->depth, screen);
if (!gc)
return;
pCopyClip = REGION_CREATE(screen, NULL, 0);
REGION_COPY(screen, pCopyClip, pRegion);
+ if (translate)
+ REGION_TRANSLATE(screen, pCopyClip, off_x, off_y);
(*gc->funcs->ChangeClip) (gc, CT_REGION, pCopyClip, 0);
ValidateGC(dst, gc);
@@ -282,11 +317,19 @@ ms_dri2_copy_region(DrawablePtr drawable, RegionPtr pRegion,
gc->ops->CopyArea(src, dst, gc,
0, 0,
drawable->width, drawable->height,
- 0, 0);
+ off_x, off_y);
FreeScratchGC(gc);
}
+static void
+ms_dri2_copy_region(DrawablePtr drawable, RegionPtr pRegion,
+ DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer)
+{
+ ms_dri2_copy_region2(drawable->pScreen, drawable, pRegion, destBuffer,
+ sourceBuffer);
+}
+
static uint64_t
gettime_us(void)
{
@@ -827,13 +870,16 @@ ms_dri2_screen_init(ScreenPtr screen)
info.driverName = NULL; /* Compat field, unused. */
info.deviceName = drmGetDeviceNameFromFd(ms->fd);
- info.version = 4;
+ info.version = 9;
info.CreateBuffer = ms_dri2_create_buffer;
info.DestroyBuffer = ms_dri2_destroy_buffer;
info.CopyRegion = ms_dri2_copy_region;
info.ScheduleSwap = ms_dri2_schedule_swap;
info.GetMSC = ms_dri2_get_msc;
info.ScheduleWaitMSC = ms_dri2_schedule_wait_msc;
+ info.CreateBuffer2 = ms_dri2_create_buffer2;
+ info.DestroyBuffer2 = ms_dri2_destroy_buffer2;
+ info.CopyRegion2 = ms_dri2_copy_region2;
/* These two will be filled in by dri2.c */
info.numDrivers = 0;
--
2.9.3
From 11b3755d9ff88414483ab072cd6f7028d967c957 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 23 Aug 2016 12:18:56 +0200
Subject: [PATCH v2 xserver 07/12] glamor: Add
glamor_shareable_fd_from_pixmap()
Add glamor_shareable_fd_from_pixmap function to get dma-buf fds suitable
for sharing across GPUs (not using GPU specific tiling).
This is necessary for the modesetting driver to correctly implement
the DRI2 SharePixmapBacking callback.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
---
glamor/glamor.c | 20 ++++++++++++++++++++
glamor/glamor.h | 20 ++++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 0cb73c4..f9020f0 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -829,6 +829,26 @@ glamor_fd_from_pixmap(ScreenPtr screen,
return -1;
}
+_X_EXPORT int
+glamor_shareable_fd_from_pixmap(ScreenPtr screen,
+ PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
+{
+ unsigned orig_usage_hint = pixmap->usage_hint;
+ int ret;
+
+ /*
+ * The actual difference between a sharable and non sharable buffer
+ * is decided 4 call levels deep in glamor_make_pixmap_exportable()
+ * based on pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED
+ * 2 of those calls are also exported API, so we cannot just add a flag.
+ */
+ pixmap->usage_hint = CREATE_PIXMAP_USAGE_SHARED;
+ ret = glamor_fd_from_pixmap(screen, pixmap, stride, size);
+ pixmap->usage_hint = orig_usage_hint;
+
+ return ret;
+}
+
int
glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
{
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 250dc83..e984092 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -187,6 +187,26 @@ extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen,
PixmapPtr pixmap,
CARD16 *stride, CARD32 *size);
+/* @glamor_shareable_fd_from_pixmap: Get a dma-buf fd suitable for sharing
+ * with other GPUs from a pixmap.
+ *
+ * @screen: Current screen pointer.
+ * @pixmap: The pixmap from which we want the fd.
+ * @stride, @size: Pointers to fill the stride and size of the
+ * buffer associated to the fd.
+ *
+ * The returned fd will point to a buffer which is suitable for sharing
+ * across GPUs (not using GPU specific tiling).
+ * The pixmap and the buffer associated by the fd will share the same
+ * content.
+ * The pixmap's stride may be modified by this function.
+ * Returns the fd on success, -1 on error.
+ * */
+extern _X_EXPORT int glamor_shareable_fd_from_pixmap(ScreenPtr screen,
+ PixmapPtr pixmap,
+ CARD16 *stride,
+ CARD32 *size);
+
/**
* @glamor_name_from_pixmap: Gets a gem name from a pixmap.
*
--
2.9.3
From ad87d5d52b6f1c4ed9eae0cd9e2ae1f23856ba5b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 17 Aug 2016 12:03:41 +0200
Subject: [PATCH v2 xserver 08/12] modesetting: Fix msSharePixmapBacking
returning a non-linear bo
glamor_fd_from_pixmap() may return a tiled bo, which is not suitable
for sharing with another GPU as tiling usually is GPU specific.
Switch to glamor_shareable_fd_from_pixmap(), which always returns a
linear bo. This fixes mis-rendering when running the mode setting
driver on the master gpu in a dual-gpu setup and running an opengl
app with DRI_PRIME=1.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
---
hw/xfree86/drivers/modesetting/driver.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 718966b..1e98c80 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1087,7 +1087,8 @@ msSharePixmapBacking(PixmapPtr ppix, ScreenPtr screen, void **handle)
int ret;
CARD16 stride;
CARD32 size;
- ret = glamor_fd_from_pixmap(ppix->drawable.pScreen, ppix, &stride, &size);
+ ret = glamor_shareable_fd_from_pixmap(ppix->drawable.pScreen, ppix,
+ &stride, &size);
if (ret == -1)
return FALSE;
--
2.9.3
From f432de42ff4133110b3382cb47b27f3943af8142 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 24 Aug 2016 14:13:19 +0200
Subject: [PATCH v2 xserver 09/12] modesetting: ms_covering_crtc: Remove unused
arguments, make static
Remove unused arguments from ms_covering_crtc, make it static as it is
only used in vblank.c.
While at it also change its first argument from a ScrnInfoPtr to a
ScreenPtr, this makes the next patch in this patch-set cleaner.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xfree86/drivers/modesetting/driver.h | 2 --
hw/xfree86/drivers/modesetting/vblank.c | 20 +++++---------------
2 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index 5e1c5d9..747e4e7 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -136,8 +136,6 @@ void ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq);
Bool ms_crtc_on(xf86CrtcPtr crtc);
xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
-xf86CrtcPtr ms_covering_crtc(ScrnInfoPtr scrn, BoxPtr box,
- xf86CrtcPtr desired, BoxPtr crtc_box_ret);
int ms_get_crtc_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc);
diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index 77e0848..c2cb70c 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -97,10 +97,10 @@ ms_crtc_on(xf86CrtcPtr crtc)
* with greater coverage
*/
-xf86CrtcPtr
-ms_covering_crtc(ScrnInfoPtr scrn,
- BoxPtr box, xf86CrtcPtr desired, BoxPtr crtc_box_ret)
+static xf86CrtcPtr
+ms_covering_crtc(ScreenPtr pScreen, BoxPtr box)
{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CrtcPtr crtc, best_crtc;
int coverage, best_coverage;
@@ -109,10 +109,6 @@ ms_covering_crtc(ScrnInfoPtr scrn,
best_crtc = NULL;
best_coverage = 0;
- crtc_box_ret->x1 = 0;
- crtc_box_ret->x2 = 0;
- crtc_box_ret->y1 = 0;
- crtc_box_ret->y2 = 0;
for (c = 0; c < xf86_config->num_crtc; c++) {
crtc = xf86_config->crtc[c];
@@ -123,12 +119,7 @@ ms_covering_crtc(ScrnInfoPtr scrn,
ms_crtc_box(crtc, &crtc_box);
ms_box_intersect(&cover_box, &crtc_box, box);
coverage = ms_box_area(&cover_box);
- if (coverage && crtc == desired) {
- *crtc_box_ret = crtc_box;
- return crtc;
- }
if (coverage > best_coverage) {
- *crtc_box_ret = crtc_box;
best_crtc = crtc;
best_coverage = coverage;
}
@@ -140,15 +131,14 @@ xf86CrtcPtr
ms_dri2_crtc_covering_drawable(DrawablePtr pDraw)
{
ScreenPtr pScreen = pDraw->pScreen;
- ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
- BoxRec box, crtcbox;
+ BoxRec box;
box.x1 = pDraw->x;
box.y1 = pDraw->y;
box.x2 = box.x1 + pDraw->width;
box.y2 = box.y1 + pDraw->height;
- return ms_covering_crtc(pScrn, &box, NULL, &crtcbox);
+ return ms_covering_crtc(pScreen, &box);
}
static Bool
--
2.9.3
From 5a040c012624afe4999e08a834d9d3f410ce7c8a Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 24 Aug 2016 14:55:27 +0200
Subject: [PATCH v2 xserver 10/12] modesetting: ms_covering_crtc: Allow calling
on non modesetting Screens
99% of the code in ms_covering_crtc is video-driver agnostic. Add a
screen_is_ms parameter when when FALSE skips the one ms specific check,
this will allow calling ms_covering_crtc on slave GPUs.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xfree86/drivers/modesetting/vblank.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index c2cb70c..0b1abb0 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -98,7 +98,7 @@ ms_crtc_on(xf86CrtcPtr crtc)
*/
static xf86CrtcPtr
-ms_covering_crtc(ScreenPtr pScreen, BoxPtr box)
+ms_covering_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -106,14 +106,20 @@ ms_covering_crtc(ScreenPtr pScreen, BoxPtr box)
int coverage, best_coverage;
int c;
BoxRec crtc_box, cover_box;
+ Bool crtc_on;
best_crtc = NULL;
best_coverage = 0;
for (c = 0; c < xf86_config->num_crtc; c++) {
crtc = xf86_config->crtc[c];
+ if (screen_is_ms)
+ crtc_on = ms_crtc_on(crtc);
+ else
+ crtc_on = crtc->enabled;
+
/* If the CRTC is off, treat it as not covering */
- if (!ms_crtc_on(crtc))
+ if (!crtc_on)
continue;
ms_crtc_box(crtc, &crtc_box);
@@ -138,7 +144,7 @@ ms_dri2_crtc_covering_drawable(DrawablePtr pDraw)
box.x2 = box.x1 + pDraw->width;
box.y2 = box.y1 + pDraw->height;
- return ms_covering_crtc(pScreen, &box);
+ return ms_covering_crtc(pScreen, &box, TRUE);
}
static Bool
--
2.9.3
From 4ee861beba7d05a836be4aa55e0947a1d8c11d74 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 24 Aug 2016 15:00:13 +0200
Subject: [PATCH v2 xserver 11/12] modesetting: Fall back to primary crtc for
vblank for drawables on slave outputs
This fixes glxgears running at 1 fps when fully covering a slave-output
and the modesetting driver is used for the master gpu.
Reported-by: Peter Wu <peter@lekensteyn.nl>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-Only fallback to primary crtc if it is in DPMSModeOn
---
hw/xfree86/drivers/modesetting/vblank.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index 0b1abb0..bedef28 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -130,6 +130,32 @@ ms_covering_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms)
best_coverage = coverage;
}
}
+
+ /* Fallback to primary crtc for drawable's on slave outputs */
+ if (best_crtc == NULL && !pScreen->isGPU) {
+ RROutputPtr primary_output = NULL;
+ ScreenPtr slave;
+
+ if (dixPrivateKeyRegistered(rrPrivKey))
+ primary_output = RRFirstOutput(scrn->pScreen);
+ if (!primary_output || !primary_output->crtc)
+ return NULL;
+
+ crtc = primary_output->crtc->devPrivate;
+ if (!ms_crtc_on(crtc))
+ return NULL;
+
+ xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) {
+ if (!slave->is_output_slave)
+ continue;
+
+ if (ms_covering_crtc(slave, box, FALSE)) {
+ /* The drawable is on a slave output, return primary crtc */
+ return crtc;
+ }
+ }
+ }
+
return best_crtc;
}
--
2.9.3