xf86-video-intel: 5 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_dri.c src/sna/sna_io.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Jan 31 02:31:39 PST 2012
src/sna/kgem.c | 14 ++++++++++----
src/sna/sna_accel.c | 24 ++++++++++++++++++++++--
src/sna/sna_dri.c | 39 ++++++++++++++++++++++++++++-----------
src/sna/sna_io.c | 36 +++++++++++++++++++++++++++---------
4 files changed, 87 insertions(+), 26 deletions(-)
New commits:
commit 9c1f8a768ca1f762c722f63bab2747e4ff1fd773
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jan 31 10:29:02 2012 +0000
sna: Avoid converting requested Y to X tiling for large pitches on gen4+
The only strong requirement is that to utilize large pitches, the object
must be tiled. Having it as X tiling is a pure convenience to facilitate
use of the blitter. A DRI client may want to keep using Y tiling
instead.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 0b2e1d6..311bac4 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2151,7 +2151,10 @@ int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int
if (width*bpp > (MAXSHORT-512) * 8) {
DBG(("%s: large pitch [%d], forcing TILING_X\n",
__FUNCTION__, width*bpp/8));
- tiling = -I915_TILING_X;
+ if (tiling > 0)
+ tiling = -tiling;
+ else if (tiling == 0)
+ tiling = -I915_TILING_X;
} else if (tiling && (width|height) > 8192) {
DBG(("%s: large tiled buffer [%dx%d], forcing TILING_X\n",
__FUNCTION__, width, height));
commit e872c1011fc7b67683703fd891234f07dd7acd04
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jan 31 10:21:05 2012 +0000
sna/dri: We need to reduce tiling on older gen if we cannot fence
Only apply the architectural limits to enable bo creation for DRI buffers.
Reported-by: Alban Browaeys <prahal at yahoo.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=45414
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 2245c03..d0e19cf 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -127,19 +127,37 @@ static inline struct kgem_bo *ref(struct kgem_bo *bo)
/* Prefer to enable TILING_Y if this buffer will never be a
* candidate for pageflipping
*/
-static bool color_use_tiling_y(struct sna *sna, DrawablePtr drawable)
+static uint32_t color_tiling(struct sna *sna, DrawablePtr drawable)
{
- if (!COLOR_PREFER_TILING_Y)
- return false;
+ uint32_t tiling;
- return (drawable->width != sna->front->drawable.width ||
- drawable->height != sna->front->drawable.height);
+ if (COLOR_PREFER_TILING_Y &&
+ (drawable->width != sna->front->drawable.width ||
+ drawable->height != sna->front->drawable.height))
+ tiling = I915_TILING_Y;
+ else
+ tiling = I915_TILING_X;
+
+ return kgem_choose_tiling(&sna->kgem, -tiling,
+ drawable->width,
+ drawable->height,
+ drawable->bitsPerPixel);
+}
+
+static uint32_t other_tiling(struct sna *sna, DrawablePtr drawable)
+{
+ /* XXX Can mix color X / depth Y? */
+ return kgem_choose_tiling(&sna->kgem, -I915_TILING_Y,
+ drawable->width,
+ drawable->height,
+ drawable->bitsPerPixel);
}
static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
PixmapPtr pixmap)
{
struct sna_pixmap *priv;
+ uint32_t tiling;
priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
if (priv == NULL)
@@ -148,9 +166,9 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
if (priv->flush)
return ref(priv->gpu_bo);
- if (priv->gpu_bo->tiling != I915_TILING_Y &&
- color_use_tiling_y(sna, &pixmap->drawable))
- sna_pixmap_change_tiling(pixmap, I915_TILING_Y);
+ tiling = color_tiling(sna, &pixmap->drawable);
+ if (priv->gpu_bo->tiling != tiling)
+ sna_pixmap_change_tiling(pixmap, tiling);
/* We need to submit any modifications to and reads from this
* buffer before we send any reply to the Client.
@@ -209,7 +227,7 @@ sna_dri_create_buffer(DrawablePtr drawable,
drawable->width,
drawable->height,
drawable->bitsPerPixel,
- color_use_tiling_y(sna, drawable) ? I915_TILING_Y : I915_TILING_X,
+ color_tiling(sna, drawable),
CREATE_EXACT);
break;
@@ -252,8 +270,7 @@ sna_dri_create_buffer(DrawablePtr drawable,
bpp = format ? format : drawable->bitsPerPixel,
bo = kgem_create_2d(&sna->kgem,
drawable->width, drawable->height, bpp,
- //sna->kgem.gen >= 40 ? I915_TILING_Y : I915_TILING_X,
- I915_TILING_Y,
+ other_tiling(sna, drawable),
CREATE_EXACT);
break;
commit a4caf67d8da37d04f8915d96b10411ba7267937e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jan 31 00:35:42 2012 +0000
sna: Trim tile sizes to fit into bo cache
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index ca7eafa..0b2e1d6 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -692,13 +692,14 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
if (kgem->max_gpu_size > kgem->max_cpu_size)
kgem->max_gpu_size = kgem->max_cpu_size;
- kgem->max_tile_size = kgem->aperture_total / 4;
+ kgem->max_tile_size = MAX_CACHE_SIZE;
if (kgem->max_tile_size > kgem->max_gpu_size / 2)
kgem->max_tile_size = kgem->max_gpu_size / 2;
totalram = total_ram_size();
if (totalram == 0) {
- DBG(("%s: total ram size unknown, assuming maximum of total aperture\n"));
+ DBG(("%s: total ram size unknown, assuming maximum of total aperture\n",
+ __FUNCTION__));
totalram = kgem->aperture_total;
}
if (kgem->max_object_size > totalram / 2)
@@ -3193,7 +3194,9 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
#if !DBG_NO_MAP_UPLOAD
/* Be a little more generous and hope to hold fewer mmappings */
alloc = ALIGN(2*size, kgem->partial_buffer_size);
- if (alloc > kgem->max_gpu_size)
+ if (alloc > kgem->max_tile_size)
+ alloc = ALIGN(size, kgem->partial_buffer_size);
+ if (alloc > kgem->max_tile_size)
alloc = PAGE_ALIGN(size);
alloc /= PAGE_SIZE;
if (kgem->has_cpu_bo) {
commit 3f7c1646c78d8854c88b214d3699e51839ba9711
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jan 31 00:09:42 2012 +0000
sna: Check that the intermediate IO buffer can also be used for blitting
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 e35be97..3115bd7 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -716,8 +716,8 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
} else {
struct sna_pixmap *priv;
- DBG(("%s: creating GPU pixmap %dx%d, stride=%d\n",
- __FUNCTION__, width, height, pad));
+ DBG(("%s: creating GPU pixmap %dx%d, stride=%d, flags=%x\n",
+ __FUNCTION__, width, height, pad, flags));
pixmap = create_pixmap(sna, screen, 0, 0, depth, usage);
if (pixmap == NullPixmap)
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 4f86f8d..f4278be 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -59,11 +59,16 @@ box_intersect(BoxPtr a, const BoxRec *b)
return a->x1 < a->x2 && a->y1 < a->y2;
}
+static inline bool upload_too_large(struct sna *sna, int width, int height)
+{
+ return width * height * 4 > sna->kgem.max_tile_size;
+}
+
static inline bool must_tile(struct sna *sna, int width, int height)
{
return (width > sna->render.max_3d_size ||
height > sna->render.max_3d_size ||
- width * height * 4 > sna->kgem.max_tile_size);
+ upload_too_large(sna, width, height));
}
static void read_boxes_inplace(struct kgem *kgem,
@@ -118,6 +123,7 @@ void sna_read_boxes(struct sna *sna,
void *ptr;
int src_pitch, cpp, offset;
int n, cmd, br13;
+ bool can_blt;
DBG(("%s x %d, src=(handle=%d, offset=(%d,%d)), dst=(size=(%d, %d), offset=(%d,%d))\n",
__FUNCTION__, nbox, src_bo->handle, src_dx, src_dy,
@@ -154,6 +160,7 @@ fallback:
return;
}
+ can_blt = kgem_bo_can_blt(kgem, src_bo);
extents = box[0];
for (n = 1; n < nbox; n++) {
if (box[n].x1 < extents.x1)
@@ -161,6 +168,9 @@ fallback:
if (box[n].x2 > extents.x2)
extents.x2 = box[n].x2;
+ if (can_blt)
+ can_blt = (box[n].x2 - box[n].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4);
+
if (box[n].y1 < extents.y1)
extents.y1 = box[n].y1;
if (box[n].y2 > extents.y2)
@@ -173,9 +183,8 @@ fallback:
}
/* Try to avoid switching rings... */
- if (kgem->ring == KGEM_RENDER ||
- !kgem_bo_can_blt(kgem, src_bo) ||
- must_tile(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) {
+ if (!can_blt || kgem->ring == KGEM_RENDER ||
+ upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) {
PixmapRec tmp;
tmp.drawable.width = extents.x2 - extents.x1;
@@ -531,6 +540,7 @@ bool sna_write_boxes(struct sna *sna, PixmapPtr dst,
void *ptr;
int offset;
int n, cmd, br13;
+ bool can_blt;
DBG(("%s x %d\n", __FUNCTION__, nbox));
@@ -542,6 +552,7 @@ fallback:
box, nbox);
}
+ can_blt = kgem_bo_can_blt(kgem, dst_bo);
extents = box[0];
for (n = 1; n < nbox; n++) {
if (box[n].x1 < extents.x1)
@@ -549,6 +560,9 @@ fallback:
if (box[n].x2 > extents.x2)
extents.x2 = box[n].x2;
+ if (can_blt)
+ can_blt = (box[n].x2 - box[n].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4);
+
if (box[n].y1 < extents.y1)
extents.y1 = box[n].y1;
if (box[n].y2 > extents.y2)
@@ -556,9 +570,8 @@ fallback:
}
/* Try to avoid switching rings... */
- if (kgem->ring == KGEM_RENDER ||
- !kgem_bo_can_blt(kgem, dst_bo) ||
- must_tile(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) {
+ if (!can_blt || kgem->ring == KGEM_RENDER ||
+ upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) {
PixmapRec tmp;
tmp.drawable.width = extents.x2 - extents.x1;
@@ -579,6 +592,7 @@ fallback:
BoxRec tile, stack[64], *clipped, *c;
int step;
+tile:
step = MIN(sna->render.max_3d_size,
8*(MAXSHORT&~63) / dst->drawable.bitsPerPixel);
while (step * step * 4 > sna->kgem.max_tile_size)
@@ -693,7 +707,7 @@ fallback:
kgem_bo_destroy(&sna->kgem, src_bo);
if (!n)
- goto fallback;
+ goto tile;
}
return true;
@@ -1069,9 +1083,13 @@ indirect_replace(struct sna *sna,
if ((int)pixmap->devKind * pixmap->drawable.height >> 12 > kgem->half_cpu_cache_pages)
return false;
- if (bo->tiling == I915_TILING_Y || kgem->ring == KGEM_RENDER) {
+ if (kgem->ring == KGEM_RENDER || !kgem_bo_can_blt(kgem, bo)) {
BoxRec box;
+ assert(!must_tile(sna,
+ pixmap->drawable.width,
+ pixmap->drawable.height));
+
src_bo = kgem_create_buffer_2d(kgem,
pixmap->drawable.width,
pixmap->drawable.height,
commit e504fab6c5354ae9d18ccefb10bd586fa49b924c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jan 30 23:49:18 2012 +0000
sna: Discard the cleared GPU buffer upon PutImage to the CPU buffer
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 26fd1ab..e35be97 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2533,6 +2533,26 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
!sna_pixmap_alloc_cpu(sna, pixmap, priv, false))
return true;
+ if (priv->clear) {
+ DBG(("%s: applying clear [%08x]\n",
+ __FUNCTION__, priv->clear_color));
+
+ pixman_fill(pixmap->devPrivate.ptr,
+ pixmap->devKind/sizeof(uint32_t),
+ pixmap->drawable.bitsPerPixel,
+ 0, 0,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ priv->clear_color);
+
+ sna_damage_all(&priv->cpu_damage,
+ pixmap->drawable.width,
+ pixmap->drawable.height);
+ sna_pixmap_free_gpu(sna, priv);
+ priv->undamaged = false;
+ priv->clear = false;
+ }
+
if (!DAMAGE_IS_ALL(priv->cpu_damage)) {
DBG(("%s: marking damage\n", __FUNCTION__));
if (region_subsumes_drawable(region, &pixmap->drawable)) {
More information about the xorg-commit
mailing list