diff options
| -rw-r--r-- | src/gallium/state_trackers/xorg/xorg_composite.c | 168 | ||||
| -rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.c | 19 | ||||
| -rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa_tgsi.c | 37 | ||||
| -rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa_tgsi.h | 3 | 
4 files changed, 114 insertions, 113 deletions
| diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c index 7379e3b746..297b6c5f5d 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -13,68 +13,43 @@  #define XFixedToDouble(f)    (((double) (f)) / 65536.)  struct xorg_composite_blend { -   int op:8; +   int op : 8; -   unsigned rgb_src_factor:5;    /**< PIPE_BLENDFACTOR_x */ -   unsigned alpha_src_factor:5;  /**< PIPE_BLENDFACTOR_x */ +   unsigned alpha_dst : 4; +   unsigned alpha_src : 4; -   unsigned rgb_dst_factor:5;    /**< PIPE_BLENDFACTOR_x */ -   unsigned alpha_dst_factor:5;  /**< PIPE_BLENDFACTOR_x */ +   unsigned rgb_src : 8;    /**< PIPE_BLENDFACTOR_x */ +   unsigned rgb_dst : 8;    /**< PIPE_BLENDFACTOR_x */  };  #define BLEND_OP_OVER 3  static const struct xorg_composite_blend xorg_blends[] = {     { PictOpClear, -     PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO, -     PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO }, - +     0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO},     { PictOpSrc, -     PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO }, - +     0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO},     { PictOpDst, -     PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO, -     PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE }, - +     0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE},     { PictOpOver, -     PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, - +     0, 1, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_INV_SRC_ALPHA},     { PictOpOverReverse, -     PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, - +     1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE},     { PictOpIn, -     PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, - +     1, 0, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},     { PictOpInReverse, -     PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE }, - +     0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_SRC_ALPHA},     { PictOpOut, -     PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, - +     1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},     { PictOpOutReverse, -     PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, - +     0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA},     { PictOpAtop, -     PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, - +     1, 1, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},     { PictOpAtopReverse, -     PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, - +     1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_SRC_ALPHA},     { PictOpXor, -     PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_ONE }, - +     1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},     { PictOpAdd, -     PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE, -     PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE }, +     0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE},  }; @@ -95,38 +70,62 @@ pixel_to_float4(Pixel pixel, float *color)  struct acceleration_info {     int op : 16; -   int with_mask : 1; -   int component_alpha : 1;  };  static const struct acceleration_info accelerated_ops[] = { -   {PictOpClear,       1, 0}, -   {PictOpSrc,         1, 0}, -   {PictOpDst,         1, 0}, -   {PictOpOver,        1, 0}, -   {PictOpOverReverse, 1, 0}, -   {PictOpIn,          1, 0}, -   {PictOpInReverse,   1, 0}, -   {PictOpOut,         1, 0}, -   {PictOpOutReverse,  1, 0}, -   {PictOpAtop,        1, 0}, -   {PictOpAtopReverse, 1, 0}, -   {PictOpXor,         1, 0}, -   {PictOpAdd,         1, 0}, -   {PictOpSaturate,    1, 0}, +   {PictOpClear,        }, +   {PictOpSrc,          }, +   {PictOpDst,          }, +   {PictOpOver,         }, +   {PictOpOverReverse,  }, +   {PictOpIn,           }, +   {PictOpInReverse,    }, +   {PictOpOut,          }, +   {PictOpOutReverse,   }, +   {PictOpAtop,         }, +   {PictOpAtopReverse,  }, +   {PictOpXor,          }, +   {PictOpAdd,          }, +   {PictOpSaturate,     },  };  static struct xorg_composite_blend -blend_for_op(int op) +blend_for_op(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, +             PicturePtr pDstPicture)  {     const int num_blends =        sizeof(xorg_blends)/sizeof(struct xorg_composite_blend);     int i; +   struct xorg_composite_blend blend = xorg_blends[BLEND_OP_OVER];     for (i = 0; i < num_blends; ++i) {        if (xorg_blends[i].op == op) -         return xorg_blends[i]; +         blend = xorg_blends[i];     } -   return xorg_blends[BLEND_OP_OVER]; + +   /* If there's no dst alpha channel, adjust the blend op so that we'll treat +    * it as always 1. +    */ +   if (pDstPicture && +       PICT_FORMAT_A(pDstPicture->format) == 0 && blend.alpha_dst) { +      if (blend.rgb_src == PIPE_BLENDFACTOR_DST_ALPHA) +         blend.rgb_src = PIPE_BLENDFACTOR_ONE; +      else if (blend.rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA) +         blend.rgb_src = PIPE_BLENDFACTOR_ZERO; +   } + +   /* If the source alpha is being used, then we should only be in a case where +    * the source blend factor is 0, and the source blend value is the mask +    * channels multiplied by the source picture's alpha. +    */ +   if (pMaskPicture && pMaskPicture->componentAlpha && +       PICT_FORMAT_RGB(pMaskPicture->format) && blend.alpha_src) { +      if (blend.rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) { +         blend.rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR; +      } else if (blend.rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) { +         blend.rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR; +      } +   } +   return blend;  }  static INLINE int @@ -203,41 +202,50 @@ boolean xorg_composite_accelerated(int op,     if (pSrcPicture->pSourcePict) {        if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill) -         XORG_FALLBACK("gradients not enabled (haven't been well tested)"); +         XORG_FALLBACK("Gradients not enabled (haven't been well tested)");     }     for (i = 0; i < accel_ops_count; ++i) {        if (op == accelerated_ops[i].op) { +         struct xorg_composite_blend blend = blend_for_op(op, +                                                          pSrcPicture, +                                                          pMaskPicture, +                                                          pDstPicture);           /* Check for component alpha */ -         if (pMaskPicture && -             (pMaskPicture->componentAlpha || -              (!accelerated_ops[i].with_mask))) -            XORG_FALLBACK("component alpha unsupported (PictOpOver=%s(%d)", -                          (accelerated_ops[i].op == PictOpOver) ? "yes" : "no", -                          accelerated_ops[i].op); +         if (pMaskPicture && pMaskPicture->componentAlpha && +             PICT_FORMAT_RGB(pMaskPicture->format)) { +            if (blend.alpha_src && +                blend.rgb_src != PIPE_BLENDFACTOR_ZERO) { +               XORG_FALLBACK("Component alpha not supported with source " +                             "alpha and source value blending. (op=%d)", +                             op); +            } +         }           return TRUE;        }     } -   XORG_FALLBACK("unsupported operation"); +   XORG_FALLBACK("Unsupported composition operation = %d", op);  }  static void  bind_blend_state(struct exa_context *exa, int op, -                 PicturePtr pSrcPicture, PicturePtr pMaskPicture) +                 PicturePtr pSrcPicture, +                 PicturePtr pMaskPicture, +                 PicturePtr pDstPicture)  {     struct xorg_composite_blend blend_opt;     struct pipe_blend_state blend; -   blend_opt = blend_for_op(op); +   blend_opt = blend_for_op(op, pSrcPicture, pMaskPicture, pDstPicture); -   memset(&blend, 0, sizeof(struct pipe_blend_state));  +   memset(&blend, 0, sizeof(struct pipe_blend_state));     blend.blend_enable = 1;     blend.colormask |= PIPE_MASK_RGBA; -   blend.rgb_src_factor   = blend_opt.rgb_src_factor; -   blend.alpha_src_factor = blend_opt.alpha_src_factor; -   blend.rgb_dst_factor   = blend_opt.rgb_dst_factor; -   blend.alpha_dst_factor = blend_opt.alpha_dst_factor; +   blend.rgb_src_factor   = blend_opt.rgb_src; +   blend.alpha_src_factor = blend_opt.rgb_src; +   blend.rgb_dst_factor   = blend_opt.rgb_dst; +   blend.alpha_dst_factor = blend_opt.rgb_dst;     cso_set_blend(exa->renderer->cso, &blend);  } @@ -273,6 +281,8 @@ bind_shaders(struct exa_context *exa, int op,     if (pMaskPicture) {        vs_traits |= VS_MASK;        fs_traits |= FS_MASK; +      if (pMaskPicture->componentAlpha) +         fs_traits |= FS_COMPONENT_ALPHA;     }     shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits); @@ -428,7 +438,7 @@ boolean xorg_composite_bind_state(struct exa_context *exa,  {     renderer_bind_framebuffer(exa->renderer, pDst);     renderer_bind_viewport(exa->renderer, pDst); -   bind_blend_state(exa, op, pSrcPicture, pMaskPicture); +   bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);     renderer_bind_rasterizer(exa->renderer);     bind_shaders(exa, op, pSrcPicture, pMaskPicture);     bind_samplers(exa, op, pSrcPicture, pMaskPicture, @@ -491,7 +501,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,     renderer_bind_framebuffer(exa->renderer, pixmap);     renderer_bind_viewport(exa->renderer, pixmap);     renderer_bind_rasterizer(exa->renderer); -   bind_blend_state(exa, PictOpSrc, NULL, NULL); +   bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);     setup_constant_buffers(exa, pixmap);     shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits); diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 39c4d26ebe..b83d97bdb6 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -105,12 +105,21 @@ xorg_exa_common_done(struct exa_context *exa)  static void  ExaWaitMarker(ScreenPtr pScreen, int marker)  { +   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +   modesettingPtr ms = modesettingPTR(pScrn); +   struct exa_context *exa = ms->exa; + +#if 0 +   xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL); +#else +   xorg_exa_finish(exa); +#endif  }  static int  ExaMarkSync(ScreenPtr pScreen)  { -    return 1; +   return 1;  }  static Bool @@ -258,11 +267,6 @@ ExaDone(PixmapPtr pPixmap)      if (!priv)  	return; -#if 1 -    xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL); -#else -    xorg_exa_finish(exa); -#endif      xorg_exa_common_done(exa);  } @@ -442,7 +446,8 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,     struct exa_pixmap_priv *priv;  #if DEBUG_PRINT -   debug_printf("ExaPrepareComposite\n"); +   debug_printf("ExaPrepareComposite(%d, src=0x%p, mask=0x%p, dst=0x%p)\n", +                op, pSrcPicture, pMaskPicture, pDstPicture);  #endif     if (!exa->pipe)        XORG_FALLBACK("accle not enabled"); diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c index 8c9b674b4b..041f4f96dc 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c @@ -50,36 +50,20 @@ struct xorg_shaders {     struct cso_hash *fs_hash;  }; -static const char over_op[] = -   "SUB TEMP[3], CONST[0].wwww, TEMP[1].wwww\n" -   "MAD TEMP[3], TEMP[0], TEMP[3], TEMP[0]\n"; - - -static INLINE void -create_preamble(struct ureg_program *ureg) -{ -} - -  static INLINE void  src_in_mask(struct ureg_program *ureg,              struct ureg_dst dst,              struct ureg_src src, -            struct ureg_src mask) +            struct ureg_src mask, +            boolean component_alpha)  { -#if 0 -   /* MUL dst, src, mask.a */ -   ureg_MUL(ureg, dst, src, -            ureg_scalar(mask, TGSI_SWIZZLE_W)); -#else -   /* MOV dst, src */ -   /* MUL dst.a, src.a, mask.a */ -   ureg_MOV(ureg, dst, src); -   ureg_MUL(ureg, -            ureg_writemask(dst, TGSI_WRITEMASK_W), -            ureg_scalar(src, TGSI_SWIZZLE_W), -            ureg_scalar(mask, TGSI_SWIZZLE_W)); -#endif +   if (component_alpha) { +      ureg_MUL(ureg, dst, src, mask); +   } +   else { +      ureg_MUL(ureg, dst, src, +               ureg_scalar(mask, TGSI_SWIZZLE_W)); +   }  }  static struct ureg_src @@ -305,6 +289,7 @@ create_fs(struct pipe_context *pipe,     boolean is_solid   = fs_traits & FS_SOLID_FILL;     boolean is_lingrad = fs_traits & FS_LINGRAD_FILL;     boolean is_radgrad = fs_traits & FS_RADGRAD_FILL; +   boolean is_comp_alpha = fs_traits & FS_COMPONENT_ALPHA;     ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);     if (ureg == NULL) @@ -401,7 +386,7 @@ create_fs(struct pipe_context *pipe,        ureg_TEX(ureg, mask,                 TGSI_TEXTURE_2D, mask_pos, mask_sampler);        /* src IN mask */ -      src_in_mask(ureg, out, ureg_src(src), ureg_src(mask)); +      src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), is_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 33c272070b..c290d44e8f 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h @@ -23,7 +23,8 @@ enum xorg_fs_traits {     FS_RADGRAD_FILL     = 1 << 4,     FS_FILL             = (FS_SOLID_FILL |                            FS_LINGRAD_FILL | -                          FS_RADGRAD_FILL) +                          FS_RADGRAD_FILL), +   FS_COMPONENT_ALPHA  = 1 << 5  };  struct xorg_shader { | 
