sna: Use shadow if the GPU is busy or not immediately mappable

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2011-12-24 19:14:09 +00:00
parent 0be136c21f
commit 72217790ee
4 changed files with 23 additions and 4 deletions

View File

@ -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;

View File

@ -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",

View File

@ -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)) {

View File

@ -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;