sna: Trigger fallback after intermediate pixmap allocation failure

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2013-09-26 14:54:18 +01:00
parent bbfbe22954
commit ec9ffc9e41
2 changed files with 40 additions and 19 deletions

View File

@ -1230,6 +1230,7 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
if (wedged(sna))
flags &= ~KGEM_CAN_CREATE_GTT;
DBG(("%s: usage=%d, flags=%x\n", __FUNCTION__, usage, flags));
switch (usage) {
case CREATE_PIXMAP_USAGE_SCRATCH:
if (flags & KGEM_CAN_CREATE_GPU)
@ -3804,6 +3805,9 @@ active:
static bool must_check sna_validate_pixmap(DrawablePtr draw, PixmapPtr pixmap)
{
DBG(("%s: target bpp=%d, source bpp=%d\n",
__FUNCTION__, draw->bitsPerPixel, pixmap->drawable.bitsPerPixel));
if (draw->bitsPerPixel == pixmap->drawable.bitsPerPixel &&
FbEvenTile(pixmap->drawable.width *
pixmap->drawable.bitsPerPixel)) {
@ -3873,9 +3877,11 @@ static bool must_check sna_gc_move_to_cpu(GCPtr gc,
switch (gc->fillStyle) {
case FillTiled:
DBG(("%s: moving tile to cpu\n", __FUNCTION__));
return sna_drawable_move_to_cpu(&gc->tile.pixmap->drawable, MOVE_READ);
case FillStippled:
case FillOpaqueStippled:
DBG(("%s: moving stipple to cpu\n", __FUNCTION__));
return sna_drawable_move_to_cpu(&gc->stipple->drawable, MOVE_READ);
default:
return true;

View File

@ -763,21 +763,27 @@ static int sna_render_picture_downsample(struct sna *sna,
DBG(("%s: creating temporary GPU bo %dx%d\n",
__FUNCTION__, width, height));
if (!sna_pixmap_force_to_gpu(pixmap, MOVE_SOURCE_HINT | MOVE_READ))
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h,
dst_x, dst_y);
tmp = screen->CreatePixmap(screen,
width, height,
pixmap->drawable.depth,
SNA_CREATE_SCRATCH);
if (!tmp)
return 0;
if (tmp == NULL)
goto fixup;
priv = sna_pixmap(tmp);
if (!priv)
goto cleanup_tmp;
if (priv == NULL) {
screen->DestroyPixmap(tmp);
goto fixup;
}
if (!sna_pixmap_force_to_gpu(pixmap, MOVE_SOURCE_HINT | MOVE_READ)) {
fixup:
DBG(("%s: unable to create GPU bo for target or temporary pixmaps\n",
__FUNCTION__));
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h,
dst_x, dst_y);
}
format = PictureMatchFormat(screen,
pixmap->drawable.depth,
@ -958,8 +964,11 @@ sna_render_pixmap_partial(struct sna *sna,
channel->bo = kgem_create_proxy(&sna->kgem, bo,
box.y1 * bo->pitch + offset,
h * bo->pitch);
if (channel->bo == NULL)
if (channel->bo == NULL) {
DBG(("%s: failed to create proxy for partial (offset=%d, size=%d)\n",
__FUNCTION__, box.y1 * bo->pitch + offset, h * bo->pitch));
return false;
}
channel->bo->pitch = bo->pitch;
@ -1029,8 +1038,10 @@ sna_render_picture_partial(struct sna *sna,
bo = priv->gpu_bo;
}
if (bo->pitch > sna->render.max_3d_pitch)
return 0;
if (bo->pitch > sna->render.max_3d_pitch) {
DBG(("%s: pitch too great %d > %d\n", __FUNCTION__, bo->pitch, sna->render.max_3d_pitch));
return -1;
}
if (bo->tiling) {
int tile_width, tile_height, tile_size;
@ -1330,15 +1341,17 @@ sna_render_picture_convolve(struct sna *sna,
}
pixmap = screen->CreatePixmap(screen, w, h, depth, SNA_CREATE_SCRATCH);
if (pixmap == NullPixmap)
return 0;
if (pixmap == NullPixmap) {
DBG(("%s: pixmap allocation failed\n", __FUNCTION__));
return -1;
}
tmp = CreatePicture(0, &pixmap->drawable,
PictureMatchFormat(screen, depth, channel->pict_format),
0, NULL, serverClient, &error);
screen->DestroyPixmap(pixmap);
if (tmp == NULL)
return 0;
return -1;
ValidatePicture(tmp);
@ -1413,15 +1426,17 @@ sna_render_picture_flatten(struct sna *sna,
DBG(("%s: %dx%d\n", __FUNCTION__, w, h));
pixmap = screen->CreatePixmap(screen, w, h, 32, SNA_CREATE_SCRATCH);
if (pixmap == NullPixmap)
return 0;
if (pixmap == NullPixmap) {
DBG(("%s: pixmap allocation failed\n", __FUNCTION__));
return -1;
}
tmp = CreatePicture(0, &pixmap->drawable,
PictureMatchFormat(screen, 32, PICT_a8r8g8b8),
0, NULL, serverClient, &error);
screen->DestroyPixmap(pixmap);
if (tmp == NULL)
return 0;
return -1;
ValidatePicture(tmp);
@ -1789,7 +1804,7 @@ sna_render_picture_convert(struct sna *sna,
tmp = screen->CreatePixmap(screen, w, h, pixmap->drawable.bitsPerPixel, 0);
if (tmp == NULL)
return 0;
return -1;
dst = CreatePicture(0, &tmp->drawable,
PictureMatchFormat(screen,