diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-02-08 09:13:27 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-02-08 09:30:12 +0000 |
commit | 8634d461bd9e5a3d3f75b0efc11db87b8d3e1245 (patch) | |
tree | 9e4b84883373d5d5bbf05db6a0b03f4d50318238 /src/sna | |
parent | 5b16972d7850b2347efc084311d664e14263cba1 (diff) |
sna: Limit max CPU bo size to prevent aperture thrashing on upload
Copying between two objects that consume more than the available GATT
space is a painful experience due to the forced use of an intermediatory
and eviction on every batch. The tiled upload paths are in comparison
remarkably efficient, so favour their use when handling extremely large
buffers.
This reverses the previous idea in that we now prefer large GPU bo
rather than large CPU bo, as the render pipeline is far more flexible
for handling those than the blitter is for handling the CPU bo (at least
for gen4+).
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/kgem.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 94b6c184..1c233204 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -575,6 +575,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen) { struct drm_i915_gem_get_aperture aperture; size_t totalram; + unsigned half_gpu_max; unsigned int i, j; memset(kgem, 0, sizeof(*kgem)); @@ -679,7 +680,6 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen) kgem->min_alignment = 64; kgem->max_object_size = 2 * kgem->aperture_total / 3; - kgem->max_cpu_size = kgem->max_object_size; kgem->max_gpu_size = kgem->max_object_size; if (!kgem->has_llc) kgem->max_gpu_size = MAX_CACHE_SIZE; @@ -691,16 +691,6 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen) if (kgem->max_gpu_size > kgem->aperture_low) kgem->max_gpu_size = kgem->aperture_low; } - if (kgem->max_gpu_size > kgem->max_cpu_size) - kgem->max_gpu_size = kgem->max_cpu_size; - - kgem->max_upload_tile_size = kgem->aperture_mappable / 2; - if (kgem->max_upload_tile_size > kgem->max_gpu_size / 2) - kgem->max_upload_tile_size = kgem->max_gpu_size / 2; - - kgem->max_copy_tile_size = (MAX_CACHE_SIZE + 1)/2; - if (kgem->max_copy_tile_size > kgem->max_gpu_size / 2) - kgem->max_copy_tile_size = kgem->max_gpu_size / 2; totalram = total_ram_size(); if (totalram == 0) { @@ -708,14 +698,32 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen) __FUNCTION__)); totalram = kgem->aperture_total; } + DBG(("%s: total ram=%ld\n", __FUNCTION__, (long)totalram)); if (kgem->max_object_size > totalram / 2) kgem->max_object_size = totalram / 2; - if (kgem->max_cpu_size > totalram / 2) - kgem->max_cpu_size = totalram / 2; if (kgem->max_gpu_size > totalram / 4) kgem->max_gpu_size = totalram / 4; + half_gpu_max = kgem->max_gpu_size / 2; + if (kgem->gen >= 40) + kgem->max_cpu_size = half_gpu_max; + else + kgem->max_cpu_size = kgem->max_object_size; + + kgem->max_copy_tile_size = (MAX_CACHE_SIZE + 1)/2; + if (kgem->max_copy_tile_size > half_gpu_max) + kgem->max_copy_tile_size = half_gpu_max; + + if (kgem->has_llc) + kgem->max_upload_tile_size = kgem->max_copy_tile_size; + else + kgem->max_upload_tile_size = kgem->aperture_mappable / 4; + if (kgem->max_upload_tile_size > half_gpu_max) + kgem->max_upload_tile_size = half_gpu_max; + kgem->large_object_size = MAX_CACHE_SIZE; + if (kgem->large_object_size > kgem->max_cpu_size) + kgem->large_object_size = kgem->max_cpu_size; if (kgem->large_object_size > kgem->max_gpu_size) kgem->large_object_size = kgem->max_gpu_size; |