[PATCH 5/7] etnaviv: apply non-alpha workaround to temporary copy in acquire_src

Russell King rmk at armlinux.org.uk
Tue Nov 22 12:12:50 UTC 2016


On Tue, Nov 22, 2016 at 12:44:18PM +0100, Lucas Stach wrote:
> The blit into the temporary pixmap needs the same workaround for
> non-alpha formats as all other blits.

Are you sure about this - we're using the blit engine here rather than
the blend engine which doesn't have the alpha problem - and we'll be
copying from an XRGB (vSrc) to an ARGB (vMask) format buffer here.

> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
>  etnaviv/etnaviv_render.c | 74 ++++++++++++++++++++++++++++--------------------
>  1 file changed, 44 insertions(+), 30 deletions(-)
> 
> diff --git a/etnaviv/etnaviv_render.c b/etnaviv/etnaviv_render.c
> index d9feeee55c61..1ab10aa54348 100644
> --- a/etnaviv/etnaviv_render.c
> +++ b/etnaviv/etnaviv_render.c
> @@ -338,6 +338,35 @@ static Bool etnaviv_composite_to_pixmap(CARD8 op, PicturePtr pSrc,
>  }
>  
>  /*
> + * There is a bug in the GPU hardware with destinations lacking alpha and
> + * swizzles BGRA/RGBA.  Rather than the GPU treating bits 7:0 as alpha, it
> + * continues to treat bits 31:24 as alpha.  This results in it replacing
> + * the B or R bits on input to the blend operation with 1.0.  However, it
> + * continues to accept the non-existent source alpha from bits 31:24.
> + *
> + * Work around this by switching to the equivalent alpha format, and using
> + * global alpha to replace the alpha channel.  The alpha channel subsitution
> + * is performed at this function's callsite.
> + */
> +static Bool etnaviv_workaround_nonalpha(struct etnaviv_pixmap *vpix)
> +{
> +	switch (vpix->pict_format.format) {
> +	case DE_FORMAT_X4R4G4B4:
> +		vpix->pict_format.format = DE_FORMAT_A4R4G4B4;
> +		return TRUE;
> +	case DE_FORMAT_X1R5G5B5:
> +		vpix->pict_format.format = DE_FORMAT_A1R5G5B5;
> +		return TRUE;
> +	case DE_FORMAT_X8R8G8B8:
> +		vpix->pict_format.format = DE_FORMAT_A8R8G8B8;
> +		return TRUE;
> +	case DE_FORMAT_R5G6B5:
> +		return TRUE;
> +	}
> +	return FALSE;
> +}
> +
> +/*
>   * Acquire the source. If we're filling a solid surface, force it to have
>   * alpha; it may be used in combination with a mask.  Otherwise, we ask
>   * for the plain source format, with or without alpha, and convert later
> @@ -350,6 +379,7 @@ static struct etnaviv_pixmap *etnaviv_acquire_src(ScreenPtr pScreen,
>  {
>  	struct etnaviv *etnaviv = etnaviv_get_screen_priv(pScreen);
>  	struct etnaviv_pixmap *vSrc, *vTemp;
> +	struct etnaviv_blend_op copy_op;
>  	DrawablePtr drawable;
>  	uint32_t colour;
>  	xPoint src_offset;
> @@ -413,45 +443,29 @@ copy_to_vtemp:
>  	if (!vTemp)
>  		return NULL;
>  
> -	if (!etnaviv_blend(etnaviv, clip, NULL, vTemp, vSrc, clip, 1,
> +	copy_op = etnaviv_composite_op[PictOpSrc];
> +
> +	if (etnaviv_workaround_nonalpha(vSrc)) {
> +		copy_op.alpha_mode |= VIVS_DE_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_GLOBAL;
> +		copy_op.src_alpha = 255;
> +	}
> +
> +	if (!etnaviv_blend(etnaviv, clip, &copy_op, vTemp, vSrc, clip, 1,
>  			   *src_topleft, ZERO_OFFSET))
>  		return NULL;
>  
> +	/*
> +	 * Reset pixmap format to original one, as the calling function may depend
> +	 * on this to be unchanged.
> +	 */
> +	etnaviv_set_format(vSrc, pict);
> +
>  	src_topleft->x = 0;
>  	src_topleft->y = 0;
>  	return vTemp;
>  }
>  
>  /*
> - * There is a bug in the GPU hardware with destinations lacking alpha and
> - * swizzles BGRA/RGBA.  Rather than the GPU treating bits 7:0 as alpha, it
> - * continues to treat bits 31:24 as alpha.  This results in it replacing
> - * the B or R bits on input to the blend operation with 1.0.  However, it
> - * continues to accept the non-existent source alpha from bits 31:24.
> - *
> - * Work around this by switching to the equivalent alpha format, and using
> - * global alpha to replace the alpha channel.  The alpha channel subsitution
> - * is performed at this function's callsite.
> - */
> -static Bool etnaviv_workaround_nonalpha(struct etnaviv_pixmap *vpix)
> -{
> -	switch (vpix->pict_format.format) {
> -	case DE_FORMAT_X4R4G4B4:
> -		vpix->pict_format.format = DE_FORMAT_A4R4G4B4;
> -		return TRUE;
> -	case DE_FORMAT_X1R5G5B5:
> -		vpix->pict_format.format = DE_FORMAT_A1R5G5B5;
> -		return TRUE;
> -	case DE_FORMAT_X8R8G8B8:
> -		vpix->pict_format.format = DE_FORMAT_A8R8G8B8;
> -		return TRUE;
> -	case DE_FORMAT_R5G6B5:
> -		return TRUE;
> -	}
> -	return FALSE;
> -}
> -
> -/*
>   * Compute the regions (in destination pixmap coordinates) which need to
>   * be composited.  Each picture's pCompositeClip includes the drawable
>   * position, so each position must be adjusted for its position on the
> -- 
> 2.10.2
> 

-- 
Russell King


More information about the etnaviv mailing list