xf86-video-intel: 5 commits - src/sna/compiler.h src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_damage.c src/sna/sna.h src/sna/sna_io.c
Chris Wilson
ickle at kemper.freedesktop.org
Sat Dec 24 14:13:39 PST 2011
src/sna/compiler.h | 2 +
src/sna/kgem.c | 2 -
src/sna/kgem.h | 15 +++++++++++++
src/sna/sna.h | 10 ++++----
src/sna/sna_accel.c | 58 ++++++++++++++++++++++++++++++++++++++++++---------
src/sna/sna_damage.c | 4 ++-
src/sna/sna_io.c | 28 +++++++++++++++++++-----
7 files changed, 96 insertions(+), 23 deletions(-)
New commits:
commit b117f65520919f4ba36010cfe913a8c53166bf23
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Dec 24 21:03:01 2011 +0000
sna: Jump straight to the fallback copy routines if the dst is not attached
Marginally simplify the convoluted logic for choosing the most
appropriate path and help prevent further errors.
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 0815bc9..284c489 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2431,11 +2431,14 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
src_priv ? src_priv->cpu_bo : NULL,
replaces));
- if (dst_priv && replaces)
+ if (dst_priv == NULL)
+ goto fallback;
+
+ if (replaces)
sna_damage_destroy(&dst_priv->cpu_damage);
/* Try to maintain the data on the GPU */
- if (dst_priv && dst_priv->gpu_bo == NULL &&
+ if (dst_priv->gpu_bo == NULL &&
((dst_priv->cpu_damage == NULL && copy_use_gpu_bo(sna, dst_priv, ®ion)) ||
(src_priv && (src_priv->gpu_bo != NULL || (src_priv->cpu_bo && kgem_bo_is_busy(src_priv->cpu_bo)))))) {
uint32_t tiling = sna_pixmap_choose_tiling(dst_pixmap);
@@ -2455,7 +2458,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
tiling, 0);
}
- if (dst_priv && dst_priv->gpu_bo) {
+ if (dst_priv->gpu_bo) {
if (!src_priv && !copy_use_gpu_bo(sna, dst_priv, ®ion)) {
DBG(("%s: fallback - src_priv=%p and not use dst gpu bo\n",
__FUNCTION__, src_priv));
commit 72217790ee2c080d618274456360b481d015e898
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Dec 24 19:14:09 2011 +0000
sna: Use shadow if the GPU is busy or not immediately mappable
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b8c05fa..ee2b969 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1848,7 +1848,7 @@ bool kgem_can_create_2d(struct kgem *kgem,
}
#endif
-static int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
+inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
{
unsigned int size;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 42a0ba4..3e69be5 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -338,6 +338,21 @@ uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo);
Bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
const void *data, int length);
+int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo);
+
+static inline bool kgem_bo_is_mappable(struct kgem *kgem,
+ struct kgem_bo *bo)
+{
+ DBG_HDR(("%s: offset: %d size: %d\n",
+ __FUNCTION__, bo->presumed_offset, bo->size));
+
+ if (kgem->gen < 40 && bo->tiling &&
+ bo->presumed_offset & (kgem_bo_fenced_size(kgem, bo) - 1))
+ return false;
+
+ return bo->presumed_offset + bo->size <= kgem->aperture_mappable;
+}
+
static inline bool kgem_bo_is_busy(struct kgem_bo *bo)
{
DBG_HDR(("%s: domain: %d exec? %d, rq? %d\n",
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 837dacf..0815bc9 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -814,6 +814,9 @@ static inline bool region_inplace(struct sna *sna,
if (priv->mapped)
return true;
+ if (priv->gpu_bo && !kgem_bo_is_mappable(&sna->kgem, priv->gpu_bo))
+ return false;
+
return ((region->extents.x2 - region->extents.x1) *
(region->extents.y2 - region->extents.y1) *
pixmap->drawable.bitsPerPixel >> 12)
@@ -1747,7 +1750,9 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
* immediately flushed...
*/
if ((priv->flush ||
- (priv->gpu_bo && region_inplace(sna, pixmap, region, priv))) &&
+ (priv->gpu_bo &&
+ region_inplace(sna, pixmap, region, priv) &&
+ !kgem_bo_is_busy(priv->gpu_bo))) &&
sna_put_image_upload_blt(drawable, gc, region,
x, y, w, h, bits, stride)) {
if (region_subsumes_drawable(region, &pixmap->drawable)) {
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 1e4a9fb..15fe42c 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -87,8 +87,7 @@ static bool map_will_stall(struct kgem *kgem, struct kgem_bo *bo)
if (kgem_bo_is_busy(bo))
return true;
- if (bo->presumed_offset &&
- bo->presumed_offset + bo->size >= kgem->aperture_mappable)
+ if (!kgem_bo_is_mappable(kgem, bo))
return true;
return false;
commit 0be136c21f0373d1eb2259b83c598655f4eb841e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Dec 24 18:44:15 2011 +0000
sna: use indirect uploads if the bo was last known to be unmappable
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 55fb88d..1e4a9fb 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -82,6 +82,18 @@ static void read_boxes_inplace(struct kgem *kgem,
} while (--n);
}
+static bool map_will_stall(struct kgem *kgem, struct kgem_bo *bo)
+{
+ if (kgem_bo_is_busy(bo))
+ return true;
+
+ if (bo->presumed_offset &&
+ bo->presumed_offset + bo->size >= kgem->aperture_mappable)
+ return true;
+
+ return false;
+}
+
void sna_read_boxes(struct sna *sna,
struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
PixmapPtr dst, int16_t dst_dx, int16_t dst_dy,
@@ -100,9 +112,15 @@ void sna_read_boxes(struct sna *sna,
__FUNCTION__, nbox, src_bo->handle, src_dx, src_dy,
dst->drawable.width, dst->drawable.height, dst_dx, dst_dy));
- if (DEBUG_NO_IO || kgem->wedged ||
- !kgem_bo_is_busy(src_bo) ||
- src_bo->tiling != I915_TILING_X) {
+ if (DEBUG_NO_IO || kgem->wedged || src_bo->tiling == I915_TILING_Y) {
+ read_boxes_inplace(kgem,
+ src_bo, src_dx, src_dy,
+ dst, dst_dx, dst_dy,
+ box, nbox);
+ return;
+ }
+
+ if (src_bo->tiling != I915_TILING_X && !map_will_stall(kgem, src_bo)){
read_boxes_inplace(kgem,
src_bo, src_dx, src_dy,
dst, dst_dx, dst_dy,
@@ -296,9 +314,8 @@ void sna_write_boxes(struct sna *sna,
DBG(("%s x %d\n", __FUNCTION__, nbox));
- if (DEBUG_NO_IO || kgem->wedged ||
- !kgem_bo_is_busy(dst_bo) ||
- dst_bo->tiling == I915_TILING_Y) {
+ if (DEBUG_NO_IO || kgem->wedged || dst_bo->tiling == I915_TILING_Y ||
+ !map_will_stall(kgem, dst_bo)) {
write_boxes_inplace(kgem,
src, stride, bpp, src_dx, src_dy,
dst_bo, dst_dx, dst_dy,
commit e764a52ee8f0c552e218b3110318be9ba06634ae
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Dec 24 15:17:06 2011 +0000
sna: Encourage large operations to be migrated to the GPU
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/compiler.h b/src/sna/compiler.h
index bd84973..364ea62 100644
--- a/src/sna/compiler.h
+++ b/src/sna/compiler.h
@@ -34,12 +34,14 @@
#define noinline __attribute__((noinline))
#define fastcall __attribute__((regparm(3)))
#define must_check __attribute__((warn_unused_result))
+#define constant __attribute__((const))
#else
#define likely(expr) (expr)
#define unlikely(expr) (expr)
#define noinline
#define fastcall
#define must_check
+#define constant
#endif
#ifdef HAVE_VALGRIND
diff --git a/src/sna/sna.h b/src/sna/sna.h
index b99d0fd..79aa08f 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -177,7 +177,7 @@ static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
return get_window_pixmap((WindowPtr)drawable);
}
-static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap)
+constant static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap)
{
return ((void **)pixmap->devPrivates)[1];
}
@@ -322,25 +322,25 @@ extern PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap);
void sna_mode_delete_fb(struct sna *sna, uint32_t fb);
-static inline struct sna *
+constant static inline struct sna *
to_sna(ScrnInfoPtr scrn)
{
return (struct sna *)(scrn->driverPrivate);
}
-static inline struct sna *
+constant static inline struct sna *
to_sna_from_screen(ScreenPtr screen)
{
return to_sna(xf86Screens[screen->myNum]);
}
-static inline struct sna *
+constant static inline struct sna *
to_sna_from_pixmap(PixmapPtr pixmap)
{
return *(void **)pixmap->devPrivates;
}
-static inline struct sna *
+constant static inline struct sna *
to_sna_from_drawable(DrawablePtr drawable)
{
return to_sna_from_screen(drawable->pScreen);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index a8723d1..837dacf 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1030,7 +1030,7 @@ done:
return true;
}
-static void
+static bool
sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box)
{
struct sna *sna = to_sna_from_pixmap(pixmap);
@@ -1039,7 +1039,27 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box)
DBG(("%s()\n", __FUNCTION__));
- assert(priv->gpu_bo);
+ if (priv->gpu_bo == NULL) {
+ struct sna *sna = to_sna_from_pixmap(pixmap);
+ unsigned flags;
+
+ flags = 0;
+ if (priv->cpu_damage)
+ flags |= CREATE_INACTIVE;
+ if (pixmap->usage_hint == SNA_CREATE_FB)
+ flags |= CREATE_EXACT | CREATE_SCANOUT;
+
+ priv->gpu_bo = kgem_create_2d(&sna->kgem,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ pixmap->drawable.bitsPerPixel,
+ sna_pixmap_choose_tiling(pixmap),
+ flags);
+ if (priv->gpu_bo == NULL)
+ return false;
+
+ DBG(("%s: created gpu bo\n", __FUNCTION__));
+ }
sna_damage_reduce(&priv->cpu_damage);
DBG(("%s: CPU damage? %d\n", __FUNCTION__, priv->cpu_damage != NULL));
@@ -1092,6 +1112,14 @@ done:
if (!priv->pinned)
list_move(&priv->inactive, &sna->active_pixmaps);
priv->gpu = true;
+ return true;
+}
+
+static inline bool
+box_inplace(PixmapPtr pixmap, const BoxRec *box)
+{
+ struct sna *sna = to_sna_from_pixmap(pixmap);
+ return ((box->x2 - box->x1) * (box->y2 - box->y1) * pixmap->drawable.bitsPerPixel >> 15) >= sna->kgem.half_cpu_cache_pages;
}
static inline Bool
@@ -1112,7 +1140,9 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
!sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_WRITE))
return FALSE;
- if (priv->gpu_bo == NULL)
+ if (priv->gpu_bo == NULL &&
+ sna_pixmap_choose_tiling(pixmap) != I915_TILING_NONE &&
+ !box_inplace(pixmap, box))
return FALSE;
get_drawable_deltas(drawable, pixmap, &dx, &dy);
@@ -1137,7 +1167,7 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
if (priv->cpu_damage == NULL ||
sna_damage_contains_box(priv->cpu_damage,
&extents) == PIXMAN_REGION_OUT)
- goto done;
+ goto move_to_gpu;
if (priv->gpu_damage == NULL ||
sna_damage_contains_box(priv->gpu_damage,
@@ -1146,8 +1176,8 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
}
move_to_gpu:
- sna_pixmap_move_area_to_gpu(pixmap, &extents);
-done:
+ if (!sna_pixmap_move_area_to_gpu(pixmap, &extents))
+ return FALSE;
if (sna_damage_contains_box(priv->gpu_damage,
&extents) != PIXMAN_REGION_IN)
*damage = &priv->gpu_damage;
commit f9f8535db6a9e3affba9ba2c2a9314dfe12ab270
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Dec 24 21:01:39 2011 +0000
sna: Fix damage reduction by adding new boxes to the tail of the box list
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index cc4bf6a..b34c7a5 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -206,7 +206,7 @@ static bool _sna_damage_create_boxes(struct sna_damage *damage,
if (box == NULL)
return false;
- list_add(&box->list, &damage->embedded_box.list);
+ list_add_tail(&box->list, &damage->embedded_box.list);
box->size = damage->remain = n;
damage->box = (BoxRec *)(box + 1);
@@ -400,6 +400,7 @@ static void __sna_damage_reduce(struct sna_damage *damage)
boxes = damage->embedded_box.box;
list_for_each_entry(iter, &damage->embedded_box.list, list)
nboxes += iter->size;
+ DBG((" nboxes=%d, residual=%d\n", nboxes, damage->remain));
nboxes -= damage->remain;
if (nboxes == 0)
goto done;
@@ -414,6 +415,7 @@ static void __sna_damage_reduce(struct sna_damage *damage)
int len = iter->size;
if (n + len > nboxes)
len = nboxes - n;
+ DBG((" copy %d/%d boxes from %d\n", len, iter->size, n));
memcpy(boxes + n, iter+1, len * sizeof(BoxRec));
n += len;
}
More information about the xorg-commit
mailing list