diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-29 18:07:14 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-29 20:12:39 +0000 |
commit | df148c962108a7f3efead0b80ab4fe77f3f79c8b (patch) | |
tree | cf55f05e74271b3710b96b5b6349ddc86119b47d /src/sna | |
parent | e1e67e8f394480eb4fef1238ccfd49cc36e4b6f2 (diff) |
sna: Limit the tile size for uploading into large pixmaps
As we may have a constrained aperture, we need to be careful not to
exceed our resources limits when uploading the pixel data. (For example,
fitting two of the maximum bo into a single batch may fail due to
fragmentation of the GATT.) So be cautious and use more tiles to reduce
the size of each individual batch.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/kgem.c | 12 | ||||
-rw-r--r-- | src/sna/kgem.h | 2 | ||||
-rw-r--r-- | src/sna/sna_io.c | 9 | ||||
-rw-r--r-- | src/sna/sna_tiling.c | 17 |
4 files changed, 31 insertions, 9 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index fff2d19b..7019638a 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -672,9 +672,15 @@ 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; - - DBG(("%s: max object size (tiled=%d, linear=%d)\n", - __FUNCTION__, kgem->max_gpu_size, kgem->max_cpu_size)); + kgem->max_tile_size = kgem->aperture_total / 4; + if (kgem->max_tile_size < kgem->max_gpu_size / 2) + kgem->max_tile_size = kgem->max_gpu_size / 2; + + DBG(("%s: max object size (gpu=%d, cpu=%d, tile=%d)\n", + __FUNCTION__, + kgem->max_gpu_size, + kgem->max_cpu_size, + kgem->max_tile_size)); /* Convert the aperture thresholds to pages */ kgem->aperture_low /= PAGE_SIZE; diff --git a/src/sna/kgem.h b/src/sna/kgem.h index f3869673..fea2d456 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -161,7 +161,7 @@ struct kgem { uint32_t aperture_total, aperture_high, aperture_low, aperture_mappable; uint32_t aperture, aperture_fenced; uint32_t min_alignment; - uint32_t max_gpu_size, max_cpu_size, max_object_size; + uint32_t max_tile_size, max_gpu_size, max_cpu_size, max_object_size; uint32_t partial_buffer_size; void (*context_switch)(struct kgem *kgem, int new_mode); diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c index 14a79013..4f86f8de 100644 --- a/src/sna/sna_io.c +++ b/src/sna/sna_io.c @@ -62,7 +62,8 @@ box_intersect(BoxPtr a, const BoxRec *b) 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); + height > sna->render.max_3d_size || + width * height * 4 > sna->kgem.max_tile_size); } static void read_boxes_inplace(struct kgem *kgem, @@ -199,6 +200,9 @@ fallback: step = MIN(sna->render.max_3d_size, 8*(MAXSHORT&~63) / dst->drawable.bitsPerPixel); + while (step * step * 4 > sna->kgem.max_tile_size) + step /= 2; + DBG(("%s: tiling download, using %dx%d tiles\n", __FUNCTION__, step, step)); @@ -577,6 +581,9 @@ fallback: step = MIN(sna->render.max_3d_size, 8*(MAXSHORT&~63) / dst->drawable.bitsPerPixel); + while (step * step * 4 > sna->kgem.max_tile_size) + step /= 2; + DBG(("%s: tiling upload, using %dx%d tiles\n", __FUNCTION__, step, step)); diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c index 52572bc6..eac664e3 100644 --- a/src/sna/sna_tiling.c +++ b/src/sna/sna_tiling.c @@ -138,7 +138,11 @@ sna_tiling_composite_done(struct sna *sna, { struct sna_tile_state *tile = op->u.priv; struct sna_composite_op tmp; - int x, y, n, step = sna->render.max_3d_size; + int x, y, n, step; + + step = sna->render.max_3d_size; + while (step * step * 4 > sna->kgem.max_tile_size) + step /= 2; DBG(("%s -- %dx%d, count=%d\n", __FUNCTION__, tile->width, tile->height, tile->rect_count)); @@ -318,21 +322,26 @@ sna_tiling_fill_boxes(struct sna *sna, { RegionRec region, tile, this; struct kgem_bo *bo; + int step; Bool ret = FALSE; pixman_region_init_rects(®ion, box, n); + step = sna->render.max_3d_size; + while (step * step * 4 > sna->kgem.max_tile_size) + step /= 2; + DBG(("%s (op=%d, format=%x, color=(%04x,%04x,%04x, %04x), tile.size=%d, box=%dx[(%d, %d), (%d, %d)])\n", __FUNCTION__, op, (int)format, color->red, color->green, color->blue, color->alpha, - sna->render.max_3d_size, n, + step, n, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); for (tile.extents.y1 = tile.extents.y2 = region.extents.y1; tile.extents.y2 < region.extents.y2; tile.extents.y1 = tile.extents.y2) { - tile.extents.y2 = tile.extents.y1 + sna->render.max_3d_size; + tile.extents.y2 = tile.extents.y1 + step; if (tile.extents.y2 > region.extents.y2) tile.extents.y2 = region.extents.y2; @@ -341,7 +350,7 @@ sna_tiling_fill_boxes(struct sna *sna, tile.extents.x1 = tile.extents.x2) { PixmapRec tmp; - tile.extents.x2 = tile.extents.x1 + sna->render.max_3d_size; + tile.extents.x2 = tile.extents.x1 + step; if (tile.extents.x2 > region.extents.x2) tile.extents.x2 = region.extents.x2; |