summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-12-24 19:14:09 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-12-24 21:31:06 +0000
commit72217790ee2c080d618274456360b481d015e898 (patch)
tree2b425a8b5b11902f035ddb1cf2368df497532e3a
parent0be136c21f0373d1eb2259b83c598655f4eb841e (diff)
sna: Use shadow if the GPU is busy or not immediately mappable
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c2
-rw-r--r--src/sna/kgem.h15
-rw-r--r--src/sna/sna_accel.c7
-rw-r--r--src/sna/sna_io.c3
4 files changed, 23 insertions, 4 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b8c05faa..ee2b9695 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1848,7 +1848,7 @@ bool kgem_can_create_2d(struct kgem *kgem,
}
#endif
-static int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
+inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
{
unsigned int size;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 42a0ba46..3e69be5b 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -338,6 +338,21 @@ uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo);
Bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
const void *data, int length);
+int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo);
+
+static inline bool kgem_bo_is_mappable(struct kgem *kgem,
+ struct kgem_bo *bo)
+{
+ DBG_HDR(("%s: offset: %d size: %d\n",
+ __FUNCTION__, bo->presumed_offset, bo->size));
+
+ if (kgem->gen < 40 && bo->tiling &&
+ bo->presumed_offset & (kgem_bo_fenced_size(kgem, bo) - 1))
+ return false;
+
+ return bo->presumed_offset + bo->size <= kgem->aperture_mappable;
+}
+
static inline bool kgem_bo_is_busy(struct kgem_bo *bo)
{
DBG_HDR(("%s: domain: %d exec? %d, rq? %d\n",
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 837dacfc..0815bc9e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -814,6 +814,9 @@ static inline bool region_inplace(struct sna *sna,
if (priv->mapped)
return true;
+ if (priv->gpu_bo && !kgem_bo_is_mappable(&sna->kgem, priv->gpu_bo))
+ return false;
+
return ((region->extents.x2 - region->extents.x1) *
(region->extents.y2 - region->extents.y1) *
pixmap->drawable.bitsPerPixel >> 12)
@@ -1747,7 +1750,9 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
* immediately flushed...
*/
if ((priv->flush ||
- (priv->gpu_bo && region_inplace(sna, pixmap, region, priv))) &&
+ (priv->gpu_bo &&
+ region_inplace(sna, pixmap, region, priv) &&
+ !kgem_bo_is_busy(priv->gpu_bo))) &&
sna_put_image_upload_blt(drawable, gc, region,
x, y, w, h, bits, stride)) {
if (region_subsumes_drawable(region, &pixmap->drawable)) {
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 1e4a9fb0..15fe42c1 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -87,8 +87,7 @@ static bool map_will_stall(struct kgem *kgem, struct kgem_bo *bo)
if (kgem_bo_is_busy(bo))
return true;
- if (bo->presumed_offset &&
- bo->presumed_offset + bo->size >= kgem->aperture_mappable)
+ if (!kgem_bo_is_mappable(kgem, bo))
return true;
return false;