xorg_composite.c revision fa799f81dec1b72e59008b7029d94a00bcf821bb
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"
7f315c0128b5f6317f910f6c54119fea97256254cZack Rusin#include "util/u_draw_quad.h"
8feb74e7753f56c0fa3ec943a45bbf48f2183e04cZack Rusin#include "util/u_math.h"
9f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin
10f315c0128b5f6317f910f6c54119fea97256254cZack Rusin#include "pipe/p_inlines.h"
11f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin
12a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin/*XXX also in Xrender.h but the including it here breaks compilition */
13a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin#define XFixedToDouble(f)    (((double) (f)) / 65536.)
14a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
1517076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusinstruct xorg_composite_blend {
16c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   int op : 8;
1717076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin
18c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   unsigned alpha_dst : 4;
19c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   unsigned alpha_src : 4;
208adcad0c703a9d339b6630ceaba5f96981c524d9Zack Rusin
21c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   unsigned rgb_src : 8;    /**< PIPE_BLENDFACTOR_x */
22c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   unsigned rgb_dst : 8;    /**< PIPE_BLENDFACTOR_x */
2317076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin};
2417076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin
252048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin#define BLEND_OP_OVER 3
2617076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusinstatic const struct xorg_composite_blend xorg_blends[] = {
2717076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin   { PictOpClear,
28c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO},
2917076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin   { PictOpSrc,
30c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO},
3117076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin   { PictOpDst,
32c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE},
3317076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin   { PictOpOver,
34c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 1, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
3517076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin   { PictOpOverReverse,
36c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE},
37074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpIn,
38c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 0, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
39074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpInReverse,
40c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_SRC_ALPHA},
41074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpOut,
42c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
4359cf40059a7c451b1d1bc0c90f674e8e4baa5ab8Zack Rusin   { PictOpOutReverse,
44c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
45074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpAtop,
46c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 1, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
47074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpAtopReverse,
48c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_SRC_ALPHA},
49074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpXor,
50c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
51074e069910c7082620be4211fe5496365f828886Zack Rusin   { PictOpAdd,
52c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin     0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE},
5317076d700c94402f82c22b2e1d99a1753e4a0834Zack Rusin};
5421cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin
556be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
566be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusinstatic INLINE void
576be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusinpixel_to_float4(Pixel pixel, float *color)
586be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin{
596be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   CARD32	    r, g, b, a;
606be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
616be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   a = (pixel >> 24) & 0xff;
626be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   r = (pixel >> 16) & 0xff;
636be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   g = (pixel >>  8) & 0xff;
646be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   b = (pixel >>  0) & 0xff;
656be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   color[0] = ((float)r) / 255.;
666be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   color[1] = ((float)g) / 255.;
676be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   color[2] = ((float)b) / 255.;
686be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   color[3] = ((float)a) / 255.;
696be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin}
706be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
711f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusinstatic boolean
721f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusinblend_for_op(struct xorg_composite_blend *blend,
731f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin             int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
74c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin             PicturePtr pDstPicture)
752048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin{
762048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   const int num_blends =
772048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin      sizeof(xorg_blends)/sizeof(struct xorg_composite_blend);
782048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   int i;
791f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   boolean supported = FALSE;
801f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin
811f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   /* our default in case something goes wrong */
821f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   *blend = xorg_blends[BLEND_OP_OVER];
832048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
842048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   for (i = 0; i < num_blends; ++i) {
851f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      if (xorg_blends[i].op == op) {
861f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         *blend = xorg_blends[i];
871f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         supported = TRUE;
881f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      }
892048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   }
90c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin
91c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   /* If there's no dst alpha channel, adjust the blend op so that we'll treat
921f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin    * it as always 1. */
93c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   if (pDstPicture &&
941f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin       PICT_FORMAT_A(pDstPicture->format) == 0 && blend->alpha_dst) {
951f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
961f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         blend->rgb_src = PIPE_BLENDFACTOR_ONE;
971f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
981f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         blend->rgb_src = PIPE_BLENDFACTOR_ZERO;
99c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   }
100c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin
101c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   /* If the source alpha is being used, then we should only be in a case where
102c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin    * the source blend factor is 0, and the source blend value is the mask
1031f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin    * channels multiplied by the source picture's alpha. */
104c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   if (pMaskPicture && pMaskPicture->componentAlpha &&
1051f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin       PICT_FORMAT_RGB(pMaskPicture->format) && blend->alpha_src) {
1061f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) {
1071f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR;
1081f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      } else if (blend->rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) {
1091f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         blend->rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR;
110c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin      }
111c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   }
112b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin
1131f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   return supported;
1142048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin}
1152048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
116d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusinstatic INLINE int
117d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusinrender_repeat_to_gallium(int mode)
118d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin{
119d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   switch(mode) {
120d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   case RepeatNone:
121fca8b2c3ae53695f8ff6e823cc316aab910490e5Zack Rusin      return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
122d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   case RepeatNormal:
123d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      return PIPE_TEX_WRAP_REPEAT;
124d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   case RepeatReflect:
125d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      return PIPE_TEX_WRAP_MIRROR_REPEAT;
126d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   case RepeatPad:
127d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
128d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   default:
129d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      debug_printf("Unsupported repeat mode\n");
130d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   }
131d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin   return PIPE_TEX_WRAP_REPEAT;
132d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin}
133d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin
134a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinstatic INLINE boolean
135a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinrender_filter_to_gallium(int xrender_filter, int *out_filter)
136a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin{
137a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
138a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   switch (xrender_filter) {
139a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   case PictFilterNearest:
140a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_NEAREST;
141a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      break;
142a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   case PictFilterBilinear:
143a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_LINEAR;
144a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      break;
145a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   case PictFilterFast:
146a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_NEAREST;
147a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      break;
148a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   case PictFilterGood:
149a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_LINEAR;
150a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      break;
151a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   case PictFilterBest:
152a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_LINEAR;
153a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      break;
15446feb7db71b05ec67a7c78f6bc608adec0734decVinson Lee   case PictFilterConvolution:
15546feb7db71b05ec67a7c78f6bc608adec0734decVinson Lee      *out_filter = PIPE_TEX_FILTER_NEAREST;
15646feb7db71b05ec67a7c78f6bc608adec0734decVinson Lee      return FALSE;
157a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   default:
15808cb1d0ce4765536f1cb6a9253a2245c31fb8ea9Vinson Lee      debug_printf("Unknown xrender filter\n");
159a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      *out_filter = PIPE_TEX_FILTER_NEAREST;
160a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      return FALSE;
161a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   }
162a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
163a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   return TRUE;
164a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin}
165a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
166a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinstatic boolean is_filter_accelerated(PicturePtr pic)
167a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin{
168a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   int filter;
169a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   if (pic && !render_filter_to_gallium(pic->filter, &filter))
170a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin       return FALSE;
171a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   return TRUE;
172a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin}
173a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
17421cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusinboolean xorg_composite_accelerated(int op,
17521cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                   PicturePtr pSrcPicture,
17621cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                   PicturePtr pMaskPicture,
17721cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                   PicturePtr pDstPicture)
17821cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin{
1796d629d4aa211d098fe9541d0b644cf67ee1d7019Jakob Bornecrantz   ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
1806d629d4aa211d098fe9541d0b644cf67ee1d7019Jakob Bornecrantz   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1816d629d4aa211d098fe9541d0b644cf67ee1d7019Jakob Bornecrantz   modesettingPtr ms = modesettingPTR(pScrn);
1821f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   struct xorg_composite_blend blend;
183c7653a83330e5ea63ad3a566da15155e216c6cb4Zack Rusin
184a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   if (!is_filter_accelerated(pSrcPicture) ||
185a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin       !is_filter_accelerated(pMaskPicture)) {
186a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      XORG_FALLBACK("Unsupported Xrender filter");
187a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   }
188a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
189626553f327394b835cecaf4795692028c2378efaMichel Dänzer   if (pSrcPicture->pSourcePict) {
190626553f327394b835cecaf4795692028c2378efaMichel Dänzer      if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
191c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin         XORG_FALLBACK("Gradients not enabled (haven't been well tested)");
192626553f327394b835cecaf4795692028c2378efaMichel Dänzer   }
193626553f327394b835cecaf4795692028c2378efaMichel Dänzer
1941f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   if (blend_for_op(&blend, op,
1951f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin                    pSrcPicture, pMaskPicture, pDstPicture)) {
1961f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      /* Check for component alpha */
1971f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      if (pMaskPicture && pMaskPicture->componentAlpha &&
1981f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin          PICT_FORMAT_RGB(pMaskPicture->format)) {
1991f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin         if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) {
2001f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin            XORG_FALLBACK("Component alpha not supported with source "
2011f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin                          "alpha and source value blending. (op=%d)",
2021f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin                          op);
203c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin         }
204c7653a83330e5ea63ad3a566da15155e216c6cb4Zack Rusin      }
205493d599af4f617d52323e0368e65da29ba4638aaZack Rusin
2061f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin      return TRUE;
207c7653a83330e5ea63ad3a566da15155e216c6cb4Zack Rusin   }
208c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   XORG_FALLBACK("Unsupported composition operation = %d", op);
20921cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin}
21021cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin
211f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusinstatic void
2122048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusinbind_blend_state(struct exa_context *exa, int op,
213c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin                 PicturePtr pSrcPicture,
214c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin                 PicturePtr pMaskPicture,
215c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin                 PicturePtr pDstPicture)
216f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin{
2172048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   struct xorg_composite_blend blend_opt;
2182048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   struct pipe_blend_state blend;
2192048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
2201f5b568fbeda9e48f0ea6473cf8193e9502bb21aZack Rusin   blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture);
2212048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
222c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   memset(&blend, 0, sizeof(struct pipe_blend_state));
2232048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin   blend.blend_enable = 1;
22459cf40059a7c451b1d1bc0c90f674e8e4baa5ab8Zack Rusin   blend.colormask |= PIPE_MASK_RGBA;
2252048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
226c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   blend.rgb_src_factor   = blend_opt.rgb_src;
227c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   blend.alpha_src_factor = blend_opt.rgb_src;
228c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   blend.rgb_dst_factor   = blend_opt.rgb_dst;
229c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   blend.alpha_dst_factor = blend_opt.rgb_dst;
2302048182e868a759c3198b3cbaf2dd1d366fe0a21Zack Rusin
231319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_blend(exa->renderer->cso, &blend);
232f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin}
233f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin
2345438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantzstatic unsigned
235c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusinpicture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask,
236c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin                      PicturePtr pDstPicture)
2375438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz{
2385438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   boolean set_alpha = FALSE;
2395438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   boolean swizzle = FALSE;
2405438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   unsigned ret = 0;
2415438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
242cb060f3b987c9fa07ebe06cf2e7e54d1eaded1e1Jakob Bornecrantz   if (pSrc->picture_format == pSrcPicture->format) {
243c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin      if (pSrc->picture_format == PICT_a8) {
244c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin         if (mask)
245c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin            return FS_MASK_LUMINANCE;
246c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin         else if (pDstPicture->format != PICT_a8) {
247c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin            /* if both dst and src are luminance then
248c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin             * we don't want to swizzle the alpha (X) of the
249c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin             * source into W component of the dst because
250c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin             * it will break our destination */
251c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin            return FS_SRC_LUMINANCE;
252c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin         }
253c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin      }
2545438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      return 0;
255cb060f3b987c9fa07ebe06cf2e7e54d1eaded1e1Jakob Bornecrantz   }
2565438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
2575438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   if (pSrc->picture_format != PICT_a8r8g8b8) {
2585438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      assert(!"can not handle formats");
2595438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      return 0;
2605438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   }
2615438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
2625438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   /* pSrc->picture_format == PICT_a8r8g8b8 */
2635438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   switch (pSrcPicture->format) {
2645438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_x8b8g8r8:
2655438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_b8g8r8:
2665438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      set_alpha = TRUE; /* fall trough */
2675438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_a8b8g8r8:
2685438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      swizzle = TRUE;
2695438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      break;
2705438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_x8r8g8b8:
2715438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_r8g8b8:
2725438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      set_alpha = TRUE; /* fall through */
2735438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_a8r8g8b8:
2745438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      break;
2755438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz#ifdef PICT_TYPE_BGRA
2765438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_b8g8r8a8:
2775438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_b8g8r8x8:
2785438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_a2r10g10b10:
2795438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_x2r10g10b10:
2805438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_a2b10g10r10:
2815438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   case PICT_x2b10g10r10:
2825438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz#endif
2835438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   default:
2845438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      assert(!"can not handle formats");
2855438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      return 0;
2865438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   }
2875438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
2885438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   if (set_alpha)
2895438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
2905438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   if (swizzle)
2915438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz      ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
2925438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
2935438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz   return ret;
2945438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz}
295f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin
296f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusinstatic void
2978bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusinbind_shaders(struct exa_context *exa, int op,
298c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin             PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture,
2995438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz             struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask)
300f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin{
3018bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   unsigned vs_traits = 0, fs_traits = 0;
3028bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   struct xorg_shader shader;
3038bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin
3046be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   exa->has_solid_color = FALSE;
3056be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
3068bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   if (pSrcPicture) {
3072cfbbc76e445d88bdac7dd4dd22aaf36bbc8e4ccZack Rusin      if (pSrcPicture->repeatType == RepeatNone && pSrcPicture->transform)
3082cfbbc76e445d88bdac7dd4dd22aaf36bbc8e4ccZack Rusin         fs_traits |= FS_SRC_REPEAT_NONE;
3092cfbbc76e445d88bdac7dd4dd22aaf36bbc8e4ccZack Rusin
310a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin      if (pSrcPicture->pSourcePict) {
311a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin         if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
31207f9ad5c322ce409fdd4b86e3913f7cc085520b5Zack Rusin            fs_traits |= FS_SOLID_FILL;
31307f9ad5c322ce409fdd4b86e3913f7cc085520b5Zack Rusin            vs_traits |= VS_SOLID_FILL;
3147edda9350acbf84b63ad67af8053fb07785637cbMichel Dänzer            debug_assert(pSrcPicture->format == PICT_a8r8g8b8);
3157edda9350acbf84b63ad67af8053fb07785637cbMichel Dänzer            pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color,
3167edda9350acbf84b63ad67af8053fb07785637cbMichel Dänzer                            exa->solid_color);
3176be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin            exa->has_solid_color = TRUE;
318a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin         } else {
319a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin            debug_assert("!gradients not supported");
320a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin         }
321a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin      } else {
322a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin         fs_traits |= FS_COMPOSITE;
323a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin         vs_traits |= VS_COMPOSITE;
324a8cbb1563213086f58d3b82b6d0755a59eb43c79Zack Rusin      }
3255438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
326c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin      fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture);
3278bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   }
3288bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin
3298bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   if (pMaskPicture) {
3308bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin      vs_traits |= VS_MASK;
3318bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin      fs_traits |= FS_MASK;
3322cfbbc76e445d88bdac7dd4dd22aaf36bbc8e4ccZack Rusin      if (pMaskPicture->repeatType == RepeatNone && pMaskPicture->transform)
3332cfbbc76e445d88bdac7dd4dd22aaf36bbc8e4ccZack Rusin         fs_traits |= FS_MASK_REPEAT_NONE;
334b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      if (pMaskPicture->componentAlpha) {
335b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         struct xorg_composite_blend blend;
336b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         blend_for_op(&blend, op,
337b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin                      pSrcPicture, pMaskPicture, NULL);
338b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         if (blend.alpha_src) {
339b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin            fs_traits |= FS_CA_SRCALPHA;
340b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         } else
341b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin            fs_traits |= FS_CA_FULL;
342b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      }
3435438ee3ecfe5c25102d196fd6d7258201e27e6caJakob Bornecrantz
344c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin      fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture);
3458bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin   }
3468bdce0c3a7b3e3798de736ef4ce72431d777901cZack Rusin
347319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
348319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
349319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
350f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin}
351f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin
352f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusinstatic void
353f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusinbind_samplers(struct exa_context *exa, int op,
354f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusin              PicturePtr pSrcPicture, PicturePtr pMaskPicture,
3550a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin              PicturePtr pDstPicture,
3560a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin              struct exa_pixmap_priv *pSrc,
3570a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin              struct exa_pixmap_priv *pMask,
3580a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin              struct exa_pixmap_priv *pDst)
359f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusin{
3600a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
3610a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   struct pipe_sampler_state src_sampler, mask_sampler;
3620a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin
36391c366359ce0bf5f450fd1d774b771c95ed2f651Zack Rusin   exa->num_bound_samplers = 0;
36491c366359ce0bf5f450fd1d774b771c95ed2f651Zack Rusin
365a6d527d7b82579feae9db20657d47a3f86115bb4Zack Rusin#if 0
366a6d527d7b82579feae9db20657d47a3f86115bb4Zack Rusin   if ((pSrc && (exa->pipe->is_texture_referenced(exa->pipe, pSrc->tex, 0, 0) &
367a6d527d7b82579feae9db20657d47a3f86115bb4Zack Rusin                 PIPE_REFERENCED_FOR_WRITE)) ||
368a6d527d7b82579feae9db20657d47a3f86115bb4Zack Rusin       (pMask && (exa->pipe->is_texture_referenced(exa->pipe, pMask->tex, 0, 0) &
369a6d527d7b82579feae9db20657d47a3f86115bb4Zack Rusin        PIPE_REFERENCED_FOR_WRITE)))
370a6d527d7b82579feae9db20657d47a3f86115bb4Zack Rusin      xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
371a6d527d7b82579feae9db20657d47a3f86115bb4Zack Rusin#endif
372a6d527d7b82579feae9db20657d47a3f86115bb4Zack Rusin
3730a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
3740a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
3750a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin
3760a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   if (pSrcPicture && pSrc) {
377b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      if (exa->has_solid_color) {
378b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         debug_assert(!"solid color with textures");
379b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         samplers[0] = NULL;
380b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         exa->bound_textures[0] = NULL;
381b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      } else {
382b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         unsigned src_wrap = render_repeat_to_gallium(
383b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin            pSrcPicture->repeatType);
384b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         int filter;
385b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin
386b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         render_filter_to_gallium(pSrcPicture->filter, &filter);
387b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin
388b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.wrap_s = src_wrap;
389b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.wrap_t = src_wrap;
390b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.min_img_filter = filter;
391b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.mag_img_filter = filter;
392b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
393b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         src_sampler.normalized_coords = 1;
394b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         samplers[0] = &src_sampler;
395b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         exa->bound_textures[0] = pSrc->tex;
396b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin         exa->num_bound_samplers = 1;
397b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      }
3980a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   }
3990a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin
4000a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   if (pMaskPicture && pMask) {
401d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      unsigned mask_wrap = render_repeat_to_gallium(
402d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin         pMaskPicture->repeatType);
403a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      int filter;
404a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
405a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      render_filter_to_gallium(pMaskPicture->filter, &filter);
406a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
407d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      mask_sampler.wrap_s = mask_wrap;
408d6b58a97c2f94ca54852414103c4ac2832279f2fZack Rusin      mask_sampler.wrap_t = mask_wrap;
409a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      mask_sampler.min_img_filter = filter;
410a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      mask_sampler.mag_img_filter = filter;
411a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
4120a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin      mask_sampler.normalized_coords = 1;
4130a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin      samplers[1] = &mask_sampler;
41491c366359ce0bf5f450fd1d774b771c95ed2f651Zack Rusin      exa->bound_textures[1] = pMask->tex;
415b17c885a8aa88ef06f384330d59aeb23b73350bbZack Rusin      exa->num_bound_samplers = 2;
4160a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin   }
417f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusin
418319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_samplers(exa->renderer->cso, exa->num_bound_samplers,
4190a2681128622b0c0a22b68c95309cc70a237cc5cZack Rusin                    (const struct pipe_sampler_state **)samplers);
420319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_sampler_textures(exa->renderer->cso, exa->num_bound_samplers,
42191c366359ce0bf5f450fd1d774b771c95ed2f651Zack Rusin                            exa->bound_textures);
422f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusin}
423f1c0a4b2f4b0054a3371fcaf5121bf53ef29b756Zack Rusin
4249ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin
4259ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin
4269ccbadb22d74c649a634c515cd1123fe96781357Zack Rusinstatic void
4279ccbadb22d74c649a634c515cd1123fe96781357Zack Rusinsetup_fs_constant_buffer(struct exa_context *exa)
4289ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin{
4299ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin   const int param_bytes = 4 * sizeof(float);
430319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   const float fs_consts[8] = {
4319ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin      0, 0, 0, 1,
4329ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin   };
433319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   renderer_set_constants(exa->renderer, PIPE_SHADER_FRAGMENT,
434319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin                          fs_consts, param_bytes);
4359ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin}
4369ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin
4379ccbadb22d74c649a634c515cd1123fe96781357Zack Rusinstatic void
4386be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusinsetup_constant_buffers(struct exa_context *exa, struct exa_pixmap_priv *pDst)
4399ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin{
4409ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin   setup_fs_constant_buffer(exa);
4419ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin}
4429ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin
443a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinstatic INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
444a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin{
445a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   if (!trans)
446a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      return FALSE;
447a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
448a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   matrix[0] = XFixedToDouble(trans->matrix[0][0]);
449bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[3] = XFixedToDouble(trans->matrix[0][1]);
450bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[6] = XFixedToDouble(trans->matrix[0][2]);
451a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
452bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[1] = XFixedToDouble(trans->matrix[1][0]);
453a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   matrix[4] = XFixedToDouble(trans->matrix[1][1]);
454bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[7] = XFixedToDouble(trans->matrix[1][2]);
455a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
456bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[2] = XFixedToDouble(trans->matrix[2][0]);
457bec5230a1ff3998d0f184fc2b7437b51082c329fZack Rusin   matrix[5] = XFixedToDouble(trans->matrix[2][1]);
458a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   matrix[8] = XFixedToDouble(trans->matrix[2][2]);
459a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
460a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   return TRUE;
461a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin}
462a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
463a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinstatic void
464a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusinsetup_transforms(struct  exa_context *exa,
465a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin                 PicturePtr pSrcPicture, PicturePtr pMaskPicture)
466a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin{
467a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   PictTransform *src_t = NULL;
468a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   PictTransform *mask_t = NULL;
469a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
470a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   if (pSrcPicture)
471a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      src_t = pSrcPicture->transform;
472a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   if (pMaskPicture)
473a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      mask_t = pMaskPicture->transform;
474a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
475a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   exa->transform.has_src  =
476a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      matrix_from_pict_transform(src_t, exa->transform.src);
477a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   exa->transform.has_mask =
478a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      matrix_from_pict_transform(mask_t, exa->transform.mask);
479a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin}
480a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
48121cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusinboolean xorg_composite_bind_state(struct exa_context *exa,
48221cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                  int op,
48321cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                  PicturePtr pSrcPicture,
48421cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                                  PicturePtr pMaskPicture,
485f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin                                  PicturePtr pDstPicture,
486f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin                                  struct exa_pixmap_priv *pSrc,
487f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin                                  struct exa_pixmap_priv *pMask,
488f9a3fce09044fbfe9a9b973d33b31cfe826d1386Zack Rusin                                  struct exa_pixmap_priv *pDst)
48921cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin{
4907fbdbad5c02e3d5bfbf0e641e2aec224e39fa974Keith Whitwell   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pDst);
4917fbdbad5c02e3d5bfbf0e641e2aec224e39fa974Keith Whitwell
4927fbdbad5c02e3d5bfbf0e641e2aec224e39fa974Keith Whitwell   renderer_bind_destination(exa->renderer, dst_surf);
4937fbdbad5c02e3d5bfbf0e641e2aec224e39fa974Keith Whitwell
494c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);
495c712f3374626d96f9c08c3571a5572bcee60a5f2Zack Rusin   bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask);
49691c366359ce0bf5f450fd1d774b771c95ed2f651Zack Rusin   bind_samplers(exa, op, pSrcPicture, pMaskPicture,
49791c366359ce0bf5f450fd1d774b771c95ed2f651Zack Rusin                 pDstPicture, pSrc, pMask, pDst);
4986be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   setup_constant_buffers(exa, pDst);
4999ccbadb22d74c649a634c515cd1123fe96781357Zack Rusin
500a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin   setup_transforms(exa, pSrcPicture, pMaskPicture);
501a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
502e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin   if (exa->num_bound_samplers == 0 ) { /* solid fill */
503e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin      renderer_begin_solid(exa->renderer);
504e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin   } else {
505e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin      renderer_begin_textures(exa->renderer,
506e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin                              exa->bound_textures,
507e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin                              exa->num_bound_samplers);
508e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin   }
509e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin
51089bb33fb20e69d9fa5325da10abf31d61d51d371Zack Rusin   return TRUE;
51121cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin}
51221cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin
51321cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusinvoid xorg_composite(struct exa_context *exa,
51421cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                    struct exa_pixmap_priv *dst,
51521cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                    int srcX, int srcY, int maskX, int maskY,
51621cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin                    int dstX, int dstY, int width, int height)
51721cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin{
518811aa02c7a0f4804189a8978395f07d27fb726ecZack Rusin   if (exa->num_bound_samplers == 0 ) { /* solid fill */
5194322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin      renderer_solid(exa->renderer,
5204322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin                     dstX, dstY, dstX + width, dstY + height,
5214322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin                     exa->solid_color);
522319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   } else {
523319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin      int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY};
524a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      float *src_matrix = NULL;
525a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      float *mask_matrix = NULL;
526a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
527a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      if (exa->transform.has_src)
528a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin         src_matrix = exa->transform.src;
529a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin      if (exa->transform.has_mask)
530a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin         mask_matrix = exa->transform.mask;
531a39a3cc14e816cc91a81028a27c4dbd4816cdc9dZack Rusin
532e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin      renderer_texture(exa->renderer,
533e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin                       pos, width, height,
534e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin                       exa->bound_textures,
535e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin                       exa->num_bound_samplers,
536e521bf7706a5527ad5750baef78feaa961f73eccZack Rusin                       src_matrix, mask_matrix);
537811aa02c7a0f4804189a8978395f07d27fb726ecZack Rusin   }
53821cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin}
53921cce6afb03bf9b9adfc6d8a1a446bb3ef22c7a8Zack Rusin
5403167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusinboolean xorg_solid_bind_state(struct exa_context *exa,
5413167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin                              struct exa_pixmap_priv *pixmap,
5423167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin                              Pixel fg)
5433167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin{
5447fbdbad5c02e3d5bfbf0e641e2aec224e39fa974Keith Whitwell   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pixmap);
5456be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   unsigned vs_traits, fs_traits;
5466be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   struct xorg_shader shader;
5476be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
5486be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   pixel_to_float4(fg, exa->solid_color);
5496be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   exa->has_solid_color = TRUE;
5506be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
551ef7746217176ba251dc6a5deb90c308c9964ed7bZack Rusin#if 0
5526be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
5536be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin                (fg >> 24) & 0xff, (fg >> 16) & 0xff,
5546be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin                (fg >> 8) & 0xff,  (fg >> 0) & 0xff,
5556be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin                exa->solid_color[0], exa->solid_color[1],
5566be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin                exa->solid_color[2], exa->solid_color[3]);
5576be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin#endif
5586be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
5596be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   vs_traits = VS_SOLID_FILL;
5606be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   fs_traits = FS_SOLID_FILL;
5616be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
5627fbdbad5c02e3d5bfbf0e641e2aec224e39fa974Keith Whitwell   renderer_bind_destination(exa->renderer, dst_surf);
563c4af8ce69e1a7105b0178da8a085b73ab984e432Zack Rusin   bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
5648d6da811d4fff50dc42e71c6149759908a458f7fJakob Bornecrantz   cso_set_samplers(exa->renderer->cso, 0, NULL);
5658d6da811d4fff50dc42e71c6149759908a458f7fJakob Bornecrantz   cso_set_sampler_textures(exa->renderer->cso, 0, NULL);
5666be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin   setup_constant_buffers(exa, pixmap);
5676be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
568319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
569319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
570319a588238b4c0c58f8f8807e1143ad79cd8f698Zack Rusin   cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
5716be1a98ab9d64584c3852b97e2f1d63697f7bf76Zack Rusin
5724322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin   renderer_begin_solid(exa->renderer);
5734322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin
57453d2fa46e7fa19d0cb7dec74efcd407ab6163c80Zack Rusin   return TRUE;
5753167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin}
5763167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin
5773167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusinvoid xorg_solid(struct exa_context *exa,
5783167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin                struct exa_pixmap_priv *pixmap,
5793167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin                int x0, int y0, int x1, int y1)
5803167c2e8a0a248c290ae8bfff23c88db8f39cd11Zack Rusin{
5814322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin   renderer_solid(exa->renderer,
5824322346f3fd03788a79d056ca7bce2db25bc9d88Zack Rusin                  x0, y0, x1, y1, exa->solid_color);
58357d0934bc562c7a0de0c79fb0263ab3569eed002Zack Rusin}
58457d0934bc562c7a0de0c79fb0263ab3569eed002Zack Rusin
585fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwellvoid
586fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwellxorg_composite_done(struct exa_context *exa)
587fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell{
588fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell   renderer_draw_flush(exa->renderer);
589fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell
590fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell   exa->transform.has_src = FALSE;
591fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell   exa->transform.has_mask = FALSE;
592fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell   exa->has_solid_color = FALSE;
593fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell   exa->num_bound_samplers = 0;
594fa799f81dec1b72e59008b7029d94a00bcf821bbKeith Whitwell}
595