xf86-video-intel: 3 commits - man/intel.man src/intel_options.c src/intel_options.h src/sna/sna_display.c src/sna/sna_display_fake.c src/sna/sna_dri.c src/sna/sna.h
Chris Wilson
ickle at kemper.freedesktop.org
Fri Aug 30 01:00:23 PDT 2013
man/intel.man | 12 ++++++++
src/intel_options.c | 1
src/intel_options.h | 1
src/sna/sna.h | 6 ++--
src/sna/sna_display.c | 62 +++++++++++++++++++++++++++++++++------------
src/sna/sna_display_fake.c | 40 +++++++++++++++++++++++------
src/sna/sna_dri.c | 24 ++++++++++-------
7 files changed, 110 insertions(+), 36 deletions(-)
New commits:
commit 6d99249c580cfb062a05ce1da446410741eb1223
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Aug 30 03:03:58 2013 +0100
sna: Protect against unattached pixmaps when peeking inside for a GPU bo
Prevent a NULL dereference for the small system pixmaps. Introduced with
commit f22d7f68b8b1bd5caf5ae831fca63eb1e6957520
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Aug 28 14:24:33 2013 +0100
sna/gen6+: Improve ring stickyness for BLT composite ops
Reported-by: Sami Farin <hvtaifwkbgefbaei at gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68728
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 5b26ebf..298883c 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -176,6 +176,7 @@ static inline PixmapPtr get_window_pixmap(WindowPtr window)
static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
{
+ assert(drawable);
if (drawable->type == DRAWABLE_PIXMAP)
return (PixmapPtr)drawable;
else
@@ -619,7 +620,8 @@ static inline struct kgem_bo *__sna_pixmap_get_bo(PixmapPtr pixmap)
static inline struct kgem_bo *__sna_drawable_peek_bo(DrawablePtr d)
{
- return sna_pixmap(get_drawable_pixmap(d))->gpu_bo;
+ struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d));
+ return priv ? priv->gpu_bo : NULL;
}
static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap, unsigned flags)
commit 314cfd7353c8c1acd961fdfc8eadbc0d55fa0f01
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Aug 29 21:30:28 2013 +0100
sna/dri: Correct the target_msc for immediate double-buffering
We also need to correctly offset the current_msc for the normal
pageflip, so rearrange the code flow so that we only do the calculation
of target_msc once.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 1eec740..44c2749 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -1044,6 +1044,11 @@ sna_dri_page_flip(struct sna *sna, struct sna_dri_frame_event *info)
if (!info->count)
return false;
+ DBG(("%s: mark handle=%d as scanout, swap front (handle=%d, name=%d) and back (handle=%d, name=%d)\n",
+ __FUNCTION__, bo->handle,
+ get_private(info->front)->bo->handle, info->front->name,
+ get_private(info->back)->bo->handle, info->back->name));
+
info->scanout[1] = info->scanout[0];
info->scanout[0].bo = ref(bo);
info->scanout[0].name = info->back->name;
@@ -1589,8 +1594,8 @@ static void sna_dri_flip_event(struct sna *sna,
/* We assume our flips arrive in order, so we don't check the frame */
switch (flip->type) {
case DRI2_FLIP:
- DBG(("%s: flip complete (drawable gone? %d)\n",
- __FUNCTION__, flip->draw == NULL));
+ DBG(("%s: flip complete (drawable gone? %d), msc=%d\n",
+ __FUNCTION__, flip->draw == NULL, flip->fe_frame));
if (flip->draw)
DRI2SwapComplete(flip->client, flip->draw,
flip->fe_frame,
@@ -1784,17 +1789,15 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw,
__FUNCTION__));
info->type = DRI2_FLIP;
sna->dri.flip_pending = info;
- *target_msc = current_msc + 1;
- return true;
- }
-
- if (!sna_dri_page_flip(sna, info)) {
- sna_dri_frame_event_info_free(sna, draw, info);
- return false;
+ } else {
+ if (!sna_dri_page_flip(sna, info)) {
+ sna_dri_frame_event_info_free(sna, draw, info);
+ return false;
+ }
}
+ current_msc++;
if (info->type != DRI2_FLIP) {
- current_msc++;
new_back:
sna_dri_flip_get_back(sna, info);
DRI2SwapComplete(client, draw, 0, 0, 0,
@@ -1802,6 +1805,7 @@ new_back:
func, data);
}
out:
+ DBG(("%s: target_msc=%lu\n", __FUNCTION__, (unsigned long)current_msc));
*target_msc = current_msc;
return true;
}
commit 68d139388a2a037347fa5c838391e67e006793ee
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Aug 29 23:00:05 2013 +0100
sna: Allow user specification of number of VirtualHeads
Previously, we instantiated a fake output in case we had a machine with
no output. (For certain server-class products.) The Bumblee project were
also doing something very similar in order to fake an extended desktop
on the Intel igfx and copy portions onto a discrete GPU. (The preferred
method for doing this upstream is through the use of PRIME). As the code
is very similar, we can support both use-cases simultaneously.
This adds the option:
Section "Device"
Driver "intel"
Option "VirtualHeads" "<count>"
EndSection
to allow the user to specify an additional set of fake outputs, which
can then be controlled using xrandr.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/man/intel.man b/man/intel.man
index 9e19687..0a26511 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -261,6 +261,18 @@ applications when monitors are connected or disconnected.
.IP
Default: enabled.
.TP
+.BI "Option \*qVirtualheads\*q \*q" integer \*q
+This option controls specifies the number of fake outputs to create in
+addition to the normal outputs detected on your hardware. These outputs
+cannot be assigned to the regular displays attached to the GPU, but do
+otherwise act as any other xrandr output and share a portion of the
+regular framebuffer. One use case for these extra heads is for extending
+your desktop onto a discrete GPU using the Bumblebee project. However,
+the recommendation here is to use PRIME instead to create a single
+Xserver that can addresses and coordinate between multiple GPUs.
+.IP
+Default: 0
+.TP
.BI "Option \*qZaphodHeads\*q \*q" string \*q
.IP
Specify the randr output(s) to use with zaphod mode for a particular driver
diff --git a/src/intel_options.c b/src/intel_options.c
index b81bde6..153cc62 100644
--- a/src/intel_options.c
+++ b/src/intel_options.c
@@ -23,6 +23,7 @@ const OptionInfoRec intel_options[] = {
#endif
#ifdef USE_SNA
{OPTION_ZAPHOD, "ZaphodHeads", OPTV_STRING, {0}, 0},
+ {OPTION_VIRTUAL, "VirtualHeads", OPTV_INTEGER, {0}, 0},
{OPTION_TEAR_FREE, "TearFree", OPTV_BOOLEAN, {0}, 0},
{OPTION_CRTC_PIXMAPS, "PerCrtcPixmaps", OPTV_BOOLEAN, {0}, 0},
#endif
diff --git a/src/intel_options.h b/src/intel_options.h
index 112983d..095660c 100644
--- a/src/intel_options.h
+++ b/src/intel_options.h
@@ -30,6 +30,7 @@ enum intel_options {
#endif
#ifdef USE_SNA
OPTION_ZAPHOD,
+ OPTION_VIRTUAL,
OPTION_TEAR_FREE,
OPTION_CRTC_PIXMAPS,
#endif
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 337ebc8..5b26ebf 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -330,7 +330,7 @@ struct sna {
};
bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna);
-bool sna_mode_fake_init(struct sna *sna);
+bool sna_mode_fake_init(struct sna *sna, int num_fake);
void sna_mode_adjust_frame(struct sna *sna, int x, int y);
extern void sna_mode_update(struct sna *sna);
extern void sna_mode_wakeup(struct sna *sna);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index da3475f..aa445ae 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2758,8 +2758,15 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
"resizing framebuffer to %dx%d\n",
width, height);
- for (i = 0; i < xf86_config->num_crtc; i++)
- sna_crtc_disable_shadow(sna, to_sna_crtc(xf86_config->crtc[i]));
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ struct sna_crtc *crtc;
+
+ crtc = to_sna_crtc(xf86_config->crtc[i]);
+ if (crtc == NULL)
+ continue;
+
+ sna_crtc_disable_shadow(sna, crtc);
+ }
assert(sna->mode.shadow_active == 0);
assert(sna->mode.shadow_damage == NULL);
assert(sna->mode.shadow == NULL);
@@ -2778,7 +2785,7 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
- if (!crtc->enabled)
+ if (!crtc->enabled || to_sna_crtc(crtc) == NULL)
continue;
if (!sna_crtc_set_mode_major(crtc,
@@ -2818,8 +2825,8 @@ static int do_page_flip(struct sna *sna, struct kgem_bo *bo,
struct drm_mode_crtc_page_flip arg;
DBG(("%s: crtc %d active? %d\n",
- __FUNCTION__, i, crtc->bo != NULL));
- if (crtc->bo == NULL)
+ __FUNCTION__, i, crtc && crtc->bo));
+ if (crtc == NULL || crtc->bo == NULL)
continue;
arg.crtc_id = crtc->id;
@@ -3019,6 +3026,9 @@ static bool sna_probe_initial_configuration(struct sna *sna)
struct drm_mode_crtc mode;
uint16_t *gamma;
+ if (sna_crtc == NULL)
+ continue;
+
crtc->enabled = FALSE;
crtc->desiredMode.status = MODE_NOMODE;
@@ -3088,6 +3098,9 @@ static bool sna_probe_initial_configuration(struct sna *sna)
xf86OutputPtr output = config->output[i];
uint32_t crtc_id;
+ if (to_sna_output(output) == NULL)
+ continue;
+
crtc_id = (uintptr_t)output->crtc;
output->crtc = NULL;
@@ -3189,6 +3202,7 @@ sna_crtc_config_notify(ScreenPtr screen)
bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
{
struct sna_mode *mode = &sna->mode;
+ int num_fake = 0;
int i;
if (sna->flags & SNA_IS_HOSTED) {
@@ -3196,6 +3210,9 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
return true;
}
+ if (!xf86GetOptValInteger(sna->Options, OPTION_VIRTUAL, &num_fake))
+ num_fake = 0;
+
mode->kmode = drmModeGetResources(sna->kgem.fd);
if (mode->kmode) {
xf86CrtcConfigInit(scrn, &sna_mode_funcs);
@@ -3211,17 +3228,20 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
if (!xf86IsEntityShared(scrn->entityList[0]))
sna_mode_compute_possible_clones(scrn);
-
- sna_setup_provider(scrn);
} else {
- if (!sna_mode_fake_init(sna))
- return false;
+ if (num_fake == 0)
+ num_fake = 1;
}
set_size_range(sna);
+ if (!sna_mode_fake_init(sna, num_fake))
+ return false;
+
if (!sna_probe_initial_configuration(sna))
xf86InitialConfiguration(scrn, TRUE);
+
+ sna_setup_provider(scrn);
return scrn->modes != NULL;
}
@@ -3241,8 +3261,15 @@ sna_mode_close(struct sna *sna)
if (sna->flags & SNA_IS_HOSTED)
return;
- for (i = 0; i < xf86_config->num_crtc; i++)
- sna_crtc_disable_shadow(sna, to_sna_crtc(xf86_config->crtc[i]));
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ struct sna_crtc *crtc;
+
+ crtc = to_sna_crtc(xf86_config->crtc[i]);
+ if (crtc == NULL)
+ continue;
+
+ sna_crtc_disable_shadow(sna, crtc);
+ }
}
void
@@ -3567,7 +3594,8 @@ sna_wait_for_scanline(struct sna *sna,
int y1, y2, pipe;
bool ret;
- assert(crtc);
+ assert(crtc != NULL);
+ assert(to_sna_crtc(crtc) != NULL);
assert(to_sna_crtc(crtc)->bo != NULL);
assert(pixmap == sna->front);
@@ -3930,7 +3958,7 @@ void sna_mode_redisplay(struct sna *sna)
struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
RegionRec damage;
- if (!sna_crtc->shadow)
+ if (sna_crtc == NULL || !sna_crtc->shadow)
continue;
assert(crtc->enabled);
@@ -3953,7 +3981,9 @@ void sna_mode_redisplay(struct sna *sna)
struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
RegionRec damage;
- if (!sna_crtc->shadow || sna_crtc->bo == sna->mode.shadow)
+ if (sna_crtc == NULL ||
+ !sna_crtc->shadow ||
+ sna_crtc->bo == sna->mode.shadow)
continue;
assert(crtc->enabled);
@@ -3987,8 +4017,8 @@ void sna_mode_redisplay(struct sna *sna)
struct drm_mode_crtc_page_flip arg;
DBG(("%s: crtc %d [%d, pipe=%d] active? %d\n",
- __FUNCTION__, i, crtc->id, crtc->pipe, crtc->bo != NULL));
- if (crtc->bo != old)
+ __FUNCTION__, i, crtc->id, crtc->pipe, crtc && crtc->bo));
+ if (crtc == NULL || crtc->bo != old)
continue;
assert(config->crtc[i]->enabled);
diff --git a/src/sna/sna_display_fake.c b/src/sna/sna_display_fake.c
index 6231eb5..afd5588 100644
--- a/src/sna/sna_display_fake.c
+++ b/src/sna/sna_display_fake.c
@@ -143,7 +143,7 @@ sna_output_dpms(xf86OutputPtr output, int dpms)
static xf86OutputStatus
sna_output_detect(xf86OutputPtr output)
{
- return XF86OutputStatusDisconnected;
+ return XF86OutputStatusUnknown;
}
static Bool
@@ -178,12 +178,15 @@ static const xf86OutputFuncsRec sna_output_funcs = {
};
static bool
-sna_output_fake(struct sna *sna)
+sna_output_fake(struct sna *sna, int n, int num_fake, int num_real_crtc, int num_real_output)
{
ScrnInfoPtr scrn = sna->scrn;
xf86OutputPtr output;
+ unsigned mask;
+ char buf[80];
- output = xf86OutputCreate(scrn, &sna_output_funcs, "FAKE");
+ sprintf(buf, "VIRTUAL%d", n+1);
+ output = xf86OutputCreate(scrn, &sna_output_funcs, buf);
if (!output)
return false;
@@ -192,8 +195,9 @@ sna_output_fake(struct sna *sna)
output->subpixel_order = SubPixelNone;
- output->possible_crtcs = 1;
- output->possible_clones = 0;
+ mask = (1 << num_fake) - 1;
+ output->possible_crtcs = mask << num_real_crtc;
+ output->possible_clones = mask << num_real_output;
output->interlaceAllowed = FALSE;
return true;
@@ -241,8 +245,28 @@ static const xf86CrtcConfigFuncsRec sna_mode_funcs = {
sna_mode_resize
};
-bool sna_mode_fake_init(struct sna *sna)
+bool sna_mode_fake_init(struct sna *sna, int num_fake)
{
- xf86CrtcConfigInit(sna->scrn, &sna_mode_funcs);
- return sna_crtc_fake(sna) && sna_output_fake(sna);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+ int n, num_real_crtc, num_real_output;
+
+ if (num_fake == 0)
+ return true;
+
+ num_real_crtc = xf86_config->num_crtc;
+ num_real_output = xf86_config->num_output;
+
+ if (num_real_crtc == 0)
+ xf86CrtcConfigInit(sna->scrn, &sna_mode_funcs);
+
+ for (n = 0; n < num_fake; n++) {
+ if (!sna_crtc_fake(sna))
+ return false;
+
+ if (!sna_output_fake(sna, n, num_fake,
+ num_real_crtc, num_real_output))
+ return false;
+ }
+
+ return true;
}
More information about the xorg-commit
mailing list