sna: Force remapping for IO transfer

Should fix regression from fcccc5528 (sna: Improve handling of inplace
IO for large transfers) whereby it was aborting the transfer it we need
to remap the buffer for the upload.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=49546
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2012-05-08 15:47:14 +01:00
parent 2a9a93e448
commit a3d37fb29f
3 changed files with 25 additions and 33 deletions

View File

@ -452,6 +452,18 @@ static inline bool kgem_bo_mapped(struct kgem_bo *bo)
return IS_CPU_MAP(bo->map) == !bo->tiling;
}
static inline bool kgem_bo_can_map(struct kgem *kgem, struct kgem_bo *bo)
{
if (kgem_bo_mapped(bo))
return true;
if (!bo->tiling && kgem->has_llc)
return true;
return kgem_bo_size(bo) <= kgem->aperture_mappable / 4;
}
static inline bool kgem_bo_is_busy(struct kgem_bo *bo)
{
DBG_HDR(("%s: domain: %d exec? %d, rq? %d\n",
@ -459,27 +471,6 @@ static inline bool kgem_bo_is_busy(struct kgem_bo *bo)
return bo->rq;
}
static inline bool kgem_bo_map_will_stall(struct kgem *kgem, struct kgem_bo *bo)
{
DBG(("%s? handle=%d, domain=%d, offset=%x, size=%x\n",
__FUNCTION__, bo->handle,
bo->domain, bo->presumed_offset, bo->size));
if (!kgem_bo_is_mappable(kgem, bo) && kgem_bo_is_busy(bo))
return true;
if (kgem->wedged)
return false;
if (kgem_bo_is_busy(bo))
return true;
if (bo->presumed_offset == 0)
return !list_is_empty(&kgem->requests);
return false;
}
static inline bool kgem_bo_is_dirty(struct kgem_bo *bo)
{
if (bo == NULL)

View File

@ -981,8 +981,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
priv->gpu_bo->exec == NULL)
kgem_retire(&sna->kgem);
if (kgem_bo_map_will_stall(&sna->kgem,
priv->gpu_bo)) {
if (kgem_bo_is_busy(priv->gpu_bo)) {
if (priv->pinned)
goto skip_inplace_map;
@ -1049,7 +1048,7 @@ skip_inplace_map:
if (flags & MOVE_INPLACE_HINT &&
priv->stride && priv->gpu_bo &&
!kgem_bo_map_will_stall(&sna->kgem, priv->gpu_bo) &&
!kgem_bo_is_busy(priv->gpu_bo) &&
pixmap_inplace(sna, pixmap, priv) &&
sna_pixmap_move_to_gpu(pixmap, flags)) {
assert(flags & MOVE_WRITE);
@ -1356,7 +1355,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
priv->gpu_bo->exec == NULL)
kgem_retire(&sna->kgem);
if (!kgem_bo_map_will_stall(&sna->kgem, priv->gpu_bo)) {
if (!kgem_bo_is_busy(priv->gpu_bo)) {
pixmap->devPrivate.ptr =
kgem_bo_map(&sna->kgem, priv->gpu_bo);
if (pixmap->devPrivate.ptr == NULL)
@ -1422,7 +1421,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
if (flags & MOVE_INPLACE_HINT &&
priv->stride && priv->gpu_bo &&
!kgem_bo_map_will_stall(&sna->kgem, priv->gpu_bo) &&
!kgem_bo_is_busy(priv->gpu_bo) &&
region_inplace(sna, pixmap, region, priv) &&
sna_pixmap_move_area_to_gpu(pixmap, &region->extents, flags)) {
assert(flags & MOVE_WRITE);
@ -2733,7 +2732,7 @@ static bool upload_inplace(struct sna *sna,
if (priv->gpu_bo) {
assert(priv->gpu_bo->proxy == NULL);
if (!kgem_bo_map_will_stall(&sna->kgem, priv->gpu_bo))
if (!kgem_bo_is_busy(priv->gpu_bo))
return true;
if (!priv->pinned &&
@ -2795,7 +2794,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
/* And mark as having a valid GTT mapping for future uploads */
if (priv->stride &&
!kgem_bo_map_will_stall(&sna->kgem, priv->gpu_bo)) {
!kgem_bo_is_busy(priv->gpu_bo)) {
pixmap->devPrivate.ptr =
kgem_bo_map(&sna->kgem, priv->gpu_bo);
if (pixmap->devPrivate.ptr) {

View File

@ -116,8 +116,7 @@ static bool download_inplace(struct kgem *kgem, struct kgem_bo *bo)
if (FORCE_INPLACE)
return FORCE_INPLACE > 0;
return !kgem_bo_map_will_stall(kgem, bo) ||
bo->tiling == I915_TILING_NONE;
return !kgem_bo_is_busy(bo) || bo->tiling == I915_TILING_NONE;
}
void sna_read_boxes(struct sna *sna,
@ -480,7 +479,7 @@ static bool write_boxes_inplace(struct kgem *kgem,
DBG(("%s x %d, handle=%d, tiling=%d\n",
__FUNCTION__, n, bo->handle, bo->tiling));
if (!kgem_bo_is_mappable(kgem, bo))
if (!kgem_bo_can_map(kgem, bo))
return false;
kgem_bo_submit(kgem, bo);
@ -525,11 +524,14 @@ static bool upload_inplace(struct kgem *kgem,
if (FORCE_INPLACE)
return FORCE_INPLACE > 0;
if (!kgem_bo_can_map(kgem, bo))
return false;
/* If we are writing through the GTT, check first if we might be
* able to almagamate a series of small writes into a single
* operation.
*/
if (!bo->map || kgem_bo_map_will_stall(kgem, bo)) {
if (!kgem_bo_mapped(bo) || kgem_bo_is_busy(bo)) {
unsigned int bytes = 0;
while (n--) {
bytes += (box->x2 - box->x1) * (box->y2 - box->y1);
@ -1146,7 +1148,7 @@ bool sna_replace(struct sna *sna,
pixmap->drawable.bitsPerPixel,
bo->tiling));
if ((!kgem_bo_mapped(bo) || bo->rq) &&
if ((!kgem_bo_mapped(bo) || kgem_bo_is_busy(bo)) &&
indirect_replace(sna, pixmap, bo, src, stride))
return true;