summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-05-03 22:33:59 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-05-03 22:40:52 +0100
commit61cac5c265279d45677262216a0ba56f548cd898 (patch)
tree87dbae797d6b512b43e2d5f55d624f2b57011263
parentdea5d429f7a52dfc945b17a57ef79744cc796b0e (diff)
sna: Maintain a reference to the chain of proxies
Rather than attempt to flatten the chain to the last link, we may need to hold a reference to the intermediate links in case of batch buffer submission. Fixes http://tnsp.org/~ccr/intel-gfx/test.html Reported-by: Matti Hamalainen <ccr@tnsp.org> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=49436 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/gen3_render.c7
-rw-r--r--src/sna/kgem.c26
-rw-r--r--src/sna/sna_accel.c3
-rw-r--r--src/sna/sna_render.c6
-rw-r--r--src/sna/sna_tiling.c8
5 files changed, 32 insertions, 18 deletions
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index ed2eaf1e..680d36f0 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2381,9 +2381,14 @@ gen3_composite_picture(struct sna *sna,
return sna_render_picture_convert(sna, picture, channel, pixmap,
x, y, w, h, dst_x, dst_y);
- if (too_large(pixmap->drawable.width, pixmap->drawable.height))
+ if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
+ DBG(("%s: pixmap too large (%dx%d), extracting (%d, %d)x(%d,%d)\n",
+ __FUNCTION__,
+ pixmap->drawable.width, pixmap->drawable.height,
+ x, y, w, h));
return sna_render_picture_extract(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
+ }
return sna_render_pixmap_bo(sna, channel, pixmap,
x, y, w, h, dst_x, dst_y);
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 49fa1735..a1169366 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2960,7 +2960,7 @@ bool kgem_check_bo(struct kgem *kgem, ...)
if (bo->exec)
continue;
- if (bo->proxy) {
+ while (bo->proxy) {
bo = bo->proxy;
if (bo->exec)
continue;
@@ -2989,7 +2989,7 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
{
uint32_t size;
- if (bo->proxy)
+ while (bo->proxy)
bo = bo->proxy;
if (bo->exec) {
if (kgem->gen < 40 &&
@@ -3034,7 +3034,7 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
va_start(ap, kgem);
while ((bo = va_arg(ap, struct kgem_bo *))) {
- if (bo->proxy)
+ while (bo->proxy)
bo = bo->proxy;
if (bo->exec) {
if (kgem->gen >= 40 || bo->tiling == I915_TILING_NONE)
@@ -3098,10 +3098,10 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
assert(bo->refcnt);
assert(!bo->purged);
- delta += bo->delta;
- if (bo->proxy) {
- DBG(("%s: adding proxy for handle=%d\n",
- __FUNCTION__, bo->handle));
+ while (bo->proxy) {
+ DBG(("%s: adding proxy [delta=%d] for handle=%d\n",
+ __FUNCTION__, bo->delta, bo->handle));
+ delta += bo->delta;
assert(bo->handle == bo->proxy->handle);
/* need to release the cache upon batch submit */
list_move(&bo->request, &kgem->next_request->buffers);
@@ -3527,8 +3527,9 @@ struct kgem_bo *kgem_create_proxy(struct kgem_bo *target,
{
struct kgem_bo *bo;
- DBG(("%s: target handle=%d, offset=%d, length=%d, io=%d\n",
- __FUNCTION__, target->handle, offset, length, target->io));
+ DBG(("%s: target handle=%d [proxy? %d], offset=%d, length=%d, io=%d\n",
+ __FUNCTION__, target->handle, target->proxy ? target->proxy->delta : -1,
+ offset, length, target->io));
bo = __kgem_bo_alloc(target->handle, length);
if (bo == NULL)
@@ -3537,15 +3538,11 @@ struct kgem_bo *kgem_create_proxy(struct kgem_bo *target,
bo->reusable = false;
bo->size.bytes = length;
- bo->io = target->io;
+ bo->io = target->io && target->proxy == NULL;
bo->dirty = target->dirty;
bo->tiling = target->tiling;
bo->pitch = target->pitch;
- if (target->proxy) {
- offset += target->delta;
- target = target->proxy;
- }
bo->proxy = kgem_bo_reference(target);
bo->delta = offset;
return bo;
@@ -4079,6 +4076,7 @@ void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
assert(_bo->proxy);
_bo = _bo->proxy;
+ assert(bo->proxy == NULL);
assert(_bo->exec == NULL);
bo = (struct kgem_partial_bo *)_bo;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 30723456..6430de8d 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2138,7 +2138,8 @@ sna_pixmap_create_upload(ScreenPtr screen,
int bpp = BitsPerPixel(depth);
void *ptr;
- DBG(("%s(%d, %d, %d)\n", __FUNCTION__, width, height, depth));
+ DBG(("%s(%d, %d, %d, flags=%x)\n", __FUNCTION__,
+ width, height, depth, flags));
assert(width);
assert(height);
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 3d0f9e94..dee66086 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -957,6 +957,10 @@ sna_render_picture_partial(struct sna *sna,
kgem_get_tile_size(&sna->kgem, bo->tiling,
&tile_width, &tile_height, &tile_size);
+ DBG(("%s: tiling=%d, size=%dx%d, chunk=%d\n",
+ __FUNCTION__, bo->tiling,
+ tile_width, tile_height, tile_size));
+
/* Ensure we align to an even tile row */
box.y1 = box.y1 & ~(2*tile_height - 1);
box.y2 = ALIGN(box.y2, 2*tile_height);
@@ -989,8 +993,6 @@ sna_render_picture_partial(struct sna *sna,
if (channel->bo == NULL)
return 0;
- channel->bo->pitch = bo->pitch;
-
if (channel->transform) {
memset(&channel->embedded_transform,
0,
diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index d0e5afc5..d7e6d400 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -188,6 +188,14 @@ sna_tiling_composite_done(struct sna *sna,
if (y2 > y + height)
y2 = y + height;
+ DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d), delta=(%d,%d)\n",
+ __FUNCTION__, n,
+ r->dst.x, r->dst.y,
+ r->width, r->height,
+ x, y, width, height,
+ x1, y1, x2, y2,
+ dx, dy));
+
if (y2 > y1 && x2 > x1) {
struct sna_composite_rectangles rr;
rr.src.x = dx + r->src.x;