sna: Improve handling of inplace IO for large transfers

If the transfer is large enough to obliterate the caches, then it is
preferrable to do it inplace rather than upload a proxy texture and
queue a blit. This helps prevent an inconsistency where one layer
believes the operation should be done inplace only for the IO layer to
perform an indirect upload.

Testing show no significant impact upon the cairo-traces, but it does
prevent x11perf -shmput from exploding.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2012-05-03 11:27:44 +01:00
parent 53568e8e49
commit fcccc5528b
2 changed files with 7 additions and 6 deletions

View File

@ -462,7 +462,7 @@ static inline bool kgem_bo_map_will_stall(struct kgem *kgem, struct kgem_bo *bo)
__FUNCTION__, bo->handle,
bo->domain, bo->presumed_offset, bo->size));
if (!kgem_bo_is_mappable(kgem, bo))
if (!kgem_bo_is_mappable(kgem, bo) && kgem_bo_is_busy(bo))
return true;
if (kgem->wedged)

View File

@ -516,17 +516,16 @@ static bool upload_inplace(struct kgem *kgem,
* able to almagamate a series of small writes into a single
* operation.
*/
if (!bo->map) {
if (!bo->map || kgem_bo_map_will_stall(kgem, bo)) {
unsigned int bytes = 0;
while (n--) {
bytes += (box->x2 - box->x1) * (box->y2 - box->y1);
box++;
}
if (bytes * bpp >> 12 < kgem->half_cpu_cache_pages)
return false;
return bytes * bpp >> 12 >= kgem->half_cpu_cache_pages;
}
return !kgem_bo_map_will_stall(kgem, bo);
return true;
}
bool sna_write_boxes(struct sna *sna, PixmapPtr dst,
@ -570,7 +569,9 @@ fallback:
}
/* Try to avoid switching rings... */
if (!can_blt || kgem->ring == KGEM_RENDER ||
if (!can_blt ||
kgem->ring == KGEM_RENDER ||
(kgem->has_semaphores && kgem->mode == KGEM_NONE) ||
upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) {
PixmapRec tmp;