summaryrefslogtreecommitdiff
path: root/src/sna
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-02-08 09:13:27 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-02-08 09:30:12 +0000
commit8634d461bd9e5a3d3f75b0efc11db87b8d3e1245 (patch)
tree9e4b84883373d5d5bbf05db6a0b03f4d50318238 /src/sna
parent5b16972d7850b2347efc084311d664e14263cba1 (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.c34
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;