summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-07-02 18:24:40 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-07-04 15:27:40 +0100
commit430c905ef306ece8a4cb19091711a9feae74b00b (patch)
treea3f7514157bd0833483eaff2faf77bb638650e53
parentae567b783e5af53f17f49dbf58b9be17fcb53737 (diff)
sna: Force tiled modes for large pitches
If the surface is so big that the 2x2 texel sampling will cause a TLB miss everytime, i.e. the row pitch exceeeds 4096, then we need to encourage tiling to prevent attrocious performance. For example, try downscaling a 2560x1600 background image on a gen3 device using I915_TILING_NONE... Using slideshow-demo /usr/share/backgrounds/cosmos/whirlpool.jpg, on a PineView netbook, fps goes from under 4 to over 40. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c8
-rw-r--r--src/sna/kgem_debug.c26
-rw-r--r--src/sna/kgem_debug_gen3.c10
3 files changed, 36 insertions, 8 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 6fe6e936..38cf582c 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1156,6 +1156,14 @@ int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int
if (tiling < 0)
return tiling;
+ if (tiling && width * bpp > 8 * 4096) {
+ DBG(("%s: TLB miss between lines %dx%d (pitch=%d), forcing tiling %d\n",
+ __FUNCTION__,
+ width, height, width*bpp/8,
+ tiling));
+ return -tiling;
+ }
+
if (tiling == I915_TILING_Y && height < 16) {
DBG(("%s: too short [%d] for TILING_Y\n",
__FUNCTION__,height));
diff --git a/src/sna/kgem_debug.c b/src/sna/kgem_debug.c
index 20fe8a2e..745c7b90 100644
--- a/src/sna/kgem_debug.c
+++ b/src/sna/kgem_debug.c
@@ -80,6 +80,17 @@ static int kgem_debug_handle_is_fenced(struct kgem *kgem, uint32_t handle)
return 0;
}
+static int kgem_debug_handle_tiling(struct kgem *kgem, uint32_t handle)
+{
+ struct kgem_bo *bo;
+
+ list_for_each_entry(bo, &kgem->next_request->buffers, request)
+ if (bo->handle == handle)
+ return bo->tiling;
+
+ return 0;
+}
+
void
kgem_debug_print(const uint32_t *data,
uint32_t offset, unsigned int index,
@@ -254,11 +265,12 @@ decode_2d(struct kgem *kgem, uint32_t offset)
data[3] & 0xffff, data[3] >> 16);
reloc = kgem_debug_get_reloc_entry(kgem, offset+4);
assert(reloc);
- kgem_debug_print(data, offset, 4, "dst offset 0x%08x [handle=%d, delta=%d, read=%x, write=%x (fenced? %d)]\n",
+ kgem_debug_print(data, offset, 4, "dst offset 0x%08x [handle=%d, delta=%d, read=%x, write=%x (fenced? %d, tiling? %d)]\n",
data[4],
reloc->target_handle, reloc->delta,
reloc->read_domains, reloc->write_domain,
- kgem_debug_handle_is_fenced(kgem, reloc->target_handle));
+ kgem_debug_handle_is_fenced(kgem, reloc->target_handle),
+ kgem_debug_handle_tiling(kgem, reloc->target_handle));
kgem_debug_print(data, offset, 5, "color\n");
return len;
@@ -299,22 +311,24 @@ decode_2d(struct kgem *kgem, uint32_t offset)
data[3] & 0xffff, data[3] >> 16);
reloc = kgem_debug_get_reloc_entry(kgem, offset+4);
assert(reloc);
- kgem_debug_print(data, offset, 4, "dst offset 0x%08x [handle=%d, delta=%d, read=%x, write=%x, (fenced? %d)]\n",
+ kgem_debug_print(data, offset, 4, "dst offset 0x%08x [handle=%d, delta=%d, read=%x, write=%x, (fenced? %d, tiling? %d)]\n",
data[4],
reloc->target_handle, reloc->delta,
reloc->read_domains, reloc->write_domain,
- kgem_debug_handle_is_fenced(kgem, reloc->target_handle));
+ kgem_debug_handle_is_fenced(kgem, reloc->target_handle),
+ kgem_debug_handle_tiling(kgem, reloc->target_handle));
kgem_debug_print(data, offset, 5, "src (%d,%d)\n",
data[5] & 0xffff, data[5] >> 16);
kgem_debug_print(data, offset, 6, "src pitch %d\n",
(short)(data[6] & 0xffff));
reloc = kgem_debug_get_reloc_entry(kgem, offset+7);
assert(reloc);
- kgem_debug_print(data, offset, 7, "src offset 0x%08x [handle=%d, delta=%d, read=%x, write=%x (fenced? %d)]\n",
+ kgem_debug_print(data, offset, 7, "src offset 0x%08x [handle=%d, delta=%d, read=%x, write=%x (fenced? %d, tiling? %d)]\n",
data[7],
reloc->target_handle, reloc->delta,
reloc->read_domains, reloc->write_domain,
- kgem_debug_handle_is_fenced(kgem, reloc->target_handle));
+ kgem_debug_handle_is_fenced(kgem, reloc->target_handle),
+ kgem_debug_handle_tiling(kgem, reloc->target_handle));
return len;
}
diff --git a/src/sna/kgem_debug_gen3.c b/src/sna/kgem_debug_gen3.c
index 6709a8ec..17ddb6bd 100644
--- a/src/sna/kgem_debug_gen3.c
+++ b/src/sna/kgem_debug_gen3.c
@@ -1155,13 +1155,19 @@ gen3_decode_3d_1d(struct kgem *kgem, uint32_t offset)
for (map = 0; map <= 15; map++) {
if (data[1] & (1 << map)) {
int width, height, pitch, dword;
+ struct drm_i915_gem_relocation_entry *reloc;
+ struct kgem_bo *bo = NULL;
const char *tiling;
+ reloc = kgem_debug_get_reloc_entry(kgem, &data[i] - kgem->batch);
+ assert(reloc->target_handle);
+
dword = data[i];
- kgem_debug_print(data, offset, i++, "map %d MS2 %s%s%s\n", map,
+ kgem_debug_print(data, offset, i++, "map %d MS2 %s%s%s, handle=%d\n", map,
dword&(1<<31)?"untrusted surface, ":"",
dword&(1<<1)?"vertical line stride enable, ":"",
- dword&(1<<0)?"vertical ofs enable, ":"");
+ dword&(1<<0)?"vertical ofs enable, ":"",
+ reloc->target_handle);
dword = data[i];
width = ((dword >> 10) & ((1 << 11) - 1))+1;