xf86-video-intel: 7 commits - src/sna/gen2_render.c src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna.h
Chris Wilson
ickle at kemper.freedesktop.org
Mon Aug 20 15:49:05 PDT 2012
src/sna/gen2_render.c | 2 -
src/sna/gen3_render.c | 68 +++++++++++++++++++++++++++++---------------------
src/sna/gen4_render.c | 18 +++++++------
src/sna/gen5_render.c | 17 ++++++------
src/sna/gen6_render.c | 14 +++++-----
src/sna/gen7_render.c | 17 ++++++------
src/sna/kgem.c | 44 ++++++++++++++++++++++++++------
src/sna/kgem.h | 6 ++--
src/sna/sna.h | 3 +-
src/sna/sna_accel.c | 14 ++++++++--
10 files changed, 129 insertions(+), 74 deletions(-)
New commits:
commit c86df17c1455a53cb52f33a25c8c362e5331621e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Aug 20 22:54:06 2012 +0100
sna/gen3: Fix assertion to check the freshly allocated vertex bo
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 7fb5a08..ab94bdb 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -1713,7 +1713,7 @@ static void gen3_vertex_close(struct sna *sna)
bo = kgem_create_linear(&sna->kgem,
4*sna->render.vertex_used, 0);
if (bo) {
- assert(sna->render.vbo->snoop == false);
+ assert(bo->snoop == false);
kgem_bo_write(&sna->kgem, bo,
sna->render.vertex_data,
4*sna->render.vertex_used);
commit 6aabe90587f4916a01a1cd2bbc577a1e7fa20eca
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Aug 20 22:09:54 2012 +0100
sna: Allow target bo promotion to GPU even on old architectures
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 f530603..9fda8ca 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2551,9 +2551,6 @@ use_cpu_bo:
if (priv->cpu_bo == NULL)
return NULL;
- if (!to_sna_from_pixmap(pixmap)->kgem.can_blt_cpu)
- return NULL;
-
if ((flags & FORCE_GPU) == 0 && !kgem_bo_is_busy(priv->cpu_bo))
return NULL;
@@ -2578,6 +2575,9 @@ use_cpu_bo:
goto move_to_gpu;
}
+ if (!to_sna_from_pixmap(pixmap)->kgem.can_blt_cpu)
+ return NULL;
+
if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, ®ion,
MOVE_READ | MOVE_ASYNC_HINT)) {
DBG(("%s: failed to move-to-cpu, fallback\n", __FUNCTION__));
commit 1a4b6fea7b1516de35e6800efa5b85f8401a5b2a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Aug 20 22:08:23 2012 +0100
sna: Assign a unique id to snoopable CPU bo
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index c5b88ff..49e27d0 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3309,6 +3309,7 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
assert(bo->snoop);
bo->refcnt = 1;
bo->pitch = stride;
+ bo->unique_id = kgem_get_unique_id(kgem);
return bo;
}
@@ -3331,6 +3332,7 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
}
bo->pitch = stride;
+ bo->unique_id = kgem_get_unique_id(kgem);
return bo;
}
@@ -3350,6 +3352,7 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
bo->map = MAKE_USER_MAP(ptr);
bo->pitch = stride;
+ bo->unique_id = kgem_get_unique_id(kgem);
return bo;
}
commit 892b1a1e431e8f27133825f8a27dde4955da0054
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Aug 20 22:07:05 2012 +0100
sna/gen3: Convert to sna_drawable_use_bo()
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 81d2c95..7fb5a08 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2483,37 +2483,48 @@ gen3_align_vertex(struct sna *sna,
static bool
gen3_composite_set_target(struct sna *sna,
struct sna_composite_op *op,
- PicturePtr dst)
+ PicturePtr dst,
+ int x, int y, int w, int h)
{
- struct sna_pixmap *priv;
+ BoxRec box;
op->dst.pixmap = get_drawable_pixmap(dst->pDrawable);
op->dst.format = dst->format;
op->dst.width = op->dst.pixmap->drawable.width;
op->dst.height = op->dst.pixmap->drawable.height;
- op->dst.bo = NULL;
- priv = sna_pixmap(op->dst.pixmap);
- if (priv &&
- priv->gpu_bo == NULL &&
- priv->cpu_bo && priv->cpu_bo->domain != DOMAIN_CPU) {
- op->dst.bo = priv->cpu_bo;
- op->damage = &priv->cpu_damage;
+ if (w && h) {
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + w;
+ box.y2 = y + h;
+ } else {
+ box.x1 = dst->pDrawable->x;
+ box.y1 = dst->pDrawable->y;
+ box.x2 = box.x1 + dst->pDrawable->width;
+ box.y2 = box.y1 + dst->pDrawable->height;
}
- if (op->dst.bo == NULL) {
- priv = sna_pixmap_force_to_gpu(op->dst.pixmap, MOVE_READ | MOVE_WRITE);
- if (priv == NULL)
+
+ op->dst.bo = sna_drawable_use_bo (dst->pDrawable,
+ PREFER_GPU | FORCE_GPU | RENDER_GPU,
+ &box, &op->damage);
+ if (op->dst.bo == NULL)
+ return false;
+
+ /* For single-stream mode there should be no minimum alignment
+ * required, except that the width must be at least 2 elements.
+ */
+ if (op->dst.bo->pitch < 2*op->dst.pixmap->drawable.bitsPerPixel) {
+ struct sna_pixmap *priv;
+
+ priv = sna_pixmap_move_to_gpu (op->dst.pixmap,
+ MOVE_READ | MOVE_WRITE);
+ if (priv == NULL || priv->pinned)
return false;
- /* For single-stream mode there should be no minimum alignment
- * required, except that the width must be at least 2 elements.
- */
if (priv->gpu_bo->pitch < 2*op->dst.pixmap->drawable.bitsPerPixel) {
struct kgem_bo *bo;
- if (priv->pinned)
- return false;
-
bo = kgem_replace_bo(&sna->kgem, priv->gpu_bo,
op->dst.width, op->dst.height,
2*op->dst.pixmap->drawable.bitsPerPixel,
@@ -2524,13 +2535,13 @@ gen3_composite_set_target(struct sna *sna,
kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
priv->gpu_bo = bo;
}
- assert(priv->gpu_bo->proxy == NULL);
op->dst.bo = priv->gpu_bo;
op->damage = &priv->gpu_damage;
+ if (sna_damage_is_all(op->damage,
+ op->dst.width, op->dst.height))
+ op->damage = NULL;
}
- if (sna_damage_is_all(op->damage, op->dst.width, op->dst.height))
- op->damage = NULL;
get_drawable_deltas(dst->pDrawable, op->dst.pixmap,
&op->dst.x, &op->dst.y);
@@ -2543,6 +2554,7 @@ gen3_composite_set_target(struct sna *sna,
op->dst.x, op->dst.y,
op->damage ? *op->damage : (void *)-1));
+ assert(op->dst.bo->proxy == NULL);
return true;
}
@@ -2832,14 +2844,13 @@ gen3_render_composite(struct sna *sna,
width, height,
tmp);
- if (!gen3_composite_set_target(sna, tmp, dst)) {
+ if (!gen3_composite_set_target(sna, tmp, dst,
+ dst_x, dst_y, width, height)) {
DBG(("%s: unable to set render target\n",
__FUNCTION__));
return false;
}
- sna_render_reduce_damage(tmp, dst_x, dst_y, width, height);
-
tmp->op = op;
tmp->rb_reversed = gen3_dst_rb_reversed(tmp->dst.format);
if (too_large(tmp->dst.width, tmp->dst.height) ||
@@ -3421,12 +3432,12 @@ gen3_render_composite_spans(struct sna *sna,
width, height, flags, tmp);
}
- if (!gen3_composite_set_target(sna, &tmp->base, dst)) {
+ if (!gen3_composite_set_target(sna, &tmp->base, dst,
+ dst_x, dst_y, width, height)) {
DBG(("%s: unable to set render target\n",
__FUNCTION__));
return false;
}
- sna_render_reduce_damage(&tmp->base, dst_x, dst_y, width, height);
tmp->base.op = op;
tmp->base.rb_reversed = gen3_dst_rb_reversed(tmp->base.dst.format);
diff --git a/src/sna/sna.h b/src/sna/sna.h
index cd55afd..157830b 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -464,7 +464,8 @@ struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling);
#define PREFER_GPU 0x1
#define FORCE_GPU 0x2
-#define IGNORE_CPU 0x4
+#define RENDER_GPU 0x4
+#define IGNORE_CPU 0x8
struct kgem_bo *
sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box,
struct sna_damage ***damage);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e592b10..f530603 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2570,6 +2570,14 @@ use_cpu_bo:
if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo))
goto move_to_gpu;
+ if (flags & RENDER_GPU) {
+ if (priv->gpu_bo && priv->gpu_bo->tiling)
+ goto move_to_gpu;
+
+ if (priv->cpu_bo->pitch >= 4096)
+ goto move_to_gpu;
+ }
+
if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, ®ion,
MOVE_READ | MOVE_ASYNC_HINT)) {
DBG(("%s: failed to move-to-cpu, fallback\n", __FUNCTION__));
commit 3ca1bfb51ba522454433d58131e7dab7fcbe7e34
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Aug 20 21:28:47 2012 +0100
sna: Trim a parameter from kgem_bo_mark_dirty() and add some assertions
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index fea1791..9e51cb7 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -547,7 +547,7 @@ static void gen2_emit_target(struct sna *sna, const struct sna_composite_op *op)
assert(sna->render_state.gen2.vertex_offset == 0);
if (sna->render_state.gen2.target == op->dst.bo->unique_id) {
- kgem_bo_mark_dirty(&sna->kgem, op->dst.bo);
+ kgem_bo_mark_dirty(op->dst.bo);
return;
}
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 72a2575..81d2c95 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -1342,6 +1342,7 @@ static void gen3_emit_target(struct sna *sna,
struct gen3_render_state *state = &sna->render_state.gen3;
/* BUF_INFO is an implicit flush, so skip if the target is unchanged. */
+ assert(bo->unique_id != 0);
if (bo->unique_id != state->current_dst) {
uint32_t v;
@@ -1373,7 +1374,7 @@ static void gen3_emit_target(struct sna *sna,
state->current_dst = bo->unique_id;
}
- kgem_bo_mark_dirty(&sna->kgem, bo);
+ kgem_bo_mark_dirty(bo);
}
static void gen3_emit_composite_state(struct sna *sna,
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index d72a2fd..632793f 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -654,15 +654,12 @@ gen4_bind_bo(struct sna *sna,
assert(!kgem_bo_is_snoop(bo));
/* After the first bind, we manage the cache domains within the batch */
- if (is_dst) {
- domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
- kgem_bo_mark_dirty(&sna->kgem, bo);
- } else
- domains = I915_GEM_DOMAIN_SAMPLER << 16;
-
offset = kgem_bo_get_binding(bo, format);
- if (offset)
+ if (offset) {
+ if (is_dst)
+ kgem_bo_mark_dirty(bo);
return offset * sizeof(uint32_t);
+ }
offset = sna->kgem.surface -=
sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
@@ -671,6 +668,11 @@ gen4_bind_bo(struct sna *sna,
ss->ss0.surface_type = GEN4_SURFACE_2D;
ss->ss0.surface_format = format;
+ if (is_dst)
+ domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
+ else
+ domains = I915_GEM_DOMAIN_SAMPLER << 16;
+
ss->ss0.data_return_format = GEN4_SURFACERETURNFORMAT_FLOAT32;
ss->ss0.color_blend = 1;
ss->ss1.base_addr =
@@ -1385,7 +1387,7 @@ gen4_emit_state(struct sna *sna,
kgem_bo_is_dirty(op->mask.bo)));
OUT_BATCH(MI_FLUSH);
kgem_clear_dirty(&sna->kgem);
- kgem_bo_mark_dirty(&sna->kgem, op->dst.bo);
+ kgem_bo_mark_dirty(op->dst.bo);
}
}
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 9b976c8..2894c58 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -639,16 +639,13 @@ gen5_bind_bo(struct sna *sna,
uint32_t *ss;
/* After the first bind, we manage the cache domains within the batch */
- if (is_dst) {
- domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
- kgem_bo_mark_dirty(&sna->kgem, bo);
- } else
- domains = I915_GEM_DOMAIN_SAMPLER << 16;
-
if (!DBG_NO_SURFACE_CACHE) {
offset = kgem_bo_get_binding(bo, format);
- if (offset)
+ if (offset) {
+ if (is_dst)
+ kgem_bo_mark_dirty(bo);
return offset * sizeof(uint32_t);
+ }
}
offset = sna->kgem.surface -=
@@ -659,6 +656,10 @@ gen5_bind_bo(struct sna *sna,
GEN5_SURFACE_BLEND_ENABLED |
format << GEN5_SURFACE_FORMAT_SHIFT);
+ if (is_dst)
+ domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
+ else
+ domains = I915_GEM_DOMAIN_SAMPLER << 16;
ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
ss[2] = ((width - 1) << GEN5_SURFACE_WIDTH_SHIFT |
@@ -1387,7 +1388,7 @@ gen5_emit_state(struct sna *sna,
if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
OUT_BATCH(MI_FLUSH);
kgem_clear_dirty(&sna->kgem);
- kgem_bo_mark_dirty(&sna->kgem, op->dst.bo);
+ kgem_bo_mark_dirty(op->dst.bo);
}
}
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 710a35e..af8899e 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -903,7 +903,7 @@ gen6_emit_state(struct sna *sna,
if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
gen6_emit_flush(sna);
kgem_clear_dirty(&sna->kgem);
- kgem_bo_mark_dirty(&sna->kgem, op->dst.bo);
+ kgem_bo_mark_dirty(op->dst.bo);
need_stall = false;
}
if (need_stall) {
@@ -1230,17 +1230,13 @@ gen6_bind_bo(struct sna *sna,
uint16_t offset;
/* After the first bind, we manage the cache domains within the batch */
- if (is_dst) {
- domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
- kgem_bo_mark_dirty(&sna->kgem, bo);
- } else
- domains = I915_GEM_DOMAIN_SAMPLER << 16;
-
offset = kgem_bo_get_binding(bo, format);
if (offset) {
DBG(("[%x] bo(handle=%d), format=%d, reuse %s binding\n",
offset, bo->handle, format,
domains & 0xffff ? "render" : "sampler"));
+ if (is_dst)
+ kgem_bo_mark_dirty(bo);
return offset * sizeof(uint32_t);
}
@@ -1250,6 +1246,10 @@ gen6_bind_bo(struct sna *sna,
ss[0] = (GEN6_SURFACE_2D << GEN6_SURFACE_TYPE_SHIFT |
GEN6_SURFACE_BLEND_ENABLED |
format << GEN6_SURFACE_FORMAT_SHIFT);
+ if (is_dst)
+ domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
+ else
+ domains = I915_GEM_DOMAIN_SAMPLER << 16;
ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
ss[2] = ((width - 1) << GEN6_SURFACE_WIDTH_SHIFT |
(height - 1) << GEN6_SURFACE_HEIGHT_SHIFT);
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 8a281e5..d34cdfa 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -1047,7 +1047,7 @@ gen7_emit_state(struct sna *sna,
need_stall = GEN7_BLEND(op->u.gen7.flags) != NO_BLEND;
gen7_emit_pipe_invalidate(sna, need_stall);
kgem_clear_dirty(&sna->kgem);
- kgem_bo_mark_dirty(&sna->kgem, op->dst.bo);
+ kgem_bo_mark_dirty(op->dst.bo);
need_stall = false;
}
if (need_stall)
@@ -1348,15 +1348,12 @@ gen7_bind_bo(struct sna *sna,
COMPILE_TIME_ASSERT(sizeof(struct gen7_surface_state) == 32);
/* After the first bind, we manage the cache domains within the batch */
- if (is_dst) {
- domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
- kgem_bo_mark_dirty(&sna->kgem, bo);
- } else
- domains = I915_GEM_DOMAIN_SAMPLER << 16;
-
offset = kgem_bo_get_binding(bo, format);
- if (offset)
+ if (offset) {
+ if (is_dst)
+ kgem_bo_mark_dirty(bo);
return offset * sizeof(uint32_t);
+ }
offset = sna->kgem.surface -=
sizeof(struct gen7_surface_state) / sizeof(uint32_t);
@@ -1364,6 +1361,10 @@ gen7_bind_bo(struct sna *sna,
ss[0] = (GEN7_SURFACE_2D << GEN7_SURFACE_TYPE_SHIFT |
gen7_tiling_bits(bo->tiling) |
format << GEN7_SURFACE_FORMAT_SHIFT);
+ if (is_dst)
+ domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
+ else
+ domains = I915_GEM_DOMAIN_SAMPLER << 16;
ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
ss[2] = ((width - 1) << GEN7_SURFACE_WIDTH_SHIFT |
(height - 1) << GEN7_SURFACE_HEIGHT_SHIFT);
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 11cd6a4..c5b88ff 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1811,6 +1811,8 @@ static void kgem_commit(struct kgem *kgem)
}
kgem_retire(kgem);
+ assert(list_is_empty(&rq->buffers));
+
gem_close(kgem->fd, rq->bo->handle);
} else {
list_add_tail(&rq->list, &kgem->requests);
@@ -3551,6 +3553,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
if (bo->exec == NULL)
_kgem_add_bo(kgem, bo);
+ assert(bo->rq == kgem->next_request);
if (kgem->gen < 40 && read_write_domain & KGEM_RELOC_FENCED) {
if (bo->tiling &&
@@ -3568,7 +3571,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
kgem->reloc[index].presumed_offset = bo->presumed_offset;
if (read_write_domain & 0x7ff)
- kgem_bo_mark_dirty(kgem, bo);
+ kgem_bo_mark_dirty(bo);
delta += bo->presumed_offset;
} else {
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 8227538..cf7cf70 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -534,15 +534,17 @@ static inline bool kgem_bo_is_dirty(struct kgem_bo *bo)
return bo->dirty;
}
-static inline void kgem_bo_mark_dirty(struct kgem *kgem, struct kgem_bo *bo)
+static inline void kgem_bo_mark_dirty(struct kgem_bo *bo)
{
if (bo->dirty)
return;
DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
+ assert(bo->exec);
+ assert(bo->rq);
bo->needs_flush = bo->dirty = true;
- list_move(&bo->request, &kgem->next_request->buffers);
+ list_move(&bo->request, &bo->rq->buffers);
}
#define KGEM_BUFFER_WRITE 0x1
commit 16f3d3a9ae145a3af51d2c0c42c6c585d676a863
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Aug 20 19:42:22 2012 +0100
sna: Keep a stash of the most recently allocated requests
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 5441eed..11cd6a4 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -125,6 +125,7 @@ struct kgem_buffer {
};
static struct kgem_bo *__kgem_freed_bo;
+static struct kgem_request *__kgem_freed_request;
static struct drm_i915_gem_exec_object2 _kgem_dummy_exec;
static inline int bytes(struct kgem_bo *bo)
@@ -538,15 +539,28 @@ static struct kgem_request *__kgem_request_alloc(void)
{
struct kgem_request *rq;
- rq = malloc(sizeof(*rq));
- if (rq == NULL)
- rq = &_kgem_static_request;
+ rq = __kgem_freed_request;
+ if (rq) {
+ __kgem_freed_request = *(struct kgem_request **)rq;
+ } else {
+ rq = malloc(sizeof(*rq));
+ if (rq == NULL)
+ rq = &_kgem_static_request;
+ }
list_init(&rq->buffers);
+ rq->bo = NULL;
return rq;
}
+static void __kgem_request_free(struct kgem_request *rq)
+{
+ _list_del(&rq->list);
+ *(struct kgem_request **)rq = __kgem_freed_request;
+ __kgem_freed_request = rq;
+}
+
static struct list *inactive(struct kgem *kgem, int num_pages)
{
return &kgem->inactive[cache_bucket(num_pages)];
@@ -1699,8 +1713,7 @@ static bool kgem_retire__requests(struct kgem *kgem)
}
}
- _list_del(&rq->list);
- free(rq);
+ __kgem_request_free(rq);
}
#if HAS_DEBUG_FULL
@@ -1963,8 +1976,7 @@ static void kgem_cleanup(struct kgem *kgem)
kgem_bo_free(kgem, bo);
}
- _list_del(&rq->list);
- free(rq);
+ __kgem_request_free(rq);
}
kgem_close_inactive(kgem);
@@ -2303,6 +2315,11 @@ bool kgem_expire_cache(struct kgem *kgem)
free(bo);
}
+ while (__kgem_freed_request) {
+ struct kgem_request *rq = __kgem_freed_request;
+ __kgem_freed_request = *(struct kgem_request **)rq;
+ free(rq);
+ }
expire = 0;
list_for_each_entry(bo, &kgem->snoop, list) {
commit fb349ced91e15ecaa025321bd37d1fe3cfdd2f44
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Aug 20 17:35:44 2012 +0100
sna: A few more buffer cache management assertions
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 3cb9eb6..5441eed 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1333,6 +1333,9 @@ static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
static void kgem_bo_move_to_snoop(struct kgem *kgem, struct kgem_bo *bo)
{
+ assert(bo->refcnt == 0);
+ assert(bo->exec == NULL);
+
if (num_pages(bo) > kgem->max_cpu_size >> 13) {
DBG(("%s handle=%d discarding large CPU buffer (%d >%d pages)\n",
__FUNCTION__, bo->handle, num_pages(bo), kgem->max_cpu_size >> 13));
@@ -1953,7 +1956,9 @@ static void kgem_cleanup(struct kgem *kgem)
list_del(&bo->request);
bo->rq = NULL;
+ bo->exec = NULL;
bo->domain = DOMAIN_NONE;
+ bo->dirty = false;
if (bo->refcnt == 0)
kgem_bo_free(kgem, bo);
}
More information about the xorg-commit
mailing list