summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2013-04-02 17:21:25 -0700
committerEric Anholt <[email protected]>2013-04-08 11:49:25 -0700
commitdfed1150904ce8455126574a3dd5439de541726c (patch)
tree7e9e726166558f44f8c6e82df17c14e395e17ae7 /src/mesa
parentb3a3cb96113f732d387141c7e120f92cba2cdd69 (diff)
intel: Do temporary CPU maps of textures that are too big to GTT map.
This still fails, since 8192*4bpp == 32768, which is too big to use the blitter on. Reviewed-by: Kenneth Graunke <[email protected]> Reviewed-by: Daniel Vetter <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index ffdaec5945c..5e0cd6140cb 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -1703,6 +1703,23 @@ intel_miptree_map_singlesample(struct intel_context *intel,
{
struct intel_miptree_map *map;
+ /* Estimate the size of the mappable aperture into the GTT. There's an
+ * ioctl to get the whole GTT size, but not one to get the mappable subset.
+ * It turns out it's basically always 256MB, though some ancient hardware
+ * was smaller.
+ */
+ uint32_t gtt_size = 256 * 1024 * 1024;
+ if (intel->gen == 2)
+ gtt_size = 128 * 1024 * 1024;
+
+ /* We don't want to map two objects such that a memcpy between them would
+ * just fault one mapping in and then the other over and over forever. So
+ * we would need to divide the GTT size by 2. Additionally, some GTT is
+ * taken up by things like the framebuffer and the ringbuffer and such, so
+ * be more conservative.
+ */
+ uint32_t max_gtt_map_object_size = gtt_size / 4;
+
assert(mt->num_samples <= 1);
map = intel_miptree_attach_map(mt, level, slice, x, y, w, h, mode);
@@ -1749,6 +1766,10 @@ intel_miptree_map_singlesample(struct intel_context *intel,
mt->region->tiling == I915_TILING_X &&
mt->region->pitch < 32768) {
intel_miptree_map_blit(intel, mt, map, level, slice);
+ } else if (mt->region->tiling != I915_TILING_NONE &&
+ mt->region->bo->size >= max_gtt_map_object_size) {
+ assert(mt->region->pitch < 32768);
+ intel_miptree_map_blit(intel, mt, map, level, slice);
} else {
intel_miptree_map_gtt(intel, mt, map, level, slice);
}