Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. #include "xorg_composite.h"
  2.  
  3. #include "xorg_renderer.h"
  4. #include "xorg_exa_tgsi.h"
  5.  
  6. #include "cso_cache/cso_context.h"
  7. #include "util/u_format.h"
  8. #include "util/u_sampler.h"
  9.  
  10.  
  11. /*XXX also in Xrender.h but the including it here breaks compilition */
  12. #define XFixedToDouble(f)    (((double) (f)) / 65536.)
  13.  
  14. struct xorg_composite_blend {
  15.    int op : 8;
  16.  
  17.    unsigned alpha_dst : 4;
  18.    unsigned alpha_src : 4;
  19.  
  20.    unsigned rgb_src : 8;    /**< PIPE_BLENDFACTOR_x */
  21.    unsigned rgb_dst : 8;    /**< PIPE_BLENDFACTOR_x */
  22. };
  23.  
  24. #define BLEND_OP_OVER 3
  25. static const struct xorg_composite_blend xorg_blends[] = {
  26.    { PictOpClear,
  27.      0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO},
  28.    { PictOpSrc,
  29.      0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO},
  30.    { PictOpDst,
  31.      0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE},
  32.    { PictOpOver,
  33.      0, 1, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
  34.    { PictOpOverReverse,
  35.      1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE},
  36.    { PictOpIn,
  37.      1, 0, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
  38.    { PictOpInReverse,
  39.      0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_SRC_ALPHA},
  40.    { PictOpOut,
  41.      1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
  42.    { PictOpOutReverse,
  43.      0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
  44.    { PictOpAtop,
  45.      1, 1, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
  46.    { PictOpAtopReverse,
  47.      1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_SRC_ALPHA},
  48.    { PictOpXor,
  49.      1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
  50.    { PictOpAdd,
  51.      0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE},
  52. };
  53.  
  54.  
  55. static INLINE void
  56. pixel_to_float4(Pixel pixel, float *color, enum pipe_format format)
  57. {
  58.    const struct util_format_description *format_desc;
  59.    uint8_t packed[4];
  60.  
  61.    format_desc = util_format_description(format);
  62.    packed[0] = pixel;
  63.    packed[1] = pixel >> 8;
  64.    packed[2] = pixel >> 16;
  65.    packed[3] = pixel >> 24;
  66.    format_desc->unpack_rgba_float(color, 0, packed, 0, 1, 1);
  67. }
  68.  
  69. static boolean
  70. blend_for_op(struct xorg_composite_blend *blend,
  71.              int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
  72.              PicturePtr pDstPicture)
  73. {
  74.    const int num_blends =
  75.       sizeof(xorg_blends)/sizeof(struct xorg_composite_blend);
  76.    int i;
  77.    boolean supported = FALSE;
  78.  
  79.    /* our default in case something goes wrong */
  80.    *blend = xorg_blends[BLEND_OP_OVER];
  81.  
  82.    for (i = 0; i < num_blends; ++i) {
  83.       if (xorg_blends[i].op == op) {
  84.          *blend = xorg_blends[i];
  85.          supported = TRUE;
  86.       }
  87.    }
  88.  
  89.    /* If there's no dst alpha channel, adjust the blend op so that we'll treat
  90.     * it as always 1. */
  91.    if (pDstPicture &&
  92.        PICT_FORMAT_A(pDstPicture->format) == 0 && blend->alpha_dst) {
  93.       if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
  94.          blend->rgb_src = PIPE_BLENDFACTOR_ONE;
  95.       else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
  96.          blend->rgb_src = PIPE_BLENDFACTOR_ZERO;
  97.    }
  98.  
  99.    /* If the source alpha is being used, then we should only be in a case where
  100.     * the source blend factor is 0, and the source blend value is the mask
  101.     * channels multiplied by the source picture's alpha. */
  102.    if (pMaskPicture && pMaskPicture->componentAlpha &&
  103.        PICT_FORMAT_RGB(pMaskPicture->format) && blend->alpha_src) {
  104.       if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) {
  105.          blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR;
  106.       } else if (blend->rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) {
  107.          blend->rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR;
  108.       }
  109.    }
  110.  
  111.    return supported;
  112. }
  113.  
  114. static INLINE int
  115. render_repeat_to_gallium(int mode)
  116. {
  117.    switch(mode) {
  118.    case RepeatNone:
  119.       return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
  120.    case RepeatNormal:
  121.       return PIPE_TEX_WRAP_REPEAT;
  122.    case RepeatReflect:
  123.       return PIPE_TEX_WRAP_MIRROR_REPEAT;
  124.    case RepeatPad:
  125.       return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  126.    default:
  127.       debug_printf("Unsupported repeat mode\n");
  128.    }
  129.    return PIPE_TEX_WRAP_REPEAT;
  130. }
  131.  
  132. static INLINE boolean
  133. render_filter_to_gallium(int xrender_filter, int *out_filter)
  134. {
  135.  
  136.    switch (xrender_filter) {
  137.    case PictFilterNearest:
  138.       *out_filter = PIPE_TEX_FILTER_NEAREST;
  139.       break;
  140.    case PictFilterBilinear:
  141.       *out_filter = PIPE_TEX_FILTER_LINEAR;
  142.       break;
  143.    case PictFilterFast:
  144.       *out_filter = PIPE_TEX_FILTER_NEAREST;
  145.       break;
  146.    case PictFilterGood:
  147.       *out_filter = PIPE_TEX_FILTER_LINEAR;
  148.       break;
  149.    case PictFilterBest:
  150.       *out_filter = PIPE_TEX_FILTER_LINEAR;
  151.       break;
  152.    case PictFilterConvolution:
  153.       *out_filter = PIPE_TEX_FILTER_NEAREST;
  154.       return FALSE;
  155.    default:
  156.       debug_printf("Unknown xrender filter\n");
  157.       *out_filter = PIPE_TEX_FILTER_NEAREST;
  158.       return FALSE;
  159.    }
  160.  
  161.    return TRUE;
  162. }
  163.  
  164. static boolean is_filter_accelerated(PicturePtr pic)
  165. {
  166.    int filter;
  167.    if (pic && !render_filter_to_gallium(pic->filter, &filter))
  168.        return FALSE;
  169.    return TRUE;
  170. }
  171.  
  172. boolean xorg_composite_accelerated(int op,
  173.                                    PicturePtr pSrcPicture,
  174.                                    PicturePtr pMaskPicture,
  175.                                    PicturePtr pDstPicture)
  176. {
  177.    ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
  178.    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
  179.    modesettingPtr ms = modesettingPTR(pScrn);
  180.    struct xorg_composite_blend blend;
  181.  
  182.    if (!is_filter_accelerated(pSrcPicture) ||
  183.        !is_filter_accelerated(pMaskPicture)) {
  184.       XORG_FALLBACK("Unsupported Xrender filter");
  185.    }
  186.  
  187.    if (pSrcPicture->pSourcePict) {
  188.       if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
  189.          XORG_FALLBACK("Gradients not enabled (haven't been well tested)");
  190.    }
  191.  
  192.    if (blend_for_op(&blend, op,
  193.                     pSrcPicture, pMaskPicture, pDstPicture)) {
  194.       /* Check for component alpha */
  195.       if (pMaskPicture && pMaskPicture->componentAlpha &&
  196.           PICT_FORMAT_RGB(pMaskPicture->format)) {
  197.          if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) {
  198.             XORG_FALLBACK("Component alpha not supported with source "
  199.                           "alpha and source value blending. (op=%d)",
  200.                           op);
  201.          }
  202.       }
  203.  
  204.       return TRUE;
  205.    }
  206.    XORG_FALLBACK("Unsupported composition operation = %d", op);
  207. }
  208.  
  209. static void
  210. bind_blend_state(struct exa_context *exa, int op,
  211.                  PicturePtr pSrcPicture,
  212.                  PicturePtr pMaskPicture,
  213.                  PicturePtr pDstPicture)
  214. {
  215.    struct xorg_composite_blend blend_opt;
  216.    struct pipe_blend_state blend;
  217.  
  218.    blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture);
  219.  
  220.    memset(&blend, 0, sizeof(struct pipe_blend_state));
  221.    blend.rt[0].blend_enable = 1;
  222.    blend.rt[0].colormask = PIPE_MASK_RGBA;
  223.  
  224.    blend.rt[0].rgb_src_factor   = blend_opt.rgb_src;
  225.    blend.rt[0].alpha_src_factor = blend_opt.rgb_src;
  226.    blend.rt[0].rgb_dst_factor   = blend_opt.rgb_dst;
  227.    blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
  228.  
  229.    cso_set_blend(exa->renderer->cso, &blend);
  230. }
  231.  
  232. static unsigned
  233. picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask,
  234.                       PicturePtr pDstPicture)
  235. {
  236.    boolean set_alpha = FALSE;
  237.    boolean swizzle = FALSE;
  238.    unsigned ret = 0;
  239.  
  240.    if (pSrc && pSrc->picture_format == pSrcPicture->format) {
  241.       if (pSrc->picture_format == PICT_a8) {
  242.          if (mask)
  243.             return FS_MASK_LUMINANCE;
  244.          else if (pDstPicture->format != PICT_a8) {
  245.             /* if both dst and src are luminance then
  246.              * we don't want to swizzle the alpha (X) of the
  247.              * source into W component of the dst because
  248.              * it will break our destination */
  249.             return FS_SRC_LUMINANCE;
  250.          }
  251.       }
  252.       return 0;
  253.    }
  254.  
  255.    if (pSrc && pSrc->picture_format != PICT_a8r8g8b8) {
  256.       assert(!"can not handle formats");
  257.       return 0;
  258.    }
  259.  
  260.    /* pSrc->picture_format == PICT_a8r8g8b8 */
  261.    switch (pSrcPicture->format) {
  262.    case PICT_x8b8g8r8:
  263.    case PICT_b8g8r8:
  264.       set_alpha = TRUE; /* fall trough */
  265.    case PICT_a8b8g8r8:
  266.       swizzle = TRUE;
  267.       break;
  268.    case PICT_x8r8g8b8:
  269.    case PICT_r8g8b8:
  270.       set_alpha = TRUE; /* fall through */
  271.    case PICT_a8r8g8b8:
  272.       break;
  273. #ifdef PICT_TYPE_BGRA
  274.    case PICT_b8g8r8a8:
  275.    case PICT_b8g8r8x8:
  276.    case PICT_a2r10g10b10:
  277.    case PICT_x2r10g10b10:
  278.    case PICT_a2b10g10r10:
  279.    case PICT_x2b10g10r10:
  280. #endif
  281.    default:
  282.       assert(!"can not handle formats");
  283.       return 0;
  284.    }
  285.  
  286.    if (set_alpha)
  287.       ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
  288.    if (swizzle)
  289.       ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
  290.  
  291.    return ret;
  292. }
  293.  
  294. static void
  295. bind_shaders(struct exa_context *exa, int op,
  296.              PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture,
  297.              struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask)
  298. {
  299.    unsigned vs_traits = 0, fs_traits = 0;
  300.    struct xorg_shader shader;
  301.  
  302.    exa->has_solid_color = FALSE;
  303.  
  304.    if (pSrcPicture) {
  305.       if (pSrcPicture->repeatType == RepeatNone && pSrcPicture->transform)
  306.          fs_traits |= FS_SRC_REPEAT_NONE;
  307.  
  308.       if (pSrcPicture->pSourcePict) {
  309.          if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
  310.             fs_traits |= FS_SOLID_FILL;
  311.             vs_traits |= VS_SOLID_FILL;
  312.             debug_assert(pSrcPicture->format == PICT_a8r8g8b8);
  313.             pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color,
  314.                             exa->solid_color, PIPE_FORMAT_B8G8R8A8_UNORM);
  315.             exa->has_solid_color = TRUE;
  316.          } else {
  317.             debug_assert("!gradients not supported");
  318.          }
  319.       } else {
  320.          fs_traits |= FS_COMPOSITE;
  321.          vs_traits |= VS_COMPOSITE;
  322.       }
  323.  
  324.       fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture);
  325.    }
  326.  
  327.    if (pMaskPicture) {
  328.       vs_traits |= VS_MASK;
  329.       fs_traits |= FS_MASK;
  330.       if (pMaskPicture->repeatType == RepeatNone && pMaskPicture->transform)
  331.          fs_traits |= FS_MASK_REPEAT_NONE;
  332.       if (pMaskPicture->componentAlpha) {
  333.          struct xorg_composite_blend blend;
  334.          blend_for_op(&blend, op,
  335.                       pSrcPicture, pMaskPicture, NULL);
  336.          if (blend.alpha_src) {
  337.             fs_traits |= FS_CA_SRCALPHA;
  338.          } else
  339.             fs_traits |= FS_CA_FULL;
  340.       }
  341.  
  342.       fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture);
  343.    }
  344.  
  345.    shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
  346.    cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
  347.    cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
  348. }
  349.  
  350. static void
  351. bind_samplers(struct exa_context *exa, int op,
  352.               PicturePtr pSrcPicture, PicturePtr pMaskPicture,
  353.               PicturePtr pDstPicture,
  354.               struct exa_pixmap_priv *pSrc,
  355.               struct exa_pixmap_priv *pMask,
  356.               struct exa_pixmap_priv *pDst)
  357. {
  358.    struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS] = {0};
  359.    struct pipe_sampler_state src_sampler, mask_sampler;
  360.    struct pipe_sampler_view view_templ;
  361.    struct pipe_sampler_view *src_view;
  362.    struct pipe_context *pipe = exa->pipe;
  363.  
  364.    exa->num_bound_samplers = 0;
  365.  
  366.    memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
  367.    memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
  368.  
  369.    if (pSrcPicture && pSrc) {
  370.       if (exa->has_solid_color) {
  371.          debug_assert(!"solid color with textures");
  372.          samplers[0] = NULL;
  373.          pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
  374.       } else {
  375.          unsigned src_wrap = render_repeat_to_gallium(
  376.             pSrcPicture->repeatType);
  377.          int filter;
  378.  
  379.          render_filter_to_gallium(pSrcPicture->filter, &filter);
  380.  
  381.          src_sampler.wrap_s = src_wrap;
  382.          src_sampler.wrap_t = src_wrap;
  383.          src_sampler.min_img_filter = filter;
  384.          src_sampler.mag_img_filter = filter;
  385.          src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
  386.          src_sampler.normalized_coords = 1;
  387.          samplers[0] = &src_sampler;
  388.          exa->num_bound_samplers = 1;
  389.          u_sampler_view_default_template(&view_templ,
  390.                                          pSrc->tex,
  391.                                          pSrc->tex->format);
  392.          src_view = pipe->create_sampler_view(pipe, pSrc->tex, &view_templ);
  393.          pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
  394.          exa->bound_sampler_views[0] = src_view;
  395.       }
  396.    }
  397.  
  398.    if (pMaskPicture && pMask) {
  399.       unsigned mask_wrap = render_repeat_to_gallium(
  400.          pMaskPicture->repeatType);
  401.       int filter;
  402.  
  403.       render_filter_to_gallium(pMaskPicture->filter, &filter);
  404.  
  405.       mask_sampler.wrap_s = mask_wrap;
  406.       mask_sampler.wrap_t = mask_wrap;
  407.       mask_sampler.min_img_filter = filter;
  408.       mask_sampler.mag_img_filter = filter;
  409.       src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
  410.       mask_sampler.normalized_coords = 1;
  411.       samplers[1] = &mask_sampler;
  412.       exa->num_bound_samplers = 2;
  413.       u_sampler_view_default_template(&view_templ,
  414.                                       pMask->tex,
  415.                                       pMask->tex->format);
  416.       src_view = pipe->create_sampler_view(pipe, pMask->tex, &view_templ);
  417.       pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
  418.       exa->bound_sampler_views[1] = src_view;
  419.    }
  420.  
  421.    cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
  422.                     exa->num_bound_samplers,
  423.                     (const struct pipe_sampler_state **)samplers);
  424.    cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
  425.                          exa->num_bound_samplers,
  426.                          exa->bound_sampler_views);
  427. }
  428.  
  429.  
  430.  
  431. static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
  432. {
  433.    if (!trans)
  434.       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.  
  451. static void
  452. setup_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.  
  469. boolean 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.  
  503. void 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.  
  530. boolean 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.  
  568. void 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.  
  576. void
  577. xorg_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.