121cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin#include "xorg_composite.h"
221cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin
3319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin#include "xorg_renderer.h"
48bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin#include "xorg_exa_tgsi.h"
58bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin
6f315c0128b5f6317f910f6c54119fea97256254cZack Rusin#include "cso_cache/cso_context.h"
73bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer#include "util/u_format.h"
8ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger#include "util/u_sampler.h"
9f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin
10f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin
11a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin/*XXX also in Xrender.h but the including it here breaks compilition */
12a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin#define XFixedToDouble(f)    (((double) (f)) / 65536.)
13a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
1417076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusinstruct xorg_composite_blend {
15c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   int op : 8;
1617076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin
17c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   unsigned alpha_dst : 4;
18c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   unsigned alpha_src : 4;
198adcad0c703a9d339b6630ceaba5f96981c524d9Zack Rusin
20c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   unsigned rgb_src : 8;    /**< PIPE_BLENDFACTOR_x */
21c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   unsigned rgb_dst : 8;    /**< PIPE_BLENDFACTOR_x */
2217076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin};
2317076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin
242048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin#define BLEND_OP_OVER 3
2517076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusinstatic const struct xorg_composite_blend xorg_blends[] = {
2617076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin   { PictOpClear,
27c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO},
2817076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin   { PictOpSrc,
29c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO},
3017076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin   { PictOpDst,
31c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE},
3217076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin   { PictOpOver,
33c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 1, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
3417076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin   { PictOpOverReverse,
35c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE},
36074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpIn,
37c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 0, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
38074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpInReverse,
39c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_SRC_ALPHA},
40074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpOut,
41c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
4259cf40059a7c451b1d1bc0c90f674e8e4baa5ab8Zack Rusin   { PictOpOutReverse,
43c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
44074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpAtop,
45c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 1, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
46074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpAtopReverse,
47c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_SRC_ALPHA},
48074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpXor,
49c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
50074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpAdd,
51c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE},
5217076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin};
5321cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin
546be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
556be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusinstatic INLINE void
563bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzerpixel_to_float4(Pixel pixel, float *color, enum pipe_format format)
576be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin{
583bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer   const struct util_format_description *format_desc;
593bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer   uint8_t packed[4];
603bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer
613bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer   format_desc = util_format_description(format);
623bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer   packed[0] = pixel;
633bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer   packed[1] = pixel >> 8;
643bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer   packed[2] = pixel >> 16;
653bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer   packed[3] = pixel >> 24;
663bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer   format_desc->unpack_rgba_float(color, 0, packed, 0, 1, 1);
676be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin}
686be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
691f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusinstatic boolean
701f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusinblend_for_op(struct xorg_composite_blend *blend,
711f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin             int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
72c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin             PicturePtr pDstPicture)
732048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin{
742048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   const int num_blends =
752048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin      sizeof(xorg_blends)/sizeof(struct xorg_composite_blend);
762048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   int i;
771f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   boolean supported = FALSE;
781f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin
791f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   /* our default in case something goes wrong */
801f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   *blend = xorg_blends[BLEND_OP_OVER];
812048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
822048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   for (i = 0; i < num_blends; ++i) {
831f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      if (xorg_blends[i].op == op) {
841f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         *blend = xorg_blends[i];
851f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         supported = TRUE;
861f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      }
872048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   }
88c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin
89c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   /* If there's no dst alpha channel, adjust the blend op so that we'll treat
901f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin    * it as always 1. */
91c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   if (pDstPicture &&
921f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin       PICT_FORMAT_A(pDstPicture->format) == 0 && blend->alpha_dst) {
931f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
941f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         blend->rgb_src = PIPE_BLENDFACTOR_ONE;
951f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
961f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         blend->rgb_src = PIPE_BLENDFACTOR_ZERO;
97c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   }
98c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin
99c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   /* If the source alpha is being used, then we should only be in a case where
100c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin    * the source blend factor is 0, and the source blend value is the mask
1011f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin    * channels multiplied by the source picture's alpha. */
102c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   if (pMaskPicture && pMaskPicture->componentAlpha &&
1031f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin       PICT_FORMAT_RGB(pMaskPicture->format) && blend->alpha_src) {
1041f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) {
1051f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR;
1061f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      } else if (blend->rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) {
1071f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         blend->rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR;
108c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin      }
109c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   }
110b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin
1111f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   return supported;
1122048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin}
1132048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
114d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusinstatic INLINE int
115d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusinrender_repeat_to_gallium(int mode)
116d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin{
117d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   switch(mode) {
118d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   case RepeatNone:
119fca8b2c3ae53695f8ff6e823cc316aab910490e5Zack Rusin      return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
120d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   case RepeatNormal:
121d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      return PIPE_TEX_WRAP_REPEAT;
122d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   case RepeatReflect:
123d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      return PIPE_TEX_WRAP_MIRROR_REPEAT;
124d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   case RepeatPad:
125d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
126d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   default:
127d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      debug_printf("Unsupported repeat mode\n");
128d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   }
129d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   return PIPE_TEX_WRAP_REPEAT;
130d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin}
131d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin
132a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinstatic INLINE boolean
133a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinrender_filter_to_gallium(int xrender_filter, int *out_filter)
134a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin{
135a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
136a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   switch (xrender_filter) {
137a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   case PictFilterNearest:
138a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_NEAREST;
139a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      break;
140a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   case PictFilterBilinear:
141a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_LINEAR;
142a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      break;
143a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   case PictFilterFast:
144a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_NEAREST;
145a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      break;
146a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   case PictFilterGood:
147a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_LINEAR;
148a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      break;
149a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   case PictFilterBest:
150a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_LINEAR;
151a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      break;
15246feb7db71b05ec67a7c78f6bc608adec0734decVinson Lee   case PictFilterConvolution:
15346feb7db71b05ec67a7c78f6bc608adec0734decVinson Lee      *out_filter = PIPE_TEX_FILTER_NEAREST;
15446feb7db71b05ec67a7c78f6bc608adec0734decVinson Lee      return FALSE;
155a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   default:
15608cb1d0ce4765536f1cb6a9253a2245c31fb8ea9Vinson Lee      debug_printf("Unknown xrender filter\n");
157a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_NEAREST;
158a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      return FALSE;
159a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   }
160a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
161a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   return TRUE;
162a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin}
163a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
164a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinstatic boolean is_filter_accelerated(PicturePtr pic)
165a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin{
166a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   int filter;
167a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   if (pic && !render_filter_to_gallium(pic->filter, &filter))
168a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin       return FALSE;
169a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   return TRUE;
170a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin}
171a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
17221cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusinboolean xorg_composite_accelerated(int op,
17321cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                   PicturePtr pSrcPicture,
17421cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                   PicturePtr pMaskPicture,
17521cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                   PicturePtr pDstPicture)
17621cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin{
1776d629d4aa211d098fe9541d0b644cf67ee1d7019Jakob Bornecrantz   ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
1782bb2e6a6e3017d462be0ae9308955f37c5ee03c6Dave Airlie   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1796d629d4aa211d098fe9541d0b644cf67ee1d7019Jakob Bornecrantz   modesettingPtr ms = modesettingPTR(pScrn);
1801f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   struct xorg_composite_blend blend;
181c7653a83330e5ea63ad3a566da15155e216c6cb4Zack Rusin
182a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   if (!is_filter_accelerated(pSrcPicture) ||
183a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin       !is_filter_accelerated(pMaskPicture)) {
184a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      XORG_FALLBACK("Unsupported Xrender filter");
185a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   }
186a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
187626553f327394b835cecaf4795692028c2378efaMichel Dänzer   if (pSrcPicture->pSourcePict) {
188626553f327394b835cecaf4795692028c2378efaMichel Dänzer      if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
189c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin         XORG_FALLBACK("Gradients not enabled (haven't been well tested)");
190626553f327394b835cecaf4795692028c2378efaMichel Dänzer   }
191626553f327394b835cecaf4795692028c2378efaMichel Dänzer
1921f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   if (blend_for_op(&blend, op,
1931f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin                    pSrcPicture, pMaskPicture, pDstPicture)) {
1941f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      /* Check for component alpha */
1951f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      if (pMaskPicture && pMaskPicture->componentAlpha &&
1961f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin          PICT_FORMAT_RGB(pMaskPicture->format)) {
1971f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) {
1981f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin            XORG_FALLBACK("Component alpha not supported with source "
1991f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin                          "alpha and source value blending. (op=%d)",
2001f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin                          op);
201c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin         }
202c7653a83330e5ea63ad3a566da15155e216c6cb4Zack Rusin      }
203493d599af4f617d52323e0368e65da29ba4638aaZack Rusin
2041f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      return TRUE;
205c7653a83330e5ea63ad3a566da15155e216c6cb4Zack Rusin   }
206c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   XORG_FALLBACK("Unsupported composition operation = %d", op);
20721cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin}
20821cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin
209f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusinstatic void
2102048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusinbind_blend_state(struct exa_context *exa, int op,
211c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin                 PicturePtr pSrcPicture,
212c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin                 PicturePtr pMaskPicture,
213c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin                 PicturePtr pDstPicture)
214f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin{
2152048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   struct xorg_composite_blend blend_opt;
2162048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   struct pipe_blend_state blend;
2172048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
2181f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture);
2192048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
220c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   memset(&blend, 0, sizeof(struct pipe_blend_state));
22192676b9fe6356a8974830c47c0191d1ca57a0741Roland Scheidegger   blend.rt[0].blend_enable = 1;
22292676b9fe6356a8974830c47c0191d1ca57a0741Roland Scheidegger   blend.rt[0].colormask = PIPE_MASK_RGBA;
2232048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
22492676b9fe6356a8974830c47c0191d1ca57a0741Roland Scheidegger   blend.rt[0].rgb_src_factor   = blend_opt.rgb_src;
22592676b9fe6356a8974830c47c0191d1ca57a0741Roland Scheidegger   blend.rt[0].alpha_src_factor = blend_opt.rgb_src;
22692676b9fe6356a8974830c47c0191d1ca57a0741Roland Scheidegger   blend.rt[0].rgb_dst_factor   = blend_opt.rgb_dst;
22792676b9fe6356a8974830c47c0191d1ca57a0741Roland Scheidegger   blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
2282048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
229319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_blend(exa->renderer->cso, &blend);
230f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin}
231f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin
2325438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantzstatic unsigned
233c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusinpicture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask,
234c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin                      PicturePtr pDstPicture)
2355438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz{
2365438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   boolean set_alpha = FALSE;
2375438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   boolean swizzle = FALSE;
2385438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   unsigned ret = 0;
2395438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
24054d1b718b897742bf424f61f911e4ca8bbffa689Marcin Slusarz   if (pSrc && pSrc->picture_format == pSrcPicture->format) {
241c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin      if (pSrc->picture_format == PICT_a8) {
242c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin         if (mask)
243c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin            return FS_MASK_LUMINANCE;
244c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin         else if (pDstPicture->format != PICT_a8) {
245c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin            /* if both dst and src are luminance then
246c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin             * we don't want to swizzle the alpha (X) of the
247c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin             * source into W component of the dst because
248c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin             * it will break our destination */
249c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin            return FS_SRC_LUMINANCE;
250c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin         }
251c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin      }
2525438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      return 0;
253cb060f3b987c9fa07ebe06cf2e7e54d1eaded1e1Jakob Bornecrantz   }
2545438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
25554d1b718b897742bf424f61f911e4ca8bbffa689Marcin Slusarz   if (pSrc && pSrc->picture_format != PICT_a8r8g8b8) {
2565438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      assert(!"can not handle formats");
2575438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      return 0;
2585438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   }
2595438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
2605438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   /* pSrc->picture_format == PICT_a8r8g8b8 */
2615438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   switch (pSrcPicture->format) {
2625438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_x8b8g8r8:
2635438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_b8g8r8:
2645438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      set_alpha = TRUE; /* fall trough */
2655438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_a8b8g8r8:
2665438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      swizzle = TRUE;
2675438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      break;
2685438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_x8r8g8b8:
2695438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_r8g8b8:
2705438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      set_alpha = TRUE; /* fall through */
2715438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_a8r8g8b8:
2725438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      break;
2735438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz#ifdef PICT_TYPE_BGRA
2745438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_b8g8r8a8:
2755438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_b8g8r8x8:
2765438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_a2r10g10b10:
2775438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_x2r10g10b10:
2785438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_a2b10g10r10:
2795438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_x2b10g10r10:
2805438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz#endif
2815438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   default:
2825438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      assert(!"can not handle formats");
2835438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      return 0;
2845438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   }
2855438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
2865438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   if (set_alpha)
2875438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
2885438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   if (swizzle)
2895438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
2905438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
2915438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   return ret;
2925438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz}
293f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin
294f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusinstatic void
2958bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusinbind_shaders(struct exa_context *exa, int op,
296c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin             PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture,
2975438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz             struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask)
298f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin{
2998bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   unsigned vs_traits = 0, fs_traits = 0;
3008bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   struct xorg_shader shader;
3018bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin
3026be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   exa->has_solid_color = FALSE;
3036be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
3048bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   if (pSrcPicture) {
3052cfbbc76e445d88bdac7dd4dd22aaf36bbc8e4ccZack Rusin      if (pSrcPicture->repeatType == RepeatNone && pSrcPicture->transform)
3062cfbbc76e445d88bdac7dd4dd22aaf36bbc8e4ccZack Rusin         fs_traits |= FS_SRC_REPEAT_NONE;
3072cfbbc76e445d88bdac7dd4dd22aaf36bbc8e4ccZack Rusin
308a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin      if (pSrcPicture->pSourcePict) {
309a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin         if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
31007f9ad5c322ce409fdd4b86e3913f7cc085520b5Zack Rusin            fs_traits |= FS_SOLID_FILL;
31107f9ad5c322ce409fdd4b86e3913f7cc085520b5Zack Rusin            vs_traits |= VS_SOLID_FILL;
3127edda9350acbf84b63ad67af8053fb07785637cbMichel Dänzer            debug_assert(pSrcPicture->format == PICT_a8r8g8b8);
3137edda9350acbf84b63ad67af8053fb07785637cbMichel Dänzer            pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color,
3143bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer                            exa->solid_color, PIPE_FORMAT_B8G8R8A8_UNORM);
3156be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin            exa->has_solid_color = TRUE;
316a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin         } else {
317a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin            debug_assert("!gradients not supported");
318a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin         }
319a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin      } else {
320a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin         fs_traits |= FS_COMPOSITE;
321a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin         vs_traits |= VS_COMPOSITE;
322a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin      }
3235438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
324c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin      fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture);
3258bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   }
3268bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin
3278bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   if (pMaskPicture) {
3288bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin      vs_traits |= VS_MASK;
3298bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin      fs_traits |= FS_MASK;
3302cfbbc76e445d88bdac7dd4dd22aaf36bbc8e4ccZack Rusin      if (pMaskPicture->repeatType == RepeatNone && pMaskPicture->transform)
3312cfbbc76e445d88bdac7dd4dd22aaf36bbc8e4ccZack Rusin         fs_traits |= FS_MASK_REPEAT_NONE;
332b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      if (pMaskPicture->componentAlpha) {
333b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         struct xorg_composite_blend blend;
334b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         blend_for_op(&blend, op,
335b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin                      pSrcPicture, pMaskPicture, NULL);
336b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         if (blend.alpha_src) {
337b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin            fs_traits |= FS_CA_SRCALPHA;
338b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         } else
339b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin            fs_traits |= FS_CA_FULL;
340b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      }
3415438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
342c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin      fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture);
3438bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   }
3448bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin
345319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
346319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
347319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
348f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin}
349f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin
350f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusinstatic void
351f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusinbind_samplers(struct exa_context *exa, int op,
352f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusin              PicturePtr pSrcPicture, PicturePtr pMaskPicture,
3530a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin              PicturePtr pDstPicture,
3540a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin              struct exa_pixmap_priv *pSrc,
3550a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin              struct exa_pixmap_priv *pMask,
3560a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin              struct exa_pixmap_priv *pDst)
357f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusin{
358fe20edf959c4ec565ef29f2556e03ce36e0c259fMarcin Slusarz   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS] = {0};
3590a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   struct pipe_sampler_state src_sampler, mask_sampler;
360ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger   struct pipe_sampler_view view_templ;
361ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger   struct pipe_sampler_view *src_view;
362ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger   struct pipe_context *pipe = exa->pipe;
3630a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin
36491c366359ce0bf5f450fd1d774b771c95ed2f651Zack Rusin   exa->num_bound_samplers = 0;
36591c366359ce0bf5f450fd1d774b771c95ed2f651Zack Rusin
3660a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
3670a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
3680a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin
3690a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   if (pSrcPicture && pSrc) {
370b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      if (exa->has_solid_color) {
371b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         debug_assert(!"solid color with textures");
372b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         samplers[0] = NULL;
373ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger         pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
374b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      } else {
375b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         unsigned src_wrap = render_repeat_to_gallium(
376b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin            pSrcPicture->repeatType);
377b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         int filter;
378b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin
379b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         render_filter_to_gallium(pSrcPicture->filter, &filter);
380b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin
381b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.wrap_s = src_wrap;
382b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.wrap_t = src_wrap;
383b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.min_img_filter = filter;
384b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.mag_img_filter = filter;
385b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
386b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.normalized_coords = 1;
387b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         samplers[0] = &src_sampler;
388b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         exa->num_bound_samplers = 1;
389ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger         u_sampler_view_default_template(&view_templ,
390ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger                                         pSrc->tex,
391ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger                                         pSrc->tex->format);
392ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger         src_view = pipe->create_sampler_view(pipe, pSrc->tex, &view_templ);
393ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger         pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
394ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger         exa->bound_sampler_views[0] = src_view;
395b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      }
3960a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   }
3970a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin
3980a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   if (pMaskPicture && pMask) {
399d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      unsigned mask_wrap = render_repeat_to_gallium(
400d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin         pMaskPicture->repeatType);
401a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      int filter;
402a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
403a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      render_filter_to_gallium(pMaskPicture->filter, &filter);
404a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
405d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      mask_sampler.wrap_s = mask_wrap;
406d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      mask_sampler.wrap_t = mask_wrap;
407a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      mask_sampler.min_img_filter = filter;
408a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      mask_sampler.mag_img_filter = filter;
409a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
4100a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin      mask_sampler.normalized_coords = 1;
4110a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin      samplers[1] = &mask_sampler;
412b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      exa->num_bound_samplers = 2;
413ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger      u_sampler_view_default_template(&view_templ,
414ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger                                      pMask->tex,
415ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger                                      pMask->tex->format);
416ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger      src_view = pipe->create_sampler_view(pipe, pMask->tex, &view_templ);
417ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger      pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
418ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger      exa->bound_sampler_views[1] = src_view;
4190a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   }
420f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusin
421c61d3fe8bddcbcf750c5f057a45b262fea92ca5eBrian Paul   cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
422c61d3fe8bddcbcf750c5f057a45b262fea92ca5eBrian Paul                    exa->num_bound_samplers,
4230a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin                    (const struct pipe_sampler_state **)samplers);
424c61d3fe8bddcbcf750c5f057a45b262fea92ca5eBrian Paul   cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
425c61d3fe8bddcbcf750c5f057a45b262fea92ca5eBrian Paul                         exa->num_bound_samplers,
426c61d3fe8bddcbcf750c5f057a45b262fea92ca5eBrian Paul                         exa->bound_sampler_views);
427f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusin}
428f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusin
4299ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin
4309ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin
431a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinstatic INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
432a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin{
433a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   if (!trans)
434a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      return FALSE;
435a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
436a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   matrix[0] = XFixedToDouble(trans->matrix[0][0]);
437bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[3] = XFixedToDouble(trans->matrix[0][1]);
438bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[6] = XFixedToDouble(trans->matrix[0][2]);
439a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
440bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[1] = XFixedToDouble(trans->matrix[1][0]);
441a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   matrix[4] = XFixedToDouble(trans->matrix[1][1]);
442bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[7] = XFixedToDouble(trans->matrix[1][2]);
443a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
444bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[2] = XFixedToDouble(trans->matrix[2][0]);
445bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[5] = XFixedToDouble(trans->matrix[2][1]);
446a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   matrix[8] = XFixedToDouble(trans->matrix[2][2]);
447a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
448a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   return TRUE;
449a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin}
450a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
451a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinstatic void
452a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinsetup_transforms(struct  exa_context *exa,
453a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin                 PicturePtr pSrcPicture, PicturePtr pMaskPicture)
454a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin{
455a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   PictTransform *src_t = NULL;
456a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   PictTransform *mask_t = NULL;
457a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
458a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   if (pSrcPicture)
459a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      src_t = pSrcPicture->transform;
460a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   if (pMaskPicture)
461a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      mask_t = pMaskPicture->transform;
462a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
463a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   exa->transform.has_src  =
464a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      matrix_from_pict_transform(src_t, exa->transform.src);
465a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   exa->transform.has_mask =
466a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      matrix_from_pict_transform(mask_t, exa->transform.mask);
467a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin}
468a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
46921cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusinboolean xorg_composite_bind_state(struct exa_context *exa,
47021cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                  int op,
47121cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                  PicturePtr pSrcPicture,
47221cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                  PicturePtr pMaskPicture,
473f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin                                  PicturePtr pDstPicture,
474f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin                                  struct exa_pixmap_priv *pSrc,
475f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin                                  struct exa_pixmap_priv *pMask,
476f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin                                  struct exa_pixmap_priv *pDst)
47721cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin{
4784c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pDst);
4797fbdbad5c02e3d5bfbf0e641e2aec224e39fa974Keith Whitwell
4804236493899b9ccfcc8df3dcf81697776621fa1f8Keith Whitwell   renderer_bind_destination(exa->renderer, dst_surf,
4814236493899b9ccfcc8df3dcf81697776621fa1f8Keith Whitwell                             pDst->width,
4824236493899b9ccfcc8df3dcf81697776621fa1f8Keith Whitwell                             pDst->height);
4837fbdbad5c02e3d5bfbf0e641e2aec224e39fa974Keith Whitwell
484c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);
485c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin   bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask);
48691c366359ce0bf5f450fd1d774b771c95ed2f651Zack Rusin   bind_samplers(exa, op, pSrcPicture, pMaskPicture,
48791c366359ce0bf5f450fd1d774b771c95ed2f651Zack Rusin                 pDstPicture, pSrc, pMask, pDst);
4889ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin
489a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   setup_transforms(exa, pSrcPicture, pMaskPicture);
490a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
491e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin   if (exa->num_bound_samplers == 0 ) { /* solid fill */
492e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin      renderer_begin_solid(exa->renderer);
493e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin   } else {
494e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin      renderer_begin_textures(exa->renderer,
495e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin                              exa->num_bound_samplers);
496e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin   }
497e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin
498ecfe1352ccce802c9299c76d600c4d2f33352701Keith Whitwell
499ecfe1352ccce802c9299c76d600c4d2f33352701Keith Whitwell   pipe_surface_reference(&dst_surf, NULL);
50089bb33fb20e69d9fa5325da10abf31d61d51d371Zack Rusin   return TRUE;
50121cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin}
50221cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin
50321cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusinvoid xorg_composite(struct exa_context *exa,
50421cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                    struct exa_pixmap_priv *dst,
50521cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                    int srcX, int srcY, int maskX, int maskY,
50621cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                    int dstX, int dstY, int width, int height)
50721cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin{
508811aa02c7a0f4804189a8978395f07d27fb726ecZack Rusin   if (exa->num_bound_samplers == 0 ) { /* solid fill */
5094322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin      renderer_solid(exa->renderer,
5104322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin                     dstX, dstY, dstX + width, dstY + height,
5114322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin                     exa->solid_color);
512319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   } else {
513319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin      int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY};
514a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      float *src_matrix = NULL;
515a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      float *mask_matrix = NULL;
516a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
517a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      if (exa->transform.has_src)
518a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin         src_matrix = exa->transform.src;
519a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      if (exa->transform.has_mask)
520a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin         mask_matrix = exa->transform.mask;
521a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
522e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin      renderer_texture(exa->renderer,
523e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin                       pos, width, height,
524ac8662c29dbf96b456d23308c1bc459eea63e36cRoland Scheidegger                       exa->bound_sampler_views,
525e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin                       exa->num_bound_samplers,
526e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin                       src_matrix, mask_matrix);
527811aa02c7a0f4804189a8978395f07d27fb726ecZack Rusin   }
52821cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin}
52921cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin
5303167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusinboolean xorg_solid_bind_state(struct exa_context *exa,
5313167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin                              struct exa_pixmap_priv *pixmap,
5323167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin                              Pixel fg)
5333167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin{
5344c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pixmap);
5356be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   unsigned vs_traits, fs_traits;
5366be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   struct xorg_shader shader;
5376be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
5383bcb9a858f482c21bc7c4d0fcd3571e25ea95090Michel Dänzer   pixel_to_float4(fg, exa->solid_color, pixmap->tex->format);
5396be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   exa->has_solid_color = TRUE;
5406be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
541ef7746217176ba251dc6a5deb90c308c9964ed7bZack Rusin#if 0
5426be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
5436be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin                (fg >> 24) & 0xff, (fg >> 16) & 0xff,
5446be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin                (fg >> 8) & 0xff,  (fg >> 0) & 0xff,
5456be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin                exa->solid_color[0], exa->solid_color[1],
5466be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin                exa->solid_color[2], exa->solid_color[3]);
5476be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin#endif
5486be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
5496be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   vs_traits = VS_SOLID_FILL;
5506be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   fs_traits = FS_SOLID_FILL;
5516be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
5524236493899b9ccfcc8df3dcf81697776621fa1f8Keith Whitwell   renderer_bind_destination(exa->renderer, dst_surf,
5534236493899b9ccfcc8df3dcf81697776621fa1f8Keith Whitwell                             pixmap->width, pixmap->height);
554c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
555c61d3fe8bddcbcf750c5f057a45b262fea92ca5eBrian Paul   cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
556c61d3fe8bddcbcf750c5f057a45b262fea92ca5eBrian Paul   cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
5576be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
558319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
559319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
560319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
5616be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
5624322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin   renderer_begin_solid(exa->renderer);
5634322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin
564ecfe1352ccce802c9299c76d600c4d2f33352701Keith Whitwell   pipe_surface_reference(&dst_surf, NULL);
56553d2fa46e7fa19d0cb7dec74efcd407ab6163c80Zack Rusin   return TRUE;
5663167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin}
5673167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin
5683167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusinvoid xorg_solid(struct exa_context *exa,
5693167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin                struct exa_pixmap_priv *pixmap,
5703167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin                int x0, int y0, int x1, int y1)
5713167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin{
5724322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin   renderer_solid(exa->renderer,
5734322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin                  x0, y0, x1, y1, exa->solid_color);
57457d0934bc562c7a0de0c79fb0263ab3569eed002Zack Rusin}
57557d0934bc562c7a0de0c79fb0263ab3569eed002Zack Rusin
576fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwellvoid
577fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwellxorg_composite_done(struct exa_context *exa)
578fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell{
579fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell   renderer_draw_flush(exa->renderer);
580fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell
581fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell   exa->transform.has_src = FALSE;
582fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell   exa->transform.has_mask = FALSE;
583fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell   exa->has_solid_color = FALSE;
584fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell   exa->num_bound_samplers = 0;
585fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell}
586