[Mesa-dev] [PATCH v2 4/5] st/xa: handle solid-fill src/mask

Rob Clark robdclark at gmail.com
Tue Apr 8 13:48:52 PDT 2014


From: Rob Clark <robclark at freedesktop.org>

Add support to property handle solid-fill src and/or mask.  Without this
we fallback to sw a lot for common things like text rendering.

Signed-off-by: Rob Clark <robclark at freedesktop.org>
---
 src/gallium/state_trackers/xa/xa_composite.c | 115 +++++------
 src/gallium/state_trackers/xa/xa_priv.h      |  13 +-
 src/gallium/state_trackers/xa/xa_renderer.c  | 298 ++++++++++++++++-----------
 src/gallium/state_trackers/xa/xa_tgsi.c      |  36 +++-
 4 files changed, 263 insertions(+), 199 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c
index 7ae35a1..b70fd47 100644
--- a/src/gallium/state_trackers/xa/xa_composite.c
+++ b/src/gallium/state_trackers/xa/xa_composite.c
@@ -111,12 +111,6 @@ blend_for_op(struct xa_composite_blend *blend,
     boolean supported = FALSE;
 
     /*
-     * Temporarily disable component alpha since it appears buggy.
-     */
-    if (mask_pic && mask_pic->component_alpha)
-	return FALSE;
-
-    /*
      * our default in case something goes wrong
      */
     *blend = xa_blends[XA_BLEND_OP_OVER];
@@ -125,6 +119,7 @@ blend_for_op(struct xa_composite_blend *blend,
 	if (xa_blends[i].op == op) {
 	    *blend = xa_blends[i];
 	    supported = TRUE;
+	    break;
 	}
     }
 
@@ -227,14 +222,6 @@ xa_composite_check_accelerated(const struct xa_composite *comp)
     if (src_pic->src_pict) {
 	if (src_pic->src_pict->type != xa_src_pict_solid_fill)
 	    return -XA_ERR_INVAL;
-
-	/*
-	 * Currently we don't support solid fill with a mask.
-	 * We can easily do that, but that would require shader,
-	 * sampler view setup and vertex setup modification.
-	 */
-	if (comp->mask)
-	    return -XA_ERR_INVAL;
     }
 
     if (blend_for_op(&blend, comp->op, comp->src, comp->mask, comp->dst)) {
@@ -336,8 +323,8 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
 	    fs_traits |= FS_SRC_REPEAT_NONE;
 
 	if (src_pic->src_pict) {
-	    if (src_pic->src_pict->type == xa_src_pict_solid_fill) {
-		fs_traits |= FS_SOLID_FILL | FS_FILL;
+	    if (is_solid_fill(src_pic)) {
+		fs_traits |= FS_SOLID_FILL;
 		vs_traits |= VS_SOLID_FILL;
 		xa_pixel_to_float4(src_pic->src_pict->solid_fill.color,
 				   ctx->solid_color);
@@ -358,9 +345,17 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
 	    mask_pic->has_transform)
 	    fs_traits |= FS_MASK_REPEAT_NONE;
 
+	if (is_solid_fill(mask_pic)) {
+	    fs_traits |= FS_SOLID_MASK;
+	    vs_traits |= VS_SOLID_MASK;
+	    xa_pixel_to_float4(mask_pic->src_pict->solid_fill.color,
+		    ctx->solid_mask);
+	    ctx->has_solid_mask = TRUE;
+	}
+
 	if (mask_pic->component_alpha) {
 	    struct xa_composite_blend blend;
-	    if (!blend_for_op(&blend, comp->op, src_pic, mask_pic, NULL))
+	    if (!blend_for_op(&blend, comp->op, src_pic, mask_pic, comp->dst))
 		return -XA_ERR_INVAL;
 
 	    if (blend.alpha_src) {
@@ -392,41 +387,38 @@ 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;
+    unsigned n = 0;
 
-    ctx->num_bound_samplers = 0;
+    /* unref old sampler views: */
+    xa_ctx_sampler_views_destroy(ctx);
 
     memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
     memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
 
-    if (src_pic) {
-	if (ctx->has_solid_color) {
-	    samplers[0] = NULL;
-	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL);
-	} else {
-	    unsigned src_wrap = xa_repeat_to_gallium(src_pic->wrap);
-	    int filter;
-
-	    (void) xa_filter_to_gallium(src_pic->filter, &filter);
-
-	    src_sampler.wrap_s = src_wrap;
-	    src_sampler.wrap_t = src_wrap;
-	    src_sampler.min_img_filter = filter;
-	    src_sampler.mag_img_filter = filter;
-	    src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
-	    src_sampler.normalized_coords = 1;
-	    samplers[0] = &src_sampler;
-	    ctx->num_bound_samplers = 1;
-	    u_sampler_view_default_template(&view_templ,
-					    src_pic->srf->tex,
-					    src_pic->srf->tex->format);
-	    src_view = pipe->create_sampler_view(pipe, src_pic->srf->tex,
-						 &view_templ);
-	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL);
-	    ctx->bound_sampler_views[0] = src_view;
-	}
+    if (src_pic && !is_solid_fill(src_pic)) {
+	unsigned src_wrap = xa_repeat_to_gallium(src_pic->wrap);
+	int filter;
+
+	(void) xa_filter_to_gallium(src_pic->filter, &filter);
+
+	src_sampler.wrap_s = src_wrap;
+	src_sampler.wrap_t = src_wrap;
+	src_sampler.min_img_filter = filter;
+	src_sampler.mag_img_filter = filter;
+	src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
+	src_sampler.normalized_coords = 1;
+	samplers[n] = &src_sampler;
+	u_sampler_view_default_template(&view_templ,
+		src_pic->srf->tex,
+		src_pic->srf->tex->format);
+	src_view = pipe->create_sampler_view(pipe, src_pic->srf->tex,
+		&view_templ);
+	ctx->bound_sampler_views[n] = src_view;
+
+	n++;
     }
 
-    if (mask_pic) {
+    if (mask_pic && !is_solid_fill(mask_pic)) {
 	unsigned mask_wrap = xa_repeat_to_gallium(mask_pic->wrap);
 	int filter;
 
@@ -438,30 +430,24 @@ bind_samplers(struct xa_context *ctx,
 	mask_sampler.mag_img_filter = filter;
 	src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
 	mask_sampler.normalized_coords = 1;
-	samplers[1] = &mask_sampler;
+	samplers[n] = &mask_sampler;
 	ctx->num_bound_samplers = 2;
 	u_sampler_view_default_template(&view_templ,
-					mask_pic->srf->tex,
-					mask_pic->srf->tex->format);
+		mask_pic->srf->tex,
+		mask_pic->srf->tex->format);
 	src_view = pipe->create_sampler_view(pipe, mask_pic->srf->tex,
-					     &view_templ);
+		&view_templ);
 	pipe_sampler_view_reference(&ctx->bound_sampler_views[1], NULL);
-	ctx->bound_sampler_views[1] = src_view;
-
-
-	/*
-	 * If src is a solid color, we have no src view, so set up a
-	 * dummy one that will not be used anyway.
-	 */
-	if (ctx->bound_sampler_views[0] == NULL)
-	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0],
-					src_view);
+	ctx->bound_sampler_views[n] = src_view;
 
+	n++;
     }
 
-    cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, ctx->num_bound_samplers,
+    ctx->num_bound_samplers = n;
+
+    cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, n,
 		     (const struct pipe_sampler_state **)samplers);
-    cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, ctx->num_bound_samplers,
+    cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, n,
 				   ctx->bound_sampler_views);
 }
 
@@ -487,10 +473,10 @@ xa_composite_prepare(struct xa_context *ctx,
 	return ret;
     bind_samplers(ctx, comp);
 
-    if (ctx->num_bound_samplers == 0 ) { /* solid fill */
+    if (ctx->num_bound_samplers == 0 && !ctx->has_solid_mask) { /* solid fill */
 	renderer_begin_solid(ctx);
     } else {
-	renderer_begin_textures(ctx);
+	renderer_begin_textures(ctx, comp);
 	ctx->comp = comp;
     }
 
@@ -503,7 +489,7 @@ xa_composite_rect(struct xa_context *ctx,
 		  int srcX, int srcY, int maskX, int maskY,
 		  int dstX, int dstY, int width, int height)
 {
-    if (ctx->num_bound_samplers == 0 ) { /* solid fill */
+    if ((ctx->num_bound_samplers == 0) && !ctx->has_solid_mask) { /* solid fill */
 	renderer_solid(ctx, dstX, dstY, dstX + width, dstY + height,
 		       ctx->solid_color);
     } else {
@@ -531,6 +517,7 @@ xa_composite_done(struct xa_context *ctx)
 
     ctx->comp = NULL;
     ctx->has_solid_color = FALSE;
+    ctx->has_solid_mask = FALSE;
     xa_ctx_sampler_views_destroy(ctx);
 }
 
diff --git a/src/gallium/state_trackers/xa/xa_priv.h b/src/gallium/state_trackers/xa/xa_priv.h
index b673379..1ef810e 100644
--- a/src/gallium/state_trackers/xa/xa_priv.h
+++ b/src/gallium/state_trackers/xa/xa_priv.h
@@ -118,6 +118,9 @@ struct xa_context {
     int has_solid_color;
     float solid_color[4];
 
+    int has_solid_mask;
+    float solid_mask[4];
+
     unsigned int num_bound_samplers;
     struct pipe_sampler_view *bound_sampler_views[XA_MAX_SAMPLERS];
     const struct xa_composite *comp;
@@ -151,6 +154,7 @@ enum xa_vs_traits {
     VS_LINGRAD_FILL = 1 << 3,
     VS_RADGRAD_FILL = 1 << 4,
     VS_YUV = 1 << 5,
+    VS_SOLID_MASK = 1 << 6,
 
     VS_FILL = (VS_SOLID_FILL | VS_LINGRAD_FILL | VS_RADGRAD_FILL)
 };
@@ -173,6 +177,7 @@ enum xa_fs_traits {
     FS_SRC_LUMINANCE = 1 << 14,
     FS_MASK_LUMINANCE = 1 << 15,
     FS_DST_LUMINANCE = 1 << 16,
+    FS_SOLID_MASK = 1 << 17,
 
     FS_FILL = (FS_SOLID_FILL | FS_LINGRAD_FILL | FS_RADGRAD_FILL),
     FS_COMPONENT_ALPHA = (FS_CA_FULL | FS_CA_SRCALPHA)
@@ -222,6 +227,12 @@ xa_pixel_to_float4_a8(uint32_t pixel, float *color)
     color[3] = ((float)a) / 255.;
 }
 
+static INLINE int
+is_solid_fill(struct xa_picture *pic)
+{
+    return pic->src_pict && (pic->src_pict->type == xa_src_pict_solid_fill);
+}
+
 /*
  * xa_tgsi.c
  */
@@ -286,7 +297,7 @@ void renderer_begin_solid(struct xa_context *r);
 void renderer_solid(struct xa_context *r,
 		    int x0, int y0, int x1, int y1, float *color);
 void
-renderer_begin_textures(struct xa_context *r);
+renderer_begin_textures(struct xa_context *r, const struct xa_composite *comp);
 
 void
 renderer_texture(struct xa_context *r,
diff --git a/src/gallium/state_trackers/xa/xa_renderer.c b/src/gallium/state_trackers/xa/xa_renderer.c
index 121d8ed..9d8c57e 100644
--- a/src/gallium/state_trackers/xa/xa_renderer.c
+++ b/src/gallium/state_trackers/xa/xa_renderer.c
@@ -136,7 +136,7 @@ renderer_init_state(struct xa_context *r)
 }
 
 static INLINE void
-add_vertex_color(struct xa_context *r, float x, float y, float color[4])
+add_vertex_coord(struct xa_context *r, float x, float y)
 {
     float *vertex = r->buffer + r->buffer_size;
 
@@ -145,98 +145,86 @@ add_vertex_color(struct xa_context *r, float x, float y, float color[4])
     vertex[2] = 0.f;		/*z */
     vertex[3] = 1.f;		/*w */
 
-    vertex[4] = color[0];	/*r */
-    vertex[5] = color[1];	/*g */
-    vertex[6] = color[2];	/*b */
-    vertex[7] = color[3];	/*a */
-
-    r->buffer_size += 8;
+    r->buffer_size += 4;
 }
 
 static INLINE void
-add_vertex_1tex(struct xa_context *r, float x, float y, float s, float t)
+add_vertex_color(struct xa_context *r, const float *color)
 {
     float *vertex = r->buffer + r->buffer_size;
 
-    vertex[0] = x;
-    vertex[1] = y;
-    vertex[2] = 0.f;		/*z */
-    vertex[3] = 1.f;		/*w */
-
-    vertex[4] = s;		/*s */
-    vertex[5] = t;		/*t */
-    vertex[6] = 0.f;		/*r */
-    vertex[7] = 1.f;		/*q */
+    vertex[0] = color[0];	/*r */
+    vertex[1] = color[1];	/*g */
+    vertex[2] = color[2];	/*b */
+    vertex[3] = color[3];	/*a */
 
-    r->buffer_size += 8;
-}
-
-static INLINE void
-add_vertex_2tex(struct xa_context *r,
-		float x, float y, float s0, float t0, float s1, float t1)
-{
-    float *vertex = r->buffer + r->buffer_size;
-
-    vertex[0] = x;
-    vertex[1] = y;
-    vertex[2] = 0.f;		/*z */
-    vertex[3] = 1.f;		/*w */
-
-    vertex[4] = s0;		/*s */
-    vertex[5] = t0;		/*t */
-    vertex[6] = 0.f;		/*r */
-    vertex[7] = 1.f;		/*q */
-
-    vertex[8] = s1;		/*s */
-    vertex[9] = t1;		/*t */
-    vertex[10] = 0.f;		/*r */
-    vertex[11] = 1.f;		/*q */
-
-    r->buffer_size += 12;
+    r->buffer_size += 4;
 }
 
 static void
 add_vertex_data1(struct xa_context *r,
                  float srcX, float srcY,  float dstX, float dstY,
                  float width, float height,
-                 struct pipe_resource *src, const float *src_matrix)
+                 struct pipe_resource *src, const float *src_matrix,
+                 const float *src_color)
 {
     float s0, t0, s1, t1, s2, t2, s3, t3;
-    float pt0[2], pt1[2], pt2[2], pt3[2];
-
-    pt0[0] = srcX;
-    pt0[1] = srcY;
-    pt1[0] = (srcX + width);
-    pt1[1] = srcY;
-    pt2[0] = (srcX + width);
-    pt2[1] = (srcY + height);
-    pt3[0] = srcX;
-    pt3[1] = (srcY + height);
 
-    if (src_matrix) {
-	map_point((float *)src_matrix, pt0[0], pt0[1], &pt0[0], &pt0[1]);
-	map_point((float *)src_matrix, pt1[0], pt1[1], &pt1[0], &pt1[1]);
-	map_point((float *)src_matrix, pt2[0], pt2[1], &pt2[0], &pt2[1]);
-	map_point((float *)src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]);
+    if (src) {
+	float pt0[2], pt1[2], pt2[2], pt3[2];
+
+	pt0[0] = srcX;
+	pt0[1] = srcY;
+	pt1[0] = (srcX + width);
+	pt1[1] = srcY;
+	pt2[0] = (srcX + width);
+	pt2[1] = (srcY + height);
+	pt3[0] = srcX;
+	pt3[1] = (srcY + height);
+
+	if (src_matrix) {
+	    map_point((float *)src_matrix, pt0[0], pt0[1], &pt0[0], &pt0[1]);
+	    map_point((float *)src_matrix, pt1[0], pt1[1], &pt1[0], &pt1[1]);
+	    map_point((float *)src_matrix, pt2[0], pt2[1], &pt2[0], &pt2[1]);
+	    map_point((float *)src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]);
+	}
+
+	s0 =  pt0[0] / src->width0;
+	s1 =  pt1[0] / src->width0;
+	s2 =  pt2[0] / src->width0;
+	s3 =  pt3[0] / src->width0;
+	t0 =  pt0[1] / src->height0;
+	t1 =  pt1[1] / src->height0;
+	t2 =  pt2[1] / src->height0;
+	t3 =  pt3[1] / src->height0;
+    } else {
+	s0 = s1 = s2 = s3 = t0 = t1 = t2 = t3 = 0.0;
     }
 
-    s0 =  pt0[0] / src->width0;
-    s1 =  pt1[0] / src->width0;
-    s2 =  pt2[0] / src->width0;
-    s3 =  pt3[0] / src->width0;
-    t0 =  pt0[1] / src->height0;
-    t1 =  pt1[1] / src->height0;
-    t2 =  pt2[1] / src->height0;
-    t3 =  pt3[1] / src->height0;
-
     /* 1st vertex */
-    add_vertex_1tex(r, dstX, dstY, s0, t0);
+    add_vertex_coord(r, dstX, dstY);
+    if (src_color)
+	add_vertex_color(r, src_color);
+    else
+	add_vertex_coord(r, s0, t0);
     /* 2nd vertex */
-    add_vertex_1tex(r, dstX + width, dstY, s1, t1);
+    add_vertex_coord(r, dstX + width, dstY);
+    if (src_color)
+	add_vertex_color(r, src_color);
+    else
+	add_vertex_coord(r, s1, t1);
     /* 3rd vertex */
-    add_vertex_1tex(r, dstX + width, dstY + height, s2, t2);
+    add_vertex_coord(r, dstX + width, dstY + height);
+    if (src_color)
+	add_vertex_color(r, src_color);
+    else
+	add_vertex_coord(r, s2, t2);
     /* 4th vertex */
-    add_vertex_1tex(r, dstX, dstY + height, s3, t3);
+    add_vertex_coord(r, dstX, dstY + height);
+    if (src_color)
+	add_vertex_color(r, src_color);
+    else
+	add_vertex_coord(r, s3, t3);
 }
 
 static void
@@ -245,55 +233,95 @@ add_vertex_data2(struct xa_context *r,
                  float dstX, float dstY, float width, float height,
                  struct pipe_resource *src,
                  struct pipe_resource *mask,
-                 const float *src_matrix, const float *mask_matrix)
+                 const float *src_matrix, const float *src_color,
+                 const float *mask_matrix, const float *mask_color)
 {
     float src_s0, src_t0, src_s1, src_t1;
     float mask_s0, mask_t0, mask_s1, mask_t1;
-    float spt0[2], spt1[2];
-    float mpt0[2], mpt1[2];
 
-    spt0[0] = srcX;
-    spt0[1] = srcY;
-    spt1[0] = srcX + width;
-    spt1[1] = srcY + height;
 
-    mpt0[0] = maskX;
-    mpt0[1] = maskY;
-    mpt1[0] = maskX + width;
-    mpt1[1] = maskY + height;
+    if (src) {
+	float spt0[2], spt1[2];
 
-    if (src_matrix) {
-	map_point((float *)src_matrix, spt0[0], spt0[1], &spt0[0], &spt0[1]);
-	map_point((float *)src_matrix, spt1[0], spt1[1], &spt1[0], &spt1[1]);
-    }
+	spt0[0] = srcX;
+	spt0[1] = srcY;
+	spt1[0] = srcX + width;
+	spt1[1] = srcY + height;
 
-    if (mask_matrix) {
-	map_point((float *)mask_matrix, mpt0[0], mpt0[1], &mpt0[0], &mpt0[1]);
-	map_point((float *)mask_matrix, mpt1[0], mpt1[1], &mpt1[0], &mpt1[1]);
-    }
+	if (src_matrix) {
+	    map_point((float *)src_matrix, spt0[0], spt0[1], &spt0[0], &spt0[1]);
+	    map_point((float *)src_matrix, spt1[0], spt1[1], &spt1[0], &spt1[1]);
+	}
 
-    src_s0 = spt0[0] / src->width0;
-    src_t0 = spt0[1] / src->height0;
-    src_s1 = spt1[0] / src->width0;
-    src_t1 = spt1[1] / src->height0;
+	src_s0 = spt0[0] / src->width0;
+	src_t0 = spt0[1] / src->height0;
+	src_s1 = spt1[0] / src->width0;
+	src_t1 = spt1[1] / src->height0;
+    } else {
+	src_s0 = src_t0 = src_s1 = src_t1 = 0.0;
+    }
 
-    mask_s0 = mpt0[0] / mask->width0;
-    mask_t0 = mpt0[1] / mask->height0;
-    mask_s1 = mpt1[0] / mask->width0;
-    mask_t1 = mpt1[1] / mask->height0;
+    if (mask) {
+	float mpt0[2], mpt1[2];
+
+	mpt0[0] = maskX;
+	mpt0[1] = maskY;
+	mpt1[0] = maskX + width;
+	mpt1[1] = maskY + height;
+
+	if (mask_matrix) {
+	    map_point((float *)mask_matrix, mpt0[0], mpt0[1], &mpt0[0], &mpt0[1]);
+	    map_point((float *)mask_matrix, mpt1[0], mpt1[1], &mpt1[0], &mpt1[1]);
+	}
+
+	mask_s0 = mpt0[0] / mask->width0;
+	mask_t0 = mpt0[1] / mask->height0;
+	mask_s1 = mpt1[0] / mask->width0;
+	mask_t1 = mpt1[1] / mask->height0;
+    } else {
+	mask_s0 = mask_t0 = mask_s1 = mask_t1 = 0.0;
+    }
 
     /* 1st vertex */
-    add_vertex_2tex(r, dstX, dstY,
-		    src_s0, src_t0, mask_s0, mask_t0);
+    add_vertex_coord(r, dstX, dstY);
+    if (src_color)
+	add_vertex_color(r, src_color);
+    else
+	add_vertex_coord(r, src_s0, src_t0);
+    if (mask_color)
+	add_vertex_color(r, mask_color);
+    else
+	add_vertex_coord(r, mask_s0, mask_t0);
     /* 2nd vertex */
-    add_vertex_2tex(r, dstX + width, dstY,
-		    src_s1, src_t0, mask_s1, mask_t0);
+    add_vertex_coord(r, dstX + width, dstY);
+    if (src_color)
+	add_vertex_color(r, src_color);
+    else
+	add_vertex_coord(r, src_s1, src_t0);
+    if (mask_color)
+	add_vertex_color(r, mask_color);
+    else
+	add_vertex_coord(r, mask_s1, mask_t0);
     /* 3rd vertex */
-    add_vertex_2tex(r, dstX + width, dstY + height,
-		    src_s1, src_t1, mask_s1, mask_t1);
+    add_vertex_coord(r, dstX + width, dstY + height);
+    if (src_color)
+	add_vertex_color(r, src_color);
+    else
+	add_vertex_coord(r, src_s1, src_t1);
+    if (mask_color)
+	add_vertex_color(r, mask_color);
+    else
+	add_vertex_coord(r, mask_s1, mask_t1);
     /* 4th vertex */
-    add_vertex_2tex(r, dstX, dstY + height,
-		    src_s0, src_t1, mask_s0, mask_t1);
+    add_vertex_coord(r, dstX, dstY + height);
+    if (src_color)
+	add_vertex_color(r, src_color);
+    else
+	add_vertex_coord(r, src_s0, src_t1);
+    if (mask_color)
+	add_vertex_color(r, mask_color);
+    else
+	add_vertex_coord(r, mask_s0, mask_t1);
 }
 
 static void
@@ -322,13 +350,17 @@ setup_vertex_data_yuv(struct xa_context *r,
     t1 = spt1[1] / tex->height0;
 
     /* 1st vertex */
-    add_vertex_1tex(r, dstX, dstY, s0, t0);
+    add_vertex_coord(r, dstX, dstY);
+    add_vertex_coord(r, s0, t0);
     /* 2nd vertex */
-    add_vertex_1tex(r, dstX + dstW, dstY, s1, t0);
+    add_vertex_coord(r, dstX + dstW, dstY);
+    add_vertex_coord(r, s1, t0);
     /* 3rd vertex */
-    add_vertex_1tex(r, dstX + dstW, dstY + dstH, s1, t1);
+    add_vertex_coord(r, dstX + dstW, dstY + dstH);
+    add_vertex_coord(r, s1, t1);
     /* 4th vertex */
-    add_vertex_1tex(r, dstX, dstY + dstH, s0, t1);
+    add_vertex_coord(r, dstX, dstY + dstH);
+    add_vertex_coord(r, s0, t1);
 }
 
 /* Set up framebuffer, viewport and vertex shader constant buffer
@@ -509,10 +541,14 @@ renderer_copy(struct xa_context *r,
 
     /* draw quad */
     renderer_draw_conditional(r, 4 * 8);
-    add_vertex_1tex(r, x0, y0, s0, t0);
-    add_vertex_1tex(r, x1, y0, s1, t0);
-    add_vertex_1tex(r, x1, y1, s1, t1);
-    add_vertex_1tex(r, x0, y1, s0, t1);
+    add_vertex_coord(r, x0, y0);
+    add_vertex_coord(r, s0, t0);
+    add_vertex_coord(r, x1, y0);
+    add_vertex_coord(r, s1, t0);
+    add_vertex_coord(r, x1, y1);
+    add_vertex_coord(r, s1, t1);
+    add_vertex_coord(r, x0, y1);
+    add_vertex_coord(r, s0, t1);
 }
 
 void
@@ -555,13 +591,17 @@ renderer_solid(struct xa_context *r,
     renderer_draw_conditional(r, 4 * 8);
 
     /* 1st vertex */
-    add_vertex_color(r, x0, y0, color);
+    add_vertex_coord(r, x0, y0);
+    add_vertex_color(r, color);
     /* 2nd vertex */
-    add_vertex_color(r, x1, y0, color);
+    add_vertex_coord(r, x1, y0);
+    add_vertex_color(r, color);
     /* 3rd vertex */
-    add_vertex_color(r, x1, y1, color);
+    add_vertex_coord(r, x1, y1);
+    add_vertex_color(r, color);
     /* 4th vertex */
-    add_vertex_color(r, x0, y1, color);
+    add_vertex_coord(r, x0, y1);
+    add_vertex_color(r, color);
 }
 
 void
@@ -571,9 +611,14 @@ renderer_draw_flush(struct xa_context *r)
 }
 
 void
-renderer_begin_textures(struct xa_context *r)
+renderer_begin_textures(struct xa_context *r,
+	const struct xa_composite *comp)
 {
-    r->attrs_per_vertex = 1 + r->num_bound_samplers;
+    r->attrs_per_vertex = 1;
+    if (comp->src)
+	r->attrs_per_vertex++;
+    if (comp->mask)
+	r->attrs_per_vertex++;
     r->buffer_size = 0;
 }
 
@@ -585,6 +630,7 @@ renderer_texture(struct xa_context *r,
 		 const float *mask_matrix)
 {
     struct pipe_sampler_view **sampler_view = r->bound_sampler_views;
+    unsigned n = 0;
 
 #if 0
     if (src_matrix) {
@@ -608,7 +654,9 @@ renderer_texture(struct xa_context *r,
 			 pos[0], pos[1], /* src */
 			 pos[4], pos[5], /* dst */
 			 width, height,
-			 sampler_view[0]->texture, src_matrix);
+			 r->has_solid_color ? NULL : sampler_view[n++]->texture,
+			 r->has_solid_color ? NULL : src_matrix,
+			 r->has_solid_color ? r->solid_color : NULL);
 	break;
     case 3:
 	renderer_draw_conditional(r, 4 * 12);
@@ -617,8 +665,12 @@ renderer_texture(struct xa_context *r,
 			 pos[2], pos[3], /* mask */
 			 pos[4], pos[5], /* dst */
 			 width, height,
-			 sampler_view[0]->texture, sampler_view[1]->texture,
-			 src_matrix, mask_matrix);
+			 r->has_solid_color ? NULL : sampler_view[n++]->texture,
+			 r->has_solid_mask ? NULL : sampler_view[n++]->texture,
+			 r->has_solid_color ? NULL : src_matrix,
+			 r->has_solid_color ? r->solid_color : NULL,
+			 r->has_solid_mask ? NULL : mask_matrix,
+			 r->has_solid_mask ? r->solid_mask : NULL);
 	break;
     default:
 	break;
diff --git a/src/gallium/state_trackers/xa/xa_tgsi.c b/src/gallium/state_trackers/xa/xa_tgsi.c
index c7454c9..e96bc53 100644
--- a/src/gallium/state_trackers/xa/xa_tgsi.c
+++ b/src/gallium/state_trackers/xa/xa_tgsi.c
@@ -42,14 +42,14 @@
 /* Vertex shader:
  * IN[0]    = vertex pos
  * IN[1]    = src tex coord | solid fill color
- * IN[2]    = mask tex coord
+ * IN[2]    = mask tex coord | solid mask color
  * IN[3]    = dst tex coord
  * CONST[0] = (2/dst_width, 2/dst_height, 1, 1)
  * CONST[1] = (-1, -1, 0, 0)
  *
  * OUT[0]   = vertex pos
  * OUT[1]   = src tex coord | solid fill color
- * OUT[2]   = mask tex coord
+ * OUT[2]   = mask tex coord | solid mask color
  * OUT[3]   = dst tex coord
  */
 
@@ -58,7 +58,7 @@
  * SAMP[1]  = mask
  * SAMP[2]  = dst
  * IN[0]    = pos src | solid fill color
- * IN[1]    = pos mask
+ * IN[1]    = pos mask | solid mask color
  * IN[2]    = pos dst
  * CONST[0] = (0, 0, 0, 1)
  *
@@ -268,6 +268,7 @@ create_vs(struct pipe_context *pipe, unsigned vs_traits)
     boolean is_fill = (vs_traits & VS_FILL) != 0;
     boolean is_composite = (vs_traits & VS_COMPOSITE) != 0;
     boolean has_mask = (vs_traits & VS_MASK) != 0;
+    boolean is_solid_mask = (vs_traits & VS_SOLID_MASK) != 0;
     boolean is_yuv = (vs_traits & VS_YUV) != 0;
     unsigned input_slot = 0;
 
@@ -296,15 +297,17 @@ create_vs(struct pipe_context *pipe, unsigned vs_traits)
 	src = ureg_DECL_vs_input(ureg, input_slot++);
 	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
 	ureg_MOV(ureg, dst, src);
-    }
-
-    if (is_fill) {
+    } else if (is_fill) {
 	src = ureg_DECL_vs_input(ureg, input_slot++);
 	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
 	ureg_MOV(ureg, dst, src);
     }
 
-    if (has_mask) {
+    if (is_solid_mask) {
+	src = ureg_DECL_vs_input(ureg, input_slot++);
+	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 1);
+	ureg_MOV(ureg, dst, src);
+    } else if (has_mask) {
 	src = ureg_DECL_vs_input(ureg, input_slot++);
 	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
 	ureg_MOV(ureg, dst, src);
@@ -436,6 +439,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
     struct ureg_dst out;
     struct ureg_src imm0 = { 0 };
     unsigned has_mask = (fs_traits & FS_MASK) != 0;
+    unsigned is_solid_mask = (fs_traits & FS_SOLID_MASK) != 0;
     unsigned is_fill = (fs_traits & FS_FILL) != 0;
     unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0;
     unsigned is_solid = (fs_traits & FS_SOLID_FILL) != 0;
@@ -452,6 +456,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
     unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
     unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
     unsigned dst_luminance = (fs_traits & FS_DST_LUMINANCE) != 0;
+    unsigned n = 0;
 
 #if 0
     print_fs_traits(fs_traits);
@@ -474,7 +479,7 @@ 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, 0);
+	src_sampler = ureg_DECL_sampler(ureg, n++);
 	src_input = ureg_DECL_fs_input(ureg,
 				       TGSI_SEMANTIC_GENERIC, 0,
 				       TGSI_INTERPOLATE_PERSPECTIVE);
@@ -492,8 +497,12 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
 	return create_yuv_shader(pipe, ureg);
     }
 
-    if (has_mask) {
-	mask_sampler = ureg_DECL_sampler(ureg, 1);
+    if (is_solid_mask) {
+	mask_pos = ureg_DECL_fs_input(ureg,
+				       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);
@@ -552,10 +561,15 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
 	    ureg_MOV(ureg, out, ureg_src(src));
     }
 
-    if (has_mask) {
+    if (is_solid_mask) {
+	mask = ureg_dst(mask_pos);
+    } else if (has_mask) {
 	mask = ureg_DECL_temporary(ureg);
 	xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
 		    mask_repeat_none, mask_swizzle, mask_set_alpha);
+    }
+
+    if (has_mask) {
 	/* src IN mask */
 
 	src_in_mask(ureg, (dst_luminance) ? src : out, ureg_src(src),
-- 
1.9.0



More information about the mesa-dev mailing list