15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xorg_composite.h"
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xorg_renderer.h"
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xorg_exa_tgsi.h"
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "cso_cache/cso_context.h"
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "util/u_format.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "util/u_sampler.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*XXX also in Xrender.h but the including it here breaks compilition */
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define XFixedToDouble(f)    (((double) (f)) / 65536.)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct xorg_composite_blend {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   int op : 8;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   unsigned alpha_dst : 4;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   unsigned alpha_src : 4;
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   unsigned rgb_src : 8;    /**< PIPE_BLENDFACTOR_x */
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   unsigned rgb_dst : 8;    /**< PIPE_BLENDFACTOR_x */
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BLEND_OP_OVER 3
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct xorg_composite_blend xorg_blends[] = {
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   { PictOpClear,
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)     0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO},
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   { PictOpSrc,
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)     0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO},
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   { PictOpDst,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE},
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   { PictOpOver,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     0, 1, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   { PictOpOverReverse,
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE},
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   { PictOpIn,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     1, 0, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   { PictOpInReverse,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_SRC_ALPHA},
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   { PictOpOut,
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)     1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   { PictOpOutReverse,
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)     0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   { PictOpAtop,
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)     1, 1, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   { PictOpAtopReverse,
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)     1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_SRC_ALPHA},
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   { PictOpXor,
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)     1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   { PictOpAdd,
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)     0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE},
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static INLINE void
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pixel_to_float4(Pixel pixel, float *color, enum pipe_format format)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   const struct util_format_description *format_desc;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   uint8_t packed[4];
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   format_desc = util_format_description(format);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   packed[0] = pixel;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   packed[1] = pixel >> 8;
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   packed[2] = pixel >> 16;
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   packed[3] = pixel >> 24;
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   format_desc->unpack_rgba_float(color, 0, packed, 0, 1, 1);
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static boolean
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)blend_for_op(struct xorg_composite_blend *blend,
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             PicturePtr pDstPicture)
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   const int num_blends =
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      sizeof(xorg_blends)/sizeof(struct xorg_composite_blend);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   int i;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   boolean supported = FALSE;
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   /* our default in case something goes wrong */
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   *blend = xorg_blends[BLEND_OP_OVER];
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   for (i = 0; i < num_blends; ++i) {
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (xorg_blends[i].op == op) {
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         *blend = xorg_blends[i];
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         supported = TRUE;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* If there's no dst alpha channel, adjust the blend op so that we'll treat
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    * it as always 1. */
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   if (pDstPicture &&
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       PICT_FORMAT_A(pDstPicture->format) == 0 && blend->alpha_dst) {
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)         blend->rgb_src = PIPE_BLENDFACTOR_ONE;
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         blend->rgb_src = PIPE_BLENDFACTOR_ZERO;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   /* If the source alpha is being used, then we should only be in a case where
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    * the source blend factor is 0, and the source blend value is the mask
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    * channels multiplied by the source picture's alpha. */
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   if (pMaskPicture && pMaskPicture->componentAlpha &&
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       PICT_FORMAT_RGB(pMaskPicture->format) && blend->alpha_src) {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) {
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR;
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      } else if (blend->rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) {
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         blend->rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR;
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   }
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   return supported;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static INLINE int
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)render_repeat_to_gallium(int mode)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   switch(mode) {
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case RepeatNone:
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case RepeatNormal:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PIPE_TEX_WRAP_REPEAT;
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case RepeatReflect:
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return PIPE_TEX_WRAP_MIRROR_REPEAT;
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case RepeatPad:
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   default:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      debug_printf("Unsupported repeat mode\n");
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   return PIPE_TEX_WRAP_REPEAT;
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static INLINE boolean
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)render_filter_to_gallium(int xrender_filter, int *out_filter)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   switch (xrender_filter) {
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PictFilterNearest:
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *out_filter = PIPE_TEX_FILTER_NEAREST;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PictFilterBilinear:
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *out_filter = PIPE_TEX_FILTER_LINEAR;
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PictFilterFast:
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *out_filter = PIPE_TEX_FILTER_NEAREST;
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PictFilterGood:
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *out_filter = PIPE_TEX_FILTER_LINEAR;
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PictFilterBest:
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *out_filter = PIPE_TEX_FILTER_LINEAR;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case PictFilterConvolution:
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *out_filter = PIPE_TEX_FILTER_NEAREST;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return FALSE;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   default:
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      debug_printf("Unknown xrender filter\n");
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *out_filter = PIPE_TEX_FILTER_NEAREST;
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return FALSE;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   return TRUE;
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static boolean is_filter_accelerated(PicturePtr pic)
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   int filter;
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   if (pic && !render_filter_to_gallium(pic->filter, &filter))
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return FALSE;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   return TRUE;
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)boolean xorg_composite_accelerated(int op,
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                   PicturePtr pSrcPicture,
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                   PicturePtr pMaskPicture,
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   PicturePtr pDstPicture)
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   modesettingPtr ms = modesettingPTR(pScrn);
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   struct xorg_composite_blend blend;
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   if (!is_filter_accelerated(pSrcPicture) ||
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       !is_filter_accelerated(pMaskPicture)) {
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      XORG_FALLBACK("Unsupported Xrender filter");
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   }
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   if (pSrcPicture->pSourcePict) {
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         XORG_FALLBACK("Gradients not enabled (haven't been well tested)");
1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   }
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   if (blend_for_op(&blend, op,
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    pSrcPicture, pMaskPicture, pDstPicture)) {
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      /* Check for component alpha */
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (pMaskPicture && pMaskPicture->componentAlpha &&
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          PICT_FORMAT_RGB(pMaskPicture->format)) {
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            XORG_FALLBACK("Component alpha not supported with source "
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          "alpha and source value blending. (op=%d)",
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          op);
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         }
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return TRUE;
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   }
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   XORG_FALLBACK("Unsupported composition operation = %d", op);
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bind_blend_state(struct exa_context *exa, int op,
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 PicturePtr pSrcPicture,
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 PicturePtr pMaskPicture,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 PicturePtr pDstPicture)
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   struct xorg_composite_blend blend_opt;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct pipe_blend_state blend;
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture);
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   memset(&blend, 0, sizeof(struct pipe_blend_state));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   blend.rt[0].blend_enable = 1;
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   blend.rt[0].colormask = PIPE_MASK_RGBA;
22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   blend.rt[0].rgb_src_factor   = blend_opt.rgb_src;
22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   blend.rt[0].alpha_src_factor = blend_opt.rgb_src;
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   blend.rt[0].rgb_dst_factor   = blend_opt.rgb_dst;
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   cso_set_blend(exa->renderer->cso, &blend);
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static unsigned
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask,
23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      PicturePtr pDstPicture)
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   boolean set_alpha = FALSE;
23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   boolean swizzle = FALSE;
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   unsigned ret = 0;
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   if (pSrc && pSrc->picture_format == pSrcPicture->format) {
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (pSrc->picture_format == PICT_a8) {
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         if (mask)
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            return FS_MASK_LUMINANCE;
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         else if (pDstPicture->format != PICT_a8) {
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            /* if both dst and src are luminance then
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)             * we don't want to swizzle the alpha (X) of the
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)             * source into W component of the dst because
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)             * it will break our destination */
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            return FS_SRC_LUMINANCE;
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         }
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return 0;
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   }
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   if (pSrc && pSrc->picture_format != PICT_a8r8g8b8) {
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      assert(!"can not handle formats");
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return 0;
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   }
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   /* pSrc->picture_format == PICT_a8r8g8b8 */
26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   switch (pSrcPicture->format) {
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PICT_x8b8g8r8:
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PICT_b8g8r8:
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      set_alpha = TRUE; /* fall trough */
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PICT_a8b8g8r8:
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      swizzle = TRUE;
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PICT_x8r8g8b8:
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PICT_r8g8b8:
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      set_alpha = TRUE; /* fall through */
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PICT_a8r8g8b8:
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifdef PICT_TYPE_BGRA
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PICT_b8g8r8a8:
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PICT_b8g8r8x8:
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   case PICT_a2r10g10b10:
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PICT_x2r10g10b10:
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   case PICT_a2b10g10r10:
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   case PICT_x2b10g10r10:
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   default:
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      assert(!"can not handle formats");
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return 0;
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   }
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   if (set_alpha)
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   if (swizzle)
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   return ret;
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static void
2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bind_shaders(struct exa_context *exa, int op,
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture,
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask)
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles){
2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   unsigned vs_traits = 0, fs_traits = 0;
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   struct xorg_shader shader;
3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   exa->has_solid_color = FALSE;
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   if (pSrcPicture) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (pSrcPicture->repeatType == RepeatNone && pSrcPicture->transform)
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         fs_traits |= FS_SRC_REPEAT_NONE;
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (pSrcPicture->pSourcePict) {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            fs_traits |= FS_SOLID_FILL;
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            vs_traits |= VS_SOLID_FILL;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            debug_assert(pSrcPicture->format == PICT_a8r8g8b8);
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color,
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            exa->solid_color, PIPE_FORMAT_B8G8R8A8_UNORM);
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            exa->has_solid_color = TRUE;
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         } else {
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            debug_assert("!gradients not supported");
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         }
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         fs_traits |= FS_COMPOSITE;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         vs_traits |= VS_COMPOSITE;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture);
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   }
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   if (pMaskPicture) {
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      vs_traits |= VS_MASK;
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fs_traits |= FS_MASK;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (pMaskPicture->repeatType == RepeatNone && pMaskPicture->transform)
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         fs_traits |= FS_MASK_REPEAT_NONE;
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (pMaskPicture->componentAlpha) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         struct xorg_composite_blend blend;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         blend_for_op(&blend, op,
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      pSrcPicture, pMaskPicture, NULL);
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         if (blend.alpha_src) {
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            fs_traits |= FS_CA_SRCALPHA;
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         } else
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            fs_traits |= FS_CA_FULL;
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture);
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   }
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bind_samplers(struct exa_context *exa, int op,
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              PicturePtr pSrcPicture, PicturePtr pMaskPicture,
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              PicturePtr pDstPicture,
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              struct exa_pixmap_priv *pSrc,
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              struct exa_pixmap_priv *pMask,
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              struct exa_pixmap_priv *pDst)
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS] = {0};
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   struct pipe_sampler_state src_sampler, mask_sampler;
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   struct pipe_sampler_view view_templ;
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   struct pipe_sampler_view *src_view;
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   struct pipe_context *pipe = exa->pipe;
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   exa->num_bound_samplers = 0;
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   if (pSrcPicture && pSrc) {
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (exa->has_solid_color) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         debug_assert(!"solid color with textures");
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         samplers[0] = NULL;
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         unsigned src_wrap = render_repeat_to_gallium(
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            pSrcPicture->repeatType);
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         int filter;
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         render_filter_to_gallium(pSrcPicture->filter, &filter);
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         src_sampler.wrap_s = src_wrap;
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         src_sampler.wrap_t = src_wrap;
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         src_sampler.min_img_filter = filter;
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         src_sampler.mag_img_filter = filter;
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         src_sampler.normalized_coords = 1;
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         samplers[0] = &src_sampler;
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         exa->num_bound_samplers = 1;
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         u_sampler_view_default_template(&view_templ,
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         pSrc->tex,
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                         pSrc->tex->format);
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         src_view = pipe->create_sampler_view(pipe, pSrc->tex, &view_templ);
3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         exa->bound_sampler_views[0] = src_view;
3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   }
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   if (pMaskPicture && pMask) {
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      unsigned mask_wrap = render_repeat_to_gallium(
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         pMaskPicture->repeatType);
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      int filter;
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      render_filter_to_gallium(pMaskPicture->filter, &filter);
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      mask_sampler.wrap_s = mask_wrap;
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      mask_sampler.wrap_t = mask_wrap;
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      mask_sampler.min_img_filter = filter;
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      mask_sampler.mag_img_filter = filter;
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      mask_sampler.normalized_coords = 1;
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      samplers[1] = &mask_sampler;
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      exa->num_bound_samplers = 2;
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      u_sampler_view_default_template(&view_templ,
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      pMask->tex,
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      pMask->tex->format);
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      src_view = pipe->create_sampler_view(pipe, pMask->tex, &view_templ);
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      exa->bound_sampler_views[1] = src_view;
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   }
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    exa->num_bound_samplers,
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    (const struct pipe_sampler_state **)samplers);
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                         exa->num_bound_samplers,
4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                         exa->bound_sampler_views);
4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles){
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   if (!trans)
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return FALSE;
435
436   matrix[0] = XFixedToDouble(trans->matrix[0][0]);
437   matrix[3] = XFixedToDouble(trans->matrix[0][1]);
438   matrix[6] = XFixedToDouble(trans->matrix[0][2]);
439
440   matrix[1] = XFixedToDouble(trans->matrix[1][0]);
441   matrix[4] = XFixedToDouble(trans->matrix[1][1]);
442   matrix[7] = XFixedToDouble(trans->matrix[1][2]);
443
444   matrix[2] = XFixedToDouble(trans->matrix[2][0]);
445   matrix[5] = XFixedToDouble(trans->matrix[2][1]);
446   matrix[8] = XFixedToDouble(trans->matrix[2][2]);
447
448   return TRUE;
449}
450
451static void
452setup_transforms(struct  exa_context *exa,
453                 PicturePtr pSrcPicture, PicturePtr pMaskPicture)
454{
455   PictTransform *src_t = NULL;
456   PictTransform *mask_t = NULL;
457
458   if (pSrcPicture)
459      src_t = pSrcPicture->transform;
460   if (pMaskPicture)
461      mask_t = pMaskPicture->transform;
462
463   exa->transform.has_src  =
464      matrix_from_pict_transform(src_t, exa->transform.src);
465   exa->transform.has_mask =
466      matrix_from_pict_transform(mask_t, exa->transform.mask);
467}
468
469boolean xorg_composite_bind_state(struct exa_context *exa,
470                                  int op,
471                                  PicturePtr pSrcPicture,
472                                  PicturePtr pMaskPicture,
473                                  PicturePtr pDstPicture,
474                                  struct exa_pixmap_priv *pSrc,
475                                  struct exa_pixmap_priv *pMask,
476                                  struct exa_pixmap_priv *pDst)
477{
478   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pDst);
479
480   renderer_bind_destination(exa->renderer, dst_surf,
481                             pDst->width,
482                             pDst->height);
483
484   bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);
485   bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask);
486   bind_samplers(exa, op, pSrcPicture, pMaskPicture,
487                 pDstPicture, pSrc, pMask, pDst);
488
489   setup_transforms(exa, pSrcPicture, pMaskPicture);
490
491   if (exa->num_bound_samplers == 0 ) { /* solid fill */
492      renderer_begin_solid(exa->renderer);
493   } else {
494      renderer_begin_textures(exa->renderer,
495                              exa->num_bound_samplers);
496   }
497
498
499   pipe_surface_reference(&dst_surf, NULL);
500   return TRUE;
501}
502
503void xorg_composite(struct exa_context *exa,
504                    struct exa_pixmap_priv *dst,
505                    int srcX, int srcY, int maskX, int maskY,
506                    int dstX, int dstY, int width, int height)
507{
508   if (exa->num_bound_samplers == 0 ) { /* solid fill */
509      renderer_solid(exa->renderer,
510                     dstX, dstY, dstX + width, dstY + height,
511                     exa->solid_color);
512   } else {
513      int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY};
514      float *src_matrix = NULL;
515      float *mask_matrix = NULL;
516
517      if (exa->transform.has_src)
518         src_matrix = exa->transform.src;
519      if (exa->transform.has_mask)
520         mask_matrix = exa->transform.mask;
521
522      renderer_texture(exa->renderer,
523                       pos, width, height,
524                       exa->bound_sampler_views,
525                       exa->num_bound_samplers,
526                       src_matrix, mask_matrix);
527   }
528}
529
530boolean xorg_solid_bind_state(struct exa_context *exa,
531                              struct exa_pixmap_priv *pixmap,
532                              Pixel fg)
533{
534   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pixmap);
535   unsigned vs_traits, fs_traits;
536   struct xorg_shader shader;
537
538   pixel_to_float4(fg, exa->solid_color, pixmap->tex->format);
539   exa->has_solid_color = TRUE;
540
541#if 0
542   debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
543                (fg >> 24) & 0xff, (fg >> 16) & 0xff,
544                (fg >> 8) & 0xff,  (fg >> 0) & 0xff,
545                exa->solid_color[0], exa->solid_color[1],
546                exa->solid_color[2], exa->solid_color[3]);
547#endif
548
549   vs_traits = VS_SOLID_FILL;
550   fs_traits = FS_SOLID_FILL;
551
552   renderer_bind_destination(exa->renderer, dst_surf,
553                             pixmap->width, pixmap->height);
554   bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
555   cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
556   cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
557
558   shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
559   cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
560   cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
561
562   renderer_begin_solid(exa->renderer);
563
564   pipe_surface_reference(&dst_surf, NULL);
565   return TRUE;
566}
567
568void xorg_solid(struct exa_context *exa,
569                struct exa_pixmap_priv *pixmap,
570                int x0, int y0, int x1, int y1)
571{
572   renderer_solid(exa->renderer,
573                  x0, y0, x1, y1, exa->solid_color);
574}
575
576void
577xorg_composite_done(struct exa_context *exa)
578{
579   renderer_draw_flush(exa->renderer);
580
581   exa->transform.has_src = FALSE;
582   exa->transform.has_mask = FALSE;
583   exa->has_solid_color = FALSE;
584   exa->num_bound_samplers = 0;
585}
586