summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-25 12:49:24 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-25 13:52:27 +0000
commit36425ba49ecbd87b1e3bf4340ca2496d8de24a7f (patch)
tree7af846620384f737a164a6e1487c58c4c0ce247a
parenta2e83c6dcba1e911f42a3004b3d0782049e243e2 (diff)
sna: Round up buffer allocations when downsampling
The pathological case being nx1 or 1xm resulting in an illegal allocation request of 0 bytes. One such example is wolframalpha.com: x = (200 + x) / 100 which generates an approximately 8500x1 image and so needs downscaling to fit in the render pipeline on all but IvyBridge. Bring on Ivy! Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c12
-rw-r--r--src/sna/sna_render.c19
2 files changed, 17 insertions, 14 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index d85e9305..1e78c1a0 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3251,20 +3251,22 @@ struct kgem_bo *kgem_upload_source_image_halved(struct kgem *kgem,
struct kgem_bo *bo;
pixman_image_t *src_image, *dst_image;
pixman_transform_t t;
+ int w, h;
void *dst;
DBG(("%s : (%d, %d), (%d, %d), stride=%d, bpp=%d\n",
__FUNCTION__, x, y, width, height, stride, bpp));
- bo = kgem_create_buffer_2d(kgem,
- width/2, height/2, bpp,
+ w = (width + 1) / 2;
+ h = (height + 1) / 2;
+
+ bo = kgem_create_buffer_2d(kgem, w, h, bpp,
KGEM_BUFFER_WRITE_INPLACE,
&dst);
if (bo == NULL)
return NULL;
- dst_image = pixman_image_create_bits(format, width/2, height/2,
- dst, bo->pitch);
+ dst_image = pixman_image_create_bits(format, w, h, dst, bo->pitch);
if (dst_image == NULL)
goto cleanup_bo;
@@ -3286,7 +3288,7 @@ struct kgem_bo *kgem_upload_source_image_halved(struct kgem *kgem,
x, y,
0, 0,
0, 0,
- width/2, height/2);
+ w, h);
pixman_image_unref(src_image);
pixman_image_unref(dst_image);
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index af817351..d1cb60b0 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -717,7 +717,8 @@ static int sna_render_picture_downsample(struct sna *sna,
goto fixup;
tmp = screen->CreatePixmap(screen,
- w/2, h/2, pixmap->drawable.depth,
+ (w+1)/2, (h+1)/2,
+ pixmap->drawable.depth,
SNA_CREATE_SCRATCH);
if (!tmp)
goto fixup;
@@ -760,18 +761,18 @@ static int sna_render_picture_downsample(struct sna *sna,
ValidatePicture(tmp_src);
if (w > sna->render.max_3d_size) {
- ww = w/4;
+ ww = (w+3)/4;
nj = 2;
} else {
- ww = w/2;
+ ww = (w+1)/2;
nj = 1;
}
if (h > sna->render.max_3d_size) {
- hh = h/4;
+ hh = (h+3)/4;
ni = 2;
} else {
- hh = h/2;
+ hh = (h+1)/2;
ni = 1;
}
@@ -783,7 +784,7 @@ static int sna_render_picture_downsample(struct sna *sna,
b.y1 = hh*i;
if (i == ni - 1)
- b.y2 = h/2;
+ b.y2 = (h+1)/2;
else
b.y2 = b.y1 + hh;
@@ -792,7 +793,7 @@ static int sna_render_picture_downsample(struct sna *sna,
b.x1 = ww*j;
if (j == nj - 1)
- b.x2 = w/2;
+ b.x2 = (w+1)/2;
else
b.x2 = b.x1 + ww;
@@ -850,8 +851,8 @@ static int sna_render_picture_downsample(struct sna *sna,
channel->offset[1] = y - dst_y;
channel->scale[0] = 1.f/w;
channel->scale[1] = 1.f/h;
- channel->width = w / 2;
- channel->height = h / 2;
+ channel->width = (w + 1) / 2;
+ channel->height = (h + 1) / 2;
channel->bo = bo;
return 1;