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:
parent
e1e67e8f39
commit
df148c9621
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue