xf86-video-intel: 2 commits - src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_io.c src/sna/sna_render.c

Chris Wilson ickle at kemper.freedesktop.org
Sat Jan 7 10:14:54 PST 2012


 src/sna/kgem.c       |   58 ++++++++++++++++++++++++++++++++++++---------------
 src/sna/kgem.h       |    4 +++
 src/sna/sna_accel.c  |   12 ++++------
 src/sna/sna_blt.c    |   48 ++++++++++++++++++------------------------
 src/sna/sna_io.c     |   38 ++++++++++++++-------------------
 src/sna/sna_render.c |   51 ++++++++++++++++++++------------------------
 6 files changed, 110 insertions(+), 101 deletions(-)

New commits:
commit 292aebfcdc042b08d3a5a21f839e6aec1175359e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 7 18:09:47 2012 +0000

    sna: Prevent reuse of scanlines after the buffer is destroyed
    
    Once the buffer is destroyed, it may be reallocated with a new pitch. We
    could track handle and pitch, but it is easier to simply restart the
    blit after the buffer is freed.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=44277
    References: https://bugs.freedesktop.org/show_bug.cgi?id=44555
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 038105a..fab9700 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -195,7 +195,7 @@ static bool sna_blt_fill_init(struct sna *sna,
 		b[8] = 0;
 		kgem->nbatch += 9;
 
-		sna->blt_state.fill_bo = bo->handle;
+		sna->blt_state.fill_bo = bo->unique_id;
 		sna->blt_state.fill_pixel = pixel;
 		sna->blt_state.fill_alu = alu;
 	}
@@ -1786,15 +1786,6 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 	}
 	assert(br13 < MAXSHORT);
 
-	if (alu == GXclear)
-		color = 0;
-	else if (alu == GXcopy) {
-		if (color == 0)
-			alu = GXclear;
-		else if (color == -1)
-			alu = GXset;
-	}
-
 	br13 |= fill_ROP[alu] << 16;
 	switch (bpp) {
 	default: assert(0);
@@ -1813,7 +1804,7 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 		DBG(("%s: replacing last fill\n", __FUNCTION__));
 		kgem->batch[kgem->nbatch-5] = br13;
 		kgem->batch[kgem->nbatch-1] = color;
-		return TRUE;
+		return true;
 	}
 	if (overwrites && kgem->nbatch >= 8 &&
 	    (kgem->batch[kgem->nbatch-8] & 0xffc0000f) == XY_SRC_COPY_BLT_CMD &&
@@ -1828,15 +1819,18 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 		 */
 		kgem->nreloc--;
 		kgem->nbatch -= 2;
-		return TRUE;
+		return true;
 	}
 
 	/* If we are currently emitting SCANLINES, keep doing so */
-	if (sna->blt_state.fill_bo == bo->handle &&
+	if (sna->blt_state.fill_bo == bo->unique_id &&
 	    sna->blt_state.fill_pixel == color &&
 	    (sna->blt_state.fill_alu == alu ||
-	     sna->blt_state.fill_alu == ~alu))
-		return FALSE;
+	     sna->blt_state.fill_alu == ~alu)) {
+		DBG(("%s: matching last fill, converting to scanlines\n",
+		     __FUNCTION__));
+		return false;
+	}
 
 	kgem_set_mode(kgem, KGEM_BLT);
 	if (!kgem_check_batch(kgem, 6) ||
@@ -1858,10 +1852,10 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 	b[5] = color;
 	kgem->nbatch += 6;
 
-	sna->blt_state.fill_bo = bo->handle;
+	sna->blt_state.fill_bo = bo->unique_id;
 	sna->blt_state.fill_pixel = color;
 	sna->blt_state.fill_alu = ~alu;
-	return TRUE;
+	return true;
 }
 
 Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
@@ -1884,6 +1878,15 @@ Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
 		return FALSE;
 	}
 
+	if (alu == GXclear)
+		pixel = 0;
+	else if (alu == GXcopy) {
+		if (pixel == 0)
+			alu = GXclear;
+		else if (pixel == -1)
+			alu = GXset;
+	}
+
 	if (nbox == 1 && sna_blt_fill_box(sna, alu, bo, bpp, pixel, box))
 		return TRUE;
 
@@ -1895,15 +1898,6 @@ Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
 	}
 	assert(br13 < MAXSHORT);
 
-	if (alu == GXclear)
-		pixel = 0;
-	else if (alu == GXcopy) {
-		if (pixel == 0)
-			alu = GXclear;
-		else if (pixel == -1)
-			alu = GXset;
-	}
-
 	br13 |= 1<<31 | fill_ROP[alu] << 16;
 	switch (bpp) {
 	default: assert(0);
@@ -1948,7 +1942,7 @@ Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
 		b[8] = 0;
 		kgem->nbatch += 9;
 
-		sna->blt_state.fill_bo = bo->handle;
+		sna->blt_state.fill_bo = bo->unique_id;
 		sna->blt_state.fill_pixel = pixel;
 		sna->blt_state.fill_alu = alu;
 	}
commit d7d07d1df3ffc889ccc32c2ed44ce374e37f851d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 7 10:37:01 2012 +0000

    sna: Pad upload buffers to ensure there are an even number of rows
    
    One restriction common to all generations is that samplers access pairs
    of rows and so we need to pad the buffer to accommodate access to that
    second row. Do so unconditionally along paths that may be used by the
    render pipeline.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 4bccccb..537cad9 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2957,6 +2957,34 @@ done:
 	return kgem_create_proxy(&bo->base, offset, size);
 }
 
+struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
+				      int width, int height, int bpp,
+				      uint32_t flags,
+				      void **ret)
+{
+	struct kgem_bo *bo;
+	int stride;
+
+	stride = width * bpp >> 3;
+	stride = ALIGN(stride, 4);
+
+	bo = kgem_create_buffer(kgem, stride * ALIGN(height, 2), flags, ret);
+	if (bo == NULL)
+		return NULL;
+
+	if (height & 1) {
+		/* Having padded this surface to ensure that accesses to
+		 * the last pair of rows is valid, remove the padding so
+		 * that it can be allocated to other pixmaps.
+		 */
+		((struct kgem_partial_bo *)bo->proxy)->used -= stride;
+		bo->size -= stride;
+	}
+
+	bo->pitch = stride;
+	return bo;
+}
+
 struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
 					 const void *data,
 					 BoxPtr box,
@@ -2964,25 +2992,22 @@ struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
 {
 	int width = box->x2 - box->x1;
 	int height = box->y2 - box->y1;
-	int dst_stride = ALIGN(width * bpp, 32) >> 3;
-	int size = dst_stride * height;
 	struct kgem_bo *bo;
 	void *dst;
 
 	DBG(("%s : (%d, %d), (%d, %d), stride=%d, bpp=%d\n",
 	     __FUNCTION__, box->x1, box->y1, box->x2, box->y2, stride, bpp));
 
-	bo = kgem_create_buffer(kgem, size, KGEM_BUFFER_WRITE, &dst);
-	if (bo == NULL)
-		return NULL;
-
-	memcpy_blt(data, dst, bpp,
-		   stride, dst_stride,
-		   box->x1, box->y1,
-		   0, 0,
-		   width, height);
+	bo = kgem_create_buffer_2d(kgem,
+				   width, height, bpp,
+				   KGEM_BUFFER_WRITE, &dst);
+	if (bo)
+		memcpy_blt(data, dst, bpp,
+			   stride, bo->pitch,
+			   box->x1, box->y1,
+			   0, 0,
+			   width, height);
 
-	bo->pitch = dst_stride;
 	return bo;
 }
 
@@ -2993,8 +3018,6 @@ struct kgem_bo *kgem_upload_source_image_halved(struct kgem *kgem,
 						int width, int height,
 						int stride, int bpp)
 {
-	int dst_stride = ALIGN(width * bpp / 2, 32) >> 3;
-	int size = dst_stride * height / 2;
 	struct kgem_bo *bo;
 	pixman_image_t *src_image, *dst_image;
 	pixman_transform_t t;
@@ -3003,12 +3026,14 @@ struct kgem_bo *kgem_upload_source_image_halved(struct kgem *kgem,
 	DBG(("%s : (%d, %d), (%d, %d), stride=%d, bpp=%d\n",
 	     __FUNCTION__, x, y, width, height, stride, bpp));
 
-	bo = kgem_create_buffer(kgem, size, KGEM_BUFFER_WRITE, &dst);
+	bo = kgem_create_buffer_2d(kgem,
+				   width, height, bpp,
+				   KGEM_BUFFER_WRITE, &dst);
 	if (bo == NULL)
 		return NULL;
 
 	dst_image = pixman_image_create_bits(format, width/2, height/2,
-					     dst, dst_stride);
+					     dst, bo->pitch);
 	if (dst_image == NULL)
 		goto cleanup_bo;
 
@@ -3034,7 +3059,6 @@ struct kgem_bo *kgem_upload_source_image_halved(struct kgem *kgem,
 	pixman_image_unref(src_image);
 	pixman_image_unref(dst_image);
 
-	bo->pitch = dst_stride;
 	return bo;
 
 cleanup_dst:
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index e5b7ccf..57ac647 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -403,6 +403,10 @@ void kgem_sync(struct kgem *kgem);
 struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 				   uint32_t size, uint32_t flags,
 				   void **ret);
+struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
+				      int width, int height, int bpp,
+				      uint32_t flags,
+				      void **ret);
 void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo);
 
 void kgem_throttle(struct kgem *kgem);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e3816b3..5bf1395 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1410,7 +1410,6 @@ sna_pixmap_create_upload(ScreenPtr screen,
 	PixmapPtr pixmap;
 	struct sna_pixmap *priv;
 	int bpp = BitsPerPixel(depth);
-	int pad = ALIGN(width * bpp / 8, 4);
 	void *ptr;
 
 	DBG(("%s(%d, %d, %d)\n", __FUNCTION__, width, height, depth));
@@ -1453,23 +1452,22 @@ sna_pixmap_create_upload(ScreenPtr screen,
 	priv = _sna_pixmap_reset(pixmap);
 	priv->header = true;
 
-	priv->gpu_bo = kgem_create_buffer(&sna->kgem,
-					  pad*height, KGEM_BUFFER_WRITE,
-					  &ptr);
+	priv->gpu_bo = kgem_create_buffer_2d(&sna->kgem,
+					     width, height, bpp,
+					     KGEM_BUFFER_WRITE,
+					     &ptr);
 	if (!priv->gpu_bo) {
 		free(priv);
 		fbDestroyPixmap(pixmap);
 		return NullPixmap;
 	}
 
-	priv->gpu_bo->pitch = pad;
-
 	pixmap->drawable.width = width;
 	pixmap->drawable.height = height;
 	pixmap->drawable.depth = depth;
 	pixmap->drawable.bitsPerPixel = bpp;
 	pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-	pixmap->devKind = pad;
+	pixmap->devKind = priv->gpu_bo->pitch;
 	pixmap->devPrivate.ptr = ptr;
 
 	return pixmap;
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index aef3f50..761d324 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -346,30 +346,27 @@ fallback:
 				extents.y2 = box[n].y2;
 		}
 
-		tmp.drawable.width = extents.x2 - extents.x1;
+		tmp.drawable.width  = extents.x2 - extents.x1;
 		tmp.drawable.height = extents.y2 - extents.y1;
-		tmp.drawable.depth = dst->drawable.depth;
+		tmp.drawable.depth  = dst->drawable.depth;
 		tmp.drawable.bitsPerPixel = dst->drawable.bitsPerPixel;
 		tmp.devPrivate.ptr = NULL;
 
 		assert(tmp.drawable.width);
 		assert(tmp.drawable.height);
 
-		tmp.devKind = tmp.drawable.width * tmp.drawable.bitsPerPixel / 8;
-		tmp.devKind = ALIGN(tmp.devKind, 4);
-
-		src_bo = kgem_create_buffer(kgem,
-					    tmp.drawable.height * tmp.devKind,
-					    KGEM_BUFFER_WRITE,
-					    &ptr);
+		src_bo = kgem_create_buffer_2d(kgem,
+					       tmp.drawable.width,
+					       tmp.drawable.height,
+					       tmp.drawable.bitsPerPixel,
+					       KGEM_BUFFER_WRITE,
+					       &ptr);
 		if (!src_bo)
 			goto fallback;
 
-		src_bo->pitch = tmp.devKind;
-
 		for (n = 0; n < nbox; n++) {
 			memcpy_blt(src, ptr, tmp.drawable.bitsPerPixel,
-				   stride, tmp.devKind,
+				   stride, src_bo->pitch,
 				   box[n].x1 + src_dx,
 				   box[n].y1 + src_dy,
 				   box[n].x1 - extents.x1,
@@ -594,21 +591,18 @@ fallback:
 		assert(tmp.drawable.width);
 		assert(tmp.drawable.height);
 
-		tmp.devKind = tmp.drawable.width * tmp.drawable.bitsPerPixel / 8;
-		tmp.devKind = ALIGN(tmp.devKind, 4);
-
-		src_bo = kgem_create_buffer(kgem,
-					    tmp.drawable.height * tmp.devKind,
-					    KGEM_BUFFER_WRITE,
-					    &ptr);
+		src_bo = kgem_create_buffer_2d(kgem,
+					       tmp.drawable.width,
+					       tmp.drawable.height,
+					       tmp.drawable.bitsPerPixel,
+					       KGEM_BUFFER_WRITE,
+					       &ptr);
 		if (!src_bo)
 			goto fallback;
 
-		src_bo->pitch = tmp.devKind;
-
 		for (n = 0; n < nbox; n++) {
 			memcpy_xor(src, ptr, tmp.drawable.bitsPerPixel,
-				   stride, tmp.devKind,
+				   stride, src_bo->pitch,
 				   box[n].x1 + src_dx,
 				   box[n].y1 + src_dy,
 				   box[n].x1 - extents.x1,
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 2501e53..712e245 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -1129,7 +1129,6 @@ sna_render_picture_fixup(struct sna *sna,
 			 int16_t dst_x, int16_t dst_y)
 {
 	pixman_image_t *dst, *src;
-	uint32_t pitch;
 	int dx, dy;
 	void *ptr;
 
@@ -1169,25 +1168,23 @@ sna_render_picture_fixup(struct sna *sna,
 	}
 
 do_fixup:
-	if (PICT_FORMAT_RGB(picture->format) == 0) {
-		pitch = ALIGN(w, 4);
+	if (PICT_FORMAT_RGB(picture->format) == 0)
 		channel->pict_format = PIXMAN_a8;
-	} else {
-		pitch = sizeof(uint32_t)*w;
+	else
 		channel->pict_format = PIXMAN_a8r8g8b8;
-	}
 	if (channel->pict_format != picture->format) {
-		DBG(("%s: converting to %08x (pitch=%d) from %08x\n",
-		     __FUNCTION__, channel->pict_format, pitch, picture->format));
+		DBG(("%s: converting to %08x from %08x\n",
+		     __FUNCTION__, channel->pict_format, picture->format));
 	}
 
 	if (picture->pDrawable &&
 	    !sna_drawable_move_to_cpu(picture->pDrawable, MOVE_READ))
 		return 0;
 
-	channel->bo = kgem_create_buffer(&sna->kgem,
-					 pitch*h, KGEM_BUFFER_WRITE,
-					 &ptr);
+	channel->bo = kgem_create_buffer_2d(&sna->kgem,
+					    w, h, PIXMAN_FORMAT_BPP(channel->pict_format),
+					    KGEM_BUFFER_WRITE,
+					    &ptr);
 	if (!channel->bo) {
 		DBG(("%s: failed to create upload buffer, using clear\n",
 		     __FUNCTION__));
@@ -1195,12 +1192,12 @@ do_fixup:
 	}
 
 	/* XXX Convolution filter? */
-	memset(ptr, 0, pitch*h);
-	channel->bo->pitch = pitch;
+	memset(ptr, 0, channel->bo->size);
 
 	/* Composite in the original format to preserve idiosyncracies */
 	if (picture->format == channel->pict_format)
-		dst = pixman_image_create_bits(picture->format, w, h, ptr, pitch);
+		dst = pixman_image_create_bits(picture->format,
+					       w, h, ptr, channel->bo->pitch);
 	else
 		dst = pixman_image_create_bits(picture->format, w, h, NULL, 0);
 	if (!dst) {
@@ -1233,7 +1230,7 @@ do_fixup:
 
 		src = dst;
 		dst = pixman_image_create_bits(channel->pict_format,
-					       w, h, ptr, pitch);
+					       w, h, ptr, channel->bo->pitch);
 		if (dst) {
 			pixman_image_composite(PictOpSrc, src, NULL, dst,
 					       0, 0,
@@ -1242,7 +1239,7 @@ do_fixup:
 					       w, h);
 			pixman_image_unref(src);
 		} else {
-			memset(ptr, 0, h*pitch);
+			memset(ptr, 0, channel->bo->size);
 			dst = src;
 		}
 	}
@@ -1273,7 +1270,6 @@ sna_render_picture_convert(struct sna *sna,
 			   int16_t w, int16_t h,
 			   int16_t dst_x, int16_t dst_y)
 {
-	uint32_t pitch;
 	pixman_image_t *src, *dst;
 	BoxRec box;
 	void *ptr;
@@ -1338,27 +1334,26 @@ sna_render_picture_convert(struct sna *sna,
 		return 0;
 
 	if (PICT_FORMAT_RGB(picture->format) == 0) {
-		pitch = ALIGN(w, 4);
 		channel->pict_format = PIXMAN_a8;
-		DBG(("%s: converting to a8 (pitch=%d) from %08x\n",
-		     __FUNCTION__, pitch, picture->format));
+		DBG(("%s: converting to a8 from %08x\n",
+		     __FUNCTION__, picture->format));
 	} else {
-		pitch = sizeof(uint32_t)*w;
 		channel->pict_format = PIXMAN_a8r8g8b8;
-		DBG(("%s: converting to a8r8g8b8 (pitch=%d) from %08x\n",
-		     __FUNCTION__, pitch, picture->format));
+		DBG(("%s: converting to a8r8g8b8 from %08x\n",
+		     __FUNCTION__, picture->format));
 	}
 
-	channel->bo = kgem_create_buffer(&sna->kgem,
-					 pitch*h, KGEM_BUFFER_WRITE,
-					 &ptr);
+	channel->bo = kgem_create_buffer_2d(&sna->kgem,
+					    w, h, PIXMAN_FORMAT_BPP(channel->pict_format),
+					    KGEM_BUFFER_WRITE,
+					    &ptr);
 	if (!channel->bo) {
 		pixman_image_unref(src);
 		return 0;
 	}
 
-	channel->bo->pitch = pitch;
-	dst = pixman_image_create_bits(channel->pict_format, w, h, ptr, pitch);
+	dst = pixman_image_create_bits(channel->pict_format,
+				       w, h, ptr, channel->bo->pitch);
 	if (!dst) {
 		kgem_bo_destroy(&sna->kgem, channel->bo);
 		pixman_image_unref(src);


More information about the xorg-commit mailing list