diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 4bccccbf..537cad9d 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; + 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); - memcpy_blt(data, dst, bpp, - stride, dst_stride, - 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 e5b7ccf2..57ac6478 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 e3816b39..5bf13951 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 aef3f509..761d3241 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 2501e535..712e2454 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);