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>
This commit is contained in:
Chris Wilson 2012-01-29 18:07:14 +00:00
parent e1e67e8f39
commit df148c9621
4 changed files with 30 additions and 8 deletions

View File

@ -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;
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 (tiled=%d, linear=%d)\n",
__FUNCTION__, kgem->max_gpu_size, kgem->max_cpu_size));
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;

View File

@ -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);

View File

@ -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));

View File

@ -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(&region, 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;