[Mesa-dev] [PATCH v2 5/5] st/xa: handle xrgb->a better
Rob Clark
robdclark at gmail.com
Tue Apr 8 13:48:53 PDT 2014
From: Rob Clark <robclark at freedesktop.org>
Detect the edge cases where texture fetch is unneeded (due to alpha
channel being wired to 1.0 and non-alpha components thrown out).
Signed-off-by: Rob Clark <robclark at freedesktop.org>
---
src/gallium/state_trackers/xa/xa_composite.c | 13 +++++++--
src/gallium/state_trackers/xa/xa_priv.h | 10 +++++++
src/gallium/state_trackers/xa/xa_tgsi.c | 43 +++++++++++++++++++---------
3 files changed, 51 insertions(+), 15 deletions(-)
diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c
index b70fd47..7f7e3e4 100644
--- a/src/gallium/state_trackers/xa/xa_composite.c
+++ b/src/gallium/state_trackers/xa/xa_composite.c
@@ -315,6 +315,7 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
struct xa_shader shader;
struct xa_picture *src_pic = comp->src;
struct xa_picture *mask_pic = comp->mask;
+ struct xa_picture *dst_pic = comp->dst;
ctx->has_solid_color = FALSE;
@@ -335,6 +336,9 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
vs_traits |= VS_COMPOSITE;
}
+ if (is_xrgb_to_alpha(dst_pic, src_pic))
+ ctx->has_solid_color = TRUE;
+
fs_traits |= picture_format_fixups(src_pic, 0);
}
@@ -351,6 +355,8 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
xa_pixel_to_float4(mask_pic->src_pict->solid_fill.color,
ctx->solid_mask);
ctx->has_solid_mask = TRUE;
+ } else if (is_xrgb_to_alpha(dst_pic, mask_pic)) {
+ ctx->has_solid_mask = TRUE;
}
if (mask_pic->component_alpha) {
@@ -387,6 +393,7 @@ bind_samplers(struct xa_context *ctx,
struct pipe_context *pipe = ctx->pipe;
struct xa_picture *src_pic = comp->src;
struct xa_picture *mask_pic = comp->mask;
+ struct xa_picture *dst_pic = comp->dst;
unsigned n = 0;
/* unref old sampler views: */
@@ -395,7 +402,8 @@ bind_samplers(struct xa_context *ctx,
memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
- if (src_pic && !is_solid_fill(src_pic)) {
+ if (src_pic && !is_solid_fill(src_pic) &&
+ !is_xrgb_to_alpha(dst_pic, src_pic)) {
unsigned src_wrap = xa_repeat_to_gallium(src_pic->wrap);
int filter;
@@ -418,7 +426,8 @@ bind_samplers(struct xa_context *ctx,
n++;
}
- if (mask_pic && !is_solid_fill(mask_pic)) {
+ if (mask_pic && !is_solid_fill(mask_pic) &&
+ !is_xrgb_to_alpha(dst_pic, mask_pic)) {
unsigned mask_wrap = xa_repeat_to_gallium(mask_pic->wrap);
int filter;
diff --git a/src/gallium/state_trackers/xa/xa_priv.h b/src/gallium/state_trackers/xa/xa_priv.h
index 1ef810e..723ea4a 100644
--- a/src/gallium/state_trackers/xa/xa_priv.h
+++ b/src/gallium/state_trackers/xa/xa_priv.h
@@ -233,6 +233,16 @@ is_solid_fill(struct xa_picture *pic)
return pic->src_pict && (pic->src_pict->type == xa_src_pict_solid_fill);
}
+/* a8 dst and xRGB src (or mask) is a special case. The texture fetch
+ * is optimized out.
+ */
+static INLINE int
+is_xrgb_to_alpha(struct xa_picture *dst, struct xa_picture *src)
+{
+ return (dst->pict_format == xa_format_a8) &&
+ (xa_format_a(src->pict_format) == 0);
+}
+
/*
* xa_tgsi.c
*/
diff --git a/src/gallium/state_trackers/xa/xa_tgsi.c b/src/gallium/state_trackers/xa/xa_tgsi.c
index e96bc53..b7e0fe1 100644
--- a/src/gallium/state_trackers/xa/xa_tgsi.c
+++ b/src/gallium/state_trackers/xa/xa_tgsi.c
@@ -479,10 +479,12 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
}
if (is_composite) {
- src_sampler = ureg_DECL_sampler(ureg, n++);
- src_input = ureg_DECL_fs_input(ureg,
- TGSI_SEMANTIC_GENERIC, 0,
- TGSI_INTERPOLATE_PERSPECTIVE);
+ if (!(dst_luminance && src_set_alpha)) {
+ src_sampler = ureg_DECL_sampler(ureg, n++);
+ src_input = ureg_DECL_fs_input(ureg,
+ TGSI_SEMANTIC_GENERIC, 0,
+ TGSI_INTERPOLATE_PERSPECTIVE);
+ }
} else if (is_fill) {
if (is_solid)
src_input = ureg_DECL_fs_input(ureg,
@@ -502,10 +504,12 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
TGSI_SEMANTIC_COLOR, 1,
TGSI_INTERPOLATE_PERSPECTIVE);
} else if (has_mask) {
- mask_sampler = ureg_DECL_sampler(ureg, n++);
- mask_pos = ureg_DECL_fs_input(ureg,
- TGSI_SEMANTIC_GENERIC, 1,
- TGSI_INTERPOLATE_PERSPECTIVE);
+ if (!(dst_luminance && mask_set_alpha)) {
+ mask_sampler = ureg_DECL_sampler(ureg, n++);
+ mask_pos = ureg_DECL_fs_input(ureg,
+ TGSI_SEMANTIC_GENERIC, 1,
+ TGSI_INTERPOLATE_PERSPECTIVE);
+ }
}
#if 0 /* unused right now */
dst_sampler = ureg_DECL_sampler(ureg, 2);
@@ -519,14 +523,22 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
src = ureg_DECL_temporary(ureg);
else
src = out;
- xrender_tex(ureg, src, src_input, src_sampler, imm0,
+
+ if (dst_luminance && src_set_alpha) {
+ ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_W),
+ ureg_scalar(imm0, TGSI_SWIZZLE_W));
+ } else {
+ xrender_tex(ureg, src, src_input, src_sampler, imm0,
src_repeat_none, src_swizzle, src_set_alpha);
+ }
} else if (is_fill) {
if (is_solid) {
- if (has_mask || src_luminance || dst_luminance)
- src = ureg_dst(src_input);
- else
+ if (has_mask || src_luminance || dst_luminance) {
+ src = ureg_DECL_temporary(ureg);
+ ureg_MOV(ureg, src, src_input);
+ } else {
ureg_MOV(ureg, out, src_input);
+ }
} else if (is_lingrad || is_radgrad) {
struct ureg_src coords, const0124, matrow0, matrow1, matrow2;
@@ -565,8 +577,13 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
mask = ureg_dst(mask_pos);
} else if (has_mask) {
mask = ureg_DECL_temporary(ureg);
- xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
+ if (dst_luminance && mask_set_alpha) {
+ ureg_MOV(ureg, ureg_writemask(mask, TGSI_WRITEMASK_W),
+ ureg_scalar(imm0, TGSI_SWIZZLE_W));
+ } else {
+ xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
mask_repeat_none, mask_swizzle, mask_set_alpha);
+ }
}
if (has_mask) {
--
1.9.0
More information about the mesa-dev
mailing list