diff options
Diffstat (limited to 'src/gallium/state_trackers/xorg/xorg_composite.c')
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_composite.c | 585 |
1 files changed, 0 insertions, 585 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c deleted file mode 100644 index 7ccb3fe4734..00000000000 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ /dev/null @@ -1,585 +0,0 @@ -#include "xorg_composite.h" - -#include "xorg_renderer.h" -#include "xorg_exa_tgsi.h" - -#include "cso_cache/cso_context.h" -#include "util/u_format.h" -#include "util/u_sampler.h" - - -/*XXX also in Xrender.h but the including it here breaks compilition */ -#define XFixedToDouble(f) (((double) (f)) / 65536.) - -struct xorg_composite_blend { - int op : 8; - - unsigned alpha_dst : 4; - unsigned alpha_src : 4; - - unsigned rgb_src : 8; /**< PIPE_BLENDFACTOR_x */ - unsigned rgb_dst : 8; /**< PIPE_BLENDFACTOR_x */ -}; - -#define BLEND_OP_OVER 3 -static const struct xorg_composite_blend xorg_blends[] = { - { PictOpClear, - 0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO}, - { PictOpSrc, - 0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO}, - { PictOpDst, - 0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE}, - { PictOpOver, - 0, 1, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_INV_SRC_ALPHA}, - { PictOpOverReverse, - 1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE}, - { PictOpIn, - 1, 0, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ZERO}, - { PictOpInReverse, - 0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_SRC_ALPHA}, - { PictOpOut, - 1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ZERO}, - { PictOpOutReverse, - 0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA}, - { PictOpAtop, - 1, 1, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA}, - { PictOpAtopReverse, - 1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_SRC_ALPHA}, - { PictOpXor, - 1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA}, - { PictOpAdd, - 0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE}, -}; - - -static INLINE void -pixel_to_float4(Pixel pixel, float *color, enum pipe_format format) -{ - const struct util_format_description *format_desc; - uint8_t packed[4]; - - format_desc = util_format_description(format); - packed[0] = pixel; - packed[1] = pixel >> 8; - packed[2] = pixel >> 16; - packed[3] = pixel >> 24; - format_desc->unpack_rgba_float(color, 0, packed, 0, 1, 1); -} - -static boolean -blend_for_op(struct xorg_composite_blend *blend, - int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, - PicturePtr pDstPicture) -{ - const int num_blends = - sizeof(xorg_blends)/sizeof(struct xorg_composite_blend); - int i; - boolean supported = FALSE; - - /* our default in case something goes wrong */ - *blend = xorg_blends[BLEND_OP_OVER]; - - for (i = 0; i < num_blends; ++i) { - if (xorg_blends[i].op == op) { - *blend = xorg_blends[i]; - supported = TRUE; - } - } - - /* If there's no dst alpha channel, adjust the blend op so that we'll treat - * it as always 1. */ - if (pDstPicture && - PICT_FORMAT_A(pDstPicture->format) == 0 && blend->alpha_dst) { - if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA) - blend->rgb_src = PIPE_BLENDFACTOR_ONE; - else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA) - blend->rgb_src = PIPE_BLENDFACTOR_ZERO; - } - - /* If the source alpha is being used, then we should only be in a case where - * the source blend factor is 0, and the source blend value is the mask - * channels multiplied by the source picture's alpha. */ - if (pMaskPicture && pMaskPicture->componentAlpha && - PICT_FORMAT_RGB(pMaskPicture->format) && blend->alpha_src) { - if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) { - blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR; - } else if (blend->rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) { - blend->rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR; - } - } - - return supported; -} - -static INLINE int -render_repeat_to_gallium(int mode) -{ - switch(mode) { - case RepeatNone: - return PIPE_TEX_WRAP_CLAMP_TO_BORDER; - case RepeatNormal: - return PIPE_TEX_WRAP_REPEAT; - case RepeatReflect: - return PIPE_TEX_WRAP_MIRROR_REPEAT; - case RepeatPad: - return PIPE_TEX_WRAP_CLAMP_TO_EDGE; - default: - debug_printf("Unsupported repeat mode\n"); - } - return PIPE_TEX_WRAP_REPEAT; -} - -static INLINE boolean -render_filter_to_gallium(int xrender_filter, int *out_filter) -{ - - switch (xrender_filter) { - case PictFilterNearest: - *out_filter = PIPE_TEX_FILTER_NEAREST; - break; - case PictFilterBilinear: - *out_filter = PIPE_TEX_FILTER_LINEAR; - break; - case PictFilterFast: - *out_filter = PIPE_TEX_FILTER_NEAREST; - break; - case PictFilterGood: - *out_filter = PIPE_TEX_FILTER_LINEAR; - break; - case PictFilterBest: - *out_filter = PIPE_TEX_FILTER_LINEAR; - break; - case PictFilterConvolution: - *out_filter = PIPE_TEX_FILTER_NEAREST; - return FALSE; - default: - debug_printf("Unknown xrender filter\n"); - *out_filter = PIPE_TEX_FILTER_NEAREST; - return FALSE; - } - - return TRUE; -} - -static boolean is_filter_accelerated(PicturePtr pic) -{ - int filter; - if (pic && !render_filter_to_gallium(pic->filter, &filter)) - return FALSE; - return TRUE; -} - -boolean xorg_composite_accelerated(int op, - PicturePtr pSrcPicture, - PicturePtr pMaskPicture, - PicturePtr pDstPicture) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - modesettingPtr ms = modesettingPTR(pScrn); - struct xorg_composite_blend blend; - - if (!is_filter_accelerated(pSrcPicture) || - !is_filter_accelerated(pMaskPicture)) { - XORG_FALLBACK("Unsupported Xrender filter"); - } - - if (pSrcPicture->pSourcePict) { - if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill) - XORG_FALLBACK("Gradients not enabled (haven't been well tested)"); - } - - if (blend_for_op(&blend, op, - pSrcPicture, pMaskPicture, pDstPicture)) { - /* Check for component alpha */ - if (pMaskPicture && pMaskPicture->componentAlpha && - PICT_FORMAT_RGB(pMaskPicture->format)) { - if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) { - XORG_FALLBACK("Component alpha not supported with source " - "alpha and source value blending. (op=%d)", - op); - } - } - - return TRUE; - } - XORG_FALLBACK("Unsupported composition operation = %d", op); -} - -static void -bind_blend_state(struct exa_context *exa, int op, - PicturePtr pSrcPicture, - PicturePtr pMaskPicture, - PicturePtr pDstPicture) -{ - struct xorg_composite_blend blend_opt; - struct pipe_blend_state blend; - - blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture); - - memset(&blend, 0, sizeof(struct pipe_blend_state)); - blend.rt[0].blend_enable = 1; - blend.rt[0].colormask = PIPE_MASK_RGBA; - - blend.rt[0].rgb_src_factor = blend_opt.rgb_src; - blend.rt[0].alpha_src_factor = blend_opt.rgb_src; - blend.rt[0].rgb_dst_factor = blend_opt.rgb_dst; - blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst; - - cso_set_blend(exa->renderer->cso, &blend); -} - -static unsigned -picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask, - PicturePtr pDstPicture) -{ - boolean set_alpha = FALSE; - boolean swizzle = FALSE; - unsigned ret = 0; - - if (pSrc && pSrc->picture_format == pSrcPicture->format) { - if (pSrc->picture_format == PICT_a8) { - if (mask) - return FS_MASK_LUMINANCE; - else if (pDstPicture->format != PICT_a8) { - /* if both dst and src are luminance then - * we don't want to swizzle the alpha (X) of the - * source into W component of the dst because - * it will break our destination */ - return FS_SRC_LUMINANCE; - } - } - return 0; - } - - if (pSrc && pSrc->picture_format != PICT_a8r8g8b8) { - assert(!"can not handle formats"); - return 0; - } - - /* pSrc->picture_format == PICT_a8r8g8b8 */ - switch (pSrcPicture->format) { - case PICT_x8b8g8r8: - case PICT_b8g8r8: - set_alpha = TRUE; /* fall trough */ - case PICT_a8b8g8r8: - swizzle = TRUE; - break; - case PICT_x8r8g8b8: - case PICT_r8g8b8: - set_alpha = TRUE; /* fall through */ - case PICT_a8r8g8b8: - break; -#ifdef PICT_TYPE_BGRA - case PICT_b8g8r8a8: - case PICT_b8g8r8x8: - case PICT_a2r10g10b10: - case PICT_x2r10g10b10: - case PICT_a2b10g10r10: - case PICT_x2b10g10r10: -#endif - default: - assert(!"can not handle formats"); - return 0; - } - - if (set_alpha) - ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA; - if (swizzle) - ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB; - - return ret; -} - -static void -bind_shaders(struct exa_context *exa, int op, - PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, - struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask) -{ - unsigned vs_traits = 0, fs_traits = 0; - struct xorg_shader shader; - - exa->has_solid_color = FALSE; - - if (pSrcPicture) { - if (pSrcPicture->repeatType == RepeatNone && pSrcPicture->transform) - fs_traits |= FS_SRC_REPEAT_NONE; - - if (pSrcPicture->pSourcePict) { - if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) { - fs_traits |= FS_SOLID_FILL; - vs_traits |= VS_SOLID_FILL; - debug_assert(pSrcPicture->format == PICT_a8r8g8b8); - pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color, - exa->solid_color, PIPE_FORMAT_B8G8R8A8_UNORM); - exa->has_solid_color = TRUE; - } else { - debug_assert("!gradients not supported"); - } - } else { - fs_traits |= FS_COMPOSITE; - vs_traits |= VS_COMPOSITE; - } - - fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture); - } - - if (pMaskPicture) { - vs_traits |= VS_MASK; - fs_traits |= FS_MASK; - if (pMaskPicture->repeatType == RepeatNone && pMaskPicture->transform) - fs_traits |= FS_MASK_REPEAT_NONE; - if (pMaskPicture->componentAlpha) { - struct xorg_composite_blend blend; - blend_for_op(&blend, op, - pSrcPicture, pMaskPicture, NULL); - if (blend.alpha_src) { - fs_traits |= FS_CA_SRCALPHA; - } else - fs_traits |= FS_CA_FULL; - } - - fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture); - } - - shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits); - cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs); - cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs); -} - -static void -bind_samplers(struct exa_context *exa, int op, - PicturePtr pSrcPicture, PicturePtr pMaskPicture, - PicturePtr pDstPicture, - struct exa_pixmap_priv *pSrc, - struct exa_pixmap_priv *pMask, - struct exa_pixmap_priv *pDst) -{ - struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS] = {0}; - struct pipe_sampler_state src_sampler, mask_sampler; - struct pipe_sampler_view view_templ; - struct pipe_sampler_view *src_view; - struct pipe_context *pipe = exa->pipe; - - exa->num_bound_samplers = 0; - - memset(&src_sampler, 0, sizeof(struct pipe_sampler_state)); - memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state)); - - if (pSrcPicture && pSrc) { - if (exa->has_solid_color) { - debug_assert(!"solid color with textures"); - samplers[0] = NULL; - pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL); - } else { - unsigned src_wrap = render_repeat_to_gallium( - pSrcPicture->repeatType); - int filter; - - render_filter_to_gallium(pSrcPicture->filter, &filter); - - src_sampler.wrap_s = src_wrap; - src_sampler.wrap_t = src_wrap; - src_sampler.min_img_filter = filter; - src_sampler.mag_img_filter = filter; - src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; - src_sampler.normalized_coords = 1; - samplers[0] = &src_sampler; - exa->num_bound_samplers = 1; - u_sampler_view_default_template(&view_templ, - pSrc->tex, - pSrc->tex->format); - src_view = pipe->create_sampler_view(pipe, pSrc->tex, &view_templ); - pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL); - exa->bound_sampler_views[0] = src_view; - } - } - - if (pMaskPicture && pMask) { - unsigned mask_wrap = render_repeat_to_gallium( - pMaskPicture->repeatType); - int filter; - - render_filter_to_gallium(pMaskPicture->filter, &filter); - - mask_sampler.wrap_s = mask_wrap; - mask_sampler.wrap_t = mask_wrap; - mask_sampler.min_img_filter = filter; - mask_sampler.mag_img_filter = filter; - src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; - mask_sampler.normalized_coords = 1; - samplers[1] = &mask_sampler; - exa->num_bound_samplers = 2; - u_sampler_view_default_template(&view_templ, - pMask->tex, - pMask->tex->format); - src_view = pipe->create_sampler_view(pipe, pMask->tex, &view_templ); - pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL); - exa->bound_sampler_views[1] = src_view; - } - - cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT, - exa->num_bound_samplers, - (const struct pipe_sampler_state **)samplers); - cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT, - exa->num_bound_samplers, - exa->bound_sampler_views); -} - - - -static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix) -{ - if (!trans) - return FALSE; - - matrix[0] = XFixedToDouble(trans->matrix[0][0]); - matrix[3] = XFixedToDouble(trans->matrix[0][1]); - matrix[6] = XFixedToDouble(trans->matrix[0][2]); - - matrix[1] = XFixedToDouble(trans->matrix[1][0]); - matrix[4] = XFixedToDouble(trans->matrix[1][1]); - matrix[7] = XFixedToDouble(trans->matrix[1][2]); - - matrix[2] = XFixedToDouble(trans->matrix[2][0]); - matrix[5] = XFixedToDouble(trans->matrix[2][1]); - matrix[8] = XFixedToDouble(trans->matrix[2][2]); - - return TRUE; -} - -static void -setup_transforms(struct exa_context *exa, - PicturePtr pSrcPicture, PicturePtr pMaskPicture) -{ - PictTransform *src_t = NULL; - PictTransform *mask_t = NULL; - - if (pSrcPicture) - src_t = pSrcPicture->transform; - if (pMaskPicture) - mask_t = pMaskPicture->transform; - - exa->transform.has_src = - matrix_from_pict_transform(src_t, exa->transform.src); - exa->transform.has_mask = - matrix_from_pict_transform(mask_t, exa->transform.mask); -} - -boolean xorg_composite_bind_state(struct exa_context *exa, - int op, - PicturePtr pSrcPicture, - PicturePtr pMaskPicture, - PicturePtr pDstPicture, - struct exa_pixmap_priv *pSrc, - struct exa_pixmap_priv *pMask, - struct exa_pixmap_priv *pDst) -{ - struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pDst); - - renderer_bind_destination(exa->renderer, dst_surf, - pDst->width, - pDst->height); - - bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture); - bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask); - bind_samplers(exa, op, pSrcPicture, pMaskPicture, - pDstPicture, pSrc, pMask, pDst); - - setup_transforms(exa, pSrcPicture, pMaskPicture); - - if (exa->num_bound_samplers == 0 ) { /* solid fill */ - renderer_begin_solid(exa->renderer); - } else { - renderer_begin_textures(exa->renderer, - exa->num_bound_samplers); - } - - - pipe_surface_reference(&dst_surf, NULL); - return TRUE; -} - -void xorg_composite(struct exa_context *exa, - struct exa_pixmap_priv *dst, - int srcX, int srcY, int maskX, int maskY, - int dstX, int dstY, int width, int height) -{ - if (exa->num_bound_samplers == 0 ) { /* solid fill */ - renderer_solid(exa->renderer, - dstX, dstY, dstX + width, dstY + height, - exa->solid_color); - } else { - int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY}; - float *src_matrix = NULL; - float *mask_matrix = NULL; - - if (exa->transform.has_src) - src_matrix = exa->transform.src; - if (exa->transform.has_mask) - mask_matrix = exa->transform.mask; - - renderer_texture(exa->renderer, - pos, width, height, - exa->bound_sampler_views, - exa->num_bound_samplers, - src_matrix, mask_matrix); - } -} - -boolean xorg_solid_bind_state(struct exa_context *exa, - struct exa_pixmap_priv *pixmap, - Pixel fg) -{ - struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pixmap); - unsigned vs_traits, fs_traits; - struct xorg_shader shader; - - pixel_to_float4(fg, exa->solid_color, pixmap->tex->format); - exa->has_solid_color = TRUE; - -#if 0 - debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n", - (fg >> 24) & 0xff, (fg >> 16) & 0xff, - (fg >> 8) & 0xff, (fg >> 0) & 0xff, - exa->solid_color[0], exa->solid_color[1], - exa->solid_color[2], exa->solid_color[3]); -#endif - - vs_traits = VS_SOLID_FILL; - fs_traits = FS_SOLID_FILL; - - renderer_bind_destination(exa->renderer, dst_surf, - pixmap->width, pixmap->height); - bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL); - cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL); - cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL); - - shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits); - cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs); - cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs); - - renderer_begin_solid(exa->renderer); - - pipe_surface_reference(&dst_surf, NULL); - return TRUE; -} - -void xorg_solid(struct exa_context *exa, - struct exa_pixmap_priv *pixmap, - int x0, int y0, int x1, int y1) -{ - renderer_solid(exa->renderer, - x0, y0, x1, y1, exa->solid_color); -} - -void -xorg_composite_done(struct exa_context *exa) -{ - renderer_draw_flush(exa->renderer); - - exa->transform.has_src = FALSE; - exa->transform.has_mask = FALSE; - exa->has_solid_color = FALSE; - exa->num_bound_samplers = 0; -} |