xf86-video-intel: 8 commits - src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/gen8_render.c src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_render.c
Chris Wilson
ickle at kemper.freedesktop.org
Thu Sep 25 08:49:46 PDT 2014
src/sna/gen4_render.c | 2
src/sna/gen5_render.c | 2
src/sna/gen6_render.c | 2
src/sna/gen7_render.c | 2
src/sna/gen8_render.c | 2
src/sna/sna_accel.c | 24 ++++-
src/sna/sna_display.c | 233 +++++++++++++++++++++++++++++++++++++-------------
src/sna/sna_render.c | 16 +++
8 files changed, 218 insertions(+), 65 deletions(-)
New commits:
commit 7302f8a6482f4eed497536fc5a8a487c10da4d52
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Sep 25 16:44:08 2014 +0100
sna: Pass scanout hints along to move-to-gpu
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index ea355aa..0aa7557 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1740,7 +1740,7 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
return true;
}
- priv = sna_pixmap_force_to_gpu(sna->front, MOVE_READ);
+ priv = sna_pixmap_force_to_gpu(sna->front, MOVE_READ | __MOVE_SCANOUT);
if (priv == NULL)
return true; /* maybe we can create a bo for the scanout? */
@@ -4180,7 +4180,7 @@ static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
if (!old_priv)
return;
- new_priv = sna_pixmap_force_to_gpu(new, MOVE_WRITE);
+ new_priv = sna_pixmap_force_to_gpu(new, MOVE_WRITE | __MOVE_SCANOUT);
if (!new_priv)
return;
commit e9087f50bf6dafff87c566d3bdbe6cef29d71fde
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Sep 25 16:41:11 2014 +0100
sna: Check scanout Pixmaps are the correct pitch and convert if necessary
As a final precaution, fixup the pitch on the bo to be used for
scanout by switching the bo on the Pixmap for a new correctly aligned
scanout bo.
Reported-by: Egbert Eich <eich at suse.com>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index e7908cb..ea355aa 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1832,6 +1832,61 @@ static void set_shadow(struct sna *sna, RegionPtr region)
priv->move_to_gpu_data = sna;
}
+static struct kgem_bo *
+get_scanout_bo(struct sna *sna, PixmapPtr pixmap)
+{
+ struct sna_pixmap *priv;
+
+ priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | __MOVE_SCANOUT);
+ if (!priv)
+ return NULL;
+
+ if (priv->gpu_bo->pitch & 63) {
+ struct kgem_bo *tmp;
+ BoxRec b;
+
+ DBG(("%s: converting to scanout bo due to bad pitch [%d]\n",
+ __FUNCTION__, priv->gpu_bo->pitch));
+
+ if (priv->pinned) {
+ DBG(("%s: failed as the Pixmap is already pinned [%x]\n",
+ __FUNCTION__, priv->pinned));
+ return NULL;
+ }
+
+ tmp = kgem_create_2d(&sna->kgem,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ sna->scrn->bitsPerPixel,
+ priv->gpu_bo->tiling,
+ CREATE_EXACT | CREATE_SCANOUT);
+ if (tmp == NULL) {
+ DBG(("%s: allocation failed\n", __FUNCTION__));
+ return NULL;
+ }
+
+ b.x1 = 0;
+ b.y1 = 0;
+ b.x2 = pixmap->drawable.width;
+ b.y2 = pixmap->drawable.height;
+
+ if (sna->render.copy_boxes(sna, GXcopy,
+ &pixmap->drawable, priv->gpu_bo, 0, 0,
+ &pixmap->drawable, tmp, 0, 0,
+ &b, 1, COPY_LAST)) {
+ DBG(("%s: copy failed\n", __FUNCTION__));
+ kgem_bo_destroy(&sna->kgem, tmp);
+ return NULL;
+ }
+
+ kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
+ priv->gpu_bo = tmp;
+ }
+
+ priv->pinned |= PIN_SCANOUT;
+ return priv->gpu_bo;
+}
+
static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
{
struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
@@ -1937,7 +1992,7 @@ out_shadow:
if (sna_crtc->slave_pixmap) {
DBG(("%s: attaching to scanout pixmap\n", __FUNCTION__));
- bo = sna_pixmap_pin(sna_crtc->slave_pixmap, PIN_SCANOUT);
+ bo = get_scanout_bo(sna, sna_crtc->slave_pixmap);
if (bo == NULL) {
DBG(("%s: failed to pin crtc scanout\n", __FUNCTION__));
sna_crtc->fallback_shadow = true;
@@ -1953,7 +2008,7 @@ out_shadow:
}
} else {
DBG(("%s: attaching to framebuffer\n", __FUNCTION__));
- bo = sna_pixmap_pin(sna->front, PIN_SCANOUT);
+ bo = get_scanout_bo(sna, sna->front);
if (bo == NULL) {
DBG(("%s: failed to pin framebuffer\n", __FUNCTION__));
sna_crtc->fallback_shadow = true;
commit 9f7c1a4c4f2a6352263c36e75a984ed4095adbc0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Sep 25 16:29:14 2014 +0100
sna: Check for scanout pitch restrictions on linear GPU bo
When converting a linear cached CPU bo into an uncached GPU bo, we must
be careful to adhere to the scanout restrictions if they apply for this
transfer or this Pixmap.
Reported-by: Egbert Eich <eich at suse.com>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 37e1e7c..4462207 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4051,6 +4051,27 @@ sna_pixmap_create_upload(ScreenPtr screen,
return pixmap;
}
+static bool can_convert_to_gpu(struct sna_pixmap *priv, unsigned flags)
+{
+ assert(priv->gpu_bo == NULL);
+
+ if (priv->cpu_bo == NULL)
+ return false;
+
+ if (priv->shm)
+ return false;
+
+ /* Linear scanout have a restriction that their pitch must be
+ * 64 byte aligned. Force the creation of a proper GPU bo if
+ * this CPU bo is not suitable for scanout.
+ */
+ if (priv->pixmap->usage_hint == SNA_CREATE_FB || flags & __MOVE_SCANOUT)
+ if (priv->cpu_bo->pitch & 63)
+ return false;
+
+ return true;
+}
+
struct sna_pixmap *
sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
{
@@ -4141,7 +4162,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
return NULL;
}
- if (is_linear && priv->cpu_bo && !priv->shm &&
+ if (is_linear &&
+ can_convert_to_gpu(priv, flags) &&
kgem_bo_convert_to_gpu(&sna->kgem, priv->cpu_bo, flags)) {
assert(!priv->mapped);
assert(!IS_STATIC_PTR(priv->ptr));
commit 4827c518fe3323eedb56e7af7aef33801236d11f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Sep 25 16:22:06 2014 +0100
sna: Use shadow CRTC bo if we fail to obtain an framebuffer for the Pixmap
This should mask driver bugs whereby we ask the kernel to make a
framebuffer out of an improper bo.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 07f5dff..e7908cb 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1846,6 +1846,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
unsigned long tiled_limit;
int tiling;
+force_shadow:
if (!sna_crtc_enable_shadow(sna, sna_crtc)) {
DBG(("%s: failed to enable crtc shadow\n"));
return NULL;
@@ -1939,26 +1940,30 @@ out_shadow:
bo = sna_pixmap_pin(sna_crtc->slave_pixmap, PIN_SCANOUT);
if (bo == NULL) {
DBG(("%s: failed to pin crtc scanout\n", __FUNCTION__));
- return NULL;
+ sna_crtc->fallback_shadow = true;
+ goto force_shadow;
}
if (!get_fb(sna, bo,
sna_crtc->slave_pixmap->drawable.width,
sna_crtc->slave_pixmap->drawable.height)) {
DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
- return NULL;
+ sna_crtc->fallback_shadow = true;
+ goto force_shadow;
}
} else {
DBG(("%s: attaching to framebuffer\n", __FUNCTION__));
bo = sna_pixmap_pin(sna->front, PIN_SCANOUT);
if (bo == NULL) {
DBG(("%s: failed to pin framebuffer\n", __FUNCTION__));
- return NULL;
+ sna_crtc->fallback_shadow = true;
+ goto force_shadow;
}
if (!get_fb(sna, bo, scrn->virtualX, scrn->virtualY)) {
DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
- return NULL;
+ sna_crtc->fallback_shadow = true;
+ goto force_shadow;
}
}
@@ -1995,7 +2000,8 @@ out_shadow:
CREATE_SCANOUT);
if (shadow == NULL) {
DBG(("%s: failed to allocate TearFree shadow bo\n", __FUNCTION__));
- return NULL;
+ sna_crtc->fallback_shadow = true;
+ goto force_shadow;
}
if (!get_fb(sna, shadow,
@@ -2003,7 +2009,8 @@ out_shadow:
region.extents.y2)) {
DBG(("%s: failed to bind fb for TearFeee shadow\n", __FUNCTION__));
kgem_bo_destroy(&sna->kgem, shadow);
- return NULL;
+ sna_crtc->fallback_shadow = true;
+ goto force_shadow;
}
sna->mode.shadow = shadow;
commit f3d27eec52cac63378c0e466db971ae125c813a1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Sep 24 16:16:25 2014 +0100
sna/gen4+: Assert that the offset coordinate is within range if negative
Invalid negative offsets could slip into the drawing rectangle
without triggering the assertion - the assertion being that they were
not greater than the maximum positive coordinate of the 3d engine.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 9a6761f..6c2d380 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -941,7 +941,7 @@ gen4_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op)
uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
- assert(!too_large(op->dst.x, op->dst.y));
+ assert(!too_large(abs(op->dst.x), abs(op->dst.y)));
assert(!too_large(op->dst.width, op->dst.height));
if (sna->render_state.gen4.drawrect_limit == limit &&
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 1ebaef9..435e674 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -877,7 +877,7 @@ gen5_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op)
uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
- assert(!too_large(op->dst.x, op->dst.y));
+ assert(!too_large(abs(op->dst.x), abs(op->dst.y)));
assert(!too_large(op->dst.width, op->dst.height));
if (!DBG_NO_STATE_CACHE &&
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 86ea146..5c625ef 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -687,7 +687,7 @@ gen6_emit_drawing_rectangle(struct sna *sna,
uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
- assert(!too_large(op->dst.x, op->dst.y));
+ assert(!too_large(abs(op->dst.x), abs(op->dst.y)));
assert(!too_large(op->dst.width, op->dst.height));
if (sna->render_state.gen6.drawrect_limit == limit &&
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 571de6e..16e666b 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -923,7 +923,7 @@ gen7_emit_drawing_rectangle(struct sna *sna,
uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
- assert(!too_large(op->dst.x, op->dst.y));
+ assert(!too_large(abs(op->dst.x), abs(op->dst.y)));
assert(!too_large(op->dst.width, op->dst.height));
if (sna->render_state.gen7.drawrect_limit == limit &&
diff --git a/src/sna/gen8_render.c b/src/sna/gen8_render.c
index e251315..6cc7a68 100644
--- a/src/sna/gen8_render.c
+++ b/src/sna/gen8_render.c
@@ -989,7 +989,7 @@ gen8_emit_drawing_rectangle(struct sna *sna,
uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
- assert(!too_large(op->dst.x, op->dst.y));
+ assert(!too_large(abs(op->dst.x), abs(op->dst.y)));
assert(!too_large(op->dst.width, op->dst.height));
if (sna->render_state.gen8.drawrect_limit == limit &&
commit a60ccd546e081f5b7bd7de762e1638927a4145a2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Sep 24 15:55:11 2014 +0100
sna: Relax constant numCrtcs assertion when ZaphodHeads is active
If ZaphodHeads is active, each screen only has a subset of the CRTC
assigned to it, in fact just the single CRTC associated with the pipe of
that screen. In that case, we only expect to have the single CRTC and so
should not assert that we have a list of all CRTCS.
It should still hold that we dynamically attach ZaphodHeads upon
hotplugging, so it is just the assert that is overzealous.
Reported-by: Nick Bowler <nbowler at draconx.ca>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=84281
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index cab17c3..07f5dff 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -217,6 +217,11 @@ enum { /* XXX copied from hw/xfree86/modes/xf86Crtc.c */
static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
+static bool is_zaphod(ScrnInfoPtr scrn)
+{
+ return xf86IsEntityShared(scrn->entityList[0]);
+}
+
inline static unsigned count_to_mask(int x)
{
return (1 << x) - 1;
@@ -1022,7 +1027,7 @@ sna_crtc_apply(xf86CrtcPtr crtc)
(uint32_t)output->possible_clones));
assert(output->possible_crtcs & (1 << sna_crtc->pipe) ||
- xf86IsEntityShared(crtc->scrn->entityList[0]));
+ is_zaphod(crtc->scrn));
output_ids[output_count] = to_connector_id(output);
if (++output_count == ARRAY_SIZE(output_ids)) {
@@ -2636,7 +2641,7 @@ sna_crtc_add(ScrnInfoPtr scrn, int id)
}
sna_crtc->pipe = get_pipe.pipe;
- if (xf86IsEntityShared(scrn->entityList[0]) &&
+ if (is_zaphod(scrn) &&
scrn->confScreen->device->screen != sna_crtc->pipe) {
free(sna_crtc);
return true;
@@ -3715,7 +3720,7 @@ sna_output_add(struct sna *sna, unsigned id, unsigned serial)
(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc);
}
- if (xf86IsEntityShared(scrn->entityList[0])) {
+ if (is_zaphod(scrn)) {
const char *str;
str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
@@ -4031,7 +4036,7 @@ void sna_mode_discover(struct sna *sna)
if (res.count_connectors > 32)
return;
- assert(sna->mode.num_real_crtc == res.count_crtcs);
+ assert(sna->mode.num_real_crtc == res.count_crtcs || is_zaphod(sna->scrn));
assert(sna->mode.max_crtc_width == res.max_width);
assert(sna->mode.max_crtc_height == res.max_height);
assert(sna->mode.num_real_encoder == res.count_encoders);
@@ -5106,7 +5111,7 @@ sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x,
(uint32_t)output->possible_clones));
assert(output->possible_crtcs & (1 << crtc->pipe) ||
- xf86IsEntityShared(sna->scrn->entityList[0]));
+ is_zaphod(sna->scrn));
output_ids[output_count] = to_connector_id(output);
if (++output_count == ARRAY_SIZE(output_ids))
commit 7637f547ca34668ef9d4f0c417de16e7126927b5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Sep 24 15:43:53 2014 +0100
sna: Tweak partial Picture extraction to prefer limiting to max 3D coordinates
Where possible, keep the offset of the partial Picture within the 3D
coordinate limit so that we can use the DrawRectangle offset to
automatically adjust the coordinates.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 71330c1..af072f0 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -1977,6 +1977,14 @@ sna_render_composite_redirect(struct sna *sna,
box.x1 = box.x1 & ~(tile_width * 8 / op->dst.pixmap->drawable.bitsPerPixel - 1);
box.x2 = ALIGN(box.x2, tile_width * 8 / op->dst.pixmap->drawable.bitsPerPixel);
+ if (box.x1 > sna->render.max_3d_size &&
+ box.x2 <= 2*sna->render.max_3d_size)
+ box.x1 = sna->render.max_3d_size;
+
+ if (box.y1 > sna->render.max_3d_size &&
+ box.y2 <= 2*sna->render.max_3d_size)
+ box.y1 = sna->render.max_3d_size;
+
offset = box.x1 * op->dst.pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size;
} else {
if (sna->kgem.gen < 040) {
@@ -1993,6 +2001,14 @@ sna_render_composite_redirect(struct sna *sna,
box.x2 = ALIGN(box.x2, 2);
}
+ if (box.x1 > sna->render.max_3d_size &&
+ box.x2 <= 2*sna->render.max_3d_size)
+ box.x1 = sna->render.max_3d_size;
+
+ if (box.y1 > sna->render.max_3d_size &&
+ box.y2 <= 2*sna->render.max_3d_size)
+ box.y1 = sna->render.max_3d_size;
+
offset = box.x1 * op->dst.pixmap->drawable.bitsPerPixel / 8;
}
commit 65a23ef90975f95444da103f45eb240b2895ef44
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Sep 24 14:06:30 2014 +0100
sna: Reuse the same buffer when panning large CRTCs
Rather than alternating between a pair of fb each time, we can reuse the
last shadow buffer so long as it remains the right size.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 3ca56f1..cab17c3 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -120,7 +120,7 @@ struct sna_crtc {
int dpms_mode;
PixmapPtr slave_pixmap;
DamagePtr slave_damage;
- struct kgem_bo *bo, *shadow_bo;
+ struct kgem_bo *bo, *shadow_bo, *client_bo;
struct sna_cursor *cursor;
unsigned int last_cursor_size;
uint32_t offset;
@@ -130,6 +130,8 @@ struct sna_crtc {
uint8_t id;
uint8_t pipe;
+ uint16_t shadow_bo_width, shadow_bo_height;
+
uint32_t rotation;
struct plane {
uint32_t id;
@@ -1121,17 +1123,17 @@ static bool wait_for_shadow(struct sna *sna,
crtc->base->bounds.y1,
crtc->base->bounds.x2,
crtc->base->bounds.y2,
- crtc->shadow_bo->handle));
+ crtc->client_bo->handle));
ret &= sna->render.copy_boxes(sna, GXcopy,
- &draw, crtc->shadow_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
+ &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
&pixmap->drawable, priv->gpu_bo, 0, 0,
&crtc->base->bounds, 1,
0);
}
- kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
- crtc->shadow_bo = NULL;
+ kgem_bo_destroy(&sna->kgem, crtc->client_bo);
+ crtc->client_bo = NULL;
list_del(&crtc->shadow_link);
}
}
@@ -1226,10 +1228,10 @@ static bool wait_for_shadow(struct sna *sna,
crtc->base->bounds.y1,
crtc->base->bounds.x2,
crtc->base->bounds.y2,
- crtc->shadow_bo->handle));
+ crtc->client_bo->handle));
ret = sna->render.copy_boxes(sna, GXcopy,
- &draw, crtc->shadow_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
+ &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
&pixmap->drawable, bo, 0, 0,
&crtc->base->bounds, 1,
0);
@@ -1240,8 +1242,8 @@ static bool wait_for_shadow(struct sna *sna,
RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, ®ion);
}
- kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
- crtc->shadow_bo = NULL;
+ kgem_bo_destroy(&sna->kgem, crtc->client_bo);
+ crtc->client_bo = NULL;
list_del(&crtc->shadow_link);
}
@@ -1433,7 +1435,7 @@ static bool sna_crtc_enable_shadow(struct sna *sna, struct sna_crtc *crtc)
static void sna_crtc_disable_override(struct sna *sna, struct sna_crtc *crtc)
{
- if (crtc->shadow_bo == NULL)
+ if (crtc->client_bo == NULL)
return;
if (!crtc->transform) {
@@ -1445,13 +1447,13 @@ static void sna_crtc_disable_override(struct sna *sna, struct sna_crtc *crtc)
tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
sna->render.copy_boxes(sna, GXcopy,
- &tmp, crtc->shadow_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
+ &tmp, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
&sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0,
&crtc->base->bounds, 1, 0);
list_del(&crtc->shadow_link);
}
- kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
- crtc->shadow_bo = NULL;
+ kgem_bo_destroy(&sna->kgem, crtc->client_bo);
+ crtc->client_bo = NULL;
}
static void sna_crtc_disable_shadow(struct sna *sna, struct sna_crtc *crtc)
@@ -1499,6 +1501,10 @@ __sna_crtc_disable(struct sna *sna, struct sna_crtc *sna_crtc)
sna->mode.dirty = true;
}
+ if (sna_crtc->shadow_bo) {
+ kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo);
+ sna_crtc->shadow_bo = NULL;
+ }
sna_crtc->transform = false;
assert(!sna_crtc->shadow);
@@ -1843,6 +1849,19 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
DBG(("%s: attaching to per-crtc pixmap %dx%d\n",
__FUNCTION__, crtc->mode.HDisplay, crtc->mode.VDisplay));
+ bo = sna_crtc->shadow_bo;
+ if (bo) {
+ if (sna_crtc->shadow_bo_width == crtc->mode.HDisplay &&
+ sna_crtc->shadow_bo_height == crtc->mode.VDisplay) {
+ DBG(("%s: reusing current shadow bo handle=%d\n",
+ __FUNCTION__, bo->handle));
+ goto out_shadow;
+ }
+
+ kgem_bo_destroy(&sna->kgem, bo);
+ sna_crtc->shadow_bo = NULL;
+ }
+
tiling = I915_TILING_X;
if (sna->kgem.gen == 071)
tiled_limit = 16 * 1024 * 8;
@@ -1862,25 +1881,29 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
scrn->bitsPerPixel,
tiling, CREATE_SCANOUT);
if (bo == NULL) {
- DBG(("%s: failed to allocate crtc scanout\n"));
+ DBG(("%s: failed to allocate crtc scanout\n", __FUNCTION__));
return NULL;
}
if (!get_fb(sna, bo, crtc->mode.HDisplay, crtc->mode.VDisplay)) {
- DBG(("%s: failed to bind fb for crtc scanout\n"));
+ DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
kgem_bo_destroy(&sna->kgem, bo);
return NULL;
}
- if (__sna_pixmap_get_bo(sna->front)) {
+ if (__sna_pixmap_get_bo(sna->front) && !crtc->transformPresent) {
DrawableRec tmp;
+ BoxRec b;
+
+ b.x1 = crtc->x;
+ b.y1 = crtc->y;
+ b.x2 = crtc->x + crtc->mode.HDisplay;
+ b.y2 = crtc->y + crtc->mode.VDisplay;
- DBG(("%s: copying onto shadow CRTC: (%d, %d), (%d, %d), handle=%d\n",
+ DBG(("%s: copying onto shadow CRTC: (%d, %d)x(%d, %d), handle=%d\n",
__FUNCTION__,
- crtc->bounds.x1,
- crtc->bounds.y1,
- crtc->bounds.x2,
- crtc->bounds.y2,
+ b.x1, b.y1,
+ b.x2, b.y2,
bo->handle));
tmp.width = crtc->mode.HDisplay;
@@ -1890,26 +1913,34 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
(void)sna->render.copy_boxes(sna, GXcopy,
&sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0,
- &tmp, bo, -crtc->bounds.x1, -crtc->bounds.y1,
- &crtc->bounds, 1,
- 0);
+ &tmp, bo, -b.x1, -b.y1,
+ &b, 1, 0);
}
+ sna_crtc->shadow_bo_width = crtc->mode.HDisplay;
+ sna_crtc->shadow_bo_height = crtc->mode.VDisplay;
+ sna_crtc->shadow_bo = bo;
+out_shadow:
sna_crtc->transform = true;
- return bo;
+ return kgem_bo_reference(bo);
} else {
+ if (sna_crtc->shadow_bo) {
+ kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo);
+ sna_crtc->shadow_bo = NULL;
+ }
+
if (sna_crtc->slave_pixmap) {
DBG(("%s: attaching to scanout pixmap\n", __FUNCTION__));
bo = sna_pixmap_pin(sna_crtc->slave_pixmap, PIN_SCANOUT);
if (bo == NULL) {
- DBG(("%s: failed to pin crtc scanout\n"));
+ DBG(("%s: failed to pin crtc scanout\n", __FUNCTION__));
return NULL;
}
if (!get_fb(sna, bo,
sna_crtc->slave_pixmap->drawable.width,
sna_crtc->slave_pixmap->drawable.height)) {
- DBG(("%s: failed to bind fb for crtc scanout\n"));
+ DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
return NULL;
}
} else {
@@ -1921,7 +1952,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
}
if (!get_fb(sna, bo, scrn->virtualX, scrn->virtualY)) {
- DBG(("%s: failed to bind fb for crtc scanout\n"));
+ DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
return NULL;
}
}
@@ -1931,7 +1962,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
DBG(("%s: enabling TearFree shadow\n", __FUNCTION__));
if (!sna_crtc_enable_shadow(sna, sna_crtc)) {
- DBG(("%s: failed to enable crtc shadow\n"));
+ DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__));
return NULL;
}
@@ -1965,7 +1996,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
if (!get_fb(sna, shadow,
region.extents.x2,
region.extents.y2)) {
- DBG(("%s: failed to bind fb for TearFeee shadow\n"));
+ DBG(("%s: failed to bind fb for TearFeee shadow\n", __FUNCTION__));
kgem_bo_destroy(&sna->kgem, shadow);
return NULL;
}
@@ -2145,6 +2176,8 @@ __sna_crtc_set_mode(xf86CrtcPtr crtc)
uint32_t saved_offset;
bool saved_transform;
+ DBG(("%s\n", __FUNCTION__));
+
saved_bo = sna_crtc->bo;
saved_transform = sna_crtc->transform;
saved_offset = sna_crtc->offset;
@@ -5169,6 +5202,11 @@ fixup_flip:
crtc->bo->active_scanout--;
kgem_bo_destroy(&sna->kgem, crtc->bo);
+ if (crtc->shadow_bo) {
+ kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
+ crtc->shadow_bo = NULL;
+ }
+
crtc->bo = kgem_bo_reference(bo);
crtc->bo->active_scanout++;
@@ -6723,11 +6761,11 @@ void sna_shadow_set_crtc(struct sna *sna,
assert(sna_crtc);
assert(!sna_crtc->transform);
- if (sna_crtc->shadow_bo != bo) {
- if (sna_crtc->shadow_bo)
- kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo);
+ if (sna_crtc->client_bo != bo) {
+ if (sna_crtc->client_bo)
+ kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo);
- sna_crtc->shadow_bo = kgem_bo_reference(bo);
+ sna_crtc->client_bo = kgem_bo_reference(bo);
sna_crtc_damage(crtc);
}
@@ -6748,11 +6786,11 @@ void sna_shadow_unset_crtc(struct sna *sna,
DBG(("%s: clearin shadow override for CRTC:%d\n",
__FUNCTION__, sna_crtc->id));
- if (sna_crtc->shadow_bo == NULL)
+ if (sna_crtc->client_bo == NULL)
return;
- kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo);
- sna_crtc->shadow_bo = NULL;
+ kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo);
+ sna_crtc->client_bo = NULL;
list_del(&sna_crtc->shadow_link);
sna->mode.shadow_dirty = true;
@@ -6884,7 +6922,7 @@ void sna_mode_redisplay(struct sna *sna)
damage.extents = crtc->bounds;
damage.data = NULL;
- bo = sna_crtc->shadow_bo;
+ bo = sna_crtc->client_bo;
if (bo == NULL)
bo = kgem_create_2d(&sna->kgem,
crtc->mode.HDisplay,
@@ -6934,7 +6972,7 @@ disable1:
}
kgem_bo_destroy(&sna->kgem, bo);
- sna_crtc->shadow_bo = NULL;
+ sna_crtc->client_bo = NULL;
continue;
}
sna->mode.flip_active++;
@@ -6945,7 +6983,7 @@ disable1:
sna_crtc->flip_bo->active_scanout++;
sna_crtc->flip_serial = sna_crtc->mode_serial;
- sna_crtc->shadow_bo = kgem_bo_reference(sna_crtc->bo);
+ sna_crtc->client_bo = kgem_bo_reference(sna_crtc->bo);
} else {
sna_crtc_redisplay(crtc, &damage, sna_crtc->bo);
kgem_scanout_flush(&sna->kgem, sna_crtc->bo);
@@ -6992,14 +7030,14 @@ disable1:
arg.crtc_id = crtc->id;
arg.user_data = (uintptr_t)crtc;
- if (crtc->shadow_bo) {
+ if (crtc->client_bo) {
DBG(("%s: apply shadow override bo for CRTC:%d on pipe=%d, handle=%d\n",
- __FUNCTION__, crtc->id, crtc->pipe, crtc->shadow_bo->handle));
- arg.fb_id = get_fb(sna, crtc->shadow_bo,
+ __FUNCTION__, crtc->id, crtc->pipe, crtc->client_bo->handle));
+ arg.fb_id = get_fb(sna, crtc->client_bo,
crtc->base->mode.HDisplay,
crtc->base->mode.VDisplay);
assert(arg.fb_id != fb);
- flip_bo = crtc->shadow_bo;
+ flip_bo = crtc->client_bo;
x = y = 0;
} else {
if (fb == 0)
@@ -7047,6 +7085,11 @@ fixup_flip:
crtc->bo->active_scanout--;
kgem_bo_destroy(&sna->kgem, crtc->bo);
+ if (crtc->shadow_bo) {
+ kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
+ crtc->shadow_bo = NULL;
+ }
+
crtc->bo = kgem_bo_reference(flip_bo);
crtc->bo->active_scanout++;
} else {
@@ -7152,6 +7195,11 @@ void sna_mode_wakeup(struct sna *sna)
crtc->bo->active_scanout--;
kgem_bo_destroy(&sna->kgem, crtc->bo);
+ if (crtc->shadow_bo) {
+ kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
+ crtc->shadow_bo = NULL;
+ }
+
crtc->bo = crtc->flip_bo;
crtc->flip_bo = NULL;
} else {
More information about the xorg-commit
mailing list