sna: Exploit the alpha-fixup of the BLT for texture format conversions
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
6d6399f97c
commit
1367e3f9ef
|
|
@ -1927,7 +1927,8 @@ g4x_composite_picture(struct sna *sna,
|
|||
channel->card_format = g4x_get_card_format(picture->format);
|
||||
if (channel->card_format == -1)
|
||||
return sna_render_picture_convert(sna, picture, channel, pixmap,
|
||||
x, y, w, h, dst_x, dst_y);
|
||||
x, y, w, h, dst_x, dst_y,
|
||||
false);
|
||||
|
||||
if (too_large(pixmap->drawable.width, pixmap->drawable.height))
|
||||
return sna_render_picture_extract(sna, picture, channel,
|
||||
|
|
|
|||
|
|
@ -1304,7 +1304,8 @@ static bool
|
|||
gen2_check_card_format(struct sna *sna,
|
||||
PicturePtr picture,
|
||||
struct sna_composite_channel *channel,
|
||||
int x, int y, int w, int h)
|
||||
int x, int y, int w, int h,
|
||||
bool *fixup_alpha)
|
||||
{
|
||||
uint32_t format = picture->format;
|
||||
unsigned int i;
|
||||
|
|
@ -1324,10 +1325,12 @@ gen2_check_card_format(struct sna *sna,
|
|||
return true;
|
||||
}
|
||||
|
||||
*fixup_alpha = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*fixup_alpha = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1343,6 +1346,7 @@ gen2_composite_picture(struct sna *sna,
|
|||
PixmapPtr pixmap;
|
||||
uint32_t color;
|
||||
int16_t dx, dy;
|
||||
bool fixup_alpha;
|
||||
|
||||
DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n",
|
||||
__FUNCTION__, x, y, w, h, dst_x, dst_y));
|
||||
|
|
@ -1417,9 +1421,9 @@ gen2_composite_picture(struct sna *sna,
|
|||
} else
|
||||
channel->transform = picture->transform;
|
||||
|
||||
if (!gen2_check_card_format(sna, picture, channel, x, y, w ,h))
|
||||
if (!gen2_check_card_format(sna, picture, channel, x, y, w ,h, &fixup_alpha))
|
||||
return sna_render_picture_convert(sna, picture, channel, pixmap,
|
||||
x, y, w, h, dst_x, dst_y);
|
||||
x, y, w, h, dst_x, dst_y, fixup_alpha);
|
||||
|
||||
channel->pict_format = picture->format;
|
||||
if (too_large(pixmap->drawable.width, pixmap->drawable.height))
|
||||
|
|
|
|||
|
|
@ -2402,7 +2402,8 @@ gen3_composite_picture(struct sna *sna,
|
|||
if (!gen3_composite_channel_set_format(channel, picture->format) &&
|
||||
!gen3_composite_channel_set_xformat(picture, channel, x, y, w, h))
|
||||
return sna_render_picture_convert(sna, picture, channel, pixmap,
|
||||
x, y, w, h, dst_x, dst_y);
|
||||
x, y, w, h, dst_x, dst_y,
|
||||
false);
|
||||
|
||||
if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
|
||||
DBG(("%s: pixmap too large (%dx%d), extracting (%d, %d)x(%d,%d)\n",
|
||||
|
|
|
|||
|
|
@ -1918,7 +1918,8 @@ gen4_composite_picture(struct sna *sna,
|
|||
channel->card_format = gen4_get_card_format(picture->format);
|
||||
if (channel->card_format == -1)
|
||||
return sna_render_picture_convert(sna, picture, channel, pixmap,
|
||||
x, y, w, h, dst_x, dst_y);
|
||||
x, y, w, h, dst_x, dst_y,
|
||||
false);
|
||||
|
||||
if (too_large(pixmap->drawable.width, pixmap->drawable.height))
|
||||
return sna_render_picture_extract(sna, picture, channel,
|
||||
|
|
|
|||
|
|
@ -1936,7 +1936,8 @@ gen5_composite_picture(struct sna *sna,
|
|||
channel->card_format = gen5_get_card_format(picture->format);
|
||||
if (channel->card_format == -1)
|
||||
return sna_render_picture_convert(sna, picture, channel, pixmap,
|
||||
x, y, w, h, dst_x, dst_y);
|
||||
x, y, w, h, dst_x, dst_y,
|
||||
false);
|
||||
|
||||
if (too_large(pixmap->drawable.width, pixmap->drawable.height))
|
||||
return sna_render_picture_extract(sna, picture, channel,
|
||||
|
|
|
|||
|
|
@ -2274,7 +2274,8 @@ gen6_composite_picture(struct sna *sna,
|
|||
channel->card_format = gen6_get_card_format(picture->format);
|
||||
if (channel->card_format == (unsigned)-1)
|
||||
return sna_render_picture_convert(sna, picture, channel, pixmap,
|
||||
x, y, w, h, dst_x, dst_y);
|
||||
x, y, w, h, dst_x, dst_y,
|
||||
false);
|
||||
|
||||
if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
|
||||
DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__,
|
||||
|
|
|
|||
|
|
@ -2386,7 +2386,8 @@ gen7_composite_picture(struct sna *sna,
|
|||
channel->card_format = gen7_get_card_format(picture->format);
|
||||
if (channel->card_format == (unsigned)-1)
|
||||
return sna_render_picture_convert(sna, picture, channel, pixmap,
|
||||
x, y, w, h, dst_x, dst_y);
|
||||
x, y, w, h, dst_x, dst_y,
|
||||
false);
|
||||
|
||||
if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
|
||||
DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__,
|
||||
|
|
|
|||
|
|
@ -1637,11 +1637,10 @@ sna_render_picture_convert(struct sna *sna,
|
|||
PixmapPtr pixmap,
|
||||
int16_t x, int16_t y,
|
||||
int16_t w, int16_t h,
|
||||
int16_t dst_x, int16_t dst_y)
|
||||
int16_t dst_x, int16_t dst_y,
|
||||
bool fixup_alpha)
|
||||
{
|
||||
pixman_image_t *src, *dst;
|
||||
BoxRec box;
|
||||
void *ptr;
|
||||
|
||||
#if NO_CONVERT
|
||||
return -1;
|
||||
|
|
@ -1691,52 +1690,113 @@ sna_render_picture_convert(struct sna *sna,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ))
|
||||
return 0;
|
||||
if (fixup_alpha && is_gpu(&pixmap->drawable)) {
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
PixmapPtr tmp;
|
||||
PicturePtr src, dst;
|
||||
int error;
|
||||
|
||||
src = pixman_image_create_bits(picture->format,
|
||||
pixmap->drawable.width,
|
||||
pixmap->drawable.height,
|
||||
pixmap->devPrivate.ptr,
|
||||
pixmap->devKind);
|
||||
if (!src)
|
||||
return 0;
|
||||
assert(PICT_FORMAT_BPP(picture->format) == pixmap->drawable.bitsPerPixel);
|
||||
channel->pict_format = PICT_FORMAT(PICT_FORMAT_BPP(picture->format),
|
||||
PICT_FORMAT_TYPE(picture->format),
|
||||
PICT_FORMAT_BPP(picture->format) - PIXMAN_FORMAT_DEPTH(picture->format),
|
||||
PICT_FORMAT_R(picture->format),
|
||||
PICT_FORMAT_G(picture->format),
|
||||
PICT_FORMAT_B(picture->format));
|
||||
|
||||
if (PICT_FORMAT_RGB(picture->format) == 0) {
|
||||
channel->pict_format = PIXMAN_a8;
|
||||
DBG(("%s: converting to a8 from %08x\n",
|
||||
DBG(("%s: converting to %08x from %08x using composite alpha-fixup\n",
|
||||
__FUNCTION__, picture->format));
|
||||
|
||||
tmp = screen->CreatePixmap(screen, w, h, pixmap->drawable.bitsPerPixel, 0);
|
||||
if (tmp == NULL)
|
||||
return 0;
|
||||
|
||||
dst = CreatePicture(0, &tmp->drawable,
|
||||
PictureMatchFormat(screen,
|
||||
pixmap->drawable.bitsPerPixel,
|
||||
channel->pict_format),
|
||||
0, NULL, serverClient, &error);
|
||||
if (dst == NULL) {
|
||||
screen->DestroyPixmap(tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
src = CreatePicture(0, &pixmap->drawable,
|
||||
PictureMatchFormat(screen,
|
||||
pixmap->drawable.depth,
|
||||
picture->format),
|
||||
0, NULL, serverClient, &error);
|
||||
if (dst == NULL) {
|
||||
FreePicture(dst, 0);
|
||||
screen->DestroyPixmap(tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ValidatePicture(src);
|
||||
ValidatePicture(dst);
|
||||
|
||||
sna_composite(PictOpSrc, src, NULL, dst,
|
||||
box.x1, box.y1,
|
||||
0, 0,
|
||||
0, 0,
|
||||
w, h);
|
||||
FreePicture(dst, 0);
|
||||
FreePicture(src, 0);
|
||||
|
||||
channel->bo = sna_pixmap_get_bo(tmp);
|
||||
kgem_bo_reference(channel->bo);
|
||||
screen->DestroyPixmap(tmp);
|
||||
} else {
|
||||
channel->pict_format = PIXMAN_a8r8g8b8;
|
||||
DBG(("%s: converting to a8r8g8b8 from %08x\n",
|
||||
__FUNCTION__, picture->format));
|
||||
}
|
||||
pixman_image_t *src, *dst;
|
||||
void *ptr;
|
||||
|
||||
channel->bo = kgem_create_buffer_2d(&sna->kgem,
|
||||
w, h, PIXMAN_FORMAT_BPP(channel->pict_format),
|
||||
KGEM_BUFFER_WRITE_INPLACE,
|
||||
&ptr);
|
||||
if (!channel->bo) {
|
||||
if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ))
|
||||
return 0;
|
||||
|
||||
src = pixman_image_create_bits(picture->format,
|
||||
pixmap->drawable.width,
|
||||
pixmap->drawable.height,
|
||||
pixmap->devPrivate.ptr,
|
||||
pixmap->devKind);
|
||||
if (!src)
|
||||
return 0;
|
||||
|
||||
if (PICT_FORMAT_RGB(picture->format) == 0) {
|
||||
channel->pict_format = PIXMAN_a8;
|
||||
DBG(("%s: converting to a8 from %08x\n",
|
||||
__FUNCTION__, picture->format));
|
||||
} else {
|
||||
channel->pict_format = PIXMAN_a8r8g8b8;
|
||||
DBG(("%s: converting to a8r8g8b8 from %08x\n",
|
||||
__FUNCTION__, picture->format));
|
||||
}
|
||||
|
||||
channel->bo = kgem_create_buffer_2d(&sna->kgem,
|
||||
w, h, PIXMAN_FORMAT_BPP(channel->pict_format),
|
||||
KGEM_BUFFER_WRITE_INPLACE,
|
||||
&ptr);
|
||||
if (!channel->bo) {
|
||||
pixman_image_unref(src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dst = pixman_image_create_bits(channel->pict_format,
|
||||
w, h, ptr, channel->bo->pitch);
|
||||
if (!dst) {
|
||||
kgem_bo_destroy(&sna->kgem, channel->bo);
|
||||
pixman_image_unref(src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pixman_image_composite(PictOpSrc, src, NULL, dst,
|
||||
box.x1, box.y1,
|
||||
0, 0,
|
||||
0, 0,
|
||||
w, h);
|
||||
pixman_image_unref(dst);
|
||||
pixman_image_unref(src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dst = pixman_image_create_bits(channel->pict_format,
|
||||
w, h, ptr, channel->bo->pitch);
|
||||
if (!dst) {
|
||||
kgem_bo_destroy(&sna->kgem, channel->bo);
|
||||
pixman_image_unref(src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pixman_image_composite(PictOpSrc, src, NULL, dst,
|
||||
box.x1, box.y1,
|
||||
0, 0,
|
||||
0, 0,
|
||||
w, h);
|
||||
pixman_image_unref(dst);
|
||||
pixman_image_unref(src);
|
||||
|
||||
channel->width = w;
|
||||
channel->height = h;
|
||||
|
||||
|
|
@ -1745,11 +1805,10 @@ sna_render_picture_convert(struct sna *sna,
|
|||
channel->offset[0] = x - dst_x - box.x1;
|
||||
channel->offset[1] = y - dst_y - box.y1;
|
||||
|
||||
DBG(("%s: offset=(%d, %d), size=(%d, %d) ptr[0]=%08x\n",
|
||||
DBG(("%s: offset=(%d, %d), size=(%d, %d)\n",
|
||||
__FUNCTION__,
|
||||
channel->offset[0], channel->offset[1],
|
||||
channel->width, channel->height,
|
||||
*(uint32_t*)ptr));
|
||||
channel->width, channel->height));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -691,7 +691,8 @@ sna_render_picture_convert(struct sna *sna,
|
|||
PixmapPtr pixmap,
|
||||
int16_t x, int16_t y,
|
||||
int16_t w, int16_t h,
|
||||
int16_t dst_x, int16_t dst_y);
|
||||
int16_t dst_x, int16_t dst_y,
|
||||
bool fixup_alpha);
|
||||
|
||||
inline static void sna_render_composite_redirect_init(struct sna_composite_op *op)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue