st/xorg: Incase of format missmatch swizzle channels and set alpha
This path is only hit for icons in gnome so far
This commit is contained in:
@@ -228,10 +228,59 @@ bind_blend_state(struct exa_context *exa, int op,
|
||||
cso_set_blend(exa->renderer->cso, &blend);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask)
|
||||
{
|
||||
boolean set_alpha = FALSE;
|
||||
boolean swizzle = FALSE;
|
||||
unsigned ret = 0;
|
||||
|
||||
if (pSrc->picture_format == pSrcPicture->format)
|
||||
return 0;
|
||||
|
||||
if (pSrc->picture_format != PICT_a8r8g8b8) {
|
||||
assert(!"can not handle formats");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* pSrc->picture_format == PICT_a8r8g8b8 */
|
||||
switch (pSrcPicture->format) {
|
||||
case PICT_x8b8g8r8:
|
||||
case PICT_b8g8r8:
|
||||
set_alpha = TRUE; /* fall trough */
|
||||
case PICT_a8b8g8r8:
|
||||
swizzle = TRUE;
|
||||
break;
|
||||
case PICT_x8r8g8b8:
|
||||
case PICT_r8g8b8:
|
||||
set_alpha = TRUE; /* fall through */
|
||||
case PICT_a8r8g8b8:
|
||||
break;
|
||||
#ifdef PICT_TYPE_BGRA
|
||||
case PICT_b8g8r8a8:
|
||||
case PICT_b8g8r8x8:
|
||||
case PICT_a2r10g10b10:
|
||||
case PICT_x2r10g10b10:
|
||||
case PICT_a2b10g10r10:
|
||||
case PICT_x2b10g10r10:
|
||||
#endif
|
||||
default:
|
||||
assert(!"can not handle formats");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (set_alpha)
|
||||
ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
|
||||
if (swizzle)
|
||||
ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
bind_shaders(struct exa_context *exa, int op,
|
||||
PicturePtr pSrcPicture, PicturePtr pMaskPicture)
|
||||
PicturePtr pSrcPicture, PicturePtr pMaskPicture,
|
||||
struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask)
|
||||
{
|
||||
unsigned vs_traits = 0, fs_traits = 0;
|
||||
struct xorg_shader shader;
|
||||
@@ -257,6 +306,8 @@ bind_shaders(struct exa_context *exa, int op,
|
||||
fs_traits |= FS_COMPOSITE;
|
||||
vs_traits |= VS_COMPOSITE;
|
||||
}
|
||||
|
||||
fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE);
|
||||
}
|
||||
|
||||
if (pMaskPicture) {
|
||||
@@ -273,6 +324,8 @@ bind_shaders(struct exa_context *exa, int op,
|
||||
} else
|
||||
fs_traits |= FS_CA_FULL;
|
||||
}
|
||||
|
||||
fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE);
|
||||
}
|
||||
|
||||
shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
|
||||
@@ -438,7 +491,7 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
|
||||
renderer_bind_viewport(exa->renderer, pDst);
|
||||
bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);
|
||||
renderer_bind_rasterizer(exa->renderer);
|
||||
bind_shaders(exa, op, pSrcPicture, pMaskPicture);
|
||||
bind_shaders(exa, op, pSrcPicture, pMaskPicture, pSrc, pMask);
|
||||
bind_samplers(exa, op, pSrcPicture, pMaskPicture,
|
||||
pDstPicture, pSrc, pMask, pDst);
|
||||
setup_constant_buffers(exa, pDst);
|
||||
|
||||
@@ -467,6 +467,41 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static Bool
|
||||
picture_check_formats(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture)
|
||||
{
|
||||
if (pSrc->picture_format == pSrcPicture->format)
|
||||
return TRUE;
|
||||
|
||||
if (pSrc->picture_format != PICT_a8r8g8b8)
|
||||
return FALSE;
|
||||
|
||||
/* pSrc->picture_format == PICT_a8r8g8b8 */
|
||||
switch (pSrcPicture->format) {
|
||||
case PICT_a8r8g8b8:
|
||||
case PICT_x8r8g8b8:
|
||||
case PICT_a8b8g8r8:
|
||||
case PICT_x8b8g8r8:
|
||||
/* just treat these two as x8... */
|
||||
case PICT_r8g8b8:
|
||||
case PICT_b8g8r8:
|
||||
return TRUE;
|
||||
#ifdef PICT_TYPE_BGRA
|
||||
case PICT_b8g8r8a8:
|
||||
case PICT_b8g8r8x8:
|
||||
return FALSE; /* does not support swizzleing the alpha channel yet */
|
||||
case PICT_a2r10g10b10:
|
||||
case PICT_x2r10g10b10:
|
||||
case PICT_a2b10g10r10:
|
||||
case PICT_x2b10g10r10:
|
||||
return FALSE;
|
||||
#endif
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
ExaPrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
PicturePtr pMaskPicture, PicturePtr pDstPicture,
|
||||
@@ -512,7 +547,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
PIPE_TEXTURE_USAGE_SAMPLER, 0))
|
||||
XORG_FALLBACK("pSrc format: %s", pf_name(priv->tex->format));
|
||||
|
||||
if (priv->picture_format != pSrcPicture->format)
|
||||
if (!picture_check_formats(priv, pSrcPicture))
|
||||
XORG_FALLBACK("pSrc pic_format: %s != %s",
|
||||
render_format_name(priv->picture_format),
|
||||
render_format_name(pSrcPicture->format));
|
||||
@@ -528,7 +563,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
|
||||
PIPE_TEXTURE_USAGE_SAMPLER, 0))
|
||||
XORG_FALLBACK("pMask format: %s", pf_name(priv->tex->format));
|
||||
|
||||
if (priv->picture_format != pMaskPicture->format)
|
||||
if (!picture_check_formats(priv, pMaskPicture))
|
||||
XORG_FALLBACK("pMask pic_format: %s != %s",
|
||||
render_format_name(priv->picture_format),
|
||||
render_format_name(pMaskPicture->format));
|
||||
|
||||
@@ -359,12 +359,18 @@ xrender_tex(struct ureg_program *ureg,
|
||||
struct ureg_dst dst,
|
||||
struct ureg_src coords,
|
||||
struct ureg_src sampler,
|
||||
boolean repeat_none)
|
||||
boolean repeat_none,
|
||||
boolean swizzle,
|
||||
boolean set_alpha)
|
||||
{
|
||||
struct ureg_src imm0 = { 0 };
|
||||
|
||||
if (repeat_none || set_alpha)
|
||||
imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
|
||||
|
||||
if (repeat_none) {
|
||||
struct ureg_dst tmp0 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst tmp1 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_src imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
|
||||
ureg_SGT(ureg, tmp1, ureg_swizzle(coords,
|
||||
TGSI_SWIZZLE_X,
|
||||
TGSI_SWIZZLE_Y,
|
||||
@@ -381,11 +387,37 @@ xrender_tex(struct ureg_program *ureg,
|
||||
ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X),
|
||||
ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y));
|
||||
ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler);
|
||||
if (swizzle)
|
||||
ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1),
|
||||
TGSI_SWIZZLE_Z,
|
||||
TGSI_SWIZZLE_Y,
|
||||
TGSI_SWIZZLE_X,
|
||||
TGSI_SWIZZLE_W));
|
||||
if (set_alpha)
|
||||
ureg_MOV(ureg,
|
||||
ureg_writemask(tmp1, TGSI_WRITEMASK_W),
|
||||
ureg_scalar(imm0, TGSI_SWIZZLE_W));
|
||||
ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0));
|
||||
ureg_release_temporary(ureg, tmp0);
|
||||
ureg_release_temporary(ureg, tmp1);
|
||||
} else
|
||||
ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler);
|
||||
} else {
|
||||
if (swizzle) {
|
||||
struct ureg_dst tmp = ureg_DECL_temporary(ureg);
|
||||
ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler);
|
||||
ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp),
|
||||
TGSI_SWIZZLE_Z,
|
||||
TGSI_SWIZZLE_Y,
|
||||
TGSI_SWIZZLE_X,
|
||||
TGSI_SWIZZLE_W));
|
||||
ureg_release_temporary(ureg, tmp);
|
||||
} else {
|
||||
ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler);
|
||||
}
|
||||
if (set_alpha)
|
||||
ureg_MOV(ureg,
|
||||
ureg_writemask(dst, TGSI_WRITEMASK_W),
|
||||
ureg_scalar(imm0, TGSI_SWIZZLE_W));
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
@@ -407,6 +439,10 @@ create_fs(struct pipe_context *pipe,
|
||||
unsigned is_yuv = (fs_traits & FS_YUV) != 0;
|
||||
unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0;
|
||||
unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0;
|
||||
unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0;
|
||||
unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0;
|
||||
unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0;
|
||||
unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0;
|
||||
|
||||
ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
|
||||
if (ureg == NULL)
|
||||
@@ -463,7 +499,7 @@ create_fs(struct pipe_context *pipe,
|
||||
else
|
||||
src = out;
|
||||
xrender_tex(ureg, src, src_input, src_sampler,
|
||||
src_repeat_none);
|
||||
src_repeat_none, src_swizzle, src_set_alpha);
|
||||
} else if (is_fill) {
|
||||
if (is_solid) {
|
||||
if (has_mask)
|
||||
@@ -503,7 +539,7 @@ create_fs(struct pipe_context *pipe,
|
||||
if (has_mask) {
|
||||
mask = ureg_DECL_temporary(ureg);
|
||||
xrender_tex(ureg, mask, mask_pos, mask_sampler,
|
||||
mask_repeat_none);
|
||||
mask_repeat_none, mask_swizzle, mask_set_alpha);
|
||||
/* src IN mask */
|
||||
src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), comp_alpha);
|
||||
ureg_release_temporary(ureg, mask);
|
||||
|
||||
@@ -28,6 +28,10 @@ enum xorg_fs_traits {
|
||||
FS_YUV = 1 << 7,
|
||||
FS_SRC_REPEAT_NONE = 1 << 8,
|
||||
FS_MASK_REPEAT_NONE = 1 << 9,
|
||||
FS_SRC_SWIZZLE_RGB = 1 << 10,
|
||||
FS_MASK_SWIZZLE_RGB = 1 << 11,
|
||||
FS_SRC_SET_ALPHA = 1 << 12,
|
||||
FS_MASK_SET_ALPHA = 1 << 13,
|
||||
|
||||
FS_FILL = (FS_SOLID_FILL |
|
||||
FS_LINGRAD_FILL |
|
||||
|
||||
Reference in New Issue
Block a user