summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-07-21 16:08:31 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-07-21 16:30:50 +0100
commitf1e7248cb353d634f27d297059911168ce1a0762 (patch)
tree5f06768cf13a4c363b678ef6f0c55d6a4c421f85
parent06db69c2c7023f702f9773be90144fdf7a1159e4 (diff)
sna: Expand the heuristic for predicting when to use CPU bo for readback
For tiny transfers, the cost of setting up the GPU operation outweighs the actual savings through increased throughput. So we try to guess when it will be preferrable to simply read from the GPU bo directly. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_accel.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 5a9eb1e9..5bec59aa 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1093,12 +1093,31 @@ sna_pixmap_create_mappable_gpu(PixmapPtr pixmap)
}
static inline bool use_cpu_bo_for_download(struct sna *sna,
- struct sna_pixmap *priv)
+ struct sna_pixmap *priv,
+ const BoxRec *box)
{
if (DBG_NO_CPU_DOWNLOAD)
return false;
- return priv->cpu_bo != NULL && sna->kgem.can_blt_cpu;
+ if (priv->cpu_bo == NULL || !sna->kgem.can_blt_cpu)
+ return false;
+
+ if (kgem_bo_is_busy(priv->gpu_bo) || kgem_bo_is_busy(priv->cpu_bo)) {
+ DBG(("%s: yes, either bo is busy, so use GPU for readback\n",
+ __FUNCTION__));
+ return true;
+ }
+
+ /* Is it worth detiling? */
+ if (kgem_bo_is_mappable(&sna->kgem, priv->gpu_bo) &&
+ (box->y2 - box->y1 - 1) * priv->gpu_bo->pitch < 4096) {
+ DBG(("%s: no, tiny transfer, expect to read inplace\n",
+ __FUNCTION__));
+ return false;
+ }
+
+ DBG(("%s: yes, default action\n", __FUNCTION__));
+ return true;
}
static inline bool use_cpu_bo_for_upload(struct sna_pixmap *priv,
@@ -1329,7 +1348,7 @@ skip_inplace_map:
if (n) {
bool ok = false;
- if (use_cpu_bo_for_download(sna, priv)) {
+ if (use_cpu_bo_for_download(sna, priv, &priv->gpu_damage->extents)) {
DBG(("%s: using CPU bo for download from GPU\n", __FUNCTION__));
ok = sna->render.copy_boxes(sna, GXcopy,
pixmap, priv->gpu_bo, 0, 0,
@@ -1794,7 +1813,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
assert(pixmap_contains_damage(pixmap, priv->gpu_damage));
ok = false;
- if (use_cpu_bo_for_download(sna, priv)) {
+ if (use_cpu_bo_for_download(sna, priv, &priv->gpu_damage->extents)) {
DBG(("%s: using CPU bo for download from GPU\n", __FUNCTION__));
ok = sna->render.copy_boxes(sna, GXcopy,
pixmap, priv->gpu_bo, 0, 0,
@@ -1904,7 +1923,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
if (n) {
bool ok = false;
- if (use_cpu_bo_for_download(sna, priv)) {
+ if (use_cpu_bo_for_download(sna, priv, &priv->gpu_damage->extents)) {
DBG(("%s: using CPU bo for download from GPU\n", __FUNCTION__));
ok = sna->render.copy_boxes(sna, GXcopy,
pixmap, priv->gpu_bo, 0, 0,
@@ -1931,7 +1950,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
DBG(("%s: region wholly inside damage\n",
__FUNCTION__));
- if (use_cpu_bo_for_download(sna, priv)) {
+ if (use_cpu_bo_for_download(sna, priv, &r->extents)) {
DBG(("%s: using CPU bo for download from GPU\n", __FUNCTION__));
ok = sna->render.copy_boxes(sna, GXcopy,
pixmap, priv->gpu_bo, 0, 0,
@@ -1958,7 +1977,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
DBG(("%s: region intersects damage\n",
__FUNCTION__));
- if (use_cpu_bo_for_download(sna, priv)) {
+ if (use_cpu_bo_for_download(sna, priv, &need.extents)) {
DBG(("%s: using CPU bo for download from GPU\n", __FUNCTION__));
ok = sna->render.copy_boxes(sna, GXcopy,
pixmap, priv->gpu_bo, 0, 0,