diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-25 12:49:24 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-25 13:52:27 +0000 |
commit | 36425ba49ecbd87b1e3bf4340ca2496d8de24a7f (patch) | |
tree | 7af846620384f737a164a6e1487c58c4c0ce247a | |
parent | a2e83c6dcba1e911f42a3004b3d0782049e243e2 (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.c | 12 | ||||
-rw-r--r-- | src/sna/sna_render.c | 19 |
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; |