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

Rob Clark robdclark at gmail.com
Thu Apr 3 04:05:53 PDT 2014


On Thu, Apr 3, 2014 at 1:17 AM, Thomas Hellstrom <thellstrom at vmware.com> wrote:
> 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.

Yeah, I saw that.. but the code looked like it was originally intended
to work that way, so I'd assumed it was a valid condition that I just
wasn't dealing with in freedreno.

BR,
-R

> 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