diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/state_trackers/xorg/xorg_composite.c | 57 | ||||
| -rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.c | 39 | ||||
| -rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa_tgsi.c | 48 | ||||
| -rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa_tgsi.h | 4 | 
4 files changed, 138 insertions, 10 deletions
| diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c index 02dc949c93..1ff19a2a5c 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -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); diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 735cabfedf..25c9fce254 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -468,6 +468,41 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,  }  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,  		    PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) @@ -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)); diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c index f8557755ef..cbb9ec137e 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c @@ -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); diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h index c038dc2231..062de947e6 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h @@ -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 | | 
