xf86-video-intel: 3 commits - src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_dri2.c src/sna/sna_driver.c src/sna/sna.h src/sna/sna_present.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Jul 1 09:00:56 PDT 2014
src/sna/sna.h | 6 -
src/sna/sna_accel.c | 156 +++++++++++++++++---------------------------------
src/sna/sna_display.c | 5 +
src/sna/sna_dri2.c | 84 +++++++++++++++++++++-----
src/sna/sna_driver.c | 18 -----
src/sna/sna_present.c | 10 ++-
6 files changed, 138 insertions(+), 141 deletions(-)
New commits:
commit b88866aa5ebf813a999e194dec24e9ef2ac4f59d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jul 1 16:59:31 2014 +0100
sna/dri2: Add a DBG option to select copy method
Often when debugging it is useful to force either use of the BLT or 3D
pipelines for copies.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 5adbd0b..0b343ce 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -55,6 +55,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DBG_CAN_FLIP 1
#define DBG_CAN_XCHG 1
+#define DBG_FORCE_COPY -1 /* KGEM_BLT or KGEM_3D */
+
#if DRI2INFOREC_VERSION < 2
#error DRI2 version supported by the Xserver is too old
#endif
@@ -772,6 +774,12 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg
return;
}
+ if (DBG_FORCE_COPY != -1) {
+ DBG(("%s: forcing %d\n", __FUNCTION__, DBG_FORCE_COPY));
+ kgem_set_mode(&sna->kgem, DBG_FORCE_COPY, dst);
+ return;
+ }
+
if (sna->kgem.mode != KGEM_NONE) {
DBG(("%s: busy, not switching\n", __FUNCTION__));
return;
commit a10781b70f222f3997928fa979f6292617f79316
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jul 1 15:11:07 2014 +0100
sna: Enforce LinearFramebuffer option
This option should only be used for compatibility. Previously this was
done at a high level, this changes it to enforce the tiling as we apply
the CRTC.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 7b89f8c..68a6500 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -254,6 +254,7 @@ struct sna {
#define SNA_REMOVE_OUTPUTS 0x400
#define SNA_HAS_FLIP 0x10000
#define SNA_HAS_ASYNC_FLIP 0x20000
+#define SNA_LINEAR_FB 0x40000
#define SNA_REPROBE 0x80000000
unsigned cpu_features;
@@ -360,11 +361,6 @@ struct sna {
int num_adaptors;
} xv;
- unsigned int tiling;
-#define SNA_TILING_FB 0x1
-#define SNA_TILING_2D 0x2
-#define SNA_TILING_ALL (~0)
-
EntityInfoPtr pEnt;
const struct intel_device_info *info;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 324107f..02e5920 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -607,12 +607,13 @@ static bool sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv, bool a
return true;
}
-static inline uint32_t default_tiling(PixmapPtr pixmap,
- uint32_t tiling)
+static inline uint32_t default_tiling(struct sna *sna, PixmapPtr pixmap)
{
- struct sna_pixmap *priv = sna_pixmap(pixmap);
- struct sna *sna = to_sna_from_pixmap(pixmap);
-
+#if DEFAULT_TILING == I915_TILING_NONE
+ return I915_TILING_NONE;
+#elif DEFAULT_TILING == I915_TILING_X
+ return I915_TILING_X;
+#else
/* Try to avoid hitting the Y-tiling GTT mapping bug on 855GM */
if (sna->kgem.gen == 021)
return I915_TILING_X;
@@ -626,41 +627,26 @@ static inline uint32_t default_tiling(PixmapPtr pixmap,
pixmap->drawable.height > sna->render.max_3d_size))
return I915_TILING_X;
- if (tiling == I915_TILING_Y &&
- sna_damage_is_all(&priv->cpu_damage,
+ if (sna_damage_is_all(&sna_pixmap(pixmap)->cpu_damage,
pixmap->drawable.width,
pixmap->drawable.height)) {
DBG(("%s: entire source is damaged, using Y-tiling\n",
__FUNCTION__));
- sna_damage_destroy(&priv->gpu_damage);
-
+ sna_damage_destroy(&sna_pixmap(priv)->gpu_damage);
return I915_TILING_Y;
}
- return tiling;
+ return I915_TILING_Y;
+#endif
}
-pure static uint32_t sna_pixmap_choose_tiling(PixmapPtr pixmap,
- uint32_t tiling)
+pure static uint32_t sna_pixmap_default_tiling(struct sna *sna, PixmapPtr pixmap)
{
- struct sna *sna = to_sna_from_pixmap(pixmap);
- uint32_t bit;
-
- /* Use tiling by default, but disable per user request */
- if (pixmap->usage_hint == SNA_CREATE_FB) {
- tiling = -I915_TILING_X;
- bit = SNA_TILING_FB;
- } else {
- tiling = default_tiling(pixmap, tiling);
- bit = SNA_TILING_2D;
- }
- if ((sna->tiling & bit) == 0)
- tiling = I915_TILING_NONE;
-
/* Also adjust tiling if it is not supported or likely to
* slow us down,
*/
- return kgem_choose_tiling(&sna->kgem, tiling,
+ return kgem_choose_tiling(&sna->kgem,
+ default_tiling(sna, pixmap),
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.bitsPerPixel);
@@ -1617,6 +1603,28 @@ static inline bool pixmap_inplace(struct sna *sna,
sna->kgem.half_cpu_cache_pages;
}
+static bool sna_pixmap_alloc_gpu(struct sna *sna,
+ PixmapPtr pixmap,
+ struct sna_pixmap *priv,
+ unsigned flags)
+{
+ uint32_t tiling;
+
+ /* Use tiling by default, but disable per user request */
+ if (pixmap->usage_hint == SNA_CREATE_FB && (sna->flags & SNA_LINEAR_FB) == 0) {
+ flags |= CREATE_SCANOUT;
+ tiling = -I915_TILING_X;
+ } else
+ tiling = sna_pixmap_default_tiling(sna, pixmap),
+
+ priv->gpu_bo = kgem_create_2d(&sna->kgem,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ pixmap->drawable.bitsPerPixel,
+ tiling, flags);
+ return priv->gpu_bo != NULL;
+}
+
static bool
sna_pixmap_create_mappable_gpu(PixmapPtr pixmap,
bool can_replace)
@@ -1643,22 +1651,9 @@ sna_pixmap_create_mappable_gpu(PixmapPtr pixmap,
}
if (priv->gpu_bo == NULL) {
- unsigned create;
-
assert_pixmap_damage(pixmap);
assert(priv->gpu_damage == NULL);
-
- create = CREATE_GTT_MAP | CREATE_INACTIVE;
- if (pixmap->usage_hint == SNA_CREATE_FB)
- create |= CREATE_SCANOUT;
-
- priv->gpu_bo =
- kgem_create_2d(&sna->kgem,
- pixmap->drawable.width,
- pixmap->drawable.height,
- pixmap->drawable.bitsPerPixel,
- sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING),
- create);
+ sna_pixmap_alloc_gpu(sna, pixmap, priv, CREATE_GTT_MAP | CREATE_INACTIVE);
}
out:
@@ -1874,7 +1869,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags)
bo = kgem_create_2d(&sna->kgem,
box.x2, box.y2,
pixmap->drawable.bitsPerPixel,
- sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING),
+ sna_pixmap_default_tiling(sna, pixmap),
0);
if (bo == NULL) {
cow->refcnt++;
@@ -1923,7 +1918,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags)
bo = kgem_create_2d(&sna->kgem,
box.x2, box.y2,
pixmap->drawable.bitsPerPixel,
- sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING),
+ sna_pixmap_default_tiling(sna, pixmap),
0);
if (bo == NULL) {
cow->refcnt++;
@@ -2601,8 +2596,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
RegionTranslate(region, dx, dy);
if (sna->kgem.has_llc && !priv->pinned &&
- sna_pixmap_choose_tiling(pixmap,
- DEFAULT_TILING) == I915_TILING_NONE) {
+ sna_pixmap_default_tiling(sna, pixmap) == I915_TILING_NONE) {
#ifdef DEBUG_MEMORY
sna->debug_memory.cpu_bo_allocs--;
sna->debug_memory.cpu_bo_bytes -= kgem_bo_size(priv->cpu_bo);
@@ -3313,24 +3307,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
if (priv->gpu_bo == NULL) {
assert(priv->gpu_damage == NULL);
- if (flags & __MOVE_FORCE ||
- priv->create & KGEM_CAN_CREATE_GPU) {
- unsigned create, tiling;
-
- create = CREATE_INACTIVE;
- if (pixmap->usage_hint == SNA_CREATE_FB)
- create |= CREATE_SCANOUT;
-
- tiling = (flags & MOVE_SOURCE_HINT) ? I915_TILING_Y : DEFAULT_TILING;
- tiling = sna_pixmap_choose_tiling(pixmap, tiling);
-
- assert(!priv->mapped);
- priv->gpu_bo = kgem_create_2d(&sna->kgem,
- pixmap->drawable.width,
- pixmap->drawable.height,
- pixmap->drawable.bitsPerPixel,
- tiling, create);
- }
+ if (flags & __MOVE_FORCE || priv->create & KGEM_CAN_CREATE_GPU)
+ sna_pixmap_alloc_gpu(sna, pixmap, priv, CREATE_INACTIVE);
if (priv->gpu_bo == NULL)
return NULL;
@@ -4127,16 +4105,13 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
priv->create));
assert(!priv->mapped);
if (flags & __MOVE_FORCE || priv->create & KGEM_CAN_CREATE_GPU) {
- unsigned create, tiling;
+ unsigned create;
assert(pixmap->drawable.width > 0);
assert(pixmap->drawable.height > 0);
assert(pixmap->drawable.bitsPerPixel >= 8);
- tiling = (flags & MOVE_SOURCE_HINT) ? I915_TILING_Y : DEFAULT_TILING;
- tiling = sna_pixmap_choose_tiling(pixmap, tiling);
-
- if (tiling == I915_TILING_NONE &&
+ if (sna_pixmap_default_tiling(sna, pixmap) == I915_TILING_NONE &&
priv->cpu_bo && !priv->shm &&
kgem_bo_convert_to_gpu(&sna->kgem, priv->cpu_bo, flags)) {
assert(!priv->mapped);
@@ -4157,15 +4132,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
create = 0;
if (flags & MOVE_INPLACE_HINT || (priv->cpu_damage && priv->cpu_bo == NULL))
create = CREATE_GTT_MAP | CREATE_INACTIVE;
- if (pixmap->usage_hint == SNA_CREATE_FB)
- create |= CREATE_SCANOUT;
- priv->gpu_bo =
- kgem_create_2d(&sna->kgem,
- pixmap->drawable.width,
- pixmap->drawable.height,
- pixmap->drawable.bitsPerPixel,
- tiling, create);
+ sna_pixmap_alloc_gpu(sna, pixmap, priv, create);
}
if (priv->gpu_bo == NULL) {
DBG(("%s: not creating GPU bo\n", __FUNCTION__));
@@ -4510,58 +4478,45 @@ static inline void box32_add_rect(Box32Rec *box, const xRectangle *r)
}
static bool
-can_create_upload_tiled_x(struct kgem *kgem,
+can_create_upload_tiled_x(struct sna *sna,
PixmapPtr pixmap,
struct sna_pixmap *priv,
bool replaces)
{
- unsigned tiling;
-
if (priv->shm || (priv->cpu && !replaces))
return false;
if ((priv->create & KGEM_CAN_CREATE_GPU) == 0)
return false;
- if (kgem->has_llc)
+ if (sna->kgem.has_llc)
return true;
- tiling = sna_pixmap_choose_tiling(pixmap, I915_TILING_X);
- assert(tiling != I915_TILING_Y && tiling != -I915_TILING_Y);
- if (tiling != I915_TILING_NONE)
+ if (sna_pixmap_default_tiling(sna, pixmap))
return false;
return true;
}
static bool
-create_upload_tiled_x(struct kgem *kgem,
+create_upload_tiled_x(struct sna *sna,
PixmapPtr pixmap,
struct sna_pixmap *priv,
bool replaces)
{
unsigned create;
- if (!can_create_upload_tiled_x(kgem, pixmap, priv, replaces))
+ if (!can_create_upload_tiled_x(sna, pixmap, priv, replaces))
return false;
assert(priv->gpu_bo == NULL);
assert(priv->gpu_damage == NULL);
create = CREATE_CPU_MAP | CREATE_INACTIVE;
- if (pixmap->usage_hint == SNA_CREATE_FB)
- create |= CREATE_SCANOUT;
- if (!kgem->has_llc)
+ if (!sna->kgem.has_llc)
create |= CREATE_CACHED;
- priv->gpu_bo =
- kgem_create_2d(kgem,
- pixmap->drawable.width,
- pixmap->drawable.height,
- pixmap->drawable.bitsPerPixel,
- sna_pixmap_choose_tiling(pixmap, I915_TILING_X),
- create);
- return priv->gpu_bo != NULL;
+ return sna_pixmap_alloc_gpu(sna, pixmap, priv, create);
}
static bool
@@ -4714,7 +4669,7 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region,
if (priv->gpu_bo && replaces) {
if (UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
- if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, true) &&
+ if (can_create_upload_tiled_x(sna, pixmap, priv, true) &&
(priv->cow ||
__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) ||
!kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) {
@@ -4737,7 +4692,7 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region,
if (priv->gpu_damage &&
region_subsumes_damage(region, priv->gpu_damage)) {
if (UNDO) kgem_bo_undo(&sna->kgem, priv->gpu_bo);
- if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, priv->cpu_damage == NULL) &&
+ if (can_create_upload_tiled_x(sna, pixmap, priv, priv->cpu_damage == NULL) &&
(__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) ||
!kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) {
DBG(("%s: discarding unusable partial target bo (busy? %d, mappable? %d)\n", __FUNCTION__,
@@ -4751,7 +4706,7 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region,
}
if (priv->gpu_bo == NULL &&
- !create_upload_tiled_x(&sna->kgem, pixmap, priv, ignore_cpu))
+ !create_upload_tiled_x(sna, pixmap, priv, ignore_cpu))
return false;
DBG(("%s: tiling=%d\n", __FUNCTION__, priv->gpu_bo->tiling));
@@ -5624,8 +5579,7 @@ move_to_gpu(PixmapPtr pixmap, struct sna_pixmap *priv,
if (priv->cpu_bo->flush && count > SOURCE_BIAS)
return true;
- if (sna_pixmap_choose_tiling(pixmap,
- DEFAULT_TILING) == I915_TILING_NONE)
+ if (sna_pixmap_default_tiling(to_sna_from_pixmap(pixmap), pixmap) == I915_TILING_NONE)
return false;
if (priv->cpu)
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 38ebc11..5579585 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1666,6 +1666,9 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
if (priv->gpu_bo->pitch > pitch_limit)
return true;
+ if (priv->gpu_bo->tiling && sna->flags & SNA_LINEAR_FB)
+ return true;
+
transform = NULL;
if (crtc->transformPresent)
transform = &crtc->transform;
@@ -1779,6 +1782,8 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
tiled_limit = 8 * 1024 * 8;
if ((unsigned long)crtc->mode.HDisplay * scrn->bitsPerPixel > tiled_limit)
tiling = I915_TILING_NONE;
+ if (sna->flags & SNA_LINEAR_FB)
+ tiling = I915_TILING_NONE;
bo = kgem_create_2d(&sna->kgem,
crtc->mode.HDisplay, crtc->mode.VDisplay,
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 9b128da..5adbd0b 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -459,7 +459,7 @@ sna_dri2_create_buffer(DrawablePtr draw,
bo = ref(bo);
bpp = pixmap->drawable.bitsPerPixel;
- if (pixmap == sna->front)
+ if (pixmap == sna->front && !(sna->flags & SNA_LINEAR_FB))
flags |= CREATE_SCANOUT;
DBG(("%s: attaching to front buffer %dx%d [%p:%d], scanout? %d\n",
__FUNCTION__,
@@ -474,7 +474,7 @@ sna_dri2_create_buffer(DrawablePtr draw,
flags |= CREATE_SCANOUT;
if (draw->width == sna->front->drawable.width &&
draw->height == sna->front->drawable.height &&
- (sna->flags & (SNA_NO_WAIT | SNA_NO_FLIP)) == 0)
+ (sna->flags & (SNA_LINEAR_FB | SNA_NO_WAIT | SNA_NO_FLIP)) == 0)
flags |= CREATE_SCANOUT;
}
case DRI2BufferBackRight:
@@ -1644,11 +1644,12 @@ can_flip(struct sna * sna,
}
/* prevent an implicit tiling mode change */
- if (get_private(front)->bo->tiling != get_private(back)->bo->tiling) {
- DBG(("%s -- no, tiling mismatch: front %d, back=%d\n",
+ if (get_private(back)->bo->tiling > I915_TILING_X) {
+ DBG(("%s -- no, tiling mismatch: front %d, back=%d, want-tiled?=%d\n",
__FUNCTION__,
get_private(front)->bo->tiling,
- get_private(back)->bo->tiling));
+ get_private(back)->bo->tiling,
+ !!(sna->flags & SNA_LINEAR_FB)));
return false;
}
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index c57832b..ce319d2 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -614,22 +614,8 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
sna->kgem.wedged = true;
}
- /* Enable tiling by default */
- sna->tiling = SNA_TILING_ALL;
-
- /* Allow user override if they set a value */
- if (!xf86ReturnOptValBool(sna->Options, OPTION_TILING_2D, TRUE))
- sna->tiling &= ~SNA_TILING_2D;
if (xf86ReturnOptValBool(sna->Options, OPTION_TILING_FB, FALSE))
- sna->tiling &= ~SNA_TILING_FB;
-
- if (sna->tiling != SNA_TILING_ALL) {
- xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Framebuffer %s, pixmaps %s\n",
- sna->tiling & SNA_TILING_FB ? "tiled" : "linear",
- sna->tiling & SNA_TILING_2D ? "tiled" : "linear");
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "Tiling disabled, expect poor performance and increased power consumption.\n");
- }
+ sna->flags |= SNA_LINEAR_FB;
if (xf86ReturnOptValBool(sna->Options, OPTION_DELETE_DP12, FALSE))
sna->flags |= SNA_REMOVE_OUTPUTS;
@@ -665,7 +651,7 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
}
scrn->currentMode = scrn->modes;
- if (sna->flags & SNA_HAS_FLIP &&
+ if ((sna->flags & (SNA_HAS_FLIP | SNA_LINEAR_FB)) == SNA_HAS_FLIP &&
xf86ReturnOptValBool(sna->Options, OPTION_TEAR_FREE, enable_tear_free(sna)))
sna->flags |= SNA_TEAR_FREE;
xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "TearFree %sabled\n",
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 5379d1e..dd4771c 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -351,6 +351,7 @@ page_flip(ScreenPtr screen,
static struct kgem_bo *
get_flip_bo(PixmapPtr pixmap)
{
+ struct sna *sna = to_sna_from_pixmap(pixmap);
struct sna_pixmap *priv;
DBG(("%s(pixmap=%ld)\n", __FUNCTION__, pixmap->drawable.serialNumber));
@@ -361,9 +362,16 @@ get_flip_bo(PixmapPtr pixmap)
return NULL;
}
+ if (sna->flags & SNA_LINEAR_FB &&
+ priv->gpu_bo->tiling &&
+ !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) {
+ DBG(("%s: invalid tiling for scanout, user requires linear\n", __FUNCTION__));
+ return NULL;
+ }
+
if (priv->gpu_bo->tiling == I915_TILING_Y &&
!sna_pixmap_change_tiling(pixmap, I915_TILING_X)) {
- DBG(("%s: bad tiling, cannot convert\n", __FUNCTION__));
+ DBG(("%s: invalid Y-tiling, cannot convert\n", __FUNCTION__));
return NULL;
}
commit 75745cd5861481c5a9a31125d357f339349dd0f8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jul 1 14:31:32 2014 +0100
sna/dri2: Use CPU fallback if possible
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index b03bf6a..9b128da 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -820,24 +820,64 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg
_kgem_set_mode(&sna->kgem, mode);
}
+static bool can_copy_cpu(struct sna *sna,
+ struct kgem_bo *src,
+ struct kgem_bo *dst)
+{
+ if (src->tiling != dst->tiling)
+ return false;
+
+ if (src->pitch != dst->pitch)
+ return false;
+
+ if (!kgem_bo_can_map__cpu(&sna->kgem, src, false))
+ return false;
+
+ if (!kgem_bo_can_map__cpu(&sna->kgem, dst, true))
+ return false;
+
+ DBG(("%s -- yes, src handle=%d, dst handle=%d\n", __FUNCTION__, src->handle, dst->handle));
+ return true;
+}
+
static void
-sna_dri2_copy_fallback(struct sna *sna, int bpp,
+sna_dri2_copy_fallback(struct sna *sna,
+ const DrawableRec *draw,
struct kgem_bo *src_bo, int sx, int sy,
struct kgem_bo *dst_bo, int dx, int dy,
const BoxRec *box, int n)
{
- void *dst = kgem_bo_map__gtt(&sna->kgem, dst_bo);
- void *src = kgem_bo_map__gtt(&sna->kgem, src_bo);
+ void *dst, *src;
+ bool clipped;
- if (dst == NULL || src == NULL)
- return;
+ clipped = (n > 1 ||
+ box->x1 + sx > 0 ||
+ box->y1 + sy > 0 ||
+ box->x2 + sx < draw->width ||
+ box->y2 + sy < draw->height);
+
+ dst = src = NULL;
+ if (!clipped && can_copy_cpu(sna, src_bo, dst_bo)) {
+ dst = kgem_bo_map__cpu(&sna->kgem, dst_bo);
+ src = kgem_bo_map__cpu(&sna->kgem, src_bo);
+ }
+
+ if (dst == NULL || src == NULL) {
+ dst = kgem_bo_map__gtt(&sna->kgem, dst_bo);
+ src = kgem_bo_map__gtt(&sna->kgem, src_bo);
+ if (dst == NULL || src == NULL)
+ return;
+ } else {
+ kgem_bo_sync__cpu_full(&sna->kgem, dst_bo, true);
+ kgem_bo_sync__cpu_full(&sna->kgem, src_bo, false);
+ }
DBG(("%s: src(%d, %d), dst(%d, %d) x %d\n",
__FUNCTION__, sx, sy, dx, dy, n));
if (sigtrap_get() == 0) {
do {
- memcpy_blt(src, dst, bpp,
+ memcpy_blt(src, dst, draw->bitsPerPixel,
src_bo->pitch, dst_bo->pitch,
box->x1 + sx, box->y1 + sy,
box->x1 + dx, box->y1 + dy,
@@ -945,6 +985,11 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
} else
sync = false;
+ scratch.x = scratch.y = 0;
+ scratch.width = scratch.height = 0;
+ scratch.depth = draw->depth;
+ scratch.bitsPerPixel = draw->bitsPerPixel;
+
src_bo = src_priv->bo;
assert(src_bo->refcnt);
if (is_front(src->attachment)) {
@@ -959,11 +1004,8 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
} else {
RegionRec source;
- scratch.x = scratch.y = 0;
scratch.width = src_priv->size & 0xffff;
scratch.height = src_priv->size >> 16;
- scratch.depth = draw->depth;
- scratch.bitsPerPixel = draw->bitsPerPixel;
src_draw = &scratch;
DBG(("%s: source size %dx%d, region size %dx%d\n",
@@ -1005,11 +1047,8 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
} else {
RegionRec target;
- scratch.x = scratch.y = 0;
scratch.width = dst_priv->size & 0xffff;
scratch.height = dst_priv->size >> 16;
- scratch.depth = draw->depth;
- scratch.bitsPerPixel = draw->bitsPerPixel;
dst_draw = &scratch;
DBG(("%s: target size %dx%d, region size %dx%d\n",
@@ -1056,7 +1095,7 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
if (wedged(sna)) {
fallback:
- sna_dri2_copy_fallback(sna, draw->bitsPerPixel,
+ sna_dri2_copy_fallback(sna, src_draw,
src_bo, sx, sy,
dst_bo, dx, dy,
boxes, n);
More information about the xorg-commit
mailing list