[Mesa-dev] [PATCH 1/4] xa: handle solid-fill src/mask

Thomas Hellstrom thellstrom at vmware.com
Wed Apr 2 22:17:22 PDT 2014


On 04/01/2014 05:04 PM, Rob Clark wrote:
> 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 |  88 ++++----
>  src/gallium/state_trackers/xa/xa_priv.h      |   7 +-
>  src/gallium/state_trackers/xa/xa_renderer.c  | 289 ++++++++++++++++-----------
>  src/gallium/state_trackers/xa/xa_tgsi.c      |  31 ++-
>  4 files changed, 242 insertions(+), 173 deletions(-)

Rob,
While testing this patch it looks like we sometimes set two samplers,
and the first one is NULL.
The SVGA driver asserts on that condition.
We might need to move the active sampler to the first entry in that
case, and adjust tex coords and shader accordingly.

I'll discuss with BrianP.

/Thomas

> diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c
> index abe5be2..f63cf49 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)) {
> @@ -322,6 +309,12 @@ picture_format_fixups(struct xa_picture *src_pic,
>  }
>  
>  static int
> +is_solid_fill(struct xa_picture *pic)
> +{
> +    return pic->src_pict && (pic->src_pict->type == xa_src_pict_solid_fill);
> +}
> +
> +static int
>  bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
>  {
>      unsigned vs_traits = 0, fs_traits = 0;
> @@ -336,8 +329,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 +351,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) {
> @@ -399,7 +400,7 @@ bind_samplers(struct xa_context *ctx,
>      memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
>  
>      if (src_pic) {
> -	if (ctx->has_solid_color) {
> +	if (is_solid_fill(src_pic)) {
>  	    samplers[0] = NULL;
>  	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL);
>  	} else {
> @@ -427,27 +428,31 @@ bind_samplers(struct xa_context *ctx,
>      }
>  
>      if (mask_pic) {
> -	unsigned mask_wrap = xa_repeat_to_gallium(mask_pic->wrap);
> -	int filter;
> -
> -	(void) xa_filter_to_gallium(mask_pic->filter, &filter);
> -
> -	mask_sampler.wrap_s = mask_wrap;
> -	mask_sampler.wrap_t = mask_wrap;
> -	mask_sampler.min_img_filter = filter;
> -	mask_sampler.mag_img_filter = filter;
> -	src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
> -	mask_sampler.normalized_coords = 1;
> -	samplers[1] = &mask_sampler;
> -	ctx->num_bound_samplers = 2;
> -	u_sampler_view_default_template(&view_templ,
> -					mask_pic->srf->tex,
> -					mask_pic->srf->tex->format);
> -	src_view = pipe->create_sampler_view(pipe, mask_pic->srf->tex,
> -					     &view_templ);
> -	pipe_sampler_view_reference(&ctx->bound_sampler_views[1], NULL);
> -	ctx->bound_sampler_views[1] = src_view;
> +	if (is_solid_fill(mask_pic)) {
> +	    samplers[1] = NULL;
> +	    pipe_sampler_view_reference(&ctx->bound_sampler_views[1], NULL);
> +	} else {
> +	    unsigned mask_wrap = xa_repeat_to_gallium(mask_pic->wrap);
> +	    int filter;
> +
> +	    (void) xa_filter_to_gallium(mask_pic->filter, &filter);
>  
> +	    mask_sampler.wrap_s = mask_wrap;
> +	    mask_sampler.wrap_t = mask_wrap;
> +	    mask_sampler.min_img_filter = filter;
> +	    mask_sampler.mag_img_filter = filter;
> +	    src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
> +	    mask_sampler.normalized_coords = 1;
> +	    samplers[1] = &mask_sampler;
> +	    ctx->num_bound_samplers = 2;
> +	    u_sampler_view_default_template(&view_templ,
> +					    mask_pic->srf->tex,
> +					    mask_pic->srf->tex->format);
> +	    src_view = pipe->create_sampler_view(pipe, mask_pic->srf->tex,
> +		    &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
> @@ -488,10 +493,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;
>      }
>  
> @@ -504,7 +509,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 {
> @@ -530,6 +535,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 b99c214..348a98e 100644
> --- a/src/gallium/state_trackers/xa/xa_priv.h
> +++ b/src/gallium/state_trackers/xa/xa_priv.h
> @@ -110,6 +110,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;
> @@ -122,6 +125,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)
>  };
> @@ -144,6 +148,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)
> @@ -258,7 +263,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 9ba78be..056648a 100644
> --- a/src/gallium/state_trackers/xa/xa_renderer.c
> +++ b/src/gallium/state_trackers/xa/xa_renderer.c
> @@ -124,7 +124,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;
>  
> @@ -133,98 +133,84 @@ 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;
> -}
> -
> -static INLINE void
> -add_vertex_1tex(struct xa_context *r, float x, float y, float s, float t)
> -{
> -    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 */
> -
> -    r->buffer_size += 8;
> +    r->buffer_size += 4;
>  }
>  
>  static INLINE void
> -add_vertex_2tex(struct xa_context *r,
> -		float x, float y, float s0, float t0, float s1, float t1)
> +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] = s0;		/*s */
> -    vertex[5] = t0;		/*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 */
>  
> -    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_color) {
> +	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;
>      }
>  
> -    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
> @@ -233,55 +219,91 @@ 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_color) {
> +	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;
> +    if (!mask_color) {
> +	float mpt0[2], mpt1[2];
> +
> +	mpt0[0] = maskX;
> +	mpt0[1] = maskY;
> +	mpt1[0] = maskX + width;
> +	mpt1[1] = maskY + height;
>  
> -    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_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;
> +    }
>  
>      /* 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
> @@ -310,13 +332,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
> @@ -493,10 +519,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
> @@ -539,13 +569,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
> @@ -555,9 +589,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;
>  }
>  
> @@ -592,7 +631,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);
> +			 sampler_view[0]->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);
> @@ -601,8 +642,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[0]->texture,
> +			 r->has_solid_mask ? NULL : sampler_view[1]->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..9cda4c3 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;
> @@ -492,7 +496,11 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
>  	return create_yuv_shader(pipe, ureg);
>      }
>  
> -    if (has_mask) {
> +    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, 1);
>  	mask_pos = ureg_DECL_fs_input(ureg,
>  				      TGSI_SEMANTIC_GENERIC, 1,
> @@ -552,10 +560,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),


More information about the mesa-dev mailing list