summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-16 14:12:36 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-16 15:39:42 +0000
commit6387f2fb8a40f32cc4a3e4228983dcf0604ac4dc (patch)
treed5ddd85d4cac6845437aceadcfe089c641c25d5d /src
parent8b2bb666662305ab88aad8198ad69b1c98407d75 (diff)
sna/gen[4567]: x1r5g5b5 is only a render target, not sampler
Whilst we can render to and blend with an depth 15 target, we cannot use it as a texture with the sampling engine. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r--src/sna/gen4_render.c85
-rw-r--r--src/sna/gen5_render.c83
-rw-r--r--src/sna/gen6_render.c83
-rw-r--r--src/sna/gen7_render.c81
-rw-r--r--src/sna/sna.h1
-rw-r--r--src/sna/sna_render.c16
6 files changed, 170 insertions, 179 deletions
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index d44ddd51..7d1005da 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -267,7 +267,6 @@ static const struct formatinfo {
{PICT_r8g8b8, GEN4_SURFACEFORMAT_R8G8B8_UNORM},
{PICT_r5g6b5, GEN4_SURFACEFORMAT_B5G6R5_UNORM},
{PICT_a1r5g5b5, GEN4_SURFACEFORMAT_B5G5R5A1_UNORM},
- {PICT_x1r5g5b5, GEN4_SURFACEFORMAT_B5G5R5X1_UNORM},
{PICT_a2r10g10b10, GEN4_SURFACEFORMAT_B10G10R10A2_UNORM},
{PICT_x2r10g10b10, GEN4_SURFACEFORMAT_B10G10R10X2_UNORM},
{PICT_a2b10g10r10, GEN4_SURFACEFORMAT_R10G10B10A2_UNORM},
@@ -562,9 +561,9 @@ static Bool gen4_check_dst_format(PictFormat format)
}
}
-static bool gen4_check_format(PicturePtr p)
+static bool gen4_check_format(uint32_t format)
{
- switch (p->format) {
+ switch (format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
case PICT_a8b8g8r8:
@@ -573,14 +572,13 @@ static bool gen4_check_format(PicturePtr p)
case PICT_x2r10g10b10:
case PICT_r8g8b8:
case PICT_r5g6b5:
- case PICT_x1r5g5b5:
case PICT_a1r5g5b5:
case PICT_a8:
case PICT_a4r4g4b4:
case PICT_x4r4g4b4:
return true;
default:
- DBG(("%s: unhandled format: %x\n", __FUNCTION__, p->format));
+ DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
return false;
}
}
@@ -652,7 +650,6 @@ static uint32_t gen4_get_card_format(PictFormat format)
if (gen4_tex_formats[i].pict_fmt == format)
return gen4_tex_formats[i].card_fmt;
}
- assert(0);
return -1;
}
@@ -1845,12 +1842,6 @@ gen4_composite_picture(struct sna *sna,
x, y, w, h, dst_x, dst_y);
}
- if (!gen4_check_format(picture)) {
- DBG(("%s: unknown format fixup\n", __FUNCTION__));
- return sna_render_picture_fixup(sna, picture, channel,
- x, y, w, h, dst_x, dst_y);
- }
-
if (!gen4_check_repeat(picture)) {
DBG(("%s: unknown repeat mode fixup\n", __FUNCTION__));
return sna_render_picture_fixup(sna, picture, channel,
@@ -1884,6 +1875,9 @@ gen4_composite_picture(struct sna *sna,
channel->transform = picture->transform;
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);
if (pixmap->drawable.width > 8192 || pixmap->drawable.height > 8192)
return sna_render_picture_extract(sna, picture, channel,
@@ -2020,7 +2014,7 @@ has_alphamap(PicturePtr p)
static bool
source_fallback(PicturePtr p)
{
- return has_alphamap(p) || is_gradient(p) || !gen4_check_filter(p) || !gen4_check_repeat(p) || !gen4_check_format(p);
+ return has_alphamap(p) || is_gradient(p) || !gen4_check_filter(p) || !gen4_check_repeat(p) || !gen4_check_format(p->format);
}
static bool
@@ -2143,7 +2137,7 @@ reuse_source(struct sna *sna,
if (!gen4_check_filter(mask))
return FALSE;
- if (!gen4_check_format(mask))
+ if (!gen4_check_format(mask->format))
return FALSE;
DBG(("%s: reusing source channel for mask with a twist\n",
@@ -2330,32 +2324,6 @@ cleanup_dst:
return FALSE;
}
-static uint32_t gen4_get_dest_format_for_depth(int depth)
-{
- switch (depth) {
- case 32:
- case 24:
- default: return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
- case 30: return GEN4_SURFACEFORMAT_B10G10R10A2_UNORM;
- case 16: return GEN4_SURFACEFORMAT_B5G6R5_UNORM;
- case 15: return GEN4_SURFACEFORMAT_B5G5R5A1_UNORM;
- case 8: return GEN4_SURFACEFORMAT_A8_UNORM;
- }
-}
-
-static uint32_t gen4_get_card_format_for_depth(int depth)
-{
- switch (depth) {
- case 32:
- default: return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
- case 30: return GEN4_SURFACEFORMAT_B10G10R10X2_UNORM;
- case 24: return GEN4_SURFACEFORMAT_B8G8R8X8_UNORM;
- case 16: return GEN4_SURFACEFORMAT_B5G6R5_UNORM;
- case 15: return GEN4_SURFACEFORMAT_B5G5R5X1_UNORM;
- case 8: return GEN4_SURFACEFORMAT_A8_UNORM;
- }
-}
-
static void
gen4_copy_bind_surfaces(struct sna *sna, const struct sna_composite_op *op)
{
@@ -2369,7 +2337,7 @@ gen4_copy_bind_surfaces(struct sna *sna, const struct sna_composite_op *op)
binding_table[0] =
gen4_bind_bo(sna,
op->dst.bo, op->dst.width, op->dst.height,
- gen4_get_dest_format_for_depth(op->dst.pixmap->drawable.depth),
+ gen4_get_dest_format(op->dst.format),
TRUE);
binding_table[1] =
gen4_bind_bo(sna,
@@ -2443,15 +2411,30 @@ gen4_render_copy_boxes(struct sna *sna, uint8_t alu,
if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
src->drawable.width > 8192 || src->drawable.height > 8192 ||
- dst->drawable.width > 8192 || dst->drawable.height > 8192)
+ dst->drawable.width > 8192 || dst->drawable.height > 8192) {
+fallback:
+ if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+ return FALSE;
+
return sna_blt_copy_boxes_fallback(sna, alu,
src, src_bo, src_dx, src_dy,
dst, dst_bo, dst_dx, dst_dy,
box, n);
+ }
DBG(("%s (%d, %d)->(%d, %d) x %d\n",
__FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n));
+ if (dst->drawable.depth == src->drawable.depth) {
+ tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+ tmp.src.pict_format = tmp.dst.format;
+ } else {
+ tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+ tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
+ }
+ if (!gen4_check_format(tmp.src.pict_format))
+ goto fallback;
+
memset(&tmp, 0, sizeof(tmp));
tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear;
@@ -2459,7 +2442,6 @@ gen4_render_copy_boxes(struct sna *sna, uint8_t alu,
tmp.dst.pixmap = dst;
tmp.dst.width = dst->drawable.width;
tmp.dst.height = dst->drawable.height;
- tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
tmp.dst.bo = dst_bo;
tmp.dst.x = dst_dx;
tmp.dst.y = dst_dy;
@@ -2468,7 +2450,7 @@ gen4_render_copy_boxes(struct sna *sna, uint8_t alu,
tmp.src.filter = SAMPLER_FILTER_NEAREST;
tmp.src.repeat = SAMPLER_EXTEND_NONE;
tmp.src.card_format =
- gen4_get_card_format_for_depth(src->drawable.depth),
+ gen4_get_card_format(tmp.src.pict_format),
tmp.src.width = src->drawable.width;
tmp.src.height = src->drawable.height;
@@ -2541,6 +2523,7 @@ gen4_render_copy(struct sna *sna, uint8_t alu,
if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
src->drawable.width > 8192 || src->drawable.height > 8192 ||
dst->drawable.width > 8192 || dst->drawable.height > 8192) {
+fallback:
if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
return FALSE;
@@ -2548,18 +2531,26 @@ gen4_render_copy(struct sna *sna, uint8_t alu,
dst->drawable.bitsPerPixel,
op);
}
+ if (dst->drawable.depth == src->drawable.depth) {
+ op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+ op->base.src.pict_format = op->base.dst.format;
+ } else {
+ op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
+ op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
+ }
+ if (!gen4_check_format(op->base.src.pict_format))
+ goto fallback;
op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear;
op->base.dst.pixmap = dst;
op->base.dst.width = dst->drawable.width;
op->base.dst.height = dst->drawable.height;
- op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
op->base.dst.bo = dst_bo;
op->base.src.bo = src_bo;
op->base.src.card_format =
- gen4_get_card_format_for_depth(src->drawable.depth),
+ gen4_get_card_format(op->base.src.pict_format);
op->base.src.width = src->drawable.width;
op->base.src.height = src->drawable.height;
op->base.src.scale[0] = 1.f/src->drawable.width;
@@ -2599,7 +2590,7 @@ gen4_fill_bind_surfaces(struct sna *sna, const struct sna_composite_op *op)
binding_table[0] =
gen4_bind_bo(sna,
op->dst.bo, op->dst.width, op->dst.height,
- gen4_get_dest_format_for_depth(op->dst.pixmap->drawable.depth),
+ gen4_get_dest_format(op->dst.format),
TRUE);
binding_table[1] =
gen4_bind_bo(sna,
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index f8d8d105..a06194e1 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -257,7 +257,6 @@ static const struct formatinfo {
{PICT_r8g8b8, GEN5_SURFACEFORMAT_R8G8B8_UNORM},
{PICT_r5g6b5, GEN5_SURFACEFORMAT_B5G6R5_UNORM},
{PICT_a1r5g5b5, GEN5_SURFACEFORMAT_B5G5R5A1_UNORM},
- {PICT_x1r5g5b5, GEN5_SURFACEFORMAT_B5G5R5X1_UNORM},
{PICT_a2r10g10b10, GEN5_SURFACEFORMAT_B10G10R10A2_UNORM},
{PICT_x2r10g10b10, GEN5_SURFACEFORMAT_B10G10R10X2_UNORM},
{PICT_a2b10g10r10, GEN5_SURFACEFORMAT_R10G10B10A2_UNORM},
@@ -563,9 +562,9 @@ static Bool gen5_check_dst_format(PictFormat format)
}
}
-static bool gen5_check_format(PicturePtr p)
+static bool gen5_check_format(uint32_t format)
{
- switch (p->format) {
+ switch (format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
case PICT_a8b8g8r8:
@@ -574,44 +573,17 @@ static bool gen5_check_format(PicturePtr p)
case PICT_x2r10g10b10:
case PICT_r8g8b8:
case PICT_r5g6b5:
- case PICT_x1r5g5b5:
case PICT_a1r5g5b5:
case PICT_a8:
case PICT_a4r4g4b4:
case PICT_x4r4g4b4:
return true;
default:
- DBG(("%s: unhandled format: %x\n", __FUNCTION__, p->format));
+ DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
return false;
}
}
-static uint32_t gen5_get_dest_format_for_depth(int depth)
-{
- switch (depth) {
- case 32:
- case 24:
- default: return GEN5_SURFACEFORMAT_B8G8R8A8_UNORM;
- case 30: return GEN5_SURFACEFORMAT_B10G10R10A2_UNORM;
- case 16: return GEN5_SURFACEFORMAT_B5G6R5_UNORM;
- case 15: return GEN5_SURFACEFORMAT_B5G5R5A1_UNORM;
- case 8: return GEN5_SURFACEFORMAT_A8_UNORM;
- }
-}
-
-static uint32_t gen5_get_card_format_for_depth(int depth)
-{
- switch (depth) {
- case 32:
- default: return GEN5_SURFACEFORMAT_B8G8R8A8_UNORM;
- case 30: return GEN5_SURFACEFORMAT_B10G10R10X2_UNORM;
- case 24: return GEN5_SURFACEFORMAT_B8G8R8X8_UNORM;
- case 16: return GEN5_SURFACEFORMAT_B5G6R5_UNORM;
- case 15: return GEN5_SURFACEFORMAT_B5G5R5X1_UNORM;
- case 8: return GEN5_SURFACEFORMAT_A8_UNORM;
- }
-}
-
typedef struct gen5_surface_state_padded {
struct gen5_surface_state state;
char pad[32 - sizeof(struct gen5_surface_state)];
@@ -679,7 +651,6 @@ static uint32_t gen5_get_card_format(PictFormat format)
if (gen5_tex_formats[i].pict_fmt == format)
return gen5_tex_formats[i].card_fmt;
}
- assert(0);
return -1;
}
@@ -1725,7 +1696,7 @@ static void gen5_video_bind_surfaces(struct sna *sna,
binding_table[0] =
gen5_bind_bo(sna,
op->dst.bo, op->dst.width, op->dst.height,
- gen5_get_dest_format_for_depth(op->dst.format),
+ gen5_get_dest_format(op->dst.format),
TRUE);
for (n = 0; n < n_src; n++) {
binding_table[1+n] =
@@ -1897,10 +1868,6 @@ gen5_composite_picture(struct sna *sna,
x, y, w, h, dst_x, dst_y);
}
- if (!gen5_check_format(picture))
- return sna_render_picture_fixup(sna, picture, channel,
- x, y, w, h, dst_x, dst_y);
-
if (!gen5_check_repeat(picture))
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
@@ -1930,6 +1897,9 @@ gen5_composite_picture(struct sna *sna,
channel->transform = picture->transform;
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);
if (too_large(pixmap->drawable.width, pixmap->drawable.height))
return sna_render_picture_extract(sna, picture, channel,
@@ -2079,7 +2049,7 @@ source_fallback(PicturePtr p)
is_gradient(p) ||
!gen5_check_filter(p) ||
!gen5_check_repeat(p) ||
- !gen5_check_format(p));
+ !gen5_check_format(p->format));
}
static bool
@@ -2202,7 +2172,7 @@ reuse_source(struct sna *sna,
if (!gen5_check_filter(mask))
return FALSE;
- if (!gen5_check_format(mask))
+ if (!gen5_check_format(mask->format))
return FALSE;
DBG(("%s: reusing source channel for mask with a twist\n",
@@ -2719,7 +2689,7 @@ gen5_copy_bind_surfaces(struct sna *sna,
binding_table[0] =
gen5_bind_bo(sna,
op->dst.bo, op->dst.width, op->dst.height,
- gen5_get_dest_format_for_depth(op->dst.pixmap->drawable.depth),
+ gen5_get_dest_format(op->dst.pixmap->drawable.depth),
TRUE);
binding_table[1] =
gen5_bind_bo(sna,
@@ -2764,11 +2734,26 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu,
if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
too_large(src->drawable.width, src->drawable.height) ||
- too_large(dst->drawable.width, dst->drawable.height))
+ too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
+ if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+ return FALSE;
+
return sna_blt_copy_boxes_fallback(sna, alu,
src, src_bo, src_dx, src_dy,
dst, dst_bo, dst_dx, dst_dy,
box, n);
+ }
+
+ if (dst->drawable.depth == src->drawable.depth) {
+ tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+ tmp.src.pict_format = tmp.dst.format;
+ } else {
+ tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+ tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
+ }
+ if (!gen5_check_format(tmp.src.pict_format))
+ goto fallback;
DBG(("%s (%d, %d)->(%d, %d) x %d\n",
__FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n));
@@ -2780,7 +2765,6 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu,
tmp.dst.pixmap = dst;
tmp.dst.width = dst->drawable.width;
tmp.dst.height = dst->drawable.height;
- tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
tmp.dst.bo = dst_bo;
tmp.dst.x = dst_dx;
tmp.dst.y = dst_dy;
@@ -2789,7 +2773,7 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu,
tmp.src.filter = SAMPLER_FILTER_NEAREST;
tmp.src.repeat = SAMPLER_EXTEND_NONE;
tmp.src.card_format =
- gen5_get_card_format_for_depth(src->drawable.depth),
+ gen5_get_card_format(tmp.src.pict_format);
tmp.src.width = src->drawable.width;
tmp.src.height = src->drawable.height;
@@ -2909,6 +2893,7 @@ gen5_render_copy(struct sna *sna, uint8_t alu,
if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
too_large(src->drawable.width, src->drawable.height) ||
too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
return FALSE;
@@ -2917,6 +2902,16 @@ gen5_render_copy(struct sna *sna, uint8_t alu,
op);
}
+ if (dst->drawable.depth == src->drawable.depth) {
+ op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+ op->base.src.pict_format = op->base.dst.format;
+ } else {
+ op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
+ op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
+ }
+ if (!gen5_check_format(op->base.src.pict_format))
+ goto fallback;
+
op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear;
op->base.dst.pixmap = dst;
@@ -2927,7 +2922,7 @@ gen5_render_copy(struct sna *sna, uint8_t alu,
op->base.src.bo = src_bo;
op->base.src.card_format =
- gen5_get_card_format_for_depth(src->drawable.depth),
+ gen5_get_card_format(op->base.src.pict_format);
op->base.src.width = src->drawable.width;
op->base.src.height = src->drawable.height;
op->base.src.scale[0] = 1.f/src->drawable.width;
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 0801e04d..8d3c0319 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -208,7 +208,6 @@ static const struct formatinfo {
{PICT_r8g8b8, GEN6_SURFACEFORMAT_R8G8B8_UNORM},
{PICT_r5g6b5, GEN6_SURFACEFORMAT_B5G6R5_UNORM},
{PICT_a1r5g5b5, GEN6_SURFACEFORMAT_B5G5R5A1_UNORM},
- {PICT_x1r5g5b5, GEN6_SURFACEFORMAT_B5G5R5X1_UNORM},
{PICT_a2r10g10b10, GEN6_SURFACEFORMAT_B10G10R10A2_UNORM},
{PICT_x2r10g10b10, GEN6_SURFACEFORMAT_B10G10R10X2_UNORM},
{PICT_a2b10g10r10, GEN6_SURFACEFORMAT_R10G10B10A2_UNORM},
@@ -311,9 +310,9 @@ static Bool gen6_check_dst_format(PictFormat format)
return FALSE;
}
-static bool gen6_check_format(PicturePtr p)
+static bool gen6_check_format(uint32_t format)
{
- switch (p->format) {
+ switch (format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
case PICT_a8b8g8r8:
@@ -322,44 +321,17 @@ static bool gen6_check_format(PicturePtr p)
case PICT_x2r10g10b10:
case PICT_r8g8b8:
case PICT_r5g6b5:
- case PICT_x1r5g5b5:
case PICT_a1r5g5b5:
case PICT_a8:
case PICT_a4r4g4b4:
case PICT_x4r4g4b4:
return true;
default:
- DBG(("%s: unhandled format: %x\n", __FUNCTION__, p->format));
+ DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
return false;
}
}
-static uint32_t gen6_get_dest_format_for_depth(int depth)
-{
- switch (depth) {
- default: assert(0);
- case 32:
- case 24: return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
- case 30: return GEN6_SURFACEFORMAT_B10G10R10A2_UNORM;
- case 16: return GEN6_SURFACEFORMAT_B5G6R5_UNORM;
- case 15: return GEN6_SURFACEFORMAT_B5G5R5A1_UNORM;
- case 8: return GEN6_SURFACEFORMAT_A8_UNORM;
- }
-}
-
-static uint32_t gen6_get_card_format_for_depth(int depth)
-{
- switch (depth) {
- default: assert(0);
- case 32: return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
- case 30: return GEN6_SURFACEFORMAT_B10G10R10X2_UNORM;
- case 24: return GEN6_SURFACEFORMAT_B8G8R8X8_UNORM;
- case 16: return GEN6_SURFACEFORMAT_B5G6R5_UNORM;
- case 15: return GEN6_SURFACEFORMAT_B5G5R5X1_UNORM;
- case 8: return GEN6_SURFACEFORMAT_A8_UNORM;
- }
-}
-
static uint32_t gen6_filter(uint32_t filter)
{
switch (filter) {
@@ -1937,7 +1909,7 @@ gen6_render_video(struct sna *sna,
tmp.dst.pixmap = pixmap;
tmp.dst.width = pixmap->drawable.width;
tmp.dst.height = pixmap->drawable.height;
- tmp.dst.format = sna_format_for_depth(pixmap->drawable.depth);
+ tmp.dst.format = sna_render_format_for_depth(pixmap->drawable.depth);
tmp.dst.bo = priv->gpu_bo;
tmp.src.filter = SAMPLER_FILTER_BILINEAR;
@@ -2093,10 +2065,6 @@ gen6_composite_picture(struct sna *sna,
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
- if (!gen6_check_format(picture))
- return sna_render_picture_fixup(sna, picture, channel,
- x, y, w, h, dst_x, dst_y);
-
channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
channel->filter = picture->filter;
@@ -2118,6 +2086,9 @@ gen6_composite_picture(struct sna *sna,
channel->transform = picture->transform;
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);
if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__,
@@ -2261,7 +2232,7 @@ has_alphamap(PicturePtr p)
static bool
source_fallback(PicturePtr p)
{
- return has_alphamap(p) || is_gradient(p) || !gen6_check_filter(p) || !gen6_check_repeat(p) || !gen6_check_format(p);
+ return has_alphamap(p) || is_gradient(p) || !gen6_check_filter(p) || !gen6_check_repeat(p) || !gen6_check_format(p->format);
}
static bool
@@ -2384,7 +2355,7 @@ reuse_source(struct sna *sna,
if (!gen6_check_filter(mask))
return FALSE;
- if (!gen6_check_format(mask))
+ if (!gen6_check_format(mask->format))
return FALSE;
DBG(("%s: reusing source channel for mask with a twist\n",
@@ -3011,7 +2982,7 @@ gen6_emit_copy_state(struct sna *sna,
binding_table[0] =
gen6_bind_bo(sna,
op->dst.bo, op->dst.width, op->dst.height,
- gen6_get_dest_format_for_depth(op->dst.pixmap->drawable.depth),
+ gen6_get_dest_format(op->dst.format),
TRUE);
binding_table[1] =
gen6_bind_bo(sna,
@@ -3113,11 +3084,26 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
dst_bo, dst_dx, dst_dy,
box, n) ||
too_large(src->drawable.width, src->drawable.height) ||
- too_large(dst->drawable.width, dst->drawable.height))
+ too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
+ if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+ return false;
+
return sna_blt_copy_boxes_fallback(sna, alu,
src, src_bo, src_dx, src_dy,
dst, dst_bo, dst_dx, dst_dy,
box, n);
+ }
+
+ if (dst->drawable.depth == src->drawable.depth) {
+ tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+ tmp.src.pict_format = tmp.dst.format;
+ } else {
+ tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+ tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
+ }
+ if (!gen6_check_format(tmp.src.pict_format))
+ goto fallback;
tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear;
@@ -3125,7 +3111,6 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
tmp.dst.x = tmp.dst.y = 0;
tmp.dst.width = dst->drawable.width;
tmp.dst.height = dst->drawable.height;
- tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
tmp.dst.bo = dst_bo;
tmp.dst.x = dst_dx;
tmp.dst.y = dst_dy;
@@ -3134,7 +3119,7 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
tmp.src.filter = SAMPLER_FILTER_NEAREST;
tmp.src.repeat = SAMPLER_EXTEND_NONE;
tmp.src.card_format =
- gen6_get_card_format_for_depth(src->drawable.depth),
+ gen6_get_card_format(tmp.src.pict_format);
tmp.src.width = src->drawable.width;
tmp.src.height = src->drawable.height;
@@ -3269,6 +3254,7 @@ gen6_render_copy(struct sna *sna, uint8_t alu,
if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
too_large(src->drawable.width, src->drawable.height) ||
too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
return FALSE;
@@ -3277,17 +3263,26 @@ gen6_render_copy(struct sna *sna, uint8_t alu,
op);
}
+ if (dst->drawable.depth == src->drawable.depth) {
+ op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+ op->base.src.pict_format = op->base.dst.format;
+ } else {
+ op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
+ op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
+ }
+ if (!gen6_check_format(op->base.src.pict_format))
+ goto fallback;
+
op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear;
op->base.dst.pixmap = dst;
op->base.dst.width = dst->drawable.width;
op->base.dst.height = dst->drawable.height;
- op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
op->base.dst.bo = dst_bo;
op->base.src.bo = src_bo;
op->base.src.card_format =
- gen6_get_card_format_for_depth(src->drawable.depth),
+ gen6_get_card_format(op->base.src.pict_format);
op->base.src.width = src->drawable.width;
op->base.src.height = src->drawable.height;
op->base.src.scale[0] = 1.f/src->drawable.width;
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 9665b3c8..b8e55659 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -216,7 +216,6 @@ static const struct formatinfo {
{PICT_r8g8b8, GEN7_SURFACEFORMAT_R8G8B8_UNORM},
{PICT_r5g6b5, GEN7_SURFACEFORMAT_B5G6R5_UNORM},
{PICT_a1r5g5b5, GEN7_SURFACEFORMAT_B5G5R5A1_UNORM},
- {PICT_x1r5g5b5, GEN7_SURFACEFORMAT_B5G5R5X1_UNORM},
{PICT_a2r10g10b10, GEN7_SURFACEFORMAT_B10G10R10A2_UNORM},
{PICT_x2r10g10b10, GEN7_SURFACEFORMAT_B10G10R10X2_UNORM},
{PICT_a2b10g10r10, GEN7_SURFACEFORMAT_R10G10B10A2_UNORM},
@@ -319,9 +318,9 @@ static Bool gen7_check_dst_format(PictFormat format)
return FALSE;
}
-static bool gen7_check_format(PicturePtr p)
+static bool gen7_check_format(uint32_t format)
{
- switch (p->format) {
+ switch (format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
case PICT_a8b8g8r8:
@@ -330,44 +329,17 @@ static bool gen7_check_format(PicturePtr p)
case PICT_x2r10g10b10:
case PICT_r8g8b8:
case PICT_r5g6b5:
- case PICT_x1r5g5b5:
case PICT_a1r5g5b5:
case PICT_a8:
case PICT_a4r4g4b4:
case PICT_x4r4g4b4:
return true;
default:
- DBG(("%s: unhandled format: %x\n", __FUNCTION__, p->format));
+ DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
return false;
}
}
-static uint32_t gen7_get_dest_format_for_depth(int depth)
-{
- switch (depth) {
- default: assert(0);
- case 32:
- case 24: return GEN7_SURFACEFORMAT_B8G8R8A8_UNORM;
- case 30: return GEN7_SURFACEFORMAT_B10G10R10A2_UNORM;
- case 16: return GEN7_SURFACEFORMAT_B5G6R5_UNORM;
- case 15: return GEN7_SURFACEFORMAT_B5G5R5A1_UNORM;
- case 8: return GEN7_SURFACEFORMAT_A8_UNORM;
- }
-}
-
-static uint32_t gen7_get_card_format_for_depth(int depth)
-{
- switch (depth) {
- default: assert(0);
- case 32: return GEN7_SURFACEFORMAT_B8G8R8A8_UNORM;
- case 30: return GEN7_SURFACEFORMAT_B10G10R10X2_UNORM;
- case 24: return GEN7_SURFACEFORMAT_B8G8R8X8_UNORM;
- case 16: return GEN7_SURFACEFORMAT_B5G6R5_UNORM;
- case 15: return GEN7_SURFACEFORMAT_B5G5R5X1_UNORM;
- case 8: return GEN7_SURFACEFORMAT_A8_UNORM;
- }
-}
-
static uint32_t gen7_filter(uint32_t filter)
{
switch (filter) {
@@ -1235,7 +1207,6 @@ static uint32_t gen7_get_card_format(PictFormat format)
if (gen7_tex_formats[i].pict_fmt == format)
return gen7_tex_formats[i].card_fmt;
}
- assert(0);
return -1;
}
@@ -2189,10 +2160,6 @@ gen7_composite_picture(struct sna *sna,
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
- if (!gen7_check_format(picture))
- return sna_render_picture_fixup(sna, picture, channel,
- x, y, w, h, dst_x, dst_y);
-
channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
channel->filter = picture->filter;
@@ -2214,6 +2181,9 @@ gen7_composite_picture(struct sna *sna,
channel->transform = picture->transform;
channel->card_format = gen7_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);
if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__,
@@ -2357,7 +2327,7 @@ has_alphamap(PicturePtr p)
static bool
source_fallback(PicturePtr p)
{
- return has_alphamap(p) || is_gradient(p) || !gen7_check_filter(p) || !gen7_check_repeat(p) || !gen7_check_format(p);
+ return has_alphamap(p) || is_gradient(p) || !gen7_check_filter(p) || !gen7_check_repeat(p) || !gen7_check_format(p->format);
}
static bool
@@ -2480,7 +2450,7 @@ reuse_source(struct sna *sna,
if (!gen7_check_filter(mask))
return FALSE;
- if (!gen7_check_format(mask))
+ if (!gen7_check_format(mask->format))
return FALSE;
DBG(("%s: reusing source channel for mask with a twist\n",
@@ -3015,7 +2985,7 @@ gen7_emit_copy_state(struct sna *sna,
binding_table[0] =
gen7_bind_bo(sna,
op->dst.bo, op->dst.width, op->dst.height,
- gen7_get_dest_format_for_depth(op->dst.pixmap->drawable.depth),
+ gen7_get_dest_format(op->dst.pixmap->drawable.depth),
TRUE);
binding_table[1] =
gen7_bind_bo(sna,
@@ -3080,11 +3050,26 @@ gen7_render_copy_boxes(struct sna *sna, uint8_t alu,
if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
too_large(src->drawable.width, src->drawable.height) ||
- too_large(dst->drawable.width, dst->drawable.height))
+ too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
+ if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
+ return FALSE;
+
return sna_blt_copy_boxes_fallback(sna, alu,
src, src_bo, src_dx, src_dy,
dst, dst_bo, dst_dx, dst_dy,
box, n);
+ }
+
+ if (dst->drawable.depth == src->drawable.depth) {
+ tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+ tmp.src.pict_format = tmp.dst.format;
+ } else {
+ tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+ tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
+ }
+ if (!gen7_check_format(tmp.src.pict_format))
+ goto fallback;
tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear;
@@ -3092,7 +3077,6 @@ gen7_render_copy_boxes(struct sna *sna, uint8_t alu,
tmp.dst.x = tmp.dst.y = 0;
tmp.dst.width = dst->drawable.width;
tmp.dst.height = dst->drawable.height;
- tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
tmp.dst.bo = dst_bo;
tmp.dst.x = dst_dx;
tmp.dst.y = dst_dy;
@@ -3101,7 +3085,7 @@ gen7_render_copy_boxes(struct sna *sna, uint8_t alu,
tmp.src.filter = SAMPLER_FILTER_NEAREST;
tmp.src.repeat = SAMPLER_EXTEND_NONE;
tmp.src.card_format =
- gen7_get_card_format_for_depth(src->drawable.depth),
+ gen7_get_card_format(tmp.src.pict_format);
tmp.src.width = src->drawable.width;
tmp.src.height = src->drawable.height;
@@ -3234,6 +3218,7 @@ gen7_render_copy(struct sna *sna, uint8_t alu,
if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
too_large(src->drawable.width, src->drawable.height) ||
too_large(dst->drawable.width, dst->drawable.height)) {
+fallback:
if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
return FALSE;
@@ -3241,18 +3226,26 @@ gen7_render_copy(struct sna *sna, uint8_t alu,
dst->drawable.bitsPerPixel,
op);
}
+ if (dst->drawable.depth == src->drawable.depth) {
+ op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
+ op->base.src.pict_format = op->base.dst.format;
+ } else {
+ op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
+ op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
+ }
+ if (!gen7_check_format(op->base.src.pict_format))
+ goto fallback;
op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear;
op->base.dst.pixmap = dst;
op->base.dst.width = dst->drawable.width;
op->base.dst.height = dst->drawable.height;
- op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
op->base.dst.bo = dst_bo;
op->base.src.bo = src_bo;
op->base.src.card_format =
- gen7_get_card_format_for_depth(src->drawable.depth),
+ gen7_get_card_format(op->base.src.pict_format);
op->base.src.width = src->drawable.width;
op->base.src.height = src->drawable.height;
op->base.src.scale[0] = 1.f/src->drawable.width;
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 5153d339..e9c85b7a 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -379,6 +379,7 @@ void sna_kgem_flush(struct kgem *kgem);
void sna_kgem_context_switch(struct kgem *kgem, int new_mode);
CARD32 sna_format_for_depth(int depth);
+CARD32 sna_render_format_for_depth(int depth);
void sna_debug_flush(struct sna *sna);
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 979b2b0c..a9a170a1 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -57,6 +57,22 @@ sna_format_for_depth(int depth)
}
}
+CARD32
+sna_render_format_for_depth(int depth)
+{
+ switch (depth) {
+ case 1: return PICT_a1;
+ case 4: return PICT_a4;
+ case 8: return PICT_a8;
+ case 15: return PICT_a1r5g5b5;
+ case 16: return PICT_r5g6b5;
+ case 30: return PICT_a2r10g10b10;
+ default: assert(0);
+ case 24:
+ case 32: return PICT_a8r8g8b8;
+ }
+}
+
static Bool
no_render_composite(struct sna *sna,
uint8_t op,