xf86-video-intel: 3 commits - src/i965_render.c src/intel.h src/intel_uxa.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

Chris Wilson ickle at kemper.freedesktop.org
Thu Nov 3 13:47:40 PDT 2011


 src/i965_render.c     |   31 ------------
 src/intel.h           |    1 
 src/intel_uxa.c       |    1 
 src/sna/gen4_render.c |   38 ++-------------
 src/sna/gen5_render.c |   38 +++------------
 src/sna/gen6_render.c |   40 ++++------------
 src/sna/gen7_render.c |   38 ++-------------
 src/sna/kgem.c        |  125 ++++++++++++++++++++++++++++++--------------------
 src/sna/kgem.h        |   10 +++-
 src/sna/sna_accel.c   |   45 ++++++------------
 10 files changed, 131 insertions(+), 236 deletions(-)

New commits:
commit 2174f840158aa9cfa370ade38be28f8dc8e4b526
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 3 20:41:31 2011 +0000

    uxa: Remove caching of surface binding location
    
    If the pixmap were to be used multiple times within a batch with
    mulitple formats, the cache would only return the initial location with
    the incorrect format and so cause rendering glitches. For instance, GTK+
    uses the same pixmap as an xrgb source and as an argb mask in order to
    premultiply and composite in a single pass. Rather than introduce an
    overly complication caching (handle, format) mechanism, kiss and remove
    the invalid implementation.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=40926
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/i965_render.c b/src/i965_render.c
index 825fc13..8907139 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1292,14 +1292,6 @@ gen4_set_picture_surface_state(intel_screen_private *intel,
 	}
 	intel_batch_mark_pixmap_domains(intel, priv,
 					read_domains, write_domain);
-	if (is_dst) {
-		if (priv->dst_bound)
-			return priv->dst_bound;
-	} else {
-		if (priv->src_bound)
-			return priv->src_bound;
-	}
-
 	ss = (struct brw_surface_state *)
 		(intel->surface_data + intel->surface_used);
 
@@ -1330,11 +1322,6 @@ gen4_set_picture_surface_state(intel_screen_private *intel,
 	offset = intel->surface_used;
 	intel->surface_used += SURFACE_STATE_PADDED_SIZE;
 
-	if (is_dst)
-		priv->dst_bound = offset;
-	else
-		priv->src_bound = offset;
-
 	return offset;
 }
 
@@ -1357,14 +1344,6 @@ gen7_set_picture_surface_state(intel_screen_private *intel,
 	}
 	intel_batch_mark_pixmap_domains(intel, priv,
 					read_domains, write_domain);
-	if (is_dst) {
-		if (priv->dst_bound)
-			return priv->dst_bound;
-	} else {
-		if (priv->src_bound)
-			return priv->src_bound;
-	}
-
 	ss = (struct gen7_surface_state *)
 		(intel->surface_data + intel->surface_used);
 
@@ -1393,11 +1372,6 @@ gen7_set_picture_surface_state(intel_screen_private *intel,
 	offset = intel->surface_used;
 	intel->surface_used += SURFACE_STATE_PADDED_SIZE;
 
-	if (is_dst)
-		priv->dst_bound = offset;
-	else
-		priv->src_bound = offset;
-
 	return offset;
 }
 
@@ -1750,8 +1724,6 @@ static Bool i965_composite_check_aperture(intel_screen_private *intel)
 
 static void i965_surface_flush(struct intel_screen_private *intel)
 {
-	struct intel_pixmap *priv;
-
 	drm_intel_bo_subdata(intel->surface_bo,
 			     0, intel->surface_used,
 			     intel->surface_data);
@@ -1768,9 +1740,6 @@ static void i965_surface_flush(struct intel_screen_private *intel)
 	intel->surface_bo =
 		drm_intel_bo_alloc(intel->bufmgr, "surface data",
 				   sizeof(intel->surface_data), 4096);
-
-	list_foreach_entry(priv, struct intel_pixmap, &intel->batch_pixmaps, batch)
-		priv->dst_bound = priv->src_bound = 0;
 }
 
 static void
diff --git a/src/intel.h b/src/intel.h
index 4acd0f2..3b3f87d 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -176,7 +176,6 @@ struct intel_pixmap {
 
 	struct list flush, batch, in_flight;
 
-	uint16_t src_bound, dst_bound;
 	uint16_t stride;
 	uint8_t tiling;
 	int8_t busy :2;
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index 9e58c69..8c6f754 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -636,7 +636,6 @@ void intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
 		if (priv->bo == bo)
 			return;
 
-		priv->dst_bound = priv->src_bound = 0;
 		if (list_is_empty(&priv->batch)) {
 			dri_bo_unreference(priv->bo);
 		} else if (!drm_intel_bo_is_reusable(priv->bo)) {
commit a1b40a20bbba4b70990a8983a2916d3d5850d828
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 3 19:27:23 2011 +0000

    sna: Support binding of a bo for multiple formats
    
    Applications may use the same pixmap with multiple formats within the
    same operation. For instance, you can premultiply and composite a normal
    pixmap in this manner.  However, as we reused the sampler binding
    locations of the source (without an alpha channel) for the mask, we
    failed to read and multiply by the alpha channel causing it to remain
    black instead of transparent.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=40926
    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 8f59dc1..3c26994 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -496,22 +496,6 @@ static Bool gen4_check_dst_format(PictFormat format)
 	return FALSE;
 }
 
-static bool gen4_format_is_dst(uint32_t format)
-{
-	switch (format) {
-	case GEN4_SURFACEFORMAT_B8G8R8A8_UNORM:
-	case GEN4_SURFACEFORMAT_R8G8B8A8_UNORM:
-	case GEN4_SURFACEFORMAT_B10G10R10A2_UNORM:
-	case GEN4_SURFACEFORMAT_B5G6R5_UNORM:
-	case GEN4_SURFACEFORMAT_B5G5R5A1_UNORM:
-	case GEN4_SURFACEFORMAT_A8_UNORM:
-	case GEN4_SURFACEFORMAT_B4G4R4A4_UNORM:
-		return true;
-	default:
-		return false;
-	}
-}
-
 typedef struct gen4_surface_state_padded {
 	struct gen4_surface_state state;
 	char pad[32 - sizeof(struct gen4_surface_state)];
@@ -657,26 +641,16 @@ gen4_bind_bo(struct sna *sna,
 	if (is_dst) {
 		domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
 		kgem_bo_mark_dirty(bo);
-	} else {
+	} else
 		domains = I915_GEM_DOMAIN_SAMPLER << 16;
-		is_dst = gen4_format_is_dst(format);
-	}
+
+	offset = kgem_bo_get_binding(bo, format);
+	if (offset)
+		return offset;
 
 	offset = sna->kgem.surface - sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
 	offset *= sizeof(uint32_t);
 
-	if (is_dst) {
-		if (bo->dst_bound)
-			return bo->dst_bound;
-
-		bo->dst_bound = offset;
-	} else {
-		if (bo->src_bound)
-			return bo->src_bound;
-
-		bo->src_bound = offset;
-	}
-
 	sna->kgem.surface -=
 		sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
 	ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss));
@@ -697,6 +671,8 @@ gen4_bind_bo(struct sna *sna,
 	ss->ss3.tiled_surface = bo->tiling != I915_TILING_NONE;
 	ss->ss3.tile_walk     = bo->tiling == I915_TILING_Y;
 
+	kgem_bo_set_binding(bo, format, offset);
+
 	DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n",
 	     offset, bo->handle, ss->ss1.base_addr,
 	     ss->ss0.surface_format, width, height, bo->pitch, bo->tiling,
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index c48e828..7839d8e 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -505,22 +505,6 @@ static uint32_t gen5_get_card_format_for_depth(int depth)
 	}
 }
 
-static bool gen5_format_is_dst(uint32_t format)
-{
-	switch (format) {
-	case GEN5_SURFACEFORMAT_B8G8R8A8_UNORM:
-	case GEN5_SURFACEFORMAT_R8G8B8A8_UNORM:
-	case GEN5_SURFACEFORMAT_B10G10R10A2_UNORM:
-	case GEN5_SURFACEFORMAT_B5G6R5_UNORM:
-	case GEN5_SURFACEFORMAT_B5G5R5A1_UNORM:
-	case GEN5_SURFACEFORMAT_A8_UNORM:
-	case GEN5_SURFACEFORMAT_B4G4R4A4_UNORM:
-		return true;
-	default:
-		return false;
-	}
-}
-
 typedef struct gen5_surface_state_padded {
 	struct gen5_surface_state state;
 	char pad[32 - sizeof(struct gen5_surface_state)];
@@ -677,26 +661,18 @@ gen5_bind_bo(struct sna *sna,
 	if (is_dst) {
 		domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
 		kgem_bo_mark_dirty(bo);
-	} else {
+	} else
 		domains = I915_GEM_DOMAIN_SAMPLER << 16;
-		is_dst = gen5_format_is_dst(format);
+
+	if (!DBG_NO_SURFACE_CACHE) {
+		offset = kgem_bo_get_binding(bo, format);
+		if (offset)
+			return offset;
 	}
 
 	offset = sna->kgem.surface - sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t);
 	offset *= sizeof(uint32_t);
 
-	if (is_dst) {
-		if (!DBG_NO_SURFACE_CACHE && bo->dst_bound)
-			return bo->dst_bound;
-
-		bo->dst_bound = offset;
-	} else {
-		if (!DBG_NO_SURFACE_CACHE && bo->src_bound)
-			return bo->src_bound;
-
-		bo->src_bound = offset;
-	}
-
 	sna->kgem.surface -=
 		sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t);
 	ss = sna->kgem.batch + sna->kgem.surface;
@@ -716,6 +692,8 @@ gen5_bind_bo(struct sna *sna,
 	ss[4] = 0;
 	ss[5] = 0;
 
+	kgem_bo_set_binding(bo, format, offset);
+
 	DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n",
 	     offset, bo->handle, ss[1],
 	     format, width, height, bo->pitch, bo->tiling,
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 51d26c8..02b051f 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -330,22 +330,6 @@ static uint32_t gen6_get_card_format_for_depth(int depth)
 	}
 }
 
-static bool gen6_format_is_dst(uint32_t format)
-{
-	switch (format) {
-	case GEN6_SURFACEFORMAT_B8G8R8A8_UNORM:
-	case GEN6_SURFACEFORMAT_R8G8B8A8_UNORM:
-	case GEN6_SURFACEFORMAT_B10G10R10A2_UNORM:
-	case GEN6_SURFACEFORMAT_B5G6R5_UNORM:
-	case GEN6_SURFACEFORMAT_B5G5R5A1_UNORM:
-	case GEN6_SURFACEFORMAT_A8_UNORM:
-	case GEN6_SURFACEFORMAT_B4G4R4A4_UNORM:
-		return true;
-	default:
-		return false;
-	}
-}
-
 static uint32_t gen6_filter(uint32_t filter)
 {
 	switch (filter) {
@@ -1073,26 +1057,20 @@ gen6_bind_bo(struct sna *sna,
 	if (is_dst) {
 		domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
 		kgem_bo_mark_dirty(bo);
-	} else {
+	} else
 		domains = I915_GEM_DOMAIN_SAMPLER << 16;
-		is_dst = gen6_format_is_dst(format);
+
+	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"));
+		return offset;
 	}
 
 	offset = sna->kgem.surface - sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
 	offset *= sizeof(uint32_t);
 
-	if (is_dst) {
-		if (bo->dst_bound)
-			return bo->dst_bound;
-
-		bo->dst_bound = offset;
-	} else {
-		if (bo->src_bound)
-			return bo->src_bound;
-
-		bo->src_bound = offset;
-	}
-
 	sna->kgem.surface -=
 		sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
 	ss = sna->kgem.batch + sna->kgem.surface;
@@ -1109,6 +1087,8 @@ gen6_bind_bo(struct sna *sna,
 	ss[4] = 0;
 	ss[5] = 0;
 
+	kgem_bo_set_binding(bo, format, offset);
+
 	DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n",
 	     offset, bo->handle, ss[1],
 	     format, width, height, bo->pitch, bo->tiling,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 3be87b7..ba6e9d5 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -342,22 +342,6 @@ static uint32_t gen7_get_card_format_for_depth(int depth)
 	}
 }
 
-static bool gen7_format_is_dst(uint32_t format)
-{
-	switch (format) {
-	case GEN7_SURFACEFORMAT_B8G8R8A8_UNORM:
-	case GEN7_SURFACEFORMAT_R8G8B8A8_UNORM:
-	case GEN7_SURFACEFORMAT_B10G10R10A2_UNORM:
-	case GEN7_SURFACEFORMAT_B5G6R5_UNORM:
-	case GEN7_SURFACEFORMAT_B5G5R5A1_UNORM:
-	case GEN7_SURFACEFORMAT_A8_UNORM:
-	case GEN7_SURFACEFORMAT_B4G4R4A4_UNORM:
-		return true;
-	default:
-		return false;
-	}
-}
-
 static uint32_t gen7_filter(uint32_t filter)
 {
 	switch (filter) {
@@ -1208,26 +1192,16 @@ gen7_bind_bo(struct sna *sna,
 	if (is_dst) {
 		domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
 		kgem_bo_mark_dirty(bo);
-	} else {
+	} else
 		domains = I915_GEM_DOMAIN_SAMPLER << 16;
-		is_dst = gen7_format_is_dst(format);
-	}
+
+	offset = kgem_bo_get_binding(bo, format);
+	if (offset)
+		return offset;
 
 	offset = sna->kgem.surface - sizeof(struct gen7_surface_state_padded) / sizeof(uint32_t);
 	offset *= sizeof(uint32_t);
 
-	if (is_dst) {
-		if (bo->dst_bound)
-			return bo->dst_bound;
-
-		bo->dst_bound = offset;
-	} else {
-		if (bo->src_bound)
-			return bo->src_bound;
-
-		bo->src_bound = offset;
-	}
-
 	sna->kgem.surface -=
 		sizeof(struct gen7_surface_state_padded) / sizeof(uint32_t);
 	ss = sna->kgem.batch + sna->kgem.surface;
@@ -1245,6 +1219,8 @@ gen7_bind_bo(struct sna *sna,
 	ss[6] = 0;
 	ss[7] = 0;
 
+	kgem_bo_set_binding(bo, format, offset);
+
 	DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n",
 	     offset, bo->handle, ss[1],
 	     format, width, height, bo->pitch, bo->tiling,
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 37e6035..046df15 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -537,12 +537,29 @@ static void kgem_fixup_self_relocs(struct kgem *kgem, struct kgem_bo *bo)
 	}
 }
 
+static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
+{
+	struct kgem_bo_binding *b;
+
+	b = bo->binding.next;
+	while (b) {
+		struct kgem_bo_binding *next = b->next;
+		free (b);
+		b = next;
+	}
+
+	list_del(&bo->list);
+	list_del(&bo->request);
+	gem_close(kgem->fd, bo->handle);
+	free(bo);
+}
+
 static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 {
 	assert(list_is_empty(&bo->list));
 	assert(bo->refcnt == 0);
 
-	bo->src_bound = bo->dst_bound = 0;
+	bo->binding.offset = 0;
 
 	if (NO_CACHE)
 		goto destroy;
@@ -573,11 +590,8 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 	return;
 
 destroy:
-	if (!bo->exec) {
-		list_del(&bo->request);
-		gem_close(kgem->fd, bo->handle);
-		free(bo);
-	}
+	if (!bo->exec)
+		kgem_bo_free(kgem, bo);
 }
 
 static void kgem_bo_unref(struct kgem *kgem, struct kgem_bo *bo)
@@ -647,8 +661,7 @@ bool kgem_retire(struct kgem *kgem)
 				} else {
 					DBG(("%s: closing %d\n",
 					     __FUNCTION__, bo->handle));
-					gem_close(kgem->fd, bo->handle);
-					free(bo);
+					kgem_bo_free(kgem, bo);
 				}
 			}
 		}
@@ -684,8 +697,8 @@ static void kgem_commit(struct kgem *kgem)
 	struct kgem_bo *bo, *next;
 
 	list_for_each_entry_safe(bo, next, &rq->buffers, request) {
-		bo->src_bound = bo->dst_bound = 0;
 		bo->presumed_offset = bo->exec->offset;
+		bo->binding.offset = 0;
 		bo->exec = NULL;
 		bo->dirty = false;
 		bo->cpu_read = false;
@@ -693,11 +706,7 @@ static void kgem_commit(struct kgem *kgem)
 
 		if (!bo->refcnt) {
 			if (!bo->reusable) {
-destroy:
-				list_del(&bo->list);
-				list_del(&bo->request);
-				gem_close(kgem->fd, bo->handle);
-				free(bo);
+destroy:			kgem_bo_free(kgem, bo);
 				continue;
 			}
 			if (!bo->deleted) {
@@ -718,15 +727,8 @@ destroy:
 
 static void kgem_close_list(struct kgem *kgem, struct list *head)
 {
-	while (!list_is_empty(head)) {
-		struct kgem_bo *bo;
-
-		bo = list_first_entry(head, struct kgem_bo, list);
-		gem_close(kgem->fd, bo->handle);
-		list_del(&bo->list);
-		list_del(&bo->request);
-		free(bo);
-	}
+	while (!list_is_empty(head))
+		kgem_bo_free(kgem, list_first_entry(head, struct kgem_bo, list));
 }
 
 static void kgem_close_inactive(struct kgem *kgem)
@@ -747,9 +749,7 @@ static void kgem_finish_partials(struct kgem *kgem)
 				DBG(("%s: discarding unused partial array: %d/%d\n",
 				     __FUNCTION__, bo->used, bo->alloc));
 
-				list_del(&bo->base.list);
-				gem_close(kgem->fd, bo->base.handle);
-				free(bo);
+				kgem_bo_free(kgem, &bo->base);
 			}
 
 			continue;
@@ -808,11 +808,8 @@ static void kgem_cleanup(struct kgem *kgem)
 			list_del(&bo->request);
 			bo->rq = NULL;
 			bo->gpu = false;
-			if (bo->refcnt == 0) {
-				list_del(&bo->list);
-				gem_close(kgem->fd, bo->handle);
-				free(bo);
-			}
+			if (bo->refcnt == 0)
+				kgem_bo_free(kgem, bo);
 		}
 
 		list_del(&rq->list);
@@ -861,7 +858,7 @@ void kgem_reset(struct kgem *kgem)
 	while (!list_is_empty(&rq->buffers)) {
 		bo = list_first_entry(&rq->buffers, struct kgem_bo, request);
 
-		bo->src_bound = bo->dst_bound = 0;
+		bo->binding.offset = 0;
 		bo->exec = NULL;
 		bo->dirty = false;
 		bo->cpu_read = false;
@@ -1137,9 +1134,7 @@ bool kgem_expire_cache(struct kgem *kgem)
 			count++;
 			size += bo->size;
 
-			gem_close(kgem->fd, bo->handle);
-			list_del(&bo->list);
-			free(bo);
+			kgem_bo_free(kgem, bo);
 		}
 	}
 
@@ -1155,7 +1150,6 @@ bool kgem_expire_cache(struct kgem *kgem)
 
 void kgem_cleanup_cache(struct kgem *kgem)
 {
-	struct kgem_bo *bo;
 	unsigned int i;
 
 	/* sync to the most recent request */
@@ -1178,14 +1172,10 @@ void kgem_cleanup_cache(struct kgem *kgem)
 	kgem_expire_partial(kgem);
 
 	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
-		while (!list_is_empty(&kgem->inactive[i])) {
-			bo = list_last_entry(&kgem->inactive[i],
-					     struct kgem_bo, list);
-
-			gem_close(kgem->fd, bo->handle);
-			list_del(&bo->list);
-			free(bo);
-		}
+		while (!list_is_empty(&kgem->inactive[i]))
+			kgem_bo_free(kgem,
+				     list_last_entry(&kgem->inactive[i],
+						     struct kgem_bo, list));
 	}
 
 	kgem->need_purge = false;
@@ -1482,9 +1472,7 @@ search_active: /* Best active match first */
 				if (!gem_madvise(kgem->fd, bo->handle,
 						 I915_MADV_WILLNEED)) {
 					kgem->need_purge |= bo->gpu;
-					gem_close(kgem->fd, bo->handle);
-					list_del(&bo->request);
-					free(bo);
+					kgem_bo_free(kgem, bo);
 					bo = NULL;
 					goto search_active;
 				}
@@ -1549,9 +1537,7 @@ skip_active_search:
 		return kgem_bo_reference(bo);
 
 next_bo:
-		gem_close(kgem->fd, bo->handle);
-		list_del(&bo->request);
-		free(bo);
+		kgem_bo_free(kgem, bo);
 		continue;
 	}
 
@@ -1588,6 +1574,8 @@ void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 {
 	if (bo->proxy) {
 		kgem_bo_unref(kgem, bo->proxy);
+
+		assert(bo->binding.next == NULL);
 		list_del(&bo->request);
 		free(bo);
 		return;
@@ -2185,3 +2173,40 @@ void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
 	} else
 		kgem_bo_sync(kgem, &bo->base, false);
 }
+
+uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format)
+{
+	struct kgem_bo_binding *b;
+
+	for (b = &bo->binding; b && b->offset; b = b->next)
+		if (format == b->format)
+			return b->offset;
+
+	return 0;
+}
+
+void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset)
+{
+	struct kgem_bo_binding *b;
+
+	for (b = &bo->binding; b; b = b->next) {
+		if (b->offset)
+			continue;
+
+		b->offset = offset;
+		b->format = format;
+
+		if (b->next)
+			b->next->offset = 0;
+
+		return;
+	}
+
+	b = malloc(sizeof(*b));
+	if (b) {
+		b->next = bo->binding.next;
+		b->format = format;
+		b->offset = offset;
+		bo->binding.next = b;
+	}
+}
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 4b260e2..a2258e1 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -51,7 +51,12 @@ struct kgem_bo {
 	struct kgem_request *rq;
 	struct drm_i915_gem_exec_object2 *exec;
 
-	uint16_t src_bound, dst_bound;
+	struct kgem_bo_binding {
+		struct kgem_bo_binding *next;
+		uint32_t format;
+		uint16_t offset;
+	} binding;
+
 	uint32_t unique_id;
 	uint32_t refcnt;
 	uint32_t handle;
@@ -172,6 +177,9 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			       int tiling,
 			       uint32_t flags);
 
+uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format);
+void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset);
+
 bool kgem_retire(struct kgem *kgem);
 
 void _kgem_submit(struct kgem *kgem);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 555cbc6..e0bf47b 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -6820,7 +6820,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 	uint8_t rop = transparent ? copy_ROP[gc->alu] : ROP_S;
 
 	DBG(("%s (%d, %d) x %d, transparent? %d, alu=%d\n",
-	     __FUNCTION__, _x, _y, _n, transparent, alu));
+	     __FUNCTION__, _x, _y, _n, transparent, rop));
 
 	if (!sna_drawable_use_gpu_bo(drawable, &clip->extents, &damage))
 		return false;
commit 31c5eb8e906bf8e59743372edb2d703b50cd311e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 3 17:07:48 2011 +0000

    sna: Clean up the fallback code for glyphs
    
    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 a2e9dc2..555cbc6 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -7548,19 +7548,19 @@ sna_image_glyph(DrawablePtr drawable, GCPtr gc,
 	     region.extents.x1, region.extents.y1,
 	     region.extents.x2, region.extents.y2));
 
+	region.data = NULL;
+	region_maybe_clip(&region, gc->pCompositeClip);
+	if (!RegionNotEmpty(&region))
+		return;
+
 	if (FORCE_FALLBACK)
-		goto fallback_clip;
+		goto fallback;
 
 	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
-		goto fallback_clip;
+		goto fallback;
 	}
 
-	region.data = NULL;
-	region_maybe_clip(&region, gc->pCompositeClip);
-	if (!RegionNotEmpty(&region))
-		return;
-
 	if (sna_drawable_use_gpu_bo(drawable, &region.extents, &damage) &&
 	    sna_reversed_glyph_blt(drawable, gc, x, y, n, info, base,
 				   damage, &region, false)) {
@@ -7577,14 +7577,6 @@ fallback:
 	DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
 	fbImageGlyphBlt(drawable, gc, x, y, n, info, base);
 	return;
-
-fallback_clip:
-	region.data = NULL;
-	region_maybe_clip(&region, gc->pCompositeClip);
-	if (!RegionNotEmpty(&region))
-		return;
-
-	goto fallback;
 }
 
 static void
@@ -7615,19 +7607,19 @@ sna_poly_glyph(DrawablePtr drawable, GCPtr gc,
 	     region.extents.x1, region.extents.y1,
 	     region.extents.x2, region.extents.y2));
 
+	region.data = NULL;
+	region_maybe_clip(&region, gc->pCompositeClip);
+	if (!RegionNotEmpty(&region))
+		return;
+
 	if (FORCE_FALLBACK)
-		goto fallback_clip;
+		goto fallback;
 
 	if (wedged(sna)) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
-		goto fallback_clip;
+		goto fallback;
 	}
 
-	region.data = NULL;
-	region_maybe_clip(&region, gc->pCompositeClip);
-	if (!RegionNotEmpty(&region))
-		return;
-
 	if (sna_drawable_use_gpu_bo(drawable, &region.extents, &damage) &&
 	    sna_reversed_glyph_blt(drawable, gc, x, y, n, info, base,
 				   damage, &region, true)) {
@@ -7644,13 +7636,6 @@ fallback:
 	DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
 	fbPolyGlyphBlt(drawable, gc, x, y, n, info, base);
 
-fallback_clip:
-	region.data = NULL;
-	region_maybe_clip(&region, gc->pCompositeClip);
-	if (!RegionNotEmpty(&region))
-		return;
-	goto fallback;
-
 }
 
 static bool


More information about the xorg-commit mailing list