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