sna/gen[23]: Tile render fill to oversized bo
If we are forced to perform a render operation to a bo too large to fit in the pipeline, copy to an intermediate and split the operation into tiles rather than fallback. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
2ccb31c5a4
commit
87f73b0434
|
|
@ -112,7 +112,7 @@ static const struct formatinfo {
|
|||
static inline bool
|
||||
too_large(int width, int height)
|
||||
{
|
||||
return (width | height) > MAX_3D_SIZE;
|
||||
return width > MAX_3D_SIZE || height > MAX_3D_SIZE;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
|
|
@ -2365,10 +2365,21 @@ gen2_render_fill_boxes(struct sna *sna,
|
|||
|
||||
if (too_large(dst->drawable.width, dst->drawable.height) ||
|
||||
dst_bo->pitch < 8 || dst_bo->pitch > 8192 ||
|
||||
!gen2_check_dst_format(format))
|
||||
return gen2_render_fill_boxes_try_blt(sna, op, format, color,
|
||||
dst, dst_bo,
|
||||
box, n);
|
||||
!gen2_check_dst_format(format)) {
|
||||
DBG(("%s: try blt, too large or incompatible destination\n",
|
||||
__FUNCTION__));
|
||||
if (gen2_render_fill_boxes_try_blt(sna, op, format, color,
|
||||
dst, dst_bo,
|
||||
box, n))
|
||||
return TRUE;
|
||||
|
||||
if (!gen2_check_dst_format(format))
|
||||
return FALSE;
|
||||
|
||||
assert(dst_bo->pitch >= 8);
|
||||
return sna_tiling_fill_boxes(sna, op, format, color,
|
||||
dst, dst_bo, box, n);
|
||||
}
|
||||
|
||||
if (prefer_blt_fill(sna) &&
|
||||
gen2_render_fill_boxes_try_blt(sna, op, format, color,
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ static const struct formatinfo {
|
|||
|
||||
static inline bool too_large(int width, int height)
|
||||
{
|
||||
return (width | height) > MAX_3D_SIZE;
|
||||
return width > MAX_3D_SIZE || height > MAX_3D_SIZE;
|
||||
}
|
||||
|
||||
static inline uint32_t gen3_buf_tiling(uint32_t tiling)
|
||||
|
|
@ -3885,8 +3885,11 @@ gen3_render_fill_boxes_try_blt(struct sna *sna,
|
|||
uint8_t alu = GXcopy;
|
||||
uint32_t pixel;
|
||||
|
||||
if (dst_bo->tiling == I915_TILING_Y)
|
||||
if (dst_bo->tiling == I915_TILING_Y) {
|
||||
DBG(("%s: y-tiling, can't blit\n", __FUNCTION__));
|
||||
assert(!too_large(dst->drawable.width, dst->drawable.height));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (color->alpha >= 0xff00) {
|
||||
if (op == PictOpOver)
|
||||
|
|
@ -3905,15 +3908,18 @@ gen3_render_fill_boxes_try_blt(struct sna *sna,
|
|||
if (color->alpha <= 0x00ff)
|
||||
alu = GXclear;
|
||||
else if (!sna_get_pixel_from_rgba(&pixel,
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
color->alpha,
|
||||
format))
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
color->alpha,
|
||||
format)) {
|
||||
DBG(("%s: unknown format %x\n", __FUNCTION__, format));
|
||||
return FALSE;
|
||||
} else
|
||||
}
|
||||
} else {
|
||||
DBG(("%s: unhandle op %d\n", __FUNCTION__, alu));
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
return sna_blt_fill_boxes(sna, alu,
|
||||
dst_bo, dst->drawable.bitsPerPixel,
|
||||
|
|
@ -3958,10 +3964,20 @@ gen3_render_fill_boxes(struct sna *sna,
|
|||
|
||||
if (too_large(dst->drawable.width, dst->drawable.height) ||
|
||||
dst_bo->pitch > 8192 ||
|
||||
!gen3_check_dst_format(format))
|
||||
return gen3_render_fill_boxes_try_blt(sna, op, format, color,
|
||||
dst, dst_bo,
|
||||
box, n);
|
||||
!gen3_check_dst_format(format)) {
|
||||
DBG(("%s: try blt, too large or incompatible destination\n",
|
||||
__FUNCTION__));
|
||||
if (gen3_render_fill_boxes_try_blt(sna, op, format, color,
|
||||
dst, dst_bo,
|
||||
box, n))
|
||||
return TRUE;
|
||||
|
||||
if (!gen3_check_dst_format(format))
|
||||
return FALSE;
|
||||
|
||||
return sna_tiling_fill_boxes(sna, op, format, color,
|
||||
dst, dst_bo, box, n);
|
||||
}
|
||||
|
||||
if (prefer_fill_blt(sna) &&
|
||||
gen3_render_fill_boxes_try_blt(sna, op, format, color,
|
||||
|
|
@ -3977,8 +3993,10 @@ gen3_render_fill_boxes(struct sna *sna,
|
|||
color->green,
|
||||
color->blue,
|
||||
color->alpha,
|
||||
PICT_a8r8g8b8))
|
||||
PICT_a8r8g8b8)) {
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
DBG(("%s: using shader for op=%d, format=%x, pixel=%x\n",
|
||||
__FUNCTION__, op, (int)format, pixel));
|
||||
|
|
|
|||
|
|
@ -2580,10 +2580,12 @@ gen4_render_fill_boxes(struct sna *sna,
|
|||
pixel, box, n))
|
||||
return TRUE;
|
||||
|
||||
if (dst->drawable.width > 8192 ||
|
||||
dst->drawable.height > 8192 ||
|
||||
!gen4_check_dst_format(format))
|
||||
if (!gen4_check_dst_format(format))
|
||||
return FALSE;
|
||||
|
||||
if (dst->drawable.width > 8192 || dst->drawable.height > 8192)
|
||||
return sna_tiling_fill_boxes(sna, op, format, color,
|
||||
dst, dst_bo, box, n);
|
||||
}
|
||||
|
||||
#if NO_FILL_BOXES
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ gen5_emit_pipelined_pointers(struct sna *sna,
|
|||
|
||||
static inline bool too_large(int width, int height)
|
||||
{
|
||||
return (width | height) > MAX_3D_SIZE;
|
||||
return width > MAX_3D_SIZE || height > MAX_3D_SIZE;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -2920,9 +2920,12 @@ gen5_render_fill_boxes(struct sna *sna,
|
|||
pixel, box, n))
|
||||
return TRUE;
|
||||
|
||||
if (too_large(dst->drawable.width, dst->drawable.height) ||
|
||||
!gen5_check_dst_format(format))
|
||||
if (!gen5_check_dst_format(format))
|
||||
return FALSE;
|
||||
|
||||
if (too_large(dst->drawable.width, dst->drawable.height))
|
||||
return sna_tiling_fill_boxes(sna, op, format, color,
|
||||
dst, dst_bo, box, n);
|
||||
}
|
||||
|
||||
if (op == PictOpClear)
|
||||
|
|
|
|||
|
|
@ -1954,7 +1954,7 @@ gen6_composite_solid_init(struct sna *sna,
|
|||
|
||||
static inline bool too_large(int width, int height)
|
||||
{
|
||||
return (width | height) > GEN6_MAX_SIZE;
|
||||
return width > GEN6_MAX_SIZE || height > GEN6_MAX_SIZE;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -3191,9 +3191,12 @@ gen6_render_fill_boxes(struct sna *sna,
|
|||
pixel, box, n))
|
||||
return TRUE;
|
||||
|
||||
if (too_large(dst->drawable.width, dst->drawable.height) ||
|
||||
!gen6_check_dst_format(format))
|
||||
if (!gen6_check_dst_format(format))
|
||||
return FALSE;
|
||||
|
||||
if (too_large(dst->drawable.width, dst->drawable.height))
|
||||
return sna_tiling_fill_boxes(sna, op, format, color,
|
||||
dst, dst_bo, box, n);
|
||||
}
|
||||
|
||||
#if NO_FILL_BOXES
|
||||
|
|
|
|||
|
|
@ -2048,7 +2048,7 @@ gen7_composite_solid_init(struct sna *sna,
|
|||
|
||||
static inline bool too_large(int width, int height)
|
||||
{
|
||||
return (width | height) > GEN7_MAX_SIZE;
|
||||
return width > GEN7_MAX_SIZE || height > GEN7_MAX_SIZE;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -3247,9 +3247,12 @@ gen7_render_fill_boxes(struct sna *sna,
|
|||
pixel, box, n))
|
||||
return TRUE;
|
||||
|
||||
if (too_large(dst->drawable.width, dst->drawable.height) ||
|
||||
!gen7_check_dst_format(format))
|
||||
if (!gen7_check_dst_format(format))
|
||||
return FALSE;
|
||||
|
||||
if (too_large(dst->drawable.width, dst->drawable.height))
|
||||
return sna_tiling_fill_boxes(sna, op, format, color,
|
||||
dst, dst_bo, box, n);
|
||||
}
|
||||
|
||||
#if NO_FILL_BOXES
|
||||
|
|
|
|||
|
|
@ -495,6 +495,12 @@ Bool sna_tiling_composite(uint32_t op,
|
|||
int16_t dst_x, int16_t dst_y,
|
||||
int16_t width, int16_t height,
|
||||
struct sna_composite_op *tmp);
|
||||
Bool sna_tiling_fill_boxes(struct sna *sna,
|
||||
CARD8 op,
|
||||
PictFormat format,
|
||||
const xRenderColor *color,
|
||||
PixmapPtr dst, struct kgem_bo *dst_bo,
|
||||
const BoxRec *box, int n);
|
||||
|
||||
Bool sna_blt_composite(struct sna *sna,
|
||||
uint32_t op,
|
||||
|
|
|
|||
|
|
@ -307,3 +307,104 @@ sna_tiling_composite(uint32_t op,
|
|||
tmp->u.priv = tile;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
sna_tiling_fill_boxes(struct sna *sna,
|
||||
CARD8 op,
|
||||
PictFormat format,
|
||||
const xRenderColor *color,
|
||||
PixmapPtr dst, struct kgem_bo *dst_bo,
|
||||
const BoxRec *box, int n)
|
||||
{
|
||||
RegionRec region, tile, this;
|
||||
struct kgem_bo *bo;
|
||||
Bool ret = FALSE;
|
||||
|
||||
pixman_region_init_rects(®ion, box, n);
|
||||
|
||||
DBG(("%s (op=%d, format=%x, color=(%04x,%04x,%04x, %04x), tile.size=%d, box=%dx[(%d, %d), (%d, %d)])\n",
|
||||
__FUNCTION__, op, (int)format,
|
||||
color->red, color->green, color->blue, color->alpha,
|
||||
sna->render.max_3d_size, n,
|
||||
region.extents.x1, region.extents.y1,
|
||||
region.extents.x2, region.extents.y2));
|
||||
|
||||
for (tile.extents.y1 = tile.extents.y2 = region.extents.y1;
|
||||
tile.extents.y2 < region.extents.y2;
|
||||
tile.extents.y1 = tile.extents.y2) {
|
||||
tile.extents.y2 = tile.extents.y1 + sna->render.max_3d_size;
|
||||
if (tile.extents.y2 > region.extents.y2)
|
||||
tile.extents.y2 = region.extents.y2;
|
||||
|
||||
for (tile.extents.x1 = tile.extents.x2 = region.extents.x1;
|
||||
tile.extents.x2 < region.extents.x2;
|
||||
tile.extents.x1 = tile.extents.x2) {
|
||||
PixmapRec tmp;
|
||||
|
||||
tile.extents.x2 = tile.extents.x1 + sna->render.max_3d_size;
|
||||
if (tile.extents.x2 > region.extents.x2)
|
||||
tile.extents.x2 = region.extents.x2;
|
||||
|
||||
tile.data = NULL;
|
||||
|
||||
RegionNull(&this);
|
||||
RegionIntersect(&this, ®ion, &tile);
|
||||
if (!RegionNotEmpty(&this))
|
||||
continue;
|
||||
|
||||
tmp.drawable.width = this.extents.x2 - this.extents.x1;
|
||||
tmp.drawable.height = this.extents.y2 - this.extents.y1;
|
||||
tmp.drawable.depth = dst->drawable.depth;
|
||||
tmp.drawable.bitsPerPixel = dst->drawable.bitsPerPixel;
|
||||
tmp.devPrivate.ptr = NULL;
|
||||
|
||||
bo = kgem_create_2d(&sna->kgem,
|
||||
tmp.drawable.width,
|
||||
tmp.drawable.height,
|
||||
dst->drawable.bitsPerPixel,
|
||||
kgem_choose_tiling(&sna->kgem,
|
||||
I915_TILING_X,
|
||||
tmp.drawable.width,
|
||||
tmp.drawable.height,
|
||||
dst->drawable.bitsPerPixel),
|
||||
CREATE_SCANOUT);
|
||||
if (bo) {
|
||||
int16_t dx = this.extents.x1;
|
||||
int16_t dy = this.extents.y1;
|
||||
|
||||
assert(bo->pitch <= 8192);
|
||||
assert(bo->tiling != I915_TILING_Y);
|
||||
|
||||
if (!sna->render.copy_boxes(sna, GXcopy,
|
||||
dst, dst_bo, 0, 0,
|
||||
&tmp, bo, -dx, -dy,
|
||||
REGION_RECTS(&this), REGION_NUM_RECTS(&this)))
|
||||
goto err;
|
||||
|
||||
RegionTranslate(&this, -dx, -dy);
|
||||
if (!sna->render.fill_boxes(sna, op, format, color,
|
||||
&tmp, bo,
|
||||
REGION_RECTS(&this), REGION_NUM_RECTS(&this)))
|
||||
goto err;
|
||||
|
||||
if (!sna->render.copy_boxes(sna, GXcopy,
|
||||
&tmp, bo, 0, 0,
|
||||
dst, dst_bo, dx, dy,
|
||||
REGION_RECTS(&this), REGION_NUM_RECTS(&this)))
|
||||
goto err;
|
||||
|
||||
kgem_bo_destroy(&sna->kgem, bo);
|
||||
}
|
||||
RegionUninit(&this);
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
goto done;
|
||||
err:
|
||||
kgem_bo_destroy(&sna->kgem, bo);
|
||||
RegionUninit(&this);
|
||||
done:
|
||||
pixman_region_fini(®ion);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue