diff options
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_composite.c | 24 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.c | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa_tgsi.c | 33 |
3 files changed, 38 insertions, 21 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c index 4dbb490ca51..f16816b2a77 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -232,15 +232,25 @@ bind_blend_state(struct exa_context *exa, int op, } static unsigned -picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask) +picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask, + PicturePtr pDstPicture) { boolean set_alpha = FALSE; boolean swizzle = FALSE; unsigned ret = 0; if (pSrc->picture_format == pSrcPicture->format) { - if (pSrc->picture_format == PICT_a8) - return mask ? FS_MASK_LUMINANCE : FS_SRC_LUMINANCE; + if (pSrc->picture_format == PICT_a8) { + if (mask) + return FS_MASK_LUMINANCE; + else if (pDstPicture->format != PICT_a8) { + /* if both dst and src are luminance then + * we don't want to swizzle the alpha (X) of the + * source into W component of the dst because + * it will break our destination */ + return FS_SRC_LUMINANCE; + } + } return 0; } @@ -285,7 +295,7 @@ picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, bool static void bind_shaders(struct exa_context *exa, int op, - PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask) { unsigned vs_traits = 0, fs_traits = 0; @@ -313,7 +323,7 @@ bind_shaders(struct exa_context *exa, int op, vs_traits |= VS_COMPOSITE; } - fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE); + fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture); } if (pMaskPicture) { @@ -331,7 +341,7 @@ bind_shaders(struct exa_context *exa, int op, fs_traits |= FS_CA_FULL; } - fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE); + fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture); } shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits); @@ -497,7 +507,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, pSrc, pMask); + bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask); bind_samplers(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask, pDst); setup_constant_buffers(exa, pDst); diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 3e2f4e8834d..aa04586455f 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -578,8 +578,6 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, render_format_name(priv->picture_format), render_format_name(pSrcPicture->format)); - if (priv->picture_format == PICT_a8) - XORG_FALLBACK("pSrc pic_format == PICT_a8"); } if (pMask) { diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c index 3bf64b6331d..13a9840bddd 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c @@ -396,15 +396,11 @@ xrender_tex(struct ureg_program *ureg, struct ureg_dst dst, struct ureg_src coords, struct ureg_src sampler, + struct ureg_src imm0, 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); @@ -466,6 +462,7 @@ create_fs(struct pipe_context *pipe, struct ureg_src /*dst_pos,*/ src_input, mask_pos; struct ureg_dst src, mask; struct ureg_dst out; + struct ureg_src imm0 = { 0 }; unsigned has_mask = (fs_traits & FS_MASK) != 0; unsigned is_fill = (fs_traits & FS_FILL) != 0; unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0; @@ -483,8 +480,6 @@ create_fs(struct pipe_context *pipe, unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0; unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0; - if (src_luminance) - assert(!"src_luminance not supported"); #if 0 print_fs_traits(fs_traits); #else @@ -502,6 +497,11 @@ create_fs(struct pipe_context *pipe, TGSI_SEMANTIC_COLOR, 0); + if (src_repeat_none || mask_repeat_none || + src_set_alpha || mask_set_alpha || + src_luminance) { + imm0 = ureg_imm4f(ureg, 0, 0, 0, 1); + } if (is_composite) { src_sampler = ureg_DECL_sampler(ureg, 0); src_input = ureg_DECL_fs_input(ureg, @@ -540,16 +540,17 @@ create_fs(struct pipe_context *pipe, TGSI_INTERPOLATE_PERSPECTIVE); #endif + if (is_composite) { - if (has_mask) + if (has_mask || src_luminance) src = ureg_DECL_temporary(ureg); else src = out; - xrender_tex(ureg, src, src_input, src_sampler, + xrender_tex(ureg, src, src_input, src_sampler, imm0, src_repeat_none, src_swizzle, src_set_alpha); } else if (is_fill) { if (is_solid) { - if (has_mask) + if (has_mask || src_luminance) src = ureg_dst(src_input); else ureg_MOV(ureg, out, src_input); @@ -557,7 +558,7 @@ create_fs(struct pipe_context *pipe, struct ureg_src coords, const0124, matrow0, matrow1, matrow2; - if (has_mask) + if (has_mask || src_luminance) src = ureg_DECL_temporary(ureg); else src = out; @@ -582,10 +583,18 @@ create_fs(struct pipe_context *pipe, } else debug_assert(!"Unknown fill type!"); } + if (src_luminance) { + ureg_MOV(ureg, src, + ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X)); + ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ), + ureg_scalar(imm0, TGSI_SWIZZLE_X)); + if (!has_mask) + ureg_MOV(ureg, out, ureg_src(src)); + } if (has_mask) { mask = ureg_DECL_temporary(ureg); - xrender_tex(ureg, mask, mask_pos, mask_sampler, + xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0, mask_repeat_none, mask_swizzle, mask_set_alpha); /* src IN mask */ src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), |