[Mesa-dev] [PATCH] st/xa: Use PIPE_FORMAT_R8_UNORM when available

Jose Fonseca jfonseca at vmware.com
Thu Sep 17 02:34:22 PDT 2015


On 16/09/15 14:04, Thomas Hellstrom wrote:
> XA has been using L8_UNORM for a8 and yuv component surfaces.
> This commit instead makes XA prefer R8_UNORM since it's assumed to have a
> higher availability.
>
> Also neither of these formats are suitable as destination formats using
> destination alpha blending, so reject those operations.
>
> Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
> ---
>   src/gallium/state_trackers/xa/xa_composite.c | 40 ++++++++++------------------
>   src/gallium/state_trackers/xa/xa_tracker.c   | 28 +++++++++++++------
>   2 files changed, 34 insertions(+), 34 deletions(-)
>
> diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c
> index 7cfd1e1..e81eeba 100644
> --- a/src/gallium/state_trackers/xa/xa_composite.c
> +++ b/src/gallium/state_trackers/xa/xa_composite.c
> @@ -78,26 +78,6 @@ static const struct xa_composite_blend xa_blends[] = {
>         0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE},
>   };
>
> -
> -/*
> - * The alpha value stored in a luminance texture is read by the
> - * hardware as color.
> - */
> -static unsigned
> -xa_convert_blend_for_luminance(unsigned factor)
> -{
> -    switch(factor) {
> -    case PIPE_BLENDFACTOR_DST_ALPHA:
> -	return PIPE_BLENDFACTOR_DST_COLOR;
> -    case PIPE_BLENDFACTOR_INV_DST_ALPHA:
> -	return PIPE_BLENDFACTOR_INV_DST_COLOR;
> -    default:
> -	break;
> -    }
> -    return factor;
> -}
> -
> -
>   static boolean
>   blend_for_op(struct xa_composite_blend *blend,
>   	     enum xa_composite_op op,
> @@ -131,10 +111,16 @@ blend_for_op(struct xa_composite_blend *blend,
>       if (!dst_pic->srf)
>   	return supported;
>
> -    if (dst_pic->srf->tex->format == PIPE_FORMAT_L8_UNORM) {
> -	blend->rgb_src = xa_convert_blend_for_luminance(blend->rgb_src);
> -	blend->rgb_dst = xa_convert_blend_for_luminance(blend->rgb_dst);
> -    }
> +    /*
> +     * None of the hardware formats we might use for dst A8 are
> +     * suitable for dst_alpha blending, since they present the
> +     * alpha channel either in all color channels (L8_UNORM) or
> +     * in the red channel only (R8_UNORM)
> +     */
> +    if ((dst_pic->srf->tex->format == PIPE_FORMAT_L8_UNORM ||
> +         dst_pic->srf->tex->format == PIPE_FORMAT_R8_UNORM) &&
> +        blend->alpha_dst)
> +        return FALSE;

I'm not very familiar with this code, but wasn't 
xa_convert_blend_for_luminance compensating for the A8 <-> L8 mismatch? 
  It looks like it was doing the right thing.   And 
xa_convert_blend_for_luminance would work both for L8 and R8.

>
>       /*
>        * If there's no dst alpha channel, adjust the blend op so that we'll treat
> @@ -298,7 +284,8 @@ picture_format_fixups(struct xa_picture *src_pic,
>   	ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
>
>       if (src_hw_format == src_pic_format) {
> -	if (src->tex->format == PIPE_FORMAT_L8_UNORM)
> +	if (src->tex->format == PIPE_FORMAT_L8_UNORM ||
> +            src->tex->format == PIPE_FORMAT_R8_UNORM)
>   	    return ((mask) ? FS_MASK_LUMINANCE : FS_SRC_LUMINANCE);
>
>   	return ret;
> @@ -372,7 +359,8 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
>   	fs_traits |= picture_format_fixups(mask_pic, 1);
>       }
>
> -    if (ctx->srf->format == PIPE_FORMAT_L8_UNORM)
> +    if (ctx->srf->format == PIPE_FORMAT_L8_UNORM ||
> +        ctx->srf->format == PIPE_FORMAT_R8_UNORM)
>   	fs_traits |= FS_DST_LUMINANCE;

What exactly is FS_DST_LUMINANCE supposed to do?  From xa_tgsi.c it 
seems to swizzle the alpha channel into the red channel, before 
outputing.  But if we no longer want to emulate A8 with R8/L8 then it 
seems that's no longer necessary.


BTW, isn't necessary to update 
src/gallium/state_trackers/xa/xa_renderer.c to apply 
FS_SRC/DST_LUMINANCE traits for R8_UNORM too?


>
>       shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
> diff --git a/src/gallium/state_trackers/xa/xa_tracker.c b/src/gallium/state_trackers/xa/xa_tracker.c
> index 2944b16..cd1394a 100644
> --- a/src/gallium/state_trackers/xa/xa_tracker.c
> +++ b/src/gallium/state_trackers/xa/xa_tracker.c
> @@ -82,7 +82,7 @@ static const unsigned int stype_bind[XA_LAST_SURFACE_TYPE] = { 0,
>   };
>
>   static struct xa_format_descriptor
> -xa_get_pipe_format(enum xa_formats xa_format)
> +xa_get_pipe_format(struct xa_tracker *xa, enum xa_formats xa_format)
>   {
>       struct xa_format_descriptor fdesc;
>
> @@ -102,7 +102,13 @@ xa_get_pipe_format(enum xa_formats xa_format)
>   	fdesc.format = PIPE_FORMAT_B5G5R5A1_UNORM;
>   	break;
>       case xa_format_a8:
> -	fdesc.format = PIPE_FORMAT_L8_UNORM;
> +        if (xa->screen->is_format_supported(xa->screen, PIPE_FORMAT_R8_UNORM,
> +                                            PIPE_TEXTURE_2D, 0,
> +                                            stype_bind[xa_type_a] |
> +                                            PIPE_BIND_RENDER_TARGET))
> +            fdesc.format = PIPE_FORMAT_R8_UNORM;
> +        else
> +            fdesc.format = PIPE_FORMAT_L8_UNORM;
>   	break;
>       case xa_format_z24:
>   	fdesc.format = PIPE_FORMAT_Z24X8_UNORM;
> @@ -126,7 +132,12 @@ xa_get_pipe_format(enum xa_formats xa_format)
>   	fdesc.format = PIPE_FORMAT_S8_UINT_Z24_UNORM;
>   	break;
>       case xa_format_yuv8:
> -	fdesc.format = PIPE_FORMAT_L8_UNORM;
> +        if (xa->screen->is_format_supported(xa->screen, PIPE_FORMAT_R8_UNORM,
> +                                            PIPE_TEXTURE_2D, 0,
> +                                            stype_bind[xa_type_yuv_component]))
> +            fdesc.format = PIPE_FORMAT_R8_UNORM;
> +        else
> +            fdesc.format = PIPE_FORMAT_L8_UNORM;
>   	break;
>       default:
>   	fdesc.xa_format = xa_format_unknown;
> @@ -184,7 +195,8 @@ xa_tracker_create(int drm_fd)
>   	for (i = 0; i < num_preferred[stype]; ++i) {
>   	    xa_format = preferred[stype][i];
>
> -	    struct xa_format_descriptor fdesc = xa_get_pipe_format(xa_format);
> +	    struct xa_format_descriptor fdesc =
> +                xa_get_pipe_format(xa, xa_format);
>
>   	    if (xa->screen->is_format_supported(xa->screen, fdesc.format,
>   						PIPE_TEXTURE_2D, 0, bind)) {
> @@ -259,7 +271,7 @@ xa_get_format_stype_depth(struct xa_tracker *xa,
>       int found = 0;
>
>       for (i = xa->format_map[stype][0]; i <= xa->format_map[stype][1]; ++i) {
> -	fdesc = xa_get_pipe_format(xa->supported_formats[i]);
> +	fdesc = xa_get_pipe_format(xa, xa->supported_formats[i]);
>   	if (fdesc.xa_format != xa_format_unknown &&
>   	    xa_format_depth(fdesc.xa_format) == depth) {
>   	    found = 1;
> @@ -277,7 +289,7 @@ XA_EXPORT int
>   xa_format_check_supported(struct xa_tracker *xa,
>   			  enum xa_formats xa_format, unsigned int flags)
>   {
> -    struct xa_format_descriptor fdesc = xa_get_pipe_format(xa_format);
> +    struct xa_format_descriptor fdesc = xa_get_pipe_format(xa, xa_format);
>       unsigned int bind;
>
>       if (fdesc.xa_format == xa_format_unknown)
> @@ -328,7 +340,7 @@ surface_create(struct xa_tracker *xa,
>       if (xa_format == xa_format_unknown)
>   	fdesc = xa_get_format_stype_depth(xa, stype, depth);
>       else
> -	fdesc = xa_get_pipe_format(xa_format);
> +	fdesc = xa_get_pipe_format(xa, xa_format);
>
>       if (fdesc.xa_format == xa_format_unknown)
>   	return NULL;
> @@ -440,7 +452,7 @@ xa_surface_redefine(struct xa_surface *srf,
>       if (xa_format == xa_format_unknown)
>   	fdesc = xa_get_format_stype_depth(xa, stype, depth);
>       else
> -	fdesc = xa_get_pipe_format(xa_format);
> +	fdesc = xa_get_pipe_format(xa, xa_format);
>
>       if (width == template->width0 && height == template->height0 &&
>   	template->format == fdesc.format &&
>



More information about the mesa-dev mailing list